Source code of Windows XP (NT5)
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.

10699 lines
239 KiB

  1. // This is a part of the Active Template Library.
  2. // Copyright (C) 1996-2001 Microsoft Corporation
  3. // All rights reserved.
  4. //
  5. // This source code is only intended as a supplement to the
  6. // Active Template Library Reference and related
  7. // electronic documentation provided with the library.
  8. // See these sources for detailed information regarding the
  9. // Active Template Library product.
  10. #ifndef __ATLBASE_H__
  11. #define __ATLBASE_H__
  12. #pragma once
  13. // Warnings outside of the push/pop sequence will be disabled for all user
  14. // projects. The only warnings that should be disabled outside the push/pop
  15. // are warnings that are a) benign and b) will show up in user projects
  16. // without being directly caused by the user
  17. #pragma warning(disable: 4505) // unreferenced local function has been removed
  18. #pragma warning(disable: 4710) // function couldn't be inlined
  19. #pragma warning(disable: 4514) // unreferenced inlines are common
  20. // These two warnings will occur in any class that contains or derives from a
  21. // class with a private copy constructor or copy assignment operator.
  22. #pragma warning(disable: 4511) // copy constructor could not be generated
  23. #pragma warning(disable: 4512) // assignment operator could not be generated
  24. #pragma warning(disable: 4355) // 'this' : used in base member initializer list
  25. #ifdef _ATL_ALL_WARNINGS
  26. #pragma warning( push )
  27. #endif
  28. #pragma warning(disable: 4127) // constant expression
  29. #pragma warning(disable: 4097) // typedef name used as synonym for class-name
  30. #pragma warning(disable: 4786) // identifier was truncated in the debug information
  31. #pragma warning(disable: 4291) // allow placement new
  32. #pragma warning(disable: 4201) // nameless unions are part of C++
  33. #pragma warning(disable: 4103) // pragma pack
  34. #pragma warning(disable: 4268) // const static/global data initialized to zeros
  35. #pragma warning (push)
  36. #ifndef __cplusplus
  37. #error ATL requires C++ compilation (use a .cpp suffix)
  38. #endif
  39. #include <atldef.h>
  40. #ifndef _WINSOCKAPI_
  41. #include <winsock2.h>
  42. #endif
  43. #include <windows.h>
  44. #include <winnls.h>
  45. #include <ole2.h>
  46. #include <oleauto.h>
  47. #include <comcat.h>
  48. #include <stddef.h>
  49. #include <winsvc.h>
  50. #include <tchar.h>
  51. #include <malloc.h>
  52. #include <limits.h>
  53. #include <errno.h>
  54. //REVIEW: Lame definition of InterlockedExchangePointer in system headers
  55. #ifdef _M_IX86
  56. #undef InterlockedExchangePointer
  57. inline void* InterlockedExchangePointer(void** pp, void* pNew) throw()
  58. {
  59. return( reinterpret_cast<void*>(static_cast<LONG_PTR>(::InterlockedExchange(reinterpret_cast<LONG*>(pp), static_cast<LONG>(reinterpret_cast<LONG_PTR>(pNew))))) );
  60. }
  61. #endif
  62. #ifndef _ATL_NO_DEBUG_CRT
  63. // Warning: if you define the above symbol, you will have
  64. // to provide your own definition of the ATLASSERT(x) macro
  65. // in order to compile ATL
  66. #include <crtdbg.h>
  67. #endif
  68. #include <olectl.h>
  69. #include <winreg.h>
  70. #include <atliface.h>
  71. #if !defined(_ATL_MIN_CRT) & defined(_MT)
  72. #include <errno.h>
  73. #include <process.h> // for _beginthreadex, _endthreadex
  74. #endif
  75. #ifdef _DEBUG
  76. #include <stdio.h>
  77. #include <stdarg.h>
  78. #endif
  79. #include <atlconv.h>
  80. #include <shlwapi.h>
  81. #include <atlsimpcoll.h>
  82. #pragma pack(push, _ATL_PACKING)
  83. #ifndef _ATL_NO_DEFAULT_LIBS
  84. #if defined(_ATL_DLL)
  85. #pragma comment(lib, "atl.lib")
  86. #endif
  87. #ifdef _DEBUG
  88. #pragma comment(lib, "atlsd.lib")
  89. #else
  90. #pragma comment(lib, "atls.lib")
  91. #ifdef _ATL_MIN_CRT
  92. #pragma comment(lib, "atlmincrt.lib")
  93. #endif
  94. #endif
  95. #endif // !_ATL_NO_DEFAULT_LIBS
  96. extern "C" const __declspec(selectany) GUID LIBID_ATLLib = {0x44EC0535,0x400F,0x11D0,{0x9D,0xCD,0x00,0xA0,0xC9,0x03,0x91,0xD3}};
  97. extern "C" const __declspec(selectany) CLSID CLSID_Registrar = {0x44EC053A,0x400F,0x11D0,{0x9D,0xCD,0x00,0xA0,0xC9,0x03,0x91,0xD3}};
  98. extern "C" const __declspec(selectany) IID IID_IRegistrar = {0x44EC053B,0x400F,0x11D0,{0x9D,0xCD,0x00,0xA0,0xC9,0x03,0x91,0xD3}};
  99. extern "C" const __declspec(selectany) IID IID_IAxWinHostWindow = {0xb6ea2050,0x048a,0x11d1,{0x82,0xb9,0x00,0xc0,0x4f,0xb9,0x94,0x2e}};
  100. extern "C" const __declspec(selectany) IID IID_IAxWinAmbientDispatch = {0xb6ea2051,0x048a,0x11d1,{0x82,0xb9,0x00,0xc0,0x4f,0xb9,0x94,0x2e}};
  101. extern "C" const __declspec(selectany) IID IID_IInternalConnection = {0x72AD0770,0x6A9F,0x11d1,{0xBC,0xEC,0x00,0x60,0x08,0x8F,0x44,0x4E}};
  102. extern "C" const __declspec(selectany) IID IID_IDocHostUIHandlerDispatch = {0x425B5AF0,0x65F1,0x11d1,{0x96,0x11,0x00,0x00,0xF8,0x1E,0x0D,0x0D}};
  103. extern "C" const __declspec(selectany) IID IID_IAxWinHostWindowLic = {0x3935BDA8,0x4ED9,0x495c,{0x86,0x50,0xE0,0x1F,0xC1,0xE3,0x8A,0x4B}};
  104. extern "C" const __declspec(selectany) IID IID_IAxWinAmbientDispatchEx = {0xB2D0778B,0xAC99,0x4c58,{0xA5,0xC8,0xE7,0x72,0x4E,0x53,0x16,0xB5}};
  105. // {B62F5910-6528-11d1-9611-0000F81E0D0D}
  106. _declspec(selectany) GUID GUID_ATLVer30 = { 0xb62f5910, 0x6528, 0x11d1, { 0x96, 0x11, 0x0, 0x0, 0xf8, 0x1e, 0xd, 0xd } };
  107. // {394C3DE0-3C6F-11d2-817B-00C04F797AB7}
  108. _declspec(selectany) GUID GUID_ATLVer70 = { 0x394c3de0, 0x3c6f, 0x11d2, { 0x81, 0x7b, 0x0, 0xc0, 0x4f, 0x79, 0x7a, 0xb7 } };
  109. // REVIEW: Temp until it gets back into UUID.LIB
  110. const __declspec(selectany) CLSID CLSID_StdGlobalInterfaceTable = {0x00000323,0x0000,0x0000,{0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46}};
  111. namespace ATL
  112. {
  113. struct _ATL_CATMAP_ENTRY
  114. {
  115. int iType;
  116. const CATID* pcatid;
  117. };
  118. #define _ATL_CATMAP_ENTRY_END 0
  119. #define _ATL_CATMAP_ENTRY_IMPLEMENTED 1
  120. #define _ATL_CATMAP_ENTRY_REQUIRED 2
  121. template <typename __OuterClass = __current_class, unsigned long __ClassOffset = __member_offset>
  122. class ContainerPair
  123. {
  124. public:
  125. typedef __OuterClass _ContainingClass;
  126. static unsigned long _GetContainerOffset()
  127. {
  128. return __ClassOffset;
  129. }
  130. };
  131. // Any contained class which wishes to access the members of its containing class can use this helper to properly
  132. // accesss the this pointer of the containing class. The contained class should derive from this.
  133. //
  134. template<typename T>
  135. class OuterClassHelper
  136. {
  137. public:
  138. __declspec(property(get=__GetOuter)) T::_ContainingClass* outer;
  139. T::_ContainingClass* __GetOuter()
  140. {
  141. return reinterpret_cast<T::_ContainingClass *>(reinterpret_cast<char *>(this) - T::_GetContainerOffset());
  142. }
  143. };
  144. typedef HRESULT (WINAPI _ATL_CREATORFUNC)(void* pv, REFIID riid, LPVOID* ppv);
  145. typedef HRESULT (WINAPI _ATL_CREATORARGFUNC)(void* pv, REFIID riid, LPVOID* ppv, DWORD_PTR dw);
  146. typedef HRESULT (WINAPI _ATL_MODULEFUNC)(DWORD_PTR dw);
  147. typedef LPCTSTR (WINAPI _ATL_DESCRIPTIONFUNC)();
  148. typedef const struct _ATL_CATMAP_ENTRY* (_ATL_CATMAPFUNC)();
  149. typedef void (__stdcall _ATL_TERMFUNC)(DWORD_PTR dw);
  150. // perfmon registration/unregistration function definitions
  151. typedef HRESULT (*_ATL_PERFREGFUNC)(HINSTANCE hDllInstance);
  152. typedef HRESULT (*_ATL_PERFUNREGFUNC)();
  153. __declspec(selectany) _ATL_PERFREGFUNC _pPerfRegFunc = NULL;
  154. __declspec(selectany) _ATL_PERFUNREGFUNC _pPerfUnRegFunc = NULL;
  155. struct _ATL_TERMFUNC_ELEM
  156. {
  157. _ATL_TERMFUNC* pFunc;
  158. DWORD_PTR dw;
  159. _ATL_TERMFUNC_ELEM* pNext;
  160. };
  161. /*
  162. struct _ATL_OBJMAP_ENTRY20
  163. {
  164. const CLSID* pclsid;
  165. HRESULT (WINAPI *pfnUpdateRegistry)(BOOL bRegister);
  166. _ATL_CREATORFUNC* pfnGetClassObject;
  167. _ATL_CREATORFUNC* pfnCreateInstance;
  168. IUnknown* pCF;
  169. DWORD dwRegister;
  170. _ATL_DESCRIPTIONFUNC* pfnGetObjectDescription;
  171. };
  172. */
  173. // Can't inherit from _ATL_OBJMAP_ENTRY20
  174. // because it messes up the OBJECT_MAP macros
  175. struct _ATL_OBJMAP_ENTRY30
  176. {
  177. const CLSID* pclsid;
  178. HRESULT (WINAPI *pfnUpdateRegistry)(BOOL bRegister);
  179. _ATL_CREATORFUNC* pfnGetClassObject;
  180. _ATL_CREATORFUNC* pfnCreateInstance;
  181. IUnknown* pCF;
  182. DWORD dwRegister;
  183. _ATL_DESCRIPTIONFUNC* pfnGetObjectDescription;
  184. _ATL_CATMAPFUNC* pfnGetCategoryMap;
  185. HRESULT WINAPI RevokeClassObject()
  186. {
  187. return CoRevokeClassObject(dwRegister);
  188. }
  189. HRESULT WINAPI RegisterClassObject(DWORD dwClsContext, DWORD dwFlags)
  190. {
  191. IUnknown* p = NULL;
  192. if (pfnGetClassObject == NULL)
  193. return S_OK;
  194. HRESULT hRes = pfnGetClassObject(pfnCreateInstance, __uuidof(IUnknown), (LPVOID*) &p);
  195. if (SUCCEEDED(hRes))
  196. hRes = CoRegisterClassObject(*pclsid, p, dwClsContext, dwFlags, &dwRegister);
  197. if (p != NULL)
  198. p->Release();
  199. return hRes;
  200. }
  201. // Added in ATL 3.0
  202. void (WINAPI *pfnObjectMain)(bool bStarting);
  203. };
  204. typedef _ATL_OBJMAP_ENTRY30 _ATL_OBJMAP_ENTRY;
  205. #if defined(_M_IA64) || defined(_M_IX86)
  206. #pragma data_seg(push)
  207. #pragma data_seg("ATL$__a")
  208. __declspec(selectany) _ATL_OBJMAP_ENTRY* __pobjMapEntryFirst = NULL;
  209. #pragma data_seg("ATL$__z")
  210. __declspec(selectany) _ATL_OBJMAP_ENTRY* __pobjMapEntryLast = NULL;
  211. #pragma data_seg("ATL$__m")
  212. #if !defined(_M_IA64)
  213. #pragma comment(linker, "/merge:ATL=.data")
  214. #endif
  215. #pragma data_seg(pop)
  216. #else
  217. //REVIEW: data_seg(push/pop)?
  218. __declspec(selectany) _ATL_OBJMAP_ENTRY* __pobjMapEntryFirst = NULL;
  219. __declspec(selectany) _ATL_OBJMAP_ENTRY* __pobjMapEntryLast = NULL;
  220. #endif // defined(_M_IA64) || defined(_M_IX86)
  221. struct _ATL_REGMAP_ENTRY
  222. {
  223. LPCOLESTR szKey;
  224. LPCOLESTR szData;
  225. };
  226. struct _AtlCreateWndData
  227. {
  228. void* m_pThis;
  229. DWORD m_dwThreadID;
  230. _AtlCreateWndData* m_pNext;
  231. };
  232. template <class T> class CSimpleArrayEqualHelper;
  233. template <class T, class TEqual = CSimpleArrayEqualHelper< T > > class CSimpleArray;
  234. /////////////////////////////////////////////////////////////////////////////
  235. // Threading Model Support
  236. class CComCriticalSection
  237. {
  238. public:
  239. CComCriticalSection() throw()
  240. {
  241. memset(&m_sec, 0, sizeof(CRITICAL_SECTION));
  242. }
  243. HRESULT Lock() throw()
  244. {
  245. HRESULT hRes = S_OK;
  246. __try
  247. {
  248. EnterCriticalSection(&m_sec);
  249. }
  250. // structured exception may be raised in low memory situations
  251. __except(EXCEPTION_EXECUTE_HANDLER)
  252. {
  253. if (STATUS_NO_MEMORY == GetExceptionCode())
  254. hRes = E_OUTOFMEMORY;
  255. else
  256. hRes = E_FAIL;
  257. }
  258. return hRes;
  259. }
  260. HRESULT Unlock() throw()
  261. {
  262. LeaveCriticalSection(&m_sec);
  263. return S_OK;
  264. }
  265. HRESULT Init() throw()
  266. {
  267. HRESULT hRes = S_OK;
  268. __try
  269. {
  270. InitializeCriticalSection(&m_sec);
  271. }
  272. // structured exception may be raised in low memory situations
  273. __except(EXCEPTION_EXECUTE_HANDLER)
  274. {
  275. if (STATUS_NO_MEMORY == GetExceptionCode())
  276. hRes = E_OUTOFMEMORY;
  277. else
  278. hRes = E_FAIL;
  279. }
  280. return hRes;
  281. }
  282. HRESULT Term() throw()
  283. {
  284. DeleteCriticalSection(&m_sec);
  285. return S_OK;
  286. }
  287. CRITICAL_SECTION m_sec;
  288. };
  289. // Module
  290. // Used by any project that uses ATL
  291. struct _ATL_BASE_MODULE70
  292. {
  293. UINT cbSize;
  294. HINSTANCE m_hInst;
  295. HINSTANCE m_hInstResource;
  296. bool m_bNT5orWin98;
  297. DWORD dwAtlBuildVer;
  298. GUID* pguidVer;
  299. CComCriticalSection m_csResource;
  300. CSimpleArray<HINSTANCE> m_rgResourceInstance;
  301. };
  302. typedef _ATL_BASE_MODULE70 _ATL_BASE_MODULE;
  303. // Used by COM related code in ATL
  304. struct _ATL_COM_MODULE70
  305. {
  306. UINT cbSize;
  307. HINSTANCE m_hInstTypeLib;
  308. _ATL_OBJMAP_ENTRY** m_ppAutoObjMapFirst;
  309. _ATL_OBJMAP_ENTRY** m_ppAutoObjMapLast;
  310. CComCriticalSection m_csObjMap;
  311. };
  312. typedef _ATL_COM_MODULE70 _ATL_COM_MODULE;
  313. // Used by Windowing code in ATL
  314. struct _ATL_WIN_MODULE70
  315. {
  316. UINT cbSize;
  317. CComCriticalSection m_csWindowCreate;
  318. _AtlCreateWndData* m_pCreateWndList;
  319. ATOM m_rgWindowClassAtoms[128];
  320. int m_nAtomIndex;
  321. };
  322. typedef _ATL_WIN_MODULE70 _ATL_WIN_MODULE;
  323. struct _ATL_MODULE70
  324. {
  325. UINT cbSize;
  326. LONG m_nLockCnt;
  327. _ATL_TERMFUNC_ELEM* m_pTermFuncs;
  328. CComCriticalSection m_csStaticDataInitAndTypeInfo;
  329. };
  330. typedef _ATL_MODULE70 _ATL_MODULE;
  331. /////////////////////////////////////////////////////////////////////////////
  332. //This define makes debugging asserts easier.
  333. #define _ATL_SIMPLEMAPENTRY ((ATL::_ATL_CREATORARGFUNC*)1)
  334. struct _ATL_INTMAP_ENTRY
  335. {
  336. const IID* piid; // the interface id (IID)
  337. DWORD_PTR dw;
  338. _ATL_CREATORARGFUNC* pFunc; //NULL:end, 1:offset, n:ptr
  339. };
  340. /////////////////////////////////////////////////////////////////////////////
  341. // Thunks for __stdcall member functions
  342. #if defined(_M_IX86)
  343. #pragma pack(push,1)
  344. struct _stdcallthunk
  345. {
  346. DWORD m_mov; // mov dword ptr [esp+0x4], pThis (esp+0x4 is hWnd)
  347. DWORD m_this; //
  348. BYTE m_jmp; // jmp WndProc
  349. DWORD m_relproc; // relative jmp
  350. void Init(DWORD_PTR proc, void* pThis)
  351. {
  352. m_mov = 0x042444C7; //C7 44 24 0C
  353. m_this = PtrToUlong(pThis);
  354. m_jmp = 0xe9;
  355. m_relproc = DWORD((INT_PTR)proc - ((INT_PTR)this+sizeof(_stdcallthunk)));
  356. // write block from data cache and
  357. // flush from instruction cache
  358. FlushInstructionCache(GetCurrentProcess(), this, sizeof(_stdcallthunk));
  359. }
  360. //some thunks will dynamically allocate the memory for the code
  361. void* GetCodeAddress()
  362. {
  363. return this;
  364. }
  365. };
  366. #pragma pack(pop)
  367. #elif defined (_M_AMD64)
  368. #pragma pack(push,2)
  369. struct _stdcallthunk
  370. {
  371. USHORT RcxMov; // mov rcx, pThis
  372. ULONG64 RcxImm; //
  373. USHORT RaxMov; // mov rax, target
  374. ULONG64 RaxImm; //
  375. USHORT RaxJmp; // jmp target
  376. void Init(DWORD_PTR proc, void *pThis)
  377. {
  378. RcxMov = 0xb948; // mov rcx, pThis
  379. RcxImm = (ULONG64)pThis; //
  380. RaxMov = 0xb848; // mov rax, target
  381. RaxImm = (ULONG64)proc; //
  382. RaxJmp = 0xe0ff; // jmp rax
  383. FlushInstructionCache(GetCurrentProcess(), this, sizeof(_stdcallthunk));
  384. }
  385. void* GetCodeAddress()
  386. {
  387. return this;
  388. }
  389. };
  390. #pragma pack(pop)
  391. #elif defined(_M_IA64)
  392. #pragma pack(push,8)
  393. #pragma section(".base", long, read, write) // Declare section to place _StdCallThunkProc in. Must be 'long'
  394. extern "C" __declspec( allocate( ".base" ) ) void* _StdCallThunkProc; // Actually, a global label exported from StdCallThunk.s
  395. struct _FuncDesc
  396. {
  397. void* pfn;
  398. void* gp;
  399. };
  400. struct _stdcallthunk
  401. {
  402. _FuncDesc m_funcdesc;
  403. void* m_pFunc;
  404. void* m_pThis;
  405. void Init(DWORD_PTR proc, void* pThis)
  406. {
  407. m_funcdesc.pfn = &_StdCallThunkProc; // Pointer to actual beginning of StdCallThunkProc
  408. m_funcdesc.gp = &m_pFunc;
  409. m_pFunc = reinterpret_cast< void* >( proc );
  410. m_pThis = pThis;
  411. ::FlushInstructionCache( GetCurrentProcess(), this, sizeof( _stdcallthunk ) );
  412. }
  413. void* GetCodeAddress()
  414. {
  415. return( &m_funcdesc );
  416. }
  417. };
  418. #pragma pack(pop)
  419. #else
  420. #error Only AMD64, IA64, and X86 supported
  421. #endif
  422. // Dynamic thunk should look something like this
  423. #if 0
  424. struct _stdcallthunk
  425. {
  426. ~_stdcallthunk()
  427. {
  428. free(p);
  429. }
  430. _stdcallthunk()
  431. {
  432. p = NULL;
  433. }
  434. void* p;
  435. void Init(DWORD proc, void* pThis)
  436. {
  437. int nLen = __getthunklen(); //this is an intrinsic provided by MSILHLP
  438. p = malloc(nLen);
  439. if (p != NULL)
  440. {
  441. __genthunk(p, proc, pThis); //this is an intrinsic provided by MSILHLP
  442. // write block from data cache and
  443. // flush from instruction cache
  444. FlushInstructionCache(GetCurrentProcess(), p, nLen);
  445. }
  446. }
  447. void* GetCodeAddress()
  448. {
  449. return p;
  450. }
  451. };
  452. #endif
  453. #if defined(_M_AMD64) || defined(_M_IX86)
  454. class CDynamicStdCallThunk
  455. {
  456. public:
  457. _stdcallthunk *pThunk;
  458. CDynamicStdCallThunk()
  459. {
  460. pThunk = NULL;
  461. }
  462. ~CDynamicStdCallThunk()
  463. {
  464. if (pThunk)
  465. HeapFree(GetProcessHeap(), 0, pThunk);
  466. }
  467. void Init(DWORD_PTR proc, void *pThis)
  468. {
  469. ATLASSERT(!pThunk);
  470. pThunk = static_cast<_stdcallthunk *>(HeapAlloc(GetProcessHeap(),
  471. HEAP_GENERATE_EXCEPTIONS, sizeof(_stdcallthunk)));
  472. ATLASSERT(pThunk);
  473. pThunk->Init(proc, pThis);
  474. }
  475. void* GetCodeAddress()
  476. {
  477. ATLASSERT(pThunk);
  478. return pThunk->GetCodeAddress();
  479. }
  480. };
  481. typedef CDynamicStdCallThunk CStdCallThunk;
  482. #else
  483. typedef _stdcallthunk CStdCallThunk;
  484. #endif // _M_IX86
  485. /////////////////////////////////////////////////////////////////////////////
  486. // QI Support
  487. ATLAPI AtlInternalQueryInterface(void* pThis,
  488. const _ATL_INTMAP_ENTRY* pEntries, REFIID iid, void** ppvObject);
  489. /////////////////////////////////////////////////////////////////////////////
  490. // Smart Pointer helpers
  491. ATLAPI_(IUnknown*) AtlComPtrAssign(IUnknown** pp, IUnknown* lp);
  492. ATLAPI_(IUnknown*) AtlComQIPtrAssign(IUnknown** pp, IUnknown* lp, REFIID riid);
  493. /////////////////////////////////////////////////////////////////////////////
  494. // Inproc Marshaling helpers
  495. ATLAPI AtlFreeMarshalStream(IStream* pStream);
  496. ATLAPI AtlMarshalPtrInProc(IUnknown* pUnk, const IID& iid, IStream** ppStream);
  497. ATLAPI AtlUnmarshalPtr(IStream* pStream, const IID& iid, IUnknown** ppUnk);
  498. ATLAPI_(BOOL) AtlWaitWithMessageLoop(HANDLE hEvent);
  499. /////////////////////////////////////////////////////////////////////////////
  500. // Connection Point Helpers
  501. ATLAPI AtlAdvise(IUnknown* pUnkCP, IUnknown* pUnk, const IID& iid, LPDWORD pdw);
  502. ATLAPI AtlUnadvise(IUnknown* pUnkCP, const IID& iid, DWORD dw);
  503. /////////////////////////////////////////////////////////////////////////////
  504. // IDispatch Error handling
  505. ATLAPI AtlSetErrorInfo(const CLSID& clsid, LPCOLESTR lpszDesc,
  506. DWORD dwHelpID, LPCOLESTR lpszHelpFile, const IID& iid, HRESULT hRes,
  507. HINSTANCE hInst);
  508. /////////////////////////////////////////////////////////////////////////////
  509. // Module
  510. ATLAPI AtlComModuleRegisterClassObjects(_ATL_COM_MODULE* pComModule, DWORD dwClsContext, DWORD dwFlags);
  511. ATLAPI AtlComModuleRevokeClassObjects(_ATL_COM_MODULE* pComModule);
  512. ATLAPI AtlComModuleGetClassObject(_ATL_COM_MODULE* pComModule, REFCLSID rclsid, REFIID riid, LPVOID* ppv);
  513. ATLAPI AtlComModuleRegisterServer(_ATL_COM_MODULE* pComModule, BOOL bRegTypeLib, const CLSID* pCLSID = NULL);
  514. ATLAPI AtlComModuleUnregisterServer(_ATL_COM_MODULE* pComModule, BOOL bUnRegTypeLib, const CLSID* pCLSID = NULL);
  515. ATLAPI AtlRegisterClassCategoriesHelper( REFCLSID clsid, const struct _ATL_CATMAP_ENTRY* pCatMap, BOOL bRegister );
  516. ATLAPI AtlUpdateRegistryFromResourceD(HINSTANCE hInst, LPCOLESTR lpszRes,
  517. BOOL bRegister, struct _ATL_REGMAP_ENTRY* pMapEntries, IRegistrar* pReg = NULL);
  518. ATLAPI AtlRegisterTypeLib(HINSTANCE hInstTypeLib, LPCOLESTR lpszIndex);
  519. ATLAPI AtlUnRegisterTypeLib(HINSTANCE hInstTypeLib, LPCOLESTR lpszIndex);
  520. ATLAPI AtlLoadTypeLib(HINSTANCE hInstTypeLib, LPCOLESTR lpszIndex, BSTR* pbstrPath, ITypeLib** ppTypeLib);
  521. #if defined(_ATL_DLL) || defined(_ATL_DLL_IMPL)
  522. ATLAPI AtlCreateRegistrar(IRegistrar** ppReg);
  523. #endif
  524. ATLAPI_(DWORD) AtlGetVersion(void* pReserved);
  525. ATLAPI AtlModuleAddTermFunc(_ATL_MODULE* pModule, _ATL_TERMFUNC* pFunc, DWORD_PTR dw);
  526. ATLAPI_(void) AtlCallTermFunc(_ATL_MODULE* pModule);
  527. ATLAPI AtlWinModuleInit(_ATL_WIN_MODULE* pWinModule);
  528. ATLAPI AtlWinModuleTerm(_ATL_WIN_MODULE* pWinModule, HINSTANCE hInst);
  529. ATLAPI_(void) AtlWinModuleAddCreateWndData(_ATL_WIN_MODULE* pWinModule, _AtlCreateWndData* pData, void* pObject);
  530. ATLAPI_(void*) AtlWinModuleExtractCreateWndData(_ATL_WIN_MODULE* pWinModule);
  531. }; //namespace ATL
  532. /////////////////////////////////////////////////////////////////////////////
  533. // GUID comparison
  534. #include <atltrace.h>
  535. namespace ATL
  536. {
  537. inline BOOL InlineIsEqualUnknown(REFGUID rguid1)
  538. {
  539. return (
  540. ((PLONG) &rguid1)[0] == 0 &&
  541. ((PLONG) &rguid1)[1] == 0 &&
  542. #ifdef _ATL_BYTESWAP
  543. ((PLONG) &rguid1)[2] == 0xC0000000 &&
  544. ((PLONG) &rguid1)[3] == 0x00000046);
  545. #else
  546. ((PLONG) &rguid1)[2] == 0x000000C0 &&
  547. ((PLONG) &rguid1)[3] == 0x46000000);
  548. #endif
  549. }
  550. // Verify that a null-terminated string points to valid memory
  551. inline BOOL AtlIsValidString(LPCWSTR psz, size_t nMaxLength = INT_MAX)
  552. {
  553. // Implement ourselves because ::IsBadStringPtrW() isn't implemented on Win9x.
  554. if ((psz == NULL) || (nMaxLength == 0))
  555. return FALSE;
  556. LPCWSTR pch;
  557. LPCWSTR pchEnd;
  558. __try
  559. {
  560. wchar_t ch;
  561. pch = psz;
  562. pchEnd = psz+nMaxLength-1;
  563. ch = *(volatile wchar_t*)pch;
  564. while ((ch != L'\0') && (pch != pchEnd))
  565. {
  566. pch++;
  567. ch = *(volatile wchar_t*)pch;
  568. }
  569. }
  570. __except (EXCEPTION_EXECUTE_HANDLER)
  571. {
  572. return FALSE;
  573. }
  574. return TRUE;
  575. }
  576. // Verify that a null-terminated string points to valid memory
  577. inline BOOL AtlIsValidString(LPCSTR psz, size_t nMaxLength = UINT_MAX)
  578. {
  579. if (psz == NULL)
  580. return FALSE;
  581. return ::IsBadStringPtrA(psz, nMaxLength) == 0;
  582. }
  583. // Verify that a pointer points to valid memory
  584. inline BOOL AtlIsValidAddress(const void* p, size_t nBytes,
  585. BOOL bReadWrite = TRUE)
  586. {
  587. return ((p != NULL) && !IsBadReadPtr(p, nBytes) &&
  588. (!bReadWrite || !IsBadWritePtr(const_cast<LPVOID>(p), nBytes)));
  589. }
  590. template<typename T>
  591. inline void AtlAssertValidObject(const T *pOb)
  592. {
  593. ATLASSERT(pOb);
  594. ATLASSERT(AtlIsValidAddress(pOb, sizeof(T)));
  595. if(pOb)
  596. pOb->AssertValid();
  597. }
  598. #ifdef _DEBUG
  599. #define ATLASSERT_VALID(x) ATL::AtlAssertValidObject(x)
  600. #else
  601. #define ATLASSERT_VALID(x) __noop;
  602. #endif
  603. }; // namespace ATL
  604. namespace ATL
  605. {
  606. template <class T>
  607. LPCTSTR AtlDebugGetClassName(T*)
  608. {
  609. #ifdef _DEBUG
  610. const _ATL_INTMAP_ENTRY* pEntries = T::_GetEntries();
  611. return (LPCTSTR)pEntries[-1].dw;
  612. #else
  613. return NULL;
  614. #endif
  615. }
  616. ATL_NOINLINE inline HRESULT AtlHresultFromLastError() throw()
  617. {
  618. DWORD dwErr = ::GetLastError();
  619. return HRESULT_FROM_WIN32(dwErr);
  620. }
  621. ATL_NOINLINE inline HRESULT AtlHresultFromWin32(DWORD nError) throw()
  622. {
  623. return( HRESULT_FROM_WIN32( nError ) );
  624. }
  625. }; // namespace ATL
  626. #include <atlexcept.h>
  627. namespace ATL
  628. {
  629. /////////////////////////////////////////////////////////////////////////////
  630. // Win32 libraries
  631. #ifndef _ATL_NO_DEFAULT_LIBS
  632. #pragma comment(lib, "kernel32.lib")
  633. #pragma comment(lib, "user32.lib")
  634. #pragma comment(lib, "olepro32.lib")
  635. #pragma comment(lib, "advapi32.lib")
  636. #pragma comment(lib, "ole32.lib")
  637. #pragma comment(lib, "shell32.lib")
  638. #pragma comment(lib, "oleaut32.lib")
  639. #pragma comment(lib, "uuid.lib")
  640. #pragma comment(lib, "shlwapi.lib")
  641. #endif // !_ATL_NO_DEFAULT_LIBS
  642. #if !defined(_ATL_MIN_CRT) && defined(_MT)
  643. // CRTThreadTraits
  644. // This class is for use with CThreadPool or CWorkerThread
  645. // It should be used if the worker class will use CRT
  646. // functions.
  647. class CRTThreadTraits
  648. {
  649. public:
  650. static HANDLE CreateThread(LPSECURITY_ATTRIBUTES lpsa, DWORD dwStackSize, LPTHREAD_START_ROUTINE pfnThreadProc, void *pvParam, DWORD dwCreationFlags, DWORD *pdwThreadId) throw()
  651. {
  652. ATLASSERT(sizeof(DWORD) == sizeof(unsigned int)); // sanity check for pdwThreadId
  653. // _beginthreadex calls CreateThread which will set the last error value before it returns.
  654. return (HANDLE) _beginthreadex(lpsa, dwStackSize, (unsigned int (__stdcall *)(void *)) pfnThreadProc, pvParam, dwCreationFlags, (unsigned int *) pdwThreadId);
  655. }
  656. };
  657. #endif
  658. // Win32ThreadTraits
  659. // This class is for use with CThreadPool or CWorkerThread
  660. // It should be used if the worker class will not use CRT
  661. // functions.
  662. class Win32ThreadTraits
  663. {
  664. public:
  665. static HANDLE CreateThread(LPSECURITY_ATTRIBUTES lpsa, DWORD dwStackSize, LPTHREAD_START_ROUTINE pfnThreadProc, void *pvParam, DWORD dwCreationFlags, DWORD *pdwThreadId) throw()
  666. {
  667. return ::CreateThread(lpsa, dwStackSize, pfnThreadProc, pvParam, dwCreationFlags, pdwThreadId);
  668. }
  669. };
  670. #if !defined(_ATL_MIN_CRT) && defined(_MT)
  671. typedef CRTThreadTraits DefaultThreadTraits;
  672. #else
  673. typedef Win32ThreadTraits DefaultThreadTraits;
  674. #endif
  675. template <typename T>
  676. HANDLE CreateThreadT(LPSECURITY_ATTRIBUTES lpsa, DWORD dwStackSize, DWORD (WINAPI * pfn)(T *pparam),
  677. T *pparam, DWORD dwCreationFlags, LPDWORD pdw)
  678. {
  679. return DefaultThreadTraits::CreateThread(lpsa,
  680. dwStackSize,
  681. (LPTHREAD_START_ROUTINE)pfn,
  682. pparam,
  683. dwCreationFlags,
  684. pdw);
  685. }
  686. template <typename T>
  687. HANDLE AtlCreateThread(DWORD (WINAPI* pfn)(T *pparam), T *pparam)
  688. {
  689. return CreateThreadT(0, 0, pfn, pparam, 0, 0);
  690. }
  691. inline HRESULT AtlSetChildSite(IUnknown* punkChild, IUnknown* punkParent)
  692. {
  693. if (punkChild == NULL)
  694. return E_POINTER;
  695. HRESULT hr;
  696. IObjectWithSite* pChildSite = NULL;
  697. hr = punkChild->QueryInterface(__uuidof(IObjectWithSite), (void**)&pChildSite);
  698. if (SUCCEEDED(hr) && pChildSite != NULL)
  699. {
  700. hr = pChildSite->SetSite(punkParent);
  701. pChildSite->Release();
  702. }
  703. return hr;
  704. }
  705. #pragma warning(push)
  706. #pragma warning(disable: 4200)
  707. struct ATLSTRINGRESOURCEIMAGE
  708. {
  709. WORD nLength;
  710. WCHAR achString[];
  711. };
  712. #pragma warning(pop)
  713. inline const ATLSTRINGRESOURCEIMAGE* _AtlGetStringResourceImage( HINSTANCE hInstance, HRSRC hResource, UINT id )
  714. {
  715. const ATLSTRINGRESOURCEIMAGE* pImage;
  716. const ATLSTRINGRESOURCEIMAGE* pImageEnd;
  717. ULONG nResourceSize;
  718. HGLOBAL hGlobal;
  719. UINT iIndex;
  720. hGlobal = ::LoadResource( hInstance, hResource );
  721. if( hGlobal == NULL )
  722. {
  723. return( NULL );
  724. }
  725. pImage = (const ATLSTRINGRESOURCEIMAGE*)::LockResource( hGlobal );
  726. if( pImage == NULL )
  727. {
  728. return( NULL );
  729. }
  730. nResourceSize = ::SizeofResource( hInstance, hResource );
  731. pImageEnd = (const ATLSTRINGRESOURCEIMAGE*)(LPBYTE( pImage )+nResourceSize);
  732. iIndex = id&0x000f;
  733. while( (iIndex > 0) && (pImage < pImageEnd) )
  734. {
  735. pImage = (const ATLSTRINGRESOURCEIMAGE*)(LPBYTE( pImage )+(sizeof( ATLSTRINGRESOURCEIMAGE )+(pImage->nLength*sizeof( WCHAR ))));
  736. iIndex--;
  737. }
  738. if( pImage >= pImageEnd )
  739. {
  740. return( NULL );
  741. }
  742. if( pImage->nLength == 0 )
  743. {
  744. return( NULL );
  745. }
  746. return( pImage );
  747. }
  748. inline const ATLSTRINGRESOURCEIMAGE* AtlGetStringResourceImage( HINSTANCE hInstance, UINT id )
  749. {
  750. HRSRC hResource;
  751. hResource = ::FindResource( hInstance, MAKEINTRESOURCE( ((id>>4)+1) ), RT_STRING );
  752. if( hResource == NULL )
  753. {
  754. return( NULL );
  755. }
  756. return _AtlGetStringResourceImage( hInstance, hResource, id );
  757. }
  758. inline const ATLSTRINGRESOURCEIMAGE* AtlGetStringResourceImage( HINSTANCE hInstance, UINT id, WORD wLanguage )
  759. {
  760. HRSRC hResource;
  761. hResource = ::FindResourceEx( hInstance, RT_STRING, MAKEINTRESOURCE( ((id>>4)+1) ), wLanguage );
  762. if( hResource == NULL )
  763. {
  764. return( NULL );
  765. }
  766. return _AtlGetStringResourceImage( hInstance, hResource, id );
  767. }
  768. template <class T>
  769. class _NoAddRefReleaseOnCComPtr : public T
  770. {
  771. private:
  772. STDMETHOD_(ULONG, AddRef)()=0;
  773. STDMETHOD_(ULONG, Release)()=0;
  774. };
  775. template< typename T >
  776. class CAutoVectorPtr
  777. {
  778. public:
  779. CAutoVectorPtr() throw() :
  780. m_p( NULL )
  781. {
  782. }
  783. CAutoVectorPtr( CAutoVectorPtr< T >& p ) throw()
  784. {
  785. m_p = p.Detach(); // Transfer ownership
  786. }
  787. explicit CAutoVectorPtr( T* p ) throw() :
  788. m_p( p )
  789. {
  790. }
  791. ~CAutoVectorPtr() throw()
  792. {
  793. Free();
  794. }
  795. operator T*() const throw()
  796. {
  797. return( m_p );
  798. }
  799. CAutoVectorPtr< T >& operator=( CAutoVectorPtr< T >& p ) throw()
  800. {
  801. Free();
  802. Attach( p.Detach() ); // Transfer ownership
  803. return( *this );
  804. }
  805. // Allocate the vector
  806. bool Allocate( size_t nElements ) throw()
  807. {
  808. ATLASSERT( m_p == NULL );
  809. ATLTRY( m_p = new T[nElements] );
  810. if( m_p == NULL )
  811. {
  812. return( false );
  813. }
  814. return( true );
  815. }
  816. // Attach to an existing pointer (takes ownership)
  817. void Attach( T* p ) throw()
  818. {
  819. ATLASSERT( m_p == NULL );
  820. m_p = p;
  821. }
  822. // Detach the pointer (releases ownership)
  823. T* Detach() throw()
  824. {
  825. T* p;
  826. p = m_p;
  827. m_p = NULL;
  828. return( p );
  829. }
  830. // Delete the vector pointed to, and set the pointer to NULL
  831. void Free() throw()
  832. {
  833. delete[] m_p;
  834. m_p = NULL;
  835. }
  836. public:
  837. T* m_p;
  838. };
  839. template< typename T >
  840. class CAutoPtr
  841. {
  842. public:
  843. CAutoPtr() throw() :
  844. m_p( NULL )
  845. {
  846. }
  847. template< typename TSrc >
  848. CAutoPtr( CAutoPtr< TSrc >& p ) throw()
  849. {
  850. m_p = p.Detach(); // Transfer ownership
  851. }
  852. template<>
  853. CAutoPtr( CAutoPtr< T >& p ) throw()
  854. {
  855. m_p = p.Detach(); // Transfer ownership
  856. }
  857. explicit CAutoPtr( T* p ) throw() :
  858. m_p( p )
  859. {
  860. }
  861. ~CAutoPtr() throw()
  862. {
  863. Free();
  864. }
  865. // Templated version to allow pBase = pDerived
  866. template< typename TSrc >
  867. CAutoPtr< T >& operator=( CAutoPtr< TSrc >& p ) throw()
  868. {
  869. Free();
  870. Attach( p.Detach() ); // Transfer ownership
  871. return( *this );
  872. }
  873. template<>
  874. CAutoPtr< T >& operator=( CAutoPtr< T >& p ) throw()
  875. {
  876. Free();
  877. Attach( p.Detach() ); // Transfer ownership
  878. return( *this );
  879. }
  880. operator T*() const throw()
  881. {
  882. return( m_p );
  883. }
  884. T* operator->() const throw()
  885. {
  886. ATLASSERT( m_p != NULL );
  887. return( m_p );
  888. }
  889. // Attach to an existing pointer (takes ownership)
  890. void Attach( T* p ) throw()
  891. {
  892. ATLASSERT( m_p == NULL );
  893. m_p = p;
  894. }
  895. // Detach the pointer (releases ownership)
  896. T* Detach() throw()
  897. {
  898. T* p;
  899. p = m_p;
  900. m_p = NULL;
  901. return( p );
  902. }
  903. // Delete the object pointed to, and set the pointer to NULL
  904. void Free() throw()
  905. {
  906. delete m_p;
  907. m_p = NULL;
  908. }
  909. public:
  910. T* m_p;
  911. };
  912. // static_cast_auto template functions. Used like static_cast, only they work on CAutoPtr objects
  913. template< class Dest, class Src >
  914. CAutoPtr< Dest >& static_cast_auto( CAutoPtr< Src >& pSrc ) throw()
  915. {
  916. Dest* pTempDest;
  917. pTempDest = static_cast< Dest* >( static_cast< Src* >( pSrc ) ); // Just to make sure you can cast from Src* to Dest*
  918. //REVIEW: this won't work if static_cast changes the pointer value
  919. ATLASSERT( reinterpret_cast< void* >( pTempDest ) == reinterpret_cast< void* >( pSrc.m_p ) );
  920. return( reinterpret_cast< CAutoPtr< Dest >& >( pSrc ) );
  921. }
  922. template< class Dest, class Src >
  923. Dest* static_cast_auto( const CAutoPtr< Src >& pSrc ) throw()
  924. {
  925. return( static_cast< Dest* >( static_cast< Src* >( pSrc ) ) );
  926. }
  927. class CCRTAllocator
  928. {
  929. public:
  930. static void* Reallocate(void* p, size_t nBytes) throw()
  931. {
  932. return realloc(p, nBytes);
  933. }
  934. static void* Allocate(size_t nBytes) throw()
  935. {
  936. return malloc(nBytes);
  937. }
  938. static void Free(void* p) throw()
  939. {
  940. free(p);
  941. }
  942. };
  943. class CComAllocator
  944. {
  945. public:
  946. static void* Reallocate(void* p, size_t nBytes) throw()
  947. {
  948. #ifdef _WIN64
  949. if( nBytes > INT_MAX )
  950. {
  951. return( NULL );
  952. }
  953. #endif
  954. return ::CoTaskMemRealloc(p, ULONG(nBytes));
  955. }
  956. static void* Allocate(size_t nBytes) throw()
  957. {
  958. #ifdef _WIN64
  959. if( nBytes > INT_MAX )
  960. {
  961. return( NULL );
  962. }
  963. #endif
  964. return ::CoTaskMemAlloc(ULONG(nBytes));
  965. }
  966. static void Free(void* p) throw()
  967. {
  968. ::CoTaskMemFree(p);
  969. }
  970. };
  971. class CLocalAllocator
  972. {
  973. public:
  974. static void* Allocate(size_t nBytes) throw()
  975. {
  976. return ::LocalAlloc(LMEM_FIXED, nBytes);
  977. }
  978. static void* Reallocate(void* p, size_t nBytes) throw()
  979. {
  980. return ::LocalReAlloc(p, nBytes, 0);
  981. }
  982. static void Free(void* p) throw()
  983. {
  984. ::LocalFree(p);
  985. }
  986. };
  987. class CGlobalAllocator
  988. {
  989. public:
  990. static void* Allocate(size_t nBytes) throw()
  991. {
  992. return ::GlobalAlloc(GMEM_FIXED, nBytes);
  993. }
  994. static void* Reallocate(void* p, size_t nBytes) throw()
  995. {
  996. return ::GlobalReAlloc(p, nBytes, 0);
  997. }
  998. static void Free(void* p) throw()
  999. {
  1000. ::GlobalFree(p);
  1001. }
  1002. };
  1003. template <class T, class Allocator = CCRTAllocator>
  1004. class CHeapPtrBase
  1005. {
  1006. protected:
  1007. CHeapPtrBase() throw() :
  1008. m_pData(NULL)
  1009. {
  1010. }
  1011. CHeapPtrBase(CHeapPtrBase<T, Allocator>& p) throw()
  1012. {
  1013. m_pData = p.Detach(); // Transfer ownership
  1014. }
  1015. explicit CHeapPtrBase(T* pData) throw() :
  1016. m_pData(pData)
  1017. {
  1018. }
  1019. public:
  1020. ~CHeapPtrBase() throw()
  1021. {
  1022. Free();
  1023. }
  1024. protected:
  1025. CHeapPtrBase<T, Allocator>& operator=(CHeapPtrBase<T, Allocator>& p) throw()
  1026. {
  1027. Free();
  1028. Attach(p.Detach()); // Transfer ownership
  1029. return *this;
  1030. }
  1031. public:
  1032. operator T*() const throw()
  1033. {
  1034. return m_pData;
  1035. }
  1036. T* operator->() const throw()
  1037. {
  1038. ATLASSERT(m_pData != NULL);
  1039. return m_pData;
  1040. }
  1041. T** operator&() throw()
  1042. {
  1043. ATLASSERT(m_pData == NULL);
  1044. return &m_pData;
  1045. }
  1046. // Allocate a buffer with the given number of bytes
  1047. bool AllocateBytes(size_t nBytes) throw()
  1048. {
  1049. ATLASSERT(m_pData == NULL);
  1050. m_pData = static_cast<T*>(Allocator::Allocate(nBytes));
  1051. if (m_pData == NULL)
  1052. return false;
  1053. return true;
  1054. }
  1055. // Attach to an existing pointer (takes ownership)
  1056. void Attach(T* pData) throw()
  1057. {
  1058. ATLASSERT(m_pData == NULL);
  1059. Allocator::Free(m_pData);
  1060. m_pData = pData;
  1061. }
  1062. // Detach the pointer (releases ownership)
  1063. T* Detach() throw()
  1064. {
  1065. T* pTemp = m_pData;
  1066. m_pData = NULL;
  1067. return pTemp;
  1068. }
  1069. // Free the memory pointed to, and set the pointer to NULL
  1070. void Free() throw()
  1071. {
  1072. Allocator::Free(m_pData);
  1073. m_pData = NULL;
  1074. }
  1075. // Reallocate the buffer to hold a given number of bytes
  1076. bool ReallocateBytes(size_t nBytes) throw()
  1077. {
  1078. T* pNew;
  1079. pNew = static_cast<T*>(Allocator::Reallocate(m_pData, nBytes));
  1080. if (pNew == NULL)
  1081. return false;
  1082. m_pData = pNew;
  1083. return true;
  1084. }
  1085. public:
  1086. T* m_pData;
  1087. };
  1088. template <typename T, class Allocator = CCRTAllocator>
  1089. class CHeapPtr :
  1090. public CHeapPtrBase<T, Allocator>
  1091. {
  1092. public:
  1093. CHeapPtr() throw()
  1094. {
  1095. }
  1096. CHeapPtr(CHeapPtr<T, Allocator>& p) throw() :
  1097. CHeapPtrBase<T, Allocator>(p)
  1098. {
  1099. }
  1100. explicit CHeapPtr(T* p) throw() :
  1101. CHeapPtrBase<T, Allocator>(p)
  1102. {
  1103. }
  1104. CHeapPtr<T, Allocator>& operator=(CHeapPtr<T, Allocator>& p) throw()
  1105. {
  1106. CHeapPtrBase<T, Allocator>::operator=(p);
  1107. return *this;
  1108. }
  1109. // Allocate a buffer with the given number of elements
  1110. bool Allocate(size_t nElements = 1) throw()
  1111. {
  1112. return AllocateBytes(nElements*sizeof(T));
  1113. }
  1114. // Reallocate the buffer to hold a given number of elements
  1115. bool Reallocate(size_t nElements) throw()
  1116. {
  1117. return ReallocateBytes(nElements*sizeof(T));
  1118. }
  1119. };
  1120. template <typename T>
  1121. class CComHeapPtr :
  1122. public CHeapPtr<T, CComAllocator>
  1123. {
  1124. public:
  1125. CComHeapPtr() throw()
  1126. {
  1127. }
  1128. explicit CComHeapPtr(T* pData) throw() :
  1129. CHeapPtr<T, CComAllocator>(pData)
  1130. {
  1131. }
  1132. };
  1133. template< typename T, int t_nFixedBytes = 128, class Allocator = CCRTAllocator >
  1134. class CTempBuffer
  1135. {
  1136. public:
  1137. CTempBuffer() throw() :
  1138. m_p( NULL )
  1139. {
  1140. }
  1141. CTempBuffer( size_t nElements ) throw( ... ) :
  1142. m_p( NULL )
  1143. {
  1144. Allocate( nElements );
  1145. }
  1146. ~CTempBuffer() throw()
  1147. {
  1148. if( m_p != reinterpret_cast< T* >( m_abFixedBuffer ) )
  1149. {
  1150. FreeHeap();
  1151. }
  1152. }
  1153. operator T*() const throw()
  1154. {
  1155. return( m_p );
  1156. }
  1157. T* operator->() const throw()
  1158. {
  1159. ATLASSERT( m_p != NULL );
  1160. return( m_p );
  1161. }
  1162. T* Allocate( size_t nElements ) throw( ... )
  1163. {
  1164. return( AllocateBytes( nElements*sizeof( T ) ) );
  1165. }
  1166. T* Reallocate( size_t nNewSize ) throw( ... )
  1167. {
  1168. if (m_p == NULL)
  1169. return AllocateBytes(nNewSize);
  1170. if (nNewSize > t_nFixedBytes)
  1171. {
  1172. if( m_p == reinterpret_cast< T* >( m_abFixedBuffer ) )
  1173. {
  1174. // We have to allocate from the heap and copy the contents into the new buffer
  1175. AllocateHeap(nNewSize);
  1176. memcpy(m_p, m_abFixedBuffer, t_nFixedBytes);
  1177. }
  1178. else
  1179. {
  1180. ReAllocateHeap( nNewSize );
  1181. }
  1182. }
  1183. else
  1184. {
  1185. m_p = reinterpret_cast< T* >( m_abFixedBuffer );
  1186. }
  1187. return m_p;
  1188. }
  1189. T* AllocateBytes( size_t nBytes )
  1190. {
  1191. ATLASSERT( m_p == NULL );
  1192. if( nBytes > t_nFixedBytes )
  1193. {
  1194. AllocateHeap( nBytes );
  1195. }
  1196. else
  1197. {
  1198. m_p = reinterpret_cast< T* >( m_abFixedBuffer );
  1199. }
  1200. return( m_p );
  1201. }
  1202. private:
  1203. ATL_NOINLINE void AllocateHeap( size_t nBytes )
  1204. {
  1205. T* p = static_cast< T* >( Allocator::Allocate( nBytes ) );
  1206. if( p == NULL )
  1207. {
  1208. AtlThrow( E_OUTOFMEMORY );
  1209. }
  1210. m_p = p;
  1211. }
  1212. ATL_NOINLINE void ReAllocateHeap( size_t nNewSize)
  1213. {
  1214. T* p = static_cast< T* >( Allocator::Reallocate(m_p, nNewSize) );
  1215. if ( p == NULL )
  1216. {
  1217. AtlThrow( E_OUTOFMEMORY );
  1218. }
  1219. m_p = p;
  1220. }
  1221. ATL_NOINLINE void FreeHeap() throw()
  1222. {
  1223. Allocator::Free( m_p );
  1224. }
  1225. private:
  1226. T* m_p;
  1227. BYTE m_abFixedBuffer[t_nFixedBytes];
  1228. };
  1229. template <class T, class Reallocator>
  1230. T* AtlSafeRealloc(T* pT, size_t cEls) throw()
  1231. {
  1232. T* pTemp;
  1233. pTemp = static_cast<T*>(Reallocator::Reallocate(pT, cEls*sizeof(T)));
  1234. if (pTemp == NULL)
  1235. {
  1236. Reallocator::Free(pT);
  1237. return NULL;
  1238. }
  1239. pT = pTemp;
  1240. return pTemp;
  1241. }
  1242. //CComPtrBase provides the basis for all other smart pointers
  1243. //The other smartpointers add their own constructors and operators
  1244. template <class T>
  1245. class CComPtrBase
  1246. {
  1247. protected:
  1248. CComPtrBase() throw()
  1249. {
  1250. p = NULL;
  1251. }
  1252. CComPtrBase(int nNull) throw()
  1253. {
  1254. ATLASSERT(nNull == 0);
  1255. (void)nNull;
  1256. p = NULL;
  1257. }
  1258. CComPtrBase(T* lp) throw()
  1259. {
  1260. p = lp;
  1261. if (p != NULL)
  1262. p->AddRef();
  1263. }
  1264. public:
  1265. typedef T _PtrClass;
  1266. ~CComPtrBase() throw()
  1267. {
  1268. if (p)
  1269. p->Release();
  1270. }
  1271. operator T*() const throw()
  1272. {
  1273. return p;
  1274. }
  1275. T& operator*() const throw()
  1276. {
  1277. ATLASSERT(p!=NULL);
  1278. return *p;
  1279. }
  1280. //The assert on operator& usually indicates a bug. If this is really
  1281. //what is needed, however, take the address of the p member explicitly.
  1282. T** operator&() throw()
  1283. {
  1284. ATLASSERT(p==NULL);
  1285. return &p;
  1286. }
  1287. _NoAddRefReleaseOnCComPtr<T>* operator->() const throw()
  1288. {
  1289. ATLASSERT(p!=NULL);
  1290. return (_NoAddRefReleaseOnCComPtr<T>*)p;
  1291. }
  1292. bool operator!() const throw()
  1293. {
  1294. return (p == NULL);
  1295. }
  1296. bool operator<(T* pT) const throw()
  1297. {
  1298. return p < pT;
  1299. }
  1300. bool operator==(T* pT) const throw()
  1301. {
  1302. return p == pT;
  1303. }
  1304. // Release the interface and set to NULL
  1305. void Release() throw()
  1306. {
  1307. T* pTemp = p;
  1308. if (pTemp)
  1309. {
  1310. p = NULL;
  1311. pTemp->Release();
  1312. }
  1313. }
  1314. // Compare two objects for equivalence
  1315. bool IsEqualObject(IUnknown* pOther) throw()
  1316. {
  1317. if (p == pOther)
  1318. return true;
  1319. if (p == NULL || pOther == NULL)
  1320. return false; // One is NULL the other is not
  1321. CComPtr<IUnknown> punk1;
  1322. CComPtr<IUnknown> punk2;
  1323. p->QueryInterface(__uuidof(IUnknown), (void**)&punk1);
  1324. pOther->QueryInterface(__uuidof(IUnknown), (void**)&punk2);
  1325. return punk1 == punk2;
  1326. }
  1327. // Attach to an existing interface (does not AddRef)
  1328. void Attach(T* p2) throw()
  1329. {
  1330. if (p)
  1331. p->Release();
  1332. p = p2;
  1333. }
  1334. // Detach the interface (does not Release)
  1335. T* Detach() throw()
  1336. {
  1337. T* pt = p;
  1338. p = NULL;
  1339. return pt;
  1340. }
  1341. HRESULT CopyTo(T** ppT) throw()
  1342. {
  1343. ATLASSERT(ppT != NULL);
  1344. if (ppT == NULL)
  1345. return E_POINTER;
  1346. *ppT = p;
  1347. if (p)
  1348. p->AddRef();
  1349. return S_OK;
  1350. }
  1351. HRESULT SetSite(IUnknown* punkParent) throw()
  1352. {
  1353. return AtlSetChildSite(p, punkParent);
  1354. }
  1355. HRESULT Advise(IUnknown* pUnk, const IID& iid, LPDWORD pdw) throw()
  1356. {
  1357. return AtlAdvise(p, pUnk, iid, pdw);
  1358. }
  1359. HRESULT CoCreateInstance(REFCLSID rclsid, LPUNKNOWN pUnkOuter = NULL, DWORD dwClsContext = CLSCTX_ALL) throw()
  1360. {
  1361. ATLASSERT(p == NULL);
  1362. return ::CoCreateInstance(rclsid, pUnkOuter, dwClsContext, __uuidof(T), (void**)&p);
  1363. }
  1364. HRESULT CoCreateInstance(LPCOLESTR szProgID, LPUNKNOWN pUnkOuter = NULL, DWORD dwClsContext = CLSCTX_ALL) throw()
  1365. {
  1366. CLSID clsid;
  1367. HRESULT hr = CLSIDFromProgID(szProgID, &clsid);
  1368. ATLASSERT(p == NULL);
  1369. if (SUCCEEDED(hr))
  1370. hr = ::CoCreateInstance(clsid, pUnkOuter, dwClsContext, __uuidof(T), (void**)&p);
  1371. return hr;
  1372. }
  1373. template <class Q>
  1374. HRESULT QueryInterface(Q** pp) const throw()
  1375. {
  1376. ATLASSERT(pp != NULL);
  1377. return p->QueryInterface(__uuidof(Q), (void**)pp);
  1378. }
  1379. T* p;
  1380. };
  1381. template <class T>
  1382. class CComPtr : public CComPtrBase<T>
  1383. {
  1384. public:
  1385. CComPtr() throw()
  1386. {
  1387. }
  1388. CComPtr(int nNull) throw() :
  1389. CComPtrBase<T>(nNull)
  1390. {
  1391. }
  1392. /*
  1393. template <typename Q>
  1394. CComPtr(Q* lp)
  1395. {
  1396. if (lp != NULL)
  1397. lp->QueryInterface(__uuidof(Q), (void**)&p);
  1398. else
  1399. p = NULL;
  1400. }
  1401. template <>
  1402. */
  1403. CComPtr(T* lp) throw() :
  1404. CComPtrBase<T>(lp)
  1405. {
  1406. }
  1407. CComPtr(const CComPtr<T>& lp) throw() :
  1408. CComPtrBase<T>(lp.p)
  1409. {
  1410. }
  1411. /*
  1412. CComPtr(DWORD dwCookie)
  1413. {
  1414. CComPtr<IGlobalInterfaceTable> spGIT;
  1415. _pModule->GetGITPtr(&spGIT);
  1416. ATLASSERT(spGIT != NULL);
  1417. ATLASSERT(dwCookie!=NULL);
  1418. spGIT->GetInterfaceFromGlobal(dwCookie, __uuidof(T), (void**)&p);
  1419. }
  1420. */
  1421. // template<>
  1422. /*
  1423. T* operator=(void* lp)
  1424. {
  1425. return (T*)AtlComPtrAssign((IUnknown**)&p, (T*)lp);
  1426. }
  1427. */
  1428. /*
  1429. template <typename Q>
  1430. T* operator=(Q* lp)
  1431. {
  1432. return (T*)AtlComQIPtrAssign((IUnknown**)&p, lp, __uuidof(T));
  1433. }
  1434. template <>
  1435. */
  1436. T* operator=(T* lp) throw()
  1437. {
  1438. return static_cast<T*>(AtlComPtrAssign((IUnknown**)&p, lp));
  1439. }
  1440. template <typename Q>
  1441. T* operator=(const CComPtr<Q>& lp) throw()
  1442. {
  1443. return static_cast<T*>(AtlComQIPtrAssign((IUnknown**)&p, lp, __uuidof(T)));
  1444. }
  1445. template <>
  1446. T* operator=(const CComPtr<T>& lp) throw()
  1447. {
  1448. return static_cast<T*>(AtlComPtrAssign((IUnknown**)&p, lp));
  1449. }
  1450. };
  1451. //specialization for IDispatch
  1452. template <>
  1453. class CComPtr<IDispatch> : public CComPtrBase<IDispatch>
  1454. {
  1455. public:
  1456. CComPtr() throw()
  1457. {
  1458. }
  1459. CComPtr(IDispatch* lp) throw() :
  1460. CComPtrBase<IDispatch>(lp)
  1461. {
  1462. }
  1463. CComPtr(const CComPtr<IDispatch>& lp) throw() :
  1464. CComPtrBase<IDispatch>(lp.p)
  1465. {
  1466. }
  1467. IDispatch* operator=(IDispatch* lp) throw()
  1468. {
  1469. return static_cast<IDispatch*>(AtlComPtrAssign((IUnknown**)&p, lp));
  1470. }
  1471. IDispatch* operator=(const CComPtr<IDispatch>& lp) throw()
  1472. {
  1473. return static_cast<IDispatch*>(AtlComPtrAssign((IUnknown**)&p, lp.p));
  1474. }
  1475. // IDispatch specific stuff
  1476. HRESULT GetPropertyByName(LPCOLESTR lpsz, VARIANT* pVar) throw()
  1477. {
  1478. ATLASSERT(p);
  1479. ATLASSERT(pVar);
  1480. DISPID dwDispID;
  1481. HRESULT hr = GetIDOfName(lpsz, &dwDispID);
  1482. if (SUCCEEDED(hr))
  1483. hr = GetProperty(dwDispID, pVar);
  1484. return hr;
  1485. }
  1486. HRESULT GetProperty(DISPID dwDispID, VARIANT* pVar) throw()
  1487. {
  1488. return GetProperty(p, dwDispID, pVar);
  1489. }
  1490. HRESULT PutPropertyByName(LPCOLESTR lpsz, VARIANT* pVar) throw()
  1491. {
  1492. ATLASSERT(p);
  1493. ATLASSERT(pVar);
  1494. DISPID dwDispID;
  1495. HRESULT hr = GetIDOfName(lpsz, &dwDispID);
  1496. if (SUCCEEDED(hr))
  1497. hr = PutProperty(dwDispID, pVar);
  1498. return hr;
  1499. }
  1500. HRESULT PutProperty(DISPID dwDispID, VARIANT* pVar) throw()
  1501. {
  1502. return PutProperty(p, dwDispID, pVar);
  1503. }
  1504. HRESULT GetIDOfName(LPCOLESTR lpsz, DISPID* pdispid) throw()
  1505. {
  1506. return p->GetIDsOfNames(IID_NULL, const_cast<LPOLESTR*>(&lpsz), 1, LOCALE_USER_DEFAULT, pdispid);
  1507. }
  1508. // Invoke a method by DISPID with no parameters
  1509. HRESULT Invoke0(DISPID dispid, VARIANT* pvarRet = NULL) throw()
  1510. {
  1511. DISPPARAMS dispparams = { NULL, NULL, 0, 0};
  1512. return p->Invoke(dispid, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &dispparams, pvarRet, NULL, NULL);
  1513. }
  1514. // Invoke a method by name with no parameters
  1515. HRESULT Invoke0(LPCOLESTR lpszName, VARIANT* pvarRet = NULL) throw()
  1516. {
  1517. HRESULT hr;
  1518. DISPID dispid;
  1519. hr = GetIDOfName(lpszName, &dispid);
  1520. if (SUCCEEDED(hr))
  1521. hr = Invoke0(dispid, pvarRet);
  1522. return hr;
  1523. }
  1524. // Invoke a method by DISPID with a single parameter
  1525. HRESULT Invoke1(DISPID dispid, VARIANT* pvarParam1, VARIANT* pvarRet = NULL) throw()
  1526. {
  1527. DISPPARAMS dispparams = { pvarParam1, NULL, 1, 0};
  1528. return p->Invoke(dispid, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &dispparams, pvarRet, NULL, NULL);
  1529. }
  1530. // Invoke a method by name with a single parameter
  1531. HRESULT Invoke1(LPCOLESTR lpszName, VARIANT* pvarParam1, VARIANT* pvarRet = NULL) throw()
  1532. {
  1533. HRESULT hr;
  1534. DISPID dispid;
  1535. hr = GetIDOfName(lpszName, &dispid);
  1536. if (SUCCEEDED(hr))
  1537. hr = Invoke1(dispid, pvarParam1, pvarRet);
  1538. return hr;
  1539. }
  1540. // Invoke a method by DISPID with two parameters
  1541. HRESULT Invoke2(DISPID dispid, VARIANT* pvarParam1, VARIANT* pvarParam2, VARIANT* pvarRet = NULL) throw();
  1542. // Invoke a method by name with two parameters
  1543. HRESULT Invoke2(LPCOLESTR lpszName, VARIANT* pvarParam1, VARIANT* pvarParam2, VARIANT* pvarRet = NULL) throw()
  1544. {
  1545. HRESULT hr;
  1546. DISPID dispid;
  1547. hr = GetIDOfName(lpszName, &dispid);
  1548. if (SUCCEEDED(hr))
  1549. hr = Invoke2(dispid, pvarParam1, pvarParam2, pvarRet);
  1550. return hr;
  1551. }
  1552. // Invoke a method by DISPID with N parameters
  1553. HRESULT InvokeN(DISPID dispid, VARIANT* pvarParams, int nParams, VARIANT* pvarRet = NULL) throw()
  1554. {
  1555. DISPPARAMS dispparams = { pvarParams, NULL, nParams, 0};
  1556. return p->Invoke(dispid, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &dispparams, pvarRet, NULL, NULL);
  1557. }
  1558. // Invoke a method by name with Nparameters
  1559. HRESULT InvokeN(LPCOLESTR lpszName, VARIANT* pvarParams, int nParams, VARIANT* pvarRet = NULL) throw()
  1560. {
  1561. HRESULT hr;
  1562. DISPID dispid;
  1563. hr = GetIDOfName(lpszName, &dispid);
  1564. if (SUCCEEDED(hr))
  1565. hr = InvokeN(dispid, pvarParams, nParams, pvarRet);
  1566. return hr;
  1567. }
  1568. static HRESULT PutProperty(IDispatch* p, DISPID dwDispID, VARIANT* pVar) throw()
  1569. {
  1570. ATLASSERT(p);
  1571. ATLTRACE(atlTraceCOM, 2, _T("CPropertyHelper::PutProperty\n"));
  1572. DISPPARAMS dispparams = {NULL, NULL, 1, 1};
  1573. dispparams.rgvarg = pVar;
  1574. DISPID dispidPut = DISPID_PROPERTYPUT;
  1575. dispparams.rgdispidNamedArgs = &dispidPut;
  1576. if (pVar->vt == VT_UNKNOWN || pVar->vt == VT_DISPATCH ||
  1577. (pVar->vt & VT_ARRAY) || (pVar->vt & VT_BYREF))
  1578. {
  1579. HRESULT hr = p->Invoke(dwDispID, IID_NULL,
  1580. LOCALE_USER_DEFAULT, DISPATCH_PROPERTYPUTREF,
  1581. &dispparams, NULL, NULL, NULL);
  1582. if (SUCCEEDED(hr))
  1583. return hr;
  1584. }
  1585. return p->Invoke(dwDispID, IID_NULL,
  1586. LOCALE_USER_DEFAULT, DISPATCH_PROPERTYPUT,
  1587. &dispparams, NULL, NULL, NULL);
  1588. }
  1589. static HRESULT GetProperty(IDispatch* p, DISPID dwDispID, VARIANT* pVar) throw()
  1590. {
  1591. ATLASSERT(p);
  1592. ATLTRACE(atlTraceCOM, 2, _T("CPropertyHelper::GetProperty\n"));
  1593. DISPPARAMS dispparamsNoArgs = {NULL, NULL, 0, 0};
  1594. return p->Invoke(dwDispID, IID_NULL,
  1595. LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET,
  1596. &dispparamsNoArgs, pVar, NULL, NULL);
  1597. }
  1598. };
  1599. template <class T, const IID* piid = &__uuidof(T)>
  1600. class CComQIPtr : public CComPtr<T>
  1601. {
  1602. public:
  1603. CComQIPtr() throw()
  1604. {
  1605. }
  1606. CComQIPtr(T* lp) throw() :
  1607. CComPtr<T>(lp)
  1608. {
  1609. }
  1610. CComQIPtr(const CComQIPtr<T,piid>& lp) throw() :
  1611. CComPtr<T>(lp.p)
  1612. {
  1613. }
  1614. CComQIPtr(IUnknown* lp) throw()
  1615. {
  1616. if (lp != NULL)
  1617. lp->QueryInterface(*piid, (void **)&p);
  1618. }
  1619. T* operator=(T* lp) throw()
  1620. {
  1621. return static_cast<T*>(AtlComPtrAssign((IUnknown**)&p, lp));
  1622. }
  1623. T* operator=(const CComQIPtr<T,piid>& lp) throw()
  1624. {
  1625. return static_cast<T*>(AtlComPtrAssign((IUnknown**)&p, lp.p));
  1626. }
  1627. T* operator=(IUnknown* lp) throw()
  1628. {
  1629. return static_cast<T*>(AtlComQIPtrAssign((IUnknown**)&p, lp, *piid));
  1630. }
  1631. };
  1632. //Specialization to make it work
  1633. template<>
  1634. class CComQIPtr<IUnknown, &IID_IUnknown> : public CComPtr<IUnknown>
  1635. {
  1636. public:
  1637. CComQIPtr() throw()
  1638. {
  1639. }
  1640. CComQIPtr(IUnknown* lp) throw()
  1641. {
  1642. //Actually do a QI to get identity
  1643. if (lp != NULL)
  1644. lp->QueryInterface(__uuidof(IUnknown), (void **)&p);
  1645. }
  1646. CComQIPtr(const CComQIPtr<IUnknown,&IID_IUnknown>& lp) throw() :
  1647. CComPtr<IUnknown>(lp.p)
  1648. {
  1649. }
  1650. IUnknown* operator=(IUnknown* lp) throw()
  1651. {
  1652. //Actually do a QI to get identity
  1653. return AtlComQIPtrAssign((IUnknown**)&p, lp, __uuidof(IUnknown));
  1654. }
  1655. IUnknown* operator=(const CComQIPtr<IUnknown,&IID_IUnknown>& lp) throw()
  1656. {
  1657. return AtlComPtrAssign((IUnknown**)&p, lp.p);
  1658. }
  1659. };
  1660. typedef CComQIPtr<IDispatch, &__uuidof(IDispatch)> CComDispatchDriver;
  1661. #define com_cast ATL::CComQIPtr
  1662. class CHandle
  1663. {
  1664. public:
  1665. CHandle() throw();
  1666. CHandle( CHandle& h ) throw();
  1667. explicit CHandle( HANDLE h ) throw();
  1668. ~CHandle() throw();
  1669. operator HANDLE() const throw();
  1670. // Attach to an existing handle (takes ownership).
  1671. void Attach( HANDLE h ) throw();
  1672. // Detach the handle from the object (releases ownership).
  1673. HANDLE Detach() throw();
  1674. // Close the handle.
  1675. void Close() throw();
  1676. public:
  1677. HANDLE m_h;
  1678. };
  1679. inline CHandle::CHandle() :
  1680. m_h( NULL )
  1681. {
  1682. }
  1683. inline CHandle::CHandle( CHandle& h ) :
  1684. m_h( NULL )
  1685. {
  1686. Attach( h.Detach() );
  1687. }
  1688. inline CHandle::CHandle( HANDLE h ) :
  1689. m_h( h )
  1690. {
  1691. }
  1692. inline CHandle::~CHandle()
  1693. {
  1694. if( m_h != NULL )
  1695. {
  1696. Close();
  1697. }
  1698. }
  1699. inline CHandle::operator HANDLE() const
  1700. {
  1701. return( m_h );
  1702. }
  1703. inline void CHandle::Attach( HANDLE h )
  1704. {
  1705. ATLASSERT( m_h == NULL );
  1706. m_h = h; // Take ownership
  1707. }
  1708. inline HANDLE CHandle::Detach()
  1709. {
  1710. HANDLE h;
  1711. h = m_h; // Release ownership
  1712. m_h = NULL;
  1713. return( h );
  1714. }
  1715. inline void CHandle::Close()
  1716. {
  1717. ATLASSERT( m_h != NULL );
  1718. ::CloseHandle( m_h );
  1719. m_h = NULL;
  1720. }
  1721. //REVIEW: Temporary #define to make vcide build
  1722. #define _ATL_NO_CAUTOLOCK
  1723. class CCritSecLock
  1724. {
  1725. public:
  1726. CCritSecLock( CRITICAL_SECTION& cs, bool bInitialLock = true );
  1727. ~CCritSecLock() throw();
  1728. void Lock();
  1729. void Unlock() throw();
  1730. // Implementation
  1731. private:
  1732. CRITICAL_SECTION& m_cs;
  1733. bool m_bLocked;
  1734. // Private to avoid accidental use
  1735. CCritSecLock( const CCritSecLock& ) throw();
  1736. CCritSecLock& operator=( const CCritSecLock& ) throw();
  1737. };
  1738. inline CCritSecLock::CCritSecLock( CRITICAL_SECTION& cs, bool bInitialLock ) :
  1739. m_cs( cs ),
  1740. m_bLocked( false )
  1741. {
  1742. if( bInitialLock )
  1743. {
  1744. Lock();
  1745. }
  1746. }
  1747. inline CCritSecLock::~CCritSecLock()
  1748. {
  1749. if( m_bLocked )
  1750. {
  1751. Unlock();
  1752. }
  1753. }
  1754. inline void CCritSecLock::Lock()
  1755. {
  1756. ATLASSERT( !m_bLocked );
  1757. __try
  1758. {
  1759. ::EnterCriticalSection( &m_cs );
  1760. }
  1761. __except( EXCEPTION_EXECUTE_HANDLER )
  1762. {
  1763. AtlThrow( E_OUTOFMEMORY );
  1764. }
  1765. m_bLocked = true;
  1766. }
  1767. inline void CCritSecLock::Unlock()
  1768. {
  1769. ATLASSERT( m_bLocked );
  1770. ::LeaveCriticalSection( &m_cs );
  1771. m_bLocked = false;
  1772. }
  1773. /////////////////////////////////////////////////////////////
  1774. // Class to Adapt CComBSTR and CComPtr for use with STL containers
  1775. // the syntax to use it is
  1776. // std::vector< CAdapt <CComBSTR> > vect;
  1777. template <class T>
  1778. class CAdapt
  1779. {
  1780. public:
  1781. CAdapt()
  1782. {
  1783. }
  1784. CAdapt(const T& rSrc) :
  1785. m_T( rSrc )
  1786. {
  1787. }
  1788. CAdapt(const CAdapt& rSrCA) :
  1789. m_T( rSrCA.m_T )
  1790. {
  1791. }
  1792. CAdapt& operator=(const T& rSrc)
  1793. {
  1794. m_T = rSrc;
  1795. return *this;
  1796. }
  1797. bool operator<(const T& rSrc) const
  1798. {
  1799. return m_T < rSrc;
  1800. }
  1801. bool operator==(const T& rSrc) const
  1802. {
  1803. return m_T == rSrc;
  1804. }
  1805. operator T&()
  1806. {
  1807. return m_T;
  1808. }
  1809. operator const T&() const
  1810. {
  1811. return m_T;
  1812. }
  1813. T m_T;
  1814. };
  1815. /////////////////////////////////////////////////////////////////////////////
  1816. // Threading Model Support
  1817. class CComAutoCriticalSection : public CComCriticalSection
  1818. {
  1819. public:
  1820. CComAutoCriticalSection()
  1821. {
  1822. HRESULT hr = CComCriticalSection::Init();
  1823. if (FAILED(hr))
  1824. AtlThrow(hr);
  1825. }
  1826. ~CComAutoCriticalSection() throw()
  1827. {
  1828. CComCriticalSection::Term();
  1829. }
  1830. private :
  1831. HRESULT Init(); // Not implemented. CComAutoCriticalSection::Init should never be called
  1832. HRESULT Term(); // Not implemented. CComAutoCriticalSection::Term should never be called
  1833. };
  1834. class CComFakeCriticalSection
  1835. {
  1836. public:
  1837. HRESULT Lock() throw() { return S_OK; }
  1838. HRESULT Unlock() throw() { return S_OK; }
  1839. HRESULT Init() throw() { return S_OK; }
  1840. HRESULT Term() throw() { return S_OK; }
  1841. };
  1842. template< class TLock >
  1843. class CComCritSecLock
  1844. {
  1845. public:
  1846. CComCritSecLock( TLock& cs, bool bInitialLock = true );
  1847. ~CComCritSecLock() throw();
  1848. HRESULT Lock() throw();
  1849. void Unlock() throw();
  1850. // Implementation
  1851. private:
  1852. TLock& m_cs;
  1853. bool m_bLocked;
  1854. // Private to avoid accidental use
  1855. CComCritSecLock( const CComCritSecLock& ) throw();
  1856. CComCritSecLock& operator=( const CComCritSecLock& ) throw();
  1857. };
  1858. template< class TLock >
  1859. inline CComCritSecLock< TLock >::CComCritSecLock( TLock& cs, bool bInitialLock ) :
  1860. m_cs( cs ),
  1861. m_bLocked( false )
  1862. {
  1863. if( bInitialLock )
  1864. {
  1865. HRESULT hr;
  1866. hr = Lock();
  1867. if( FAILED( hr ) )
  1868. {
  1869. AtlThrow( hr );
  1870. }
  1871. }
  1872. }
  1873. template< class TLock >
  1874. inline CComCritSecLock< TLock >::~CComCritSecLock() throw()
  1875. {
  1876. if( m_bLocked )
  1877. {
  1878. Unlock();
  1879. }
  1880. }
  1881. template< class TLock >
  1882. inline HRESULT CComCritSecLock< TLock >::Lock() throw()
  1883. {
  1884. HRESULT hr;
  1885. ATLASSERT( !m_bLocked );
  1886. hr = m_cs.Lock();
  1887. if( FAILED( hr ) )
  1888. {
  1889. return( hr );
  1890. }
  1891. m_bLocked = true;
  1892. return( S_OK );
  1893. }
  1894. template< class TLock >
  1895. inline void CComCritSecLock< TLock >::Unlock() throw()
  1896. {
  1897. ATLASSERT( m_bLocked );
  1898. m_cs.Unlock();
  1899. m_bLocked = false;
  1900. }
  1901. class CComMultiThreadModelNoCS
  1902. {
  1903. public:
  1904. static ULONG WINAPI Increment(LPLONG p) throw() {return InterlockedIncrement(p);}
  1905. static ULONG WINAPI Decrement(LPLONG p) throw() {return InterlockedDecrement(p);}
  1906. typedef CComFakeCriticalSection AutoCriticalSection;
  1907. typedef CComFakeCriticalSection CriticalSection;
  1908. typedef CComMultiThreadModelNoCS ThreadModelNoCS;
  1909. };
  1910. class CComMultiThreadModel
  1911. {
  1912. public:
  1913. static ULONG WINAPI Increment(LPLONG p) throw() {return InterlockedIncrement(p);}
  1914. static ULONG WINAPI Decrement(LPLONG p) throw() {return InterlockedDecrement(p);}
  1915. typedef CComAutoCriticalSection AutoCriticalSection;
  1916. typedef CComCriticalSection CriticalSection;
  1917. typedef CComMultiThreadModelNoCS ThreadModelNoCS;
  1918. };
  1919. class CComSingleThreadModel
  1920. {
  1921. public:
  1922. static ULONG WINAPI Increment(LPLONG p) throw() {return ++(*p);}
  1923. static ULONG WINAPI Decrement(LPLONG p) throw() {return --(*p);}
  1924. typedef CComFakeCriticalSection AutoCriticalSection;
  1925. typedef CComFakeCriticalSection CriticalSection;
  1926. typedef CComSingleThreadModel ThreadModelNoCS;
  1927. };
  1928. #if defined(_ATL_SINGLE_THREADED)
  1929. #if defined(_ATL_APARTMENT_THREADED) || defined(_ATL_FREE_THREADED)
  1930. #pragma message ("More than one global threading model defined.")
  1931. #endif
  1932. typedef CComSingleThreadModel CComObjectThreadModel;
  1933. typedef CComSingleThreadModel CComGlobalsThreadModel;
  1934. #elif defined(_ATL_APARTMENT_THREADED)
  1935. #if defined(_ATL_SINGLE_THREADED) || defined(_ATL_FREE_THREADED)
  1936. #pragma message ("More than one global threading model defined.")
  1937. #endif
  1938. typedef CComSingleThreadModel CComObjectThreadModel;
  1939. typedef CComMultiThreadModel CComGlobalsThreadModel;
  1940. #elif defined(_ATL_FREE_THREADED)
  1941. #if defined(_ATL_SINGLE_THREADED) || defined(_ATL_APARTMENT_THREADED)
  1942. #pragma message ("More than one global threading model defined.")
  1943. #endif
  1944. typedef CComMultiThreadModel CComObjectThreadModel;
  1945. typedef CComMultiThreadModel CComGlobalsThreadModel;
  1946. #else
  1947. #pragma message ("No global threading model defined")
  1948. #endif
  1949. /////////////////////////////////////////////////////////////////////////////
  1950. // CComModule
  1951. #define THREADFLAGS_APARTMENT 0x1
  1952. #define THREADFLAGS_BOTH 0x2
  1953. #define AUTPRXFLAG 0x4
  1954. HRESULT WINAPI AtlDumpIID(REFIID iid, LPCTSTR pszClassName, HRESULT hr);
  1955. struct _QIThunk
  1956. {
  1957. STDMETHOD(QueryInterface)(REFIID iid, void** pp)
  1958. {
  1959. ATLASSERT(m_dwRef >= 0);
  1960. ATLASSERT(m_pUnk != NULL);
  1961. return m_pUnk->QueryInterface(iid, pp);
  1962. }
  1963. STDMETHOD_(ULONG, AddRef)()
  1964. {
  1965. ATLASSERT(m_pUnk != NULL);
  1966. if (m_bBreak)
  1967. DebugBreak();
  1968. m_pUnk->AddRef();
  1969. return InternalAddRef();
  1970. }
  1971. ULONG InternalAddRef()
  1972. {
  1973. ATLASSERT(m_pUnk != NULL);
  1974. if (m_bBreak)
  1975. DebugBreak();
  1976. ATLASSERT(m_dwRef >= 0);
  1977. long l = InterlockedIncrement(&m_dwRef);
  1978. TCHAR buf[512];
  1979. wsprintf(buf, _T("QIThunk - %-10d\tAddRef :\tObject = 0x%08x\tRefcount = %d\t"), m_nIndex, m_pUnk, m_dwRef);
  1980. OutputDebugString(buf);
  1981. AtlDumpIID(m_iid, m_lpszClassName, S_OK);
  1982. if (l > m_dwMaxRef)
  1983. m_dwMaxRef = l;
  1984. return l;
  1985. }
  1986. STDMETHOD_(ULONG, Release)();
  1987. STDMETHOD(f3)();
  1988. STDMETHOD(f4)();
  1989. STDMETHOD(f5)();
  1990. STDMETHOD(f6)();
  1991. STDMETHOD(f7)();
  1992. STDMETHOD(f8)();
  1993. STDMETHOD(f9)();
  1994. STDMETHOD(f10)();
  1995. STDMETHOD(f11)();
  1996. STDMETHOD(f12)();
  1997. STDMETHOD(f13)();
  1998. STDMETHOD(f14)();
  1999. STDMETHOD(f15)();
  2000. STDMETHOD(f16)();
  2001. STDMETHOD(f17)();
  2002. STDMETHOD(f18)();
  2003. STDMETHOD(f19)();
  2004. STDMETHOD(f20)();
  2005. STDMETHOD(f21)();
  2006. STDMETHOD(f22)();
  2007. STDMETHOD(f23)();
  2008. STDMETHOD(f24)();
  2009. STDMETHOD(f25)();
  2010. STDMETHOD(f26)();
  2011. STDMETHOD(f27)();
  2012. STDMETHOD(f28)();
  2013. STDMETHOD(f29)();
  2014. STDMETHOD(f30)();
  2015. STDMETHOD(f31)();
  2016. STDMETHOD(f32)();
  2017. STDMETHOD(f33)();
  2018. STDMETHOD(f34)();
  2019. STDMETHOD(f35)();
  2020. STDMETHOD(f36)();
  2021. STDMETHOD(f37)();
  2022. STDMETHOD(f38)();
  2023. STDMETHOD(f39)();
  2024. STDMETHOD(f40)();
  2025. STDMETHOD(f41)();
  2026. STDMETHOD(f42)();
  2027. STDMETHOD(f43)();
  2028. STDMETHOD(f44)();
  2029. STDMETHOD(f45)();
  2030. STDMETHOD(f46)();
  2031. STDMETHOD(f47)();
  2032. STDMETHOD(f48)();
  2033. STDMETHOD(f49)();
  2034. STDMETHOD(f50)();
  2035. STDMETHOD(f51)();
  2036. STDMETHOD(f52)();
  2037. STDMETHOD(f53)();
  2038. STDMETHOD(f54)();
  2039. STDMETHOD(f55)();
  2040. STDMETHOD(f56)();
  2041. STDMETHOD(f57)();
  2042. STDMETHOD(f58)();
  2043. STDMETHOD(f59)();
  2044. STDMETHOD(f60)();
  2045. STDMETHOD(f61)();
  2046. STDMETHOD(f62)();
  2047. STDMETHOD(f63)();
  2048. STDMETHOD(f64)();
  2049. STDMETHOD(f65)();
  2050. STDMETHOD(f66)();
  2051. STDMETHOD(f67)();
  2052. STDMETHOD(f68)();
  2053. STDMETHOD(f69)();
  2054. STDMETHOD(f70)();
  2055. STDMETHOD(f71)();
  2056. STDMETHOD(f72)();
  2057. STDMETHOD(f73)();
  2058. STDMETHOD(f74)();
  2059. STDMETHOD(f75)();
  2060. STDMETHOD(f76)();
  2061. STDMETHOD(f77)();
  2062. STDMETHOD(f78)();
  2063. STDMETHOD(f79)();
  2064. STDMETHOD(f80)();
  2065. STDMETHOD(f81)();
  2066. STDMETHOD(f82)();
  2067. STDMETHOD(f83)();
  2068. STDMETHOD(f84)();
  2069. STDMETHOD(f85)();
  2070. STDMETHOD(f86)();
  2071. STDMETHOD(f87)();
  2072. STDMETHOD(f88)();
  2073. STDMETHOD(f89)();
  2074. STDMETHOD(f90)();
  2075. STDMETHOD(f91)();
  2076. STDMETHOD(f92)();
  2077. STDMETHOD(f93)();
  2078. STDMETHOD(f94)();
  2079. STDMETHOD(f95)();
  2080. STDMETHOD(f96)();
  2081. STDMETHOD(f97)();
  2082. STDMETHOD(f98)();
  2083. STDMETHOD(f99)();
  2084. STDMETHOD(f100)();
  2085. STDMETHOD(f101)();
  2086. STDMETHOD(f102)();
  2087. STDMETHOD(f103)();
  2088. STDMETHOD(f104)();
  2089. STDMETHOD(f105)();
  2090. STDMETHOD(f106)();
  2091. STDMETHOD(f107)();
  2092. STDMETHOD(f108)();
  2093. STDMETHOD(f109)();
  2094. STDMETHOD(f110)();
  2095. STDMETHOD(f111)();
  2096. STDMETHOD(f112)();
  2097. STDMETHOD(f113)();
  2098. STDMETHOD(f114)();
  2099. STDMETHOD(f115)();
  2100. STDMETHOD(f116)();
  2101. STDMETHOD(f117)();
  2102. STDMETHOD(f118)();
  2103. STDMETHOD(f119)();
  2104. STDMETHOD(f120)();
  2105. STDMETHOD(f121)();
  2106. STDMETHOD(f122)();
  2107. STDMETHOD(f123)();
  2108. STDMETHOD(f124)();
  2109. STDMETHOD(f125)();
  2110. STDMETHOD(f126)();
  2111. STDMETHOD(f127)();
  2112. STDMETHOD(f128)();
  2113. STDMETHOD(f129)();
  2114. STDMETHOD(f130)();
  2115. STDMETHOD(f131)();
  2116. STDMETHOD(f132)();
  2117. STDMETHOD(f133)();
  2118. STDMETHOD(f134)();
  2119. STDMETHOD(f135)();
  2120. STDMETHOD(f136)();
  2121. STDMETHOD(f137)();
  2122. STDMETHOD(f138)();
  2123. STDMETHOD(f139)();
  2124. STDMETHOD(f140)();
  2125. STDMETHOD(f141)();
  2126. STDMETHOD(f142)();
  2127. STDMETHOD(f143)();
  2128. STDMETHOD(f144)();
  2129. STDMETHOD(f145)();
  2130. STDMETHOD(f146)();
  2131. STDMETHOD(f147)();
  2132. STDMETHOD(f148)();
  2133. STDMETHOD(f149)();
  2134. STDMETHOD(f150)();
  2135. STDMETHOD(f151)();
  2136. STDMETHOD(f152)();
  2137. STDMETHOD(f153)();
  2138. STDMETHOD(f154)();
  2139. STDMETHOD(f155)();
  2140. STDMETHOD(f156)();
  2141. STDMETHOD(f157)();
  2142. STDMETHOD(f158)();
  2143. STDMETHOD(f159)();
  2144. STDMETHOD(f160)();
  2145. STDMETHOD(f161)();
  2146. STDMETHOD(f162)();
  2147. STDMETHOD(f163)();
  2148. STDMETHOD(f164)();
  2149. STDMETHOD(f165)();
  2150. STDMETHOD(f166)();
  2151. STDMETHOD(f167)();
  2152. STDMETHOD(f168)();
  2153. STDMETHOD(f169)();
  2154. STDMETHOD(f170)();
  2155. STDMETHOD(f171)();
  2156. STDMETHOD(f172)();
  2157. STDMETHOD(f173)();
  2158. STDMETHOD(f174)();
  2159. STDMETHOD(f175)();
  2160. STDMETHOD(f176)();
  2161. STDMETHOD(f177)();
  2162. STDMETHOD(f178)();
  2163. STDMETHOD(f179)();
  2164. STDMETHOD(f180)();
  2165. STDMETHOD(f181)();
  2166. STDMETHOD(f182)();
  2167. STDMETHOD(f183)();
  2168. STDMETHOD(f184)();
  2169. STDMETHOD(f185)();
  2170. STDMETHOD(f186)();
  2171. STDMETHOD(f187)();
  2172. STDMETHOD(f188)();
  2173. STDMETHOD(f189)();
  2174. STDMETHOD(f190)();
  2175. STDMETHOD(f191)();
  2176. STDMETHOD(f192)();
  2177. STDMETHOD(f193)();
  2178. STDMETHOD(f194)();
  2179. STDMETHOD(f195)();
  2180. STDMETHOD(f196)();
  2181. STDMETHOD(f197)();
  2182. STDMETHOD(f198)();
  2183. STDMETHOD(f199)();
  2184. STDMETHOD(f200)();
  2185. STDMETHOD(f201)();
  2186. STDMETHOD(f202)();
  2187. STDMETHOD(f203)();
  2188. STDMETHOD(f204)();
  2189. STDMETHOD(f205)();
  2190. STDMETHOD(f206)();
  2191. STDMETHOD(f207)();
  2192. STDMETHOD(f208)();
  2193. STDMETHOD(f209)();
  2194. STDMETHOD(f210)();
  2195. STDMETHOD(f211)();
  2196. STDMETHOD(f212)();
  2197. STDMETHOD(f213)();
  2198. STDMETHOD(f214)();
  2199. STDMETHOD(f215)();
  2200. STDMETHOD(f216)();
  2201. STDMETHOD(f217)();
  2202. STDMETHOD(f218)();
  2203. STDMETHOD(f219)();
  2204. STDMETHOD(f220)();
  2205. STDMETHOD(f221)();
  2206. STDMETHOD(f222)();
  2207. STDMETHOD(f223)();
  2208. STDMETHOD(f224)();
  2209. STDMETHOD(f225)();
  2210. STDMETHOD(f226)();
  2211. STDMETHOD(f227)();
  2212. STDMETHOD(f228)();
  2213. STDMETHOD(f229)();
  2214. STDMETHOD(f230)();
  2215. STDMETHOD(f231)();
  2216. STDMETHOD(f232)();
  2217. STDMETHOD(f233)();
  2218. STDMETHOD(f234)();
  2219. STDMETHOD(f235)();
  2220. STDMETHOD(f236)();
  2221. STDMETHOD(f237)();
  2222. STDMETHOD(f238)();
  2223. STDMETHOD(f239)();
  2224. STDMETHOD(f240)();
  2225. STDMETHOD(f241)();
  2226. STDMETHOD(f242)();
  2227. STDMETHOD(f243)();
  2228. STDMETHOD(f244)();
  2229. STDMETHOD(f245)();
  2230. STDMETHOD(f246)();
  2231. STDMETHOD(f247)();
  2232. STDMETHOD(f248)();
  2233. STDMETHOD(f249)();
  2234. STDMETHOD(f250)();
  2235. STDMETHOD(f251)();
  2236. STDMETHOD(f252)();
  2237. STDMETHOD(f253)();
  2238. STDMETHOD(f254)();
  2239. STDMETHOD(f255)();
  2240. STDMETHOD(f256)();
  2241. STDMETHOD(f257)();
  2242. STDMETHOD(f258)();
  2243. STDMETHOD(f259)();
  2244. STDMETHOD(f260)();
  2245. STDMETHOD(f261)();
  2246. STDMETHOD(f262)();
  2247. STDMETHOD(f263)();
  2248. STDMETHOD(f264)();
  2249. STDMETHOD(f265)();
  2250. STDMETHOD(f266)();
  2251. STDMETHOD(f267)();
  2252. STDMETHOD(f268)();
  2253. STDMETHOD(f269)();
  2254. STDMETHOD(f270)();
  2255. STDMETHOD(f271)();
  2256. STDMETHOD(f272)();
  2257. STDMETHOD(f273)();
  2258. STDMETHOD(f274)();
  2259. STDMETHOD(f275)();
  2260. STDMETHOD(f276)();
  2261. STDMETHOD(f277)();
  2262. STDMETHOD(f278)();
  2263. STDMETHOD(f279)();
  2264. STDMETHOD(f280)();
  2265. STDMETHOD(f281)();
  2266. STDMETHOD(f282)();
  2267. STDMETHOD(f283)();
  2268. STDMETHOD(f284)();
  2269. STDMETHOD(f285)();
  2270. STDMETHOD(f286)();
  2271. STDMETHOD(f287)();
  2272. STDMETHOD(f288)();
  2273. STDMETHOD(f289)();
  2274. STDMETHOD(f290)();
  2275. STDMETHOD(f291)();
  2276. STDMETHOD(f292)();
  2277. STDMETHOD(f293)();
  2278. STDMETHOD(f294)();
  2279. STDMETHOD(f295)();
  2280. STDMETHOD(f296)();
  2281. STDMETHOD(f297)();
  2282. STDMETHOD(f298)();
  2283. STDMETHOD(f299)();
  2284. STDMETHOD(f300)();
  2285. STDMETHOD(f301)();
  2286. STDMETHOD(f302)();
  2287. STDMETHOD(f303)();
  2288. STDMETHOD(f304)();
  2289. STDMETHOD(f305)();
  2290. STDMETHOD(f306)();
  2291. STDMETHOD(f307)();
  2292. STDMETHOD(f308)();
  2293. STDMETHOD(f309)();
  2294. STDMETHOD(f310)();
  2295. STDMETHOD(f311)();
  2296. STDMETHOD(f312)();
  2297. STDMETHOD(f313)();
  2298. STDMETHOD(f314)();
  2299. STDMETHOD(f315)();
  2300. STDMETHOD(f316)();
  2301. STDMETHOD(f317)();
  2302. STDMETHOD(f318)();
  2303. STDMETHOD(f319)();
  2304. STDMETHOD(f320)();
  2305. STDMETHOD(f321)();
  2306. STDMETHOD(f322)();
  2307. STDMETHOD(f323)();
  2308. STDMETHOD(f324)();
  2309. STDMETHOD(f325)();
  2310. STDMETHOD(f326)();
  2311. STDMETHOD(f327)();
  2312. STDMETHOD(f328)();
  2313. STDMETHOD(f329)();
  2314. STDMETHOD(f330)();
  2315. STDMETHOD(f331)();
  2316. STDMETHOD(f332)();
  2317. STDMETHOD(f333)();
  2318. STDMETHOD(f334)();
  2319. STDMETHOD(f335)();
  2320. STDMETHOD(f336)();
  2321. STDMETHOD(f337)();
  2322. STDMETHOD(f338)();
  2323. STDMETHOD(f339)();
  2324. STDMETHOD(f340)();
  2325. STDMETHOD(f341)();
  2326. STDMETHOD(f342)();
  2327. STDMETHOD(f343)();
  2328. STDMETHOD(f344)();
  2329. STDMETHOD(f345)();
  2330. STDMETHOD(f346)();
  2331. STDMETHOD(f347)();
  2332. STDMETHOD(f348)();
  2333. STDMETHOD(f349)();
  2334. STDMETHOD(f350)();
  2335. STDMETHOD(f351)();
  2336. STDMETHOD(f352)();
  2337. STDMETHOD(f353)();
  2338. STDMETHOD(f354)();
  2339. STDMETHOD(f355)();
  2340. STDMETHOD(f356)();
  2341. STDMETHOD(f357)();
  2342. STDMETHOD(f358)();
  2343. STDMETHOD(f359)();
  2344. STDMETHOD(f360)();
  2345. STDMETHOD(f361)();
  2346. STDMETHOD(f362)();
  2347. STDMETHOD(f363)();
  2348. STDMETHOD(f364)();
  2349. STDMETHOD(f365)();
  2350. STDMETHOD(f366)();
  2351. STDMETHOD(f367)();
  2352. STDMETHOD(f368)();
  2353. STDMETHOD(f369)();
  2354. STDMETHOD(f370)();
  2355. STDMETHOD(f371)();
  2356. STDMETHOD(f372)();
  2357. STDMETHOD(f373)();
  2358. STDMETHOD(f374)();
  2359. STDMETHOD(f375)();
  2360. STDMETHOD(f376)();
  2361. STDMETHOD(f377)();
  2362. STDMETHOD(f378)();
  2363. STDMETHOD(f379)();
  2364. STDMETHOD(f380)();
  2365. STDMETHOD(f381)();
  2366. STDMETHOD(f382)();
  2367. STDMETHOD(f383)();
  2368. STDMETHOD(f384)();
  2369. STDMETHOD(f385)();
  2370. STDMETHOD(f386)();
  2371. STDMETHOD(f387)();
  2372. STDMETHOD(f388)();
  2373. STDMETHOD(f389)();
  2374. STDMETHOD(f390)();
  2375. STDMETHOD(f391)();
  2376. STDMETHOD(f392)();
  2377. STDMETHOD(f393)();
  2378. STDMETHOD(f394)();
  2379. STDMETHOD(f395)();
  2380. STDMETHOD(f396)();
  2381. STDMETHOD(f397)();
  2382. STDMETHOD(f398)();
  2383. STDMETHOD(f399)();
  2384. STDMETHOD(f400)();
  2385. STDMETHOD(f401)();
  2386. STDMETHOD(f402)();
  2387. STDMETHOD(f403)();
  2388. STDMETHOD(f404)();
  2389. STDMETHOD(f405)();
  2390. STDMETHOD(f406)();
  2391. STDMETHOD(f407)();
  2392. STDMETHOD(f408)();
  2393. STDMETHOD(f409)();
  2394. STDMETHOD(f410)();
  2395. STDMETHOD(f411)();
  2396. STDMETHOD(f412)();
  2397. STDMETHOD(f413)();
  2398. STDMETHOD(f414)();
  2399. STDMETHOD(f415)();
  2400. STDMETHOD(f416)();
  2401. STDMETHOD(f417)();
  2402. STDMETHOD(f418)();
  2403. STDMETHOD(f419)();
  2404. STDMETHOD(f420)();
  2405. STDMETHOD(f421)();
  2406. STDMETHOD(f422)();
  2407. STDMETHOD(f423)();
  2408. STDMETHOD(f424)();
  2409. STDMETHOD(f425)();
  2410. STDMETHOD(f426)();
  2411. STDMETHOD(f427)();
  2412. STDMETHOD(f428)();
  2413. STDMETHOD(f429)();
  2414. STDMETHOD(f430)();
  2415. STDMETHOD(f431)();
  2416. STDMETHOD(f432)();
  2417. STDMETHOD(f433)();
  2418. STDMETHOD(f434)();
  2419. STDMETHOD(f435)();
  2420. STDMETHOD(f436)();
  2421. STDMETHOD(f437)();
  2422. STDMETHOD(f438)();
  2423. STDMETHOD(f439)();
  2424. STDMETHOD(f440)();
  2425. STDMETHOD(f441)();
  2426. STDMETHOD(f442)();
  2427. STDMETHOD(f443)();
  2428. STDMETHOD(f444)();
  2429. STDMETHOD(f445)();
  2430. STDMETHOD(f446)();
  2431. STDMETHOD(f447)();
  2432. STDMETHOD(f448)();
  2433. STDMETHOD(f449)();
  2434. STDMETHOD(f450)();
  2435. STDMETHOD(f451)();
  2436. STDMETHOD(f452)();
  2437. STDMETHOD(f453)();
  2438. STDMETHOD(f454)();
  2439. STDMETHOD(f455)();
  2440. STDMETHOD(f456)();
  2441. STDMETHOD(f457)();
  2442. STDMETHOD(f458)();
  2443. STDMETHOD(f459)();
  2444. STDMETHOD(f460)();
  2445. STDMETHOD(f461)();
  2446. STDMETHOD(f462)();
  2447. STDMETHOD(f463)();
  2448. STDMETHOD(f464)();
  2449. STDMETHOD(f465)();
  2450. STDMETHOD(f466)();
  2451. STDMETHOD(f467)();
  2452. STDMETHOD(f468)();
  2453. STDMETHOD(f469)();
  2454. STDMETHOD(f470)();
  2455. STDMETHOD(f471)();
  2456. STDMETHOD(f472)();
  2457. STDMETHOD(f473)();
  2458. STDMETHOD(f474)();
  2459. STDMETHOD(f475)();
  2460. STDMETHOD(f476)();
  2461. STDMETHOD(f477)();
  2462. STDMETHOD(f478)();
  2463. STDMETHOD(f479)();
  2464. STDMETHOD(f480)();
  2465. STDMETHOD(f481)();
  2466. STDMETHOD(f482)();
  2467. STDMETHOD(f483)();
  2468. STDMETHOD(f484)();
  2469. STDMETHOD(f485)();
  2470. STDMETHOD(f486)();
  2471. STDMETHOD(f487)();
  2472. STDMETHOD(f488)();
  2473. STDMETHOD(f489)();
  2474. STDMETHOD(f490)();
  2475. STDMETHOD(f491)();
  2476. STDMETHOD(f492)();
  2477. STDMETHOD(f493)();
  2478. STDMETHOD(f494)();
  2479. STDMETHOD(f495)();
  2480. STDMETHOD(f496)();
  2481. STDMETHOD(f497)();
  2482. STDMETHOD(f498)();
  2483. STDMETHOD(f499)();
  2484. STDMETHOD(f500)();
  2485. STDMETHOD(f501)();
  2486. STDMETHOD(f502)();
  2487. STDMETHOD(f503)();
  2488. STDMETHOD(f504)();
  2489. STDMETHOD(f505)();
  2490. STDMETHOD(f506)();
  2491. STDMETHOD(f507)();
  2492. STDMETHOD(f508)();
  2493. STDMETHOD(f509)();
  2494. STDMETHOD(f510)();
  2495. STDMETHOD(f511)();
  2496. STDMETHOD(f512)();
  2497. STDMETHOD(f513)();
  2498. STDMETHOD(f514)();
  2499. STDMETHOD(f515)();
  2500. STDMETHOD(f516)();
  2501. STDMETHOD(f517)();
  2502. STDMETHOD(f518)();
  2503. STDMETHOD(f519)();
  2504. STDMETHOD(f520)();
  2505. STDMETHOD(f521)();
  2506. STDMETHOD(f522)();
  2507. STDMETHOD(f523)();
  2508. STDMETHOD(f524)();
  2509. STDMETHOD(f525)();
  2510. STDMETHOD(f526)();
  2511. STDMETHOD(f527)();
  2512. STDMETHOD(f528)();
  2513. STDMETHOD(f529)();
  2514. STDMETHOD(f530)();
  2515. STDMETHOD(f531)();
  2516. STDMETHOD(f532)();
  2517. STDMETHOD(f533)();
  2518. STDMETHOD(f534)();
  2519. STDMETHOD(f535)();
  2520. STDMETHOD(f536)();
  2521. STDMETHOD(f537)();
  2522. STDMETHOD(f538)();
  2523. STDMETHOD(f539)();
  2524. STDMETHOD(f540)();
  2525. STDMETHOD(f541)();
  2526. STDMETHOD(f542)();
  2527. STDMETHOD(f543)();
  2528. STDMETHOD(f544)();
  2529. STDMETHOD(f545)();
  2530. STDMETHOD(f546)();
  2531. STDMETHOD(f547)();
  2532. STDMETHOD(f548)();
  2533. STDMETHOD(f549)();
  2534. STDMETHOD(f550)();
  2535. STDMETHOD(f551)();
  2536. STDMETHOD(f552)();
  2537. STDMETHOD(f553)();
  2538. STDMETHOD(f554)();
  2539. STDMETHOD(f555)();
  2540. STDMETHOD(f556)();
  2541. STDMETHOD(f557)();
  2542. STDMETHOD(f558)();
  2543. STDMETHOD(f559)();
  2544. STDMETHOD(f560)();
  2545. STDMETHOD(f561)();
  2546. STDMETHOD(f562)();
  2547. STDMETHOD(f563)();
  2548. STDMETHOD(f564)();
  2549. STDMETHOD(f565)();
  2550. STDMETHOD(f566)();
  2551. STDMETHOD(f567)();
  2552. STDMETHOD(f568)();
  2553. STDMETHOD(f569)();
  2554. STDMETHOD(f570)();
  2555. STDMETHOD(f571)();
  2556. STDMETHOD(f572)();
  2557. STDMETHOD(f573)();
  2558. STDMETHOD(f574)();
  2559. STDMETHOD(f575)();
  2560. STDMETHOD(f576)();
  2561. STDMETHOD(f577)();
  2562. STDMETHOD(f578)();
  2563. STDMETHOD(f579)();
  2564. STDMETHOD(f580)();
  2565. STDMETHOD(f581)();
  2566. STDMETHOD(f582)();
  2567. STDMETHOD(f583)();
  2568. STDMETHOD(f584)();
  2569. STDMETHOD(f585)();
  2570. STDMETHOD(f586)();
  2571. STDMETHOD(f587)();
  2572. STDMETHOD(f588)();
  2573. STDMETHOD(f589)();
  2574. STDMETHOD(f590)();
  2575. STDMETHOD(f591)();
  2576. STDMETHOD(f592)();
  2577. STDMETHOD(f593)();
  2578. STDMETHOD(f594)();
  2579. STDMETHOD(f595)();
  2580. STDMETHOD(f596)();
  2581. STDMETHOD(f597)();
  2582. STDMETHOD(f598)();
  2583. STDMETHOD(f599)();
  2584. STDMETHOD(f600)();
  2585. STDMETHOD(f601)();
  2586. STDMETHOD(f602)();
  2587. STDMETHOD(f603)();
  2588. STDMETHOD(f604)();
  2589. STDMETHOD(f605)();
  2590. STDMETHOD(f606)();
  2591. STDMETHOD(f607)();
  2592. STDMETHOD(f608)();
  2593. STDMETHOD(f609)();
  2594. STDMETHOD(f610)();
  2595. STDMETHOD(f611)();
  2596. STDMETHOD(f612)();
  2597. STDMETHOD(f613)();
  2598. STDMETHOD(f614)();
  2599. STDMETHOD(f615)();
  2600. STDMETHOD(f616)();
  2601. STDMETHOD(f617)();
  2602. STDMETHOD(f618)();
  2603. STDMETHOD(f619)();
  2604. STDMETHOD(f620)();
  2605. STDMETHOD(f621)();
  2606. STDMETHOD(f622)();
  2607. STDMETHOD(f623)();
  2608. STDMETHOD(f624)();
  2609. STDMETHOD(f625)();
  2610. STDMETHOD(f626)();
  2611. STDMETHOD(f627)();
  2612. STDMETHOD(f628)();
  2613. STDMETHOD(f629)();
  2614. STDMETHOD(f630)();
  2615. STDMETHOD(f631)();
  2616. STDMETHOD(f632)();
  2617. STDMETHOD(f633)();
  2618. STDMETHOD(f634)();
  2619. STDMETHOD(f635)();
  2620. STDMETHOD(f636)();
  2621. STDMETHOD(f637)();
  2622. STDMETHOD(f638)();
  2623. STDMETHOD(f639)();
  2624. STDMETHOD(f640)();
  2625. STDMETHOD(f641)();
  2626. STDMETHOD(f642)();
  2627. STDMETHOD(f643)();
  2628. STDMETHOD(f644)();
  2629. STDMETHOD(f645)();
  2630. STDMETHOD(f646)();
  2631. STDMETHOD(f647)();
  2632. STDMETHOD(f648)();
  2633. STDMETHOD(f649)();
  2634. STDMETHOD(f650)();
  2635. STDMETHOD(f651)();
  2636. STDMETHOD(f652)();
  2637. STDMETHOD(f653)();
  2638. STDMETHOD(f654)();
  2639. STDMETHOD(f655)();
  2640. STDMETHOD(f656)();
  2641. STDMETHOD(f657)();
  2642. STDMETHOD(f658)();
  2643. STDMETHOD(f659)();
  2644. STDMETHOD(f660)();
  2645. STDMETHOD(f661)();
  2646. STDMETHOD(f662)();
  2647. STDMETHOD(f663)();
  2648. STDMETHOD(f664)();
  2649. STDMETHOD(f665)();
  2650. STDMETHOD(f666)();
  2651. STDMETHOD(f667)();
  2652. STDMETHOD(f668)();
  2653. STDMETHOD(f669)();
  2654. STDMETHOD(f670)();
  2655. STDMETHOD(f671)();
  2656. STDMETHOD(f672)();
  2657. STDMETHOD(f673)();
  2658. STDMETHOD(f674)();
  2659. STDMETHOD(f675)();
  2660. STDMETHOD(f676)();
  2661. STDMETHOD(f677)();
  2662. STDMETHOD(f678)();
  2663. STDMETHOD(f679)();
  2664. STDMETHOD(f680)();
  2665. STDMETHOD(f681)();
  2666. STDMETHOD(f682)();
  2667. STDMETHOD(f683)();
  2668. STDMETHOD(f684)();
  2669. STDMETHOD(f685)();
  2670. STDMETHOD(f686)();
  2671. STDMETHOD(f687)();
  2672. STDMETHOD(f688)();
  2673. STDMETHOD(f689)();
  2674. STDMETHOD(f690)();
  2675. STDMETHOD(f691)();
  2676. STDMETHOD(f692)();
  2677. STDMETHOD(f693)();
  2678. STDMETHOD(f694)();
  2679. STDMETHOD(f695)();
  2680. STDMETHOD(f696)();
  2681. STDMETHOD(f697)();
  2682. STDMETHOD(f698)();
  2683. STDMETHOD(f699)();
  2684. STDMETHOD(f700)();
  2685. STDMETHOD(f701)();
  2686. STDMETHOD(f702)();
  2687. STDMETHOD(f703)();
  2688. STDMETHOD(f704)();
  2689. STDMETHOD(f705)();
  2690. STDMETHOD(f706)();
  2691. STDMETHOD(f707)();
  2692. STDMETHOD(f708)();
  2693. STDMETHOD(f709)();
  2694. STDMETHOD(f710)();
  2695. STDMETHOD(f711)();
  2696. STDMETHOD(f712)();
  2697. STDMETHOD(f713)();
  2698. STDMETHOD(f714)();
  2699. STDMETHOD(f715)();
  2700. STDMETHOD(f716)();
  2701. STDMETHOD(f717)();
  2702. STDMETHOD(f718)();
  2703. STDMETHOD(f719)();
  2704. STDMETHOD(f720)();
  2705. STDMETHOD(f721)();
  2706. STDMETHOD(f722)();
  2707. STDMETHOD(f723)();
  2708. STDMETHOD(f724)();
  2709. STDMETHOD(f725)();
  2710. STDMETHOD(f726)();
  2711. STDMETHOD(f727)();
  2712. STDMETHOD(f728)();
  2713. STDMETHOD(f729)();
  2714. STDMETHOD(f730)();
  2715. STDMETHOD(f731)();
  2716. STDMETHOD(f732)();
  2717. STDMETHOD(f733)();
  2718. STDMETHOD(f734)();
  2719. STDMETHOD(f735)();
  2720. STDMETHOD(f736)();
  2721. STDMETHOD(f737)();
  2722. STDMETHOD(f738)();
  2723. STDMETHOD(f739)();
  2724. STDMETHOD(f740)();
  2725. STDMETHOD(f741)();
  2726. STDMETHOD(f742)();
  2727. STDMETHOD(f743)();
  2728. STDMETHOD(f744)();
  2729. STDMETHOD(f745)();
  2730. STDMETHOD(f746)();
  2731. STDMETHOD(f747)();
  2732. STDMETHOD(f748)();
  2733. STDMETHOD(f749)();
  2734. STDMETHOD(f750)();
  2735. STDMETHOD(f751)();
  2736. STDMETHOD(f752)();
  2737. STDMETHOD(f753)();
  2738. STDMETHOD(f754)();
  2739. STDMETHOD(f755)();
  2740. STDMETHOD(f756)();
  2741. STDMETHOD(f757)();
  2742. STDMETHOD(f758)();
  2743. STDMETHOD(f759)();
  2744. STDMETHOD(f760)();
  2745. STDMETHOD(f761)();
  2746. STDMETHOD(f762)();
  2747. STDMETHOD(f763)();
  2748. STDMETHOD(f764)();
  2749. STDMETHOD(f765)();
  2750. STDMETHOD(f766)();
  2751. STDMETHOD(f767)();
  2752. STDMETHOD(f768)();
  2753. STDMETHOD(f769)();
  2754. STDMETHOD(f770)();
  2755. STDMETHOD(f771)();
  2756. STDMETHOD(f772)();
  2757. STDMETHOD(f773)();
  2758. STDMETHOD(f774)();
  2759. STDMETHOD(f775)();
  2760. STDMETHOD(f776)();
  2761. STDMETHOD(f777)();
  2762. STDMETHOD(f778)();
  2763. STDMETHOD(f779)();
  2764. STDMETHOD(f780)();
  2765. STDMETHOD(f781)();
  2766. STDMETHOD(f782)();
  2767. STDMETHOD(f783)();
  2768. STDMETHOD(f784)();
  2769. STDMETHOD(f785)();
  2770. STDMETHOD(f786)();
  2771. STDMETHOD(f787)();
  2772. STDMETHOD(f788)();
  2773. STDMETHOD(f789)();
  2774. STDMETHOD(f790)();
  2775. STDMETHOD(f791)();
  2776. STDMETHOD(f792)();
  2777. STDMETHOD(f793)();
  2778. STDMETHOD(f794)();
  2779. STDMETHOD(f795)();
  2780. STDMETHOD(f796)();
  2781. STDMETHOD(f797)();
  2782. STDMETHOD(f798)();
  2783. STDMETHOD(f799)();
  2784. STDMETHOD(f800)();
  2785. STDMETHOD(f801)();
  2786. STDMETHOD(f802)();
  2787. STDMETHOD(f803)();
  2788. STDMETHOD(f804)();
  2789. STDMETHOD(f805)();
  2790. STDMETHOD(f806)();
  2791. STDMETHOD(f807)();
  2792. STDMETHOD(f808)();
  2793. STDMETHOD(f809)();
  2794. STDMETHOD(f810)();
  2795. STDMETHOD(f811)();
  2796. STDMETHOD(f812)();
  2797. STDMETHOD(f813)();
  2798. STDMETHOD(f814)();
  2799. STDMETHOD(f815)();
  2800. STDMETHOD(f816)();
  2801. STDMETHOD(f817)();
  2802. STDMETHOD(f818)();
  2803. STDMETHOD(f819)();
  2804. STDMETHOD(f820)();
  2805. STDMETHOD(f821)();
  2806. STDMETHOD(f822)();
  2807. STDMETHOD(f823)();
  2808. STDMETHOD(f824)();
  2809. STDMETHOD(f825)();
  2810. STDMETHOD(f826)();
  2811. STDMETHOD(f827)();
  2812. STDMETHOD(f828)();
  2813. STDMETHOD(f829)();
  2814. STDMETHOD(f830)();
  2815. STDMETHOD(f831)();
  2816. STDMETHOD(f832)();
  2817. STDMETHOD(f833)();
  2818. STDMETHOD(f834)();
  2819. STDMETHOD(f835)();
  2820. STDMETHOD(f836)();
  2821. STDMETHOD(f837)();
  2822. STDMETHOD(f838)();
  2823. STDMETHOD(f839)();
  2824. STDMETHOD(f840)();
  2825. STDMETHOD(f841)();
  2826. STDMETHOD(f842)();
  2827. STDMETHOD(f843)();
  2828. STDMETHOD(f844)();
  2829. STDMETHOD(f845)();
  2830. STDMETHOD(f846)();
  2831. STDMETHOD(f847)();
  2832. STDMETHOD(f848)();
  2833. STDMETHOD(f849)();
  2834. STDMETHOD(f850)();
  2835. STDMETHOD(f851)();
  2836. STDMETHOD(f852)();
  2837. STDMETHOD(f853)();
  2838. STDMETHOD(f854)();
  2839. STDMETHOD(f855)();
  2840. STDMETHOD(f856)();
  2841. STDMETHOD(f857)();
  2842. STDMETHOD(f858)();
  2843. STDMETHOD(f859)();
  2844. STDMETHOD(f860)();
  2845. STDMETHOD(f861)();
  2846. STDMETHOD(f862)();
  2847. STDMETHOD(f863)();
  2848. STDMETHOD(f864)();
  2849. STDMETHOD(f865)();
  2850. STDMETHOD(f866)();
  2851. STDMETHOD(f867)();
  2852. STDMETHOD(f868)();
  2853. STDMETHOD(f869)();
  2854. STDMETHOD(f870)();
  2855. STDMETHOD(f871)();
  2856. STDMETHOD(f872)();
  2857. STDMETHOD(f873)();
  2858. STDMETHOD(f874)();
  2859. STDMETHOD(f875)();
  2860. STDMETHOD(f876)();
  2861. STDMETHOD(f877)();
  2862. STDMETHOD(f878)();
  2863. STDMETHOD(f879)();
  2864. STDMETHOD(f880)();
  2865. STDMETHOD(f881)();
  2866. STDMETHOD(f882)();
  2867. STDMETHOD(f883)();
  2868. STDMETHOD(f884)();
  2869. STDMETHOD(f885)();
  2870. STDMETHOD(f886)();
  2871. STDMETHOD(f887)();
  2872. STDMETHOD(f888)();
  2873. STDMETHOD(f889)();
  2874. STDMETHOD(f890)();
  2875. STDMETHOD(f891)();
  2876. STDMETHOD(f892)();
  2877. STDMETHOD(f893)();
  2878. STDMETHOD(f894)();
  2879. STDMETHOD(f895)();
  2880. STDMETHOD(f896)();
  2881. STDMETHOD(f897)();
  2882. STDMETHOD(f898)();
  2883. STDMETHOD(f899)();
  2884. STDMETHOD(f900)();
  2885. STDMETHOD(f901)();
  2886. STDMETHOD(f902)();
  2887. STDMETHOD(f903)();
  2888. STDMETHOD(f904)();
  2889. STDMETHOD(f905)();
  2890. STDMETHOD(f906)();
  2891. STDMETHOD(f907)();
  2892. STDMETHOD(f908)();
  2893. STDMETHOD(f909)();
  2894. STDMETHOD(f910)();
  2895. STDMETHOD(f911)();
  2896. STDMETHOD(f912)();
  2897. STDMETHOD(f913)();
  2898. STDMETHOD(f914)();
  2899. STDMETHOD(f915)();
  2900. STDMETHOD(f916)();
  2901. STDMETHOD(f917)();
  2902. STDMETHOD(f918)();
  2903. STDMETHOD(f919)();
  2904. STDMETHOD(f920)();
  2905. STDMETHOD(f921)();
  2906. STDMETHOD(f922)();
  2907. STDMETHOD(f923)();
  2908. STDMETHOD(f924)();
  2909. STDMETHOD(f925)();
  2910. STDMETHOD(f926)();
  2911. STDMETHOD(f927)();
  2912. STDMETHOD(f928)();
  2913. STDMETHOD(f929)();
  2914. STDMETHOD(f930)();
  2915. STDMETHOD(f931)();
  2916. STDMETHOD(f932)();
  2917. STDMETHOD(f933)();
  2918. STDMETHOD(f934)();
  2919. STDMETHOD(f935)();
  2920. STDMETHOD(f936)();
  2921. STDMETHOD(f937)();
  2922. STDMETHOD(f938)();
  2923. STDMETHOD(f939)();
  2924. STDMETHOD(f940)();
  2925. STDMETHOD(f941)();
  2926. STDMETHOD(f942)();
  2927. STDMETHOD(f943)();
  2928. STDMETHOD(f944)();
  2929. STDMETHOD(f945)();
  2930. STDMETHOD(f946)();
  2931. STDMETHOD(f947)();
  2932. STDMETHOD(f948)();
  2933. STDMETHOD(f949)();
  2934. STDMETHOD(f950)();
  2935. STDMETHOD(f951)();
  2936. STDMETHOD(f952)();
  2937. STDMETHOD(f953)();
  2938. STDMETHOD(f954)();
  2939. STDMETHOD(f955)();
  2940. STDMETHOD(f956)();
  2941. STDMETHOD(f957)();
  2942. STDMETHOD(f958)();
  2943. STDMETHOD(f959)();
  2944. STDMETHOD(f960)();
  2945. STDMETHOD(f961)();
  2946. STDMETHOD(f962)();
  2947. STDMETHOD(f963)();
  2948. STDMETHOD(f964)();
  2949. STDMETHOD(f965)();
  2950. STDMETHOD(f966)();
  2951. STDMETHOD(f967)();
  2952. STDMETHOD(f968)();
  2953. STDMETHOD(f969)();
  2954. STDMETHOD(f970)();
  2955. STDMETHOD(f971)();
  2956. STDMETHOD(f972)();
  2957. STDMETHOD(f973)();
  2958. STDMETHOD(f974)();
  2959. STDMETHOD(f975)();
  2960. STDMETHOD(f976)();
  2961. STDMETHOD(f977)();
  2962. STDMETHOD(f978)();
  2963. STDMETHOD(f979)();
  2964. STDMETHOD(f980)();
  2965. STDMETHOD(f981)();
  2966. STDMETHOD(f982)();
  2967. STDMETHOD(f983)();
  2968. STDMETHOD(f984)();
  2969. STDMETHOD(f985)();
  2970. STDMETHOD(f986)();
  2971. STDMETHOD(f987)();
  2972. STDMETHOD(f988)();
  2973. STDMETHOD(f989)();
  2974. STDMETHOD(f990)();
  2975. STDMETHOD(f991)();
  2976. STDMETHOD(f992)();
  2977. STDMETHOD(f993)();
  2978. STDMETHOD(f994)();
  2979. STDMETHOD(f995)();
  2980. STDMETHOD(f996)();
  2981. STDMETHOD(f997)();
  2982. STDMETHOD(f998)();
  2983. STDMETHOD(f999)();
  2984. STDMETHOD(f1000)();
  2985. STDMETHOD(f1001)();
  2986. STDMETHOD(f1002)();
  2987. STDMETHOD(f1003)();
  2988. STDMETHOD(f1004)();
  2989. STDMETHOD(f1005)();
  2990. STDMETHOD(f1006)();
  2991. STDMETHOD(f1007)();
  2992. STDMETHOD(f1008)();
  2993. STDMETHOD(f1009)();
  2994. STDMETHOD(f1010)();
  2995. STDMETHOD(f1011)();
  2996. STDMETHOD(f1012)();
  2997. STDMETHOD(f1013)();
  2998. STDMETHOD(f1014)();
  2999. STDMETHOD(f1015)();
  3000. STDMETHOD(f1016)();
  3001. STDMETHOD(f1017)();
  3002. STDMETHOD(f1018)();
  3003. STDMETHOD(f1019)();
  3004. STDMETHOD(f1020)();
  3005. STDMETHOD(f1021)();
  3006. STDMETHOD(f1022)();
  3007. STDMETHOD(f1023)();
  3008. _QIThunk(IUnknown* pOrig, LPCTSTR p, const IID& i, UINT n, bool b)
  3009. {
  3010. m_lpszClassName = p;
  3011. m_iid = i;
  3012. m_nIndex = n;
  3013. m_dwRef = 0;
  3014. m_dwMaxRef = 0;
  3015. m_pUnk = pOrig;
  3016. m_bBreak = b;
  3017. m_bNonAddRefThunk = false;
  3018. }
  3019. IUnknown* m_pUnk;
  3020. long m_dwRef;
  3021. long m_dwMaxRef;
  3022. LPCTSTR m_lpszClassName;
  3023. IID m_iid;
  3024. UINT m_nIndex;
  3025. bool m_bBreak;
  3026. bool m_bNonAddRefThunk;
  3027. void Dump()
  3028. {
  3029. TCHAR buf[512];
  3030. if (m_dwRef != 0)
  3031. {
  3032. wsprintf(buf, _T("ATL: QIThunk - %-10d\tLEAK :\tObject = 0x%08x\tRefcount = %d\tMaxRefCount = %d\t"), m_nIndex, m_pUnk, m_dwRef, m_dwMaxRef);
  3033. OutputDebugString(buf);
  3034. AtlDumpIID(m_iid, m_lpszClassName, S_OK);
  3035. }
  3036. else
  3037. {
  3038. wsprintf(buf, _T("ATL: QIThunk - %-10d\tNonAddRef LEAK :\tObject = 0x%08x\t"), m_nIndex, m_pUnk);
  3039. OutputDebugString(buf);
  3040. AtlDumpIID(m_iid, m_lpszClassName, S_OK);
  3041. }
  3042. }
  3043. };
  3044. }; // namespace ATL
  3045. namespace ATL
  3046. {
  3047. /////////////////////////////////////////////////////////////////////////////
  3048. // Dual argument helper classes
  3049. class _U_RECT
  3050. {
  3051. public:
  3052. _U_RECT(LPRECT lpRect) : m_lpRect(lpRect)
  3053. { }
  3054. _U_RECT(RECT& rc) : m_lpRect(&rc)
  3055. { }
  3056. LPRECT m_lpRect;
  3057. };
  3058. class _U_MENUorID
  3059. {
  3060. public:
  3061. _U_MENUorID(HMENU hMenu) : m_hMenu(hMenu)
  3062. { }
  3063. _U_MENUorID(UINT nID) : m_hMenu((HMENU)(UINT_PTR)nID)
  3064. { }
  3065. HMENU m_hMenu;
  3066. };
  3067. class _U_STRINGorID
  3068. {
  3069. public:
  3070. _U_STRINGorID(LPCTSTR lpString) : m_lpstr(lpString)
  3071. { }
  3072. _U_STRINGorID(UINT nID) : m_lpstr(MAKEINTRESOURCE(nID))
  3073. { }
  3074. LPCTSTR m_lpstr;
  3075. };
  3076. #ifdef _ATL_STATIC_REGISTRY
  3077. #define UpdateRegistryFromResource UpdateRegistryFromResourceS
  3078. #else
  3079. #define UpdateRegistryFromResource UpdateRegistryFromResourceD
  3080. #endif // _ATL_STATIC_REGISTRY
  3081. #ifndef _delayimp_h
  3082. extern "C" IMAGE_DOS_HEADER __ImageBase;
  3083. #endif
  3084. class CAtlBaseModule : public _ATL_BASE_MODULE
  3085. {
  3086. public :
  3087. static bool m_bInitFailed;
  3088. CAtlBaseModule() throw()
  3089. {
  3090. cbSize = sizeof(_ATL_BASE_MODULE);
  3091. m_hInst = m_hInstResource = reinterpret_cast<HINSTANCE>(&__ImageBase);
  3092. m_bNT5orWin98 = false;
  3093. OSVERSIONINFO version;
  3094. memset(&version, 0, sizeof(version));
  3095. version.dwOSVersionInfoSize = sizeof(version);
  3096. ::GetVersionEx(&version);
  3097. if(version.dwPlatformId == VER_PLATFORM_WIN32_NT)
  3098. {
  3099. if(version.dwMajorVersion >= 5)
  3100. {
  3101. m_bNT5orWin98 = true;
  3102. }
  3103. }
  3104. else if(version.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)
  3105. {
  3106. if((version.dwMajorVersion > 4) || ((version.dwMajorVersion == 4) &&
  3107. (version.dwMinorVersion > 0)))
  3108. {
  3109. m_bNT5orWin98 = true;
  3110. }
  3111. }
  3112. dwAtlBuildVer = _ATL_VER;
  3113. pguidVer = &GUID_ATLVer70;
  3114. if (FAILED(m_csResource.Init()))
  3115. {
  3116. ATLTRACE(atlTraceGeneral, 0, _T("ERROR : Unable to initialize critical section in CAtlBaseModule\n"));
  3117. ATLASSERT(0);
  3118. CAtlBaseModule::m_bInitFailed = true;
  3119. }
  3120. }
  3121. ~CAtlBaseModule() throw ()
  3122. {
  3123. }
  3124. HINSTANCE GetModuleInstance() throw()
  3125. {
  3126. return m_hInst;
  3127. }
  3128. HINSTANCE GetResourceInstance() throw()
  3129. {
  3130. return m_hInstResource;
  3131. }
  3132. HINSTANCE SetResourceInstance(HINSTANCE hInst) throw()
  3133. {
  3134. return static_cast< HINSTANCE >(InterlockedExchangePointer((void**)&m_hInstResource, hInst));
  3135. }
  3136. bool AddResourceInstance(HINSTANCE hInst) throw()
  3137. {
  3138. CComCritSecLock<CComCriticalSection> lock(m_csResource, false);
  3139. if (FAILED(lock.Lock()))
  3140. {
  3141. ATLTRACE(atlTraceGeneral, 0, _T("ERROR : Unable to lock critical section in CAtlBaseModule\n"));
  3142. ATLASSERT(0);
  3143. return false;
  3144. }
  3145. return m_rgResourceInstance.Add(hInst) != FALSE;
  3146. }
  3147. bool RemoveResourceInstance(HINSTANCE hInst) throw()
  3148. {
  3149. CComCritSecLock<CComCriticalSection> lock(m_csResource, false);
  3150. if (FAILED(lock.Lock()))
  3151. {
  3152. ATLTRACE(atlTraceGeneral, 0, _T("ERROR : Unable to lock critical section in CAtlBaseModule\n"));
  3153. ATLASSERT(0);
  3154. return false;
  3155. }
  3156. for (int i = 0; i < m_rgResourceInstance.GetSize(); i++)
  3157. {
  3158. if (m_rgResourceInstance[i] == hInst)
  3159. {
  3160. m_rgResourceInstance.RemoveAt(i);
  3161. return true;
  3162. }
  3163. }
  3164. return false;
  3165. }
  3166. HINSTANCE GetHInstanceAt(int i) throw()
  3167. {
  3168. CComCritSecLock<CComCriticalSection> lock(m_csResource, false);
  3169. if (FAILED(lock.Lock()))
  3170. {
  3171. ATLTRACE(atlTraceGeneral, 0, _T("ERROR : Unable to lock critical section in CAtlBaseModule\n"));
  3172. ATLASSERT(0);
  3173. return NULL;
  3174. }
  3175. if (i > m_rgResourceInstance.GetSize() || i < 0)
  3176. {
  3177. return NULL;
  3178. }
  3179. if (i == m_rgResourceInstance.GetSize())
  3180. {
  3181. return m_hInstResource;
  3182. }
  3183. return m_rgResourceInstance[i];
  3184. }
  3185. };
  3186. __declspec(selectany) bool CAtlBaseModule::m_bInitFailed = false;
  3187. extern CAtlBaseModule _AtlBaseModule;
  3188. inline const ATLSTRINGRESOURCEIMAGE* AtlGetStringResourceImage( UINT id )
  3189. {
  3190. const ATLSTRINGRESOURCEIMAGE* p = NULL;
  3191. HINSTANCE hInst = _AtlBaseModule.GetHInstanceAt(0);
  3192. for (int i = 1; hInst != NULL && p == NULL; hInst = _AtlBaseModule.GetHInstanceAt(i++))
  3193. {
  3194. p = AtlGetStringResourceImage(hInst, id);
  3195. }
  3196. return p;
  3197. }
  3198. inline const ATLSTRINGRESOURCEIMAGE* AtlGetStringResourceImage( UINT id, WORD wLanguage )
  3199. {
  3200. const ATLSTRINGRESOURCEIMAGE* p = NULL;
  3201. HINSTANCE hInst = _AtlBaseModule.GetHInstanceAt(0);
  3202. for (int i = 1; hInst != NULL && p == NULL; hInst = _AtlBaseModule.GetHInstanceAt(i++))
  3203. {
  3204. p = AtlGetStringResourceImage(hInst, id, wLanguage);
  3205. }
  3206. return p;
  3207. }
  3208. inline int AtlLoadString(UINT nID, LPTSTR lpBuffer, int nBufferMax) throw()
  3209. {
  3210. HINSTANCE hInst = _AtlBaseModule.GetHInstanceAt(0);
  3211. int nRet = 0;
  3212. for (int i = 1; hInst != NULL && nRet == 0; hInst = _AtlBaseModule.GetHInstanceAt(i++))
  3213. {
  3214. nRet = LoadString(hInst, nID, lpBuffer, nBufferMax);
  3215. }
  3216. return nRet;
  3217. }
  3218. inline HINSTANCE AtlFindResourceInstance(LPCTSTR lpName, LPCTSTR lpType, WORD wLanguage = 0) throw()
  3219. {
  3220. ATLASSERT(lpType != RT_STRING); // Call AtlGetStringResourceImage to get the string
  3221. if (lpType == RT_STRING)
  3222. return NULL;
  3223. if (IS_INTRESOURCE(lpType))
  3224. {
  3225. if (lpType == RT_ICON)
  3226. {
  3227. lpType = RT_GROUP_ICON;
  3228. }
  3229. else if (lpType == RT_CURSOR)
  3230. {
  3231. lpType = RT_GROUP_CURSOR;
  3232. }
  3233. }
  3234. HINSTANCE hInst = _AtlBaseModule.GetHInstanceAt(0);
  3235. HRSRC hResource = NULL;
  3236. for (int i = 1; hInst != NULL; hInst = _AtlBaseModule.GetHInstanceAt(i++))
  3237. {
  3238. hResource = ::FindResourceEx(hInst, lpType, lpName, wLanguage);
  3239. if (hResource != NULL)
  3240. {
  3241. return hInst;
  3242. }
  3243. }
  3244. return NULL;
  3245. }
  3246. inline HINSTANCE AtlFindResourceInstance(UINT nID, LPCTSTR lpType, WORD wLanguage = 0) throw()
  3247. {
  3248. return AtlFindResourceInstance(MAKEINTRESOURCE(nID), lpType, wLanguage);
  3249. }
  3250. class CAtlDebugInterfacesModule
  3251. {
  3252. public:
  3253. CAtlDebugInterfacesModule() throw() :
  3254. m_nIndexQI( 0 ),
  3255. m_nIndexBreakAt( 0 )
  3256. {
  3257. if (FAILED(m_cs.Init()))
  3258. {
  3259. ATLTRACE(atlTraceCOM, 0, _T("ERROR : Unable to initialize critical section in CAtlDebugInterfacesModule\n"));
  3260. ATLASSERT(0);
  3261. CAtlBaseModule::m_bInitFailed = true;
  3262. }
  3263. }
  3264. ~CAtlDebugInterfacesModule() throw()
  3265. {
  3266. DumpLeakedThunks();
  3267. }
  3268. HRESULT AddThunk(IUnknown** pp, LPCTSTR lpsz, REFIID iid) throw()
  3269. {
  3270. if ((pp == NULL) || (*pp == NULL))
  3271. return E_POINTER;
  3272. IUnknown* p = *pp;
  3273. _QIThunk* pThunk = NULL;
  3274. CComCritSecLock<CComCriticalSection> lock(m_cs, false);
  3275. HRESULT hr = lock.Lock();
  3276. if (FAILED(hr))
  3277. {
  3278. ATLTRACE(atlTraceCOM, 0, _T("ERROR : Unable to lock critical section in CAtlDebugInterfacesModule\n"));
  3279. ATLASSERT(0);
  3280. return hr;
  3281. }
  3282. // Check if exists already for identity
  3283. if (InlineIsEqualUnknown(iid))
  3284. {
  3285. for (int i = 0; i < m_aThunks.GetSize(); i++)
  3286. {
  3287. if (m_aThunks[i]->m_pUnk == p && InlineIsEqualGUID(m_aThunks[i]->m_iid, iid))
  3288. {
  3289. m_aThunks[i]->InternalAddRef();
  3290. pThunk = m_aThunks[i];
  3291. break;
  3292. }
  3293. }
  3294. }
  3295. if (pThunk == NULL)
  3296. {
  3297. ++m_nIndexQI;
  3298. if (m_nIndexBreakAt == m_nIndexQI)
  3299. DebugBreak();
  3300. ATLTRY(pThunk = new _QIThunk(p, lpsz, iid, m_nIndexQI, (m_nIndexBreakAt == m_nIndexQI)));
  3301. if (pThunk == NULL)
  3302. {
  3303. return E_OUTOFMEMORY;
  3304. }
  3305. pThunk->InternalAddRef();
  3306. m_aThunks.Add(pThunk);
  3307. }
  3308. *pp = (IUnknown*)pThunk;
  3309. return S_OK;
  3310. }
  3311. HRESULT AddNonAddRefThunk(IUnknown* p, LPCTSTR lpsz, IUnknown** ppThunkRet) throw()
  3312. {
  3313. if (ppThunkRet == NULL)
  3314. return E_POINTER;
  3315. *ppThunkRet = NULL;
  3316. _QIThunk* pThunk = NULL;
  3317. CComCritSecLock<CComCriticalSection> lock(m_cs, false);
  3318. HRESULT hr = lock.Lock();
  3319. if (FAILED(hr))
  3320. {
  3321. ATLTRACE(atlTraceCOM, 0, _T("ERROR : Unable to lock critical section in CAtlDebugInterfacesModule\n"));
  3322. ATLASSERT(0);
  3323. return hr;
  3324. }
  3325. // Check if exists already for identity
  3326. for (int i = 0; i < m_aThunks.GetSize(); i++)
  3327. {
  3328. if (m_aThunks[i]->m_pUnk == p)
  3329. {
  3330. m_aThunks[i]->m_bNonAddRefThunk = true;
  3331. pThunk = m_aThunks[i];
  3332. break;
  3333. }
  3334. }
  3335. if (pThunk == NULL)
  3336. {
  3337. ++m_nIndexQI;
  3338. if (m_nIndexBreakAt == m_nIndexQI)
  3339. DebugBreak();
  3340. ATLTRY(pThunk = new _QIThunk(p, lpsz, __uuidof(IUnknown), m_nIndexQI, (m_nIndexBreakAt == m_nIndexQI)));
  3341. if (pThunk == NULL)
  3342. {
  3343. return E_OUTOFMEMORY;
  3344. }
  3345. pThunk->m_bNonAddRefThunk = true;
  3346. m_aThunks.Add(pThunk);
  3347. }
  3348. *ppThunkRet = (IUnknown*)pThunk;
  3349. return S_OK;;
  3350. }
  3351. void DeleteNonAddRefThunk(IUnknown* pUnk) throw()
  3352. {
  3353. CComCritSecLock<CComCriticalSection> lock(m_cs, false);
  3354. HRESULT hr = lock.Lock();
  3355. if (FAILED(hr))
  3356. {
  3357. ATLTRACE(atlTraceCOM, 0, _T("ERROR : Unable to lock critical section in CAtlDebugInterfacesModule\n"));
  3358. ATLASSERT(0);
  3359. return;
  3360. }
  3361. for (int i = 0; i < m_aThunks.GetSize(); i++)
  3362. {
  3363. if (m_aThunks[i]->m_bNonAddRefThunk && m_aThunks[i]->m_pUnk == pUnk)
  3364. {
  3365. delete m_aThunks[i];
  3366. m_aThunks.RemoveAt(i);
  3367. break;
  3368. }
  3369. }
  3370. }
  3371. void DeleteThunk(_QIThunk* p) throw()
  3372. {
  3373. CComCritSecLock<CComCriticalSection> lock(m_cs, false);
  3374. HRESULT hr = lock.Lock();
  3375. if (FAILED(hr))
  3376. {
  3377. ATLTRACE(atlTraceCOM, 0, _T("ERROR : Unable to lock critical section in CAtlDebugInterfacesModule\n"));
  3378. ATLASSERT(0);
  3379. return;
  3380. }
  3381. int nIndex = m_aThunks.Find(p);
  3382. if (nIndex != -1)
  3383. {
  3384. m_aThunks[nIndex]->m_pUnk = NULL;
  3385. delete m_aThunks[nIndex];
  3386. m_aThunks.RemoveAt(nIndex);
  3387. }
  3388. }
  3389. bool DumpLeakedThunks()
  3390. {
  3391. bool b = false;
  3392. for (int i = 0; i < m_aThunks.GetSize(); i++)
  3393. {
  3394. b = true;
  3395. m_aThunks[i]->Dump();
  3396. delete m_aThunks[i];
  3397. }
  3398. m_aThunks.RemoveAll();
  3399. return b;
  3400. }
  3401. public:
  3402. UINT m_nIndexQI;
  3403. UINT m_nIndexBreakAt;
  3404. CSimpleArray<_QIThunk*> m_aThunks;
  3405. CComCriticalSection m_cs;
  3406. };
  3407. extern CAtlDebugInterfacesModule _AtlDebugInterfacesModule;
  3408. class CAtlComModule : public _ATL_COM_MODULE
  3409. {
  3410. public:
  3411. CAtlComModule() throw()
  3412. {
  3413. cbSize = sizeof(_ATL_COM_MODULE);
  3414. m_hInstTypeLib = reinterpret_cast<HINSTANCE>(&__ImageBase);
  3415. m_ppAutoObjMapFirst = &__pobjMapEntryFirst + 1;
  3416. m_ppAutoObjMapLast = &__pobjMapEntryLast;
  3417. if (FAILED(m_csObjMap.Init()))
  3418. {
  3419. ATLTRACE(atlTraceCOM, 0, _T("ERROR : Unable to initialize critical section in CAtlComModule\n"));
  3420. ATLASSERT(0);
  3421. CAtlBaseModule::m_bInitFailed = true;
  3422. }
  3423. }
  3424. ~CAtlComModule()
  3425. {
  3426. Term();
  3427. }
  3428. // Called from ~CAtlComModule or from ~CAtlExeModule.
  3429. void Term()
  3430. {
  3431. if (cbSize == 0)
  3432. return;
  3433. for (_ATL_OBJMAP_ENTRY** ppEntry = m_ppAutoObjMapFirst; ppEntry < m_ppAutoObjMapLast; ppEntry++)
  3434. {
  3435. if (*ppEntry != NULL)
  3436. {
  3437. _ATL_OBJMAP_ENTRY* pEntry = *ppEntry;
  3438. if (pEntry->pCF != NULL)
  3439. pEntry->pCF->Release();
  3440. pEntry->pCF = NULL;
  3441. }
  3442. }
  3443. // Set to 0 to indicate that this function has been called
  3444. // At this point no one should be concerned about cbsize
  3445. // having the correct value
  3446. cbSize = 0;
  3447. }
  3448. // Registry support (helpers)
  3449. HRESULT RegisterTypeLib()
  3450. {
  3451. return AtlRegisterTypeLib(m_hInstTypeLib, NULL);
  3452. }
  3453. HRESULT RegisterTypeLib(LPCTSTR lpszIndex)
  3454. {
  3455. USES_CONVERSION;
  3456. return AtlRegisterTypeLib(m_hInstTypeLib, T2COLE(lpszIndex));
  3457. }
  3458. HRESULT UnRegisterTypeLib()
  3459. {
  3460. return AtlUnRegisterTypeLib(m_hInstTypeLib, NULL);
  3461. }
  3462. HRESULT UnRegisterTypeLib(LPCTSTR lpszIndex)
  3463. {
  3464. USES_CONVERSION;
  3465. return AtlUnRegisterTypeLib(m_hInstTypeLib, T2COLE(lpszIndex));
  3466. }
  3467. // RegisterServer walks the ATL Autogenerated object map and registers each object in the map
  3468. // If pCLSID is not NULL then only the object referred to by pCLSID is registered (The default case)
  3469. // otherwise all the objects are registered
  3470. HRESULT RegisterServer(BOOL bRegTypeLib = FALSE, const CLSID* pCLSID = NULL)
  3471. {
  3472. return AtlComModuleRegisterServer(this, bRegTypeLib, pCLSID);
  3473. }
  3474. // UnregisterServer walks the ATL Autogenerated object map and unregisters each object in the map
  3475. // If pCLSID is not NULL then only the object referred to by pCLSID is unregistered (The default case)
  3476. // otherwise all the objects are unregistered.
  3477. HRESULT UnregisterServer(BOOL bRegTypeLib = FALSE, const CLSID* pCLSID = NULL)
  3478. {
  3479. return AtlComModuleUnregisterServer(this, bRegTypeLib, pCLSID);
  3480. }
  3481. // Implementation
  3482. // Call ObjectMain for all the objects.
  3483. void ExecuteObjectMain(bool bStarting)
  3484. {
  3485. for (_ATL_OBJMAP_ENTRY** ppEntry = m_ppAutoObjMapFirst; ppEntry < m_ppAutoObjMapLast; ppEntry++)
  3486. {
  3487. if (*ppEntry != NULL)
  3488. (*ppEntry)->pfnObjectMain(bStarting);
  3489. }
  3490. }
  3491. };
  3492. class CAtlWinModule : public _ATL_WIN_MODULE
  3493. {
  3494. public:
  3495. CAtlWinModule()
  3496. {
  3497. cbSize = sizeof(_ATL_WIN_MODULE);
  3498. HRESULT hr = AtlWinModuleInit(this);
  3499. if (FAILED(hr))
  3500. CAtlBaseModule::m_bInitFailed = true;
  3501. }
  3502. ~CAtlWinModule()
  3503. {
  3504. AtlWinModuleTerm(this, _AtlBaseModule.GetModuleInstance());
  3505. }
  3506. void AddCreateWndData(_AtlCreateWndData* pData, void* pObject)
  3507. {
  3508. AtlWinModuleAddCreateWndData(this, pData, pObject);
  3509. }
  3510. void* ExtractCreateWndData()
  3511. {
  3512. return AtlWinModuleExtractCreateWndData(this);
  3513. }
  3514. };
  3515. class CAtlModule;
  3516. __declspec(selectany) CAtlModule* _pAtlModule = NULL;
  3517. class CRegObject;
  3518. class ATL_NO_VTABLE CAtlModule : public _ATL_MODULE
  3519. {
  3520. public :
  3521. static GUID m_libid;
  3522. IGlobalInterfaceTable* m_pGIT;
  3523. CAtlModule() throw()
  3524. {
  3525. // Should have only one instance of a class
  3526. // derived from CAtlModule in a project.
  3527. ATLASSERT(_pAtlModule == NULL);
  3528. cbSize = sizeof(_ATL_MODULE);
  3529. m_pTermFuncs = NULL;
  3530. m_nLockCnt = 0;
  3531. _pAtlModule = this;
  3532. if (FAILED(m_csStaticDataInitAndTypeInfo.Init()))
  3533. {
  3534. ATLTRACE(atlTraceGeneral, 0, _T("ERROR : Unable to initialize critical section in CAtlModule\n"));
  3535. ATLASSERT(0);
  3536. CAtlBaseModule::m_bInitFailed = true;
  3537. }
  3538. m_pGIT = NULL;
  3539. }
  3540. void Term() throw()
  3541. {
  3542. // cbSize == 0 indicates that Term has already been called
  3543. if (cbSize == 0)
  3544. return;
  3545. // Call term functions
  3546. if (m_pTermFuncs != NULL)
  3547. {
  3548. AtlCallTermFunc(this);
  3549. m_pTermFuncs = NULL;
  3550. }
  3551. if (m_pGIT != NULL)
  3552. m_pGIT->Release();
  3553. cbSize = 0;
  3554. }
  3555. ~CAtlModule() throw()
  3556. {
  3557. Term();
  3558. }
  3559. virtual LONG Lock() throw()
  3560. {
  3561. return CComGlobalsThreadModel::Increment(&m_nLockCnt);
  3562. }
  3563. virtual LONG Unlock() throw()
  3564. {
  3565. return CComGlobalsThreadModel::Decrement(&m_nLockCnt);
  3566. }
  3567. virtual LONG GetLockCount() throw()
  3568. {
  3569. return m_nLockCnt;
  3570. }
  3571. HRESULT AddTermFunc(_ATL_TERMFUNC* pFunc, DWORD_PTR dw) throw()
  3572. {
  3573. return AtlModuleAddTermFunc(this, pFunc, dw);
  3574. }
  3575. virtual HRESULT GetGITPtr(IGlobalInterfaceTable** ppGIT) throw()
  3576. {
  3577. ATLASSERT(ppGIT != NULL);
  3578. if (ppGIT == NULL)
  3579. return E_POINTER;
  3580. HRESULT hr = S_OK;
  3581. if (m_pGIT == NULL)
  3582. {
  3583. hr = ::CoCreateInstance(CLSID_StdGlobalInterfaceTable, NULL, CLSCTX_INPROC_SERVER,
  3584. __uuidof(IGlobalInterfaceTable), (void**)&m_pGIT);
  3585. }
  3586. if (SUCCEEDED(hr))
  3587. {
  3588. ATLASSERT(m_pGIT != NULL);
  3589. *ppGIT = m_pGIT;
  3590. m_pGIT->AddRef();
  3591. }
  3592. return hr;
  3593. }
  3594. virtual HRESULT AddCommonRGSReplacements(IRegistrarBase* /*pRegistrar*/) throw()
  3595. {
  3596. return S_OK;
  3597. }
  3598. #if defined(_ATL_DLL) || defined(_ATL_DLL_IMPL)
  3599. // Resource-based Registration
  3600. HRESULT WINAPI UpdateRegistryFromResourceD(LPCTSTR lpszRes, BOOL bRegister,
  3601. struct _ATL_REGMAP_ENTRY* pMapEntries = NULL) throw()
  3602. {
  3603. USES_CONVERSION;
  3604. return UpdateRegistryFromResourceDHelper(T2COLE(lpszRes), bRegister, pMapEntries);
  3605. }
  3606. HRESULT WINAPI UpdateRegistryFromResourceD(UINT nResID, BOOL bRegister,
  3607. struct _ATL_REGMAP_ENTRY* pMapEntries = NULL) throw()
  3608. {
  3609. return UpdateRegistryFromResourceDHelper((LPCOLESTR)MAKEINTRESOURCE(nResID), bRegister, pMapEntries);
  3610. }
  3611. #endif
  3612. #ifdef _ATL_STATIC_REGISTRY
  3613. // Statically linking to Registry Ponent
  3614. HRESULT WINAPI UpdateRegistryFromResourceS(LPCTSTR lpszRes, BOOL bRegister,
  3615. struct _ATL_REGMAP_ENTRY* pMapEntries = NULL) throw();
  3616. HRESULT WINAPI UpdateRegistryFromResourceS(UINT nResID, BOOL bRegister,
  3617. struct _ATL_REGMAP_ENTRY* pMapEntries = NULL) throw();
  3618. #endif
  3619. // Implementation
  3620. #if defined(_ATL_DLL) || defined(_ATL_DLL_IMPL)
  3621. inline HRESULT WINAPI UpdateRegistryFromResourceDHelper(LPCOLESTR lpszRes, BOOL bRegister,
  3622. struct _ATL_REGMAP_ENTRY* pMapEntries = NULL) throw()
  3623. {
  3624. CComPtr<IRegistrar> spRegistrar;
  3625. HRESULT hr = AtlCreateRegistrar(&spRegistrar);
  3626. if (FAILED(hr))
  3627. return hr;
  3628. if (NULL != pMapEntries)
  3629. {
  3630. while (NULL != pMapEntries->szKey)
  3631. {
  3632. ATLASSERT(NULL != pMapEntries->szData);
  3633. spRegistrar->AddReplacement(pMapEntries->szKey, pMapEntries->szData);
  3634. pMapEntries++;
  3635. }
  3636. }
  3637. hr = AddCommonRGSReplacements(spRegistrar);
  3638. if (FAILED(hr))
  3639. return hr;
  3640. return AtlUpdateRegistryFromResourceD(_AtlBaseModule.GetModuleInstance(), lpszRes, bRegister,
  3641. NULL, spRegistrar);
  3642. }
  3643. #endif
  3644. static void EscapeSingleQuote(LPOLESTR lpDest, LPCOLESTR lp) throw()
  3645. {
  3646. while (*lp)
  3647. {
  3648. *lpDest++ = *lp;
  3649. if (*lp == '\'')
  3650. *lpDest++ = *lp;
  3651. lp++;
  3652. }
  3653. *lpDest = NULL;
  3654. }
  3655. // search for an occurence of string p2 in string p1
  3656. static LPCTSTR FindOneOf(LPCTSTR p1, LPCTSTR p2) throw()
  3657. {
  3658. while (p1 != NULL && *p1 != NULL)
  3659. {
  3660. LPCTSTR p = p2;
  3661. while (p != NULL && *p != NULL)
  3662. {
  3663. if (*p1 == *p)
  3664. return CharNext(p1);
  3665. p = CharNext(p);
  3666. }
  3667. p1 = CharNext(p1);
  3668. }
  3669. return NULL;
  3670. }
  3671. static int WordCmpI(LPCTSTR psz1, LPCTSTR psz2) throw()
  3672. {
  3673. TCHAR c1 = (TCHAR)CharUpper((LPTSTR)*psz1);
  3674. TCHAR c2 = (TCHAR)CharUpper((LPTSTR)*psz2);
  3675. while (c1 != NULL && c1 == c2 && c1 != ' ' && c1 != '\t')
  3676. {
  3677. psz1 = CharNext(psz1);
  3678. psz2 = CharNext(psz2);
  3679. c1 = (TCHAR)CharUpper((LPTSTR)*psz1);
  3680. c2 = (TCHAR)CharUpper((LPTSTR)*psz2);
  3681. }
  3682. if ((c1 == NULL || c1 == ' ' || c1 == '\t') && (c2 == NULL || c2 == ' ' || c2 == '\t'))
  3683. return 0;
  3684. return (c1 < c2) ? -1 : 1;
  3685. }
  3686. };
  3687. __declspec(selectany) GUID CAtlModule::m_libid = {0x0, 0x0, 0x0, {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0} };
  3688. #define DECLARE_LIBID(libid) \
  3689. static void InitLibId() throw() \
  3690. { \
  3691. CAtlModule::m_libid = libid; \
  3692. }
  3693. #define DECLARE_REGISTRY_APPID_RESOURCEID(resid, appid) \
  3694. static LPCOLESTR GetAppId() throw() \
  3695. { \
  3696. return OLESTR(appid); \
  3697. } \
  3698. static TCHAR* GetAppIdT() throw() \
  3699. { \
  3700. return _T(appid); \
  3701. } \
  3702. static HRESULT WINAPI UpdateRegistryAppId(BOOL bRegister) throw() \
  3703. { \
  3704. _ATL_REGMAP_ENTRY aMapEntries [] = \
  3705. { \
  3706. { OLESTR("APPID"), GetAppId() }, \
  3707. { NULL, NULL } \
  3708. }; \
  3709. return ATL::_pAtlModule->UpdateRegistryFromResource(resid, bRegister, aMapEntries); \
  3710. }
  3711. inline HRESULT AtlGetGITPtr(IGlobalInterfaceTable** ppGIT) throw()
  3712. {
  3713. if (ppGIT == NULL)
  3714. return E_POINTER;
  3715. if (_pAtlModule == NULL)
  3716. {
  3717. return CoCreateInstance(CLSID_StdGlobalInterfaceTable, NULL, CLSCTX_INPROC_SERVER,
  3718. __uuidof(IGlobalInterfaceTable), (void**)ppGIT);
  3719. }
  3720. else
  3721. {
  3722. return _pAtlModule->GetGITPtr(ppGIT);
  3723. }
  3724. }
  3725. template <class T>
  3726. class ATL_NO_VTABLE CAtlModuleT : public CAtlModule
  3727. {
  3728. public :
  3729. CAtlModuleT() throw()
  3730. {
  3731. T::InitLibId();
  3732. }
  3733. static void InitLibId() throw()
  3734. {
  3735. }
  3736. HRESULT RegisterServer(BOOL bRegTypeLib = FALSE, const CLSID* pCLSID = NULL) throw();
  3737. HRESULT UnregisterServer(BOOL bUnRegTypeLib, const CLSID* pCLSID = NULL) throw();
  3738. static HRESULT WINAPI UpdateRegistryAppId(BOOL /*bRegister*/) throw()
  3739. {
  3740. return S_OK;
  3741. }
  3742. HRESULT RegisterAppId() throw()
  3743. {
  3744. return T::UpdateRegistryAppId(TRUE);
  3745. }
  3746. HRESULT UnregisterAppId() throw()
  3747. {
  3748. return T::UpdateRegistryAppId(FALSE);
  3749. }
  3750. };
  3751. template <class T>
  3752. class ATL_NO_VTABLE CAtlDllModuleT : public CAtlModuleT<T>
  3753. {
  3754. public :
  3755. CAtlDllModuleT() throw();
  3756. ~CAtlDllModuleT();
  3757. BOOL WINAPI DllMain(DWORD dwReason, LPVOID /* lpReserved */) throw()
  3758. {
  3759. if (dwReason == DLL_PROCESS_ATTACH)
  3760. {
  3761. if (CAtlBaseModule::m_bInitFailed)
  3762. {
  3763. ATLASSERT(0);
  3764. return FALSE;
  3765. }
  3766. #ifdef _ATL_MIN_CRT
  3767. DisableThreadLibraryCalls(_AtlBaseModule.GetModuleInstance());
  3768. #endif
  3769. }
  3770. return TRUE; // ok
  3771. }
  3772. HRESULT DllCanUnloadNow() throw()
  3773. {
  3774. T* pT = static_cast<T*>(this);
  3775. return (pT->GetLockCount()==0) ? S_OK : S_FALSE;
  3776. }
  3777. HRESULT DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv) throw()
  3778. {
  3779. T* pT = static_cast<T*>(this);
  3780. return pT->GetClassObject(rclsid, riid, ppv);
  3781. }
  3782. HRESULT DllRegisterServer(BOOL bRegTypeLib = TRUE) throw()
  3783. {
  3784. // registers object, typelib and all interfaces in typelib
  3785. T* pT = static_cast<T*>(this);
  3786. HRESULT hr = pT->RegisterAppId();
  3787. if (SUCCEEDED(hr))
  3788. hr = pT->RegisterServer(bRegTypeLib);
  3789. return hr;
  3790. }
  3791. HRESULT DllUnregisterServer(BOOL bUnRegTypeLib = TRUE) throw()
  3792. {
  3793. T* pT = static_cast<T*>(this);
  3794. HRESULT hr = pT->UnregisterServer(bUnRegTypeLib);
  3795. if (SUCCEEDED(hr))
  3796. hr = pT->UnregisterAppId();
  3797. return hr;
  3798. }
  3799. // Obtain a Class Factory (DLL only)
  3800. HRESULT GetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv) throw();
  3801. };
  3802. template <class T>
  3803. class ATL_NO_VTABLE CAtlExeModuleT : public CAtlModuleT<T>
  3804. {
  3805. public :
  3806. #ifndef _ATL_NO_COM_SUPPORT
  3807. DWORD m_dwMainThreadID;
  3808. HANDLE m_hEventShutdown;
  3809. DWORD m_dwTimeOut;
  3810. DWORD m_dwPause;
  3811. bool m_bDelayShutdown;
  3812. bool m_bActivity;
  3813. #endif // _ATL_NO_COM_SUPPORT
  3814. CAtlExeModuleT() throw();
  3815. ~CAtlExeModuleT() throw();
  3816. static HRESULT InitializeCom() throw()
  3817. {
  3818. #if ((_WIN32_WINNT >= 0x0400 ) || defined(_WIN32_DCOM)) & defined(_ATL_FREE_THREADED)
  3819. return CoInitializeEx(NULL, COINIT_MULTITHREADED);
  3820. #else
  3821. return CoInitialize(NULL);
  3822. #endif
  3823. }
  3824. static void UninitializeCom() throw()
  3825. {
  3826. CoUninitialize();
  3827. }
  3828. LONG Unlock() throw()
  3829. {
  3830. LONG lRet = CComGlobalsThreadModel::Decrement(&m_nLockCnt);
  3831. #ifndef _ATL_NO_COM_SUPPORT
  3832. if (lRet == 0)
  3833. {
  3834. if (m_bDelayShutdown)
  3835. {
  3836. m_bActivity = true;
  3837. ::SetEvent(m_hEventShutdown); // tell monitor that we transitioned to zero
  3838. }
  3839. else
  3840. {
  3841. ::PostThreadMessage(m_dwMainThreadID, WM_QUIT, 0, 0);
  3842. }
  3843. }
  3844. #endif // _ATL_NO_COM_SUPPORT
  3845. return lRet;
  3846. }
  3847. void MonitorShutdown() throw()
  3848. {
  3849. while (1)
  3850. {
  3851. ::WaitForSingleObject(m_hEventShutdown, INFINITE);
  3852. DWORD dwWait = 0;
  3853. do
  3854. {
  3855. m_bActivity = false;
  3856. dwWait = ::WaitForSingleObject(m_hEventShutdown, m_dwTimeOut);
  3857. } while (dwWait == WAIT_OBJECT_0);
  3858. // timed out
  3859. if (!m_bActivity && m_nLockCnt == 0) // if no activity let's really bail
  3860. {
  3861. #if ((_WIN32_WINNT >= 0x0400 ) || defined(_WIN32_DCOM)) & defined(_ATL_FREE_THREADED)
  3862. ::CoSuspendClassObjects();
  3863. if (m_nLockCnt == 0)
  3864. #endif
  3865. break;
  3866. }
  3867. }
  3868. ::CloseHandle(m_hEventShutdown);
  3869. ::PostThreadMessage(m_dwMainThreadID, WM_QUIT, 0, 0);
  3870. }
  3871. HANDLE StartMonitor() throw()
  3872. {
  3873. m_hEventShutdown = ::CreateEvent(NULL, false, false, NULL);
  3874. if (m_hEventShutdown == NULL)
  3875. return false;
  3876. DWORD dwThreadID;
  3877. HANDLE h = ::CreateThread(NULL, 0, MonitorProc, this, 0, &dwThreadID);
  3878. return h;
  3879. }
  3880. static DWORD WINAPI MonitorProc(void* pv) throw()
  3881. {
  3882. CAtlExeModuleT<T>* p = static_cast<CAtlExeModuleT<T>*>(pv);
  3883. p->MonitorShutdown();
  3884. return 0;
  3885. }
  3886. int WinMain(int nShowCmd) throw()
  3887. {
  3888. if (CAtlBaseModule::m_bInitFailed)
  3889. {
  3890. ATLASSERT(0);
  3891. return -1;
  3892. }
  3893. T* pT = static_cast<T*>(this);
  3894. HRESULT hr = S_OK;
  3895. LPTSTR lpCmdLine = GetCommandLine(); //this line necessary for _ATL_MIN_CRT
  3896. if (pT->ParseCommandLine(lpCmdLine, &hr) == true)
  3897. hr = pT->Run(nShowCmd);
  3898. return hr;
  3899. }
  3900. // Scan command line and perform registration
  3901. // Return value specifies if server should run
  3902. // Parses the command line and registers/unregisters the rgs file if necessary
  3903. bool ParseCommandLine(LPCTSTR lpCmdLine, HRESULT* pnRetCode) throw()
  3904. {
  3905. *pnRetCode = S_OK;
  3906. TCHAR szTokens[] = _T("-/");
  3907. T* pT = static_cast<T*>(this);
  3908. LPCTSTR lpszToken = FindOneOf(lpCmdLine, szTokens);
  3909. while (lpszToken != NULL)
  3910. {
  3911. if (WordCmpI(lpszToken, _T("UnregServer"))==0)
  3912. {
  3913. *pnRetCode = pT->UnregisterServer(TRUE);
  3914. if (SUCCEEDED(*pnRetCode))
  3915. *pnRetCode = pT->UnregisterAppId();
  3916. return false;
  3917. }
  3918. // Register as Local Server
  3919. if (WordCmpI(lpszToken, _T("RegServer"))==0)
  3920. {
  3921. *pnRetCode = pT->RegisterAppId();
  3922. if (SUCCEEDED(*pnRetCode))
  3923. *pnRetCode = pT->RegisterServer(TRUE);
  3924. return false;
  3925. }
  3926. lpszToken = FindOneOf(lpszToken, szTokens);
  3927. }
  3928. return true;
  3929. }
  3930. HRESULT PreMessageLoop(int /*nShowCmd*/) throw()
  3931. {
  3932. HRESULT hr = S_OK;
  3933. T* pT = static_cast<T*>(this);
  3934. pT;
  3935. #ifndef _ATL_NO_COM_SUPPORT
  3936. #if ((_WIN32_WINNT >= 0x0400 ) || defined(_WIN32_DCOM)) & defined(_ATL_FREE_THREADED)
  3937. hr = pT->RegisterClassObjects(CLSCTX_LOCAL_SERVER,
  3938. REGCLS_MULTIPLEUSE | REGCLS_SUSPENDED);
  3939. if (FAILED(hr))
  3940. return hr;
  3941. if (hr == S_OK)
  3942. {
  3943. if (m_bDelayShutdown)
  3944. {
  3945. CHandle h(pT->StartMonitor());
  3946. if (h.m_h == NULL)
  3947. {
  3948. hr = E_FAIL;
  3949. }
  3950. else
  3951. {
  3952. hr = CoResumeClassObjects();
  3953. ATLASSERT(SUCCEEDED(hr));
  3954. if (FAILED(hr))
  3955. {
  3956. ::SetEvent(m_hEventShutdown); // tell monitor to shutdown
  3957. ::WaitForSingleObject(h, m_dwTimeOut * 2);
  3958. }
  3959. }
  3960. }
  3961. if (FAILED(hr))
  3962. pT->RevokeClassObjects();
  3963. }
  3964. else
  3965. {
  3966. m_bDelayShutdown = false;
  3967. }
  3968. #else
  3969. hr = pT->RegisterClassObjects(CLSCTX_LOCAL_SERVER,
  3970. REGCLS_MULTIPLEUSE);
  3971. if (hr == S_OK)
  3972. {
  3973. if (m_bDelayShutdown && !pT->StartMonitor())
  3974. {
  3975. hr = E_FAIL;
  3976. }
  3977. }
  3978. else
  3979. {
  3980. m_bDelayShutdown = false;
  3981. }
  3982. #endif
  3983. #endif // _ATL_NO_COM_SUPPORT
  3984. ATLASSERT(SUCCEEDED(hr));
  3985. return hr;
  3986. }
  3987. HRESULT PostMessageLoop() throw()
  3988. {
  3989. HRESULT hr = S_OK;
  3990. #ifndef _ATL_NO_COM_SUPPORT
  3991. T* pT = static_cast<T*>(this);
  3992. hr = pT->RevokeClassObjects();
  3993. if (m_bDelayShutdown)
  3994. Sleep(m_dwPause); //wait for any threads to finish
  3995. #endif // _ATL_NO_COM_SUPPORT
  3996. return hr;
  3997. }
  3998. void RunMessageLoop() throw()
  3999. {
  4000. MSG msg;
  4001. while (GetMessage(&msg, 0, 0, 0) > 0)
  4002. {
  4003. TranslateMessage(&msg);
  4004. DispatchMessage(&msg);
  4005. }
  4006. }
  4007. HRESULT Run(int nShowCmd = SW_HIDE) throw()
  4008. {
  4009. HRESULT hr = S_OK;
  4010. T* pT = static_cast<T*>(this);
  4011. hr = pT->PreMessageLoop(nShowCmd);
  4012. // Call RunMessageLoop only if PreMessageLoop returns S_OK.
  4013. if (hr == S_OK)
  4014. {
  4015. pT->RunMessageLoop();
  4016. }
  4017. // Call PostMessageLoop if PreMessageLoop returns success.
  4018. if (SUCCEEDED(hr))
  4019. {
  4020. hr = pT->PostMessageLoop();
  4021. }
  4022. ATLASSERT(SUCCEEDED(hr));
  4023. return hr;
  4024. }
  4025. // Register/Revoke All Class Factories with the OS (EXE only)
  4026. HRESULT RegisterClassObjects(DWORD dwClsContext, DWORD dwFlags) throw();
  4027. HRESULT RevokeClassObjects() throw();
  4028. };
  4029. template <class T, UINT nServiceNameID>
  4030. class ATL_NO_VTABLE CAtlServiceModuleT : public CAtlExeModuleT<T>
  4031. {
  4032. public :
  4033. CAtlServiceModuleT() throw()
  4034. {
  4035. m_bService = TRUE;
  4036. LoadString(_AtlBaseModule.GetModuleInstance(), nServiceNameID, m_szServiceName, sizeof(m_szServiceName) / sizeof(TCHAR));
  4037. // set up the initial service status
  4038. m_hServiceStatus = NULL;
  4039. m_status.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
  4040. m_status.dwCurrentState = SERVICE_STOPPED;
  4041. m_status.dwControlsAccepted = SERVICE_ACCEPT_STOP;
  4042. m_status.dwWin32ExitCode = 0;
  4043. m_status.dwServiceSpecificExitCode = 0;
  4044. m_status.dwCheckPoint = 0;
  4045. m_status.dwWaitHint = 0;
  4046. }
  4047. int WinMain(int nShowCmd) throw()
  4048. {
  4049. if (CAtlBaseModule::m_bInitFailed)
  4050. {
  4051. ATLASSERT(0);
  4052. return -1;
  4053. }
  4054. T* pT = static_cast<T*>(this);
  4055. HRESULT hr = S_OK;
  4056. LPTSTR lpCmdLine = GetCommandLine(); //this line necessary for _ATL_MIN_CRT
  4057. if (pT->ParseCommandLine(lpCmdLine, &hr) == true)
  4058. hr = pT->Start(nShowCmd);
  4059. return (int)hr;
  4060. }
  4061. HRESULT Start(int nShowCmd) throw()
  4062. {
  4063. T* pT = static_cast<T*>(this);
  4064. // Are we Service or Local Server
  4065. CRegKey keyAppID;
  4066. LONG lRes = keyAppID.Open(HKEY_CLASSES_ROOT, _T("AppID"), KEY_READ);
  4067. if (lRes != ERROR_SUCCESS)
  4068. {
  4069. m_status.dwWin32ExitCode = lRes;
  4070. return m_status.dwWin32ExitCode;
  4071. }
  4072. CRegKey key;
  4073. USES_CONVERSION;
  4074. lRes = key.Open(keyAppID, pT->GetAppIdT(), KEY_READ);
  4075. if (lRes != ERROR_SUCCESS)
  4076. {
  4077. m_status.dwWin32ExitCode = lRes;
  4078. return m_status.dwWin32ExitCode;
  4079. }
  4080. TCHAR szValue[_MAX_PATH];
  4081. DWORD dwLen = _MAX_PATH;
  4082. lRes = key.QueryStringValue(_T("LocalService"), szValue, &dwLen);
  4083. m_bService = FALSE;
  4084. if (lRes == ERROR_SUCCESS)
  4085. m_bService = TRUE;
  4086. if (m_bService)
  4087. {
  4088. SERVICE_TABLE_ENTRY st[] =
  4089. {
  4090. { m_szServiceName, _ServiceMain },
  4091. { NULL, NULL }
  4092. };
  4093. if (::StartServiceCtrlDispatcher(st) == 0)
  4094. m_bService = FALSE;
  4095. else
  4096. return m_status.dwWin32ExitCode;
  4097. }
  4098. // local server - call Run() directly, rather than
  4099. // from ServiceMain()
  4100. m_status.dwWin32ExitCode = pT->Run(nShowCmd);
  4101. return m_status.dwWin32ExitCode;
  4102. }
  4103. inline HRESULT RegisterAppId(bool bService = false) throw()
  4104. {
  4105. if (!Uninstall())
  4106. return E_FAIL;
  4107. HRESULT hr = T::UpdateRegistryAppId(TRUE);
  4108. if (FAILED(hr))
  4109. return hr;
  4110. CRegKey keyAppID;
  4111. LONG lRes = keyAppID.Open(HKEY_CLASSES_ROOT, _T("AppID"), KEY_WRITE);
  4112. if (lRes != ERROR_SUCCESS)
  4113. return AtlHresultFromWin32(lRes);
  4114. CRegKey key;
  4115. USES_CONVERSION;
  4116. lRes = key.Open(keyAppID, T::GetAppIdT(), KEY_WRITE);
  4117. if (lRes != ERROR_SUCCESS)
  4118. return AtlHresultFromWin32(lRes);
  4119. key.DeleteValue(_T("LocalService"));
  4120. if (!bService)
  4121. return S_OK;
  4122. key.SetStringValue(_T("LocalService"), m_szServiceName);
  4123. // Create service
  4124. if (!Install())
  4125. return E_FAIL;
  4126. return S_OK;
  4127. }
  4128. HRESULT UnregisterAppId() throw()
  4129. {
  4130. if (!Uninstall())
  4131. return E_FAIL;
  4132. // First remove entries not in the RGS file.
  4133. CRegKey keyAppID;
  4134. LONG lRes = keyAppID.Open(HKEY_CLASSES_ROOT, _T("AppID"), KEY_WRITE);
  4135. if (lRes != ERROR_SUCCESS)
  4136. return AtlHresultFromWin32(lRes);
  4137. CRegKey key;
  4138. USES_CONVERSION;
  4139. lRes = key.Open(keyAppID, T::GetAppIdT(), KEY_WRITE);
  4140. if (lRes != ERROR_SUCCESS)
  4141. return AtlHresultFromWin32(lRes);
  4142. key.DeleteValue(_T("LocalService"));
  4143. return T::UpdateRegistryAppId(FALSE);
  4144. }
  4145. // Parses the command line and registers/unregisters the rgs file if necessary
  4146. bool ParseCommandLine(LPCTSTR lpCmdLine, HRESULT* pnRetCode) throw()
  4147. {
  4148. if (!CAtlExeModuleT<T>::ParseCommandLine(lpCmdLine, pnRetCode))
  4149. return false;
  4150. TCHAR szTokens[] = _T("-/");
  4151. *pnRetCode = S_OK;
  4152. T* pT = static_cast<T*>(this);
  4153. LPCTSTR lpszToken = FindOneOf(lpCmdLine, szTokens);
  4154. while (lpszToken != NULL)
  4155. {
  4156. if (WordCmpI(lpszToken, _T("Service"))==0)
  4157. {
  4158. *pnRetCode = pT->RegisterAppId(true);
  4159. if (SUCCEEDED(*pnRetCode))
  4160. *pnRetCode = pT->RegisterServer(TRUE);
  4161. return SUCCEEDED(*pnRetCode)? true : false;
  4162. }
  4163. lpszToken = FindOneOf(lpszToken, szTokens);
  4164. }
  4165. return true;
  4166. }
  4167. void ServiceMain(DWORD dwArgc, LPTSTR* lpszArgv) throw()
  4168. {
  4169. lpszArgv;
  4170. dwArgc;
  4171. HRESULT hr = E_FAIL;
  4172. // Register the control request handler
  4173. m_status.dwCurrentState = SERVICE_START_PENDING;
  4174. m_hServiceStatus = RegisterServiceCtrlHandler(m_szServiceName, _Handler);
  4175. if (m_hServiceStatus == NULL)
  4176. {
  4177. LogEvent(_T("Handler not installed"));
  4178. return;
  4179. }
  4180. SetServiceStatus(SERVICE_START_PENDING);
  4181. m_status.dwWin32ExitCode = S_OK;
  4182. m_status.dwCheckPoint = 0;
  4183. m_status.dwWaitHint = 0;
  4184. T* pT = static_cast<T*>(this);
  4185. #ifndef _ATL_NO_COM_SUPPORT
  4186. hr = T::InitializeCom();
  4187. if (FAILED(hr))
  4188. return;
  4189. m_bDelayShutdown = false;
  4190. #endif
  4191. // When the Run function returns, the service has stopped.
  4192. m_status.dwWin32ExitCode = pT->Run(SW_HIDE);
  4193. #ifndef _ATL_NO_COM_SUPPORT
  4194. if (m_bService)
  4195. T::UninitializeCom();
  4196. #endif
  4197. SetServiceStatus(SERVICE_STOPPED);
  4198. LogEvent(_T("Service stopped"));
  4199. }
  4200. HRESULT Run(int nShowCmd = SW_HIDE) throw()
  4201. {
  4202. HRESULT hr = S_OK;
  4203. T* pT = static_cast<T*>(this);
  4204. hr = pT->PreMessageLoop(nShowCmd);
  4205. if (hr == S_OK)
  4206. {
  4207. if (m_bService)
  4208. {
  4209. LogEvent(_T("Service started"));
  4210. SetServiceStatus(SERVICE_RUNNING);
  4211. }
  4212. pT->RunMessageLoop();
  4213. }
  4214. if (SUCCEEDED(hr))
  4215. {
  4216. hr = pT->PostMessageLoop();
  4217. }
  4218. return hr;
  4219. }
  4220. HRESULT PreMessageLoop(int nShowCmd) throw()
  4221. {
  4222. HRESULT hr = S_OK;
  4223. if (m_bService)
  4224. {
  4225. m_dwThreadID = GetCurrentThreadId();
  4226. T* pT = static_cast<T*>(this);
  4227. hr = pT->InitializeSecurity();
  4228. if (FAILED(hr))
  4229. return hr;
  4230. }
  4231. hr = CAtlExeModuleT<T>::PreMessageLoop(nShowCmd);
  4232. if (FAILED(hr))
  4233. return hr;
  4234. return hr;
  4235. }
  4236. // This function provides the default security settings for your service,
  4237. // you should overide this in your specific service module class to change
  4238. // as appropriate. By default, this will allow any caller and calls will be
  4239. // on the callers security token (impersonated).
  4240. HRESULT InitializeSecurity() throw()
  4241. {
  4242. // This provides a NULL DACL which will allow access to everyone.
  4243. CSecurityDescriptor sd;
  4244. sd.InitializeFromThreadToken();
  4245. return CoInitializeSecurity(sd, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_PKT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, NULL);
  4246. }
  4247. void OnStop() throw()
  4248. {
  4249. SetServiceStatus(SERVICE_STOP_PENDING);
  4250. PostThreadMessage(m_dwThreadID, WM_QUIT, 0, 0);
  4251. }
  4252. void OnPause() throw()
  4253. {
  4254. }
  4255. void OnContinue() throw()
  4256. {
  4257. }
  4258. void OnInterrogate() throw()
  4259. {
  4260. }
  4261. void OnShutdown() throw()
  4262. {
  4263. }
  4264. void OnUnknownRequest(DWORD /*dwOpcode*/) throw()
  4265. {
  4266. LogEvent(_T("Bad service request"));
  4267. }
  4268. void Handler(DWORD dwOpcode) throw()
  4269. {
  4270. T* pT = static_cast<T*>(this);
  4271. switch (dwOpcode)
  4272. {
  4273. case SERVICE_CONTROL_STOP:
  4274. pT->OnStop();
  4275. break;
  4276. case SERVICE_CONTROL_PAUSE:
  4277. pT->OnPause();
  4278. break;
  4279. case SERVICE_CONTROL_CONTINUE:
  4280. pT->OnContinue();
  4281. break;
  4282. case SERVICE_CONTROL_INTERROGATE:
  4283. pT->OnInterrogate();
  4284. break;
  4285. case SERVICE_CONTROL_SHUTDOWN:
  4286. pT->OnShutdown();
  4287. break;
  4288. default:
  4289. pT->OnUnknownRequest(dwOpcode);
  4290. }
  4291. }
  4292. BOOL IsInstalled() throw()
  4293. {
  4294. BOOL bResult = FALSE;
  4295. SC_HANDLE hSCM = ::OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
  4296. if (hSCM != NULL)
  4297. {
  4298. SC_HANDLE hService = ::OpenService(hSCM, m_szServiceName, SERVICE_QUERY_CONFIG);
  4299. if (hService != NULL)
  4300. {
  4301. bResult = TRUE;
  4302. ::CloseServiceHandle(hService);
  4303. }
  4304. ::CloseServiceHandle(hSCM);
  4305. }
  4306. return bResult;
  4307. }
  4308. BOOL Install() throw()
  4309. {
  4310. if (IsInstalled())
  4311. return TRUE;
  4312. SC_HANDLE hSCM = ::OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
  4313. if (hSCM == NULL)
  4314. {
  4315. TCHAR szBuf[1024];
  4316. if (AtlLoadString(ATL_SERIVCE_MANAGER_OPEN_ERROR, szBuf, 1024) == 0)
  4317. lstrcpy(szBuf, _T("Could not open Service Manager"));
  4318. MessageBox(NULL, szBuf, m_szServiceName, MB_OK);
  4319. return FALSE;
  4320. }
  4321. // Get the executable file path
  4322. TCHAR szFilePath[_MAX_PATH];
  4323. ::GetModuleFileName(NULL, szFilePath, _MAX_PATH);
  4324. SC_HANDLE hService = ::CreateService(
  4325. hSCM, m_szServiceName, m_szServiceName,
  4326. SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS,
  4327. SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL,
  4328. szFilePath, NULL, NULL, _T("RPCSS\0"), NULL, NULL);
  4329. if (hService == NULL)
  4330. {
  4331. ::CloseServiceHandle(hSCM);
  4332. TCHAR szBuf[1024];
  4333. if (AtlLoadString(ATL_SERIVCE_START_ERROR, szBuf, 1024) == 0)
  4334. lstrcpy(szBuf, _T("Could not start service"));
  4335. MessageBox(NULL, szBuf, m_szServiceName, MB_OK);
  4336. return FALSE;
  4337. }
  4338. ::CloseServiceHandle(hService);
  4339. ::CloseServiceHandle(hSCM);
  4340. return TRUE;
  4341. }
  4342. BOOL Uninstall() throw()
  4343. {
  4344. if (!IsInstalled())
  4345. return TRUE;
  4346. SC_HANDLE hSCM = ::OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
  4347. if (hSCM == NULL)
  4348. {
  4349. TCHAR szBuf[1024];
  4350. if (AtlLoadString(ATL_SERIVCE_MANAGER_OPEN_ERROR, szBuf, 1024) == 0)
  4351. lstrcpy(szBuf, _T("Could not open Service Manager"));
  4352. MessageBox(NULL, szBuf, m_szServiceName, MB_OK);
  4353. return FALSE;
  4354. }
  4355. SC_HANDLE hService = ::OpenService(hSCM, m_szServiceName, SERVICE_STOP | DELETE);
  4356. if (hService == NULL)
  4357. {
  4358. ::CloseServiceHandle(hSCM);
  4359. TCHAR szBuf[1024];
  4360. if (AtlLoadString(ATL_SERIVCE_OPEN_ERROR, szBuf, 1024) == 0)
  4361. lstrcpy(szBuf, _T("Could not open service"));
  4362. MessageBox(NULL, szBuf, m_szServiceName, MB_OK);
  4363. return FALSE;
  4364. }
  4365. SERVICE_STATUS status;
  4366. BOOL bRet = ::ControlService(hService, SERVICE_CONTROL_STOP, &status);
  4367. if (!bRet)
  4368. {
  4369. DWORD dwError = GetLastError();
  4370. if (dwError == ERROR_SERVICE_CANNOT_ACCEPT_CTRL && status.dwCurrentState == SERVICE_STOP_PENDING)
  4371. {
  4372. }
  4373. else
  4374. {
  4375. TCHAR szBuf[1024];
  4376. if (AtlLoadString(ATL_SERIVCE_STOP_ERROR, szBuf, 1024) == 0)
  4377. lstrcpy(szBuf, _T("Could not stop service"));
  4378. MessageBox(NULL, szBuf, m_szServiceName, MB_OK);
  4379. }
  4380. }
  4381. BOOL bDelete = ::DeleteService(hService);
  4382. ::CloseServiceHandle(hService);
  4383. ::CloseServiceHandle(hSCM);
  4384. if (bDelete)
  4385. return TRUE;
  4386. TCHAR szBuf[1024];
  4387. if (AtlLoadString(ATL_SERIVCE_DELETE_ERROR, szBuf, 1024) == 0)
  4388. lstrcpy(szBuf, _T("Could not delete service"));
  4389. MessageBox(NULL, szBuf, m_szServiceName, MB_OK);
  4390. return FALSE;
  4391. }
  4392. LONG Unlock() throw()
  4393. {
  4394. LONG lRet;
  4395. if (m_bService)
  4396. {
  4397. // We are running as a service, therefore transition to zero does not
  4398. // unload the process
  4399. lRet = CAtlModuleT<T>::Unlock();
  4400. }
  4401. else
  4402. {
  4403. // We are running as EXE, use MonitorShutdown logic provided by CExeModule
  4404. lRet = CAtlExeModuleT<T>::Unlock();
  4405. }
  4406. return lRet;
  4407. }
  4408. void LogEventEx(int id, LPCTSTR pszMessage=NULL, WORD type = EVENTLOG_INFORMATION_TYPE) throw()
  4409. {
  4410. HANDLE hEventSource;
  4411. if (m_szServiceName)
  4412. {
  4413. /* Get a handle to use with ReportEvent(). */
  4414. hEventSource = RegisterEventSource(NULL, m_szServiceName);
  4415. if (hEventSource != NULL)
  4416. {
  4417. /* Write to event log. */
  4418. ReportEvent(hEventSource,
  4419. type,
  4420. (WORD)0,
  4421. id,
  4422. NULL,
  4423. (WORD)(pszMessage != NULL ? 1 : 0),
  4424. 0,
  4425. pszMessage != NULL ? &pszMessage : NULL,
  4426. NULL);
  4427. DeregisterEventSource(hEventSource);
  4428. }
  4429. }
  4430. }
  4431. void __cdecl LogEvent(LPCTSTR pszFormat, ...) throw()
  4432. {
  4433. TCHAR chMsg[256];
  4434. HANDLE hEventSource;
  4435. LPTSTR lpszStrings[1];
  4436. va_list pArg;
  4437. va_start(pArg, pszFormat);
  4438. _vstprintf(chMsg, pszFormat, pArg);
  4439. va_end(pArg);
  4440. lpszStrings[0] = chMsg;
  4441. if (!m_bService)
  4442. {
  4443. // Not running as a service, so print out the error message
  4444. // to the console if possible
  4445. _putts(chMsg);
  4446. }
  4447. /* Get a handle to use with ReportEvent(). */
  4448. hEventSource = RegisterEventSource(NULL, m_szServiceName);
  4449. if (hEventSource != NULL)
  4450. {
  4451. /* Write to event log. */
  4452. ReportEvent(hEventSource, EVENTLOG_INFORMATION_TYPE, 0, 0, NULL, 1, 0, (LPCTSTR*) &lpszStrings[0], NULL);
  4453. DeregisterEventSource(hEventSource);
  4454. }
  4455. }
  4456. void SetServiceStatus(DWORD dwState) throw()
  4457. {
  4458. m_status.dwCurrentState = dwState;
  4459. ::SetServiceStatus(m_hServiceStatus, &m_status);
  4460. }
  4461. //Implementation
  4462. protected:
  4463. static void WINAPI _ServiceMain(DWORD dwArgc, LPTSTR* lpszArgv) throw()
  4464. {
  4465. ((T*)_pAtlModule)->ServiceMain(dwArgc, lpszArgv);
  4466. }
  4467. static void WINAPI _Handler(DWORD dwOpcode) throw()
  4468. {
  4469. ((T*)_pAtlModule)->Handler(dwOpcode);
  4470. }
  4471. // data members
  4472. public:
  4473. TCHAR m_szServiceName[256];
  4474. SERVICE_STATUS_HANDLE m_hServiceStatus;
  4475. SERVICE_STATUS m_status;
  4476. BOOL m_bService;
  4477. DWORD m_dwThreadID;
  4478. };
  4479. class CComModule;
  4480. __declspec(selectany) CComModule* _pModule = NULL;
  4481. class CComModule : public CAtlModuleT<CComModule>
  4482. {
  4483. public :
  4484. CComModule()
  4485. {
  4486. // Should have only one instance of a class
  4487. // derived from CComModule in a project.
  4488. ATLASSERT(_pModule == NULL);
  4489. _pModule = this;
  4490. }
  4491. __declspec(property(get = get_m_hInst)) HINSTANCE m_hInst;
  4492. HINSTANCE& get_m_hInst() const throw()
  4493. {
  4494. return _AtlBaseModule.m_hInst;
  4495. }
  4496. __declspec(property(get = get_m_hInstResource, put = put_m_hInstResource)) HINSTANCE m_hInstResource;
  4497. HINSTANCE& get_m_hInstResource() const throw()
  4498. {
  4499. return _AtlBaseModule.m_hInstResource;
  4500. }
  4501. void put_m_hInstResource(HINSTANCE h) throw()
  4502. {
  4503. _AtlBaseModule.SetResourceInstance(h);
  4504. }
  4505. HINSTANCE SetResourceInstance(HINSTANCE h) throw()
  4506. {
  4507. return _AtlBaseModule.SetResourceInstance(h);
  4508. }
  4509. HINSTANCE GetModuleInstance() throw()
  4510. {
  4511. return _AtlBaseModule.m_hInst;
  4512. }
  4513. HINSTANCE GetResourceInstance() throw()
  4514. {
  4515. return _AtlBaseModule.m_hInstResource;
  4516. }
  4517. __declspec(property(get = get_m_hInstTypeLib, put = put_m_hInstTypeLib)) HINSTANCE m_hInstTypeLib;
  4518. HINSTANCE& get_m_hInstTypeLib() throw();
  4519. void put_m_hInstTypeLib(HINSTANCE h) throw();
  4520. HINSTANCE GetTypeLibInstance() throw();
  4521. // For Backward compatibility
  4522. _ATL_OBJMAP_ENTRY* m_pObjMap;
  4523. __declspec(property(get = get_m_csWindowCreate)) CRITICAL_SECTION m_csWindowCreate;
  4524. CRITICAL_SECTION& get_m_csWindowCreate() throw();
  4525. __declspec(property(get = get_m_csObjMap)) CRITICAL_SECTION m_csObjMap;
  4526. CRITICAL_SECTION& get_m_csObjMap() throw();
  4527. __declspec(property(get = get_m_csStaticDataInit)) CRITICAL_SECTION m_csTypeInfoHolder;
  4528. __declspec(property(get = get_m_csStaticDataInit)) CRITICAL_SECTION m_csStaticDataInit;
  4529. CRITICAL_SECTION& get_m_csStaticDataInit() throw();
  4530. void EnterStaticDataCriticalSection() throw()
  4531. {
  4532. EnterCriticalSection(&m_csStaticDataInit);
  4533. }
  4534. void LeaveStaticDataCriticalSection() throw()
  4535. {
  4536. LeaveCriticalSection(&m_csStaticDataInit);
  4537. }
  4538. __declspec(property(get = get_dwAtlBuildVer)) DWORD dwAtlBuildVer;
  4539. DWORD& get_dwAtlBuildVer() throw()
  4540. {
  4541. return _AtlBaseModule.dwAtlBuildVer;
  4542. }
  4543. __declspec(property(get = get_m_pCreateWndList, put = put_m_pCreateWndList)) _AtlCreateWndData* m_pCreateWndList;
  4544. _AtlCreateWndData*& get_m_pCreateWndList() throw();
  4545. void put_m_pCreateWndList(_AtlCreateWndData* p) throw();
  4546. __declspec(property(get = get_pguidVer)) GUID* pguidVer;
  4547. GUID*& get_pguidVer() throw()
  4548. {
  4549. return _AtlBaseModule.pguidVer;
  4550. }
  4551. #ifdef _ATL_DEBUG_INTERFACES
  4552. __declspec(property(get = get_m_nIndexQI, put = put_m_nIndexQI)) UINT m_nIndexQI;
  4553. UINT& get_m_nIndexQI() throw();
  4554. void put_m_nIndexQI(UINT nIndex) throw();
  4555. __declspec(property(get = get_m_nIndexBreakAt, put = put_m_nIndexBreakAt)) UINT m_nIndexBreakAt;
  4556. UINT& get_m_nIndexBreakAt() throw();
  4557. void put_m_nIndexBreakAt(UINT nIndex) throw();
  4558. __declspec(property(get = get_m_paThunks)) CSimpleArray<_QIThunk*>* m_paThunks;
  4559. CSimpleArray<_QIThunk*>* get_m_paThunks() throw();
  4560. HRESULT AddThunk(IUnknown** pp, LPCTSTR lpsz, REFIID iid) throw();
  4561. HRESULT AddNonAddRefThunk(IUnknown* p, LPCTSTR lpsz, IUnknown** ppThunkRet) throw();
  4562. void DeleteNonAddRefThunk(IUnknown* pUnk) throw();
  4563. void DeleteThunk(_QIThunk* p) throw();
  4564. bool DumpLeakedThunks() throw();
  4565. #endif // _ATL_DEBUG_INTERFACES
  4566. HRESULT Init(_ATL_OBJMAP_ENTRY* p, HINSTANCE h, const GUID* plibid = NULL) throw();
  4567. void Term() throw();
  4568. HRESULT GetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv) throw();
  4569. // Register/Revoke All Class Factories with the OS (EXE only)
  4570. HRESULT RegisterClassObjects(DWORD dwClsContext, DWORD dwFlags) throw();
  4571. HRESULT RevokeClassObjects() throw();
  4572. // Registry support (helpers)
  4573. HRESULT RegisterTypeLib() throw();
  4574. HRESULT RegisterTypeLib(LPCTSTR lpszIndex) throw();
  4575. HRESULT UnRegisterTypeLib() throw();
  4576. HRESULT UnRegisterTypeLib(LPCTSTR lpszIndex) throw();
  4577. HRESULT RegisterServer(BOOL bRegTypeLib = FALSE, const CLSID* pCLSID = NULL) throw();
  4578. HRESULT UnregisterServer(BOOL bUnRegTypeLib, const CLSID* pCLSID = NULL) throw();
  4579. HRESULT UnregisterServer(const CLSID* pCLSID = NULL) throw();
  4580. void AddCreateWndData(_AtlCreateWndData* pData, void* pObject) throw();
  4581. void* ExtractCreateWndData() throw();
  4582. // Only used in CComAutoThreadModule
  4583. HRESULT CreateInstance(void* /*pfnCreateInstance*/, REFIID /*riid*/, void** /*ppvObj*/) throw()
  4584. {
  4585. ATLASSERT(0);
  4586. ATLTRACENOTIMPL(_T("CComModule::CreateInstance"));
  4587. }
  4588. HRESULT RegisterAppId(LPCTSTR pAppId);
  4589. HRESULT UnregisterAppId(LPCTSTR pAppId);
  4590. // Resource-based Registration
  4591. virtual HRESULT WINAPI UpdateRegistryFromResourceD(LPCTSTR lpszRes, BOOL bRegister,
  4592. struct _ATL_REGMAP_ENTRY* pMapEntries = NULL) throw()
  4593. {
  4594. #if defined(_ATL_DLL) || defined(_ATL_DLL_IMPL)
  4595. return CAtlModuleT<CComModule>::UpdateRegistryFromResourceD(lpszRes, bRegister, pMapEntries);
  4596. #else
  4597. lpszRes;
  4598. bRegister;
  4599. pMapEntries;
  4600. return E_FAIL;
  4601. #endif
  4602. }
  4603. virtual HRESULT WINAPI UpdateRegistryFromResourceD(UINT nResID, BOOL bRegister,
  4604. struct _ATL_REGMAP_ENTRY* pMapEntries = NULL) throw()
  4605. {
  4606. #if defined(_ATL_DLL) || defined(_ATL_DLL_IMPL)
  4607. return CAtlModuleT<CComModule>::UpdateRegistryFromResourceD(nResID, bRegister, pMapEntries);
  4608. #else
  4609. nResID;
  4610. bRegister;
  4611. pMapEntries;
  4612. return E_FAIL;
  4613. #endif
  4614. }
  4615. // Statically linking to Registry Ponent
  4616. virtual HRESULT WINAPI UpdateRegistryFromResourceS(LPCTSTR lpszRes, BOOL bRegister,
  4617. struct _ATL_REGMAP_ENTRY* pMapEntries = NULL) throw()
  4618. {
  4619. #ifdef _ATL_STATIC_REGISTRY
  4620. return CAtlModuleT<CComModule>::UpdateRegistryFromResourceS(lpszRes, bRegister, pMapEntries);
  4621. #else
  4622. lpszRes;
  4623. bRegister;
  4624. pMapEntries;
  4625. return E_FAIL;
  4626. #endif
  4627. }
  4628. virtual HRESULT WINAPI UpdateRegistryFromResourceS(UINT nResID, BOOL bRegister,
  4629. struct _ATL_REGMAP_ENTRY* pMapEntries = NULL) throw()
  4630. {
  4631. #ifdef _ATL_STATIC_REGISTRY
  4632. return CAtlModuleT<CComModule>::UpdateRegistryFromResourceS(nResID, bRegister, pMapEntries);
  4633. #else
  4634. nResID;
  4635. bRegister;
  4636. pMapEntries;
  4637. return E_FAIL;
  4638. #endif
  4639. }
  4640. // Use RGS file for registration
  4641. ATL_DEPRECATED static HRESULT RegisterProgID(LPCTSTR lpszCLSID, LPCTSTR lpszProgID, LPCTSTR lpszUserDesc);
  4642. // Standard Registration
  4643. ATL_DEPRECATED HRESULT WINAPI UpdateRegistryClass(const CLSID& clsid, LPCTSTR lpszProgID,
  4644. LPCTSTR lpszVerIndProgID, UINT nDescID, DWORD dwFlags, BOOL bRegister);
  4645. ATL_DEPRECATED HRESULT WINAPI UpdateRegistryClass(const CLSID& clsid, LPCTSTR lpszProgID,
  4646. LPCTSTR lpszVerIndProgID, LPCTSTR szDesc, DWORD dwFlags, BOOL bRegister);
  4647. ATL_DEPRECATED HRESULT WINAPI RegisterClassHelper(const CLSID& clsid, LPCTSTR lpszProgID,
  4648. LPCTSTR lpszVerIndProgID, LPCTSTR szDesc, DWORD dwFlags);
  4649. ATL_DEPRECATED HRESULT WINAPI UnregisterClassHelper(const CLSID& clsid, LPCTSTR lpszProgID,
  4650. LPCTSTR lpszVerIndProgID);
  4651. BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /* lpReserved */, _ATL_OBJMAP_ENTRY* pObjMap, const GUID* pLibID)
  4652. {
  4653. if (dwReason == DLL_PROCESS_ATTACH)
  4654. {
  4655. if (CAtlBaseModule::m_bInitFailed)
  4656. {
  4657. ATLASSERT(0);
  4658. return FALSE;
  4659. }
  4660. if (FAILED(Init(pObjMap, hInstance, pLibID)))
  4661. {
  4662. Term();
  4663. return FALSE;
  4664. }
  4665. #ifdef _ATL_MIN_CRT
  4666. DisableThreadLibraryCalls(hInstance);
  4667. #endif
  4668. }
  4669. else if (dwReason == DLL_PROCESS_DETACH)
  4670. Term();
  4671. return TRUE; // ok
  4672. }
  4673. HRESULT DllCanUnloadNow() throw()
  4674. {
  4675. return (GetLockCount()==0) ? S_OK : S_FALSE;
  4676. }
  4677. HRESULT DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv) throw()
  4678. {
  4679. return GetClassObject(rclsid, riid, ppv);
  4680. }
  4681. HRESULT DllRegisterServer(BOOL bRegTypeLib = TRUE) throw()
  4682. {
  4683. // registers object, typelib and all interfaces in typelib
  4684. return RegisterServer(bRegTypeLib);
  4685. }
  4686. HRESULT DllUnregisterServer(BOOL bUnRegTypeLib = TRUE) throw()
  4687. {
  4688. return UnregisterServer(bUnRegTypeLib);
  4689. }
  4690. };
  4691. template <class T>
  4692. class CComGITPtr
  4693. {
  4694. public:
  4695. CComGITPtr() throw()
  4696. {
  4697. m_dwCookie = 0;
  4698. }
  4699. CComGITPtr(T* p)
  4700. {
  4701. m_dwCookie = 0;
  4702. HRESULT hr = Attach(p);
  4703. if (FAILED(hr))
  4704. AtlThrow(hr);
  4705. }
  4706. CComGITPtr(const CComGITPtr& git)
  4707. {
  4708. m_dwCookie = 0;
  4709. CComPtr<T> spT;
  4710. HRESULT hr = git.CopyTo(&spT);
  4711. if (SUCCEEDED(hr))
  4712. hr = Attach(spT);
  4713. if (FAILED(hr))
  4714. AtlThrow(hr);
  4715. }
  4716. explicit CComGITPtr(DWORD dwCookie) throw()
  4717. {
  4718. ATLASSERT(m_dwCookie != NULL);
  4719. m_dwCookie = dwCookie;
  4720. #ifdef _DEBUG
  4721. CComPtr<T> spT;
  4722. HRESULT hr = CopyTo(&spT);
  4723. ATLASSERT(SUCCEEDED(hr));
  4724. #endif
  4725. }
  4726. ~CComGITPtr() throw()
  4727. {
  4728. Revoke();
  4729. }
  4730. CComGITPtr<T>& operator=(const CComGITPtr<T>& git)
  4731. {
  4732. CComPtr<T> spT;
  4733. HRESULT hr = git.CopyTo(&spT);
  4734. if (SUCCEEDED(hr))
  4735. hr = Attach(spT);
  4736. if (FAILED(hr))
  4737. AtlThrow(hr);
  4738. return *this;
  4739. }
  4740. CComGITPtr<T>& operator=(T* p)
  4741. {
  4742. HRESULT hr = Attach(p);
  4743. if (FAILED(hr))
  4744. AtlThrow(hr);
  4745. return *this;
  4746. }
  4747. CComGITPtr<T>& operator=(DWORD dwCookie)
  4748. {
  4749. HRESULT hr = Attach(dwCookie);
  4750. if (FAILED(hr))
  4751. AtlThrow(hr);
  4752. m_dwCookie = dwCookie;
  4753. #ifdef _DEBUG
  4754. CComPtr<T> spT;
  4755. hr = CopyTo(&spT);
  4756. ATLASSERT(SUCCEEDED(hr));
  4757. #endif
  4758. return *this;
  4759. }
  4760. // Get the cookie from the class
  4761. operator DWORD() const
  4762. {
  4763. return m_dwCookie;
  4764. }
  4765. // Get the cookie from the class
  4766. DWORD GetCookie() const
  4767. {
  4768. return m_dwCookie;
  4769. }
  4770. // Register the passed interface pointer in the GIT
  4771. HRESULT Attach(T* p) throw()
  4772. {
  4773. CComPtr<IGlobalInterfaceTable> spGIT;
  4774. HRESULT hr = E_FAIL;
  4775. hr = AtlGetGITPtr(&spGIT);
  4776. ATLASSERT(spGIT != NULL);
  4777. ATLASSERT(SUCCEEDED(hr));
  4778. if (FAILED(hr))
  4779. return hr;
  4780. if (m_dwCookie != 0)
  4781. hr = spGIT->RevokeInterfaceFromGlobal(m_dwCookie);
  4782. if (FAILED(hr))
  4783. return hr;
  4784. return spGIT->RegisterInterfaceInGlobal(p, __uuidof(T), &m_dwCookie);
  4785. }
  4786. HRESULT Attach(DWORD dwCookie) throw()
  4787. {
  4788. ATLASSERT(dwCookie != NULL);
  4789. HRESULT hr = Revoke();
  4790. if (FAILED(hr))
  4791. return hr;
  4792. m_dwCookie = dwCookie;
  4793. return S_OK;
  4794. }
  4795. // Detach
  4796. DWORD Detach() throw()
  4797. {
  4798. DWORD dwCookie = m_dwCookie;
  4799. m_dwCookie = NULL;
  4800. return dwCookie;
  4801. }
  4802. // Remove the interface from the GIT
  4803. HRESULT Revoke() throw()
  4804. {
  4805. HRESULT hr = S_OK;
  4806. if (m_dwCookie != 0)
  4807. {
  4808. CComPtr<IGlobalInterfaceTable> spGIT;
  4809. HRESULT hr = E_FAIL;
  4810. hr = AtlGetGITPtr(&spGIT);
  4811. ATLASSERT(spGIT != NULL);
  4812. ATLASSERT(SUCCEEDED(hr));
  4813. if (FAILED(hr))
  4814. return hr;
  4815. hr = spGIT->RevokeInterfaceFromGlobal(m_dwCookie);
  4816. if (SUCCEEDED(hr))
  4817. m_dwCookie = 0;
  4818. }
  4819. return hr;
  4820. }
  4821. // Get's the interface from the GIT and copies it to the passed pointer. The pointer
  4822. // must be released by the caller when finished.
  4823. HRESULT CopyTo(T** pp) const throw()
  4824. {
  4825. CComPtr<IGlobalInterfaceTable> spGIT;
  4826. HRESULT hr = E_FAIL;
  4827. hr = AtlGetGITPtr(&spGIT);
  4828. ATLASSERT(spGIT != NULL);
  4829. ATLASSERT(SUCCEEDED(hr));
  4830. if (FAILED(hr))
  4831. return hr;
  4832. ATLASSERT(m_dwCookie!=NULL);
  4833. return spGIT->GetInterfaceFromGlobal(m_dwCookie, __uuidof(T), (void**)pp);
  4834. }
  4835. DWORD m_dwCookie;
  4836. };
  4837. inline static void atlBadThunkCall()
  4838. {
  4839. ATLASSERT(FALSE && "Call through deleted thunk");
  4840. }
  4841. //REVIEW:
  4842. //AXPMOD Alpha needs to handle impl-thunks differently because of the intel asm in the
  4843. //macro the customer will need to link with the lib\qithunk.lib to get this
  4844. //functionality
  4845. #ifdef _M_IX86
  4846. #define ATL_IMPL_THUNK(n)\
  4847. __declspec(naked) inline HRESULT _QIThunk::f##n()\
  4848. {\
  4849. __asm mov eax, [esp+4] /* eax = this */ \
  4850. __asm cmp dword ptr [eax+8], 0 /* if( this->m_dwRef > 0 ) */ \
  4851. __asm jg goodref\
  4852. __asm call atlBadThunkCall\
  4853. __asm goodref:\
  4854. __asm mov eax, [esp+4] /* eax = this */ \
  4855. __asm mov eax, dword ptr [eax+4] /* eax = this->m_pUnk */ \
  4856. __asm mov [esp+4], eax /* this = m_pUnk */ \
  4857. __asm mov eax, dword ptr [eax] /* eax = m_pUnk->vtbl */ \
  4858. __asm mov eax, dword ptr [eax+4*n] /* eax = this->vtbl[n] */ \
  4859. __asm jmp eax /* call the real method on m_pUnk */ \
  4860. }
  4861. #pragma warning(push,4)
  4862. #pragma warning(disable : 4388)
  4863. ATL_IMPL_THUNK(3)
  4864. ATL_IMPL_THUNK(4)
  4865. ATL_IMPL_THUNK(5)
  4866. ATL_IMPL_THUNK(6)
  4867. ATL_IMPL_THUNK(7)
  4868. ATL_IMPL_THUNK(8)
  4869. ATL_IMPL_THUNK(9)
  4870. ATL_IMPL_THUNK(10)
  4871. ATL_IMPL_THUNK(11)
  4872. ATL_IMPL_THUNK(12)
  4873. ATL_IMPL_THUNK(13)
  4874. ATL_IMPL_THUNK(14)
  4875. ATL_IMPL_THUNK(15)
  4876. ATL_IMPL_THUNK(16)
  4877. ATL_IMPL_THUNK(17)
  4878. ATL_IMPL_THUNK(18)
  4879. ATL_IMPL_THUNK(19)
  4880. ATL_IMPL_THUNK(20)
  4881. ATL_IMPL_THUNK(21)
  4882. ATL_IMPL_THUNK(22)
  4883. ATL_IMPL_THUNK(23)
  4884. ATL_IMPL_THUNK(24)
  4885. ATL_IMPL_THUNK(25)
  4886. ATL_IMPL_THUNK(26)
  4887. ATL_IMPL_THUNK(27)
  4888. ATL_IMPL_THUNK(28)
  4889. ATL_IMPL_THUNK(29)
  4890. ATL_IMPL_THUNK(30)
  4891. ATL_IMPL_THUNK(31)
  4892. ATL_IMPL_THUNK(32)
  4893. ATL_IMPL_THUNK(33)
  4894. ATL_IMPL_THUNK(34)
  4895. ATL_IMPL_THUNK(35)
  4896. ATL_IMPL_THUNK(36)
  4897. ATL_IMPL_THUNK(37)
  4898. ATL_IMPL_THUNK(38)
  4899. ATL_IMPL_THUNK(39)
  4900. ATL_IMPL_THUNK(40)
  4901. ATL_IMPL_THUNK(41)
  4902. ATL_IMPL_THUNK(42)
  4903. ATL_IMPL_THUNK(43)
  4904. ATL_IMPL_THUNK(44)
  4905. ATL_IMPL_THUNK(45)
  4906. ATL_IMPL_THUNK(46)
  4907. ATL_IMPL_THUNK(47)
  4908. ATL_IMPL_THUNK(48)
  4909. ATL_IMPL_THUNK(49)
  4910. ATL_IMPL_THUNK(50)
  4911. ATL_IMPL_THUNK(51)
  4912. ATL_IMPL_THUNK(52)
  4913. ATL_IMPL_THUNK(53)
  4914. ATL_IMPL_THUNK(54)
  4915. ATL_IMPL_THUNK(55)
  4916. ATL_IMPL_THUNK(56)
  4917. ATL_IMPL_THUNK(57)
  4918. ATL_IMPL_THUNK(58)
  4919. ATL_IMPL_THUNK(59)
  4920. ATL_IMPL_THUNK(60)
  4921. ATL_IMPL_THUNK(61)
  4922. ATL_IMPL_THUNK(62)
  4923. ATL_IMPL_THUNK(63)
  4924. ATL_IMPL_THUNK(64)
  4925. ATL_IMPL_THUNK(65)
  4926. ATL_IMPL_THUNK(66)
  4927. ATL_IMPL_THUNK(67)
  4928. ATL_IMPL_THUNK(68)
  4929. ATL_IMPL_THUNK(69)
  4930. ATL_IMPL_THUNK(70)
  4931. ATL_IMPL_THUNK(71)
  4932. ATL_IMPL_THUNK(72)
  4933. ATL_IMPL_THUNK(73)
  4934. ATL_IMPL_THUNK(74)
  4935. ATL_IMPL_THUNK(75)
  4936. ATL_IMPL_THUNK(76)
  4937. ATL_IMPL_THUNK(77)
  4938. ATL_IMPL_THUNK(78)
  4939. ATL_IMPL_THUNK(79)
  4940. ATL_IMPL_THUNK(80)
  4941. ATL_IMPL_THUNK(81)
  4942. ATL_IMPL_THUNK(82)
  4943. ATL_IMPL_THUNK(83)
  4944. ATL_IMPL_THUNK(84)
  4945. ATL_IMPL_THUNK(85)
  4946. ATL_IMPL_THUNK(86)
  4947. ATL_IMPL_THUNK(87)
  4948. ATL_IMPL_THUNK(88)
  4949. ATL_IMPL_THUNK(89)
  4950. ATL_IMPL_THUNK(90)
  4951. ATL_IMPL_THUNK(91)
  4952. ATL_IMPL_THUNK(92)
  4953. ATL_IMPL_THUNK(93)
  4954. ATL_IMPL_THUNK(94)
  4955. ATL_IMPL_THUNK(95)
  4956. ATL_IMPL_THUNK(96)
  4957. ATL_IMPL_THUNK(97)
  4958. ATL_IMPL_THUNK(98)
  4959. ATL_IMPL_THUNK(99)
  4960. ATL_IMPL_THUNK(100)
  4961. ATL_IMPL_THUNK(101)
  4962. ATL_IMPL_THUNK(102)
  4963. ATL_IMPL_THUNK(103)
  4964. ATL_IMPL_THUNK(104)
  4965. ATL_IMPL_THUNK(105)
  4966. ATL_IMPL_THUNK(106)
  4967. ATL_IMPL_THUNK(107)
  4968. ATL_IMPL_THUNK(108)
  4969. ATL_IMPL_THUNK(109)
  4970. ATL_IMPL_THUNK(110)
  4971. ATL_IMPL_THUNK(111)
  4972. ATL_IMPL_THUNK(112)
  4973. ATL_IMPL_THUNK(113)
  4974. ATL_IMPL_THUNK(114)
  4975. ATL_IMPL_THUNK(115)
  4976. ATL_IMPL_THUNK(116)
  4977. ATL_IMPL_THUNK(117)
  4978. ATL_IMPL_THUNK(118)
  4979. ATL_IMPL_THUNK(119)
  4980. ATL_IMPL_THUNK(120)
  4981. ATL_IMPL_THUNK(121)
  4982. ATL_IMPL_THUNK(122)
  4983. ATL_IMPL_THUNK(123)
  4984. ATL_IMPL_THUNK(124)
  4985. ATL_IMPL_THUNK(125)
  4986. ATL_IMPL_THUNK(126)
  4987. ATL_IMPL_THUNK(127)
  4988. ATL_IMPL_THUNK(128)
  4989. ATL_IMPL_THUNK(129)
  4990. ATL_IMPL_THUNK(130)
  4991. ATL_IMPL_THUNK(131)
  4992. ATL_IMPL_THUNK(132)
  4993. ATL_IMPL_THUNK(133)
  4994. ATL_IMPL_THUNK(134)
  4995. ATL_IMPL_THUNK(135)
  4996. ATL_IMPL_THUNK(136)
  4997. ATL_IMPL_THUNK(137)
  4998. ATL_IMPL_THUNK(138)
  4999. ATL_IMPL_THUNK(139)
  5000. ATL_IMPL_THUNK(140)
  5001. ATL_IMPL_THUNK(141)
  5002. ATL_IMPL_THUNK(142)
  5003. ATL_IMPL_THUNK(143)
  5004. ATL_IMPL_THUNK(144)
  5005. ATL_IMPL_THUNK(145)
  5006. ATL_IMPL_THUNK(146)
  5007. ATL_IMPL_THUNK(147)
  5008. ATL_IMPL_THUNK(148)
  5009. ATL_IMPL_THUNK(149)
  5010. ATL_IMPL_THUNK(150)
  5011. ATL_IMPL_THUNK(151)
  5012. ATL_IMPL_THUNK(152)
  5013. ATL_IMPL_THUNK(153)
  5014. ATL_IMPL_THUNK(154)
  5015. ATL_IMPL_THUNK(155)
  5016. ATL_IMPL_THUNK(156)
  5017. ATL_IMPL_THUNK(157)
  5018. ATL_IMPL_THUNK(158)
  5019. ATL_IMPL_THUNK(159)
  5020. ATL_IMPL_THUNK(160)
  5021. ATL_IMPL_THUNK(161)
  5022. ATL_IMPL_THUNK(162)
  5023. ATL_IMPL_THUNK(163)
  5024. ATL_IMPL_THUNK(164)
  5025. ATL_IMPL_THUNK(165)
  5026. ATL_IMPL_THUNK(166)
  5027. ATL_IMPL_THUNK(167)
  5028. ATL_IMPL_THUNK(168)
  5029. ATL_IMPL_THUNK(169)
  5030. ATL_IMPL_THUNK(170)
  5031. ATL_IMPL_THUNK(171)
  5032. ATL_IMPL_THUNK(172)
  5033. ATL_IMPL_THUNK(173)
  5034. ATL_IMPL_THUNK(174)
  5035. ATL_IMPL_THUNK(175)
  5036. ATL_IMPL_THUNK(176)
  5037. ATL_IMPL_THUNK(177)
  5038. ATL_IMPL_THUNK(178)
  5039. ATL_IMPL_THUNK(179)
  5040. ATL_IMPL_THUNK(180)
  5041. ATL_IMPL_THUNK(181)
  5042. ATL_IMPL_THUNK(182)
  5043. ATL_IMPL_THUNK(183)
  5044. ATL_IMPL_THUNK(184)
  5045. ATL_IMPL_THUNK(185)
  5046. ATL_IMPL_THUNK(186)
  5047. ATL_IMPL_THUNK(187)
  5048. ATL_IMPL_THUNK(188)
  5049. ATL_IMPL_THUNK(189)
  5050. ATL_IMPL_THUNK(190)
  5051. ATL_IMPL_THUNK(191)
  5052. ATL_IMPL_THUNK(192)
  5053. ATL_IMPL_THUNK(193)
  5054. ATL_IMPL_THUNK(194)
  5055. ATL_IMPL_THUNK(195)
  5056. ATL_IMPL_THUNK(196)
  5057. ATL_IMPL_THUNK(197)
  5058. ATL_IMPL_THUNK(198)
  5059. ATL_IMPL_THUNK(199)
  5060. ATL_IMPL_THUNK(200)
  5061. ATL_IMPL_THUNK(201)
  5062. ATL_IMPL_THUNK(202)
  5063. ATL_IMPL_THUNK(203)
  5064. ATL_IMPL_THUNK(204)
  5065. ATL_IMPL_THUNK(205)
  5066. ATL_IMPL_THUNK(206)
  5067. ATL_IMPL_THUNK(207)
  5068. ATL_IMPL_THUNK(208)
  5069. ATL_IMPL_THUNK(209)
  5070. ATL_IMPL_THUNK(210)
  5071. ATL_IMPL_THUNK(211)
  5072. ATL_IMPL_THUNK(212)
  5073. ATL_IMPL_THUNK(213)
  5074. ATL_IMPL_THUNK(214)
  5075. ATL_IMPL_THUNK(215)
  5076. ATL_IMPL_THUNK(216)
  5077. ATL_IMPL_THUNK(217)
  5078. ATL_IMPL_THUNK(218)
  5079. ATL_IMPL_THUNK(219)
  5080. ATL_IMPL_THUNK(220)
  5081. ATL_IMPL_THUNK(221)
  5082. ATL_IMPL_THUNK(222)
  5083. ATL_IMPL_THUNK(223)
  5084. ATL_IMPL_THUNK(224)
  5085. ATL_IMPL_THUNK(225)
  5086. ATL_IMPL_THUNK(226)
  5087. ATL_IMPL_THUNK(227)
  5088. ATL_IMPL_THUNK(228)
  5089. ATL_IMPL_THUNK(229)
  5090. ATL_IMPL_THUNK(230)
  5091. ATL_IMPL_THUNK(231)
  5092. ATL_IMPL_THUNK(232)
  5093. ATL_IMPL_THUNK(233)
  5094. ATL_IMPL_THUNK(234)
  5095. ATL_IMPL_THUNK(235)
  5096. ATL_IMPL_THUNK(236)
  5097. ATL_IMPL_THUNK(237)
  5098. ATL_IMPL_THUNK(238)
  5099. ATL_IMPL_THUNK(239)
  5100. ATL_IMPL_THUNK(240)
  5101. ATL_IMPL_THUNK(241)
  5102. ATL_IMPL_THUNK(242)
  5103. ATL_IMPL_THUNK(243)
  5104. ATL_IMPL_THUNK(244)
  5105. ATL_IMPL_THUNK(245)
  5106. ATL_IMPL_THUNK(246)
  5107. ATL_IMPL_THUNK(247)
  5108. ATL_IMPL_THUNK(248)
  5109. ATL_IMPL_THUNK(249)
  5110. ATL_IMPL_THUNK(250)
  5111. ATL_IMPL_THUNK(251)
  5112. ATL_IMPL_THUNK(252)
  5113. ATL_IMPL_THUNK(253)
  5114. ATL_IMPL_THUNK(254)
  5115. ATL_IMPL_THUNK(255)
  5116. ATL_IMPL_THUNK(256)
  5117. ATL_IMPL_THUNK(257)
  5118. ATL_IMPL_THUNK(258)
  5119. ATL_IMPL_THUNK(259)
  5120. ATL_IMPL_THUNK(260)
  5121. ATL_IMPL_THUNK(261)
  5122. ATL_IMPL_THUNK(262)
  5123. ATL_IMPL_THUNK(263)
  5124. ATL_IMPL_THUNK(264)
  5125. ATL_IMPL_THUNK(265)
  5126. ATL_IMPL_THUNK(266)
  5127. ATL_IMPL_THUNK(267)
  5128. ATL_IMPL_THUNK(268)
  5129. ATL_IMPL_THUNK(269)
  5130. ATL_IMPL_THUNK(270)
  5131. ATL_IMPL_THUNK(271)
  5132. ATL_IMPL_THUNK(272)
  5133. ATL_IMPL_THUNK(273)
  5134. ATL_IMPL_THUNK(274)
  5135. ATL_IMPL_THUNK(275)
  5136. ATL_IMPL_THUNK(276)
  5137. ATL_IMPL_THUNK(277)
  5138. ATL_IMPL_THUNK(278)
  5139. ATL_IMPL_THUNK(279)
  5140. ATL_IMPL_THUNK(280)
  5141. ATL_IMPL_THUNK(281)
  5142. ATL_IMPL_THUNK(282)
  5143. ATL_IMPL_THUNK(283)
  5144. ATL_IMPL_THUNK(284)
  5145. ATL_IMPL_THUNK(285)
  5146. ATL_IMPL_THUNK(286)
  5147. ATL_IMPL_THUNK(287)
  5148. ATL_IMPL_THUNK(288)
  5149. ATL_IMPL_THUNK(289)
  5150. ATL_IMPL_THUNK(290)
  5151. ATL_IMPL_THUNK(291)
  5152. ATL_IMPL_THUNK(292)
  5153. ATL_IMPL_THUNK(293)
  5154. ATL_IMPL_THUNK(294)
  5155. ATL_IMPL_THUNK(295)
  5156. ATL_IMPL_THUNK(296)
  5157. ATL_IMPL_THUNK(297)
  5158. ATL_IMPL_THUNK(298)
  5159. ATL_IMPL_THUNK(299)
  5160. ATL_IMPL_THUNK(300)
  5161. ATL_IMPL_THUNK(301)
  5162. ATL_IMPL_THUNK(302)
  5163. ATL_IMPL_THUNK(303)
  5164. ATL_IMPL_THUNK(304)
  5165. ATL_IMPL_THUNK(305)
  5166. ATL_IMPL_THUNK(306)
  5167. ATL_IMPL_THUNK(307)
  5168. ATL_IMPL_THUNK(308)
  5169. ATL_IMPL_THUNK(309)
  5170. ATL_IMPL_THUNK(310)
  5171. ATL_IMPL_THUNK(311)
  5172. ATL_IMPL_THUNK(312)
  5173. ATL_IMPL_THUNK(313)
  5174. ATL_IMPL_THUNK(314)
  5175. ATL_IMPL_THUNK(315)
  5176. ATL_IMPL_THUNK(316)
  5177. ATL_IMPL_THUNK(317)
  5178. ATL_IMPL_THUNK(318)
  5179. ATL_IMPL_THUNK(319)
  5180. ATL_IMPL_THUNK(320)
  5181. ATL_IMPL_THUNK(321)
  5182. ATL_IMPL_THUNK(322)
  5183. ATL_IMPL_THUNK(323)
  5184. ATL_IMPL_THUNK(324)
  5185. ATL_IMPL_THUNK(325)
  5186. ATL_IMPL_THUNK(326)
  5187. ATL_IMPL_THUNK(327)
  5188. ATL_IMPL_THUNK(328)
  5189. ATL_IMPL_THUNK(329)
  5190. ATL_IMPL_THUNK(330)
  5191. ATL_IMPL_THUNK(331)
  5192. ATL_IMPL_THUNK(332)
  5193. ATL_IMPL_THUNK(333)
  5194. ATL_IMPL_THUNK(334)
  5195. ATL_IMPL_THUNK(335)
  5196. ATL_IMPL_THUNK(336)
  5197. ATL_IMPL_THUNK(337)
  5198. ATL_IMPL_THUNK(338)
  5199. ATL_IMPL_THUNK(339)
  5200. ATL_IMPL_THUNK(340)
  5201. ATL_IMPL_THUNK(341)
  5202. ATL_IMPL_THUNK(342)
  5203. ATL_IMPL_THUNK(343)
  5204. ATL_IMPL_THUNK(344)
  5205. ATL_IMPL_THUNK(345)
  5206. ATL_IMPL_THUNK(346)
  5207. ATL_IMPL_THUNK(347)
  5208. ATL_IMPL_THUNK(348)
  5209. ATL_IMPL_THUNK(349)
  5210. ATL_IMPL_THUNK(350)
  5211. ATL_IMPL_THUNK(351)
  5212. ATL_IMPL_THUNK(352)
  5213. ATL_IMPL_THUNK(353)
  5214. ATL_IMPL_THUNK(354)
  5215. ATL_IMPL_THUNK(355)
  5216. ATL_IMPL_THUNK(356)
  5217. ATL_IMPL_THUNK(357)
  5218. ATL_IMPL_THUNK(358)
  5219. ATL_IMPL_THUNK(359)
  5220. ATL_IMPL_THUNK(360)
  5221. ATL_IMPL_THUNK(361)
  5222. ATL_IMPL_THUNK(362)
  5223. ATL_IMPL_THUNK(363)
  5224. ATL_IMPL_THUNK(364)
  5225. ATL_IMPL_THUNK(365)
  5226. ATL_IMPL_THUNK(366)
  5227. ATL_IMPL_THUNK(367)
  5228. ATL_IMPL_THUNK(368)
  5229. ATL_IMPL_THUNK(369)
  5230. ATL_IMPL_THUNK(370)
  5231. ATL_IMPL_THUNK(371)
  5232. ATL_IMPL_THUNK(372)
  5233. ATL_IMPL_THUNK(373)
  5234. ATL_IMPL_THUNK(374)
  5235. ATL_IMPL_THUNK(375)
  5236. ATL_IMPL_THUNK(376)
  5237. ATL_IMPL_THUNK(377)
  5238. ATL_IMPL_THUNK(378)
  5239. ATL_IMPL_THUNK(379)
  5240. ATL_IMPL_THUNK(380)
  5241. ATL_IMPL_THUNK(381)
  5242. ATL_IMPL_THUNK(382)
  5243. ATL_IMPL_THUNK(383)
  5244. ATL_IMPL_THUNK(384)
  5245. ATL_IMPL_THUNK(385)
  5246. ATL_IMPL_THUNK(386)
  5247. ATL_IMPL_THUNK(387)
  5248. ATL_IMPL_THUNK(388)
  5249. ATL_IMPL_THUNK(389)
  5250. ATL_IMPL_THUNK(390)
  5251. ATL_IMPL_THUNK(391)
  5252. ATL_IMPL_THUNK(392)
  5253. ATL_IMPL_THUNK(393)
  5254. ATL_IMPL_THUNK(394)
  5255. ATL_IMPL_THUNK(395)
  5256. ATL_IMPL_THUNK(396)
  5257. ATL_IMPL_THUNK(397)
  5258. ATL_IMPL_THUNK(398)
  5259. ATL_IMPL_THUNK(399)
  5260. ATL_IMPL_THUNK(400)
  5261. ATL_IMPL_THUNK(401)
  5262. ATL_IMPL_THUNK(402)
  5263. ATL_IMPL_THUNK(403)
  5264. ATL_IMPL_THUNK(404)
  5265. ATL_IMPL_THUNK(405)
  5266. ATL_IMPL_THUNK(406)
  5267. ATL_IMPL_THUNK(407)
  5268. ATL_IMPL_THUNK(408)
  5269. ATL_IMPL_THUNK(409)
  5270. ATL_IMPL_THUNK(410)
  5271. ATL_IMPL_THUNK(411)
  5272. ATL_IMPL_THUNK(412)
  5273. ATL_IMPL_THUNK(413)
  5274. ATL_IMPL_THUNK(414)
  5275. ATL_IMPL_THUNK(415)
  5276. ATL_IMPL_THUNK(416)
  5277. ATL_IMPL_THUNK(417)
  5278. ATL_IMPL_THUNK(418)
  5279. ATL_IMPL_THUNK(419)
  5280. ATL_IMPL_THUNK(420)
  5281. ATL_IMPL_THUNK(421)
  5282. ATL_IMPL_THUNK(422)
  5283. ATL_IMPL_THUNK(423)
  5284. ATL_IMPL_THUNK(424)
  5285. ATL_IMPL_THUNK(425)
  5286. ATL_IMPL_THUNK(426)
  5287. ATL_IMPL_THUNK(427)
  5288. ATL_IMPL_THUNK(428)
  5289. ATL_IMPL_THUNK(429)
  5290. ATL_IMPL_THUNK(430)
  5291. ATL_IMPL_THUNK(431)
  5292. ATL_IMPL_THUNK(432)
  5293. ATL_IMPL_THUNK(433)
  5294. ATL_IMPL_THUNK(434)
  5295. ATL_IMPL_THUNK(435)
  5296. ATL_IMPL_THUNK(436)
  5297. ATL_IMPL_THUNK(437)
  5298. ATL_IMPL_THUNK(438)
  5299. ATL_IMPL_THUNK(439)
  5300. ATL_IMPL_THUNK(440)
  5301. ATL_IMPL_THUNK(441)
  5302. ATL_IMPL_THUNK(442)
  5303. ATL_IMPL_THUNK(443)
  5304. ATL_IMPL_THUNK(444)
  5305. ATL_IMPL_THUNK(445)
  5306. ATL_IMPL_THUNK(446)
  5307. ATL_IMPL_THUNK(447)
  5308. ATL_IMPL_THUNK(448)
  5309. ATL_IMPL_THUNK(449)
  5310. ATL_IMPL_THUNK(450)
  5311. ATL_IMPL_THUNK(451)
  5312. ATL_IMPL_THUNK(452)
  5313. ATL_IMPL_THUNK(453)
  5314. ATL_IMPL_THUNK(454)
  5315. ATL_IMPL_THUNK(455)
  5316. ATL_IMPL_THUNK(456)
  5317. ATL_IMPL_THUNK(457)
  5318. ATL_IMPL_THUNK(458)
  5319. ATL_IMPL_THUNK(459)
  5320. ATL_IMPL_THUNK(460)
  5321. ATL_IMPL_THUNK(461)
  5322. ATL_IMPL_THUNK(462)
  5323. ATL_IMPL_THUNK(463)
  5324. ATL_IMPL_THUNK(464)
  5325. ATL_IMPL_THUNK(465)
  5326. ATL_IMPL_THUNK(466)
  5327. ATL_IMPL_THUNK(467)
  5328. ATL_IMPL_THUNK(468)
  5329. ATL_IMPL_THUNK(469)
  5330. ATL_IMPL_THUNK(470)
  5331. ATL_IMPL_THUNK(471)
  5332. ATL_IMPL_THUNK(472)
  5333. ATL_IMPL_THUNK(473)
  5334. ATL_IMPL_THUNK(474)
  5335. ATL_IMPL_THUNK(475)
  5336. ATL_IMPL_THUNK(476)
  5337. ATL_IMPL_THUNK(477)
  5338. ATL_IMPL_THUNK(478)
  5339. ATL_IMPL_THUNK(479)
  5340. ATL_IMPL_THUNK(480)
  5341. ATL_IMPL_THUNK(481)
  5342. ATL_IMPL_THUNK(482)
  5343. ATL_IMPL_THUNK(483)
  5344. ATL_IMPL_THUNK(484)
  5345. ATL_IMPL_THUNK(485)
  5346. ATL_IMPL_THUNK(486)
  5347. ATL_IMPL_THUNK(487)
  5348. ATL_IMPL_THUNK(488)
  5349. ATL_IMPL_THUNK(489)
  5350. ATL_IMPL_THUNK(490)
  5351. ATL_IMPL_THUNK(491)
  5352. ATL_IMPL_THUNK(492)
  5353. ATL_IMPL_THUNK(493)
  5354. ATL_IMPL_THUNK(494)
  5355. ATL_IMPL_THUNK(495)
  5356. ATL_IMPL_THUNK(496)
  5357. ATL_IMPL_THUNK(497)
  5358. ATL_IMPL_THUNK(498)
  5359. ATL_IMPL_THUNK(499)
  5360. ATL_IMPL_THUNK(500)
  5361. ATL_IMPL_THUNK(501)
  5362. ATL_IMPL_THUNK(502)
  5363. ATL_IMPL_THUNK(503)
  5364. ATL_IMPL_THUNK(504)
  5365. ATL_IMPL_THUNK(505)
  5366. ATL_IMPL_THUNK(506)
  5367. ATL_IMPL_THUNK(507)
  5368. ATL_IMPL_THUNK(508)
  5369. ATL_IMPL_THUNK(509)
  5370. ATL_IMPL_THUNK(510)
  5371. ATL_IMPL_THUNK(511)
  5372. ATL_IMPL_THUNK(512)
  5373. ATL_IMPL_THUNK(513)
  5374. ATL_IMPL_THUNK(514)
  5375. ATL_IMPL_THUNK(515)
  5376. ATL_IMPL_THUNK(516)
  5377. ATL_IMPL_THUNK(517)
  5378. ATL_IMPL_THUNK(518)
  5379. ATL_IMPL_THUNK(519)
  5380. ATL_IMPL_THUNK(520)
  5381. ATL_IMPL_THUNK(521)
  5382. ATL_IMPL_THUNK(522)
  5383. ATL_IMPL_THUNK(523)
  5384. ATL_IMPL_THUNK(524)
  5385. ATL_IMPL_THUNK(525)
  5386. ATL_IMPL_THUNK(526)
  5387. ATL_IMPL_THUNK(527)
  5388. ATL_IMPL_THUNK(528)
  5389. ATL_IMPL_THUNK(529)
  5390. ATL_IMPL_THUNK(530)
  5391. ATL_IMPL_THUNK(531)
  5392. ATL_IMPL_THUNK(532)
  5393. ATL_IMPL_THUNK(533)
  5394. ATL_IMPL_THUNK(534)
  5395. ATL_IMPL_THUNK(535)
  5396. ATL_IMPL_THUNK(536)
  5397. ATL_IMPL_THUNK(537)
  5398. ATL_IMPL_THUNK(538)
  5399. ATL_IMPL_THUNK(539)
  5400. ATL_IMPL_THUNK(540)
  5401. ATL_IMPL_THUNK(541)
  5402. ATL_IMPL_THUNK(542)
  5403. ATL_IMPL_THUNK(543)
  5404. ATL_IMPL_THUNK(544)
  5405. ATL_IMPL_THUNK(545)
  5406. ATL_IMPL_THUNK(546)
  5407. ATL_IMPL_THUNK(547)
  5408. ATL_IMPL_THUNK(548)
  5409. ATL_IMPL_THUNK(549)
  5410. ATL_IMPL_THUNK(550)
  5411. ATL_IMPL_THUNK(551)
  5412. ATL_IMPL_THUNK(552)
  5413. ATL_IMPL_THUNK(553)
  5414. ATL_IMPL_THUNK(554)
  5415. ATL_IMPL_THUNK(555)
  5416. ATL_IMPL_THUNK(556)
  5417. ATL_IMPL_THUNK(557)
  5418. ATL_IMPL_THUNK(558)
  5419. ATL_IMPL_THUNK(559)
  5420. ATL_IMPL_THUNK(560)
  5421. ATL_IMPL_THUNK(561)
  5422. ATL_IMPL_THUNK(562)
  5423. ATL_IMPL_THUNK(563)
  5424. ATL_IMPL_THUNK(564)
  5425. ATL_IMPL_THUNK(565)
  5426. ATL_IMPL_THUNK(566)
  5427. ATL_IMPL_THUNK(567)
  5428. ATL_IMPL_THUNK(568)
  5429. ATL_IMPL_THUNK(569)
  5430. ATL_IMPL_THUNK(570)
  5431. ATL_IMPL_THUNK(571)
  5432. ATL_IMPL_THUNK(572)
  5433. ATL_IMPL_THUNK(573)
  5434. ATL_IMPL_THUNK(574)
  5435. ATL_IMPL_THUNK(575)
  5436. ATL_IMPL_THUNK(576)
  5437. ATL_IMPL_THUNK(577)
  5438. ATL_IMPL_THUNK(578)
  5439. ATL_IMPL_THUNK(579)
  5440. ATL_IMPL_THUNK(580)
  5441. ATL_IMPL_THUNK(581)
  5442. ATL_IMPL_THUNK(582)
  5443. ATL_IMPL_THUNK(583)
  5444. ATL_IMPL_THUNK(584)
  5445. ATL_IMPL_THUNK(585)
  5446. ATL_IMPL_THUNK(586)
  5447. ATL_IMPL_THUNK(587)
  5448. ATL_IMPL_THUNK(588)
  5449. ATL_IMPL_THUNK(589)
  5450. ATL_IMPL_THUNK(590)
  5451. ATL_IMPL_THUNK(591)
  5452. ATL_IMPL_THUNK(592)
  5453. ATL_IMPL_THUNK(593)
  5454. ATL_IMPL_THUNK(594)
  5455. ATL_IMPL_THUNK(595)
  5456. ATL_IMPL_THUNK(596)
  5457. ATL_IMPL_THUNK(597)
  5458. ATL_IMPL_THUNK(598)
  5459. ATL_IMPL_THUNK(599)
  5460. ATL_IMPL_THUNK(600)
  5461. ATL_IMPL_THUNK(601)
  5462. ATL_IMPL_THUNK(602)
  5463. ATL_IMPL_THUNK(603)
  5464. ATL_IMPL_THUNK(604)
  5465. ATL_IMPL_THUNK(605)
  5466. ATL_IMPL_THUNK(606)
  5467. ATL_IMPL_THUNK(607)
  5468. ATL_IMPL_THUNK(608)
  5469. ATL_IMPL_THUNK(609)
  5470. ATL_IMPL_THUNK(610)
  5471. ATL_IMPL_THUNK(611)
  5472. ATL_IMPL_THUNK(612)
  5473. ATL_IMPL_THUNK(613)
  5474. ATL_IMPL_THUNK(614)
  5475. ATL_IMPL_THUNK(615)
  5476. ATL_IMPL_THUNK(616)
  5477. ATL_IMPL_THUNK(617)
  5478. ATL_IMPL_THUNK(618)
  5479. ATL_IMPL_THUNK(619)
  5480. ATL_IMPL_THUNK(620)
  5481. ATL_IMPL_THUNK(621)
  5482. ATL_IMPL_THUNK(622)
  5483. ATL_IMPL_THUNK(623)
  5484. ATL_IMPL_THUNK(624)
  5485. ATL_IMPL_THUNK(625)
  5486. ATL_IMPL_THUNK(626)
  5487. ATL_IMPL_THUNK(627)
  5488. ATL_IMPL_THUNK(628)
  5489. ATL_IMPL_THUNK(629)
  5490. ATL_IMPL_THUNK(630)
  5491. ATL_IMPL_THUNK(631)
  5492. ATL_IMPL_THUNK(632)
  5493. ATL_IMPL_THUNK(633)
  5494. ATL_IMPL_THUNK(634)
  5495. ATL_IMPL_THUNK(635)
  5496. ATL_IMPL_THUNK(636)
  5497. ATL_IMPL_THUNK(637)
  5498. ATL_IMPL_THUNK(638)
  5499. ATL_IMPL_THUNK(639)
  5500. ATL_IMPL_THUNK(640)
  5501. ATL_IMPL_THUNK(641)
  5502. ATL_IMPL_THUNK(642)
  5503. ATL_IMPL_THUNK(643)
  5504. ATL_IMPL_THUNK(644)
  5505. ATL_IMPL_THUNK(645)
  5506. ATL_IMPL_THUNK(646)
  5507. ATL_IMPL_THUNK(647)
  5508. ATL_IMPL_THUNK(648)
  5509. ATL_IMPL_THUNK(649)
  5510. ATL_IMPL_THUNK(650)
  5511. ATL_IMPL_THUNK(651)
  5512. ATL_IMPL_THUNK(652)
  5513. ATL_IMPL_THUNK(653)
  5514. ATL_IMPL_THUNK(654)
  5515. ATL_IMPL_THUNK(655)
  5516. ATL_IMPL_THUNK(656)
  5517. ATL_IMPL_THUNK(657)
  5518. ATL_IMPL_THUNK(658)
  5519. ATL_IMPL_THUNK(659)
  5520. ATL_IMPL_THUNK(660)
  5521. ATL_IMPL_THUNK(661)
  5522. ATL_IMPL_THUNK(662)
  5523. ATL_IMPL_THUNK(663)
  5524. ATL_IMPL_THUNK(664)
  5525. ATL_IMPL_THUNK(665)
  5526. ATL_IMPL_THUNK(666)
  5527. ATL_IMPL_THUNK(667)
  5528. ATL_IMPL_THUNK(668)
  5529. ATL_IMPL_THUNK(669)
  5530. ATL_IMPL_THUNK(670)
  5531. ATL_IMPL_THUNK(671)
  5532. ATL_IMPL_THUNK(672)
  5533. ATL_IMPL_THUNK(673)
  5534. ATL_IMPL_THUNK(674)
  5535. ATL_IMPL_THUNK(675)
  5536. ATL_IMPL_THUNK(676)
  5537. ATL_IMPL_THUNK(677)
  5538. ATL_IMPL_THUNK(678)
  5539. ATL_IMPL_THUNK(679)
  5540. ATL_IMPL_THUNK(680)
  5541. ATL_IMPL_THUNK(681)
  5542. ATL_IMPL_THUNK(682)
  5543. ATL_IMPL_THUNK(683)
  5544. ATL_IMPL_THUNK(684)
  5545. ATL_IMPL_THUNK(685)
  5546. ATL_IMPL_THUNK(686)
  5547. ATL_IMPL_THUNK(687)
  5548. ATL_IMPL_THUNK(688)
  5549. ATL_IMPL_THUNK(689)
  5550. ATL_IMPL_THUNK(690)
  5551. ATL_IMPL_THUNK(691)
  5552. ATL_IMPL_THUNK(692)
  5553. ATL_IMPL_THUNK(693)
  5554. ATL_IMPL_THUNK(694)
  5555. ATL_IMPL_THUNK(695)
  5556. ATL_IMPL_THUNK(696)
  5557. ATL_IMPL_THUNK(697)
  5558. ATL_IMPL_THUNK(698)
  5559. ATL_IMPL_THUNK(699)
  5560. ATL_IMPL_THUNK(700)
  5561. ATL_IMPL_THUNK(701)
  5562. ATL_IMPL_THUNK(702)
  5563. ATL_IMPL_THUNK(703)
  5564. ATL_IMPL_THUNK(704)
  5565. ATL_IMPL_THUNK(705)
  5566. ATL_IMPL_THUNK(706)
  5567. ATL_IMPL_THUNK(707)
  5568. ATL_IMPL_THUNK(708)
  5569. ATL_IMPL_THUNK(709)
  5570. ATL_IMPL_THUNK(710)
  5571. ATL_IMPL_THUNK(711)
  5572. ATL_IMPL_THUNK(712)
  5573. ATL_IMPL_THUNK(713)
  5574. ATL_IMPL_THUNK(714)
  5575. ATL_IMPL_THUNK(715)
  5576. ATL_IMPL_THUNK(716)
  5577. ATL_IMPL_THUNK(717)
  5578. ATL_IMPL_THUNK(718)
  5579. ATL_IMPL_THUNK(719)
  5580. ATL_IMPL_THUNK(720)
  5581. ATL_IMPL_THUNK(721)
  5582. ATL_IMPL_THUNK(722)
  5583. ATL_IMPL_THUNK(723)
  5584. ATL_IMPL_THUNK(724)
  5585. ATL_IMPL_THUNK(725)
  5586. ATL_IMPL_THUNK(726)
  5587. ATL_IMPL_THUNK(727)
  5588. ATL_IMPL_THUNK(728)
  5589. ATL_IMPL_THUNK(729)
  5590. ATL_IMPL_THUNK(730)
  5591. ATL_IMPL_THUNK(731)
  5592. ATL_IMPL_THUNK(732)
  5593. ATL_IMPL_THUNK(733)
  5594. ATL_IMPL_THUNK(734)
  5595. ATL_IMPL_THUNK(735)
  5596. ATL_IMPL_THUNK(736)
  5597. ATL_IMPL_THUNK(737)
  5598. ATL_IMPL_THUNK(738)
  5599. ATL_IMPL_THUNK(739)
  5600. ATL_IMPL_THUNK(740)
  5601. ATL_IMPL_THUNK(741)
  5602. ATL_IMPL_THUNK(742)
  5603. ATL_IMPL_THUNK(743)
  5604. ATL_IMPL_THUNK(744)
  5605. ATL_IMPL_THUNK(745)
  5606. ATL_IMPL_THUNK(746)
  5607. ATL_IMPL_THUNK(747)
  5608. ATL_IMPL_THUNK(748)
  5609. ATL_IMPL_THUNK(749)
  5610. ATL_IMPL_THUNK(750)
  5611. ATL_IMPL_THUNK(751)
  5612. ATL_IMPL_THUNK(752)
  5613. ATL_IMPL_THUNK(753)
  5614. ATL_IMPL_THUNK(754)
  5615. ATL_IMPL_THUNK(755)
  5616. ATL_IMPL_THUNK(756)
  5617. ATL_IMPL_THUNK(757)
  5618. ATL_IMPL_THUNK(758)
  5619. ATL_IMPL_THUNK(759)
  5620. ATL_IMPL_THUNK(760)
  5621. ATL_IMPL_THUNK(761)
  5622. ATL_IMPL_THUNK(762)
  5623. ATL_IMPL_THUNK(763)
  5624. ATL_IMPL_THUNK(764)
  5625. ATL_IMPL_THUNK(765)
  5626. ATL_IMPL_THUNK(766)
  5627. ATL_IMPL_THUNK(767)
  5628. ATL_IMPL_THUNK(768)
  5629. ATL_IMPL_THUNK(769)
  5630. ATL_IMPL_THUNK(770)
  5631. ATL_IMPL_THUNK(771)
  5632. ATL_IMPL_THUNK(772)
  5633. ATL_IMPL_THUNK(773)
  5634. ATL_IMPL_THUNK(774)
  5635. ATL_IMPL_THUNK(775)
  5636. ATL_IMPL_THUNK(776)
  5637. ATL_IMPL_THUNK(777)
  5638. ATL_IMPL_THUNK(778)
  5639. ATL_IMPL_THUNK(779)
  5640. ATL_IMPL_THUNK(780)
  5641. ATL_IMPL_THUNK(781)
  5642. ATL_IMPL_THUNK(782)
  5643. ATL_IMPL_THUNK(783)
  5644. ATL_IMPL_THUNK(784)
  5645. ATL_IMPL_THUNK(785)
  5646. ATL_IMPL_THUNK(786)
  5647. ATL_IMPL_THUNK(787)
  5648. ATL_IMPL_THUNK(788)
  5649. ATL_IMPL_THUNK(789)
  5650. ATL_IMPL_THUNK(790)
  5651. ATL_IMPL_THUNK(791)
  5652. ATL_IMPL_THUNK(792)
  5653. ATL_IMPL_THUNK(793)
  5654. ATL_IMPL_THUNK(794)
  5655. ATL_IMPL_THUNK(795)
  5656. ATL_IMPL_THUNK(796)
  5657. ATL_IMPL_THUNK(797)
  5658. ATL_IMPL_THUNK(798)
  5659. ATL_IMPL_THUNK(799)
  5660. ATL_IMPL_THUNK(800)
  5661. ATL_IMPL_THUNK(801)
  5662. ATL_IMPL_THUNK(802)
  5663. ATL_IMPL_THUNK(803)
  5664. ATL_IMPL_THUNK(804)
  5665. ATL_IMPL_THUNK(805)
  5666. ATL_IMPL_THUNK(806)
  5667. ATL_IMPL_THUNK(807)
  5668. ATL_IMPL_THUNK(808)
  5669. ATL_IMPL_THUNK(809)
  5670. ATL_IMPL_THUNK(810)
  5671. ATL_IMPL_THUNK(811)
  5672. ATL_IMPL_THUNK(812)
  5673. ATL_IMPL_THUNK(813)
  5674. ATL_IMPL_THUNK(814)
  5675. ATL_IMPL_THUNK(815)
  5676. ATL_IMPL_THUNK(816)
  5677. ATL_IMPL_THUNK(817)
  5678. ATL_IMPL_THUNK(818)
  5679. ATL_IMPL_THUNK(819)
  5680. ATL_IMPL_THUNK(820)
  5681. ATL_IMPL_THUNK(821)
  5682. ATL_IMPL_THUNK(822)
  5683. ATL_IMPL_THUNK(823)
  5684. ATL_IMPL_THUNK(824)
  5685. ATL_IMPL_THUNK(825)
  5686. ATL_IMPL_THUNK(826)
  5687. ATL_IMPL_THUNK(827)
  5688. ATL_IMPL_THUNK(828)
  5689. ATL_IMPL_THUNK(829)
  5690. ATL_IMPL_THUNK(830)
  5691. ATL_IMPL_THUNK(831)
  5692. ATL_IMPL_THUNK(832)
  5693. ATL_IMPL_THUNK(833)
  5694. ATL_IMPL_THUNK(834)
  5695. ATL_IMPL_THUNK(835)
  5696. ATL_IMPL_THUNK(836)
  5697. ATL_IMPL_THUNK(837)
  5698. ATL_IMPL_THUNK(838)
  5699. ATL_IMPL_THUNK(839)
  5700. ATL_IMPL_THUNK(840)
  5701. ATL_IMPL_THUNK(841)
  5702. ATL_IMPL_THUNK(842)
  5703. ATL_IMPL_THUNK(843)
  5704. ATL_IMPL_THUNK(844)
  5705. ATL_IMPL_THUNK(845)
  5706. ATL_IMPL_THUNK(846)
  5707. ATL_IMPL_THUNK(847)
  5708. ATL_IMPL_THUNK(848)
  5709. ATL_IMPL_THUNK(849)
  5710. ATL_IMPL_THUNK(850)
  5711. ATL_IMPL_THUNK(851)
  5712. ATL_IMPL_THUNK(852)
  5713. ATL_IMPL_THUNK(853)
  5714. ATL_IMPL_THUNK(854)
  5715. ATL_IMPL_THUNK(855)
  5716. ATL_IMPL_THUNK(856)
  5717. ATL_IMPL_THUNK(857)
  5718. ATL_IMPL_THUNK(858)
  5719. ATL_IMPL_THUNK(859)
  5720. ATL_IMPL_THUNK(860)
  5721. ATL_IMPL_THUNK(861)
  5722. ATL_IMPL_THUNK(862)
  5723. ATL_IMPL_THUNK(863)
  5724. ATL_IMPL_THUNK(864)
  5725. ATL_IMPL_THUNK(865)
  5726. ATL_IMPL_THUNK(866)
  5727. ATL_IMPL_THUNK(867)
  5728. ATL_IMPL_THUNK(868)
  5729. ATL_IMPL_THUNK(869)
  5730. ATL_IMPL_THUNK(870)
  5731. ATL_IMPL_THUNK(871)
  5732. ATL_IMPL_THUNK(872)
  5733. ATL_IMPL_THUNK(873)
  5734. ATL_IMPL_THUNK(874)
  5735. ATL_IMPL_THUNK(875)
  5736. ATL_IMPL_THUNK(876)
  5737. ATL_IMPL_THUNK(877)
  5738. ATL_IMPL_THUNK(878)
  5739. ATL_IMPL_THUNK(879)
  5740. ATL_IMPL_THUNK(880)
  5741. ATL_IMPL_THUNK(881)
  5742. ATL_IMPL_THUNK(882)
  5743. ATL_IMPL_THUNK(883)
  5744. ATL_IMPL_THUNK(884)
  5745. ATL_IMPL_THUNK(885)
  5746. ATL_IMPL_THUNK(886)
  5747. ATL_IMPL_THUNK(887)
  5748. ATL_IMPL_THUNK(888)
  5749. ATL_IMPL_THUNK(889)
  5750. ATL_IMPL_THUNK(890)
  5751. ATL_IMPL_THUNK(891)
  5752. ATL_IMPL_THUNK(892)
  5753. ATL_IMPL_THUNK(893)
  5754. ATL_IMPL_THUNK(894)
  5755. ATL_IMPL_THUNK(895)
  5756. ATL_IMPL_THUNK(896)
  5757. ATL_IMPL_THUNK(897)
  5758. ATL_IMPL_THUNK(898)
  5759. ATL_IMPL_THUNK(899)
  5760. ATL_IMPL_THUNK(900)
  5761. ATL_IMPL_THUNK(901)
  5762. ATL_IMPL_THUNK(902)
  5763. ATL_IMPL_THUNK(903)
  5764. ATL_IMPL_THUNK(904)
  5765. ATL_IMPL_THUNK(905)
  5766. ATL_IMPL_THUNK(906)
  5767. ATL_IMPL_THUNK(907)
  5768. ATL_IMPL_THUNK(908)
  5769. ATL_IMPL_THUNK(909)
  5770. ATL_IMPL_THUNK(910)
  5771. ATL_IMPL_THUNK(911)
  5772. ATL_IMPL_THUNK(912)
  5773. ATL_IMPL_THUNK(913)
  5774. ATL_IMPL_THUNK(914)
  5775. ATL_IMPL_THUNK(915)
  5776. ATL_IMPL_THUNK(916)
  5777. ATL_IMPL_THUNK(917)
  5778. ATL_IMPL_THUNK(918)
  5779. ATL_IMPL_THUNK(919)
  5780. ATL_IMPL_THUNK(920)
  5781. ATL_IMPL_THUNK(921)
  5782. ATL_IMPL_THUNK(922)
  5783. ATL_IMPL_THUNK(923)
  5784. ATL_IMPL_THUNK(924)
  5785. ATL_IMPL_THUNK(925)
  5786. ATL_IMPL_THUNK(926)
  5787. ATL_IMPL_THUNK(927)
  5788. ATL_IMPL_THUNK(928)
  5789. ATL_IMPL_THUNK(929)
  5790. ATL_IMPL_THUNK(930)
  5791. ATL_IMPL_THUNK(931)
  5792. ATL_IMPL_THUNK(932)
  5793. ATL_IMPL_THUNK(933)
  5794. ATL_IMPL_THUNK(934)
  5795. ATL_IMPL_THUNK(935)
  5796. ATL_IMPL_THUNK(936)
  5797. ATL_IMPL_THUNK(937)
  5798. ATL_IMPL_THUNK(938)
  5799. ATL_IMPL_THUNK(939)
  5800. ATL_IMPL_THUNK(940)
  5801. ATL_IMPL_THUNK(941)
  5802. ATL_IMPL_THUNK(942)
  5803. ATL_IMPL_THUNK(943)
  5804. ATL_IMPL_THUNK(944)
  5805. ATL_IMPL_THUNK(945)
  5806. ATL_IMPL_THUNK(946)
  5807. ATL_IMPL_THUNK(947)
  5808. ATL_IMPL_THUNK(948)
  5809. ATL_IMPL_THUNK(949)
  5810. ATL_IMPL_THUNK(950)
  5811. ATL_IMPL_THUNK(951)
  5812. ATL_IMPL_THUNK(952)
  5813. ATL_IMPL_THUNK(953)
  5814. ATL_IMPL_THUNK(954)
  5815. ATL_IMPL_THUNK(955)
  5816. ATL_IMPL_THUNK(956)
  5817. ATL_IMPL_THUNK(957)
  5818. ATL_IMPL_THUNK(958)
  5819. ATL_IMPL_THUNK(959)
  5820. ATL_IMPL_THUNK(960)
  5821. ATL_IMPL_THUNK(961)
  5822. ATL_IMPL_THUNK(962)
  5823. ATL_IMPL_THUNK(963)
  5824. ATL_IMPL_THUNK(964)
  5825. ATL_IMPL_THUNK(965)
  5826. ATL_IMPL_THUNK(966)
  5827. ATL_IMPL_THUNK(967)
  5828. ATL_IMPL_THUNK(968)
  5829. ATL_IMPL_THUNK(969)
  5830. ATL_IMPL_THUNK(970)
  5831. ATL_IMPL_THUNK(971)
  5832. ATL_IMPL_THUNK(972)
  5833. ATL_IMPL_THUNK(973)
  5834. ATL_IMPL_THUNK(974)
  5835. ATL_IMPL_THUNK(975)
  5836. ATL_IMPL_THUNK(976)
  5837. ATL_IMPL_THUNK(977)
  5838. ATL_IMPL_THUNK(978)
  5839. ATL_IMPL_THUNK(979)
  5840. ATL_IMPL_THUNK(980)
  5841. ATL_IMPL_THUNK(981)
  5842. ATL_IMPL_THUNK(982)
  5843. ATL_IMPL_THUNK(983)
  5844. ATL_IMPL_THUNK(984)
  5845. ATL_IMPL_THUNK(985)
  5846. ATL_IMPL_THUNK(986)
  5847. ATL_IMPL_THUNK(987)
  5848. ATL_IMPL_THUNK(988)
  5849. ATL_IMPL_THUNK(989)
  5850. ATL_IMPL_THUNK(990)
  5851. ATL_IMPL_THUNK(991)
  5852. ATL_IMPL_THUNK(992)
  5853. ATL_IMPL_THUNK(993)
  5854. ATL_IMPL_THUNK(994)
  5855. ATL_IMPL_THUNK(995)
  5856. ATL_IMPL_THUNK(996)
  5857. ATL_IMPL_THUNK(997)
  5858. ATL_IMPL_THUNK(998)
  5859. ATL_IMPL_THUNK(999)
  5860. ATL_IMPL_THUNK(1000)
  5861. ATL_IMPL_THUNK(1001)
  5862. ATL_IMPL_THUNK(1002)
  5863. ATL_IMPL_THUNK(1003)
  5864. ATL_IMPL_THUNK(1004)
  5865. ATL_IMPL_THUNK(1005)
  5866. ATL_IMPL_THUNK(1006)
  5867. ATL_IMPL_THUNK(1007)
  5868. ATL_IMPL_THUNK(1008)
  5869. ATL_IMPL_THUNK(1009)
  5870. ATL_IMPL_THUNK(1010)
  5871. ATL_IMPL_THUNK(1011)
  5872. ATL_IMPL_THUNK(1012)
  5873. ATL_IMPL_THUNK(1013)
  5874. ATL_IMPL_THUNK(1014)
  5875. ATL_IMPL_THUNK(1015)
  5876. ATL_IMPL_THUNK(1016)
  5877. ATL_IMPL_THUNK(1017)
  5878. ATL_IMPL_THUNK(1018)
  5879. ATL_IMPL_THUNK(1019)
  5880. ATL_IMPL_THUNK(1020)
  5881. ATL_IMPL_THUNK(1021)
  5882. ATL_IMPL_THUNK(1022)
  5883. ATL_IMPL_THUNK(1023)
  5884. #pragma warning(pop)
  5885. #endif // _M_IX86
  5886. /////////////////////////////////////////////////////////////////////////////////////////////
  5887. // Thread Pooling classes
  5888. class _AtlAptCreateObjData
  5889. {
  5890. public:
  5891. _ATL_CREATORFUNC* pfnCreateInstance;
  5892. const IID* piid;
  5893. HANDLE hEvent;
  5894. LPSTREAM pStream;
  5895. HRESULT hRes;
  5896. };
  5897. class CComApartment
  5898. {
  5899. public:
  5900. CComApartment()
  5901. {
  5902. m_nLockCnt = 0;
  5903. m_hThread = NULL;
  5904. }
  5905. static UINT ATL_CREATE_OBJECT;
  5906. static DWORD WINAPI _Apartment(void* pv)
  5907. {
  5908. return ((CComApartment*)pv)->Apartment();
  5909. }
  5910. DWORD Apartment()
  5911. {
  5912. CoInitialize(NULL);
  5913. MSG msg;
  5914. while(GetMessage(&msg, 0, 0, 0) > 0)
  5915. {
  5916. if (msg.message == ATL_CREATE_OBJECT)
  5917. {
  5918. _AtlAptCreateObjData* pdata = (_AtlAptCreateObjData*)msg.lParam;
  5919. IUnknown* pUnk = NULL;
  5920. pdata->hRes = pdata->pfnCreateInstance(NULL, __uuidof(IUnknown), (void**)&pUnk);
  5921. if (SUCCEEDED(pdata->hRes))
  5922. pdata->hRes = CoMarshalInterThreadInterfaceInStream(*pdata->piid, pUnk, &pdata->pStream);
  5923. if (SUCCEEDED(pdata->hRes))
  5924. {
  5925. pUnk->Release();
  5926. ATLTRACE(atlTraceCOM, 2, _T("Object created on thread = %d\n"), GetCurrentThreadId());
  5927. }
  5928. #ifdef _DEBUG
  5929. else
  5930. {
  5931. ATLTRACE(atlTraceCOM, 2, _T("Failed to create Object on thread = %d\n"), GetCurrentThreadId());
  5932. }
  5933. #endif
  5934. SetEvent(pdata->hEvent);
  5935. }
  5936. DispatchMessage(&msg);
  5937. }
  5938. CoUninitialize();
  5939. return 0;
  5940. }
  5941. LONG Lock() {return CComGlobalsThreadModel::Increment(&m_nLockCnt);}
  5942. LONG Unlock(){return CComGlobalsThreadModel::Decrement(&m_nLockCnt);
  5943. }
  5944. LONG GetLockCount() {return m_nLockCnt;}
  5945. DWORD m_dwThreadID;
  5946. HANDLE m_hThread;
  5947. LONG m_nLockCnt;
  5948. };
  5949. __declspec(selectany) UINT CComApartment::ATL_CREATE_OBJECT = 0;
  5950. class CComSimpleThreadAllocator
  5951. {
  5952. public:
  5953. CComSimpleThreadAllocator()
  5954. {
  5955. m_nThread = 0;
  5956. }
  5957. int GetThread(CComApartment* /*pApt*/, int nThreads)
  5958. {
  5959. if (++m_nThread == nThreads)
  5960. m_nThread = 0;
  5961. return m_nThread;
  5962. }
  5963. int m_nThread;
  5964. };
  5965. __interface IAtlAutoThreadModule
  5966. {
  5967. virtual HRESULT CreateInstance(void* pfnCreateInstance, REFIID riid, void** ppvObj);
  5968. };
  5969. __declspec(selectany) IAtlAutoThreadModule* _pAtlAutoThreadModule;
  5970. template <class T, class ThreadAllocator = CComSimpleThreadAllocator, DWORD dwWait = INFINITE>
  5971. class ATL_NO_VTABLE CAtlAutoThreadModuleT : public IAtlAutoThreadModule
  5972. {
  5973. // This class is not for use in a DLL.
  5974. // If this class were used in a DLL, there will be a deadlock when the DLL is unloaded.
  5975. // because of dwWait's default value of INFINITE
  5976. public:
  5977. CAtlAutoThreadModuleT(int nThreads = T::GetDefaultThreads())
  5978. {
  5979. ATLASSERT(_pAtlAutoThreadModule == NULL);
  5980. _pAtlAutoThreadModule = this;
  5981. m_pApartments = NULL;
  5982. m_nThreads= 0;
  5983. ATLTRY(m_pApartments = new CComApartment[nThreads]);
  5984. ATLASSERT(m_pApartments != NULL);
  5985. if(m_pApartments == NULL)
  5986. {
  5987. CAtlBaseModule::m_bInitFailed = true;
  5988. }
  5989. memset(m_pApartments, 0, sizeof(CComApartment) * nThreads);
  5990. m_nThreads = nThreads;
  5991. for (int i = 0; i < nThreads; i++)
  5992. {
  5993. #if !defined(_ATL_MIN_CRT) && defined(_MT)
  5994. typedef unsigned ( __stdcall *pfnThread )( void * );
  5995. m_pApartments[i].m_hThread = (HANDLE)_beginthreadex(NULL, 0, (pfnThread)CComApartment::_Apartment, &m_pApartments[i], 0, (UINT*)&m_pApartments[i].m_dwThreadID);
  5996. if (m_pApartments[i].m_hThread == NULL)
  5997. {
  5998. HRESULT hr = E_FAIL;
  5999. switch (errno)
  6000. {
  6001. case EAGAIN:
  6002. hr = HRESULT_FROM_WIN32(ERROR_TOO_MANY_TCBS);
  6003. break;
  6004. case EINVAL:
  6005. hr = E_INVALIDARG;
  6006. break;
  6007. }
  6008. CAtlBaseModule::m_bInitFailed = true;
  6009. break;
  6010. }
  6011. #else
  6012. m_pApartments[i].m_hThread = ::CreateThread(NULL, 0, CComApartment::_Apartment, (void*)&m_pApartments[i], 0, &m_pApartments[i].m_dwThreadID);
  6013. // clean up allocated threads
  6014. if (m_pApartments[i].m_hThread == NULL)
  6015. {
  6016. CAtlBaseModule::m_bInitFailed = true;
  6017. break;
  6018. }
  6019. #endif
  6020. }
  6021. CComApartment::ATL_CREATE_OBJECT = RegisterWindowMessage(_T("ATL_CREATE_OBJECT"));
  6022. }
  6023. ~CAtlAutoThreadModuleT()
  6024. {
  6025. if (m_pApartments == NULL)
  6026. return;
  6027. DWORD dwCurrentThreadId = GetCurrentThreadId();
  6028. int nCurrentThread = -1;
  6029. for (int i=0; i < m_nThreads; i++)
  6030. {
  6031. if (m_pApartments[i].m_hThread == NULL)
  6032. continue;
  6033. if (m_pApartments[i].m_dwThreadID == dwCurrentThreadId)
  6034. {
  6035. nCurrentThread = i;
  6036. continue;
  6037. }
  6038. while (::PostThreadMessage(m_pApartments[i].m_dwThreadID, WM_QUIT, 0, 0) == 0)
  6039. {
  6040. if (GetLastError() == ERROR_INVALID_THREAD_ID)
  6041. {
  6042. ATLASSERT(FALSE);
  6043. break;
  6044. }
  6045. ::Sleep(100);
  6046. }
  6047. ::WaitForSingleObject(m_pApartments[i].m_hThread, dwWait);
  6048. CloseHandle(m_pApartments[i].m_hThread);
  6049. }
  6050. if (nCurrentThread != -1)
  6051. CloseHandle(m_pApartments[nCurrentThread].m_hThread);
  6052. delete [] m_pApartments;
  6053. m_pApartments = NULL;
  6054. }
  6055. HRESULT CreateInstance(void* pfnCreateInstance, REFIID riid, void** ppvObj)
  6056. {
  6057. ATLASSERT(ppvObj != NULL);
  6058. if (ppvObj == NULL)
  6059. return E_POINTER;
  6060. *ppvObj = NULL;
  6061. _ATL_CREATORFUNC* pFunc = (_ATL_CREATORFUNC*) pfnCreateInstance;
  6062. _AtlAptCreateObjData data;
  6063. data.pfnCreateInstance = pFunc;
  6064. data.piid = &riid;
  6065. data.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
  6066. data.hRes = S_OK;
  6067. int nThread = m_Allocator.GetThread(m_pApartments, m_nThreads);
  6068. int nIterations = 0;
  6069. while(::PostThreadMessage(m_pApartments[nThread].m_dwThreadID, CComApartment::ATL_CREATE_OBJECT, 0, (LPARAM)&data) == 0 && ++nIterations < 100)
  6070. {
  6071. Sleep(100);
  6072. }
  6073. if (nIterations < 100)
  6074. {
  6075. AtlWaitWithMessageLoop(data.hEvent);
  6076. }
  6077. else
  6078. {
  6079. data.hRes = AtlHresultFromLastError();
  6080. }
  6081. CloseHandle(data.hEvent);
  6082. if (SUCCEEDED(data.hRes))
  6083. data.hRes = CoGetInterfaceAndReleaseStream(data.pStream, riid, ppvObj);
  6084. return data.hRes;
  6085. }
  6086. DWORD dwThreadID;
  6087. int m_nThreads;
  6088. CComApartment* m_pApartments;
  6089. ThreadAllocator m_Allocator;
  6090. static int GetDefaultThreads()
  6091. {
  6092. SYSTEM_INFO si;
  6093. GetSystemInfo(&si);
  6094. return si.dwNumberOfProcessors * 4;
  6095. }
  6096. };
  6097. class CAtlAutoThreadModule : public CAtlAutoThreadModuleT<CAtlAutoThreadModule>
  6098. {
  6099. public :
  6100. };
  6101. template <class ThreadAllocator = CComSimpleThreadAllocator, DWORD dwWait = INFINITE>
  6102. class CComAutoThreadModule :
  6103. public CComModule,
  6104. public CAtlAutoThreadModuleT<CComAutoThreadModule, ThreadAllocator, dwWait>
  6105. {
  6106. public:
  6107. CComAutoThreadModule(int nThreads = GetDefaultThreads()) :
  6108. CAtlAutoThreadModuleT<CComAutoThreadModule, ThreadAllocator, dwWait>(nThreads)
  6109. {
  6110. }
  6111. HRESULT Init(_ATL_OBJMAP_ENTRY* p, HINSTANCE h, const GUID* plibid = NULL, int nThreads = GetDefaultThreads())
  6112. {
  6113. ATLASSERT(nThreads == GetDefaultThreads() && _T("Set number of threads through the constructor"));
  6114. return CComModule::Init(p, h, plibid);
  6115. }
  6116. };
  6117. #define ATL_VARIANT_TRUE VARIANT_BOOL( -1 )
  6118. #define ATL_VARIANT_FALSE VARIANT_BOOL( 0 )
  6119. /////////////////////////////////////////////////////////////////////////////
  6120. // CComBSTR
  6121. class CComBSTR
  6122. {
  6123. public:
  6124. BSTR m_str;
  6125. CComBSTR() throw()
  6126. {
  6127. m_str = NULL;
  6128. }
  6129. CComBSTR(int nSize)
  6130. {
  6131. if (nSize == 0)
  6132. m_str = NULL;
  6133. else
  6134. {
  6135. m_str = ::SysAllocStringLen(NULL, nSize);
  6136. if (m_str == NULL)
  6137. AtlThrow(E_OUTOFMEMORY);
  6138. }
  6139. }
  6140. CComBSTR(int nSize, LPCOLESTR sz)
  6141. {
  6142. if (nSize == 0)
  6143. m_str = NULL;
  6144. else
  6145. {
  6146. m_str = ::SysAllocStringLen(sz, nSize);
  6147. if (m_str == NULL)
  6148. AtlThrow(E_OUTOFMEMORY);
  6149. }
  6150. }
  6151. CComBSTR(LPCOLESTR pSrc)
  6152. {
  6153. if (pSrc == NULL)
  6154. m_str = NULL;
  6155. else
  6156. {
  6157. m_str = ::SysAllocString(pSrc);
  6158. if (m_str == NULL)
  6159. AtlThrow(E_OUTOFMEMORY);
  6160. }
  6161. }
  6162. CComBSTR(const CComBSTR& src)
  6163. {
  6164. m_str = src.Copy();
  6165. if (!!src && m_str == NULL)
  6166. AtlThrow(E_OUTOFMEMORY);
  6167. }
  6168. CComBSTR(REFGUID guid)
  6169. {
  6170. OLECHAR szGUID[64];
  6171. ::StringFromGUID2(guid, szGUID, 64);
  6172. m_str = ::SysAllocString(szGUID);
  6173. if (m_str == NULL)
  6174. AtlThrow(E_OUTOFMEMORY);
  6175. }
  6176. CComBSTR& operator=(const CComBSTR& src)
  6177. {
  6178. if (m_str != src.m_str)
  6179. {
  6180. ::SysFreeString(m_str);
  6181. m_str = src.Copy();
  6182. if (!!src && m_str == NULL)
  6183. AtlThrow(E_OUTOFMEMORY);
  6184. }
  6185. return *this;
  6186. }
  6187. CComBSTR& operator=(LPCOLESTR pSrc)
  6188. {
  6189. ::SysFreeString(m_str);
  6190. if (pSrc != NULL)
  6191. {
  6192. m_str = ::SysAllocString(pSrc);
  6193. if (m_str == NULL)
  6194. AtlThrow(E_OUTOFMEMORY);
  6195. }
  6196. else
  6197. m_str = NULL;
  6198. return *this;
  6199. }
  6200. ~CComBSTR() throw()
  6201. {
  6202. ::SysFreeString(m_str);
  6203. }
  6204. unsigned int Length() const throw()
  6205. {
  6206. return (m_str == NULL)? 0 : SysStringLen(m_str);
  6207. }
  6208. unsigned int ByteLength() const throw()
  6209. {
  6210. return (m_str == NULL)? 0 : SysStringByteLen(m_str);
  6211. }
  6212. operator BSTR() const throw()
  6213. {
  6214. return m_str;
  6215. }
  6216. BSTR* operator&() throw()
  6217. {
  6218. return &m_str;
  6219. }
  6220. BSTR Copy() const throw()
  6221. {
  6222. if (m_str == NULL)
  6223. return NULL;
  6224. return ::SysAllocStringByteLen((char*)m_str, ::SysStringByteLen(m_str));
  6225. }
  6226. HRESULT CopyTo(BSTR* pbstr) throw()
  6227. {
  6228. ATLASSERT(pbstr != NULL);
  6229. if (pbstr == NULL)
  6230. return E_POINTER;
  6231. *pbstr = Copy();
  6232. if ((*pbstr == NULL) && (m_str != NULL))
  6233. return E_OUTOFMEMORY;
  6234. return S_OK;
  6235. }
  6236. // copy BSTR to VARIANT
  6237. HRESULT CopyTo(VARIANT *pvarDest) throw()
  6238. {
  6239. ATLASSERT(pvarDest != NULL);
  6240. HRESULT hRes = E_POINTER;
  6241. if (pvarDest != NULL)
  6242. {
  6243. pvarDest->vt = VT_BSTR;
  6244. pvarDest->bstrVal = Copy();
  6245. if (pvarDest->bstrVal == NULL && m_str != NULL)
  6246. hRes = E_OUTOFMEMORY;
  6247. else
  6248. hRes = S_OK;
  6249. }
  6250. return hRes;
  6251. }
  6252. void Attach(BSTR src) throw()
  6253. {
  6254. ::SysFreeString(m_str);
  6255. m_str = src;
  6256. }
  6257. BSTR Detach() throw()
  6258. {
  6259. BSTR s = m_str;
  6260. m_str = NULL;
  6261. return s;
  6262. }
  6263. void Empty() throw()
  6264. {
  6265. ::SysFreeString(m_str);
  6266. m_str = NULL;
  6267. }
  6268. bool operator!() const throw()
  6269. {
  6270. return (m_str == NULL);
  6271. }
  6272. HRESULT Append(const CComBSTR& bstrSrc) throw()
  6273. {
  6274. return AppendBSTR(bstrSrc.m_str);
  6275. }
  6276. HRESULT Append(LPCOLESTR lpsz) throw()
  6277. {
  6278. return Append(lpsz, UINT(ocslen(lpsz)));
  6279. }
  6280. // a BSTR is just a LPCOLESTR so we need a special version to signify
  6281. // that we are appending a BSTR
  6282. HRESULT AppendBSTR(BSTR p) throw()
  6283. {
  6284. if (p == NULL)
  6285. return S_OK;
  6286. BSTR bstrNew = NULL;
  6287. HRESULT hr;
  6288. hr = VarBstrCat(m_str, p, &bstrNew);
  6289. if (SUCCEEDED(hr))
  6290. {
  6291. ::SysFreeString(m_str);
  6292. m_str = bstrNew;
  6293. }
  6294. return hr;
  6295. }
  6296. HRESULT Append(LPCOLESTR lpsz, int nLen) throw()
  6297. {
  6298. if (lpsz == NULL || (m_str != NULL && nLen == 0))
  6299. return S_OK;
  6300. int n1 = Length();
  6301. BSTR b;
  6302. b = ::SysAllocStringLen(NULL, n1+nLen);
  6303. if (b == NULL)
  6304. return E_OUTOFMEMORY;
  6305. memcpy(b, m_str, n1*sizeof(OLECHAR));
  6306. memcpy(b+n1, lpsz, nLen*sizeof(OLECHAR));
  6307. b[n1+nLen] = NULL;
  6308. SysFreeString(m_str);
  6309. m_str = b;
  6310. return S_OK;
  6311. }
  6312. HRESULT Append(char ch) throw()
  6313. {
  6314. OLECHAR chO = ch;
  6315. return( Append( &chO, 1 ) );
  6316. }
  6317. HRESULT Append(wchar_t ch) throw()
  6318. {
  6319. return( Append( &ch, 1 ) );
  6320. }
  6321. HRESULT AppendBytes(const char* lpsz, int nLen) throw()
  6322. {
  6323. if (lpsz == NULL || nLen == 0)
  6324. return S_OK;
  6325. int n1 = ByteLength();
  6326. BSTR b;
  6327. b = ::SysAllocStringByteLen(NULL, n1+nLen);
  6328. if (b == NULL)
  6329. return E_OUTOFMEMORY;
  6330. memcpy(b, m_str, n1);
  6331. memcpy(((char*)b)+n1, lpsz, nLen);
  6332. *((OLECHAR*)(((char*)b)+n1+nLen)) = NULL;
  6333. SysFreeString(m_str);
  6334. m_str = b;
  6335. return S_OK;
  6336. }
  6337. HRESULT AssignBSTR(const BSTR bstrSrc) throw()
  6338. {
  6339. ::SysFreeString(m_str);
  6340. HRESULT hr = S_OK;
  6341. if (bstrSrc != NULL)
  6342. {
  6343. m_str = ::SysAllocStringByteLen((char*)bstrSrc, ::SysStringByteLen(bstrSrc));
  6344. if (m_str == NULL)
  6345. hr = E_OUTOFMEMORY;
  6346. }
  6347. else
  6348. m_str = NULL;
  6349. return S_OK;
  6350. }
  6351. HRESULT ToLower() throw()
  6352. {
  6353. if (m_str != NULL)
  6354. {
  6355. #ifdef _UNICODE
  6356. // Convert in place
  6357. CharLowerBuff(m_str, Length());
  6358. #else
  6359. // Cannot use conversion macros due to possible embedded NULLs
  6360. UINT _acp = _AtlGetConversionACP();
  6361. int _convert = WideCharToMultiByte(_acp, 0, m_str, Length(), NULL, 0, NULL, NULL);
  6362. LPSTR pszA = (LPSTR) alloca(_convert);
  6363. if (pszA == NULL)
  6364. return E_OUTOFMEMORY;
  6365. int nRet = WideCharToMultiByte(_acp, 0, m_str, Length(), pszA, _convert, NULL, NULL);
  6366. if (nRet == 0)
  6367. {
  6368. ATLASSERT(0);
  6369. return AtlHresultFromLastError();
  6370. }
  6371. CharLowerBuff(pszA, nRet);
  6372. _convert = MultiByteToWideChar(_acp, 0, pszA, nRet, NULL, 0);
  6373. LPWSTR pszW = (LPWSTR) alloca(_convert * sizeof(OLECHAR));
  6374. if (pszW == NULL)
  6375. return E_OUTOFMEMORY;
  6376. nRet = MultiByteToWideChar(_acp, 0, pszA, nRet, pszW, _convert);
  6377. if (nRet == 0)
  6378. {
  6379. ATLASSERT(0);
  6380. return AtlHresultFromLastError();
  6381. }
  6382. BSTR b = ::SysAllocStringByteLen((LPCSTR) pszW, nRet * sizeof(OLECHAR));
  6383. if (b == NULL)
  6384. return E_OUTOFMEMORY;
  6385. SysFreeString(m_str);
  6386. m_str = b;
  6387. #endif
  6388. }
  6389. return S_OK;
  6390. }
  6391. HRESULT ToUpper() throw()
  6392. {
  6393. if (m_str != NULL)
  6394. {
  6395. #ifdef _UNICODE
  6396. // Convert in place
  6397. CharUpperBuff(m_str, Length());
  6398. #else
  6399. // Cannot use conversion macros due to possible embedded NULLs
  6400. UINT _acp = _AtlGetConversionACP();
  6401. int _convert = WideCharToMultiByte(_acp, 0, m_str, Length(), NULL, 0, NULL, NULL);
  6402. LPSTR pszA = (LPSTR) alloca(_convert);
  6403. if (pszA == NULL)
  6404. return E_OUTOFMEMORY;
  6405. int nRet = WideCharToMultiByte(_acp, 0, m_str, Length(), pszA, _convert, NULL, NULL);
  6406. if (nRet == 0)
  6407. {
  6408. ATLASSERT(0);
  6409. return AtlHresultFromLastError();
  6410. }
  6411. CharUpperBuff(pszA, nRet);
  6412. _convert = MultiByteToWideChar(_acp, 0, pszA, nRet, NULL, 0);
  6413. LPWSTR pszW = (LPWSTR) alloca(_convert * sizeof(OLECHAR));
  6414. if (pszW == NULL)
  6415. return E_OUTOFMEMORY;
  6416. nRet = MultiByteToWideChar(_acp, 0, pszA, nRet, pszW, _convert);
  6417. if (nRet == 0)
  6418. {
  6419. ATLASSERT(0);
  6420. return AtlHresultFromLastError();
  6421. }
  6422. BSTR b = ::SysAllocStringByteLen((LPCSTR) pszW, nRet * sizeof(OLECHAR));
  6423. if (b == NULL)
  6424. return E_OUTOFMEMORY;
  6425. SysFreeString(m_str);
  6426. m_str = b;
  6427. #endif
  6428. }
  6429. return S_OK;
  6430. }
  6431. bool LoadString(HINSTANCE hInst, UINT nID) throw()
  6432. {
  6433. ::SysFreeString(m_str);
  6434. m_str = NULL;
  6435. return LoadStringResource(hInst, nID, m_str);
  6436. }
  6437. bool LoadString(UINT nID) throw()
  6438. {
  6439. ::SysFreeString(m_str);
  6440. m_str = NULL;
  6441. return LoadStringResource(nID, m_str);
  6442. }
  6443. CComBSTR& operator+=(const CComBSTR& bstrSrc)
  6444. {
  6445. HRESULT hr;
  6446. hr = AppendBSTR(bstrSrc.m_str);
  6447. if (FAILED(hr))
  6448. AtlThrow(hr);
  6449. return *this;
  6450. }
  6451. CComBSTR& operator+=(LPCOLESTR pszSrc)
  6452. {
  6453. HRESULT hr;
  6454. hr = Append(pszSrc);
  6455. if (FAILED(hr))
  6456. AtlThrow(hr);
  6457. return *this;
  6458. }
  6459. bool operator<(const CComBSTR& bstrSrc) const throw()
  6460. {
  6461. return VarBstrCmp(m_str, bstrSrc.m_str, LOCALE_USER_DEFAULT, 0) == VARCMP_LT;
  6462. }
  6463. bool operator<(LPCOLESTR pszSrc) const
  6464. {
  6465. CComBSTR bstr2(pszSrc);
  6466. return operator<(bstr2);
  6467. }
  6468. bool operator>(const CComBSTR& bstrSrc) const throw()
  6469. {
  6470. return VarBstrCmp(m_str, bstrSrc.m_str, LOCALE_USER_DEFAULT, 0) == VARCMP_GT;
  6471. }
  6472. bool operator>(LPCOLESTR pszSrc) const
  6473. {
  6474. CComBSTR bstr2(pszSrc);
  6475. return operator>(bstr2);
  6476. }
  6477. bool operator!=(const CComBSTR& bstrSrc) const throw()
  6478. {
  6479. return !operator==(bstrSrc);
  6480. }
  6481. bool operator!=(LPCOLESTR pszSrc) const
  6482. {
  6483. return !operator==(pszSrc);
  6484. }
  6485. bool operator!=(int nNull) const throw()
  6486. {
  6487. return !operator==(nNull);
  6488. }
  6489. bool operator==(const CComBSTR& bstrSrc) const throw()
  6490. {
  6491. return VarBstrCmp(m_str, bstrSrc.m_str, LOCALE_USER_DEFAULT, 0) == VARCMP_EQ;
  6492. }
  6493. bool operator==(LPCOLESTR pszSrc) const
  6494. {
  6495. CComBSTR bstr2(pszSrc);
  6496. return operator==(bstr2);
  6497. }
  6498. bool operator==(int nNull) const throw()
  6499. {
  6500. ATLASSERT(nNull == NULL);
  6501. (void)nNull;
  6502. return (m_str == NULL);
  6503. }
  6504. CComBSTR(LPCSTR pSrc)
  6505. {
  6506. if (pSrc != NULL)
  6507. {
  6508. m_str = A2WBSTR(pSrc);
  6509. if (m_str == NULL)
  6510. AtlThrow(E_OUTOFMEMORY);
  6511. }
  6512. else
  6513. m_str = NULL;
  6514. }
  6515. CComBSTR(int nSize, LPCSTR sz)
  6516. {
  6517. if (nSize != 0 && sz == NULL)
  6518. {
  6519. m_str = ::SysAllocStringLen(NULL, nSize);
  6520. if (m_str == NULL)
  6521. AtlThrow(E_OUTOFMEMORY);
  6522. return;
  6523. }
  6524. m_str = A2WBSTR(sz, nSize);
  6525. if (m_str == NULL && nSize != 0)
  6526. AtlThrow(E_OUTOFMEMORY);
  6527. }
  6528. HRESULT Append(LPCSTR lpsz) throw()
  6529. {
  6530. if (lpsz == NULL)
  6531. return S_OK;
  6532. USES_CONVERSION;
  6533. LPCOLESTR lpo = A2COLE(lpsz);
  6534. if (lpo == NULL)
  6535. return E_OUTOFMEMORY;
  6536. return Append(lpo, UINT(ocslen(lpo)));
  6537. }
  6538. CComBSTR& operator=(LPCSTR pSrc)
  6539. {
  6540. ::SysFreeString(m_str);
  6541. m_str = A2WBSTR(pSrc);
  6542. if (m_str == NULL && pSrc != NULL)
  6543. AtlThrow(E_OUTOFMEMORY);
  6544. return *this;
  6545. }
  6546. bool operator<(LPCSTR pszSrc) const
  6547. {
  6548. CComBSTR bstr2(pszSrc);
  6549. return operator<(bstr2);
  6550. }
  6551. bool operator>(LPCSTR pszSrc) const
  6552. {
  6553. CComBSTR bstr2(pszSrc);
  6554. return operator>(bstr2);
  6555. }
  6556. bool operator!=(LPCSTR pszSrc) const
  6557. {
  6558. return !operator==(pszSrc);
  6559. }
  6560. bool operator==(LPCSTR pszSrc) const
  6561. {
  6562. CComBSTR bstr2(pszSrc);
  6563. return operator==(bstr2);
  6564. }
  6565. HRESULT WriteToStream(IStream* pStream) throw()
  6566. {
  6567. ATLASSERT(pStream != NULL);
  6568. ULONG cb;
  6569. ULONG cbStrLen = ULONG(m_str ? SysStringByteLen(m_str)+sizeof(OLECHAR) : 0);
  6570. HRESULT hr = pStream->Write((void*) &cbStrLen, sizeof(cbStrLen), &cb);
  6571. if (FAILED(hr))
  6572. return hr;
  6573. return cbStrLen ? pStream->Write((void*) m_str, cbStrLen, &cb) : S_OK;
  6574. }
  6575. HRESULT ReadFromStream(IStream* pStream) throw()
  6576. {
  6577. ATLASSERT(pStream != NULL);
  6578. ATLASSERT(m_str == NULL); // should be empty
  6579. ULONG cbStrLen = 0;
  6580. HRESULT hr = pStream->Read((void*) &cbStrLen, sizeof(cbStrLen), NULL);
  6581. if ((hr == S_OK) && (cbStrLen != 0))
  6582. {
  6583. //subtract size for terminating NULL which we wrote out
  6584. //since SysAllocStringByteLen overallocates for the NULL
  6585. m_str = SysAllocStringByteLen(NULL, cbStrLen-sizeof(OLECHAR));
  6586. if (m_str == NULL)
  6587. hr = E_OUTOFMEMORY;
  6588. else
  6589. hr = pStream->Read((void*) m_str, cbStrLen, NULL);
  6590. // If SysAllocStringByteLen or IStream::Read failed, reset seek
  6591. // pointer to start of BSTR size.
  6592. if (hr != S_OK)
  6593. {
  6594. LARGE_INTEGER nOffset;
  6595. nOffset.QuadPart = -(static_cast<LONGLONG>(sizeof(cbStrLen)));
  6596. pStream->Seek(nOffset, STREAM_SEEK_CUR, NULL);
  6597. }
  6598. }
  6599. if (hr == S_FALSE)
  6600. hr = E_FAIL;
  6601. return hr;
  6602. }
  6603. static bool LoadStringResource(HINSTANCE hInstance, UINT uID, BSTR& bstrText) throw()
  6604. {
  6605. const ATLSTRINGRESOURCEIMAGE* pImage;
  6606. ATLASSERT(bstrText == NULL);
  6607. pImage = AtlGetStringResourceImage(hInstance, uID);
  6608. if (pImage != NULL)
  6609. {
  6610. bstrText = ::SysAllocStringLen(pImage->achString, pImage->nLength);
  6611. }
  6612. return (bstrText != NULL) ? true : false;
  6613. }
  6614. static bool LoadStringResource(UINT uID, BSTR& bstrText) throw()
  6615. {
  6616. const ATLSTRINGRESOURCEIMAGE* pImage;
  6617. ATLASSERT(bstrText == NULL);
  6618. pImage = AtlGetStringResourceImage(uID);
  6619. if (pImage != NULL)
  6620. {
  6621. bstrText = ::SysAllocStringLen(pImage->achString, pImage->nLength);
  6622. }
  6623. return (bstrText != NULL) ? true : false;
  6624. }
  6625. // each character in BSTR is copied to each element in SAFEARRAY
  6626. HRESULT BSTRToArray(LPSAFEARRAY *ppArray) throw()
  6627. {
  6628. return VectorFromBstr(m_str, ppArray);
  6629. }
  6630. // first character of each element in SAFEARRAY is copied to BSTR
  6631. HRESULT ArrayToBSTR(const SAFEARRAY *pSrc) throw()
  6632. {
  6633. ::SysFreeString(m_str);
  6634. return BstrFromVector((LPSAFEARRAY)pSrc, &m_str);
  6635. }
  6636. };
  6637. /////////////////////////////////////////////////////////////////////////////
  6638. // CComTypeAttr
  6639. class CComTypeAttr
  6640. {
  6641. // Construction
  6642. public:
  6643. CComTypeAttr( ITypeInfo* pTypeInfo ) throw() :
  6644. m_pTypeAttr( NULL ),
  6645. m_pTypeInfo( pTypeInfo )
  6646. {
  6647. }
  6648. ~CComTypeAttr() throw()
  6649. {
  6650. Release();
  6651. }
  6652. // Operators
  6653. public:
  6654. TYPEATTR* operator->() throw()
  6655. {
  6656. ATLASSERT( m_pTypeAttr != NULL );
  6657. return m_pTypeAttr;
  6658. }
  6659. TYPEATTR** operator&() throw()
  6660. {
  6661. ATLASSERT( m_pTypeAttr == NULL );
  6662. return &m_pTypeAttr;
  6663. }
  6664. operator const TYPEATTR*() const throw()
  6665. {
  6666. return m_pTypeAttr;
  6667. }
  6668. // Operations
  6669. public:
  6670. void Release() throw()
  6671. {
  6672. if( m_pTypeAttr != NULL )
  6673. {
  6674. ATLASSERT( m_pTypeInfo != NULL );
  6675. m_pTypeInfo->ReleaseTypeAttr( m_pTypeAttr );
  6676. m_pTypeAttr = NULL;
  6677. }
  6678. }
  6679. public:
  6680. TYPEATTR* m_pTypeAttr;
  6681. CComPtr< ITypeInfo > m_pTypeInfo;
  6682. };
  6683. /////////////////////////////////////////////////////////////////////////////
  6684. // CComVarDesc
  6685. class CComVarDesc
  6686. {
  6687. // Construction
  6688. public:
  6689. CComVarDesc( ITypeInfo* pTypeInfo ) throw() :
  6690. m_pVarDesc( NULL ),
  6691. m_pTypeInfo( pTypeInfo )
  6692. {
  6693. }
  6694. ~CComVarDesc() throw()
  6695. {
  6696. Release();
  6697. }
  6698. // Operators
  6699. public:
  6700. VARDESC* operator->() throw()
  6701. {
  6702. ATLASSERT( m_pVarDesc != NULL );
  6703. return m_pVarDesc;
  6704. }
  6705. VARDESC** operator&() throw()
  6706. {
  6707. ATLASSERT( m_pVarDesc == NULL );
  6708. return &m_pVarDesc;
  6709. }
  6710. operator const VARDESC*() const throw()
  6711. {
  6712. return m_pVarDesc;
  6713. }
  6714. // Operations
  6715. public:
  6716. void Release() throw()
  6717. {
  6718. if( m_pVarDesc != NULL )
  6719. {
  6720. ATLASSERT( m_pTypeInfo != NULL );
  6721. m_pTypeInfo->ReleaseVarDesc( m_pVarDesc );
  6722. m_pVarDesc = NULL;
  6723. }
  6724. }
  6725. public:
  6726. VARDESC* m_pVarDesc;
  6727. CComPtr< ITypeInfo > m_pTypeInfo;
  6728. };
  6729. /////////////////////////////////////////////////////////////////////////////
  6730. // CComFuncDesc
  6731. class CComFuncDesc
  6732. {
  6733. // Construction
  6734. public:
  6735. CComFuncDesc( ITypeInfo* pTypeInfo ) throw() :
  6736. m_pFuncDesc( NULL ),
  6737. m_pTypeInfo( pTypeInfo )
  6738. {
  6739. }
  6740. ~CComFuncDesc() throw()
  6741. {
  6742. Release();
  6743. }
  6744. // Operators
  6745. public:
  6746. FUNCDESC* operator->() throw()
  6747. {
  6748. ATLASSERT( m_pFuncDesc != NULL );
  6749. return m_pFuncDesc;
  6750. }
  6751. FUNCDESC** operator&() throw()
  6752. {
  6753. ATLASSERT( m_pFuncDesc == NULL );
  6754. return &m_pFuncDesc;
  6755. }
  6756. operator const FUNCDESC*() const throw()
  6757. {
  6758. return m_pFuncDesc;
  6759. }
  6760. // Operations
  6761. public:
  6762. void Release() throw()
  6763. {
  6764. if( m_pFuncDesc != NULL )
  6765. {
  6766. ATLASSERT( m_pTypeInfo != NULL );
  6767. m_pTypeInfo->ReleaseFuncDesc( m_pFuncDesc );
  6768. m_pFuncDesc = NULL;
  6769. }
  6770. }
  6771. public:
  6772. FUNCDESC* m_pFuncDesc;
  6773. CComPtr< ITypeInfo > m_pTypeInfo;
  6774. };
  6775. /////////////////////////////////////////////////////////////////////////////
  6776. // CComExcepInfo
  6777. class CComExcepInfo :
  6778. public EXCEPINFO
  6779. {
  6780. // Construction
  6781. public:
  6782. CComExcepInfo()
  6783. {
  6784. memset( this, 0, sizeof( *this ) );
  6785. }
  6786. ~CComExcepInfo()
  6787. {
  6788. Clear();
  6789. }
  6790. // Operations
  6791. public:
  6792. void Clear()
  6793. {
  6794. if (bstrSource != NULL)
  6795. ::SysFreeString(bstrSource);
  6796. if (bstrDescription != NULL)
  6797. ::SysFreeString(bstrDescription);
  6798. if (bstrHelpFile != NULL)
  6799. ::SysFreeString(bstrHelpFile);
  6800. memset(this, 0, sizeof(*this));
  6801. }
  6802. };
  6803. /////////////////////////////////////////////////////////////////////////////
  6804. // CComVariant
  6805. template< typename T >
  6806. class CVarTypeInfo
  6807. {
  6808. // static const VARTYPE VT; // VARTYPE corresponding to type T
  6809. // static T VARIANT::* const pmField; // Pointer-to-member of corresponding field in VARIANT struct
  6810. };
  6811. template<>
  6812. class CVarTypeInfo< char >
  6813. {
  6814. public:
  6815. static const VARTYPE VT = VT_I1;
  6816. static char VARIANT::* const pmField;
  6817. };
  6818. __declspec( selectany ) char VARIANT::* const CVarTypeInfo< char >::pmField = &VARIANT::cVal;
  6819. template<>
  6820. class CVarTypeInfo< unsigned char >
  6821. {
  6822. public:
  6823. static const VARTYPE VT = VT_UI1;
  6824. static unsigned char VARIANT::* const pmField;
  6825. };
  6826. __declspec( selectany ) unsigned char VARIANT::* const CVarTypeInfo< unsigned char >::pmField = &VARIANT::bVal;
  6827. template<>
  6828. class CVarTypeInfo< char* >
  6829. {
  6830. public:
  6831. static const VARTYPE VT = VT_I1|VT_BYREF;
  6832. static char* VARIANT::* const pmField;
  6833. };
  6834. __declspec( selectany ) char* VARIANT::* const CVarTypeInfo< char* >::pmField = &VARIANT::pcVal;
  6835. template<>
  6836. class CVarTypeInfo< unsigned char* >
  6837. {
  6838. public:
  6839. static const VARTYPE VT = VT_UI1|VT_BYREF;
  6840. static unsigned char* VARIANT::* const pmField;
  6841. };
  6842. __declspec( selectany ) unsigned char* VARIANT::* const CVarTypeInfo< unsigned char* >::pmField = &VARIANT::pbVal;
  6843. template<>
  6844. class CVarTypeInfo< short >
  6845. {
  6846. public:
  6847. static const VARTYPE VT = VT_I2;
  6848. static short VARIANT::* const pmField;
  6849. };
  6850. __declspec( selectany ) short VARIANT::* const CVarTypeInfo< short >::pmField = &VARIANT::iVal;
  6851. template<>
  6852. class CVarTypeInfo< short* >
  6853. {
  6854. public:
  6855. static const VARTYPE VT = VT_I2|VT_BYREF;
  6856. static short* VARIANT::* const pmField;
  6857. };
  6858. __declspec( selectany ) short* VARIANT::* const CVarTypeInfo< short* >::pmField = &VARIANT::piVal;
  6859. template<>
  6860. class CVarTypeInfo< unsigned short >
  6861. {
  6862. public:
  6863. static const VARTYPE VT = VT_UI2;
  6864. static unsigned short VARIANT::* const pmField;
  6865. };
  6866. __declspec( selectany ) unsigned short VARIANT::* const CVarTypeInfo< unsigned short >::pmField = &VARIANT::uiVal;
  6867. #ifdef _NATIVE_WCHAR_T_DEFINED // Only treat unsigned short* as VT_UI2|VT_BYREF if BSTR isn't the same as unsigned short*
  6868. template<>
  6869. class CVarTypeInfo< unsigned short* >
  6870. {
  6871. public:
  6872. static const VARTYPE VT = VT_UI2|VT_BYREF;
  6873. static unsigned short* VARIANT::* const pmField;
  6874. };
  6875. __declspec( selectany ) unsigned short* VARIANT::* const CVarTypeInfo< unsigned short* >::pmField = &VARIANT::puiVal;
  6876. #endif // _NATIVE_WCHAR_T_DEFINED
  6877. template<>
  6878. class CVarTypeInfo< int >
  6879. {
  6880. public:
  6881. static const VARTYPE VT = VT_I4;
  6882. static int VARIANT::* const pmField;
  6883. };
  6884. __declspec( selectany ) int VARIANT::* const CVarTypeInfo< int >::pmField = &VARIANT::intVal;
  6885. template<>
  6886. class CVarTypeInfo< int* >
  6887. {
  6888. public:
  6889. static const VARTYPE VT = VT_I4|VT_BYREF;
  6890. static int* VARIANT::* const pmField;
  6891. };
  6892. __declspec( selectany ) int* VARIANT::* const CVarTypeInfo< int* >::pmField = &VARIANT::pintVal;
  6893. template<>
  6894. class CVarTypeInfo< unsigned int >
  6895. {
  6896. public:
  6897. static const VARTYPE VT = VT_UI4;
  6898. static unsigned int VARIANT::* const pmField;
  6899. };
  6900. __declspec( selectany ) unsigned int VARIANT::* const CVarTypeInfo< unsigned int >::pmField = &VARIANT::uintVal;
  6901. template<>
  6902. class CVarTypeInfo< unsigned int* >
  6903. {
  6904. public:
  6905. static const VARTYPE VT = VT_UI4|VT_BYREF;
  6906. static unsigned int* VARIANT::* const pmField;
  6907. };
  6908. __declspec( selectany ) unsigned int* VARIANT::* const CVarTypeInfo< unsigned int* >::pmField = &VARIANT::puintVal;
  6909. template<>
  6910. class CVarTypeInfo< long >
  6911. {
  6912. public:
  6913. static const VARTYPE VT = VT_I4;
  6914. static long VARIANT::* const pmField;
  6915. };
  6916. __declspec( selectany ) long VARIANT::* const CVarTypeInfo< long >::pmField = &VARIANT::lVal;
  6917. template<>
  6918. class CVarTypeInfo< long* >
  6919. {
  6920. public:
  6921. static const VARTYPE VT = VT_I4|VT_BYREF;
  6922. static long* VARIANT::* const pmField;
  6923. };
  6924. __declspec( selectany ) long* VARIANT::* const CVarTypeInfo< long* >::pmField = &VARIANT::plVal;
  6925. template<>
  6926. class CVarTypeInfo< unsigned long >
  6927. {
  6928. public:
  6929. static const VARTYPE VT = VT_UI4;
  6930. static unsigned long VARIANT::* const pmField;
  6931. };
  6932. __declspec( selectany ) unsigned long VARIANT::* const CVarTypeInfo< unsigned long >::pmField = &VARIANT::ulVal;
  6933. template<>
  6934. class CVarTypeInfo< unsigned long* >
  6935. {
  6936. public:
  6937. static const VARTYPE VT = VT_UI4|VT_BYREF;
  6938. static unsigned long* VARIANT::* const pmField;
  6939. };
  6940. __declspec( selectany ) unsigned long* VARIANT::* const CVarTypeInfo< unsigned long* >::pmField = &VARIANT::pulVal;
  6941. template<>
  6942. class CVarTypeInfo< __int64 >
  6943. {
  6944. public:
  6945. static const VARTYPE VT = VT_I8;
  6946. static __int64 VARIANT::* const pmField;
  6947. };
  6948. __declspec( selectany ) __int64 VARIANT::* const CVarTypeInfo< __int64 >::pmField = &VARIANT::llVal;
  6949. template<>
  6950. class CVarTypeInfo< __int64* >
  6951. {
  6952. public:
  6953. static const VARTYPE VT = VT_I8|VT_BYREF;
  6954. static __int64* VARIANT::* const pmField;
  6955. };
  6956. __declspec( selectany ) __int64* VARIANT::* const CVarTypeInfo< __int64* >::pmField = &VARIANT::pllVal;
  6957. template<>
  6958. class CVarTypeInfo< unsigned __int64 >
  6959. {
  6960. public:
  6961. static const VARTYPE VT = VT_UI8;
  6962. static unsigned __int64 VARIANT::* const pmField;
  6963. };
  6964. __declspec( selectany ) unsigned __int64 VARIANT::* const CVarTypeInfo< unsigned __int64 >::pmField = &VARIANT::ullVal;
  6965. template<>
  6966. class CVarTypeInfo< unsigned __int64* >
  6967. {
  6968. public:
  6969. static const VARTYPE VT = VT_UI8|VT_BYREF;
  6970. static unsigned __int64* VARIANT::* const pmField;
  6971. };
  6972. __declspec( selectany ) unsigned __int64* VARIANT::* const CVarTypeInfo< unsigned __int64* >::pmField = &VARIANT::pullVal;
  6973. template<>
  6974. class CVarTypeInfo< float >
  6975. {
  6976. public:
  6977. static const VARTYPE VT = VT_R4;
  6978. static float VARIANT::* const pmField;
  6979. };
  6980. __declspec( selectany ) float VARIANT::* const CVarTypeInfo< float >::pmField = &VARIANT::fltVal;
  6981. template<>
  6982. class CVarTypeInfo< float* >
  6983. {
  6984. public:
  6985. static const VARTYPE VT = VT_R4|VT_BYREF;
  6986. static float* VARIANT::* const pmField;
  6987. };
  6988. __declspec( selectany ) float* VARIANT::* const CVarTypeInfo< float* >::pmField = &VARIANT::pfltVal;
  6989. template<>
  6990. class CVarTypeInfo< double >
  6991. {
  6992. public:
  6993. static const VARTYPE VT = VT_R8;
  6994. static double VARIANT::* const pmField;
  6995. };
  6996. __declspec( selectany ) double VARIANT::* const CVarTypeInfo< double >::pmField = &VARIANT::dblVal;
  6997. template<>
  6998. class CVarTypeInfo< double* >
  6999. {
  7000. public:
  7001. static const VARTYPE VT = VT_R8|VT_BYREF;
  7002. static double* VARIANT::* const pmField;
  7003. };
  7004. __declspec( selectany ) double* VARIANT::* const CVarTypeInfo< double* >::pmField = &VARIANT::pdblVal;
  7005. template<>
  7006. class CVarTypeInfo< VARIANT >
  7007. {
  7008. public:
  7009. static const VARTYPE VT = VT_VARIANT;
  7010. };
  7011. template<>
  7012. class CVarTypeInfo< BSTR >
  7013. {
  7014. public:
  7015. static const VARTYPE VT = VT_BSTR;
  7016. static BSTR VARIANT::* const pmField;
  7017. };
  7018. __declspec( selectany ) BSTR VARIANT::* const CVarTypeInfo< BSTR >::pmField = &VARIANT::bstrVal;
  7019. template<>
  7020. class CVarTypeInfo< BSTR* >
  7021. {
  7022. public:
  7023. static const VARTYPE VT = VT_BSTR|VT_BYREF;
  7024. static BSTR* VARIANT::* const pmField;
  7025. };
  7026. __declspec( selectany ) BSTR* VARIANT::* const CVarTypeInfo< BSTR* >::pmField = &VARIANT::pbstrVal;
  7027. template<>
  7028. class CVarTypeInfo< IUnknown* >
  7029. {
  7030. public:
  7031. static const VARTYPE VT = VT_UNKNOWN;
  7032. static IUnknown* VARIANT::* const pmField;
  7033. };
  7034. __declspec( selectany ) IUnknown* VARIANT::* const CVarTypeInfo< IUnknown* >::pmField = &VARIANT::punkVal;
  7035. template<>
  7036. class CVarTypeInfo< IUnknown** >
  7037. {
  7038. public:
  7039. static const VARTYPE VT = VT_UNKNOWN|VT_BYREF;
  7040. static IUnknown** VARIANT::* const pmField;
  7041. };
  7042. __declspec( selectany ) IUnknown** VARIANT::* const CVarTypeInfo< IUnknown** >::pmField = &VARIANT::ppunkVal;
  7043. template<>
  7044. class CVarTypeInfo< IDispatch* >
  7045. {
  7046. public:
  7047. static const VARTYPE VT = VT_DISPATCH;
  7048. static IDispatch* VARIANT::* const pmField;
  7049. };
  7050. __declspec( selectany ) IDispatch* VARIANT::* const CVarTypeInfo< IDispatch* >::pmField = &VARIANT::pdispVal;
  7051. template<>
  7052. class CVarTypeInfo< IDispatch** >
  7053. {
  7054. public:
  7055. static const VARTYPE VT = VT_DISPATCH|VT_BYREF;
  7056. static IDispatch** VARIANT::* const pmField;
  7057. };
  7058. __declspec( selectany ) IDispatch** VARIANT::* const CVarTypeInfo< IDispatch** >::pmField = &VARIANT::ppdispVal;
  7059. template<>
  7060. class CVarTypeInfo< CY >
  7061. {
  7062. public:
  7063. static const VARTYPE VT = VT_CY;
  7064. static CY VARIANT::* const pmField;
  7065. };
  7066. __declspec( selectany ) CY VARIANT::* const CVarTypeInfo< CY >::pmField = &VARIANT::cyVal;
  7067. template<>
  7068. class CVarTypeInfo< CY* >
  7069. {
  7070. public:
  7071. static const VARTYPE VT = VT_CY|VT_BYREF;
  7072. static CY* VARIANT::* const pmField;
  7073. };
  7074. __declspec( selectany ) CY* VARIANT::* const CVarTypeInfo< CY* >::pmField = &VARIANT::pcyVal;
  7075. class CComVariant : public tagVARIANT
  7076. {
  7077. // Constructors
  7078. public:
  7079. CComVariant() throw()
  7080. {
  7081. ::VariantInit(this);
  7082. }
  7083. ~CComVariant() throw()
  7084. {
  7085. Clear();
  7086. }
  7087. CComVariant(const VARIANT& varSrc)
  7088. {
  7089. vt = VT_EMPTY;
  7090. InternalCopy(&varSrc);
  7091. }
  7092. CComVariant(const CComVariant& varSrc)
  7093. {
  7094. vt = VT_EMPTY;
  7095. InternalCopy(&varSrc);
  7096. }
  7097. CComVariant(LPCOLESTR lpszSrc)
  7098. {
  7099. vt = VT_EMPTY;
  7100. *this = lpszSrc;
  7101. }
  7102. CComVariant(LPCSTR lpszSrc)
  7103. {
  7104. vt = VT_EMPTY;
  7105. *this = lpszSrc;
  7106. }
  7107. CComVariant(bool bSrc)
  7108. {
  7109. vt = VT_BOOL;
  7110. boolVal = bSrc ? ATL_VARIANT_TRUE : ATL_VARIANT_FALSE;
  7111. }
  7112. CComVariant(int nSrc, VARTYPE vtSrc = VT_I4) throw()
  7113. {
  7114. ATLASSERT(vtSrc == VT_I4 || vtSrc == VT_INT);
  7115. vt = vtSrc;
  7116. intVal = nSrc;
  7117. }
  7118. CComVariant(BYTE nSrc) throw()
  7119. {
  7120. vt = VT_UI1;
  7121. bVal = nSrc;
  7122. }
  7123. CComVariant(short nSrc) throw()
  7124. {
  7125. vt = VT_I2;
  7126. iVal = nSrc;
  7127. }
  7128. CComVariant(long nSrc, VARTYPE vtSrc = VT_I4) throw()
  7129. {
  7130. ATLASSERT(vtSrc == VT_I4 || vtSrc == VT_ERROR);
  7131. vt = vtSrc;
  7132. lVal = nSrc;
  7133. }
  7134. CComVariant(float fltSrc) throw()
  7135. {
  7136. vt = VT_R4;
  7137. fltVal = fltSrc;
  7138. }
  7139. CComVariant(double dblSrc, VARTYPE vtSrc = VT_R8) throw()
  7140. {
  7141. ATLASSERT(vtSrc == VT_R8 || vtSrc == VT_DATE);
  7142. vt = vtSrc;
  7143. dblVal = dblSrc;
  7144. }
  7145. #if (_WIN32_WINNT >= 0x0510) || defined(_ATL_SUPPORT_VT_I8)
  7146. CComVariant(LONGLONG nSrc) throw()
  7147. {
  7148. vt = VT_I8;
  7149. llVal = nSrc;
  7150. }
  7151. CComVariant(ULONGLONG nSrc) throw()
  7152. {
  7153. vt = VT_UI8;
  7154. ullVal = nSrc;
  7155. }
  7156. #endif
  7157. CComVariant(CY cySrc) throw()
  7158. {
  7159. vt = VT_CY;
  7160. cyVal.Hi = cySrc.Hi;
  7161. cyVal.Lo = cySrc.Lo;
  7162. }
  7163. CComVariant(IDispatch* pSrc) throw()
  7164. {
  7165. vt = VT_DISPATCH;
  7166. pdispVal = pSrc;
  7167. // Need to AddRef as VariantClear will Release
  7168. if (pdispVal != NULL)
  7169. pdispVal->AddRef();
  7170. }
  7171. CComVariant(IUnknown* pSrc) throw()
  7172. {
  7173. vt = VT_UNKNOWN;
  7174. punkVal = pSrc;
  7175. // Need to AddRef as VariantClear will Release
  7176. if (punkVal != NULL)
  7177. punkVal->AddRef();
  7178. }
  7179. CComVariant(char cSrc) throw()
  7180. {
  7181. vt = VT_I1;
  7182. cVal = cSrc;
  7183. }
  7184. CComVariant(unsigned short nSrc) throw()
  7185. {
  7186. vt = VT_UI2;
  7187. uiVal = nSrc;
  7188. }
  7189. CComVariant(unsigned long nSrc) throw()
  7190. {
  7191. vt = VT_UI4;
  7192. ulVal = nSrc;
  7193. }
  7194. CComVariant(unsigned int nSrc, VARTYPE vtSrc = VT_UI4) throw()
  7195. {
  7196. ATLASSERT(vtSrc == VT_UI4 || vtSrc == VT_UINT);
  7197. vt = vtSrc;
  7198. uintVal= nSrc;
  7199. }
  7200. CComVariant(const CComBSTR& bstrSrc)
  7201. {
  7202. vt = VT_EMPTY;
  7203. *this = bstrSrc;
  7204. }
  7205. CComVariant(const SAFEARRAY *pSrc)
  7206. {
  7207. LPSAFEARRAY pCopy;
  7208. if (pSrc != NULL)
  7209. {
  7210. HRESULT hRes = ::SafeArrayCopy((LPSAFEARRAY)pSrc, &pCopy);
  7211. if (SUCCEEDED(hRes) && pCopy != NULL)
  7212. {
  7213. ::SafeArrayGetVartype((LPSAFEARRAY)pSrc, &vt);
  7214. vt |= VT_ARRAY;
  7215. parray = pCopy;
  7216. }
  7217. else
  7218. {
  7219. vt = VT_ERROR;
  7220. scode = hRes;
  7221. }
  7222. }
  7223. }
  7224. // Assignment Operators
  7225. public:
  7226. CComVariant& operator=(const CComVariant& varSrc)
  7227. {
  7228. InternalCopy(&varSrc);
  7229. return *this;
  7230. }
  7231. CComVariant& operator=(const VARIANT& varSrc)
  7232. {
  7233. InternalCopy(&varSrc);
  7234. return *this;
  7235. }
  7236. CComVariant& operator=(const CComBSTR& bstrSrc)
  7237. {
  7238. Clear();
  7239. vt = VT_BSTR;
  7240. bstrVal = bstrSrc.Copy();
  7241. if (bstrVal == NULL && bstrSrc.m_str != NULL)
  7242. {
  7243. vt = VT_ERROR;
  7244. scode = E_OUTOFMEMORY;
  7245. }
  7246. return *this;
  7247. }
  7248. CComVariant& operator=(LPCOLESTR lpszSrc)
  7249. {
  7250. Clear();
  7251. vt = VT_BSTR;
  7252. bstrVal = ::SysAllocString(lpszSrc);
  7253. if (bstrVal == NULL && lpszSrc != NULL)
  7254. {
  7255. vt = VT_ERROR;
  7256. scode = E_OUTOFMEMORY;
  7257. }
  7258. return *this;
  7259. }
  7260. CComVariant& operator=(LPCSTR lpszSrc)
  7261. {
  7262. USES_CONVERSION;
  7263. Clear();
  7264. vt = VT_BSTR;
  7265. bstrVal = ::SysAllocString(A2COLE(lpszSrc));
  7266. if (bstrVal == NULL && lpszSrc != NULL)
  7267. {
  7268. vt = VT_ERROR;
  7269. scode = E_OUTOFMEMORY;
  7270. }
  7271. return *this;
  7272. }
  7273. CComVariant& operator=(bool bSrc)
  7274. {
  7275. if (vt != VT_BOOL)
  7276. {
  7277. Clear();
  7278. vt = VT_BOOL;
  7279. }
  7280. boolVal = bSrc ? ATL_VARIANT_TRUE : ATL_VARIANT_FALSE;
  7281. return *this;
  7282. }
  7283. CComVariant& operator=(int nSrc) throw()
  7284. {
  7285. if (vt != VT_I4)
  7286. {
  7287. Clear();
  7288. vt = VT_I4;
  7289. }
  7290. intVal = nSrc;
  7291. return *this;
  7292. }
  7293. CComVariant& operator=(BYTE nSrc) throw()
  7294. {
  7295. if (vt != VT_UI1)
  7296. {
  7297. Clear();
  7298. vt = VT_UI1;
  7299. }
  7300. bVal = nSrc;
  7301. return *this;
  7302. }
  7303. CComVariant& operator=(short nSrc) throw()
  7304. {
  7305. if (vt != VT_I2)
  7306. {
  7307. Clear();
  7308. vt = VT_I2;
  7309. }
  7310. iVal = nSrc;
  7311. return *this;
  7312. }
  7313. CComVariant& operator=(long nSrc) throw()
  7314. {
  7315. if (vt != VT_I4)
  7316. {
  7317. Clear();
  7318. vt = VT_I4;
  7319. }
  7320. lVal = nSrc;
  7321. return *this;
  7322. }
  7323. CComVariant& operator=(float fltSrc) throw()
  7324. {
  7325. if (vt != VT_R4)
  7326. {
  7327. Clear();
  7328. vt = VT_R4;
  7329. }
  7330. fltVal = fltSrc;
  7331. return *this;
  7332. }
  7333. CComVariant& operator=(double dblSrc) throw()
  7334. {
  7335. if (vt != VT_R8)
  7336. {
  7337. Clear();
  7338. vt = VT_R8;
  7339. }
  7340. dblVal = dblSrc;
  7341. return *this;
  7342. }
  7343. CComVariant& operator=(CY cySrc) throw()
  7344. {
  7345. if (vt != VT_CY)
  7346. {
  7347. Clear();
  7348. vt = VT_CY;
  7349. }
  7350. cyVal.Hi = cySrc.Hi;
  7351. cyVal.Lo = cySrc.Lo;
  7352. return *this;
  7353. }
  7354. CComVariant& operator=(IDispatch* pSrc) throw()
  7355. {
  7356. Clear();
  7357. vt = VT_DISPATCH;
  7358. pdispVal = pSrc;
  7359. // Need to AddRef as VariantClear will Release
  7360. if (pdispVal != NULL)
  7361. pdispVal->AddRef();
  7362. return *this;
  7363. }
  7364. CComVariant& operator=(IUnknown* pSrc) throw()
  7365. {
  7366. Clear();
  7367. vt = VT_UNKNOWN;
  7368. punkVal = pSrc;
  7369. // Need to AddRef as VariantClear will Release
  7370. if (punkVal != NULL)
  7371. punkVal->AddRef();
  7372. return *this;
  7373. }
  7374. CComVariant& operator=(char cSrc) throw()
  7375. {
  7376. if (vt != VT_I1)
  7377. {
  7378. Clear();
  7379. vt = VT_I1;
  7380. }
  7381. cVal = cSrc;
  7382. return *this;
  7383. }
  7384. CComVariant& operator=(unsigned short nSrc) throw()
  7385. {
  7386. if (vt != VT_UI2)
  7387. {
  7388. Clear();
  7389. vt = VT_UI2;
  7390. }
  7391. uiVal = nSrc;
  7392. return *this;
  7393. }
  7394. CComVariant& operator=(unsigned long nSrc) throw()
  7395. {
  7396. if (vt != VT_UI4)
  7397. {
  7398. Clear();
  7399. vt = VT_UI4;
  7400. }
  7401. ulVal = nSrc;
  7402. return *this;
  7403. }
  7404. CComVariant& operator=(unsigned int nSrc) throw()
  7405. {
  7406. if (vt != VT_UI4)
  7407. {
  7408. Clear();
  7409. vt = VT_UI4;
  7410. }
  7411. uintVal= nSrc;
  7412. return *this;
  7413. }
  7414. #if (_WIN32_WINNT >= 0x0510) || defined(_ATL_SUPPORT_VT_I8)
  7415. CComVariant& operator=(LONGLONG nSrc) throw()
  7416. {
  7417. if (vt != VT_I8)
  7418. {
  7419. Clear();
  7420. vt = VT_I8;
  7421. }
  7422. llVal = nSrc;
  7423. return *this;
  7424. }
  7425. CComVariant& operator=(ULONGLONG nSrc) throw()
  7426. {
  7427. if (vt != VT_UI8)
  7428. {
  7429. Clear();
  7430. vt = VT_UI8;
  7431. }
  7432. ullVal = nSrc;
  7433. return *this;
  7434. }
  7435. #endif
  7436. CComVariant& operator=(const SAFEARRAY *pSrc)
  7437. {
  7438. Clear();
  7439. LPSAFEARRAY pCopy;
  7440. if (pSrc != NULL)
  7441. {
  7442. HRESULT hRes = ::SafeArrayCopy((LPSAFEARRAY)pSrc, &pCopy);
  7443. if (SUCCEEDED(hRes) && pCopy != NULL)
  7444. {
  7445. ::SafeArrayGetVartype((LPSAFEARRAY)pSrc, &vt);
  7446. vt |= VT_ARRAY;
  7447. parray = pCopy;
  7448. }
  7449. else
  7450. {
  7451. vt = VT_ERROR;
  7452. scode = hRes;
  7453. }
  7454. }
  7455. return *this;
  7456. }
  7457. // Comparison Operators
  7458. public:
  7459. bool operator==(const VARIANT& varSrc) const throw()
  7460. {
  7461. // For backwards compatibility
  7462. if (vt == VT_NULL && varSrc.vt == VT_NULL)
  7463. return true;
  7464. return VarCmp((VARIANT*)this, (VARIANT*)&varSrc, LOCALE_USER_DEFAULT, 0) == VARCMP_EQ;
  7465. }
  7466. bool operator!=(const VARIANT& varSrc) const throw()
  7467. {
  7468. return !operator==(varSrc);
  7469. }
  7470. bool operator<(const VARIANT& varSrc) const throw()
  7471. {
  7472. if (vt == VT_NULL && varSrc.vt == VT_NULL)
  7473. return false;
  7474. return VarCmp((VARIANT*)this, (VARIANT*)&varSrc, LOCALE_USER_DEFAULT, 0)==VARCMP_LT;
  7475. }
  7476. bool operator>(const VARIANT& varSrc) const throw()
  7477. {
  7478. if (vt == VT_NULL && varSrc.vt == VT_NULL)
  7479. return false;
  7480. return VarCmp((VARIANT*)this, (VARIANT*)&varSrc, LOCALE_USER_DEFAULT, 0)==VARCMP_GT;
  7481. }
  7482. // Operations
  7483. public:
  7484. HRESULT Clear() { return ::VariantClear(this); }
  7485. HRESULT Copy(const VARIANT* pSrc) { return ::VariantCopy(this, const_cast<VARIANT*>(pSrc)); }
  7486. // copy VARIANT to BSTR
  7487. HRESULT CopyTo(BSTR *pstrDest)
  7488. {
  7489. ATLASSERT(pstrDest != NULL && vt == VT_BSTR);
  7490. HRESULT hRes = E_POINTER;
  7491. if (pstrDest != NULL && vt == VT_BSTR)
  7492. {
  7493. *pstrDest = ::SysAllocStringByteLen((char*)bstrVal, ::SysStringByteLen(bstrVal));
  7494. if (*pstrDest == NULL)
  7495. hRes = E_OUTOFMEMORY;
  7496. else
  7497. hRes = S_OK;
  7498. }
  7499. else if (vt != VT_BSTR)
  7500. hRes = DISP_E_TYPEMISMATCH;
  7501. return hRes;
  7502. }
  7503. HRESULT Attach(VARIANT* pSrc)
  7504. {
  7505. // Clear out the variant
  7506. HRESULT hr = Clear();
  7507. if (!FAILED(hr))
  7508. {
  7509. // Copy the contents and give control to CComVariant
  7510. memcpy(this, pSrc, sizeof(VARIANT));
  7511. pSrc->vt = VT_EMPTY;
  7512. hr = S_OK;
  7513. }
  7514. return hr;
  7515. }
  7516. HRESULT Detach(VARIANT* pDest)
  7517. {
  7518. ATLASSERT(pDest != NULL);
  7519. // Clear out the variant
  7520. HRESULT hr = ::VariantClear(pDest);
  7521. if (!FAILED(hr))
  7522. {
  7523. // Copy the contents and remove control from CComVariant
  7524. memcpy(pDest, this, sizeof(VARIANT));
  7525. vt = VT_EMPTY;
  7526. hr = S_OK;
  7527. }
  7528. return hr;
  7529. }
  7530. HRESULT ChangeType(VARTYPE vtNew, const VARIANT* pSrc = NULL)
  7531. {
  7532. VARIANT* pVar = const_cast<VARIANT*>(pSrc);
  7533. // Convert in place if pSrc is NULL
  7534. if (pVar == NULL)
  7535. pVar = this;
  7536. // Do nothing if doing in place convert and vts not different
  7537. return ::VariantChangeType(this, pVar, 0, vtNew);
  7538. }
  7539. template< typename T >
  7540. void SetByRef( T* pT ) throw()
  7541. {
  7542. Clear();
  7543. vt = CVarTypeInfo< T >::VT|VT_BYREF;
  7544. byref = pT;
  7545. }
  7546. HRESULT WriteToStream(IStream* pStream);
  7547. HRESULT ReadFromStream(IStream* pStream);
  7548. // Return the size in bytes of the current contents
  7549. ULONG GetSize() const;
  7550. // Implementation
  7551. public:
  7552. HRESULT InternalClear()
  7553. {
  7554. HRESULT hr = Clear();
  7555. ATLASSERT(SUCCEEDED(hr));
  7556. if (FAILED(hr))
  7557. {
  7558. vt = VT_ERROR;
  7559. scode = hr;
  7560. }
  7561. return hr;
  7562. }
  7563. void InternalCopy(const VARIANT* pSrc)
  7564. {
  7565. HRESULT hr = Copy(pSrc);
  7566. if (FAILED(hr))
  7567. {
  7568. vt = VT_ERROR;
  7569. scode = hr;
  7570. }
  7571. }
  7572. };
  7573. #pragma warning(push)
  7574. #pragma warning(disable: 4702)
  7575. inline HRESULT CComVariant::WriteToStream(IStream* pStream)
  7576. {
  7577. HRESULT hr = pStream->Write(&vt, sizeof(VARTYPE), NULL);
  7578. if (FAILED(hr))
  7579. return hr;
  7580. int cbWrite = 0;
  7581. switch (vt)
  7582. {
  7583. case VT_UNKNOWN:
  7584. case VT_DISPATCH:
  7585. {
  7586. CComPtr<IPersistStream> spStream;
  7587. if (punkVal != NULL)
  7588. {
  7589. hr = punkVal->QueryInterface(__uuidof(IPersistStream), (void**)&spStream);
  7590. if (FAILED(hr))
  7591. {
  7592. hr = punkVal->QueryInterface(__uuidof(IPersistStreamInit), (void**)&spStream);
  7593. if (FAILED(hr))
  7594. return hr;
  7595. }
  7596. }
  7597. if (spStream != NULL)
  7598. return OleSaveToStream(spStream, pStream);
  7599. return WriteClassStm(pStream, CLSID_NULL);
  7600. }
  7601. case VT_UI1:
  7602. case VT_I1:
  7603. cbWrite = sizeof(BYTE);
  7604. break;
  7605. case VT_I2:
  7606. case VT_UI2:
  7607. case VT_BOOL:
  7608. cbWrite = sizeof(short);
  7609. break;
  7610. case VT_I4:
  7611. case VT_UI4:
  7612. case VT_R4:
  7613. case VT_INT:
  7614. case VT_UINT:
  7615. case VT_ERROR:
  7616. cbWrite = sizeof(long);
  7617. break;
  7618. case VT_I8:
  7619. case VT_UI8:
  7620. cbWrite = sizeof(LONGLONG);
  7621. break;
  7622. case VT_R8:
  7623. case VT_CY:
  7624. case VT_DATE:
  7625. cbWrite = sizeof(double);
  7626. break;
  7627. default:
  7628. break;
  7629. }
  7630. if (cbWrite != 0)
  7631. return pStream->Write((void*) &bVal, cbWrite, NULL);
  7632. CComBSTR bstrWrite;
  7633. CComVariant varBSTR;
  7634. if (vt != VT_BSTR)
  7635. {
  7636. hr = VariantChangeType(&varBSTR, this, VARIANT_NOVALUEPROP, VT_BSTR);
  7637. if (FAILED(hr))
  7638. return hr;
  7639. bstrWrite.Attach(varBSTR.bstrVal);
  7640. }
  7641. else
  7642. bstrWrite.Attach(bstrVal);
  7643. hr = bstrWrite.WriteToStream(pStream);
  7644. bstrWrite.Detach();
  7645. return hr;
  7646. }
  7647. #pragma warning(pop)
  7648. inline HRESULT CComVariant::ReadFromStream(IStream* pStream)
  7649. {
  7650. ATLASSERT(pStream != NULL);
  7651. HRESULT hr;
  7652. hr = VariantClear(this);
  7653. if (FAILED(hr))
  7654. return hr;
  7655. VARTYPE vtRead;
  7656. hr = pStream->Read(&vtRead, sizeof(VARTYPE), NULL);
  7657. if (hr == S_FALSE)
  7658. hr = E_FAIL;
  7659. if (FAILED(hr))
  7660. return hr;
  7661. vt = vtRead;
  7662. int cbRead = 0;
  7663. switch (vtRead)
  7664. {
  7665. case VT_UNKNOWN:
  7666. case VT_DISPATCH:
  7667. {
  7668. punkVal = NULL;
  7669. return OleLoadFromStream(pStream,
  7670. (vtRead == VT_UNKNOWN) ? __uuidof(IUnknown) : __uuidof(IDispatch),
  7671. (void**)&punkVal);
  7672. }
  7673. case VT_UI1:
  7674. case VT_I1:
  7675. cbRead = sizeof(BYTE);
  7676. break;
  7677. case VT_I2:
  7678. case VT_UI2:
  7679. case VT_BOOL:
  7680. cbRead = sizeof(short);
  7681. break;
  7682. case VT_I4:
  7683. case VT_UI4:
  7684. case VT_R4:
  7685. case VT_INT:
  7686. case VT_UINT:
  7687. case VT_ERROR:
  7688. cbRead = sizeof(long);
  7689. break;
  7690. case VT_I8:
  7691. case VT_UI8:
  7692. cbRead = sizeof(LONGLONG);
  7693. break;
  7694. case VT_R8:
  7695. case VT_CY:
  7696. case VT_DATE:
  7697. cbRead = sizeof(double);
  7698. break;
  7699. default:
  7700. break;
  7701. }
  7702. if (cbRead != 0)
  7703. {
  7704. hr = pStream->Read((void*) &bVal, cbRead, NULL);
  7705. if (hr == S_FALSE)
  7706. hr = E_FAIL;
  7707. return hr;
  7708. }
  7709. CComBSTR bstrRead;
  7710. hr = bstrRead.ReadFromStream(pStream);
  7711. if (FAILED(hr))
  7712. {
  7713. // If CComBSTR::ReadFromStream failed, reset seek pointer to start of
  7714. // variant type.
  7715. LARGE_INTEGER nOffset;
  7716. nOffset.QuadPart = -(static_cast<LONGLONG>(sizeof(VARTYPE)));
  7717. pStream->Seek(nOffset, STREAM_SEEK_CUR, NULL);
  7718. return hr;
  7719. }
  7720. vt = VT_BSTR;
  7721. bstrVal = bstrRead.Detach();
  7722. if (vtRead != VT_BSTR)
  7723. hr = ChangeType(vtRead);
  7724. return hr;
  7725. }
  7726. inline ULONG CComVariant::GetSize() const
  7727. {
  7728. ULONG nSize = sizeof(VARTYPE);
  7729. HRESULT hr;
  7730. switch (vt)
  7731. {
  7732. case VT_UNKNOWN:
  7733. case VT_DISPATCH:
  7734. {
  7735. CComPtr<IPersistStream> spStream;
  7736. if (punkVal != NULL)
  7737. {
  7738. hr = punkVal->QueryInterface(__uuidof(IPersistStream), (void**)&spStream);
  7739. if (FAILED(hr))
  7740. {
  7741. hr = punkVal->QueryInterface(__uuidof(IPersistStreamInit), (void**)&spStream);
  7742. if (FAILED(hr))
  7743. break;
  7744. }
  7745. }
  7746. if (spStream != NULL)
  7747. {
  7748. ULARGE_INTEGER nPersistSize;
  7749. nPersistSize.QuadPart = 0;
  7750. spStream->GetSizeMax(&nPersistSize);
  7751. nSize += nPersistSize.LowPart + sizeof(CLSID);
  7752. }
  7753. else
  7754. nSize += sizeof(CLSID);
  7755. }
  7756. break;
  7757. case VT_UI1:
  7758. case VT_I1:
  7759. nSize += sizeof(BYTE);
  7760. break;
  7761. case VT_I2:
  7762. case VT_UI2:
  7763. case VT_BOOL:
  7764. nSize += sizeof(short);
  7765. break;
  7766. case VT_I4:
  7767. case VT_UI4:
  7768. case VT_R4:
  7769. case VT_INT:
  7770. case VT_UINT:
  7771. case VT_ERROR:
  7772. nSize += sizeof(long);
  7773. break;
  7774. case VT_I8:
  7775. case VT_UI8:
  7776. nSize += sizeof(LONGLONG);
  7777. break;
  7778. case VT_R8:
  7779. case VT_CY:
  7780. case VT_DATE:
  7781. nSize += sizeof(double);
  7782. break;
  7783. default:
  7784. break;
  7785. }
  7786. if (nSize == sizeof(VARTYPE))
  7787. {
  7788. BSTR bstr = NULL;
  7789. CComVariant varBSTR;
  7790. if (vt != VT_BSTR)
  7791. {
  7792. hr = VariantChangeType(&varBSTR, const_cast<VARIANT*>((const VARIANT*)this), VARIANT_NOVALUEPROP, VT_BSTR);
  7793. if (SUCCEEDED(hr))
  7794. bstr = varBSTR.bstrVal;
  7795. }
  7796. else
  7797. bstr = bstrVal;
  7798. // Add the size of the length, the string itself and the NULL character
  7799. if (bstr != NULL)
  7800. nSize += sizeof(ULONG) + SysStringByteLen(bstr) + sizeof(OLECHAR);
  7801. }
  7802. return nSize;
  7803. }
  7804. inline HRESULT CComPtr<IDispatch>::Invoke2(DISPID dispid, VARIANT* pvarParam1, VARIANT* pvarParam2, VARIANT* pvarRet)
  7805. {
  7806. CComVariant varArgs[2] = { *pvarParam2, *pvarParam1 };
  7807. DISPPARAMS dispparams = { &varArgs[0], NULL, 2, 0};
  7808. return p->Invoke(dispid, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &dispparams, pvarRet, NULL, NULL);
  7809. }
  7810. template< typename T >
  7811. void AtlInitVariantFromArg( CComVariant& var, const T& arg )
  7812. {
  7813. VARIANT* pvar = &var;
  7814. pvar->*(CVarTypeInfo< T >::pmField) = arg;
  7815. pvar->vt = CVarTypeInfo< T >::VT;
  7816. }
  7817. /////////////////////////////////////////////////////////////////////////////
  7818. // CRegKey
  7819. class CRegKey
  7820. {
  7821. public:
  7822. CRegKey() throw();
  7823. CRegKey( CRegKey& key ) throw();
  7824. explicit CRegKey(HKEY hKey) throw();
  7825. ~CRegKey() throw();
  7826. CRegKey& operator=( CRegKey& key ) throw();
  7827. // Attributes
  7828. public:
  7829. operator HKEY() const throw();
  7830. HKEY m_hKey;
  7831. // Operations
  7832. public:
  7833. ATL_DEPRECATED LONG SetValue(DWORD dwValue, LPCTSTR lpszValueName);
  7834. ATL_DEPRECATED LONG SetValue(LPCTSTR lpszValue, LPCTSTR lpszValueName = NULL, bool bMulti = false, int nValueLen = -1);
  7835. LONG SetValue(LPCTSTR pszValueName, DWORD dwType, const void* pValue, ULONG nBytes) throw();
  7836. LONG SetGUIDValue(LPCTSTR pszValueName, REFGUID guidValue) throw();
  7837. LONG SetBinaryValue(LPCTSTR pszValueName, const void* pValue, ULONG nBytes) throw();
  7838. LONG SetDWORDValue(LPCTSTR pszValueName, DWORD dwValue) throw();
  7839. LONG SetQWORDValue(LPCTSTR pszValueName, ULONGLONG qwValue) throw();
  7840. LONG SetStringValue(LPCTSTR pszValueName, LPCTSTR pszValue, DWORD dwType = REG_SZ) throw();
  7841. LONG SetMultiStringValue(LPCTSTR pszValueName, LPCTSTR pszValue) throw();
  7842. ATL_DEPRECATED LONG QueryValue(DWORD& dwValue, LPCTSTR lpszValueName);
  7843. ATL_DEPRECATED LONG QueryValue(LPTSTR szValue, LPCTSTR lpszValueName, DWORD* pdwCount);
  7844. LONG QueryValue(LPCTSTR pszValueName, DWORD* pdwType, void* pData, ULONG* pnBytes) throw();
  7845. LONG QueryGUIDValue(LPCTSTR pszValueName, GUID& guidValue) throw();
  7846. LONG QueryBinaryValue(LPCTSTR pszValueName, void* pValue, ULONG* pnBytes) throw();
  7847. LONG QueryDWORDValue(LPCTSTR pszValueName, DWORD& dwValue) throw();
  7848. LONG QueryQWORDValue(LPCTSTR pszValueName, ULONGLONG& qwValue) throw();
  7849. LONG QueryStringValue(LPCTSTR pszValueName, LPTSTR pszValue, ULONG* pnChars) throw();
  7850. LONG QueryMultiStringValue(LPCTSTR pszValueName, LPTSTR pszValue, ULONG* pnChars) throw();
  7851. // Get the key's security attributes.
  7852. LONG GetKeySecurity(SECURITY_INFORMATION si, PSECURITY_DESCRIPTOR psd, LPDWORD pnBytes) throw();
  7853. // Set the key's security attributes.
  7854. LONG SetKeySecurity(SECURITY_INFORMATION si, PSECURITY_DESCRIPTOR psd) throw();
  7855. LONG SetKeyValue(LPCTSTR lpszKeyName, LPCTSTR lpszValue, LPCTSTR lpszValueName = NULL) throw();
  7856. static LONG WINAPI SetValue(HKEY hKeyParent, LPCTSTR lpszKeyName,
  7857. LPCTSTR lpszValue, LPCTSTR lpszValueName = NULL);
  7858. // Create a new registry key (or open an existing one).
  7859. LONG Create(HKEY hKeyParent, LPCTSTR lpszKeyName,
  7860. LPTSTR lpszClass = REG_NONE, DWORD dwOptions = REG_OPTION_NON_VOLATILE,
  7861. REGSAM samDesired = KEY_READ | KEY_WRITE,
  7862. LPSECURITY_ATTRIBUTES lpSecAttr = NULL,
  7863. LPDWORD lpdwDisposition = NULL) throw();
  7864. // Open an existing registry key.
  7865. LONG Open(HKEY hKeyParent, LPCTSTR lpszKeyName,
  7866. REGSAM samDesired = KEY_READ | KEY_WRITE) throw();
  7867. // Close the registry key.
  7868. LONG Close() throw();
  7869. // Flush the key's data to disk.
  7870. LONG Flush() throw();
  7871. // Detach the CRegKey object from its HKEY. Releases ownership.
  7872. HKEY Detach() throw();
  7873. // Attach the CRegKey object to an existing HKEY. Takes ownership.
  7874. void Attach(HKEY hKey) throw();
  7875. // Enumerate the subkeys of the key.
  7876. LONG EnumKey(DWORD iIndex, LPTSTR pszName, LPDWORD pnNameLength, FILETIME* pftLastWriteTime = NULL) throw();
  7877. LONG NotifyChangeKeyValue(BOOL bWatchSubtree, DWORD dwNotifyFilter, HANDLE hEvent, BOOL bAsync = TRUE) throw();
  7878. LONG DeleteSubKey(LPCTSTR lpszSubKey) throw();
  7879. LONG RecurseDeleteKey(LPCTSTR lpszKey) throw();
  7880. LONG DeleteValue(LPCTSTR lpszValue) throw();
  7881. };
  7882. inline CRegKey::CRegKey() :
  7883. m_hKey( NULL )
  7884. {
  7885. }
  7886. inline CRegKey::CRegKey( CRegKey& key ) :
  7887. m_hKey( NULL )
  7888. {
  7889. Attach( key.Detach() );
  7890. }
  7891. inline CRegKey::CRegKey(HKEY hKey) :
  7892. m_hKey(hKey)
  7893. {
  7894. }
  7895. inline CRegKey::~CRegKey()
  7896. {Close();}
  7897. inline CRegKey& CRegKey::operator=( CRegKey& key )
  7898. {
  7899. Close();
  7900. Attach( key.Detach() );
  7901. return( *this );
  7902. }
  7903. inline CRegKey::operator HKEY() const
  7904. {return m_hKey;}
  7905. inline HKEY CRegKey::Detach()
  7906. {
  7907. HKEY hKey = m_hKey;
  7908. m_hKey = NULL;
  7909. return hKey;
  7910. }
  7911. inline void CRegKey::Attach(HKEY hKey)
  7912. {
  7913. ATLASSERT(m_hKey == NULL);
  7914. m_hKey = hKey;
  7915. }
  7916. inline LONG CRegKey::DeleteSubKey(LPCTSTR lpszSubKey)
  7917. {
  7918. ATLASSERT(m_hKey != NULL);
  7919. return RegDeleteKey(m_hKey, lpszSubKey);
  7920. }
  7921. inline LONG CRegKey::DeleteValue(LPCTSTR lpszValue)
  7922. {
  7923. ATLASSERT(m_hKey != NULL);
  7924. return RegDeleteValue(m_hKey, (LPTSTR)lpszValue);
  7925. }
  7926. inline LONG CRegKey::Close()
  7927. {
  7928. LONG lRes = ERROR_SUCCESS;
  7929. if (m_hKey != NULL)
  7930. {
  7931. lRes = RegCloseKey(m_hKey);
  7932. m_hKey = NULL;
  7933. }
  7934. return lRes;
  7935. }
  7936. inline LONG CRegKey::Flush()
  7937. {
  7938. ATLASSERT(m_hKey != NULL);
  7939. return ::RegFlushKey(m_hKey);
  7940. }
  7941. inline LONG CRegKey::EnumKey(DWORD iIndex, LPTSTR pszName, LPDWORD pnNameLength, FILETIME* pftLastWriteTime)
  7942. {
  7943. FILETIME ftLastWriteTime;
  7944. ATLASSERT(m_hKey != NULL);
  7945. if (pftLastWriteTime == NULL)
  7946. {
  7947. pftLastWriteTime = &ftLastWriteTime;
  7948. }
  7949. return ::RegEnumKeyEx(m_hKey, iIndex, pszName, pnNameLength, NULL, NULL, NULL, pftLastWriteTime);
  7950. }
  7951. inline LONG CRegKey::NotifyChangeKeyValue(BOOL bWatchSubtree, DWORD dwNotifyFilter, HANDLE hEvent, BOOL bAsync)
  7952. {
  7953. ATLASSERT(m_hKey != NULL);
  7954. ATLASSERT((hEvent != NULL) || !bAsync);
  7955. return ::RegNotifyChangeKeyValue(m_hKey, bWatchSubtree, dwNotifyFilter, hEvent, bAsync);
  7956. }
  7957. inline LONG CRegKey::Create(HKEY hKeyParent, LPCTSTR lpszKeyName,
  7958. LPTSTR lpszClass, DWORD dwOptions, REGSAM samDesired,
  7959. LPSECURITY_ATTRIBUTES lpSecAttr, LPDWORD lpdwDisposition)
  7960. {
  7961. ATLASSERT(hKeyParent != NULL);
  7962. DWORD dw;
  7963. HKEY hKey = NULL;
  7964. LONG lRes = RegCreateKeyEx(hKeyParent, lpszKeyName, 0,
  7965. lpszClass, dwOptions, samDesired, lpSecAttr, &hKey, &dw);
  7966. if (lpdwDisposition != NULL)
  7967. *lpdwDisposition = dw;
  7968. if (lRes == ERROR_SUCCESS)
  7969. {
  7970. lRes = Close();
  7971. m_hKey = hKey;
  7972. }
  7973. return lRes;
  7974. }
  7975. inline LONG CRegKey::Open(HKEY hKeyParent, LPCTSTR lpszKeyName, REGSAM samDesired)
  7976. {
  7977. ATLASSERT(hKeyParent != NULL);
  7978. HKEY hKey = NULL;
  7979. LONG lRes = RegOpenKeyEx(hKeyParent, lpszKeyName, 0, samDesired, &hKey);
  7980. if (lRes == ERROR_SUCCESS)
  7981. {
  7982. lRes = Close();
  7983. ATLASSERT(lRes == ERROR_SUCCESS);
  7984. m_hKey = hKey;
  7985. }
  7986. return lRes;
  7987. }
  7988. #pragma warning(push)
  7989. #pragma warning(disable: 4996)
  7990. inline LONG CRegKey::QueryValue(DWORD& dwValue, LPCTSTR lpszValueName)
  7991. {
  7992. DWORD dwType = NULL;
  7993. DWORD dwCount = sizeof(DWORD);
  7994. LONG lRes = RegQueryValueEx(m_hKey, lpszValueName, NULL, &dwType,
  7995. (LPBYTE)&dwValue, &dwCount);
  7996. ATLASSERT((lRes!=ERROR_SUCCESS) || (dwType == REG_DWORD));
  7997. ATLASSERT((lRes!=ERROR_SUCCESS) || (dwCount == sizeof(DWORD)));
  7998. return lRes;
  7999. }
  8000. inline LONG CRegKey::QueryValue(LPTSTR pszValue, LPCTSTR lpszValueName, DWORD* pdwCount)
  8001. {
  8002. ATLASSERT(pdwCount != NULL);
  8003. DWORD dwType = NULL;
  8004. LONG lRes = RegQueryValueEx(m_hKey, lpszValueName, NULL, &dwType,
  8005. (LPBYTE)pszValue, pdwCount);
  8006. ATLASSERT((lRes!=ERROR_SUCCESS) || (dwType == REG_SZ) ||
  8007. (dwType == REG_MULTI_SZ) || (dwType == REG_EXPAND_SZ));
  8008. return lRes;
  8009. }
  8010. #pragma warning(pop)
  8011. inline LONG CRegKey::QueryValue(LPCTSTR pszValueName, DWORD* pdwType, void* pData, ULONG* pnBytes) throw()
  8012. {
  8013. ATLASSERT(m_hKey != NULL);
  8014. return( ::RegQueryValueEx(m_hKey, pszValueName, NULL, pdwType, static_cast< LPBYTE >( pData ), pnBytes) );
  8015. }
  8016. inline LONG CRegKey::QueryDWORDValue(LPCTSTR pszValueName, DWORD& dwValue)
  8017. {
  8018. LONG lRes;
  8019. ULONG nBytes;
  8020. DWORD dwType;
  8021. ATLASSERT(m_hKey != NULL);
  8022. nBytes = sizeof(DWORD);
  8023. lRes = ::RegQueryValueEx(m_hKey, pszValueName, NULL, &dwType, reinterpret_cast<LPBYTE>(&dwValue),
  8024. &nBytes);
  8025. if (lRes != ERROR_SUCCESS)
  8026. return lRes;
  8027. if (dwType != REG_DWORD)
  8028. return ERROR_INVALID_DATA;
  8029. return ERROR_SUCCESS;
  8030. }
  8031. inline LONG CRegKey::QueryQWORDValue(LPCTSTR pszValueName, ULONGLONG& qwValue)
  8032. {
  8033. LONG lRes;
  8034. ULONG nBytes;
  8035. DWORD dwType;
  8036. ATLASSERT(m_hKey != NULL);
  8037. nBytes = sizeof(ULONGLONG);
  8038. lRes = ::RegQueryValueEx(m_hKey, pszValueName, NULL, &dwType, reinterpret_cast<LPBYTE>(&qwValue),
  8039. &nBytes);
  8040. if (lRes != ERROR_SUCCESS)
  8041. return lRes;
  8042. if (dwType != REG_QWORD)
  8043. return ERROR_INVALID_DATA;
  8044. return ERROR_SUCCESS;
  8045. }
  8046. inline LONG CRegKey::QueryBinaryValue(LPCTSTR pszValueName, void* pValue, ULONG* pnBytes)
  8047. {
  8048. LONG lRes;
  8049. DWORD dwType;
  8050. ATLASSERT(pnBytes != NULL);
  8051. ATLASSERT(m_hKey != NULL);
  8052. lRes = ::RegQueryValueEx(m_hKey, pszValueName, NULL, &dwType, reinterpret_cast<LPBYTE>(pValue),
  8053. pnBytes);
  8054. if (lRes != ERROR_SUCCESS)
  8055. return lRes;
  8056. if (dwType != REG_BINARY)
  8057. return ERROR_INVALID_DATA;
  8058. return ERROR_SUCCESS;
  8059. }
  8060. inline LONG CRegKey::QueryStringValue(LPCTSTR pszValueName, LPTSTR pszValue, ULONG* pnChars)
  8061. {
  8062. LONG lRes;
  8063. DWORD dwType;
  8064. ULONG nBytes;
  8065. ATLASSERT(m_hKey != NULL);
  8066. ATLASSERT(pnChars != NULL);
  8067. nBytes = (*pnChars)*sizeof(TCHAR);
  8068. *pnChars = 0;
  8069. lRes = ::RegQueryValueEx(m_hKey, pszValueName, NULL, &dwType, reinterpret_cast<LPBYTE>(pszValue),
  8070. &nBytes);
  8071. if (lRes != ERROR_SUCCESS)
  8072. return lRes;
  8073. if (dwType != REG_SZ)
  8074. return ERROR_INVALID_DATA;
  8075. *pnChars = nBytes/sizeof(TCHAR);
  8076. return ERROR_SUCCESS;
  8077. }
  8078. inline LONG CRegKey::QueryMultiStringValue(LPCTSTR pszValueName, LPTSTR pszValue, ULONG* pnChars)
  8079. {
  8080. LONG lRes;
  8081. DWORD dwType;
  8082. ULONG nBytes;
  8083. ATLASSERT(m_hKey != NULL);
  8084. ATLASSERT(pnChars != NULL);
  8085. nBytes = (*pnChars)*sizeof(TCHAR);
  8086. *pnChars = 0;
  8087. lRes = ::RegQueryValueEx(m_hKey, pszValueName, NULL, &dwType, reinterpret_cast<LPBYTE>(pszValue),
  8088. &nBytes);
  8089. if (lRes != ERROR_SUCCESS)
  8090. return lRes;
  8091. if (dwType != REG_MULTI_SZ)
  8092. return ERROR_INVALID_DATA;
  8093. *pnChars = nBytes/sizeof(TCHAR);
  8094. return ERROR_SUCCESS;
  8095. }
  8096. inline LONG CRegKey::QueryGUIDValue(LPCTSTR pszValueName, GUID& guidValue)
  8097. {
  8098. USES_CONVERSION;
  8099. TCHAR szGUID[64];
  8100. LONG lRes;
  8101. ULONG nCount;
  8102. HRESULT hr;
  8103. ATLASSERT(m_hKey != NULL);
  8104. guidValue = GUID_NULL;
  8105. nCount = 64;
  8106. lRes = QueryStringValue(pszValueName, szGUID, &nCount);
  8107. if (lRes != ERROR_SUCCESS)
  8108. return lRes;
  8109. hr = ::CLSIDFromString(T2OLE(szGUID), &guidValue);
  8110. if (FAILED(hr))
  8111. return ERROR_INVALID_DATA;
  8112. return ERROR_SUCCESS;
  8113. }
  8114. inline LONG WINAPI CRegKey::SetValue(HKEY hKeyParent, LPCTSTR lpszKeyName, LPCTSTR lpszValue, LPCTSTR lpszValueName)
  8115. {
  8116. ATLASSERT(lpszValue != NULL);
  8117. CRegKey key;
  8118. LONG lRes = key.Create(hKeyParent, lpszKeyName);
  8119. if (lRes == ERROR_SUCCESS)
  8120. lRes = key.SetStringValue(lpszValueName, lpszValue);
  8121. return lRes;
  8122. }
  8123. inline LONG CRegKey::SetKeyValue(LPCTSTR lpszKeyName, LPCTSTR lpszValue, LPCTSTR lpszValueName)
  8124. {
  8125. ATLASSERT(lpszValue != NULL);
  8126. CRegKey key;
  8127. LONG lRes = key.Create(m_hKey, lpszKeyName);
  8128. if (lRes == ERROR_SUCCESS)
  8129. lRes = key.SetStringValue(lpszValueName, lpszValue);
  8130. return lRes;
  8131. }
  8132. #pragma warning(push)
  8133. #pragma warning(disable: 4996)
  8134. inline LONG CRegKey::SetValue(DWORD dwValue, LPCTSTR pszValueName)
  8135. {
  8136. ATLASSERT(m_hKey != NULL);
  8137. return SetDWORDValue(pszValueName, dwValue);
  8138. }
  8139. inline LONG CRegKey::SetValue(LPCTSTR lpszValue, LPCTSTR lpszValueName, bool bMulti, int nValueLen)
  8140. {
  8141. ATLASSERT(lpszValue != NULL);
  8142. ATLASSERT(m_hKey != NULL);
  8143. if (bMulti && nValueLen == -1)
  8144. return ERROR_INVALID_PARAMETER;
  8145. if (nValueLen == -1)
  8146. nValueLen = lstrlen(lpszValue) + 1;
  8147. DWORD dwType = bMulti ? REG_MULTI_SZ : REG_SZ;
  8148. return ::RegSetValueEx(m_hKey, lpszValueName, NULL, dwType,
  8149. reinterpret_cast<const BYTE*>(lpszValue), nValueLen*sizeof(TCHAR));
  8150. }
  8151. #pragma warning(pop)
  8152. inline LONG CRegKey::SetValue(LPCTSTR pszValueName, DWORD dwType, const void* pValue, ULONG nBytes) throw()
  8153. {
  8154. ATLASSERT(m_hKey != NULL);
  8155. return ::RegSetValueEx(m_hKey, pszValueName, NULL, dwType, static_cast<const BYTE*>(pValue), nBytes);
  8156. }
  8157. inline LONG CRegKey::SetBinaryValue(LPCTSTR pszValueName, const void* pData, ULONG nBytes)
  8158. {
  8159. ATLASSERT(m_hKey != NULL);
  8160. return ::RegSetValueEx(m_hKey, pszValueName, NULL, REG_BINARY, reinterpret_cast<const BYTE*>(pData), nBytes);
  8161. }
  8162. inline LONG CRegKey::SetDWORDValue(LPCTSTR pszValueName, DWORD dwValue)
  8163. {
  8164. ATLASSERT(m_hKey != NULL);
  8165. return ::RegSetValueEx(m_hKey, pszValueName, NULL, REG_DWORD, reinterpret_cast<const BYTE*>(&dwValue), sizeof(DWORD));
  8166. }
  8167. inline LONG CRegKey::SetQWORDValue(LPCTSTR pszValueName, ULONGLONG qwValue)
  8168. {
  8169. ATLASSERT(m_hKey != NULL);
  8170. return ::RegSetValueEx(m_hKey, pszValueName, NULL, REG_QWORD, reinterpret_cast<const BYTE*>(&qwValue), sizeof(ULONGLONG));
  8171. }
  8172. inline LONG CRegKey::SetStringValue(LPCTSTR pszValueName, LPCTSTR pszValue, DWORD dwType)
  8173. {
  8174. ATLASSERT(m_hKey != NULL);
  8175. ATLASSERT(pszValue != NULL);
  8176. ATLASSERT((dwType == REG_SZ) || (dwType == REG_EXPAND_SZ));
  8177. return ::RegSetValueEx(m_hKey, pszValueName, NULL, dwType, reinterpret_cast<const BYTE*>(pszValue), (lstrlen(pszValue)+1)*sizeof(TCHAR));
  8178. }
  8179. inline LONG CRegKey::SetMultiStringValue(LPCTSTR pszValueName, LPCTSTR pszValue)
  8180. {
  8181. LPCTSTR pszTemp;
  8182. ULONG nBytes;
  8183. ULONG nLength;
  8184. ATLASSERT(m_hKey != NULL);
  8185. ATLASSERT(pszValue != NULL);
  8186. // Find the total length (in bytes) of all of the strings, including the
  8187. // terminating '\0' of each string, and the second '\0' that terminates
  8188. // the list.
  8189. nBytes = 0;
  8190. pszTemp = pszValue;
  8191. do
  8192. {
  8193. nLength = lstrlen(pszTemp)+1;
  8194. pszTemp += nLength;
  8195. nBytes += nLength*sizeof(TCHAR);
  8196. } while (nLength != 1);
  8197. return ::RegSetValueEx(m_hKey, pszValueName, NULL, REG_MULTI_SZ, reinterpret_cast<const BYTE*>(pszValue),
  8198. nBytes);
  8199. }
  8200. inline LONG CRegKey::SetGUIDValue(LPCTSTR pszValueName, REFGUID guidValue)
  8201. {
  8202. USES_CONVERSION;
  8203. OLECHAR szGUID[64];
  8204. ATLASSERT(m_hKey != NULL);
  8205. ::StringFromGUID2(guidValue, szGUID, 64);
  8206. return SetStringValue(pszValueName, OLE2CT(szGUID));
  8207. }
  8208. inline LONG CRegKey::GetKeySecurity(SECURITY_INFORMATION si, PSECURITY_DESCRIPTOR psd, LPDWORD pnBytes)
  8209. {
  8210. ATLASSERT(m_hKey != NULL);
  8211. ATLASSERT(pnBytes != NULL);
  8212. return ::RegGetKeySecurity(m_hKey, si, psd, pnBytes);
  8213. }
  8214. inline LONG CRegKey::SetKeySecurity(SECURITY_INFORMATION si, PSECURITY_DESCRIPTOR psd)
  8215. {
  8216. ATLASSERT(m_hKey != NULL);
  8217. ATLASSERT(psd != NULL);
  8218. return ::RegSetKeySecurity(m_hKey, si, psd);
  8219. }
  8220. inline LONG CRegKey::RecurseDeleteKey(LPCTSTR lpszKey)
  8221. {
  8222. CRegKey key;
  8223. LONG lRes = key.Open(m_hKey, lpszKey, KEY_READ | KEY_WRITE);
  8224. if (lRes != ERROR_SUCCESS)
  8225. {
  8226. if (lRes != ERROR_FILE_NOT_FOUND && lRes != ERROR_PATH_NOT_FOUND)
  8227. {
  8228. ATLTRACE(atlTraceCOM, 0, _T("CRegKey::RecurseDeleteKey : Failed to Open Key %s(Error = %d)\n"), lpszKey, lRes);
  8229. }
  8230. return lRes;
  8231. }
  8232. FILETIME time;
  8233. DWORD dwSize = 256;
  8234. TCHAR szBuffer[256];
  8235. while (RegEnumKeyEx(key.m_hKey, 0, szBuffer, &dwSize, NULL, NULL, NULL,
  8236. &time)==ERROR_SUCCESS)
  8237. {
  8238. lRes = key.RecurseDeleteKey(szBuffer);
  8239. if (lRes != ERROR_SUCCESS)
  8240. return lRes;
  8241. dwSize = 256;
  8242. }
  8243. key.Close();
  8244. return DeleteSubKey(lpszKey);
  8245. }
  8246. inline HRESULT CComModule::RegisterProgID(LPCTSTR lpszCLSID, LPCTSTR lpszProgID, LPCTSTR lpszUserDesc)
  8247. {
  8248. CRegKey keyProgID;
  8249. LONG lRes = keyProgID.Create(HKEY_CLASSES_ROOT, lpszProgID, REG_NONE, REG_OPTION_NON_VOLATILE, KEY_SET_VALUE);
  8250. if (lRes == ERROR_SUCCESS)
  8251. {
  8252. lRes = keyProgID.SetStringValue(NULL, lpszUserDesc);
  8253. if (lRes == ERROR_SUCCESS)
  8254. {
  8255. lRes = keyProgID.SetKeyValue(_T("CLSID"), lpszCLSID);
  8256. if (lRes == ERROR_SUCCESS)
  8257. return S_OK;
  8258. }
  8259. }
  8260. return AtlHresultFromWin32(lRes);
  8261. }
  8262. inline HRESULT CComModule::RegisterAppId(LPCTSTR pAppId)
  8263. {
  8264. CRegKey keyAppID;
  8265. HRESULT hr = S_OK;
  8266. LONG lRet;
  8267. if ( (lRet = keyAppID.Open(HKEY_CLASSES_ROOT, _T("AppID"), KEY_WRITE)) == ERROR_SUCCESS)
  8268. {
  8269. TCHAR szModule1[_MAX_PATH];
  8270. TCHAR szModule2[_MAX_PATH];
  8271. TCHAR* pszFileName;
  8272. if (::GetModuleFileName(GetModuleInstance(), szModule1, _MAX_PATH) != 0)
  8273. {
  8274. if (::GetFullPathName(szModule1, _MAX_PATH, szModule2, &pszFileName) != 0)
  8275. {
  8276. CRegKey keyAppIDEXE;
  8277. if ( (lRet = keyAppIDEXE.Create(keyAppID, pszFileName, REG_NONE, REG_OPTION_NON_VOLATILE, KEY_READ | KEY_WRITE)) == ERROR_SUCCESS)
  8278. {
  8279. lRet = keyAppIDEXE.SetStringValue(_T("AppID"), pAppId);
  8280. if (lRet != ERROR_SUCCESS)
  8281. {
  8282. ATLTRACE(atlTraceCOM, 0, _T("CComModule::RegisterAppId : Failed to set app id string value\n"));
  8283. hr = AtlHresultFromWin32(lRet);
  8284. return hr;
  8285. }
  8286. }
  8287. else
  8288. {
  8289. ATLTRACE(atlTraceCOM, 0, _T("CComModule::RegisterAppId : Failed to create file name key\n"));
  8290. hr = AtlHresultFromWin32(lRet);
  8291. return hr;
  8292. }
  8293. if ( (lRet = keyAppIDEXE.Create(keyAppID, pAppId, REG_NONE, REG_OPTION_NON_VOLATILE, KEY_READ | KEY_WRITE)) == ERROR_SUCCESS)
  8294. {
  8295. lRet = keyAppIDEXE.SetStringValue(NULL, pszFileName);
  8296. if (lRet != ERROR_SUCCESS)
  8297. {
  8298. ATLTRACE(atlTraceCOM, 0, _T("CComModule::RegisterAppId : Failed to set file name string value\n"));
  8299. hr = AtlHresultFromWin32(lRet);
  8300. return hr;
  8301. }
  8302. }
  8303. else
  8304. {
  8305. ATLTRACE(atlTraceCOM, 0, _T("CComModule::RegisterAppId : Failed to create app id key\n"));
  8306. hr = AtlHresultFromWin32(lRet);
  8307. return hr;
  8308. }
  8309. }
  8310. else
  8311. {
  8312. ATLTRACE(atlTraceCOM, 0, _T("CComModule::RegisterAppId : Failed to get full path name for file %s\n"), szModule1);
  8313. hr = AtlHresultFromLastError();
  8314. }
  8315. }
  8316. else
  8317. {
  8318. ATLTRACE(atlTraceCOM, 0, _T("CComModule::RegisterAppId : Failed to get module name\n"));
  8319. hr = AtlHresultFromLastError();
  8320. }
  8321. }
  8322. else
  8323. {
  8324. ATLTRACE(atlTraceCOM, 0, _T("CComModule::RegisterAppId : Failed to open registry key\n"));
  8325. hr = AtlHresultFromWin32(lRet);
  8326. }
  8327. return hr;
  8328. }
  8329. inline HRESULT CComModule::UnregisterAppId(LPCTSTR pAppId)
  8330. {
  8331. CRegKey keyAppID;
  8332. HRESULT hr = S_OK;
  8333. LONG lRet = keyAppID.Open(HKEY_CLASSES_ROOT, _T("AppID"), KEY_READ | KEY_WRITE);
  8334. if (lRet == ERROR_SUCCESS)
  8335. {
  8336. TCHAR szModule1[_MAX_PATH];
  8337. TCHAR szModule2[_MAX_PATH];
  8338. TCHAR* pszFileName;
  8339. if (::GetModuleFileName(GetModuleInstance(), szModule1, _MAX_PATH) != 0)
  8340. {
  8341. if (::GetFullPathName(szModule1, _MAX_PATH, szModule2, &pszFileName) != 0)
  8342. {
  8343. if ((lRet = keyAppID.RecurseDeleteKey(pAppId)) != ERROR_SUCCESS)
  8344. {
  8345. if (lRet != ERROR_FILE_NOT_FOUND)
  8346. hr = AtlHresultFromWin32(lRet);
  8347. }
  8348. if ((lRet = keyAppID.RecurseDeleteKey(pszFileName)) != ERROR_SUCCESS)
  8349. {
  8350. if (lRet != ERROR_FILE_NOT_FOUND)
  8351. hr = AtlHresultFromWin32(lRet);
  8352. }
  8353. }
  8354. else
  8355. {
  8356. ATLTRACE(atlTraceCOM, 0, _T("CComModule::UnregisterAppId : Failed to get full path name for file %s\n"), szModule1);
  8357. hr = AtlHresultFromLastError();
  8358. }
  8359. }
  8360. else
  8361. {
  8362. ATLTRACE(atlTraceCOM, 0, _T("CComModule::UnregisterAppId : Failed to get module name\n"));
  8363. hr = AtlHresultFromLastError();
  8364. }
  8365. }
  8366. else
  8367. {
  8368. if (lRet != ERROR_FILE_NOT_FOUND && lRet != ERROR_PATH_NOT_FOUND)
  8369. {
  8370. ATLTRACE(atlTraceCOM, 0, _T("CComModule::UnregisterAppId : Failed to open registry key\n"));
  8371. hr = AtlHresultFromWin32(lRet);
  8372. }
  8373. }
  8374. return hr;
  8375. }
  8376. #ifdef _ATL_STATIC_REGISTRY
  8377. }; //namespace ATL
  8378. #include <statreg.h>
  8379. namespace ATL
  8380. {
  8381. // Statically linking to Registry Ponent
  8382. inline HRESULT WINAPI CAtlModule::UpdateRegistryFromResourceS(LPCTSTR lpszRes, BOOL bRegister,
  8383. struct _ATL_REGMAP_ENTRY* pMapEntries /*= NULL*/) throw()
  8384. {
  8385. CRegObject ro;
  8386. if (pMapEntries != NULL)
  8387. {
  8388. while (pMapEntries->szKey != NULL)
  8389. {
  8390. ATLASSERT(NULL != pMapEntries->szData);
  8391. ro.AddReplacement(pMapEntries->szKey, pMapEntries->szData);
  8392. pMapEntries++;
  8393. }
  8394. }
  8395. HRESULT hr = AddCommonRGSReplacements(&ro);
  8396. if (FAILED(hr))
  8397. return hr;
  8398. USES_CONVERSION;
  8399. TCHAR szModule[_MAX_PATH];
  8400. GetModuleFileName(_AtlBaseModule.GetModuleInstance(), szModule, _MAX_PATH);
  8401. LPOLESTR pszModule;
  8402. pszModule = T2OLE(szModule);
  8403. OLECHAR pszModuleQuote[_MAX_PATH * 2];
  8404. EscapeSingleQuote(pszModuleQuote, pszModule);
  8405. ro.AddReplacement(OLESTR("Module"), pszModuleQuote);
  8406. LPCOLESTR szType = OLESTR("REGISTRY");
  8407. hr = (bRegister) ? ro.ResourceRegisterSz(pszModule, T2COLE(lpszRes), szType) :
  8408. ro.ResourceUnregisterSz(pszModule, T2COLE(lpszRes), szType);
  8409. return hr;
  8410. }
  8411. inline HRESULT WINAPI CAtlModule::UpdateRegistryFromResourceS(UINT nResID, BOOL bRegister,
  8412. struct _ATL_REGMAP_ENTRY* pMapEntries /*= NULL*/) throw()
  8413. {
  8414. CRegObject ro;
  8415. if (pMapEntries != NULL)
  8416. {
  8417. while (pMapEntries->szKey != NULL)
  8418. {
  8419. ATLASSERT(NULL != pMapEntries->szData);
  8420. ro.AddReplacement(pMapEntries->szKey, pMapEntries->szData);
  8421. pMapEntries++;
  8422. }
  8423. }
  8424. HRESULT hr = AddCommonRGSReplacements(&ro);
  8425. if (FAILED(hr))
  8426. return hr;
  8427. USES_CONVERSION;
  8428. TCHAR szModule[_MAX_PATH];
  8429. GetModuleFileName(_AtlBaseModule.GetModuleInstance(), szModule, _MAX_PATH);
  8430. LPOLESTR pszModule;
  8431. pszModule = T2OLE(szModule);
  8432. OLECHAR pszModuleQuote[_MAX_PATH * 2];
  8433. EscapeSingleQuote(pszModuleQuote, pszModule);
  8434. ro.AddReplacement(OLESTR("Module"), pszModuleQuote);
  8435. LPCOLESTR szType = OLESTR("REGISTRY");
  8436. hr = (bRegister) ? ro.ResourceRegister(pszModule, nResID, szType) :
  8437. ro.ResourceUnregister(pszModule, nResID, szType);
  8438. return hr;
  8439. }
  8440. #endif //_ATL_STATIC_REGISTRY
  8441. #pragma warning( push )
  8442. #pragma warning( disable: 4996 ) // Disable "deprecated symbol" warning
  8443. inline HRESULT WINAPI CComModule::UpdateRegistryClass(const CLSID& clsid, LPCTSTR lpszProgID,
  8444. LPCTSTR lpszVerIndProgID, UINT nDescID, DWORD dwFlags, BOOL bRegister)
  8445. {
  8446. if (bRegister)
  8447. {
  8448. TCHAR szDesc[256];
  8449. LoadString(m_hInst, nDescID, szDesc, 256);
  8450. return RegisterClassHelper(clsid, lpszProgID, lpszVerIndProgID, szDesc, dwFlags);
  8451. }
  8452. return UnregisterClassHelper(clsid, lpszProgID, lpszVerIndProgID);
  8453. }
  8454. inline HRESULT WINAPI CComModule::UpdateRegistryClass(const CLSID& clsid, LPCTSTR lpszProgID,
  8455. LPCTSTR lpszVerIndProgID, LPCTSTR szDesc, DWORD dwFlags, BOOL bRegister)
  8456. {
  8457. if (bRegister)
  8458. return RegisterClassHelper(clsid, lpszProgID, lpszVerIndProgID, szDesc, dwFlags);
  8459. return UnregisterClassHelper(clsid, lpszProgID, lpszVerIndProgID);
  8460. }
  8461. inline HRESULT WINAPI CComModule::RegisterClassHelper(const CLSID& clsid, LPCTSTR lpszProgID,
  8462. LPCTSTR lpszVerIndProgID, LPCTSTR szDesc, DWORD dwFlags)
  8463. {
  8464. static const TCHAR szProgID[] = _T("ProgID");
  8465. static const TCHAR szVIProgID[] = _T("VersionIndependentProgID");
  8466. static const TCHAR szLS32[] = _T("LocalServer32");
  8467. static const TCHAR szIPS32[] = _T("InprocServer32");
  8468. static const TCHAR szThreadingModel[] = _T("ThreadingModel");
  8469. static const TCHAR szAUTPRX32[] = _T("AUTPRX32.DLL");
  8470. static const TCHAR szApartment[] = _T("Apartment");
  8471. static const TCHAR szBoth[] = _T("both");
  8472. USES_CONVERSION;
  8473. TCHAR szModule[_MAX_PATH];
  8474. DWORD dwLen = GetModuleFileName(m_hInst, szModule, _MAX_PATH);
  8475. if (dwLen == 0)
  8476. {
  8477. return AtlHresultFromLastError();
  8478. }
  8479. LPOLESTR lpOleStr;
  8480. HRESULT hRes = StringFromCLSID(clsid, &lpOleStr);
  8481. if (FAILED(hRes))
  8482. return hRes;
  8483. LPTSTR lpsz = OLE2T(lpOleStr);
  8484. hRes = RegisterProgID(lpsz, lpszProgID, szDesc);
  8485. if (hRes == S_OK)
  8486. hRes = RegisterProgID(lpsz, lpszVerIndProgID, szDesc);
  8487. LONG lRes = ERROR_SUCCESS;
  8488. if (hRes == S_OK)
  8489. {
  8490. CRegKey key;
  8491. lRes = key.Open(HKEY_CLASSES_ROOT, _T("CLSID"), KEY_READ | KEY_WRITE);
  8492. if (lRes == ERROR_SUCCESS)
  8493. {
  8494. lRes = key.Create(key, lpsz, REG_NONE, REG_OPTION_NON_VOLATILE, KEY_READ | KEY_WRITE);
  8495. if (lRes == ERROR_SUCCESS)
  8496. {
  8497. lRes = key.SetStringValue(NULL, szDesc);
  8498. if (lRes == ERROR_SUCCESS)
  8499. {
  8500. lRes = key.SetKeyValue(szProgID, lpszProgID);
  8501. if (lRes == ERROR_SUCCESS)
  8502. {
  8503. lRes = key.SetKeyValue(szVIProgID, lpszVerIndProgID);
  8504. if (lRes == ERROR_SUCCESS)
  8505. {
  8506. if ((m_hInst == NULL) || (m_hInst == GetModuleHandle(NULL))) // register as EXE
  8507. {
  8508. lRes = key.SetKeyValue(szLS32, szModule);
  8509. }
  8510. else
  8511. {
  8512. lRes = key.SetKeyValue(szIPS32, (dwFlags & AUTPRXFLAG) ? szAUTPRX32 : szModule);
  8513. if (lRes == ERROR_SUCCESS)
  8514. {
  8515. LPCTSTR lpszModel = (dwFlags & THREADFLAGS_BOTH) ? szBoth :
  8516. (dwFlags & THREADFLAGS_APARTMENT) ? szApartment : NULL;
  8517. if (lpszModel != NULL)
  8518. lRes = key.SetKeyValue(szIPS32, lpszModel, szThreadingModel);
  8519. }
  8520. }
  8521. }
  8522. }
  8523. }
  8524. }
  8525. }
  8526. }
  8527. CoTaskMemFree(lpOleStr);
  8528. if (lRes != ERROR_SUCCESS)
  8529. hRes = AtlHresultFromWin32(lRes);
  8530. return hRes;
  8531. }
  8532. inline HRESULT WINAPI CComModule::UnregisterClassHelper(const CLSID& clsid, LPCTSTR lpszProgID,
  8533. LPCTSTR lpszVerIndProgID)
  8534. {
  8535. USES_CONVERSION;
  8536. CRegKey key;
  8537. LONG lRet;
  8538. key.Attach(HKEY_CLASSES_ROOT);
  8539. if (lpszProgID != NULL && lstrcmpi(lpszProgID, _T("")))
  8540. {
  8541. lRet = key.RecurseDeleteKey(lpszProgID);
  8542. if (lRet != ERROR_SUCCESS && lRet != ERROR_FILE_NOT_FOUND && lRet != ERROR_PATH_NOT_FOUND)
  8543. {
  8544. ATLTRACE(atlTraceCOM, 0, _T("Failed to Unregister ProgID : %s\n"), lpszProgID);
  8545. key.Detach();
  8546. return AtlHresultFromWin32(lRet);
  8547. }
  8548. }
  8549. if (lpszVerIndProgID != NULL && lstrcmpi(lpszVerIndProgID, _T("")))
  8550. {
  8551. lRet = key.RecurseDeleteKey(lpszVerIndProgID);
  8552. if (lRet != ERROR_SUCCESS && lRet != ERROR_FILE_NOT_FOUND && lRet != ERROR_PATH_NOT_FOUND)
  8553. {
  8554. ATLTRACE(atlTraceCOM, 0, _T("Failed to Unregister Version Independent ProgID : %s\n"), lpszVerIndProgID);
  8555. key.Detach();
  8556. return AtlHresultFromWin32(lRet);
  8557. }
  8558. }
  8559. LPOLESTR lpOleStr;
  8560. HRESULT hr = StringFromCLSID(clsid, &lpOleStr);
  8561. if (SUCCEEDED(hr))
  8562. {
  8563. LPTSTR lpsz = OLE2T(lpOleStr);
  8564. lRet = key.Open(key, _T("CLSID"), KEY_READ | KEY_WRITE);
  8565. if (lRet == ERROR_SUCCESS)
  8566. lRet = key.RecurseDeleteKey(lpsz);
  8567. if (lRet != ERROR_SUCCESS && lRet != ERROR_FILE_NOT_FOUND && lRet != ERROR_PATH_NOT_FOUND)
  8568. {
  8569. ATLTRACE(atlTraceCOM, 0, _T("Failed to delete CLSID : %s\n"), lpsz);
  8570. hr = AtlHresultFromWin32(lRet);
  8571. }
  8572. CoTaskMemFree(lpOleStr);
  8573. }
  8574. else
  8575. {
  8576. ATLTRACE(atlTraceCOM, 0, _T("Failed to delete CLSID : {%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}"),
  8577. clsid.Data1,
  8578. clsid.Data2,
  8579. clsid.Data3,
  8580. clsid.Data4[0],
  8581. clsid.Data4[1],
  8582. clsid.Data4[2],
  8583. clsid.Data4[3],
  8584. clsid.Data4[4],
  8585. clsid.Data4[5],
  8586. clsid.Data4[6],
  8587. clsid.Data4[7]
  8588. );
  8589. }
  8590. key.Detach();
  8591. return hr;
  8592. }
  8593. #pragma warning( pop )
  8594. /////////////////////////////////////////////////////////////////////////////
  8595. // Large Block Allocation Helper - CVBufHelper & CVirtualBuffer
  8596. template <class T>
  8597. class CVBufHelper
  8598. {
  8599. public:
  8600. virtual T* operator()(T* pCurrent) {return pCurrent;}
  8601. };
  8602. template <class T>
  8603. class CVirtualBuffer
  8604. {
  8605. protected:
  8606. CVirtualBuffer() {}
  8607. T* m_pTop;
  8608. int m_nMaxElements;
  8609. public:
  8610. T* m_pBase;
  8611. T* m_pCurrent;
  8612. CVirtualBuffer(int nMaxElements)
  8613. {
  8614. m_nMaxElements = nMaxElements;
  8615. m_pBase = (T*) VirtualAlloc(NULL, sizeof(T) * nMaxElements,
  8616. MEM_RESERVE, PAGE_READWRITE);
  8617. m_pTop = m_pCurrent = m_pBase;
  8618. // Commit first page - chances are this is all that will be used
  8619. VirtualAlloc(m_pBase, sizeof(T), MEM_COMMIT, PAGE_READWRITE);
  8620. }
  8621. ~CVirtualBuffer()
  8622. {
  8623. VirtualFree(m_pBase, 0, MEM_RELEASE);
  8624. }
  8625. int Except(LPEXCEPTION_POINTERS lpEP)
  8626. {
  8627. EXCEPTION_RECORD* pExcept = lpEP->ExceptionRecord;
  8628. if (pExcept->ExceptionCode != EXCEPTION_ACCESS_VIOLATION)
  8629. return EXCEPTION_CONTINUE_SEARCH;
  8630. BYTE* pAddress = (LPBYTE) pExcept->ExceptionInformation[1];
  8631. VirtualAlloc(pAddress, sizeof(T), MEM_COMMIT, PAGE_READWRITE);
  8632. return EXCEPTION_CONTINUE_EXECUTION;
  8633. }
  8634. void Seek(int nElement)
  8635. {
  8636. ATLASSERT(nElement >= 0 && nElement < m_nMaxElements);
  8637. m_pCurrent = &m_pBase[nElement];
  8638. }
  8639. void SetAt(int nElement, const T& Element)
  8640. {
  8641. ATLASSERT(nElement >= 0 && nElement < m_nMaxElements);
  8642. __try
  8643. {
  8644. T* p = &m_pBase[nElement];
  8645. *p = Element;
  8646. m_pTop = p++ > m_pTop ? p : m_pTop;
  8647. }
  8648. __except(Except(GetExceptionInformation()))
  8649. {
  8650. }
  8651. }
  8652. template <class Q>
  8653. void WriteBulk(Q& helper)
  8654. {
  8655. __try
  8656. {
  8657. m_pCurrent = helper(m_pBase);
  8658. m_pTop = m_pCurrent > m_pTop ? m_pCurrent : m_pTop;
  8659. }
  8660. __except(Except(GetExceptionInformation()))
  8661. {
  8662. }
  8663. }
  8664. void Write(const T& Element)
  8665. {
  8666. __try
  8667. {
  8668. *m_pCurrent = Element;
  8669. m_pCurrent++;
  8670. m_pTop = m_pCurrent > m_pTop ? m_pCurrent : m_pTop;
  8671. }
  8672. __except(Except(GetExceptionInformation()))
  8673. {
  8674. }
  8675. }
  8676. T& Read()
  8677. {
  8678. return *m_pCurrent;
  8679. }
  8680. operator BSTR()
  8681. {
  8682. BSTR bstrTemp;
  8683. __try
  8684. {
  8685. bstrTemp = SysAllocStringByteLen((char*) m_pBase,
  8686. (UINT) ((BYTE*)m_pTop - (BYTE*)m_pBase));
  8687. }
  8688. __except(Except(GetExceptionInformation()))
  8689. {
  8690. }
  8691. return bstrTemp;
  8692. }
  8693. const T& operator[](int nElement) const
  8694. {
  8695. return m_pBase[nElement];
  8696. }
  8697. operator T*()
  8698. {
  8699. return m_pBase;
  8700. }
  8701. };
  8702. typedef CVirtualBuffer<BYTE> CVirtualBytes;
  8703. inline HRESULT WINAPI AtlDumpIID(REFIID iid, LPCTSTR pszClassName, HRESULT hr)
  8704. {
  8705. USES_CONVERSION;
  8706. CRegKey key;
  8707. TCHAR szName[100];
  8708. DWORD dwType,dw = sizeof(szName);
  8709. LPOLESTR pszGUID = NULL;
  8710. if (FAILED(StringFromCLSID(iid, &pszGUID)))
  8711. return hr;
  8712. OutputDebugString(pszClassName);
  8713. OutputDebugString(_T(" - "));
  8714. // Attempt to find it in the interfaces section
  8715. if (key.Open(HKEY_CLASSES_ROOT, _T("Interface"), KEY_READ) == ERROR_SUCCESS)
  8716. {
  8717. if (key.Open(key, OLE2T(pszGUID), KEY_READ) == ERROR_SUCCESS)
  8718. {
  8719. *szName = 0;
  8720. if (RegQueryValueEx(key.m_hKey, (LPTSTR)NULL, NULL, &dwType, (LPBYTE)szName, &dw) == ERROR_SUCCESS)
  8721. {
  8722. OutputDebugString(szName);
  8723. }
  8724. }
  8725. }
  8726. // Attempt to find it in the clsid section
  8727. else if (key.Open(HKEY_CLASSES_ROOT, _T("CLSID"), KEY_READ) == ERROR_SUCCESS)
  8728. {
  8729. if (key.Open(key, OLE2T(pszGUID), KEY_READ) == ERROR_SUCCESS)
  8730. {
  8731. *szName = 0;
  8732. if (RegQueryValueEx(key.m_hKey, (LPTSTR)NULL, NULL, &dwType, (LPBYTE)szName, &dw) == ERROR_SUCCESS)
  8733. {
  8734. OutputDebugString(_T("(CLSID\?\?\?) "));
  8735. OutputDebugString(szName);
  8736. }
  8737. }
  8738. }
  8739. else
  8740. OutputDebugString(OLE2T(pszGUID));
  8741. if (hr != S_OK)
  8742. OutputDebugString(_T(" - failed"));
  8743. OutputDebugString(_T("\n"));
  8744. CoTaskMemFree(pszGUID);
  8745. return hr;
  8746. }
  8747. /////////////////////////////////////////////////////////////////////////////
  8748. // _ATL_MSG - extended MSG structure
  8749. struct _ATL_MSG : public MSG
  8750. {
  8751. public:
  8752. // Additional data members
  8753. int cbSize;
  8754. BOOL bHandled;
  8755. // Constructors
  8756. _ATL_MSG() : cbSize(sizeof(_ATL_MSG)), bHandled(TRUE)
  8757. {
  8758. hwnd = NULL;
  8759. message = 0;
  8760. wParam = 0;
  8761. lParam = 0;
  8762. time = 0;
  8763. pt.x = pt.y = 0;
  8764. }
  8765. _ATL_MSG(HWND hWnd, UINT uMsg, WPARAM wParamIn, LPARAM lParamIn, DWORD dwTime, POINT ptIn, BOOL bHandledIn) : cbSize(sizeof(_ATL_MSG)), bHandled(bHandledIn)
  8766. {
  8767. hwnd = hWnd;
  8768. message = uMsg;
  8769. wParam = wParamIn;
  8770. lParam = lParamIn;
  8771. time = dwTime;
  8772. pt = ptIn;
  8773. }
  8774. _ATL_MSG(HWND hWnd, UINT uMsg, WPARAM wParamIn, LPARAM lParamIn, BOOL bHandledIn = TRUE) : cbSize(sizeof(_ATL_MSG)), bHandled(bHandledIn)
  8775. {
  8776. hwnd = hWnd;
  8777. message = uMsg;
  8778. wParam = wParamIn;
  8779. lParam = lParamIn;
  8780. time = 0;
  8781. pt.x = pt.y = 0;
  8782. }
  8783. _ATL_MSG(MSG& msg, BOOL bHandledIn = TRUE) : cbSize(sizeof(_ATL_MSG)), bHandled(bHandledIn)
  8784. {
  8785. hwnd = msg.hwnd;
  8786. message = msg.message;
  8787. wParam = msg.wParam;
  8788. lParam = msg.lParam;
  8789. time = msg.time;
  8790. pt = msg.pt;
  8791. }
  8792. };
  8793. #pragma pack(pop)
  8794. // WM_FORWARDMSG - used to forward a message to another window for processing
  8795. // WPARAM - DWORD dwUserData - defined by user
  8796. // LPARAM - LPMSG pMsg - a pointer to the MSG structure
  8797. // return value - 0 if the message was not processed, nonzero if it was
  8798. #define WM_FORWARDMSG 0x037F
  8799. }; //namespace ATL
  8800. #include <atlbase.inl>
  8801. #ifndef _ATL_NO_AUTOMATIC_NAMESPACE
  8802. using namespace ATL;
  8803. #endif //!_ATL_NO_AUTOMATIC_NAMESPACE
  8804. //only suck in definition if static linking
  8805. #ifndef _ATL_DLL_IMPL
  8806. #ifndef _ATL_DLL
  8807. #define _ATLBASE_IMPL
  8808. #endif
  8809. #endif
  8810. #ifdef _ATL_ATTRIBUTES
  8811. #include <atlplus.h>
  8812. #endif
  8813. //All exports go here
  8814. #ifdef _ATLBASE_IMPL
  8815. namespace ATL
  8816. {
  8817. /////////////////////////////////////////////////////////////////////////////
  8818. // statics
  8819. static UINT WINAPI AtlGetDirLen(LPCOLESTR lpszPathName)
  8820. {
  8821. ATLASSERT(lpszPathName != NULL);
  8822. // always capture the complete file name including extension (if present)
  8823. LPCOLESTR lpszTemp = lpszPathName;
  8824. for (LPCOLESTR lpsz = lpszPathName; *lpsz != NULL; )
  8825. {
  8826. LPCOLESTR lp = CharNextO(lpsz);
  8827. // remember last directory/drive separator
  8828. if (*lpsz == OLESTR('\\') || *lpsz == OLESTR('/') || *lpsz == OLESTR(':'))
  8829. lpszTemp = lp;
  8830. lpsz = lp;
  8831. }
  8832. return UINT( lpszTemp-lpszPathName );
  8833. }
  8834. /////////////////////////////////////////////////////////////////////////////
  8835. // QI support
  8836. ATLINLINE ATLAPI AtlInternalQueryInterface(void* pThis,
  8837. const _ATL_INTMAP_ENTRY* pEntries, REFIID iid, void** ppvObject)
  8838. {
  8839. ATLASSERT(pThis != NULL);
  8840. // First entry in the com map should be a simple map entry
  8841. ATLASSERT(pEntries->pFunc == _ATL_SIMPLEMAPENTRY);
  8842. if (ppvObject == NULL)
  8843. return E_POINTER;
  8844. *ppvObject = NULL;
  8845. if (InlineIsEqualUnknown(iid)) // use first interface
  8846. {
  8847. IUnknown* pUnk = (IUnknown*)((INT_PTR)pThis+pEntries->dw);
  8848. pUnk->AddRef();
  8849. *ppvObject = pUnk;
  8850. return S_OK;
  8851. }
  8852. while (pEntries->pFunc != NULL)
  8853. {
  8854. BOOL bBlind = (pEntries->piid == NULL);
  8855. if (bBlind || InlineIsEqualGUID(*(pEntries->piid), iid))
  8856. {
  8857. if (pEntries->pFunc == _ATL_SIMPLEMAPENTRY) //offset
  8858. {
  8859. ATLASSERT(!bBlind);
  8860. IUnknown* pUnk = (IUnknown*)((INT_PTR)pThis+pEntries->dw);
  8861. pUnk->AddRef();
  8862. *ppvObject = pUnk;
  8863. return S_OK;
  8864. }
  8865. else //actual function call
  8866. {
  8867. HRESULT hRes = pEntries->pFunc(pThis,
  8868. iid, ppvObject, pEntries->dw);
  8869. if (hRes == S_OK || (!bBlind && FAILED(hRes)))
  8870. return hRes;
  8871. }
  8872. }
  8873. pEntries++;
  8874. }
  8875. return E_NOINTERFACE;
  8876. }
  8877. /////////////////////////////////////////////////////////////////////////////
  8878. // Smart Pointer helpers
  8879. ATLINLINE ATLAPI_(IUnknown*) AtlComPtrAssign(IUnknown** pp, IUnknown* lp)
  8880. {
  8881. if (lp != NULL)
  8882. lp->AddRef();
  8883. if (*pp)
  8884. (*pp)->Release();
  8885. *pp = lp;
  8886. return lp;
  8887. }
  8888. ATLINLINE ATLAPI_(IUnknown*) AtlComQIPtrAssign(IUnknown** pp, IUnknown* lp, REFIID riid)
  8889. {
  8890. IUnknown* pTemp = *pp;
  8891. *pp = NULL;
  8892. if (lp != NULL)
  8893. lp->QueryInterface(riid, (void**)pp);
  8894. if (pTemp)
  8895. pTemp->Release();
  8896. return *pp;
  8897. }
  8898. /////////////////////////////////////////////////////////////////////////////
  8899. // Inproc Marshaling helpers
  8900. //This API should be called from the same thread that called
  8901. //AtlMarshalPtrInProc
  8902. ATLINLINE ATLAPI AtlFreeMarshalStream(IStream* pStream)
  8903. {
  8904. if (pStream != NULL)
  8905. {
  8906. LARGE_INTEGER l;
  8907. l.QuadPart = 0;
  8908. pStream->Seek(l, STREAM_SEEK_SET, NULL);
  8909. CoReleaseMarshalData(pStream);
  8910. pStream->Release();
  8911. }
  8912. return S_OK;
  8913. }
  8914. ATLINLINE ATLAPI AtlMarshalPtrInProc(IUnknown* pUnk, const IID& iid, IStream** ppStream)
  8915. {
  8916. HRESULT hRes = CreateStreamOnHGlobal(NULL, TRUE, ppStream);
  8917. if (SUCCEEDED(hRes))
  8918. {
  8919. hRes = CoMarshalInterface(*ppStream, iid,
  8920. pUnk, MSHCTX_INPROC, NULL, MSHLFLAGS_TABLESTRONG);
  8921. if (FAILED(hRes))
  8922. {
  8923. (*ppStream)->Release();
  8924. *ppStream = NULL;
  8925. }
  8926. }
  8927. return hRes;
  8928. }
  8929. ATLINLINE ATLAPI AtlUnmarshalPtr(IStream* pStream, const IID& iid, IUnknown** ppUnk)
  8930. {
  8931. ATLASSERT(ppUnk != NULL);
  8932. if (ppUnk == NULL)
  8933. return E_POINTER;
  8934. *ppUnk = NULL;
  8935. HRESULT hRes = E_INVALIDARG;
  8936. if (pStream != NULL)
  8937. {
  8938. LARGE_INTEGER l;
  8939. l.QuadPart = 0;
  8940. pStream->Seek(l, STREAM_SEEK_SET, NULL);
  8941. hRes = CoUnmarshalInterface(pStream, iid, (void**)ppUnk);
  8942. }
  8943. return hRes;
  8944. }
  8945. ATLINLINE ATLAPI_(BOOL) AtlWaitWithMessageLoop(HANDLE hEvent)
  8946. {
  8947. DWORD dwRet;
  8948. MSG msg;
  8949. while(1)
  8950. {
  8951. dwRet = MsgWaitForMultipleObjects(1, &hEvent, FALSE, INFINITE, QS_ALLINPUT);
  8952. if (dwRet == WAIT_OBJECT_0)
  8953. return TRUE; // The event was signaled
  8954. if (dwRet != WAIT_OBJECT_0 + 1)
  8955. break; // Something else happened
  8956. // There is one or more window message available. Dispatch them
  8957. while(PeekMessage(&msg,0,0,0,PM_NOREMOVE))
  8958. {
  8959. // check for unicode window so we call the appropriate functions
  8960. BOOL bUnicode = ::IsWindowUnicode(msg.hwnd);
  8961. BOOL bRet;
  8962. if (bUnicode)
  8963. bRet = ::GetMessageW(&msg, NULL, 0, 0);
  8964. else
  8965. bRet = ::GetMessageA(&msg, NULL, 0, 0);
  8966. if (bRet > 0)
  8967. {
  8968. ::TranslateMessage(&msg);
  8969. if (bUnicode)
  8970. ::DispatchMessageW(&msg);
  8971. else
  8972. ::DispatchMessageA(&msg);
  8973. }
  8974. if (WaitForSingleObject(hEvent, 0) == WAIT_OBJECT_0)
  8975. return TRUE; // Event is now signaled.
  8976. }
  8977. }
  8978. return FALSE;
  8979. }
  8980. /////////////////////////////////////////////////////////////////////////////
  8981. // Connection Point Helpers
  8982. ATLINLINE ATLAPI AtlAdvise(IUnknown* pUnkCP, IUnknown* pUnk, const IID& iid, LPDWORD pdw)
  8983. {
  8984. CComPtr<IConnectionPointContainer> pCPC;
  8985. CComPtr<IConnectionPoint> pCP;
  8986. HRESULT hRes = pUnkCP->QueryInterface(__uuidof(IConnectionPointContainer), (void**)&pCPC);
  8987. if (SUCCEEDED(hRes))
  8988. hRes = pCPC->FindConnectionPoint(iid, &pCP);
  8989. if (SUCCEEDED(hRes))
  8990. hRes = pCP->Advise(pUnk, pdw);
  8991. return hRes;
  8992. }
  8993. ATLINLINE ATLAPI AtlUnadvise(IUnknown* pUnkCP, const IID& iid, DWORD dw)
  8994. {
  8995. CComPtr<IConnectionPointContainer> pCPC;
  8996. CComPtr<IConnectionPoint> pCP;
  8997. HRESULT hRes = pUnkCP->QueryInterface(__uuidof(IConnectionPointContainer), (void**)&pCPC);
  8998. if (SUCCEEDED(hRes))
  8999. hRes = pCPC->FindConnectionPoint(iid, &pCP);
  9000. if (SUCCEEDED(hRes))
  9001. hRes = pCP->Unadvise(dw);
  9002. return hRes;
  9003. }
  9004. /////////////////////////////////////////////////////////////////////////////
  9005. // IDispatch Error handling
  9006. ATLINLINE ATLAPI AtlSetErrorInfo(const CLSID& clsid, LPCOLESTR lpszDesc, DWORD dwHelpID,
  9007. LPCOLESTR lpszHelpFile, const IID& iid, HRESULT hRes, HINSTANCE hInst)
  9008. {
  9009. USES_CONVERSION;
  9010. TCHAR szDesc[1024];
  9011. szDesc[0] = NULL;
  9012. // For a valid HRESULT the id should be in the range [0x0200, 0xffff]
  9013. if (IS_INTRESOURCE(lpszDesc)) //id
  9014. {
  9015. UINT nID = LOWORD((DWORD_PTR)lpszDesc);
  9016. ATLASSERT((nID >= 0x0200 && nID <= 0xffff) || hRes != 0);
  9017. if (LoadString(hInst, nID, szDesc, 1024) == 0)
  9018. {
  9019. ATLASSERT(FALSE);
  9020. lstrcpy(szDesc, _T("Unknown Error"));
  9021. }
  9022. lpszDesc = T2OLE(szDesc);
  9023. if (hRes == 0)
  9024. hRes = MAKE_HRESULT(3, FACILITY_ITF, nID);
  9025. }
  9026. CComPtr<ICreateErrorInfo> pICEI;
  9027. if (SUCCEEDED(CreateErrorInfo(&pICEI)))
  9028. {
  9029. CComPtr<IErrorInfo> pErrorInfo;
  9030. pICEI->SetGUID(iid);
  9031. LPOLESTR lpsz;
  9032. ProgIDFromCLSID(clsid, &lpsz);
  9033. if (lpsz != NULL)
  9034. pICEI->SetSource(lpsz);
  9035. if (dwHelpID != 0 && lpszHelpFile != NULL)
  9036. {
  9037. pICEI->SetHelpContext(dwHelpID);
  9038. pICEI->SetHelpFile(const_cast<LPOLESTR>(lpszHelpFile));
  9039. }
  9040. CoTaskMemFree(lpsz);
  9041. pICEI->SetDescription((LPOLESTR)lpszDesc);
  9042. if (SUCCEEDED(pICEI->QueryInterface(__uuidof(IErrorInfo), (void**)&pErrorInfo)))
  9043. SetErrorInfo(0, pErrorInfo);
  9044. }
  9045. return (hRes == 0) ? DISP_E_EXCEPTION : hRes;
  9046. }
  9047. /////////////////////////////////////////////////////////////////////////////
  9048. // Module
  9049. //Although these functions are big, they are only used once in a module
  9050. //so we should make them inline.
  9051. #if !defined(_ATL_DLL) && !defined(_ATL_DLL_IMPL)
  9052. ATLINLINE ATLAPI AtlCreateRegistrar(IRegistrar** ppRegistrar)
  9053. {
  9054. ATLASSERT(false); // Check your project settings if this assert fires.
  9055. *ppRegistrar = NULL;
  9056. ATLTRACENOTIMPL(_T("AtlCreateRegistrar"));
  9057. }
  9058. #endif
  9059. ATLINLINE ATLAPI AtlComModuleRegisterClassObjects(_ATL_COM_MODULE* pComModule, DWORD dwClsContext, DWORD dwFlags)
  9060. {
  9061. ATLASSERT(pComModule != NULL);
  9062. if (pComModule == NULL)
  9063. return E_INVALIDARG;
  9064. HRESULT hr = S_FALSE;
  9065. for (_ATL_OBJMAP_ENTRY** ppEntry = pComModule->m_ppAutoObjMapFirst; ppEntry < pComModule->m_ppAutoObjMapLast && SUCCEEDED(hr); ppEntry++)
  9066. {
  9067. if (*ppEntry != NULL)
  9068. hr = (*ppEntry)->RegisterClassObject(dwClsContext, dwFlags);
  9069. }
  9070. return hr;
  9071. }
  9072. ATLINLINE ATLAPI AtlComModuleRevokeClassObjects(_ATL_COM_MODULE* pComModule)
  9073. {
  9074. ATLASSERT(pComModule != NULL);
  9075. if (pComModule == NULL)
  9076. return E_INVALIDARG;
  9077. HRESULT hr = S_OK;
  9078. for (_ATL_OBJMAP_ENTRY** ppEntry = pComModule->m_ppAutoObjMapFirst; ppEntry < pComModule->m_ppAutoObjMapLast && hr == S_OK; ppEntry++)
  9079. {
  9080. if (*ppEntry != NULL)
  9081. hr = (*ppEntry)->RevokeClassObject();
  9082. }
  9083. return hr;
  9084. }
  9085. ATLINLINE ATLAPI AtlComModuleGetClassObject(_ATL_COM_MODULE* pComModule, REFCLSID rclsid, REFIID riid, LPVOID* ppv)
  9086. {
  9087. ATLASSERT(pComModule != NULL);
  9088. if (pComModule == NULL)
  9089. return E_INVALIDARG;
  9090. #ifndef _ATL_OLEDB_CONFORMANCE_TESTS
  9091. ATLASSERT(ppv != NULL);
  9092. #endif
  9093. if (ppv == NULL)
  9094. return E_POINTER;
  9095. *ppv = NULL;
  9096. HRESULT hr = S_OK;
  9097. for (_ATL_OBJMAP_ENTRY** ppEntry = pComModule->m_ppAutoObjMapFirst; ppEntry < pComModule->m_ppAutoObjMapLast; ppEntry++)
  9098. {
  9099. if (*ppEntry != NULL)
  9100. {
  9101. _ATL_OBJMAP_ENTRY* pEntry = *ppEntry;
  9102. if ((pEntry->pfnGetClassObject != NULL) && InlineIsEqualGUID(rclsid, *pEntry->pclsid))
  9103. {
  9104. if (pEntry->pCF == NULL)
  9105. {
  9106. CComCritSecLock<CComCriticalSection> lock(pComModule->m_csObjMap, false);
  9107. hr = lock.Lock();
  9108. if (FAILED(hr))
  9109. {
  9110. ATLTRACE(atlTraceCOM, 0, _T("ERROR : Unable to lock critical section in AtlComModuleGetClassObject\n"));
  9111. ATLASSERT(0);
  9112. break;
  9113. }
  9114. if (pEntry->pCF == NULL)
  9115. hr = pEntry->pfnGetClassObject(pEntry->pfnCreateInstance, __uuidof(IUnknown), (LPVOID*)&pEntry->pCF);
  9116. }
  9117. if (pEntry->pCF != NULL)
  9118. hr = pEntry->pCF->QueryInterface(riid, ppv);
  9119. break;
  9120. }
  9121. }
  9122. }
  9123. if (*ppv == NULL && hr == S_OK)
  9124. hr = CLASS_E_CLASSNOTAVAILABLE;
  9125. return hr;
  9126. }
  9127. ATLINLINE ATLAPI AtlModuleAddTermFunc(_ATL_MODULE* pModule, _ATL_TERMFUNC* pFunc, DWORD_PTR dw)
  9128. {
  9129. HRESULT hr = S_OK;
  9130. _ATL_TERMFUNC_ELEM* pNew = NULL;
  9131. ATLTRY(pNew = new _ATL_TERMFUNC_ELEM);
  9132. if (pNew == NULL)
  9133. hr = E_OUTOFMEMORY;
  9134. else
  9135. {
  9136. pNew->pFunc = pFunc;
  9137. pNew->dw = dw;
  9138. CComCritSecLock<CComCriticalSection> lock(pModule->m_csStaticDataInitAndTypeInfo, false);
  9139. hr = lock.Lock();
  9140. if (SUCCEEDED(hr))
  9141. {
  9142. pNew->pNext = pModule->m_pTermFuncs;
  9143. pModule->m_pTermFuncs = pNew;
  9144. }
  9145. else
  9146. {
  9147. delete pNew;
  9148. ATLTRACE(atlTraceGeneral, 0, _T("ERROR : Unable to lock critical section in AtlModuleAddTermFunc\n"));
  9149. ATLASSERT(0);
  9150. }
  9151. }
  9152. return hr;
  9153. }
  9154. ATLINLINE ATLAPI_(void) AtlCallTermFunc(_ATL_MODULE* pModule)
  9155. {
  9156. _ATL_TERMFUNC_ELEM* pElem = pModule->m_pTermFuncs;
  9157. _ATL_TERMFUNC_ELEM* pNext = NULL;
  9158. while (pElem != NULL)
  9159. {
  9160. pElem->pFunc(pElem->dw);
  9161. pNext = pElem->pNext;
  9162. delete pElem;
  9163. pElem = pNext;
  9164. }
  9165. pModule->m_pTermFuncs = NULL;
  9166. }
  9167. ATLINLINE ATLAPI AtlRegisterClassCategoriesHelper( REFCLSID clsid,
  9168. const struct _ATL_CATMAP_ENTRY* pCatMap, BOOL bRegister )
  9169. {
  9170. CComPtr< ICatRegister > pCatRegister;
  9171. HRESULT hResult;
  9172. const struct _ATL_CATMAP_ENTRY* pEntry;
  9173. CATID catid;
  9174. if( pCatMap == NULL )
  9175. {
  9176. return( S_OK );
  9177. }
  9178. if (InlineIsEqualGUID(clsid, GUID_NULL))
  9179. {
  9180. ATLASSERT(0 && _T("Use OBJECT_ENTRY_NON_CREATEABLE_EX macro if you want to register class categories for non creatable objects."));
  9181. return S_OK;
  9182. }
  9183. hResult = CoCreateInstance( CLSID_StdComponentCategoriesMgr, NULL,
  9184. CLSCTX_INPROC_SERVER, __uuidof(ICatRegister), (void**)&pCatRegister );
  9185. if( FAILED( hResult ) )
  9186. {
  9187. // Since not all systems have the category manager installed, we'll allow
  9188. // the registration to succeed even though we didn't register our
  9189. // categories. If you really want to register categories on a system
  9190. // without the category manager, you can either manually add the
  9191. // appropriate entries to your registry script (.rgs), or you can
  9192. // redistribute comcat.dll.
  9193. return( S_OK );
  9194. }
  9195. hResult = S_OK;
  9196. pEntry = pCatMap;
  9197. while( pEntry->iType != _ATL_CATMAP_ENTRY_END )
  9198. {
  9199. catid = *pEntry->pcatid;
  9200. if( bRegister )
  9201. {
  9202. if( pEntry->iType == _ATL_CATMAP_ENTRY_IMPLEMENTED )
  9203. {
  9204. hResult = pCatRegister->RegisterClassImplCategories( clsid, 1,
  9205. &catid );
  9206. }
  9207. else
  9208. {
  9209. ATLASSERT( pEntry->iType == _ATL_CATMAP_ENTRY_REQUIRED );
  9210. hResult = pCatRegister->RegisterClassReqCategories( clsid, 1,
  9211. &catid );
  9212. }
  9213. if( FAILED( hResult ) )
  9214. {
  9215. return( hResult );
  9216. }
  9217. }
  9218. else
  9219. {
  9220. if( pEntry->iType == _ATL_CATMAP_ENTRY_IMPLEMENTED )
  9221. {
  9222. pCatRegister->UnRegisterClassImplCategories( clsid, 1, &catid );
  9223. }
  9224. else
  9225. {
  9226. ATLASSERT( pEntry->iType == _ATL_CATMAP_ENTRY_REQUIRED );
  9227. pCatRegister->UnRegisterClassReqCategories( clsid, 1, &catid );
  9228. }
  9229. }
  9230. pEntry++;
  9231. }
  9232. // When unregistering remove "Implemented Categories" and "Required Categories" subkeys if they are empty.
  9233. if (!bRegister)
  9234. {
  9235. OLECHAR szGUID[64];
  9236. ::StringFromGUID2(clsid, szGUID, 64);
  9237. USES_CONVERSION;
  9238. TCHAR* pszGUID = OLE2T(szGUID);
  9239. if (pszGUID != NULL)
  9240. {
  9241. TCHAR szKey[128];
  9242. lstrcpy(szKey, _T("CLSID\\"));
  9243. lstrcat(szKey, pszGUID);
  9244. lstrcat(szKey, _T("\\Required Categories"));
  9245. CRegKey root(HKEY_CLASSES_ROOT);
  9246. CRegKey key;
  9247. DWORD cbSubKeys = 0;
  9248. LRESULT lRes = key.Open(root, szKey, KEY_READ);
  9249. if (lRes == ERROR_SUCCESS)
  9250. {
  9251. lRes = RegQueryInfoKey(key, NULL, NULL, NULL, &cbSubKeys, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
  9252. key.Close();
  9253. if (lRes == ERROR_SUCCESS && cbSubKeys == 0)
  9254. {
  9255. root.DeleteSubKey(szKey);
  9256. }
  9257. }
  9258. lstrcpy(szKey, _T("CLSID\\"));
  9259. lstrcat(szKey, pszGUID);
  9260. lstrcat(szKey, _T("\\Implemented Categories"));
  9261. lRes = key.Open(root, szKey, KEY_READ);
  9262. if (lRes == ERROR_SUCCESS)
  9263. {
  9264. lRes = RegQueryInfoKey(key, NULL, NULL, NULL, &cbSubKeys, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
  9265. key.Close();
  9266. if (lRes == ERROR_SUCCESS && cbSubKeys == 0)
  9267. {
  9268. root.DeleteSubKey(szKey);
  9269. }
  9270. }
  9271. }
  9272. }
  9273. return( S_OK );
  9274. }
  9275. // AtlComModuleRegisterServer walks the ATL Autogenerated Object Map and registers each object in the map
  9276. // If pCLSID is not NULL then only the object referred to by pCLSID is registered (The default case)
  9277. // otherwise all the objects are registered
  9278. ATLINLINE ATLAPI AtlComModuleRegisterServer(_ATL_COM_MODULE* pComModule, BOOL bRegTypeLib, const CLSID* pCLSID)
  9279. {
  9280. ATLASSERT(pComModule != NULL);
  9281. if (pComModule == NULL)
  9282. return E_INVALIDARG;
  9283. ATLASSERT(pComModule->m_hInstTypeLib != NULL);
  9284. HRESULT hr = S_OK;
  9285. for (_ATL_OBJMAP_ENTRY** ppEntry = pComModule->m_ppAutoObjMapFirst; ppEntry < pComModule->m_ppAutoObjMapLast; ppEntry++)
  9286. {
  9287. if (*ppEntry != NULL)
  9288. {
  9289. _ATL_OBJMAP_ENTRY* pEntry = *ppEntry;
  9290. if (pCLSID != NULL)
  9291. {
  9292. if (!IsEqualGUID(*pCLSID, *pEntry->pclsid))
  9293. continue;
  9294. }
  9295. hr = pEntry->pfnUpdateRegistry(TRUE);
  9296. if (FAILED(hr))
  9297. break;
  9298. hr = AtlRegisterClassCategoriesHelper( *pEntry->pclsid,
  9299. pEntry->pfnGetCategoryMap(), TRUE );
  9300. if (FAILED(hr))
  9301. break;
  9302. }
  9303. }
  9304. if (SUCCEEDED(hr) && bRegTypeLib)
  9305. hr = AtlRegisterTypeLib(pComModule->m_hInstTypeLib, 0);
  9306. return hr;
  9307. }
  9308. // AtlComUnregisterServer walks the ATL Object Map and unregisters each object in the map
  9309. // If pCLSID is not NULL then only the object referred to by pCLSID is unregistered (The default case)
  9310. // otherwise all the objects are unregistered.
  9311. ATLINLINE ATLAPI AtlComModuleUnregisterServer(_ATL_COM_MODULE* pComModule, BOOL bUnRegTypeLib, const CLSID* pCLSID)
  9312. {
  9313. ATLASSERT(pComModule != NULL);
  9314. if (pComModule == NULL)
  9315. return E_INVALIDARG;
  9316. HRESULT hr = S_OK;
  9317. for (_ATL_OBJMAP_ENTRY** ppEntry = pComModule->m_ppAutoObjMapFirst; ppEntry < pComModule->m_ppAutoObjMapLast; ppEntry++)
  9318. {
  9319. if (*ppEntry != NULL)
  9320. {
  9321. _ATL_OBJMAP_ENTRY* pEntry = *ppEntry;
  9322. if (pCLSID != NULL)
  9323. {
  9324. if (!IsEqualGUID(*pCLSID, *pEntry->pclsid))
  9325. continue;
  9326. }
  9327. hr = AtlRegisterClassCategoriesHelper( *pEntry->pclsid, pEntry->pfnGetCategoryMap(), FALSE );
  9328. if (FAILED(hr))
  9329. break;
  9330. hr = pEntry->pfnUpdateRegistry(FALSE); //unregister
  9331. if (FAILED(hr))
  9332. break;
  9333. }
  9334. }
  9335. if (SUCCEEDED(hr) && bUnRegTypeLib)
  9336. hr = AtlUnRegisterTypeLib(pComModule->m_hInstTypeLib, 0);
  9337. return hr;
  9338. }
  9339. ATLINLINE ATLAPI AtlUpdateRegistryFromResourceD(HINSTANCE hInst, LPCOLESTR lpszRes,
  9340. BOOL bRegister, struct _ATL_REGMAP_ENTRY* pMapEntries, IRegistrar* pReg)
  9341. {
  9342. ATLASSERT(hInst != NULL);
  9343. if (hInst == NULL)
  9344. return E_INVALIDARG;
  9345. HRESULT hRes = S_OK;
  9346. CComPtr<IRegistrar> p;
  9347. if (pReg != NULL)
  9348. p = pReg;
  9349. else
  9350. {
  9351. hRes = AtlCreateRegistrar(&p);
  9352. }
  9353. if (NULL != pMapEntries)
  9354. {
  9355. while (NULL != pMapEntries->szKey)
  9356. {
  9357. ATLASSERT(NULL != pMapEntries->szData);
  9358. p->AddReplacement(pMapEntries->szKey, pMapEntries->szData);
  9359. pMapEntries++;
  9360. }
  9361. }
  9362. if (SUCCEEDED(hRes))
  9363. {
  9364. TCHAR szModule[_MAX_PATH];
  9365. ATLVERIFY( GetModuleFileName(hInst, szModule, _MAX_PATH) != 0 );
  9366. USES_CONVERSION;
  9367. LPOLESTR pszModule;
  9368. pszModule = T2OLE(szModule);
  9369. size_t nLen = ocslen(pszModule);
  9370. LPOLESTR pszModuleQuote = (LPOLESTR)alloca((nLen*2+1)*sizeof(OLECHAR));
  9371. CAtlModule::EscapeSingleQuote(pszModuleQuote, pszModule);
  9372. p->AddReplacement(OLESTR("Module"), pszModuleQuote);
  9373. LPCOLESTR szType = OLESTR("REGISTRY");
  9374. if (IS_INTRESOURCE(lpszRes))
  9375. {
  9376. if (bRegister)
  9377. hRes = p->ResourceRegister(pszModule, ((UINT)LOWORD((DWORD_PTR)lpszRes)), szType);
  9378. else
  9379. hRes = p->ResourceUnregister(pszModule, ((UINT)LOWORD((DWORD_PTR)lpszRes)), szType);
  9380. }
  9381. else
  9382. {
  9383. if (bRegister)
  9384. hRes = p->ResourceRegisterSz(pszModule, lpszRes, szType);
  9385. else
  9386. hRes = p->ResourceUnregisterSz(pszModule, lpszRes, szType);
  9387. }
  9388. }
  9389. return hRes;
  9390. }
  9391. /////////////////////////////////////////////////////////////////////////////
  9392. // TypeLib Support
  9393. ATLINLINE ATLAPI AtlLoadTypeLib(HINSTANCE hInstTypeLib, LPCOLESTR lpszIndex, BSTR* pbstrPath, ITypeLib** ppTypeLib)
  9394. {
  9395. ATLASSERT(pbstrPath != NULL && ppTypeLib != NULL);
  9396. if (pbstrPath == NULL || ppTypeLib == NULL)
  9397. return E_POINTER;
  9398. *pbstrPath = NULL;
  9399. *ppTypeLib = NULL;
  9400. USES_CONVERSION;
  9401. ATLASSERT(hInstTypeLib != NULL);
  9402. TCHAR szModule[_MAX_PATH+10];
  9403. ATLVERIFY( GetModuleFileName(hInstTypeLib, szModule, _MAX_PATH) != 0 );
  9404. // get the extension pointer in case of fail
  9405. LPTSTR lpszExt = NULL;
  9406. lpszExt = PathFindExtension(szModule);
  9407. if (lpszIndex != NULL)
  9408. lstrcat(szModule, OLE2CT(lpszIndex));
  9409. LPOLESTR lpszModule = T2OLE(szModule);
  9410. HRESULT hr = LoadTypeLib(lpszModule, ppTypeLib);
  9411. if (!SUCCEEDED(hr))
  9412. {
  9413. // typelib not in module, try <module>.tlb instead
  9414. lstrcpy(lpszExt, _T(".tlb"));
  9415. lpszModule = T2OLE(szModule);
  9416. hr = LoadTypeLib(lpszModule, ppTypeLib);
  9417. }
  9418. if (SUCCEEDED(hr))
  9419. {
  9420. *pbstrPath = ::SysAllocString(lpszModule);
  9421. if (*pbstrPath == NULL)
  9422. hr = E_OUTOFMEMORY;
  9423. }
  9424. return hr;
  9425. }
  9426. ATLINLINE ATLAPI AtlUnRegisterTypeLib(HINSTANCE hInstTypeLib, LPCOLESTR lpszIndex)
  9427. {
  9428. CComBSTR bstrPath;
  9429. CComPtr<ITypeLib> pTypeLib;
  9430. HRESULT hr = AtlLoadTypeLib(hInstTypeLib, lpszIndex, &bstrPath, &pTypeLib);
  9431. if (SUCCEEDED(hr))
  9432. {
  9433. TLIBATTR* ptla;
  9434. hr = pTypeLib->GetLibAttr(&ptla);
  9435. if (SUCCEEDED(hr))
  9436. {
  9437. hr = UnRegisterTypeLib(ptla->guid, ptla->wMajorVerNum, ptla->wMinorVerNum, ptla->lcid, ptla->syskind);
  9438. pTypeLib->ReleaseTLibAttr(ptla);
  9439. }
  9440. }
  9441. return hr;
  9442. }
  9443. ATLINLINE ATLAPI AtlRegisterTypeLib(HINSTANCE hInstTypeLib, LPCOLESTR lpszIndex)
  9444. {
  9445. CComBSTR bstrPath;
  9446. CComPtr<ITypeLib> pTypeLib;
  9447. HRESULT hr = AtlLoadTypeLib(hInstTypeLib, lpszIndex, &bstrPath, &pTypeLib);
  9448. if (SUCCEEDED(hr))
  9449. {
  9450. OLECHAR szDir[_MAX_PATH];
  9451. ocscpy(szDir, bstrPath);
  9452. // If index is specified remove it from the path
  9453. if (lpszIndex != NULL)
  9454. {
  9455. size_t nLenPath = ocslen(szDir);
  9456. size_t nLenIndex = ocslen(lpszIndex);
  9457. if (memcmp(szDir + nLenPath - nLenIndex, lpszIndex, nLenIndex) == 0)
  9458. szDir[nLenPath - nLenIndex] = 0;
  9459. }
  9460. szDir[AtlGetDirLen(szDir)] = 0;
  9461. hr = ::RegisterTypeLib(pTypeLib, bstrPath, szDir);
  9462. }
  9463. return hr;
  9464. }
  9465. ATLINLINE ATLAPI_(DWORD) AtlGetVersion(void* /* pReserved */)
  9466. {
  9467. return _ATL_VER;
  9468. }
  9469. ATLINLINE ATLAPI_(void) AtlWinModuleAddCreateWndData(_ATL_WIN_MODULE* pWinModule, _AtlCreateWndData* pData, void* pObject)
  9470. {
  9471. ATLASSERT(pData != NULL && pObject != NULL);
  9472. pData->m_pThis = pObject;
  9473. pData->m_dwThreadID = ::GetCurrentThreadId();
  9474. CComCritSecLock<CComCriticalSection> lock(pWinModule->m_csWindowCreate, false);
  9475. if (FAILED(lock.Lock()))
  9476. {
  9477. ATLTRACE(atlTraceWindowing, 0, _T("ERROR : Unable to lock critical section in AtlWinModuleAddCreateWndData\n"));
  9478. ATLASSERT(0);
  9479. return;
  9480. }
  9481. pData->m_pNext = pWinModule->m_pCreateWndList;
  9482. pWinModule->m_pCreateWndList = pData;
  9483. }
  9484. ATLINLINE ATLAPI_(void*) AtlWinModuleExtractCreateWndData(_ATL_WIN_MODULE* pWinModule)
  9485. {
  9486. void* pv = NULL;
  9487. CComCritSecLock<CComCriticalSection> lock(pWinModule->m_csWindowCreate, false);
  9488. if (FAILED(lock.Lock()))
  9489. {
  9490. ATLTRACE(atlTraceWindowing, 0, _T("ERROR : Unable to lock critical section in AtlWinModuleExtractCreateWndData\n"));
  9491. ATLASSERT(0);
  9492. return pv;
  9493. }
  9494. _AtlCreateWndData* pEntry = pWinModule->m_pCreateWndList;
  9495. if(pEntry != NULL)
  9496. {
  9497. DWORD dwThreadID = ::GetCurrentThreadId();
  9498. _AtlCreateWndData* pPrev = NULL;
  9499. while(pEntry != NULL)
  9500. {
  9501. if(pEntry->m_dwThreadID == dwThreadID)
  9502. {
  9503. if(pPrev == NULL)
  9504. pWinModule->m_pCreateWndList = pEntry->m_pNext;
  9505. else
  9506. pPrev->m_pNext = pEntry->m_pNext;
  9507. pv = pEntry->m_pThis;
  9508. break;
  9509. }
  9510. pPrev = pEntry;
  9511. pEntry = pEntry->m_pNext;
  9512. }
  9513. }
  9514. return pv;
  9515. }
  9516. ATLINLINE ATLAPI AtlWinModuleInit(_ATL_WIN_MODULE* pWinModule)
  9517. {
  9518. // check only in the DLL
  9519. if (pWinModule->cbSize != sizeof(_ATL_WIN_MODULE))
  9520. return E_INVALIDARG;
  9521. pWinModule->m_pCreateWndList = NULL;
  9522. pWinModule->m_nAtomIndex = 0;
  9523. HRESULT hr = pWinModule->m_csWindowCreate.Init();
  9524. if (FAILED(hr))
  9525. {
  9526. ATLTRACE(atlTraceWindowing, 0, _T("ERROR : Unable to initialize critical section in AtlWinModuleInit\n"));
  9527. ATLASSERT(0);
  9528. }
  9529. return hr;
  9530. }
  9531. ATLINLINE ATLAPI AtlWinModuleTerm(_ATL_WIN_MODULE* pWinModule, HINSTANCE hInst)
  9532. {
  9533. // Check only in the DLL
  9534. if (pWinModule->cbSize != sizeof(_ATL_WIN_MODULE))
  9535. return E_INVALIDARG;
  9536. for (int i = 0; i < pWinModule->m_nAtomIndex; i++)
  9537. UnregisterClass((LPCTSTR)pWinModule->m_rgWindowClassAtoms[i], hInst);
  9538. return S_OK;
  9539. }
  9540. /////////////////////////////////////////////////////////////////////////////
  9541. // General DLL Version Helpers
  9542. inline HRESULT AtlGetDllVersion(HINSTANCE hInstDLL, DLLVERSIONINFO* pDllVersionInfo)
  9543. {
  9544. ATLASSERT(!::IsBadWritePtr(pDllVersionInfo, sizeof(DLLVERSIONINFO)));
  9545. // We must get this function explicitly because some DLLs don't implement it.
  9546. DLLGETVERSIONPROC pfnDllGetVersion = (DLLGETVERSIONPROC)::GetProcAddress(hInstDLL, "DllGetVersion");
  9547. if(pfnDllGetVersion == NULL)
  9548. return E_NOTIMPL;
  9549. return (*pfnDllGetVersion)(pDllVersionInfo);
  9550. }
  9551. inline HRESULT AtlGetDllVersion(LPCTSTR lpstrDllName, DLLVERSIONINFO* pDllVersionInfo)
  9552. {
  9553. HINSTANCE hInstDLL = ::LoadLibrary(lpstrDllName);
  9554. if(hInstDLL == NULL)
  9555. return AtlHresultFromLastError();
  9556. HRESULT hRet = AtlGetDllVersion(hInstDLL, pDllVersionInfo);
  9557. ::FreeLibrary(hInstDLL);
  9558. return hRet;
  9559. }
  9560. // Common Control Versions:
  9561. // Win95/WinNT 4.0 maj=4 min=00
  9562. // IE 3.x maj=4 min=70
  9563. // IE 4.0 maj=4 min=71
  9564. // IE 5.0 maj=5 min=80
  9565. // Win2000 maj=5 min=81
  9566. inline HRESULT AtlGetCommCtrlVersion(LPDWORD pdwMajor, LPDWORD pdwMinor)
  9567. {
  9568. ATLASSERT(!::IsBadWritePtr(pdwMajor, sizeof(DWORD)) && !::IsBadWritePtr(pdwMinor, sizeof(DWORD)));
  9569. DLLVERSIONINFO dvi;
  9570. memset(&dvi, 0, sizeof(dvi));
  9571. dvi.cbSize = sizeof(dvi);
  9572. HRESULT hRet = AtlGetDllVersion(_T("comctl32.dll"), &dvi);
  9573. if(SUCCEEDED(hRet))
  9574. {
  9575. *pdwMajor = dvi.dwMajorVersion;
  9576. *pdwMinor = dvi.dwMinorVersion;
  9577. }
  9578. else if(hRet == E_NOTIMPL)
  9579. {
  9580. // If DllGetVersion is not there, then the DLL is a version
  9581. // previous to the one shipped with IE 3.x
  9582. *pdwMajor = 4;
  9583. *pdwMinor = 0;
  9584. hRet = S_OK;
  9585. }
  9586. return hRet;
  9587. }
  9588. // Shell Versions:
  9589. // Win95/WinNT 4.0 maj=4 min=00
  9590. // IE 3.x, IE 4.0 without Web Integrated Desktop maj=4 min=00
  9591. // IE 4.0 with Web Integrated Desktop maj=4 min=71
  9592. // IE 4.01 with Web Integrated Desktop maj=4 min=72
  9593. // Win2000 maj=5 min=00
  9594. inline HRESULT AtlGetShellVersion(LPDWORD pdwMajor, LPDWORD pdwMinor)
  9595. {
  9596. ATLASSERT(!::IsBadWritePtr(pdwMajor, sizeof(DWORD)) && !::IsBadWritePtr(pdwMinor, sizeof(DWORD)));
  9597. DLLVERSIONINFO dvi;
  9598. memset(&dvi, 0, sizeof(dvi));
  9599. dvi.cbSize = sizeof(dvi);
  9600. HRESULT hRet = AtlGetDllVersion(_T("shell32.dll"), &dvi);
  9601. if(SUCCEEDED(hRet))
  9602. {
  9603. *pdwMajor = dvi.dwMajorVersion;
  9604. *pdwMinor = dvi.dwMinorVersion;
  9605. }
  9606. else if(hRet == E_NOTIMPL)
  9607. {
  9608. // If DllGetVersion is not there, then the DLL is a version
  9609. // previous to the one shipped with IE 4.x
  9610. *pdwMajor = 4;
  9611. *pdwMinor = 0;
  9612. hRet = S_OK;
  9613. }
  9614. return hRet;
  9615. }
  9616. }; //namespace ATL
  9617. #endif // _ATLBASE_IMPL
  9618. #pragma warning( pop )
  9619. #ifdef _ATL_ALL_WARNINGS
  9620. #pragma warning( pop )
  9621. #endif
  9622. /////////////////////////////////////////////////////////////////////////////
  9623. #endif // __ATLBASE_H__