Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

410 lines
16 KiB

  1. #ifndef NEWMLSTR
  2. // MLStr.h : Declaration of the CMLStr
  3. #ifndef __MLSTR_H_
  4. #define __MLSTR_H_
  5. #ifdef ASTRIMPL
  6. #include "mlstrw.h"
  7. #endif
  8. #include "mlstra.h"
  9. #ifdef ASTRIMPL
  10. #include "mlstrbuf.h"
  11. #endif
  12. #define MAX_LOCK_COUNT 4
  13. // Error Code
  14. #define FACILITY_MLSTR 0x0A15
  15. #define MLSTR_E_ACCESSDENIED MAKE_HRESULT(1, FACILITY_MLSTR, 1002)
  16. #define MLSTR_E_TOOMANYNESTOFLOCK MAKE_HRESULT(1, FACILITY_MLSTR, 1003)
  17. #define MLSTR_E_STRBUFNOTAVAILABLE MAKE_HRESULT(1, FACILITY_MLSTR, 1004)
  18. /////////////////////////////////////////////////////////////////////////////
  19. // CMLStr
  20. class ATL_NO_VTABLE CMLStr :
  21. public CComObjectRoot,
  22. public CComCoClass<CMLStr, &CLSID_CMLangString>,
  23. #ifdef ASTRIMPL
  24. public IMLangString
  25. #else
  26. public IMLangStringWStr
  27. #endif
  28. {
  29. typedef HRESULT (CMLStr::*PFNUNLOCKPROC)(void* pKey, const void* pszSrc, long cchSrc, long* pcchActual, long* plActualLen);
  30. public:
  31. CMLStr(void);
  32. DECLARE_NO_REGISTRY()
  33. BEGIN_COM_MAP(CMLStr)
  34. COM_INTERFACE_ENTRY(IMLangString)
  35. #ifdef ASTRIMPL
  36. COM_INTERFACE_ENTRY_TEAR_OFF(IID_IMLangStringWStr, CMLStrW)
  37. #else
  38. COM_INTERFACE_ENTRY(IMLangStringWStr)
  39. #endif
  40. COM_INTERFACE_ENTRY_TEAR_OFF(IID_IMLangStringAStr, CMLStrA)
  41. END_COM_MAP()
  42. public:
  43. // IMLangString
  44. STDMETHOD(Sync)(/*[in]*/ BOOL fNoAccess);
  45. STDMETHOD(GetLength)(/*[out, retval]*/ long* plLen);
  46. STDMETHOD(SetMLStr)(/*[in]*/ long lDestPos, /*[in]*/ long lDestLen, /*[in]*/ IUnknown* pSrcMLStr, /*[in]*/ long lSrcPos, /*[in]*/ long lSrcLen);
  47. STDMETHOD(GetMLStr)(/*[in]*/ long lSrcPos, /*[in]*/ long lSrcLen, /*[in]*/ IUnknown* pUnkOuter, /*[in]*/ DWORD dwClsContext, /*[in]*/ const IID* piid, /*[out]*/ IUnknown** ppDestMLStr, /*[out]*/ long* plDestPos, /*[out]*/ long* plDestLen);
  48. #ifndef ASTRIMPL
  49. // IMLangStringWStr
  50. STDMETHOD(SetWStr)(/*[in]*/ long lDestPos, /*[in]*/ long lDestLen, /*[in, size_is(cchSrc)]*/ const WCHAR* pszSrc, /*[in]*/ long cchSrc, /*[out]*/ long* pcchActual, /*[out]*/ long* plActualLen);
  51. STDMETHOD(SetStrBufW)(/*[in]*/ long lDestPos, /*[in]*/ long lDestLen, /*[in]*/ IMLangStringBufW* pSrcBuf, /*[out]*/ long* pcchActual, /*[out]*/ long* plActualLen);
  52. STDMETHOD(GetWStr)(/*[in]*/ long lSrcPos, /*[in]*/ long lSrcLen, /*[out, size_is(cchDest)]*/ WCHAR* pszDest, /*[in]*/ long cchDest, /*[out]*/ long* pcchActual, /*[out]*/ long* plActualLen);
  53. STDMETHOD(GetStrBufW)(/*[in]*/ long lSrcPos, /*[in]*/ long lSrcMaxLen, /*[out]*/ IMLangStringBufW** ppDestBuf, /*[out]*/ long* plDestLen);
  54. STDMETHOD(LockWStr)(/*[in]*/ long lSrcPos, /*[in]*/ long lSrcLen, /*[in]*/ long lFlags, /*[in]*/ long cchRequest, /*[out, size_is(,*pcchDest)]*/ WCHAR** ppszDest, /*[out]*/ long* pcchDest, /*[out]*/ long* plDestLen);
  55. STDMETHOD(UnlockWStr)(/*[in, size_is(cchSrc)]*/ const WCHAR* pszSrc, /*[in]*/ long cchSrc, /*[out]*/ long* pcchActual, /*[out]*/ long* plActualLen);
  56. #endif
  57. STDMETHOD(SetLocale)(/*[in]*/ long lDestPos, /*[in]*/ long lDestLen, /*[in]*/ LCID locale);
  58. STDMETHOD(GetLocale)(/*[in]*/ long lSrcPos, /*[in]*/ long lSrcMaxLen, /*[out]*/ LCID* plocale, /*[out]*/ long* plLocalePos, /*[out]*/ long* plLocaleLen);
  59. #ifdef ASTRIMPL
  60. protected:
  61. class CLockInfo
  62. {
  63. protected:
  64. class CLockInfoEntry
  65. {
  66. public:
  67. void* m_psz;
  68. PFNUNLOCKPROC m_pfnUnlockProc;
  69. long m_lFlags;
  70. UINT m_uCodePage;
  71. long m_lPos;
  72. long m_lLen;
  73. long m_cchPos;
  74. long m_cchLen;
  75. };
  76. public:
  77. CLockInfo(CMLStr* pMLStr) : m_pMLStr(pMLStr)
  78. {
  79. m_nLockCount = 0;
  80. m_pLockArray = NULL;
  81. }
  82. ~CLockInfo(void)
  83. {
  84. UnlockAll();
  85. }
  86. HRESULT UnlockAll(void);
  87. HRESULT StartLock(BOOL fWrite)
  88. {
  89. if (fWrite && !m_nLockCount)
  90. m_nLockCount = -1; // Negative means write lock
  91. else if (!fWrite && m_nLockCount >= 0)
  92. m_nLockCount++;
  93. else
  94. return MLSTR_E_ACCESSDENIED;
  95. return S_OK;
  96. }
  97. HRESULT EndLock(BOOL fWrite)
  98. {
  99. ASSERT(m_nLockCount);
  100. if (fWrite)
  101. m_nLockCount = 0;
  102. else
  103. m_nLockCount--;
  104. return S_OK;
  105. }
  106. HRESULT Lock(PFNUNLOCKPROC pfnUnlockProc, long lFlags, UINT uCodePage, void* psz, long lPos, long lLen, long cchPos, long cchLen);
  107. HRESULT Find(const void* psz, long cch, void** ppKey);
  108. HRESULT Unlock(void* pKey, const void* psz, long cch, long* pcchActual, long* plActualLen);
  109. long GetFlags(void* pKey) {return ((CLockInfoEntry*)pKey)->m_lFlags;}
  110. UINT GetCodePage(void* pKey) {return ((CLockInfoEntry*)pKey)->m_uCodePage;}
  111. long GetPos(void* pKey) {return ((CLockInfoEntry*)pKey)->m_lPos;}
  112. long GetLen(void* pKey) {return ((CLockInfoEntry*)pKey)->m_lLen;}
  113. long GetCChPos(void* pKey) {return ((CLockInfoEntry*)pKey)->m_cchPos;}
  114. long GetCChLen(void* pKey) {return ((CLockInfoEntry*)pKey)->m_cchLen;}
  115. protected:
  116. CMLStr* const m_pMLStr;
  117. int m_nLockCount;
  118. CLockInfoEntry* m_pLockArray;
  119. };
  120. class CMLStrBufStandardW : public CMLStrBufW
  121. {
  122. protected:
  123. LPVOID MemAlloc(ULONG cb) {return ::CoTaskMemAlloc(cb);}
  124. LPVOID MemRealloc(LPVOID pv, ULONG cb) {return ::CoTaskMemRealloc(pv, cb);}
  125. void MemFree(LPVOID pv) {::CoTaskMemFree(pv);}
  126. long RoundBufSize(long cchStr);
  127. };
  128. #endif
  129. public:
  130. // Called from CMLStrW and CMLStrA
  131. #ifdef ASTRIMPL
  132. class CLock
  133. {
  134. public:
  135. CLock(BOOL fWrite, CMLStr* pMLStr, HRESULT& hr) : m_fWrite(fWrite), m_pMLStr(pMLStr) {m_fLocked = (SUCCEEDED(hr) && SUCCEEDED(hr = m_pMLStr->GetLockInfo()->StartLock(m_fWrite)));}
  136. ~CLock(void) {if (m_fLocked) m_pMLStr->GetLockInfo()->EndLock(m_fWrite);}
  137. HRESULT FallThrough(void) {m_fLocked = FALSE; return S_OK;} // Don't call EndLock in destructor
  138. protected:
  139. const BOOL m_fWrite;
  140. CMLStr* const m_pMLStr;
  141. BOOL m_fLocked;
  142. };
  143. #endif
  144. HRESULT PrepareMLStrBuf(void);
  145. HRESULT SetStrBufCommon(void* pMLStrX, long lDestPos, long lDestLen, UINT uCodePage, IMLangStringBufW* pSrcBufW, IMLangStringBufA* pSrcBufA, long* pcchActual, long* plActualLen);
  146. #ifdef ASTRIMPL
  147. HRESULT UnlockStrCommon(const void* pszSrc, long cchSrc, long* pcchActual, long* plActualLen);
  148. #endif
  149. HRESULT CheckThread(void) {return (m_dwThreadID == ::GetCurrentThreadId()) ? S_OK : E_FAIL;}
  150. HRESULT RegularizePosLen(long* plPos, long* plLen);
  151. HRESULT GetLen(long cchOffset, long cchLen, long* plLen);
  152. HRESULT GetCCh(long cchOffset, long lLen, long* pcchLen);
  153. static HRESULT CalcLenW(const WCHAR*, long cchLen, long* plLen) {if (plLen) *plLen = cchLen; return S_OK;}
  154. static HRESULT CalcLenA(UINT uCodePage, const CHAR*, long cchLen, long* plLen);
  155. static HRESULT CalcCChW(const WCHAR*, long lLen, long* pcchLen) {if (pcchLen) *pcchLen = lLen; return S_OK;}
  156. static HRESULT CalcCChA(UINT uCodePage, const CHAR*, long lLen, long* pcchLen);
  157. static HRESULT CalcBufSizeW(long lLen, long* pcchSize) {if (pcchSize) *pcchSize = lLen; return S_OK;}
  158. static HRESULT CalcBufSizeA(long lLen, long* pcchSize) {if (pcchSize) *pcchSize = lLen * 2; return S_OK;}
  159. static HRESULT ConvAStrToWStr(UINT uCodePage, const CHAR* pszSrc, long cchSrc, WCHAR* pszDest, long cchDest, long* pcchActualA, long* pcchActualW, long* plActualLen);
  160. static HRESULT ConvWStrToAStr(BOOL fCanStopAtMiddle, UINT uCodePage, const WCHAR* pszSrc, long cchSrc, CHAR* pszDest, long cchDest, long* pcchActualA, long* pcchActualW, long* plActualLen);
  161. IMLangStringBufW* GetMLStrBufW(void) const {return m_pMLStrBufW;}
  162. void SetMLStrBufW(IMLangStringBufW* pBuf) {m_pMLStrBufW = pBuf;}
  163. IMLangStringBufA* GetMLStrBufA(void) const {return m_pMLStrBufA;}
  164. void SetMLStrBufA(IMLangStringBufA* pBuf) {m_pMLStrBufA = pBuf;}
  165. UINT GetCodePage(void) const {return m_uCodePage;}
  166. void SetCodePage(UINT uCodePage) {m_uCodePage = uCodePage;}
  167. long GetBufFlags(void) const {return m_lBufFlags;}
  168. void SetBufFlags(long lBufFlags) {m_lBufFlags = lBufFlags;}
  169. long GetBufCCh(void) const {return m_cchBuf;}
  170. void SetBufCCh(long cchBuf) {m_cchBuf = cchBuf;}
  171. LCID GetLocale(void) const {return m_locale;}
  172. void SetLocale(LCID locale) {m_locale = locale;}
  173. #ifdef ASTRIMPL
  174. CLockInfo* GetLockInfo(void) {return &m_LockInfo;}
  175. #else
  176. BOOL IsLocked(void) const {return (m_lLockFlags != 0);}
  177. BOOL IsDirectLock(void) const {return m_fDirectLock;}
  178. void SetDirectLockFlag(BOOL fDirectLock) {m_fDirectLock = fDirectLock;}
  179. long GetLockFlags(void) const {return m_lLockFlags;}
  180. void SetLockFlags(long lFlags) {m_lLockFlags = lFlags;}
  181. #endif
  182. HRESULT MemAlloc(ULONG cb, void** ppv) {void* pv = ::CoTaskMemAlloc(cb); if (ppv) *ppv = pv; return (pv) ? S_OK : E_OUTOFMEMORY;}
  183. HRESULT MemFree(void* pv) {::CoTaskMemFree(pv); return S_OK;}
  184. #ifdef ASTRIMPL
  185. HRESULT UnlockWStrDirect(void* pKey, const void* pszSrc, long cchSrc, long* pcchActual, long* plActualLen);
  186. HRESULT UnlockWStrIndirect(void* pKey, const void* pszSrc, long cchSrc, long* pcchActual, long* plActualLen);
  187. HRESULT UnlockAStrDirect(void* pKey, const void* pszSrc, long cchSrc, long* pcchActual, long* plActualLen);
  188. HRESULT UnlockAStrIndirect(void* pKey, const void* pszSrc, long cchSrc, long* pcchActual, long* plActualLen);
  189. #endif
  190. protected:
  191. ~CMLStr(void);
  192. #ifndef ASTRIMPL
  193. static HRESULT ConvertMLStrBufAToWStr(UINT uCodePage, IMLangStringBufA* pMLStrBufA, long cchSrcPos, long cchSrcLen, WCHAR* pszBuf, long cchBuf, long* pcchActual);
  194. static HRESULT ConvertWStrToMLStrBufA(const WCHAR* pszSrc, long cchSrc, UINT uCodePage, IMLangStringBufA* pMLStrBufA, long cchDestPos, long cchDestLen);
  195. #endif
  196. DWORD m_dwThreadID;
  197. IMLangStringBufW* m_pMLStrBufW;
  198. IMLangStringBufA* m_pMLStrBufA;
  199. UINT m_uCodePage;
  200. long m_lBufFlags;
  201. long m_cchBuf;
  202. LCID m_locale;
  203. #ifdef ASTRIMPL
  204. CLockInfo m_LockInfo;
  205. #else
  206. BOOL m_fDirectLock;
  207. long m_lLockFlags;
  208. WCHAR* m_pszLockBuf;
  209. long m_cchLockPos;
  210. long m_cchLockLen;
  211. long m_lLockPos;
  212. long m_lLockLen;
  213. #endif
  214. };
  215. #endif //__MLSTR_H_
  216. #else // NEWMLSTR
  217. // MLStr.h : Declaration of the CMLStr
  218. #ifndef __MLSTR_H_
  219. #define __MLSTR_H_
  220. #include "mlstrw.h" // IMLangStringWStrImpl
  221. #include "mlstra.h" // IMLangStringAStrImpl
  222. #include "util.h"
  223. /////////////////////////////////////////////////////////////////////////////
  224. // CMLStr
  225. class ATL_NO_VTABLE CMLStr :
  226. public CComObjectRoot,
  227. public CComCoClass<CMLStr, &CLSID_CMLangString>,
  228. public IMLangString,
  229. public IMLStrAttrNotifySink,
  230. public IConnectionPointContainerImpl<CMLStr>,
  231. public IConnectionPointImpl<CMLStr, &IID_IMLangStringNotifySink>
  232. {
  233. public:
  234. CMLStr();
  235. DECLARE_NO_REGISTRY()
  236. BEGIN_COM_MAP(CMLStr)
  237. COM_INTERFACE_ENTRY(IMLangString)
  238. COM_INTERFACE_ENTRY_TEAR_OFF(IID_IMLangStringWStr, CMLStrW)
  239. COM_INTERFACE_ENTRY_TEAR_OFF(IID_IMLangStringAStr, CMLStrA)
  240. COM_INTERFACE_ENTRY(IMLStrAttrNotifySink)
  241. COM_INTERFACE_ENTRY_IMPL(IConnectionPointContainer)
  242. END_COM_MAP()
  243. BEGIN_CONNECTION_POINT_MAP(CMLStr)
  244. CONNECTION_POINT_ENTRY(IID_IMLangStringNotifySink)
  245. END_CONNECTION_POINT_MAP()
  246. public:
  247. // IMLangString
  248. STDMETHOD(LockMLStr)(/*[in]*/ long lPos, /*[in]*/ long lLen, /*[in]*/ DWORD dwFlags, /*[out]*/ DWORD* pdwCookie, /*[out]*/ long* plActualPos, /*[out]*/ long* plActualLen);
  249. STDMETHOD(UnlockMLStr)(/*[in]*/ DWORD dwCookie);
  250. STDMETHOD(GetLength)(/*[out, retval]*/ long* plLen);
  251. STDMETHOD(SetMLStr)(/*[in]*/ long lDestPos, /*[in]*/ long lDestLen, /*[in]*/ IUnknown* pSrcMLStr, /*[in]*/ long lSrcPos, /*[in]*/ long lSrcLen);
  252. STDMETHOD(RegisterAttr)(/*[in]*/ IUnknown* pUnk, /*[out]*/ DWORD* pdwCookie);
  253. STDMETHOD(UnregisterAttr)(/*[in]*/ DWORD dwCookie);
  254. STDMETHOD(EnumAttr)(/*[out]*/ IEnumUnknown** ppEnumUnk);
  255. STDMETHOD(FindAttr)(/*[in]*/ REFIID riid, /*[in]*/ LPARAM lParam, /*[out]*/ IUnknown** ppUnk);
  256. // IMLStrAttrNotifySink
  257. STDMETHOD(OnRequestEdit)(/*[in]*/ long lDestPos, /*[in]*/ long lDestLen, /*[in]*/ long lNewLen, /*[in]*/ REFIID riid, /*[in]*/ LPARAM lParam, /*[in]*/ IUnknown* pUnk);
  258. STDMETHOD(OnCanceledEdit)(/*[in]*/ long lDestPos, /*[in]*/ long lDestLen, /*[in]*/ long lNewLen, /*[in]*/ REFIID riid, /*[in]*/ LPARAM lParam, /*[in]*/ IUnknown* pUnk);
  259. STDMETHOD(OnChanged)(/*[in]*/ long lDestPos, /*[in]*/ long lDestLen, /*[in]*/ long lNewLen, /*[in]*/ REFIID riid, /*[in]*/ LPARAM lParam, /*[in]*/ IUnknown* pUnk);
  260. //---------------------------------------------------------------------------
  261. protected:
  262. struct LOCKINFO
  263. {
  264. long lPos;
  265. long lLen;
  266. DWORD dwFlags;
  267. DWORD dwThrd;
  268. };
  269. //---------------------------------------------------------------------------
  270. protected:
  271. class CLockList : public CMLListFast
  272. {
  273. protected:
  274. struct CCell : public CMLListFast::CCell
  275. {
  276. LOCKINFO m_linfo;
  277. };
  278. public:
  279. inline CLockList(void) : CMLListFast(sizeof(CCell), sizeof(CCell) * 8) {}
  280. inline HRESULT SetLock(void* pv, long lPos, long lLen, DWORD dwFlags, DWORD dwThrd)
  281. {
  282. ((CCell*)pv)->m_linfo.lPos = lPos;
  283. ((CCell*)pv)->m_linfo.lLen = lLen;
  284. ((CCell*)pv)->m_linfo.dwFlags = dwFlags;
  285. ((CCell*)pv)->m_linfo.dwThrd = dwThrd;
  286. return S_OK;
  287. }
  288. inline HRESULT GetLockInfo(void* pv, LOCKINFO** pplinfo)
  289. {
  290. *pplinfo = &((CCell*)pv)->m_linfo;
  291. return S_OK;
  292. }
  293. };
  294. //---------------------------------------------------------------------------
  295. protected:
  296. class CAttrList : public CMLListLru
  297. {
  298. protected:
  299. struct CCell : public CMLListLru::CCell
  300. {
  301. IMLStrAttr* m_pAttr;
  302. DWORD m_dwCookie;
  303. };
  304. public:
  305. inline CAttrList(void) : CMLListLru(sizeof(CCell), sizeof(CCell) * 8) {}
  306. inline IMLStrAttr* GetAttr(void* pv) {return ((CCell*)pv)->m_pAttr;}
  307. inline void SetAttr(void* pv, IMLStrAttr* pAttr) {((CCell*)pv)->m_pAttr = pAttr;}
  308. inline DWORD GetCookie(void* pv) const {return ((CCell*)pv)->m_dwCookie;}
  309. inline void SetCookie(void* pv, DWORD dwCookie) {((CCell*)pv)->m_dwCookie = dwCookie;}
  310. };
  311. //---------------------------------------------------------------------------
  312. // IEnumUnknown object for IMLangString::EnumAttr()
  313. protected:
  314. class ATL_NO_VTABLE CEnumAttr :
  315. public CComObjectRoot,
  316. public IEnumUnknown
  317. {
  318. public:
  319. CEnumAttr(void);
  320. ~CEnumAttr(void);
  321. void Init(CMLStr* pMLStr);
  322. BEGIN_COM_MAP(CEnumAttr)
  323. COM_INTERFACE_ENTRY(IEnumUnknown)
  324. END_COM_MAP()
  325. STDMETHOD(Next)(ULONG celt, IUnknown** rgelt, ULONG* pceltFetched);
  326. STDMETHOD(Skip)(ULONG celt);
  327. STDMETHOD(Reset)(void);
  328. STDMETHOD(Clone)(IEnumUnknown** ppEnum);
  329. protected:
  330. CMLStr* m_pMLStr;
  331. void* m_pv;
  332. };
  333. friend class CEnumAttr;
  334. //---------------------------------------------------------------------------
  335. // Fire notification to all of IMLangStringNotifySink advised.
  336. protected:
  337. class CFire : public CFireConnection<IMLangStringNotifySink, &IID_IMLangStringNotifySink>
  338. {
  339. public:
  340. inline CFire(HRESULT& rhr, CMLStr* const pMLStr) :
  341. CFireConnection<IMLangStringNotifySink, &IID_IMLangStringNotifySink>(rhr)
  342. {
  343. if (SUCCEEDED(*m_phr) &&
  344. FAILED(*m_phr = pMLStr->EnumConnections(&m_pEnumConn)))
  345. {
  346. m_pEnumConn = NULL;
  347. }
  348. }
  349. };
  350. //---------------------------------------------------------------------------
  351. protected:
  352. ~CMLStr(void);
  353. HRESULT CheckAccessValidation(long lPos, long lLen, DWORD dwFlags, DWORD dwThrd, long* plActualPos, long* plActualLen);
  354. inline HRESULT StartEndConnectionAttr(IUnknown* const pUnk, DWORD* const pdwCookie, DWORD dwCookie)
  355. {
  356. return ::StartEndConnection(pUnk, &IID_IMLStrAttrNotifySink, (IMLStrAttrNotifySink*)this, pdwCookie, dwCookie);
  357. }
  358. protected:
  359. long m_lLen;
  360. CLockList m_lock;
  361. CAttrList m_attr;
  362. HANDLE m_hUnlockEvent;
  363. int m_cWaitUnlock;
  364. HANDLE m_hZeroEvent;
  365. };
  366. #endif //__MLSTR_H_
  367. #endif // NEWMLSTR