home *** CD-ROM | disk | FTP | other *** search
/ Magazyn Internet 2000 May / MICD_2000_05.iso / CBuilder5 / INSTALL / DATA1.CAB / Program_Built_Files / Include / Atl / atlbase.h next >
Encoding:
C/C++ Source or Header  |  2000-02-01  |  139.2 KB  |  6,257 lines

  1. // This is a part of the Active Template Library.
  2. // Copyright (C) 1996-1998 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.  
  11. #ifndef __ATLBASE_H__
  12. #define __ATLBASE_H__
  13.  
  14. #ifndef __cplusplus
  15.     #error ATL requires C++ compilation (use a .cpp suffix)
  16. #endif
  17.  
  18. #ifdef __BORLANDC__
  19. #ifdef _BCB_ATL_DEBUG
  20. #define _DEBUG
  21. #endif
  22. #pragma comment(lib, "bcbatl.lib")
  23. #define _ATL_NO_FORCE_LIBS        // Eliminate #pragma comment(lib, xxxx)
  24. #ifdef USING_ATLVCL
  25. #define _ATL_NO_DEBUG_CRT         // avoid including (CRTDBG.H). Needed functions are defined in UTILCLS.H
  26. #endif // USING_ATLVCL
  27. #endif // __BORLANDC__
  28.  
  29.  
  30. #ifndef _ATL_NO_PRAGMA_WARNINGS
  31. #pragma warning(disable: 4201) // nameless unions are part of C++
  32. #pragma warning(disable: 4127) // constant expression
  33. #pragma warning(disable: 4505) // unreferenced local function has been removed
  34. #pragma warning(disable: 4512) // can't generate assignment operator (so what?)
  35. #pragma warning(disable: 4514) // unreferenced inlines are common
  36. #pragma warning(disable: 4103) // pragma pack
  37. #pragma warning(disable: 4702) // unreachable code
  38. #pragma warning(disable: 4237) // bool
  39. #pragma warning(disable: 4710) // function couldn't be inlined
  40. #pragma warning(disable: 4355) // 'this' : used in base member initializer list
  41. #pragma warning(disable: 4097) // typedef name used as synonym for class-name
  42. #pragma warning(disable: 4786) // identifier was truncated in the debug information
  43. #pragma warning(disable: 4268) // const static/global data initialized to zeros
  44. #pragma warning(disable: 4291) // allow placement new
  45. #ifdef __BORLANDC__
  46. #pragma warn -rch              // unreachable code (break after return in default case)
  47. #pragma warn -ccc              // condition is always true: [enumerated value] & [defined value]
  48. #endif // __BORLANDC__
  49. #endif //!_ATL_NO_PRAGMA_WARNINGS
  50.  
  51. #include "atldef.h"
  52.  
  53. #include <windows.h>
  54. #include <winnls.h>
  55. #include <ole2.h>
  56.  
  57. #include <comcat.h>
  58. #include <stddef.h>
  59.  
  60. #ifdef new
  61. #pragma push_macro("new")
  62. #define _ATL_REDEF_NEW
  63. #undef new
  64. #endif
  65.  
  66. #include <tchar.h>
  67. #include <malloc.h>
  68.  
  69. #ifndef _ATL_NO_DEBUG_CRT
  70. // Warning: if you define the above symbol, you will have
  71. // to provide your own definition of the ATLASSERT(x) macro
  72. // in order to compile ATL
  73.     #include "crtdbg.h"
  74. #endif
  75.  
  76. #include <olectl.h>
  77. #include <winreg.h>
  78. #include "atliface.h"
  79.  
  80. #ifdef _DEBUG
  81. #include <stdio.h>
  82. #include <stdarg.h>
  83. #endif
  84.  
  85. #include "atlconv.h"
  86.  
  87. #include <shlwapi.h>
  88.  
  89. #pragma pack(push, _ATL_PACKING)
  90.  
  91. #ifndef __BORLANDC__
  92. #if defined(_ATL_DLL)
  93.     #pragma comment(lib, "atl.lib")
  94. #endif
  95. #endif
  96.  
  97. #ifndef __BORLANDC__
  98. extern "C" const __declspec(selectany) GUID LIBID_ATLLib = {0x44EC0535,0x400F,0x11D0,{0x9D,0xCD,0x00,0xA0,0xC9,0x03,0x91,0xD3}};
  99. extern "C" const __declspec(selectany) CLSID CLSID_Registrar = {0x44EC053A,0x400F,0x11D0,{0x9D,0xCD,0x00,0xA0,0xC9,0x03,0x91,0xD3}};
  100. extern "C" const __declspec(selectany) IID IID_IRegistrar = {0x44EC053B,0x400F,0x11D0,{0x9D,0xCD,0x00,0xA0,0xC9,0x03,0x91,0xD3}};
  101. extern "C" const __declspec(selectany) IID IID_IAxWinHostWindow = {0xb6ea2050,0x48a,0x11d1,{0x82,0xb9,0x0,0xc0,0x4f,0xb9,0x94,0x2e}};
  102. extern "C" const __declspec(selectany) IID IID_IAxWinAmbientDispatch = {0xb6ea2051,0x48a,0x11d1,{0x82,0xb9,0x0,0xc0,0x4f,0xb9,0x94,0x2e}};
  103. extern "C" const __declspec(selectany) IID IID_IInternalConnection = {0x72AD0770,0x6A9F,0x11d1,{0xBC,0xEC,0x00,0x60,0x08,0x8F,0x44,0x4E}};
  104. extern "C" const __declspec(selectany) IID IID_IDocHostUIHandlerDispatch = {0x425B5AF0,0x65F1,0x11d1,{0x96,0x11,0x00,0x00,0xF8,0x1E,0x0D,0x0D}};
  105. #else
  106. extern "C" const GUID LIBID_ATLLib;
  107. extern "C" const CLSID CLSID_Registrar;
  108. extern "C" const IID IID_IRegistrar;
  109. extern "C" const IID IID_IAxWinHostWindow;
  110. extern "C" const IID IID_IAxWinAmbientDispatch;
  111. extern "C" const IID IID_IInternalConnection;
  112. extern "C" const IID IID_IDocHostUIHandlerDispatch;
  113. #endif
  114.  
  115.  
  116. #ifndef _ATL_DLL_IMPL
  117. namespace ATL
  118. {
  119. #endif
  120.  
  121. struct _ATL_CATMAP_ENTRY
  122. {
  123.    int iType;
  124.    const CATID* pcatid;
  125. };
  126.  
  127. #define _ATL_CATMAP_ENTRY_END 0
  128. #define _ATL_CATMAP_ENTRY_IMPLEMENTED 1
  129. #define _ATL_CATMAP_ENTRY_REQUIRED 2
  130.  
  131. typedef HRESULT (WINAPI _ATL_CREATORFUNC)(void* pv, REFIID riid, LPVOID* ppv);
  132. typedef HRESULT (WINAPI _ATL_CREATORARGFUNC)(void* pv, REFIID riid, LPVOID* ppv, DWORD dw);
  133. typedef HRESULT (WINAPI _ATL_MODULEFUNC)(DWORD dw);
  134. typedef LPCTSTR (WINAPI _ATL_DESCRIPTIONFUNC)();
  135. typedef const struct _ATL_CATMAP_ENTRY* (_ATL_CATMAPFUNC)();
  136. typedef void (__stdcall _ATL_TERMFUNC)(DWORD dw);
  137.  
  138. struct _ATL_TERMFUNC_ELEM
  139. {
  140.     _ATL_TERMFUNC* pFunc;
  141.     DWORD dw;
  142.     _ATL_TERMFUNC_ELEM* pNext;
  143. };
  144.  
  145. struct _ATL_OBJMAP_ENTRY
  146. {
  147.     const CLSID* pclsid;
  148.     HRESULT (WINAPI *pfnUpdateRegistry)(BOOL bRegister);
  149.     _ATL_CREATORFUNC* pfnGetClassObject;
  150.     _ATL_CREATORFUNC* pfnCreateInstance;
  151.     IUnknown* pCF;
  152.     DWORD dwRegister;
  153.     _ATL_DESCRIPTIONFUNC* pfnGetObjectDescription;
  154.     _ATL_CATMAPFUNC* pfnGetCategoryMap;
  155.     HRESULT WINAPI RevokeClassObject()
  156.     {
  157.         return CoRevokeClassObject(dwRegister);
  158.     }
  159.     HRESULT WINAPI RegisterClassObject(DWORD dwClsContext, DWORD dwFlags)
  160.     {
  161.         IUnknown* p = NULL;
  162.         if (pfnGetClassObject == NULL)
  163.             return S_OK;
  164.         HRESULT hRes = pfnGetClassObject(pfnCreateInstance, IID_IUnknown, (LPVOID*) &p);
  165.         if (SUCCEEDED(hRes))
  166.             hRes = CoRegisterClassObject(*pclsid, p, dwClsContext, dwFlags, &dwRegister);
  167.         if (p != NULL)
  168.             p->Release();
  169.         return hRes;
  170.     }
  171. // Added in ATL 3.0
  172.     void (WINAPI *pfnObjectMain)(bool bStarting);
  173. };
  174.  
  175. struct _ATL_REGMAP_ENTRY
  176. {
  177.     LPCOLESTR     szKey;
  178.     LPCOLESTR     szData;
  179. };
  180.  
  181. struct _AtlCreateWndData
  182. {
  183.     void* m_pThis;
  184.     DWORD m_dwThreadID;
  185.     _AtlCreateWndData* m_pNext;
  186. };
  187.  
  188. struct _ATL_MODULE
  189. {
  190. // Attributes
  191. public:
  192.     UINT cbSize;
  193.     HINSTANCE m_hInst;
  194.     HINSTANCE m_hInstResource;
  195.     HINSTANCE m_hInstTypeLib;
  196.     _ATL_OBJMAP_ENTRY* m_pObjMap;
  197.     LONG m_nLockCnt;
  198.     HANDLE m_hHeap;
  199.     union
  200.     {
  201.         CRITICAL_SECTION m_csTypeInfoHolder;
  202.         CRITICAL_SECTION m_csStaticDataInit;
  203.     };
  204.     CRITICAL_SECTION m_csWindowCreate;
  205.     CRITICAL_SECTION m_csObjMap;
  206. // Original Size = 100
  207. // Stuff added in ATL 3.0
  208.     DWORD dwAtlBuildVer;
  209.     _AtlCreateWndData* m_pCreateWndList;
  210.     bool m_bDestroyHeap;
  211.     GUID* pguidVer;
  212.     DWORD m_dwHeaps;    // Number of heaps we have (-1)
  213.     HANDLE* m_phHeaps;
  214.     int m_nHeap;        // Which heap to choose from
  215.     _ATL_TERMFUNC_ELEM* m_pTermFuncs;
  216. };
  217.  
  218. const int _nAtlModuleVer1Size = 100;
  219.  
  220. //This define makes debugging asserts easier.
  221. #define _ATL_SIMPLEMAPENTRY ((_ATL_CREATORARGFUNC*)1)
  222.  
  223. struct _ATL_INTMAP_ENTRY
  224. {
  225.     const IID* piid;       // the interface id (IID)
  226.     DWORD dw;
  227.     _ATL_CREATORARGFUNC* pFunc; //NULL:end, 1:offset, n:ptr
  228. };
  229.  
  230. /////////////////////////////////////////////////////////////////////////////
  231. // QI Support
  232.  
  233. ATLAPI AtlInternalQueryInterface(void* pThis,
  234.     const _ATL_INTMAP_ENTRY* pEntries, REFIID iid, void** ppvObject);
  235.  
  236. /////////////////////////////////////////////////////////////////////////////
  237. // Smart Pointer helpers
  238.  
  239. ATLAPI_(IUnknown*) AtlComPtrAssign(IUnknown** pp, IUnknown* lp);
  240. ATLAPI_(IUnknown*) AtlComQIPtrAssign(IUnknown** pp, IUnknown* lp, REFIID riid);
  241.  
  242. /////////////////////////////////////////////////////////////////////////////
  243. // Inproc Marshaling helpers
  244.  
  245. ATLAPI AtlFreeMarshalStream(IStream* pStream);
  246. ATLAPI AtlMarshalPtrInProc(IUnknown* pUnk, const IID& iid, IStream** ppStream);
  247. ATLAPI AtlUnmarshalPtr(IStream* pStream, const IID& iid, IUnknown** ppUnk);
  248.  
  249. ATLAPI_(BOOL) AtlWaitWithMessageLoop(HANDLE hEvent);
  250.  
  251. /////////////////////////////////////////////////////////////////////////////
  252. // Connection Point Helpers
  253.  
  254. ATLAPI AtlAdvise(IUnknown* pUnkCP, IUnknown* pUnk, const IID& iid, LPDWORD pdw);
  255. ATLAPI AtlUnadvise(IUnknown* pUnkCP, const IID& iid, DWORD dw);
  256.  
  257. /////////////////////////////////////////////////////////////////////////////
  258. // IDispatch Error handling
  259.  
  260. ATLAPI AtlSetErrorInfo(const CLSID& clsid, LPCOLESTR lpszDesc,
  261.     DWORD dwHelpID, LPCOLESTR lpszHelpFile, const IID& iid, HRESULT hRes,
  262.     HINSTANCE hInst);
  263.  
  264. /////////////////////////////////////////////////////////////////////////////
  265. // Module
  266.  
  267. ATLAPI AtlModuleRegisterClassObjects(_ATL_MODULE* pM, DWORD dwClsContext, DWORD dwFlags);
  268. ATLAPI AtlModuleRevokeClassObjects(_ATL_MODULE* pM);
  269. ATLAPI AtlModuleGetClassObject(_ATL_MODULE* pM, REFCLSID rclsid, REFIID riid, LPVOID* ppv);
  270. ATLAPI AtlModuleRegisterServer(_ATL_MODULE* pM, BOOL bRegTypeLib, const CLSID* pCLSID = NULL);
  271. ATLAPI AtlModuleUnregisterServer(_ATL_MODULE* pM, const CLSID* pCLSID = NULL);
  272. ATLAPI AtlModuleUnregisterServerEx(_ATL_MODULE* pM, BOOL bUnRegTypeLib, const CLSID* pCLSID = NULL);
  273. ATLAPI AtlModuleUpdateRegistryFromResourceD(_ATL_MODULE*pM, LPCOLESTR lpszRes,
  274.     BOOL bRegister, struct _ATL_REGMAP_ENTRY* pMapEntries, IRegistrar* pReg = NULL);
  275. ATLAPI AtlModuleRegisterTypeLib(_ATL_MODULE* pM, LPCOLESTR lpszIndex);
  276. ATLAPI AtlModuleUnRegisterTypeLib(_ATL_MODULE* pM, LPCOLESTR lpszIndex);
  277. ATLAPI AtlModuleLoadTypeLib(_ATL_MODULE* pM, LPCOLESTR lpszIndex, BSTR* pbstrPath, ITypeLib** ppTypeLib);
  278.  
  279. ATLAPI AtlModuleInit(_ATL_MODULE* pM, _ATL_OBJMAP_ENTRY* p, HINSTANCE h);
  280. ATLAPI AtlModuleTerm(_ATL_MODULE* pM);
  281. ATLAPI_(DWORD) AtlGetVersion(void* pReserved);
  282. ATLAPI_(void) AtlModuleAddCreateWndData(_ATL_MODULE* pM, _AtlCreateWndData* pData, void* pObject);
  283. ATLAPI_(void*) AtlModuleExtractCreateWndData(_ATL_MODULE* pM);
  284. ATLAPI AtlModuleAddTermFunc(_ATL_MODULE* pM, _ATL_TERMFUNC* pFunc, DWORD dw);
  285.  
  286.  
  287. #ifndef _ATL_DLL_IMPL
  288. }; //namespace ATL
  289. #endif
  290.  
  291. namespace ATL
  292. {
  293.  
  294. enum atlTraceFlags
  295. {
  296.     // Application defined categories
  297.     atlTraceUser        = 0x00000001,
  298.     atlTraceUser2       = 0x00000002,
  299.     atlTraceUser3       = 0x00000004,
  300.     atlTraceUser4       = 0x00000008,
  301.     // ATL defined categories
  302.     atlTraceGeneral     = 0x00000020,
  303.     atlTraceCOM         = 0x00000040,
  304.     atlTraceQI      = 0x00000080,
  305.     atlTraceRegistrar   = 0x00000100,
  306.     atlTraceRefcount    = 0x00000200,
  307.     atlTraceWindowing   = 0x00000400,
  308.     atlTraceControls    = 0x00000800,
  309.     atlTraceHosting     = 0x00001000,
  310.     atlTraceDBClient    = 0x00002000,
  311.     atlTraceDBProvider  = 0x00004000,
  312.     atlTraceSnapin      = 0x00008000,
  313.     atlTraceNotImpl     = 0x00010000,
  314. };
  315.  
  316. #ifndef ATL_TRACE_CATEGORY
  317. #define ATL_TRACE_CATEGORY 0xFFFFFFFF
  318. #endif
  319.  
  320. #ifdef _DEBUG
  321.  
  322. #ifndef ATL_TRACE_LEVEL
  323. #define ATL_TRACE_LEVEL 0
  324. #endif
  325.  
  326. inline void _cdecl AtlTrace(LPCSTR lpszFormat, ...)
  327. {
  328.     va_list args;
  329.     va_start(args, lpszFormat);
  330.  
  331.     int nBuf;
  332.     char szBuffer[512];
  333.  
  334.     nBuf = _vsnprintf(szBuffer, sizeof(szBuffer), lpszFormat, args);
  335.     ATLASSERT(nBuf < sizeof(szBuffer)); //Output truncated as it was > sizeof(szBuffer)
  336.  
  337.     OutputDebugStringA(szBuffer);
  338.     va_end(args);
  339. }
  340. inline void _cdecl AtlTrace2(DWORD category, UINT level, LPCSTR lpszFormat, ...)
  341. {
  342.     if (category & ATL_TRACE_CATEGORY && level <= ATL_TRACE_LEVEL)
  343.     {
  344.         va_list args;
  345.         va_start(args, lpszFormat);
  346.  
  347.         int nBuf;
  348.         char szBuffer[512];
  349.  
  350.         nBuf = _vsnprintf(szBuffer, sizeof(szBuffer), lpszFormat, args);
  351.         ATLASSERT(nBuf < sizeof(szBuffer)); //Output truncated as it was > sizeof(szBuffer)
  352.  
  353.         OutputDebugStringA("ATL: ");
  354.         OutputDebugStringA(szBuffer);
  355.         va_end(args);
  356.     }
  357. }
  358. #ifndef OLE2ANSI
  359. inline void _cdecl AtlTrace(LPCWSTR lpszFormat, ...)
  360. {
  361.     va_list args;
  362.     va_start(args, lpszFormat);
  363.  
  364.     int nBuf;
  365.     WCHAR szBuffer[512];
  366.  
  367.     nBuf = _vsnwprintf(szBuffer, sizeof(szBuffer) / sizeof(WCHAR), lpszFormat, args);
  368.     ATLASSERT(nBuf < sizeof(szBuffer));//Output truncated as it was > sizeof(szBuffer)
  369.  
  370.     OutputDebugStringW(szBuffer);
  371.     va_end(args);
  372. }
  373. inline void _cdecl AtlTrace2(DWORD category, UINT level, LPCWSTR lpszFormat, ...)
  374. {
  375.     if (category & ATL_TRACE_CATEGORY && level <= ATL_TRACE_LEVEL)
  376.     {
  377.         va_list args;
  378.         va_start(args, lpszFormat);
  379.  
  380.         int nBuf;
  381.         WCHAR szBuffer[512];
  382.  
  383.         nBuf = _vsnwprintf(szBuffer, sizeof(szBuffer) / sizeof(WCHAR), lpszFormat, args);
  384.         ATLASSERT(nBuf < sizeof(szBuffer));//Output truncated as it was > sizeof(szBuffer)
  385.  
  386.         OutputDebugStringW(L"ATL: ");
  387.         OutputDebugStringW(szBuffer);
  388.         va_end(args);
  389.     }
  390. }
  391. #endif //!OLE2ANSI
  392.  
  393.  
  394. #ifndef ATLTRACE
  395. #define ATLTRACE            AtlTrace
  396. #define ATLTRACE2           AtlTrace2
  397. #endif
  398. #define ATLTRACENOTIMPL(funcname)   ATLTRACE2(atlTraceNotImpl, 2, _T("ATL: %s not implemented.\n"), funcname); return E_NOTIMPL
  399. #else // !DEBUG
  400. inline void _cdecl AtlTrace(LPCSTR , ...){}
  401. inline void _cdecl AtlTrace2(DWORD, UINT, LPCSTR , ...){}
  402. #ifndef OLE2ANSI
  403. inline void _cdecl AtlTrace(LPCWSTR , ...){}
  404. inline void _cdecl AtlTrace2(DWORD, UINT, LPCWSTR , ...){}
  405. #endif //OLE2ANSI
  406. #ifndef ATLTRACE
  407. #define ATLTRACE            1 ? (void)0 : AtlTrace
  408. #define ATLTRACE2           1 ? (void)0 : AtlTrace2
  409. #endif //ATLTRACE
  410. #define ATLTRACENOTIMPL(funcname)   return E_NOTIMPL
  411. #endif //_DEBUG
  412.  
  413.  
  414.  
  415.  
  416.  
  417. /////////////////////////////////////////////////////////////////////////////
  418. // Win32 libraries
  419.  
  420. #ifndef __BORLANDC__
  421. #pragma comment(lib, "kernel32.lib")
  422. #pragma comment(lib, "user32.lib")
  423. #pragma comment(lib, "olepro32.lib")
  424. #pragma comment(lib, "advapi32.lib")
  425. #pragma comment(lib, "ole32.lib")
  426. #pragma comment(lib, "oleaut32.lib")
  427. #pragma comment(lib, "uuid.lib")
  428. #endif
  429.  
  430. #ifndef __BORLANDC__
  431. static HRESULT AtlSetChildSite(IUnknown* punkChild, IUnknown* punkParent)
  432. {
  433.     if (punkChild == NULL)
  434.         return E_POINTER;
  435.  
  436.     HRESULT hr;
  437.     IObjectWithSite* pChildSite = NULL;
  438.     hr = punkChild->QueryInterface(IID_IObjectWithSite, (void**)&pChildSite);
  439.     if (SUCCEEDED(hr) && pChildSite != NULL)
  440.     {
  441.         hr = pChildSite->SetSite(punkParent);
  442.         pChildSite->Release();
  443.     }
  444.     return hr;
  445. }
  446. #else
  447. extern HRESULT AtlSetChildSite(IUnknown* punkChild, IUnknown* punkParent);
  448. #endif
  449.  
  450. template <class T>
  451. class _NoAddRefReleaseOnCComPtr : public T
  452. {
  453.     private:
  454.         STDMETHOD_(ULONG, AddRef)()=0;
  455.         STDMETHOD_(ULONG, Release)()=0;
  456. };
  457.  
  458. template <class T>
  459. class CComPtr
  460. {
  461. public:
  462.     typedef T _PtrClass;
  463.     CComPtr()
  464.     {
  465.         p=NULL;
  466.     }
  467.     CComPtr(T* lp)
  468.     {
  469.         if ((p = lp) != NULL)
  470.             p->AddRef();
  471.     }
  472.     CComPtr(const CComPtr<T>& lp)
  473.     {
  474.         if ((p = lp.p) != NULL)
  475.             p->AddRef();
  476.     }
  477.     ~CComPtr()
  478.     {
  479.         if (p)
  480.             p->Release();
  481.     }
  482.     void Release()
  483.     {
  484.         IUnknown* pTemp = p;
  485.         if (pTemp)
  486.         {
  487.             p = NULL;
  488.             pTemp->Release();
  489.         }
  490.     }
  491.     operator T*() const
  492.     {
  493.         return (T*)p;
  494.     }
  495.     T& operator*() const
  496.     {
  497.         ATLASSERT(p!=NULL);
  498.         return *p;
  499.     }
  500.     //The assert on operator& usually indicates a bug.  If this is really
  501.     //what is needed, however, take the address of the p member explicitly.
  502.     T** operator&()
  503.     {
  504.         ATLASSERT(p==NULL);
  505.         return &p;
  506.     }
  507.     _NoAddRefReleaseOnCComPtr<T>* operator->() const
  508.     {
  509.         ATLASSERT(p!=NULL);
  510.         return (_NoAddRefReleaseOnCComPtr<T>*)p;
  511.     }
  512.     T* operator=(T* lp)
  513.     {
  514.         return (T*)AtlComPtrAssign((IUnknown**)&p, lp);
  515.     }
  516.     T* operator=(const CComPtr<T>& lp)
  517.     {
  518.         return (T*)AtlComPtrAssign((IUnknown**)&p, lp.p);
  519.     }
  520.     bool operator!() const
  521.     {
  522.         return (p == NULL);
  523.     }
  524.     bool operator<(T* pT) const
  525.     {
  526.         return p < pT;
  527.     }
  528.     bool operator==(T* pT) const
  529.     {
  530.         return p == pT;
  531.     }
  532.     // Compare two objects for equivalence
  533.     bool IsEqualObject(IUnknown* pOther)
  534.     {
  535.         if (p == NULL && pOther == NULL)
  536.             return true; // They are both NULL objects
  537.  
  538.         if (p == NULL || pOther == NULL)
  539.             return false; // One is NULL the other is not
  540.  
  541.         CComPtr<IUnknown> punk1;
  542.         CComPtr<IUnknown> punk2;
  543.         p->QueryInterface(IID_IUnknown, (void**)&punk1);
  544.         pOther->QueryInterface(IID_IUnknown, (void**)&punk2);
  545.         return punk1 == punk2;
  546.     }
  547.     void Attach(T* p2)
  548.     {
  549.         if (p)
  550.             p->Release();
  551.         p = p2;
  552.     }
  553.     T* Detach()
  554.     {
  555.         T* pt = p;
  556.         p = NULL;
  557.         return pt;
  558.     }
  559.     HRESULT CopyTo(T** ppT)
  560.     {
  561.         ATLASSERT(ppT != NULL);
  562.         if (ppT == NULL)
  563.             return E_POINTER;
  564.         *ppT = p;
  565.         if (p)
  566.             p->AddRef();
  567.         return S_OK;
  568.     }
  569.     HRESULT SetSite(IUnknown* punkParent)
  570.     {
  571.         return AtlSetChildSite(p, punkParent);
  572.     }
  573.     HRESULT Advise(IUnknown* pUnk, const IID& iid, LPDWORD pdw)
  574.     {
  575.         return AtlAdvise(p, pUnk, iid, pdw);
  576.     }
  577.     HRESULT CoCreateInstance(REFCLSID rclsid, LPUNKNOWN pUnkOuter = NULL, DWORD dwClsContext = CLSCTX_ALL)
  578.     {
  579.         ATLASSERT(p == NULL);
  580.         return ::CoCreateInstance(rclsid, pUnkOuter, dwClsContext, __uuidof(T), (void**)&p);
  581.     }
  582.     HRESULT CoCreateInstance(LPCOLESTR szProgID, LPUNKNOWN pUnkOuter = NULL, DWORD dwClsContext = CLSCTX_ALL)
  583.     {
  584.         CLSID clsid;
  585.         HRESULT hr = CLSIDFromProgID(szProgID, &clsid);
  586.         ATLASSERT(p == NULL);
  587.         if (SUCCEEDED(hr))
  588.             hr = ::CoCreateInstance(clsid, pUnkOuter, dwClsContext, __uuidof(T), (void**)&p);
  589.         return hr;
  590.     }
  591.     template <class Q>
  592.     HRESULT QueryInterface(Q** pp) const
  593.     {
  594.         ATLASSERT(pp != NULL && *pp == NULL);
  595.         return p->QueryInterface(__uuidof(Q), (void**)pp);
  596.     }
  597.     T* p;
  598. };
  599.  
  600.  
  601. template <class T, const IID* piid = &__uuidof(T)>
  602. class CComQIPtr
  603. {
  604. public:
  605.     typedef T _PtrClass;
  606.     CComQIPtr()
  607.     {
  608.         p=NULL;
  609.     }
  610.     CComQIPtr(T* lp)
  611.     {
  612.         if ((p = lp) != NULL)
  613.             p->AddRef();
  614.     }
  615.     CComQIPtr(const CComQIPtr<T,piid>& lp)
  616.     {
  617.         if ((p = lp.p) != NULL)
  618.             p->AddRef();
  619.     }
  620.     CComQIPtr(IUnknown* lp)
  621.     {
  622.         p=NULL;
  623.         if (lp != NULL)
  624.             lp->QueryInterface(*piid, (void **)&p);
  625.     }
  626.     ~CComQIPtr()
  627.     {
  628.         if (p)
  629.             p->Release();
  630.     }
  631.     void Release()
  632.     {
  633.         IUnknown* pTemp = p;
  634.         if (pTemp)
  635.         {
  636.             p = NULL;
  637.             pTemp->Release();
  638.         }
  639.     }
  640.     operator T*() const
  641.     {
  642.         return p;
  643.     }
  644.     T& operator*() const
  645.     {
  646.         ATLASSERT(p!=NULL); return *p;
  647.     }
  648.     //The assert on operator& usually indicates a bug.  If this is really
  649.     //what is needed, however, take the address of the p member explicitly.
  650.     T** operator&()
  651.     {
  652.         ATLASSERT(p==NULL);
  653.         return &p;
  654.     }
  655.     _NoAddRefReleaseOnCComPtr<T>* operator->() const
  656.     {
  657.         ATLASSERT(p!=NULL);
  658.         return (_NoAddRefReleaseOnCComPtr<T>*)p;
  659.     }
  660.     T* operator=(T* lp)
  661.     {
  662.         return (T*)AtlComPtrAssign((IUnknown**)&p, lp);
  663.     }
  664.     T* operator=(const CComQIPtr<T,piid>& lp)
  665.     {
  666.         return (T*)AtlComPtrAssign((IUnknown**)&p, lp.p);
  667.     }
  668.     T* operator=(IUnknown* lp)
  669.     {
  670.         return (T*)AtlComQIPtrAssign((IUnknown**)&p, lp, *piid);
  671.     }
  672.     bool operator!() const
  673.     {
  674.         return (p == NULL);
  675.     }
  676.     bool operator<(T* pT) const
  677.     {
  678.         return p < pT;
  679.     }
  680.     bool operator==(T* pT) const
  681.     {
  682.         return p == pT;
  683.     }
  684.     // Compare two objects for equivalence
  685.     bool IsEqualObject(IUnknown* pOther)
  686.     {
  687.         if (p == NULL && pOther == NULL)
  688.             return true; // They are both NULL objects
  689.  
  690.         if (p == NULL || pOther == NULL)
  691.             return false; // One is NULL the other is not
  692.  
  693.         CComPtr<IUnknown> punk1;
  694.         CComPtr<IUnknown> punk2;
  695.         p->QueryInterface(IID_IUnknown, (void**)&punk1);
  696.         pOther->QueryInterface(IID_IUnknown, (void**)&punk2);
  697.         return punk1 == punk2;
  698.     }
  699.     void Attach(T* p2)
  700.     {
  701.         if (p)
  702.             p->Release();
  703.         p = p2;
  704.     }
  705.     T* Detach()
  706.     {
  707.         T* pt = p;
  708.         p = NULL;
  709.         return pt;
  710.     }
  711.     HRESULT CopyTo(T** ppT)
  712.     {
  713.         ATLASSERT(ppT != NULL);
  714.         if (ppT == NULL)
  715.             return E_POINTER;
  716.         *ppT = p;
  717.         if (p)
  718.             p->AddRef();
  719.         return S_OK;
  720.     }
  721.     HRESULT SetSite(IUnknown* punkParent)
  722.     {
  723.         return AtlSetChildSite(p, punkParent);
  724.     }
  725.     HRESULT Advise(IUnknown* pUnk, const IID& iid, LPDWORD pdw)
  726.     {
  727.         return AtlAdvise(p, pUnk, iid, pdw);
  728.     }
  729.     HRESULT CoCreateInstance(REFCLSID rclsid, LPUNKNOWN pUnkOuter = NULL, DWORD dwClsContext = CLSCTX_ALL)
  730.     {
  731.         ATLASSERT(p == NULL);
  732.         return ::CoCreateInstance(rclsid, pUnkOuter, dwClsContext, __uuidof(T), (void**)&p);
  733.     }
  734.     HRESULT CoCreateInstance(LPCOLESTR szProgID, LPUNKNOWN pUnkOuter = NULL, DWORD dwClsContext = CLSCTX_ALL)
  735.     {
  736.         CLSID clsid;
  737.         HRESULT hr = CLSIDFromProgID(szProgID, &clsid);
  738.         ATLASSERT(p == NULL);
  739.         if (SUCCEEDED(hr))
  740.             hr = ::CoCreateInstance(clsid, pUnkOuter, dwClsContext, __uuidof(T), (void**)&p);
  741.         return hr;
  742.     }
  743.     template <class Q>
  744.     HRESULT QueryInterface(Q** pp)
  745.     {
  746.         ATLASSERT(pp != NULL && *pp == NULL);
  747.         return p->QueryInterface(__uuidof(Q), (void**)pp);
  748.     }
  749.     T* p;
  750. };
  751.  
  752. #if !defined(__BORLANDC__) // MS_BUG
  753. //Specialization to make it work
  754. template<>
  755. class CComQIPtr<IUnknown, &IID_IUnknown>
  756. {
  757. public:
  758.     typedef IUnknown _PtrClass;
  759.     CComQIPtr()
  760.     {
  761.         p=NULL;
  762.     }
  763.     CComQIPtr(IUnknown* lp)
  764.     {
  765.         //Actually do a QI to get identity
  766.         p=NULL;
  767.         if (lp != NULL)
  768.             lp->QueryInterface(IID_IUnknown, (void **)&p);
  769.     }
  770.     CComQIPtr(const CComQIPtr<IUnknown,&IID_IUnknown>& lp)
  771.     {
  772.         if ((p = lp.p) != NULL)
  773.             p->AddRef();
  774.     }
  775.     ~CComQIPtr()
  776.     {
  777.         if (p)
  778.             p->Release();
  779.     }
  780.     void Release()
  781.     {
  782.         IUnknown* pTemp = p;
  783.         if (pTemp)
  784.         {
  785.             p = NULL;
  786.             pTemp->Release();
  787.         }
  788.     }
  789.     operator IUnknown*() const
  790.     {
  791.         return p;
  792.     }
  793.     IUnknown& operator*() const
  794.     {
  795.         ATLASSERT(p!=NULL);
  796.         return *p;
  797.     }
  798.     //The assert on operator& usually indicates a bug.  If this is really
  799.     //what is needed, however, take the address of the p member explicitly.
  800.     IUnknown** operator&()
  801.     {
  802.         ATLASSERT(p==NULL);
  803.         return &p;
  804.     }
  805.     _NoAddRefReleaseOnCComPtr<T>* operator->() const
  806.     {
  807.         ATLASSERT(p!=NULL);
  808.         return (_NoAddRefReleaseOnCComPtr<T>*)p;
  809.     }
  810.     IUnknown* operator=(IUnknown* lp)
  811.     {
  812.         //Actually do a QI to get identity
  813.         return (IUnknown*)AtlComQIPtrAssign((IUnknown**)&p, lp, IID_IUnknown);
  814.     }
  815.     IUnknown* operator=(const CComQIPtr<IUnknown,&IID_IUnknown>& lp)
  816.     {
  817.         return (IUnknown*)AtlComPtrAssign((IUnknown**)&p, lp.p);
  818.     }
  819.     bool operator!() const
  820.     {
  821.         return (p == NULL);
  822.     }
  823.     bool operator<(IUnknown* pT) const
  824.     {
  825.         return p < pT;
  826.     }
  827.     bool operator==(IUnknown* pT) const
  828.     {
  829.         return p == pT;
  830.     }
  831.     // Compare two objects for equivalence
  832.     bool IsEqualObject(IUnknown* pOther)
  833.     {
  834.         if (p == NULL && pOther == NULL)
  835.             return true; // They are both NULL objects
  836.  
  837.         if (p == NULL || pOther == NULL)
  838.             return false; // One is NULL the other is not
  839.  
  840.         CComPtr<IUnknown> punk1;
  841.         CComPtr<IUnknown> punk2;
  842.         p->QueryInterface(IID_IUnknown, (void**)&punk1);
  843.         pOther->QueryInterface(IID_IUnknown, (void**)&punk2);
  844.         return punk1 == punk2;
  845.     }
  846.     IUnknown* Detach()
  847.     {
  848.         IUnknown* pt = p;
  849.         p = NULL;
  850.         return pt;
  851.     }
  852.     HRESULT CopyTo(T** ppT)
  853.     {
  854.         ATLASSERT(ppT != NULL);
  855.         if (ppT == NULL)
  856.             return E_POINTER;
  857.         *ppT = p;
  858.         if (p)
  859.             p->AddRef();
  860.         return S_OK;
  861.     }
  862.     HRESULT SetSite(IUnknown* punkParent)
  863.     {
  864.         return AtlSetChildSite(p, punkParent);
  865.     }
  866.     HRESULT Advise(IUnknown* pUnk, const IID& iid, LPDWORD pdw)
  867.     {
  868.         return AtlAdvise(p, pUnk, iid, pdw);
  869.     }
  870.     HRESULT CoCreateInstance(REFCLSID rclsid, LPUNKNOWN pUnkOuter = NULL, DWORD dwClsContext = CLSCTX_ALL)
  871.     {
  872.         ATLASSERT(p == NULL);
  873.         return ::CoCreateInstance(rclsid, pUnkOuter, dwClsContext, __uuidof(T), (void**)&p);
  874.     }
  875.     HRESULT CoCreateInstance(LPCOLESTR szProgID, LPUNKNOWN pUnkOuter = NULL, DWORD dwClsContext = CLSCTX_ALL)
  876.     {
  877.         CLSID clsid;
  878.         HRESULT hr = CLSIDFromProgID(szProgID, &clsid);
  879.         ATLASSERT(p == NULL);
  880.         if (SUCCEEDED(hr))
  881.             hr = ::CoCreateInstance(clsid, pUnkOuter, dwClsContext, __uuidof(T), (void**)&p);
  882.         return hr;
  883.     }
  884.     template <class Q>
  885.     HRESULT QueryInterface(Q** pp)
  886.     {
  887.         ATLASSERT(pp != NULL && *pp == NULL);
  888.         return p->QueryInterface(__uuidof(Q), (void**)pp);
  889.     }
  890.     IUnknown* p;
  891. };
  892. #endif // !defined __BORLANDC__
  893.  
  894. #define com_cast CComQIPtr
  895.  
  896. /////////////////////////////////////////////////////////////
  897. // Class to Adapt CComBSTR and CComPtr for use with STL containers
  898. // the syntax to use it is
  899. // std::vector< CAdapt <CComBSTR> > vect;
  900.  
  901. template <class T>
  902. class CAdapt
  903. {
  904. public:
  905.     CAdapt()
  906.     {
  907.     }
  908.     CAdapt(const T& rSrc)
  909.     {
  910.         m_T = rSrc;
  911.     }
  912.  
  913.     CAdapt(const CAdapt& rSrCA)
  914.     {
  915.         m_T = rSrCA.m_T;
  916.     }
  917.  
  918.     CAdapt& operator=(const T& rSrc)
  919.     {
  920.         m_T = rSrc;
  921.         return *this;
  922.     }
  923.     bool operator<(const T& rSrc) const
  924.     {
  925.         return m_T < rSrc;
  926.     }
  927.     bool operator==(const T& rSrc) const
  928.     {
  929.         return m_T == rSrc;
  930.     }
  931.     operator T&()
  932.     {
  933.         return m_T;
  934.     }
  935.  
  936.     operator const T&() const
  937.     {
  938.         return m_T;
  939.     }
  940.  
  941.     T m_T;
  942. };
  943.  
  944. /////////////////////////////////////////////////////////////////////////////
  945. // GUID comparison
  946.  
  947. #if defined(__BORLANDC__) && defined(_GUIDDEF_H_)
  948.  // don't define this function
  949. #else
  950.  
  951. inline BOOL InlineIsEqualGUID(REFGUID rguid1, REFGUID rguid2)
  952. {
  953.    return (
  954.       ((PLONG) &rguid1)[0] == ((PLONG) &rguid2)[0] &&
  955.       ((PLONG) &rguid1)[1] == ((PLONG) &rguid2)[1] &&
  956.       ((PLONG) &rguid1)[2] == ((PLONG) &rguid2)[2] &&
  957.       ((PLONG) &rguid1)[3] == ((PLONG) &rguid2)[3]);
  958. }
  959. #endif
  960.  
  961. inline BOOL InlineIsEqualUnknown(REFGUID rguid1)
  962. {
  963.    return (
  964.       ((PLONG) &rguid1)[0] == 0 &&
  965.       ((PLONG) &rguid1)[1] == 0 &&
  966. #ifdef _ATL_BYTESWAP
  967.       ((PLONG) &rguid1)[2] == 0xC0000000 &&
  968.       ((PLONG) &rguid1)[3] == 0x00000046);
  969. #else
  970.       ((PLONG) &rguid1)[2] == 0x000000C0 &&
  971.       ((PLONG) &rguid1)[3] == 0x46000000);
  972. #endif
  973. }
  974.  
  975. /////////////////////////////////////////////////////////////////////////////
  976. // Threading Model Support
  977.  
  978. class CComCriticalSection
  979. {
  980. public:
  981.     void Lock() {EnterCriticalSection(&m_sec);}
  982.     void Unlock() {LeaveCriticalSection(&m_sec);}
  983.     void Init() {InitializeCriticalSection(&m_sec);}
  984.     void Term() {DeleteCriticalSection(&m_sec);}
  985.     CRITICAL_SECTION m_sec;
  986. };
  987.  
  988. class CComAutoCriticalSection
  989. {
  990. public:
  991.     void Lock() {EnterCriticalSection(&m_sec);}
  992.     void Unlock() {LeaveCriticalSection(&m_sec);}
  993.     CComAutoCriticalSection() {InitializeCriticalSection(&m_sec);}
  994.     ~CComAutoCriticalSection() {DeleteCriticalSection(&m_sec);}
  995.     CRITICAL_SECTION m_sec;
  996. };
  997.  
  998. class CComFakeCriticalSection
  999. {
  1000. public:
  1001.     void Lock() {}
  1002.     void Unlock() {}
  1003.     void Init() {}
  1004.     void Term() {}
  1005. };
  1006.  
  1007. class CComMultiThreadModelNoCS
  1008. {
  1009. public:
  1010.     static ULONG WINAPI Increment(LPLONG p) {return InterlockedIncrement(p);}
  1011.     static ULONG WINAPI Decrement(LPLONG p) {return InterlockedDecrement(p);}
  1012.     typedef CComFakeCriticalSection AutoCriticalSection;
  1013.     typedef CComFakeCriticalSection CriticalSection;
  1014.     typedef CComMultiThreadModelNoCS ThreadModelNoCS;
  1015. };
  1016.  
  1017. class CComMultiThreadModel
  1018. {
  1019. public:
  1020.     static ULONG WINAPI Increment(LPLONG p) {return InterlockedIncrement(p);}
  1021.     static ULONG WINAPI Decrement(LPLONG p) {return InterlockedDecrement(p);}
  1022.     typedef CComAutoCriticalSection AutoCriticalSection;
  1023.     typedef CComCriticalSection CriticalSection;
  1024.     typedef CComMultiThreadModelNoCS ThreadModelNoCS;
  1025. };
  1026.  
  1027. class CComSingleThreadModel
  1028. {
  1029. public:
  1030.     static ULONG WINAPI Increment(LPLONG p) {return ++(*p);}
  1031.     static ULONG WINAPI Decrement(LPLONG p) {return --(*p);}
  1032.     typedef CComFakeCriticalSection AutoCriticalSection;
  1033.     typedef CComFakeCriticalSection CriticalSection;
  1034.     typedef CComSingleThreadModel ThreadModelNoCS;
  1035. };
  1036.  
  1037. #if defined(_ATL_SINGLE_THREADED)
  1038.     typedef CComSingleThreadModel CComObjectThreadModel;
  1039.     typedef CComSingleThreadModel CComGlobalsThreadModel;
  1040. #elif defined(_ATL_APARTMENT_THREADED)
  1041.     typedef CComSingleThreadModel CComObjectThreadModel;
  1042.     typedef CComMultiThreadModel CComGlobalsThreadModel;
  1043. #else
  1044.     typedef CComMultiThreadModel CComObjectThreadModel;
  1045.     typedef CComMultiThreadModel CComGlobalsThreadModel;
  1046. #endif
  1047.  
  1048. /////////////////////////////////////////////////////////////////////////////
  1049. // CComModule
  1050.  
  1051. #define THREADFLAGS_APARTMENT 0x1
  1052. #define THREADFLAGS_BOTH 0x2
  1053. #define AUTPRXFLAG 0x4
  1054.  
  1055. HRESULT WINAPI AtlDumpIID(REFIID iid, LPCTSTR pszClassName, HRESULT hr);
  1056.  
  1057. #ifdef _ATL_DEBUG_INTERFACES
  1058. struct _QIThunk
  1059. {
  1060.     STDMETHOD(QueryInterface)(REFIID iid, void** pp)
  1061.     {
  1062.         ATLASSERT(m_dwRef >= 0);
  1063.         return pUnk->QueryInterface(iid, pp);
  1064.     }
  1065.     STDMETHOD_(ULONG, AddRef)()
  1066.     {
  1067.         if (bBreak)
  1068.             DebugBreak();
  1069.         pUnk->AddRef();
  1070.         return InternalAddRef();
  1071.     }
  1072.     ULONG InternalAddRef()
  1073.     {
  1074.         if (bBreak)
  1075.             DebugBreak();
  1076.         ATLASSERT(m_dwRef >= 0);
  1077.         long l = InterlockedIncrement(&m_dwRef);
  1078.         ATLTRACE(_T("%d> "), m_dwRef);
  1079.         AtlDumpIID(iid, lpszClassName, S_OK);
  1080.         if (l > m_dwMaxRef)
  1081.             m_dwMaxRef = l;
  1082.         return l;
  1083.     }
  1084.     STDMETHOD_(ULONG, Release)();
  1085.  
  1086.     STDMETHOD(f3)();
  1087.     STDMETHOD(f4)();
  1088.     STDMETHOD(f5)();
  1089.     STDMETHOD(f6)();
  1090.     STDMETHOD(f7)();
  1091.     STDMETHOD(f8)();
  1092.     STDMETHOD(f9)();
  1093.     STDMETHOD(f10)();
  1094.     STDMETHOD(f11)();
  1095.     STDMETHOD(f12)();
  1096.     STDMETHOD(f13)();
  1097.     STDMETHOD(f14)();
  1098.     STDMETHOD(f15)();
  1099.     STDMETHOD(f16)();
  1100.     STDMETHOD(f17)();
  1101.     STDMETHOD(f18)();
  1102.     STDMETHOD(f19)();
  1103.     STDMETHOD(f20)();
  1104.     STDMETHOD(f21)();
  1105.     STDMETHOD(f22)();
  1106.     STDMETHOD(f23)();
  1107.     STDMETHOD(f24)();
  1108.     STDMETHOD(f25)();
  1109.     STDMETHOD(f26)();
  1110.     STDMETHOD(f27)();
  1111.     STDMETHOD(f28)();
  1112.     STDMETHOD(f29)();
  1113.     STDMETHOD(f30)();
  1114.     STDMETHOD(f31)();
  1115.     STDMETHOD(f32)();
  1116.     STDMETHOD(f33)();
  1117.     STDMETHOD(f34)();
  1118.     STDMETHOD(f35)();
  1119.     STDMETHOD(f36)();
  1120.     STDMETHOD(f37)();
  1121.     STDMETHOD(f38)();
  1122.     STDMETHOD(f39)();
  1123.     STDMETHOD(f40)();
  1124.     STDMETHOD(f41)();
  1125.     STDMETHOD(f42)();
  1126.     STDMETHOD(f43)();
  1127.     STDMETHOD(f44)();
  1128.     STDMETHOD(f45)();
  1129.     STDMETHOD(f46)();
  1130.     STDMETHOD(f47)();
  1131.     STDMETHOD(f48)();
  1132.     STDMETHOD(f49)();
  1133.     STDMETHOD(f50)();
  1134.     STDMETHOD(f51)();
  1135.     STDMETHOD(f52)();
  1136.     STDMETHOD(f53)();
  1137.     STDMETHOD(f54)();
  1138.     STDMETHOD(f55)();
  1139.     STDMETHOD(f56)();
  1140.     STDMETHOD(f57)();
  1141.     STDMETHOD(f58)();
  1142.     STDMETHOD(f59)();
  1143.     STDMETHOD(f60)();
  1144.     STDMETHOD(f61)();
  1145.     STDMETHOD(f62)();
  1146.     STDMETHOD(f63)();
  1147.     STDMETHOD(f64)();
  1148.     STDMETHOD(f65)();
  1149.     STDMETHOD(f66)();
  1150.     STDMETHOD(f67)();
  1151.     STDMETHOD(f68)();
  1152.     STDMETHOD(f69)();
  1153.     STDMETHOD(f70)();
  1154.     STDMETHOD(f71)();
  1155.     STDMETHOD(f72)();
  1156.     STDMETHOD(f73)();
  1157.     STDMETHOD(f74)();
  1158.     STDMETHOD(f75)();
  1159.     STDMETHOD(f76)();
  1160.     STDMETHOD(f77)();
  1161.     STDMETHOD(f78)();
  1162.     STDMETHOD(f79)();
  1163.     STDMETHOD(f80)();
  1164.     STDMETHOD(f81)();
  1165.     STDMETHOD(f82)();
  1166.     STDMETHOD(f83)();
  1167.     STDMETHOD(f84)();
  1168.     STDMETHOD(f85)();
  1169.     STDMETHOD(f86)();
  1170.     STDMETHOD(f87)();
  1171.     STDMETHOD(f88)();
  1172.     STDMETHOD(f89)();
  1173.     STDMETHOD(f90)();
  1174.     STDMETHOD(f91)();
  1175.     STDMETHOD(f92)();
  1176.     STDMETHOD(f93)();
  1177.     STDMETHOD(f94)();
  1178.     STDMETHOD(f95)();
  1179.     STDMETHOD(f96)();
  1180.     STDMETHOD(f97)();
  1181.     STDMETHOD(f98)();
  1182.     STDMETHOD(f99)();
  1183.     STDMETHOD(f100)();
  1184.     STDMETHOD(f101)();
  1185.     STDMETHOD(f102)();
  1186.     STDMETHOD(f103)();
  1187.     STDMETHOD(f104)();
  1188.     STDMETHOD(f105)();
  1189.     STDMETHOD(f106)();
  1190.     STDMETHOD(f107)();
  1191.     STDMETHOD(f108)();
  1192.     STDMETHOD(f109)();
  1193.     STDMETHOD(f110)();
  1194.     STDMETHOD(f111)();
  1195.     STDMETHOD(f112)();
  1196.     STDMETHOD(f113)();
  1197.     STDMETHOD(f114)();
  1198.     STDMETHOD(f115)();
  1199.     STDMETHOD(f116)();
  1200.     STDMETHOD(f117)();
  1201.     STDMETHOD(f118)();
  1202.     STDMETHOD(f119)();
  1203.     STDMETHOD(f120)();
  1204.     STDMETHOD(f121)();
  1205.     STDMETHOD(f122)();
  1206.     STDMETHOD(f123)();
  1207.     STDMETHOD(f124)();
  1208.     STDMETHOD(f125)();
  1209.     STDMETHOD(f126)();
  1210.     STDMETHOD(f127)();
  1211.     STDMETHOD(f128)();
  1212.     STDMETHOD(f129)();
  1213.     STDMETHOD(f130)();
  1214.     STDMETHOD(f131)();
  1215.     STDMETHOD(f132)();
  1216.     STDMETHOD(f133)();
  1217.     STDMETHOD(f134)();
  1218.     STDMETHOD(f135)();
  1219.     STDMETHOD(f136)();
  1220.     STDMETHOD(f137)();
  1221.     STDMETHOD(f138)();
  1222.     STDMETHOD(f139)();
  1223.     STDMETHOD(f140)();
  1224.     STDMETHOD(f141)();
  1225.     STDMETHOD(f142)();
  1226.     STDMETHOD(f143)();
  1227.     STDMETHOD(f144)();
  1228.     STDMETHOD(f145)();
  1229.     STDMETHOD(f146)();
  1230.     STDMETHOD(f147)();
  1231.     STDMETHOD(f148)();
  1232.     STDMETHOD(f149)();
  1233.     STDMETHOD(f150)();
  1234.     STDMETHOD(f151)();
  1235.     STDMETHOD(f152)();
  1236.     STDMETHOD(f153)();
  1237.     STDMETHOD(f154)();
  1238.     STDMETHOD(f155)();
  1239.     STDMETHOD(f156)();
  1240.     STDMETHOD(f157)();
  1241.     STDMETHOD(f158)();
  1242.     STDMETHOD(f159)();
  1243.     STDMETHOD(f160)();
  1244.     STDMETHOD(f161)();
  1245.     STDMETHOD(f162)();
  1246.     STDMETHOD(f163)();
  1247.     STDMETHOD(f164)();
  1248.     STDMETHOD(f165)();
  1249.     STDMETHOD(f166)();
  1250.     STDMETHOD(f167)();
  1251.     STDMETHOD(f168)();
  1252.     STDMETHOD(f169)();
  1253.     STDMETHOD(f170)();
  1254.     STDMETHOD(f171)();
  1255.     STDMETHOD(f172)();
  1256.     STDMETHOD(f173)();
  1257.     STDMETHOD(f174)();
  1258.     STDMETHOD(f175)();
  1259.     STDMETHOD(f176)();
  1260.     STDMETHOD(f177)();
  1261.     STDMETHOD(f178)();
  1262.     STDMETHOD(f179)();
  1263.     STDMETHOD(f180)();
  1264.     STDMETHOD(f181)();
  1265.     STDMETHOD(f182)();
  1266.     STDMETHOD(f183)();
  1267.     STDMETHOD(f184)();
  1268.     STDMETHOD(f185)();
  1269.     STDMETHOD(f186)();
  1270.     STDMETHOD(f187)();
  1271.     STDMETHOD(f188)();
  1272.     STDMETHOD(f189)();
  1273.     STDMETHOD(f190)();
  1274.     STDMETHOD(f191)();
  1275.     STDMETHOD(f192)();
  1276.     STDMETHOD(f193)();
  1277.     STDMETHOD(f194)();
  1278.     STDMETHOD(f195)();
  1279.     STDMETHOD(f196)();
  1280.     STDMETHOD(f197)();
  1281.     STDMETHOD(f198)();
  1282.     STDMETHOD(f199)();
  1283.     STDMETHOD(f200)();
  1284.     STDMETHOD(f201)();
  1285.     STDMETHOD(f202)();
  1286.     STDMETHOD(f203)();
  1287.     STDMETHOD(f204)();
  1288.     STDMETHOD(f205)();
  1289.     STDMETHOD(f206)();
  1290.     STDMETHOD(f207)();
  1291.     STDMETHOD(f208)();
  1292.     STDMETHOD(f209)();
  1293.     STDMETHOD(f210)();
  1294.     STDMETHOD(f211)();
  1295.     STDMETHOD(f212)();
  1296.     STDMETHOD(f213)();
  1297.     STDMETHOD(f214)();
  1298.     STDMETHOD(f215)();
  1299.     STDMETHOD(f216)();
  1300.     STDMETHOD(f217)();
  1301.     STDMETHOD(f218)();
  1302.     STDMETHOD(f219)();
  1303.     STDMETHOD(f220)();
  1304.     STDMETHOD(f221)();
  1305.     STDMETHOD(f222)();
  1306.     STDMETHOD(f223)();
  1307.     STDMETHOD(f224)();
  1308.     STDMETHOD(f225)();
  1309.     STDMETHOD(f226)();
  1310.     STDMETHOD(f227)();
  1311.     STDMETHOD(f228)();
  1312.     STDMETHOD(f229)();
  1313.     STDMETHOD(f230)();
  1314.     STDMETHOD(f231)();
  1315.     STDMETHOD(f232)();
  1316.     STDMETHOD(f233)();
  1317.     STDMETHOD(f234)();
  1318.     STDMETHOD(f235)();
  1319.     STDMETHOD(f236)();
  1320.     STDMETHOD(f237)();
  1321.     STDMETHOD(f238)();
  1322.     STDMETHOD(f239)();
  1323.     STDMETHOD(f240)();
  1324.     STDMETHOD(f241)();
  1325.     STDMETHOD(f242)();
  1326.     STDMETHOD(f243)();
  1327.     STDMETHOD(f244)();
  1328.     STDMETHOD(f245)();
  1329.     STDMETHOD(f246)();
  1330.     STDMETHOD(f247)();
  1331.     STDMETHOD(f248)();
  1332.     STDMETHOD(f249)();
  1333.     STDMETHOD(f250)();
  1334.     STDMETHOD(f251)();
  1335.     STDMETHOD(f252)();
  1336.     STDMETHOD(f253)();
  1337.     STDMETHOD(f254)();
  1338.     STDMETHOD(f255)();
  1339.     STDMETHOD(f256)();
  1340.     STDMETHOD(f257)();
  1341.     STDMETHOD(f258)();
  1342.     STDMETHOD(f259)();
  1343.     STDMETHOD(f260)();
  1344.     STDMETHOD(f261)();
  1345.     STDMETHOD(f262)();
  1346.     STDMETHOD(f263)();
  1347.     STDMETHOD(f264)();
  1348.     STDMETHOD(f265)();
  1349.     STDMETHOD(f266)();
  1350.     STDMETHOD(f267)();
  1351.     STDMETHOD(f268)();
  1352.     STDMETHOD(f269)();
  1353.     STDMETHOD(f270)();
  1354.     STDMETHOD(f271)();
  1355.     STDMETHOD(f272)();
  1356.     STDMETHOD(f273)();
  1357.     STDMETHOD(f274)();
  1358.     STDMETHOD(f275)();
  1359.     STDMETHOD(f276)();
  1360.     STDMETHOD(f277)();
  1361.     STDMETHOD(f278)();
  1362.     STDMETHOD(f279)();
  1363.     STDMETHOD(f280)();
  1364.     STDMETHOD(f281)();
  1365.     STDMETHOD(f282)();
  1366.     STDMETHOD(f283)();
  1367.     STDMETHOD(f284)();
  1368.     STDMETHOD(f285)();
  1369.     STDMETHOD(f286)();
  1370.     STDMETHOD(f287)();
  1371.     STDMETHOD(f288)();
  1372.     STDMETHOD(f289)();
  1373.     STDMETHOD(f290)();
  1374.     STDMETHOD(f291)();
  1375.     STDMETHOD(f292)();
  1376.     STDMETHOD(f293)();
  1377.     STDMETHOD(f294)();
  1378.     STDMETHOD(f295)();
  1379.     STDMETHOD(f296)();
  1380.     STDMETHOD(f297)();
  1381.     STDMETHOD(f298)();
  1382.     STDMETHOD(f299)();
  1383.     STDMETHOD(f300)();
  1384.     STDMETHOD(f301)();
  1385.     STDMETHOD(f302)();
  1386.     STDMETHOD(f303)();
  1387.     STDMETHOD(f304)();
  1388.     STDMETHOD(f305)();
  1389.     STDMETHOD(f306)();
  1390.     STDMETHOD(f307)();
  1391.     STDMETHOD(f308)();
  1392.     STDMETHOD(f309)();
  1393.     STDMETHOD(f310)();
  1394.     STDMETHOD(f311)();
  1395.     STDMETHOD(f312)();
  1396.     STDMETHOD(f313)();
  1397.     STDMETHOD(f314)();
  1398.     STDMETHOD(f315)();
  1399.     STDMETHOD(f316)();
  1400.     STDMETHOD(f317)();
  1401.     STDMETHOD(f318)();
  1402.     STDMETHOD(f319)();
  1403.     STDMETHOD(f320)();
  1404.     STDMETHOD(f321)();
  1405.     STDMETHOD(f322)();
  1406.     STDMETHOD(f323)();
  1407.     STDMETHOD(f324)();
  1408.     STDMETHOD(f325)();
  1409.     STDMETHOD(f326)();
  1410.     STDMETHOD(f327)();
  1411.     STDMETHOD(f328)();
  1412.     STDMETHOD(f329)();
  1413.     STDMETHOD(f330)();
  1414.     STDMETHOD(f331)();
  1415.     STDMETHOD(f332)();
  1416.     STDMETHOD(f333)();
  1417.     STDMETHOD(f334)();
  1418.     STDMETHOD(f335)();
  1419.     STDMETHOD(f336)();
  1420.     STDMETHOD(f337)();
  1421.     STDMETHOD(f338)();
  1422.     STDMETHOD(f339)();
  1423.     STDMETHOD(f340)();
  1424.     STDMETHOD(f341)();
  1425.     STDMETHOD(f342)();
  1426.     STDMETHOD(f343)();
  1427.     STDMETHOD(f344)();
  1428.     STDMETHOD(f345)();
  1429.     STDMETHOD(f346)();
  1430.     STDMETHOD(f347)();
  1431.     STDMETHOD(f348)();
  1432.     STDMETHOD(f349)();
  1433.     STDMETHOD(f350)();
  1434.     STDMETHOD(f351)();
  1435.     STDMETHOD(f352)();
  1436.     STDMETHOD(f353)();
  1437.     STDMETHOD(f354)();
  1438.     STDMETHOD(f355)();
  1439.     STDMETHOD(f356)();
  1440.     STDMETHOD(f357)();
  1441.     STDMETHOD(f358)();
  1442.     STDMETHOD(f359)();
  1443.     STDMETHOD(f360)();
  1444.     STDMETHOD(f361)();
  1445.     STDMETHOD(f362)();
  1446.     STDMETHOD(f363)();
  1447.     STDMETHOD(f364)();
  1448.     STDMETHOD(f365)();
  1449.     STDMETHOD(f366)();
  1450.     STDMETHOD(f367)();
  1451.     STDMETHOD(f368)();
  1452.     STDMETHOD(f369)();
  1453.     STDMETHOD(f370)();
  1454.     STDMETHOD(f371)();
  1455.     STDMETHOD(f372)();
  1456.     STDMETHOD(f373)();
  1457.     STDMETHOD(f374)();
  1458.     STDMETHOD(f375)();
  1459.     STDMETHOD(f376)();
  1460.     STDMETHOD(f377)();
  1461.     STDMETHOD(f378)();
  1462.     STDMETHOD(f379)();
  1463.     STDMETHOD(f380)();
  1464.     STDMETHOD(f381)();
  1465.     STDMETHOD(f382)();
  1466.     STDMETHOD(f383)();
  1467.     STDMETHOD(f384)();
  1468.     STDMETHOD(f385)();
  1469.     STDMETHOD(f386)();
  1470.     STDMETHOD(f387)();
  1471.     STDMETHOD(f388)();
  1472.     STDMETHOD(f389)();
  1473.     STDMETHOD(f390)();
  1474.     STDMETHOD(f391)();
  1475.     STDMETHOD(f392)();
  1476.     STDMETHOD(f393)();
  1477.     STDMETHOD(f394)();
  1478.     STDMETHOD(f395)();
  1479.     STDMETHOD(f396)();
  1480.     STDMETHOD(f397)();
  1481.     STDMETHOD(f398)();
  1482.     STDMETHOD(f399)();
  1483.     STDMETHOD(f400)();
  1484.     STDMETHOD(f401)();
  1485.     STDMETHOD(f402)();
  1486.     STDMETHOD(f403)();
  1487.     STDMETHOD(f404)();
  1488.     STDMETHOD(f405)();
  1489.     STDMETHOD(f406)();
  1490.     STDMETHOD(f407)();
  1491.     STDMETHOD(f408)();
  1492.     STDMETHOD(f409)();
  1493.     STDMETHOD(f410)();
  1494.     STDMETHOD(f411)();
  1495.     STDMETHOD(f412)();
  1496.     STDMETHOD(f413)();
  1497.     STDMETHOD(f414)();
  1498.     STDMETHOD(f415)();
  1499.     STDMETHOD(f416)();
  1500.     STDMETHOD(f417)();
  1501.     STDMETHOD(f418)();
  1502.     STDMETHOD(f419)();
  1503.     STDMETHOD(f420)();
  1504.     STDMETHOD(f421)();
  1505.     STDMETHOD(f422)();
  1506.     STDMETHOD(f423)();
  1507.     STDMETHOD(f424)();
  1508.     STDMETHOD(f425)();
  1509.     STDMETHOD(f426)();
  1510.     STDMETHOD(f427)();
  1511.     STDMETHOD(f428)();
  1512.     STDMETHOD(f429)();
  1513.     STDMETHOD(f430)();
  1514.     STDMETHOD(f431)();
  1515.     STDMETHOD(f432)();
  1516.     STDMETHOD(f433)();
  1517.     STDMETHOD(f434)();
  1518.     STDMETHOD(f435)();
  1519.     STDMETHOD(f436)();
  1520.     STDMETHOD(f437)();
  1521.     STDMETHOD(f438)();
  1522.     STDMETHOD(f439)();
  1523.     STDMETHOD(f440)();
  1524.     STDMETHOD(f441)();
  1525.     STDMETHOD(f442)();
  1526.     STDMETHOD(f443)();
  1527.     STDMETHOD(f444)();
  1528.     STDMETHOD(f445)();
  1529.     STDMETHOD(f446)();
  1530.     STDMETHOD(f447)();
  1531.     STDMETHOD(f448)();
  1532.     STDMETHOD(f449)();
  1533.     STDMETHOD(f450)();
  1534.     STDMETHOD(f451)();
  1535.     STDMETHOD(f452)();
  1536.     STDMETHOD(f453)();
  1537.     STDMETHOD(f454)();
  1538.     STDMETHOD(f455)();
  1539.     STDMETHOD(f456)();
  1540.     STDMETHOD(f457)();
  1541.     STDMETHOD(f458)();
  1542.     STDMETHOD(f459)();
  1543.     STDMETHOD(f460)();
  1544.     STDMETHOD(f461)();
  1545.     STDMETHOD(f462)();
  1546.     STDMETHOD(f463)();
  1547.     STDMETHOD(f464)();
  1548.     STDMETHOD(f465)();
  1549.     STDMETHOD(f466)();
  1550.     STDMETHOD(f467)();
  1551.     STDMETHOD(f468)();
  1552.     STDMETHOD(f469)();
  1553.     STDMETHOD(f470)();
  1554.     STDMETHOD(f471)();
  1555.     STDMETHOD(f472)();
  1556.     STDMETHOD(f473)();
  1557.     STDMETHOD(f474)();
  1558.     STDMETHOD(f475)();
  1559.     STDMETHOD(f476)();
  1560.     STDMETHOD(f477)();
  1561.     STDMETHOD(f478)();
  1562.     STDMETHOD(f479)();
  1563.     STDMETHOD(f480)();
  1564.     STDMETHOD(f481)();
  1565.     STDMETHOD(f482)();
  1566.     STDMETHOD(f483)();
  1567.     STDMETHOD(f484)();
  1568.     STDMETHOD(f485)();
  1569.     STDMETHOD(f486)();
  1570.     STDMETHOD(f487)();
  1571.     STDMETHOD(f488)();
  1572.     STDMETHOD(f489)();
  1573.     STDMETHOD(f490)();
  1574.     STDMETHOD(f491)();
  1575.     STDMETHOD(f492)();
  1576.     STDMETHOD(f493)();
  1577.     STDMETHOD(f494)();
  1578.     STDMETHOD(f495)();
  1579.     STDMETHOD(f496)();
  1580.     STDMETHOD(f497)();
  1581.     STDMETHOD(f498)();
  1582.     STDMETHOD(f499)();
  1583.     STDMETHOD(f500)();
  1584.     STDMETHOD(f501)();
  1585.     STDMETHOD(f502)();
  1586.     STDMETHOD(f503)();
  1587.     STDMETHOD(f504)();
  1588.     STDMETHOD(f505)();
  1589.     STDMETHOD(f506)();
  1590.     STDMETHOD(f507)();
  1591.     STDMETHOD(f508)();
  1592.     STDMETHOD(f509)();
  1593.     STDMETHOD(f510)();
  1594.     STDMETHOD(f511)();
  1595.     STDMETHOD(f512)();
  1596.     STDMETHOD(f513)();
  1597.     STDMETHOD(f514)();
  1598.     STDMETHOD(f515)();
  1599.     STDMETHOD(f516)();
  1600.     STDMETHOD(f517)();
  1601.     STDMETHOD(f518)();
  1602.     STDMETHOD(f519)();
  1603.     STDMETHOD(f520)();
  1604.     STDMETHOD(f521)();
  1605.     STDMETHOD(f522)();
  1606.     STDMETHOD(f523)();
  1607.     STDMETHOD(f524)();
  1608.     STDMETHOD(f525)();
  1609.     STDMETHOD(f526)();
  1610.     STDMETHOD(f527)();
  1611.     STDMETHOD(f528)();
  1612.     STDMETHOD(f529)();
  1613.     STDMETHOD(f530)();
  1614.     STDMETHOD(f531)();
  1615.     STDMETHOD(f532)();
  1616.     STDMETHOD(f533)();
  1617.     STDMETHOD(f534)();
  1618.     STDMETHOD(f535)();
  1619.     STDMETHOD(f536)();
  1620.     STDMETHOD(f537)();
  1621.     STDMETHOD(f538)();
  1622.     STDMETHOD(f539)();
  1623.     STDMETHOD(f540)();
  1624.     STDMETHOD(f541)();
  1625.     STDMETHOD(f542)();
  1626.     STDMETHOD(f543)();
  1627.     STDMETHOD(f544)();
  1628.     STDMETHOD(f545)();
  1629.     STDMETHOD(f546)();
  1630.     STDMETHOD(f547)();
  1631.     STDMETHOD(f548)();
  1632.     STDMETHOD(f549)();
  1633.     STDMETHOD(f550)();
  1634.     STDMETHOD(f551)();
  1635.     STDMETHOD(f552)();
  1636.     STDMETHOD(f553)();
  1637.     STDMETHOD(f554)();
  1638.     STDMETHOD(f555)();
  1639.     STDMETHOD(f556)();
  1640.     STDMETHOD(f557)();
  1641.     STDMETHOD(f558)();
  1642.     STDMETHOD(f559)();
  1643.     STDMETHOD(f560)();
  1644.     STDMETHOD(f561)();
  1645.     STDMETHOD(f562)();
  1646.     STDMETHOD(f563)();
  1647.     STDMETHOD(f564)();
  1648.     STDMETHOD(f565)();
  1649.     STDMETHOD(f566)();
  1650.     STDMETHOD(f567)();
  1651.     STDMETHOD(f568)();
  1652.     STDMETHOD(f569)();
  1653.     STDMETHOD(f570)();
  1654.     STDMETHOD(f571)();
  1655.     STDMETHOD(f572)();
  1656.     STDMETHOD(f573)();
  1657.     STDMETHOD(f574)();
  1658.     STDMETHOD(f575)();
  1659.     STDMETHOD(f576)();
  1660.     STDMETHOD(f577)();
  1661.     STDMETHOD(f578)();
  1662.     STDMETHOD(f579)();
  1663.     STDMETHOD(f580)();
  1664.     STDMETHOD(f581)();
  1665.     STDMETHOD(f582)();
  1666.     STDMETHOD(f583)();
  1667.     STDMETHOD(f584)();
  1668.     STDMETHOD(f585)();
  1669.     STDMETHOD(f586)();
  1670.     STDMETHOD(f587)();
  1671.     STDMETHOD(f588)();
  1672.     STDMETHOD(f589)();
  1673.     STDMETHOD(f590)();
  1674.     STDMETHOD(f591)();
  1675.     STDMETHOD(f592)();
  1676.     STDMETHOD(f593)();
  1677.     STDMETHOD(f594)();
  1678.     STDMETHOD(f595)();
  1679.     STDMETHOD(f596)();
  1680.     STDMETHOD(f597)();
  1681.     STDMETHOD(f598)();
  1682.     STDMETHOD(f599)();
  1683.     STDMETHOD(f600)();
  1684.     STDMETHOD(f601)();
  1685.     STDMETHOD(f602)();
  1686.     STDMETHOD(f603)();
  1687.     STDMETHOD(f604)();
  1688.     STDMETHOD(f605)();
  1689.     STDMETHOD(f606)();
  1690.     STDMETHOD(f607)();
  1691.     STDMETHOD(f608)();
  1692.     STDMETHOD(f609)();
  1693.     STDMETHOD(f610)();
  1694.     STDMETHOD(f611)();
  1695.     STDMETHOD(f612)();
  1696.     STDMETHOD(f613)();
  1697.     STDMETHOD(f614)();
  1698.     STDMETHOD(f615)();
  1699.     STDMETHOD(f616)();
  1700.     STDMETHOD(f617)();
  1701.     STDMETHOD(f618)();
  1702.     STDMETHOD(f619)();
  1703.     STDMETHOD(f620)();
  1704.     STDMETHOD(f621)();
  1705.     STDMETHOD(f622)();
  1706.     STDMETHOD(f623)();
  1707.     STDMETHOD(f624)();
  1708.     STDMETHOD(f625)();
  1709.     STDMETHOD(f626)();
  1710.     STDMETHOD(f627)();
  1711.     STDMETHOD(f628)();
  1712.     STDMETHOD(f629)();
  1713.     STDMETHOD(f630)();
  1714.     STDMETHOD(f631)();
  1715.     STDMETHOD(f632)();
  1716.     STDMETHOD(f633)();
  1717.     STDMETHOD(f634)();
  1718.     STDMETHOD(f635)();
  1719.     STDMETHOD(f636)();
  1720.     STDMETHOD(f637)();
  1721.     STDMETHOD(f638)();
  1722.     STDMETHOD(f639)();
  1723.     STDMETHOD(f640)();
  1724.     STDMETHOD(f641)();
  1725.     STDMETHOD(f642)();
  1726.     STDMETHOD(f643)();
  1727.     STDMETHOD(f644)();
  1728.     STDMETHOD(f645)();
  1729.     STDMETHOD(f646)();
  1730.     STDMETHOD(f647)();
  1731.     STDMETHOD(f648)();
  1732.     STDMETHOD(f649)();
  1733.     STDMETHOD(f650)();
  1734.     STDMETHOD(f651)();
  1735.     STDMETHOD(f652)();
  1736.     STDMETHOD(f653)();
  1737.     STDMETHOD(f654)();
  1738.     STDMETHOD(f655)();
  1739.     STDMETHOD(f656)();
  1740.     STDMETHOD(f657)();
  1741.     STDMETHOD(f658)();
  1742.     STDMETHOD(f659)();
  1743.     STDMETHOD(f660)();
  1744.     STDMETHOD(f661)();
  1745.     STDMETHOD(f662)();
  1746.     STDMETHOD(f663)();
  1747.     STDMETHOD(f664)();
  1748.     STDMETHOD(f665)();
  1749.     STDMETHOD(f666)();
  1750.     STDMETHOD(f667)();
  1751.     STDMETHOD(f668)();
  1752.     STDMETHOD(f669)();
  1753.     STDMETHOD(f670)();
  1754.     STDMETHOD(f671)();
  1755.     STDMETHOD(f672)();
  1756.     STDMETHOD(f673)();
  1757.     STDMETHOD(f674)();
  1758.     STDMETHOD(f675)();
  1759.     STDMETHOD(f676)();
  1760.     STDMETHOD(f677)();
  1761.     STDMETHOD(f678)();
  1762.     STDMETHOD(f679)();
  1763.     STDMETHOD(f680)();
  1764.     STDMETHOD(f681)();
  1765.     STDMETHOD(f682)();
  1766.     STDMETHOD(f683)();
  1767.     STDMETHOD(f684)();
  1768.     STDMETHOD(f685)();
  1769.     STDMETHOD(f686)();
  1770.     STDMETHOD(f687)();
  1771.     STDMETHOD(f688)();
  1772.     STDMETHOD(f689)();
  1773.     STDMETHOD(f690)();
  1774.     STDMETHOD(f691)();
  1775.     STDMETHOD(f692)();
  1776.     STDMETHOD(f693)();
  1777.     STDMETHOD(f694)();
  1778.     STDMETHOD(f695)();
  1779.     STDMETHOD(f696)();
  1780.     STDMETHOD(f697)();
  1781.     STDMETHOD(f698)();
  1782.     STDMETHOD(f699)();
  1783.     STDMETHOD(f700)();
  1784.     STDMETHOD(f701)();
  1785.     STDMETHOD(f702)();
  1786.     STDMETHOD(f703)();
  1787.     STDMETHOD(f704)();
  1788.     STDMETHOD(f705)();
  1789.     STDMETHOD(f706)();
  1790.     STDMETHOD(f707)();
  1791.     STDMETHOD(f708)();
  1792.     STDMETHOD(f709)();
  1793.     STDMETHOD(f710)();
  1794.     STDMETHOD(f711)();
  1795.     STDMETHOD(f712)();
  1796.     STDMETHOD(f713)();
  1797.     STDMETHOD(f714)();
  1798.     STDMETHOD(f715)();
  1799.     STDMETHOD(f716)();
  1800.     STDMETHOD(f717)();
  1801.     STDMETHOD(f718)();
  1802.     STDMETHOD(f719)();
  1803.     STDMETHOD(f720)();
  1804.     STDMETHOD(f721)();
  1805.     STDMETHOD(f722)();
  1806.     STDMETHOD(f723)();
  1807.     STDMETHOD(f724)();
  1808.     STDMETHOD(f725)();
  1809.     STDMETHOD(f726)();
  1810.     STDMETHOD(f727)();
  1811.     STDMETHOD(f728)();
  1812.     STDMETHOD(f729)();
  1813.     STDMETHOD(f730)();
  1814.     STDMETHOD(f731)();
  1815.     STDMETHOD(f732)();
  1816.     STDMETHOD(f733)();
  1817.     STDMETHOD(f734)();
  1818.     STDMETHOD(f735)();
  1819.     STDMETHOD(f736)();
  1820.     STDMETHOD(f737)();
  1821.     STDMETHOD(f738)();
  1822.     STDMETHOD(f739)();
  1823.     STDMETHOD(f740)();
  1824.     STDMETHOD(f741)();
  1825.     STDMETHOD(f742)();
  1826.     STDMETHOD(f743)();
  1827.     STDMETHOD(f744)();
  1828.     STDMETHOD(f745)();
  1829.     STDMETHOD(f746)();
  1830.     STDMETHOD(f747)();
  1831.     STDMETHOD(f748)();
  1832.     STDMETHOD(f749)();
  1833.     STDMETHOD(f750)();
  1834.     STDMETHOD(f751)();
  1835.     STDMETHOD(f752)();
  1836.     STDMETHOD(f753)();
  1837.     STDMETHOD(f754)();
  1838.     STDMETHOD(f755)();
  1839.     STDMETHOD(f756)();
  1840.     STDMETHOD(f757)();
  1841.     STDMETHOD(f758)();
  1842.     STDMETHOD(f759)();
  1843.     STDMETHOD(f760)();
  1844.     STDMETHOD(f761)();
  1845.     STDMETHOD(f762)();
  1846.     STDMETHOD(f763)();
  1847.     STDMETHOD(f764)();
  1848.     STDMETHOD(f765)();
  1849.     STDMETHOD(f766)();
  1850.     STDMETHOD(f767)();
  1851.     STDMETHOD(f768)();
  1852.     STDMETHOD(f769)();
  1853.     STDMETHOD(f770)();
  1854.     STDMETHOD(f771)();
  1855.     STDMETHOD(f772)();
  1856.     STDMETHOD(f773)();
  1857.     STDMETHOD(f774)();
  1858.     STDMETHOD(f775)();
  1859.     STDMETHOD(f776)();
  1860.     STDMETHOD(f777)();
  1861.     STDMETHOD(f778)();
  1862.     STDMETHOD(f779)();
  1863.     STDMETHOD(f780)();
  1864.     STDMETHOD(f781)();
  1865.     STDMETHOD(f782)();
  1866.     STDMETHOD(f783)();
  1867.     STDMETHOD(f784)();
  1868.     STDMETHOD(f785)();
  1869.     STDMETHOD(f786)();
  1870.     STDMETHOD(f787)();
  1871.     STDMETHOD(f788)();
  1872.     STDMETHOD(f789)();
  1873.     STDMETHOD(f790)();
  1874.     STDMETHOD(f791)();
  1875.     STDMETHOD(f792)();
  1876.     STDMETHOD(f793)();
  1877.     STDMETHOD(f794)();
  1878.     STDMETHOD(f795)();
  1879.     STDMETHOD(f796)();
  1880.     STDMETHOD(f797)();
  1881.     STDMETHOD(f798)();
  1882.     STDMETHOD(f799)();
  1883.     STDMETHOD(f800)();
  1884.     STDMETHOD(f801)();
  1885.     STDMETHOD(f802)();
  1886.     STDMETHOD(f803)();
  1887.     STDMETHOD(f804)();
  1888.     STDMETHOD(f805)();
  1889.     STDMETHOD(f806)();
  1890.     STDMETHOD(f807)();
  1891.     STDMETHOD(f808)();
  1892.     STDMETHOD(f809)();
  1893.     STDMETHOD(f810)();
  1894.     STDMETHOD(f811)();
  1895.     STDMETHOD(f812)();
  1896.     STDMETHOD(f813)();
  1897.     STDMETHOD(f814)();
  1898.     STDMETHOD(f815)();
  1899.     STDMETHOD(f816)();
  1900.     STDMETHOD(f817)();
  1901.     STDMETHOD(f818)();
  1902.     STDMETHOD(f819)();
  1903.     STDMETHOD(f820)();
  1904.     STDMETHOD(f821)();
  1905.     STDMETHOD(f822)();
  1906.     STDMETHOD(f823)();
  1907.     STDMETHOD(f824)();
  1908.     STDMETHOD(f825)();
  1909.     STDMETHOD(f826)();
  1910.     STDMETHOD(f827)();
  1911.     STDMETHOD(f828)();
  1912.     STDMETHOD(f829)();
  1913.     STDMETHOD(f830)();
  1914.     STDMETHOD(f831)();
  1915.     STDMETHOD(f832)();
  1916.     STDMETHOD(f833)();
  1917.     STDMETHOD(f834)();
  1918.     STDMETHOD(f835)();
  1919.     STDMETHOD(f836)();
  1920.     STDMETHOD(f837)();
  1921.     STDMETHOD(f838)();
  1922.     STDMETHOD(f839)();
  1923.     STDMETHOD(f840)();
  1924.     STDMETHOD(f841)();
  1925.     STDMETHOD(f842)();
  1926.     STDMETHOD(f843)();
  1927.     STDMETHOD(f844)();
  1928.     STDMETHOD(f845)();
  1929.     STDMETHOD(f846)();
  1930.     STDMETHOD(f847)();
  1931.     STDMETHOD(f848)();
  1932.     STDMETHOD(f849)();
  1933.     STDMETHOD(f850)();
  1934.     STDMETHOD(f851)();
  1935.     STDMETHOD(f852)();
  1936.     STDMETHOD(f853)();
  1937.     STDMETHOD(f854)();
  1938.     STDMETHOD(f855)();
  1939.     STDMETHOD(f856)();
  1940.     STDMETHOD(f857)();
  1941.     STDMETHOD(f858)();
  1942.     STDMETHOD(f859)();
  1943.     STDMETHOD(f860)();
  1944.     STDMETHOD(f861)();
  1945.     STDMETHOD(f862)();
  1946.     STDMETHOD(f863)();
  1947.     STDMETHOD(f864)();
  1948.     STDMETHOD(f865)();
  1949.     STDMETHOD(f866)();
  1950.     STDMETHOD(f867)();
  1951.     STDMETHOD(f868)();
  1952.     STDMETHOD(f869)();
  1953.     STDMETHOD(f870)();
  1954.     STDMETHOD(f871)();
  1955.     STDMETHOD(f872)();
  1956.     STDMETHOD(f873)();
  1957.     STDMETHOD(f874)();
  1958.     STDMETHOD(f875)();
  1959.     STDMETHOD(f876)();
  1960.     STDMETHOD(f877)();
  1961.     STDMETHOD(f878)();
  1962.     STDMETHOD(f879)();
  1963.     STDMETHOD(f880)();
  1964.     STDMETHOD(f881)();
  1965.     STDMETHOD(f882)();
  1966.     STDMETHOD(f883)();
  1967.     STDMETHOD(f884)();
  1968.     STDMETHOD(f885)();
  1969.     STDMETHOD(f886)();
  1970.     STDMETHOD(f887)();
  1971.     STDMETHOD(f888)();
  1972.     STDMETHOD(f889)();
  1973.     STDMETHOD(f890)();
  1974.     STDMETHOD(f891)();
  1975.     STDMETHOD(f892)();
  1976.     STDMETHOD(f893)();
  1977.     STDMETHOD(f894)();
  1978.     STDMETHOD(f895)();
  1979.     STDMETHOD(f896)();
  1980.     STDMETHOD(f897)();
  1981.     STDMETHOD(f898)();
  1982.     STDMETHOD(f899)();
  1983.     STDMETHOD(f900)();
  1984.     STDMETHOD(f901)();
  1985.     STDMETHOD(f902)();
  1986.     STDMETHOD(f903)();
  1987.     STDMETHOD(f904)();
  1988.     STDMETHOD(f905)();
  1989.     STDMETHOD(f906)();
  1990.     STDMETHOD(f907)();
  1991.     STDMETHOD(f908)();
  1992.     STDMETHOD(f909)();
  1993.     STDMETHOD(f910)();
  1994.     STDMETHOD(f911)();
  1995.     STDMETHOD(f912)();
  1996.     STDMETHOD(f913)();
  1997.     STDMETHOD(f914)();
  1998.     STDMETHOD(f915)();
  1999.     STDMETHOD(f916)();
  2000.     STDMETHOD(f917)();
  2001.     STDMETHOD(f918)();
  2002.     STDMETHOD(f919)();
  2003.     STDMETHOD(f920)();
  2004.     STDMETHOD(f921)();
  2005.     STDMETHOD(f922)();
  2006.     STDMETHOD(f923)();
  2007.     STDMETHOD(f924)();
  2008.     STDMETHOD(f925)();
  2009.     STDMETHOD(f926)();
  2010.     STDMETHOD(f927)();
  2011.     STDMETHOD(f928)();
  2012.     STDMETHOD(f929)();
  2013.     STDMETHOD(f930)();
  2014.     STDMETHOD(f931)();
  2015.     STDMETHOD(f932)();
  2016.     STDMETHOD(f933)();
  2017.     STDMETHOD(f934)();
  2018.     STDMETHOD(f935)();
  2019.     STDMETHOD(f936)();
  2020.     STDMETHOD(f937)();
  2021.     STDMETHOD(f938)();
  2022.     STDMETHOD(f939)();
  2023.     STDMETHOD(f940)();
  2024.     STDMETHOD(f941)();
  2025.     STDMETHOD(f942)();
  2026.     STDMETHOD(f943)();
  2027.     STDMETHOD(f944)();
  2028.     STDMETHOD(f945)();
  2029.     STDMETHOD(f946)();
  2030.     STDMETHOD(f947)();
  2031.     STDMETHOD(f948)();
  2032.     STDMETHOD(f949)();
  2033.     STDMETHOD(f950)();
  2034.     STDMETHOD(f951)();
  2035.     STDMETHOD(f952)();
  2036.     STDMETHOD(f953)();
  2037.     STDMETHOD(f954)();
  2038.     STDMETHOD(f955)();
  2039.     STDMETHOD(f956)();
  2040.     STDMETHOD(f957)();
  2041.     STDMETHOD(f958)();
  2042.     STDMETHOD(f959)();
  2043.     STDMETHOD(f960)();
  2044.     STDMETHOD(f961)();
  2045.     STDMETHOD(f962)();
  2046.     STDMETHOD(f963)();
  2047.     STDMETHOD(f964)();
  2048.     STDMETHOD(f965)();
  2049.     STDMETHOD(f966)();
  2050.     STDMETHOD(f967)();
  2051.     STDMETHOD(f968)();
  2052.     STDMETHOD(f969)();
  2053.     STDMETHOD(f970)();
  2054.     STDMETHOD(f971)();
  2055.     STDMETHOD(f972)();
  2056.     STDMETHOD(f973)();
  2057.     STDMETHOD(f974)();
  2058.     STDMETHOD(f975)();
  2059.     STDMETHOD(f976)();
  2060.     STDMETHOD(f977)();
  2061.     STDMETHOD(f978)();
  2062.     STDMETHOD(f979)();
  2063.     STDMETHOD(f980)();
  2064.     STDMETHOD(f981)();
  2065.     STDMETHOD(f982)();
  2066.     STDMETHOD(f983)();
  2067.     STDMETHOD(f984)();
  2068.     STDMETHOD(f985)();
  2069.     STDMETHOD(f986)();
  2070.     STDMETHOD(f987)();
  2071.     STDMETHOD(f988)();
  2072.     STDMETHOD(f989)();
  2073.     STDMETHOD(f990)();
  2074.     STDMETHOD(f991)();
  2075.     STDMETHOD(f992)();
  2076.     STDMETHOD(f993)();
  2077.     STDMETHOD(f994)();
  2078.     STDMETHOD(f995)();
  2079.     STDMETHOD(f996)();
  2080.     STDMETHOD(f997)();
  2081.     STDMETHOD(f998)();
  2082.     STDMETHOD(f999)();
  2083.     STDMETHOD(f1000)();
  2084.     STDMETHOD(f1001)();
  2085.     STDMETHOD(f1002)();
  2086.     STDMETHOD(f1003)();
  2087.     STDMETHOD(f1004)();
  2088.     STDMETHOD(f1005)();
  2089.     STDMETHOD(f1006)();
  2090.     STDMETHOD(f1007)();
  2091.     STDMETHOD(f1008)();
  2092.     STDMETHOD(f1009)();
  2093.     STDMETHOD(f1010)();
  2094.     STDMETHOD(f1011)();
  2095.     STDMETHOD(f1012)();
  2096.     STDMETHOD(f1013)();
  2097.     STDMETHOD(f1014)();
  2098.     STDMETHOD(f1015)();
  2099.     STDMETHOD(f1016)();
  2100.     STDMETHOD(f1017)();
  2101.     STDMETHOD(f1018)();
  2102.     STDMETHOD(f1019)();
  2103.     STDMETHOD(f1020)();
  2104.     STDMETHOD(f1021)();
  2105.     STDMETHOD(f1022)();
  2106.     STDMETHOD(f1023)();
  2107.     STDMETHOD(f1024)();
  2108.     _QIThunk(IUnknown* pOrig, LPCTSTR p, const IID& i, UINT n, bool b)
  2109.     {
  2110.         lpszClassName = p;
  2111.         iid = i;
  2112.         nIndex = n;
  2113.         m_dwRef = 0;
  2114.         m_dwMaxRef = 0;
  2115.         pUnk = pOrig;
  2116.         bBreak = b;
  2117.         bNonAddRefThunk = false;
  2118.     }
  2119.     IUnknown* pUnk;
  2120.     long m_dwRef;
  2121.     long m_dwMaxRef;
  2122.     LPCTSTR lpszClassName;
  2123.     IID iid;
  2124.     UINT nIndex;
  2125.     bool bBreak;
  2126.     bool bNonAddRefThunk;
  2127.     void Dump()
  2128.     {
  2129.         TCHAR buf[256];
  2130.         if (m_dwRef != 0)
  2131.         {
  2132.             wsprintf(buf, _T("INTERFACE LEAK: RefCount = %d, MaxRefCount = %d, {Allocation = %d} "), m_dwRef, m_dwMaxRef, nIndex);
  2133.             OutputDebugString(buf);
  2134.             AtlDumpIID(iid, lpszClassName, S_OK);
  2135.         }
  2136.         else
  2137.         {
  2138.             wsprintf(buf, _T("NonAddRef Thunk LEAK: {Allocation = %d}\n"), nIndex);
  2139.             OutputDebugString(buf);
  2140.         }
  2141.     }
  2142. };
  2143. #endif
  2144.  
  2145.  
  2146. /////////////////////////////////////////////////////////////////////////////
  2147. // Collection helpers - CSimpleArray & CSimpleMap
  2148.  
  2149. template <class T>
  2150. class CSimpleArray
  2151. {
  2152. public:
  2153.     T* m_aT;
  2154.     int m_nSize;
  2155.     int m_nAllocSize;
  2156.  
  2157. // Construction/destruction
  2158.     CSimpleArray() : m_aT(NULL), m_nSize(0), m_nAllocSize(0)
  2159.     { }
  2160.  
  2161.     ~CSimpleArray()
  2162.     {
  2163.         RemoveAll();
  2164.     }
  2165.  
  2166. // Operations
  2167.     int GetSize() const
  2168.     {
  2169.         return m_nSize;
  2170.     }
  2171.     BOOL Add(T& t)
  2172.     {
  2173.         if(m_nSize == m_nAllocSize)
  2174.         {
  2175.             T* aT;
  2176.             int nNewAllocSize = (m_nAllocSize == 0) ? 1 : (m_nSize * 2);
  2177.             aT = (T*)realloc(m_aT, nNewAllocSize * sizeof(T));
  2178.             if(aT == NULL)
  2179.                 return FALSE;
  2180.             m_nAllocSize = nNewAllocSize;
  2181.             m_aT = aT;
  2182.         }
  2183.         m_nSize++;
  2184.         SetAtIndex(m_nSize - 1, t);
  2185.         return TRUE;
  2186.     }
  2187.     BOOL Remove(T& t)
  2188.     {
  2189.         int nIndex = Find(t);
  2190.         if(nIndex == -1)
  2191.             return FALSE;
  2192.         return RemoveAt(nIndex);
  2193.     }
  2194.     BOOL RemoveAt(int nIndex)
  2195.     {
  2196.         if(nIndex != (m_nSize - 1))
  2197.         {
  2198.             m_aT[nIndex].~T();
  2199.             memmove((void*)&m_aT[nIndex], (void*)&m_aT[nIndex + 1], (m_nSize - (nIndex + 1)) * sizeof(T));
  2200.         }
  2201.         m_nSize--;
  2202.         return TRUE;
  2203.     }
  2204.     void RemoveAll()
  2205.     {
  2206.         if(m_aT != NULL)
  2207.         {
  2208.             for(int i = 0; i < m_nSize; i++)
  2209.                 m_aT[i].~T();
  2210.             free(m_aT);
  2211.             m_aT = NULL;
  2212.         }
  2213.         m_nSize = 0;
  2214.         m_nAllocSize = 0;
  2215.     }
  2216.     T& operator[] (int nIndex) const
  2217.     {
  2218.         ATLASSERT(nIndex >= 0 && nIndex < m_nSize);
  2219.         return m_aT[nIndex];
  2220.     }
  2221.     T* GetData() const
  2222.     {
  2223.         return m_aT;
  2224.     }
  2225.  
  2226. // Implementation
  2227.     class Wrapper
  2228.     {
  2229.     public:
  2230.         Wrapper(T& _t) : t(_t)
  2231.         {
  2232.         }
  2233.         template <class _Ty>
  2234.         void *operator new(size_t, _Ty* p)
  2235.         {
  2236.             return p;
  2237.         }
  2238.         T t;
  2239.     };
  2240.     void SetAtIndex(int nIndex, T& t)
  2241.     {
  2242.         ATLASSERT(nIndex >= 0 && nIndex < m_nSize);
  2243.         new(&m_aT[nIndex]) Wrapper(t);
  2244.     }
  2245.     int Find(T& t) const
  2246.     {
  2247.         for(int i = 0; i < m_nSize; i++)
  2248.         {
  2249.             if(m_aT[i] == t)
  2250.                 return i;
  2251.         }
  2252.         return -1;  // not found
  2253.     }
  2254. };
  2255.  
  2256. // for arrays of simple types
  2257. template <class T>
  2258. class CSimpleValArray : public CSimpleArray< T >
  2259. {
  2260. public:
  2261.     BOOL Add(T t)
  2262.     {
  2263.         return CSimpleArray< T >::Add(t);
  2264.     }
  2265.     BOOL Remove(T t)
  2266.     {
  2267.         return CSimpleArray< T >::Remove(t);
  2268.     }
  2269.     T operator[] (int nIndex) const
  2270.     {
  2271.         return CSimpleArray< T >::operator[](nIndex);
  2272.     }
  2273. };
  2274.  
  2275.  
  2276. // intended for small number of simple types or pointers
  2277. template <class TKey, class TVal>
  2278. class CSimpleMap
  2279. {
  2280. public:
  2281.     TKey* m_aKey;
  2282.     TVal* m_aVal;
  2283.     int m_nSize;
  2284.  
  2285. // Construction/destruction
  2286.     CSimpleMap() : m_aKey(NULL), m_aVal(NULL), m_nSize(0)
  2287.     { }
  2288.  
  2289.     ~CSimpleMap()
  2290.     {
  2291.         RemoveAll();
  2292.     }
  2293.  
  2294. // Operations
  2295.     int GetSize() const
  2296.     {
  2297.         return m_nSize;
  2298.     }
  2299.     BOOL Add(TKey key, TVal val)
  2300.     {
  2301.         TKey* pKey;
  2302.         pKey = (TKey*)realloc(m_aKey, (m_nSize + 1) * sizeof(TKey));
  2303.         if(pKey == NULL)
  2304.             return FALSE;
  2305.         m_aKey = pKey;
  2306.         TVal* pVal;
  2307.         pVal = (TVal*)realloc(m_aVal, (m_nSize + 1) * sizeof(TVal));
  2308.         if(pVal == NULL)
  2309.             return FALSE;
  2310.         m_aVal = pVal;
  2311.         m_nSize++;
  2312.         SetAtIndex(m_nSize - 1, key, val);
  2313.         return TRUE;
  2314.     }
  2315.     BOOL Remove(TKey key)
  2316.     {
  2317.         int nIndex = FindKey(key);
  2318.         if(nIndex == -1)
  2319.             return FALSE;
  2320.         if(nIndex != (m_nSize - 1))
  2321.         {
  2322.             m_aKey[nIndex].~TKey();
  2323.             m_aVal[nIndex].~TVal();
  2324.             memmove((void*)&m_aKey[nIndex], (void*)&m_aKey[nIndex + 1], (m_nSize - (nIndex + 1)) * sizeof(TKey));
  2325.             memmove((void*)&m_aVal[nIndex], (void*)&m_aVal[nIndex + 1], (m_nSize - (nIndex + 1)) * sizeof(TVal));
  2326.         }
  2327.         TKey* pKey;
  2328.         pKey = (TKey*)realloc(m_aKey, (m_nSize - 1) * sizeof(TKey));
  2329.         if(pKey != NULL || m_nSize == 1)
  2330.             m_aKey = pKey;
  2331.         TVal* pVal;
  2332.         pVal = (TVal*)realloc(m_aVal, (m_nSize - 1) * sizeof(TVal));
  2333.         if(pVal != NULL || m_nSize == 1)
  2334.             m_aVal = pVal;
  2335.         m_nSize--;
  2336.         return TRUE;
  2337.     }
  2338.     void RemoveAll()
  2339.     {
  2340.         if(m_aKey != NULL)
  2341.         {
  2342.             for(int i = 0; i < m_nSize; i++)
  2343.             {
  2344.                 m_aKey[i].~TKey();
  2345.                 m_aVal[i].~TVal();
  2346.             }
  2347.             free(m_aKey);
  2348.             m_aKey = NULL;
  2349.         }
  2350.         if(m_aVal != NULL)
  2351.         {
  2352.             free(m_aVal);
  2353.             m_aVal = NULL;
  2354.         }
  2355.  
  2356.         m_nSize = 0;
  2357.     }
  2358.     BOOL SetAt(TKey key, TVal val)
  2359.     {
  2360.         int nIndex = FindKey(key);
  2361.         if(nIndex == -1)
  2362.             return FALSE;
  2363.         SetAtIndex(nIndex, key, val);
  2364.         return TRUE;
  2365.     }
  2366.     TVal Lookup(TKey key) const
  2367.     {
  2368.         int nIndex = FindKey(key);
  2369.         if(nIndex == -1)
  2370.             return NULL;    // must be able to convert
  2371.         return GetValueAt(nIndex);
  2372.     }
  2373.     TKey ReverseLookup(TVal val) const
  2374.     {
  2375.         int nIndex = FindVal(val);
  2376.         if(nIndex == -1)
  2377.             return NULL;    // must be able to convert
  2378.         return GetKeyAt(nIndex);
  2379.     }
  2380.     TKey& GetKeyAt(int nIndex) const
  2381.     {
  2382.         ATLASSERT(nIndex >= 0 && nIndex < m_nSize);
  2383.         return m_aKey[nIndex];
  2384.     }
  2385.     TVal& GetValueAt(int nIndex) const
  2386.     {
  2387.         ATLASSERT(nIndex >= 0 && nIndex < m_nSize);
  2388.         return m_aVal[nIndex];
  2389.     }
  2390.  
  2391. // Implementation
  2392.  
  2393.     template <typename T>
  2394.     class Wrapper
  2395.     {
  2396.     public:
  2397.         Wrapper(T& _t) : t(_t)
  2398.         {
  2399.         }
  2400.         template <typename _Ty>
  2401.         void *operator new(size_t, _Ty* p)
  2402.         {
  2403.             return p;
  2404.         }
  2405.         T t;
  2406.     };
  2407.     void SetAtIndex(int nIndex, TKey& key, TVal& val)
  2408.     {
  2409.         ATLASSERT(nIndex >= 0 && nIndex < m_nSize);
  2410.         new(&m_aKey[nIndex]) Wrapper<TKey>(key);
  2411.         new(&m_aVal[nIndex]) Wrapper<TVal>(val);
  2412.     }
  2413.     int FindKey(TKey& key) const
  2414.     {
  2415.         for(int i = 0; i < m_nSize; i++)
  2416.         {
  2417.             if(m_aKey[i] == key)
  2418.                 return i;
  2419.         }
  2420.         return -1;  // not found
  2421.     }
  2422.     int FindVal(TVal& val) const
  2423.     {
  2424.         for(int i = 0; i < m_nSize; i++)
  2425.         {
  2426.             if(m_aVal[i] == val)
  2427.                 return i;
  2428.         }
  2429.         return -1;  // not found
  2430.     }
  2431. };
  2432.  
  2433.  
  2434. class CComModule;
  2435.  
  2436. #ifndef __BORLANDC__
  2437. __declspec(selectany) CComModule* _pModule=NULL;
  2438.  
  2439. // {B62F5910-6528-11d1-9611-0000F81E0D0D}
  2440. _declspec(selectany) GUID GUID_ATLVer30 = { 0xb62f5910, 0x6528, 0x11d1, { 0x96, 0x11, 0x0, 0x0, 0xf8, 0x1e, 0xd, 0xd } };
  2441.  
  2442. #else
  2443. extern CComModule* _pModule;
  2444. extern "C" GUID GUID_ATLVer30;
  2445. #endif
  2446.  
  2447. class CComModule : public _ATL_MODULE
  2448. {
  2449. // Operations
  2450. public:
  2451.     static GUID m_libid;
  2452. #ifdef _ATL_DEBUG_INTERFACES
  2453.     UINT m_nIndexQI;
  2454.     UINT m_nIndexBreakAt;
  2455.     CSimpleArray<_QIThunk*>* m_paThunks;
  2456. #endif // _ATL_DEBUG_INTERFACES
  2457.  
  2458.     void AddCreateWndData(_AtlCreateWndData* pData, void* pObject)
  2459.     {
  2460.         AtlModuleAddCreateWndData(this, pData, pObject);
  2461.     }
  2462.     void* ExtractCreateWndData()
  2463.     {
  2464.         return AtlModuleExtractCreateWndData(this);
  2465.     }
  2466.  
  2467.     HRESULT Init(_ATL_OBJMAP_ENTRY* p, HINSTANCE h, const GUID* plibid = NULL)
  2468.     {
  2469.         pguidVer = &GUID_ATLVer30;
  2470.         _pModule = this;
  2471.         cbSize = sizeof(_ATL_MODULE);
  2472.         dwAtlBuildVer = _ATL_VER;
  2473.         AtlModuleInit(this, p, h);
  2474.         if (plibid != NULL)
  2475.             memcpy((void*)&m_libid, plibid, sizeof(GUID));
  2476. #ifdef _ATL_MIN_CRT
  2477.         // Create a base heap
  2478.         m_hHeap = HeapCreate(0, 0, 0);
  2479.  
  2480. #ifndef _ATL_NO_MP_HEAP
  2481.         SYSTEM_INFO si;
  2482.         GetSystemInfo(&si);
  2483.         if (si.dwNumberOfProcessors > 1)
  2484.         {
  2485.             DWORD dwHeaps = si.dwNumberOfProcessors * 2;
  2486.             m_dwHeaps = 0xFFFFFFFF;
  2487.             for (int bits = 0; bits < 32; bits++)
  2488.             {
  2489.                 if (dwHeaps & 0x80000000)
  2490.                     break;
  2491.                 dwHeaps <<= 1;
  2492.                 m_dwHeaps >>= 1;
  2493.             }
  2494.             m_dwHeaps >>= 1;
  2495.  
  2496.             // Allocate more heaps for each processor
  2497.             m_phHeaps = (HANDLE*) HeapAlloc(m_hHeap, _ATL_HEAPFLAGS, sizeof(HANDLE) * (m_dwHeaps + 1));
  2498.             for (DWORD i = 0; i <= m_dwHeaps; i++)
  2499.                 m_phHeaps[i] = HeapCreate(0, 0, 0);
  2500.         }
  2501.         else
  2502. #endif
  2503.         {
  2504.             m_phHeaps = NULL;
  2505.             m_dwHeaps = 0;
  2506.         }
  2507. #endif
  2508. #ifdef _ATL_DEBUG_INTERFACES
  2509.         m_nIndexQI = 0;
  2510.         m_nIndexBreakAt = 0;
  2511.         m_paThunks = NULL;
  2512.         ATLTRY(m_paThunks = new CSimpleArray<_QIThunk*>);
  2513.         if (m_paThunks == NULL)
  2514.             return E_OUTOFMEMORY;
  2515. #endif // _ATL_DEBUG_INTERFACES
  2516.         return S_OK;
  2517.     }
  2518. #ifdef _ATL_DEBUG_INTERFACES
  2519.     HRESULT AddThunk(IUnknown** pp, LPCTSTR lpsz, REFIID iid)
  2520.     {
  2521.         if ((pp == NULL) || (*pp == NULL))
  2522.             return E_POINTER;
  2523.         IUnknown* p = *pp;
  2524.         _QIThunk* pThunk = NULL;
  2525.         EnterCriticalSection(&m_csObjMap);
  2526.         // Check if exists already for identity
  2527.         if (InlineIsEqualUnknown(iid))
  2528.         {
  2529.             for (int i = 0; i < m_paThunks->GetSize(); i++)
  2530.             {
  2531.                 if (m_paThunks->operator[](i)->pUnk == p)
  2532.                 {
  2533.                     m_paThunks->operator[](i)->InternalAddRef();
  2534.                     pThunk = m_paThunks->operator[](i);
  2535.                     break;
  2536.                 }
  2537.             }
  2538.         }
  2539.         if (pThunk == NULL)
  2540.         {
  2541.             ++m_nIndexQI;
  2542.             if (m_nIndexBreakAt == m_nIndexQI)
  2543.                 DebugBreak();
  2544.             ATLTRY(pThunk = new _QIThunk(p, lpsz, iid, m_nIndexQI, (m_nIndexBreakAt == m_nIndexQI)));
  2545.             if (pThunk == NULL)
  2546.                 return E_OUTOFMEMORY;
  2547.             pThunk->InternalAddRef();
  2548.             m_paThunks->Add(pThunk);
  2549.         }
  2550.         LeaveCriticalSection(&m_csObjMap);
  2551.         *pp = (IUnknown*)pThunk;
  2552.         return S_OK;
  2553.     }
  2554.     HRESULT AddNonAddRefThunk(IUnknown* p, LPCTSTR lpsz, IUnknown** ppThunkRet)
  2555.     {
  2556.         _QIThunk* pThunk = NULL;
  2557.         EnterCriticalSection(&m_csObjMap);
  2558.         // Check if exists already for identity
  2559.         for (int i = 0; i < m_paThunks->GetSize(); i++)
  2560.         {
  2561.             if (m_paThunks->operator[](i)->pUnk == p)
  2562.             {
  2563.                 m_paThunks->operator[](i)->bNonAddRefThunk = true;
  2564.                 pThunk = m_paThunks->operator[](i);
  2565.                 break;
  2566.             }
  2567.         }
  2568.         if (pThunk == NULL)
  2569.         {
  2570.             ++m_nIndexQI;
  2571.             if (m_nIndexBreakAt == m_nIndexQI)
  2572.                 DebugBreak();
  2573.             ATLTRY(pThunk = new _QIThunk(p, lpsz, IID_IUnknown, m_nIndexQI, (m_nIndexBreakAt == m_nIndexQI)));
  2574.             if (pThunk == NULL)
  2575.             {
  2576.                 *ppThunkRet = NULL;
  2577.                 return E_OUTOFMEMORY;
  2578.             }
  2579.             pThunk->bNonAddRefThunk = true;
  2580.             m_paThunks->Add(pThunk);
  2581.         }
  2582.         LeaveCriticalSection(&m_csObjMap);
  2583.         *ppThunkRet = (IUnknown*)pThunk;
  2584.         return S_OK;;
  2585.     }
  2586.     void DeleteNonAddRefThunk(IUnknown* pUnk)
  2587.     {
  2588.         EnterCriticalSection(&m_csObjMap);
  2589.         for (int i = 0; i < m_paThunks->GetSize(); i++)
  2590.         {
  2591.             if (m_paThunks->operator[](i)->pUnk == pUnk)
  2592.             {
  2593.                 delete m_paThunks->operator[](i);
  2594.                 m_paThunks->RemoveAt(i);
  2595.                 break;
  2596.             }
  2597.         }
  2598.         LeaveCriticalSection(&m_csObjMap);
  2599.     }
  2600.     void DeleteThunk(_QIThunk* p)
  2601.     {
  2602.         EnterCriticalSection(&m_csObjMap);
  2603.         int nIndex = m_paThunks->Find(p);
  2604.         if (nIndex != -1)
  2605.         {
  2606.             delete m_paThunks->operator[](nIndex);
  2607.             m_paThunks->RemoveAt(nIndex);
  2608.         }
  2609.         LeaveCriticalSection(&m_csObjMap);
  2610.     }
  2611.     bool DumpLeakedThunks()
  2612.     {
  2613.         bool b = false;
  2614.         for (int i = 0; i < m_paThunks->GetSize(); i++)
  2615.         {
  2616.             b = true;
  2617.             m_paThunks->operator[](i)->Dump();
  2618.             delete m_paThunks->operator[](i);
  2619.         }
  2620.         m_paThunks->RemoveAll();
  2621.         return b;
  2622.     }
  2623. #endif // _ATL_DEBUG_INTERFACES
  2624.     void Term()
  2625.     {
  2626. #ifdef _ATL_DEBUG_INTERFACES
  2627.         m_bDestroyHeap = false; // prevent heap from going away
  2628.         AtlModuleTerm(this);
  2629.         DumpLeakedThunks();
  2630.         delete m_paThunks;
  2631. #ifndef _ATL_NO_MP_HEAP
  2632.         if (m_phHeaps != NULL)
  2633.         {
  2634.             for (DWORD i = 0; i <= m_dwHeaps; i++)
  2635.                 HeapDestroy(m_phHeaps[i]);
  2636.         }
  2637. #endif
  2638.         if (m_hHeap != NULL)
  2639.             HeapDestroy(m_hHeap);
  2640. #else
  2641.         AtlModuleTerm(this);
  2642. #endif // _ATL_DEBUG_INTERFACES
  2643.     }
  2644.  
  2645.     HRESULT AddTermFunc(_ATL_TERMFUNC* pFunc, DWORD dw)
  2646.     {
  2647.         return AtlModuleAddTermFunc(this, pFunc, dw);
  2648.     }
  2649.  
  2650.     LONG Lock()
  2651.     {
  2652.         return CComGlobalsThreadModel::Increment(&m_nLockCnt);
  2653.     }
  2654.     LONG Unlock()
  2655.     {
  2656.         return CComGlobalsThreadModel::Decrement(&m_nLockCnt);
  2657.     }
  2658.     LONG GetLockCount()
  2659.     {
  2660.         return m_nLockCnt;
  2661.     }
  2662.  
  2663.     HINSTANCE GetModuleInstance() {return m_hInst;}
  2664.     HINSTANCE GetResourceInstance() {return m_hInstResource;}
  2665.     HINSTANCE GetTypeLibInstance() {return m_hInstTypeLib;}
  2666.  
  2667.     // Registry support (helpers)
  2668.     HRESULT RegisterTypeLib()
  2669.     {
  2670.         return AtlModuleRegisterTypeLib(this, NULL);
  2671.     }
  2672.     HRESULT RegisterTypeLib(LPCTSTR lpszIndex)
  2673.     {
  2674.         USES_CONVERSION;
  2675.         return AtlModuleRegisterTypeLib(this, T2COLE(lpszIndex));
  2676.     }
  2677.     HRESULT UnRegisterTypeLib()
  2678.     {
  2679.         return AtlModuleUnRegisterTypeLib(this, NULL);
  2680.     }
  2681.     HRESULT UnRegisterTypeLib(LPCTSTR lpszIndex)
  2682.     {
  2683.         USES_CONVERSION;
  2684.         return AtlModuleUnRegisterTypeLib(this, T2COLE(lpszIndex));
  2685.     }
  2686.     HRESULT RegisterServer(BOOL bRegTypeLib = FALSE, const CLSID* pCLSID = NULL)
  2687.     {
  2688.         return AtlModuleRegisterServer(this, bRegTypeLib, pCLSID);
  2689.     }
  2690.  
  2691.     HRESULT UnregisterServer(const CLSID* pCLSID = NULL)
  2692.     {
  2693.         return AtlModuleUnregisterServer(this, pCLSID);
  2694.     }
  2695.     HRESULT UnregisterServer(BOOL bUnRegTypeLib, const CLSID* pCLSID = NULL)
  2696.     {
  2697.         return AtlModuleUnregisterServerEx(this, bUnRegTypeLib, pCLSID);
  2698.     }
  2699.  
  2700.     // Resource-based Registration
  2701.     HRESULT WINAPI UpdateRegistryFromResourceD(LPCTSTR lpszRes, BOOL bRegister,
  2702.         struct _ATL_REGMAP_ENTRY* pMapEntries = NULL)
  2703.     {
  2704.         USES_CONVERSION;
  2705.         return AtlModuleUpdateRegistryFromResourceD(this, T2COLE(lpszRes), bRegister,
  2706.             pMapEntries);
  2707.     }
  2708.     HRESULT WINAPI UpdateRegistryFromResourceD(UINT nResID, BOOL bRegister,
  2709.         struct _ATL_REGMAP_ENTRY* pMapEntries = NULL)
  2710.     {
  2711.         return AtlModuleUpdateRegistryFromResourceD(this,
  2712.             (LPCOLESTR)MAKEINTRESOURCE(nResID), bRegister, pMapEntries);
  2713.     }
  2714.  
  2715. #ifdef _ATL_STATIC_REGISTRY
  2716.     // Statically linking to Registry Ponent
  2717.     HRESULT WINAPI UpdateRegistryFromResourceS(LPCTSTR lpszRes, BOOL bRegister,
  2718.         struct _ATL_REGMAP_ENTRY* pMapEntries = NULL);
  2719.     HRESULT WINAPI UpdateRegistryFromResourceS(UINT nResID, BOOL bRegister,
  2720.         struct _ATL_REGMAP_ENTRY* pMapEntries = NULL);
  2721. #endif
  2722.  
  2723.     // Standard Registration
  2724.     HRESULT WINAPI UpdateRegistryClass(const CLSID& clsid, LPCTSTR lpszProgID,
  2725.         LPCTSTR lpszVerIndProgID, UINT nDescID, DWORD dwFlags, BOOL bRegister);
  2726.     HRESULT WINAPI RegisterClassHelper(const CLSID& clsid, LPCTSTR lpszProgID,
  2727.         LPCTSTR lpszVerIndProgID, UINT nDescID, DWORD dwFlags);
  2728.     HRESULT WINAPI UnregisterClassHelper(const CLSID& clsid, LPCTSTR lpszProgID,
  2729.         LPCTSTR lpszVerIndProgID);
  2730.  
  2731.     // Register/Revoke All Class Factories with the OS (EXE only)
  2732.     HRESULT RegisterClassObjects(DWORD dwClsContext, DWORD dwFlags)
  2733.     {
  2734.         return AtlModuleRegisterClassObjects(this, dwClsContext, dwFlags);
  2735.     }
  2736.     HRESULT RevokeClassObjects()
  2737.     {
  2738.         return AtlModuleRevokeClassObjects(this);
  2739.     }
  2740.  
  2741.     // Obtain a Class Factory (DLL only)
  2742.     HRESULT GetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv)
  2743.     {
  2744.         return AtlModuleGetClassObject(this, rclsid, riid, ppv);
  2745.     }
  2746.  
  2747.     // Only used in CComAutoThreadModule
  2748.     HRESULT CreateInstance(void* /*pfnCreateInstance*/, REFIID /*riid*/, void** /*ppvObj*/)
  2749.     {
  2750.         ATLASSERT(FALSE);
  2751.         return E_NOTIMPL;
  2752.     }
  2753.     static HRESULT RegisterProgID(LPCTSTR lpszCLSID, LPCTSTR lpszProgID, LPCTSTR lpszUserDesc);
  2754.  
  2755.     static void ReplaceSingleQuote(LPOLESTR lpDest, LPCOLESTR lp)
  2756.     {
  2757.         while (*lp)
  2758.         {
  2759.             *lpDest++ = *lp;
  2760.             if (*lp == OLESTR('\''))
  2761.                 *lpDest++ = *lp;
  2762.             lp++;
  2763.         }
  2764.         *lpDest = NULL;
  2765.     }
  2766. };
  2767.  
  2768. #ifdef _ATL_DEBUG_INTERFACES
  2769. inline ULONG _QIThunk::Release()
  2770. {
  2771.     if (bBreak)
  2772.         DebugBreak();
  2773.     ATLASSERT(m_dwRef > 0);
  2774.     ULONG l = InterlockedDecrement(&m_dwRef);
  2775.     ATLTRACE(_T("%d< "), m_dwRef);
  2776.     AtlDumpIID(iid, lpszClassName, S_OK);
  2777.     pUnk->Release();
  2778.     if (l == 0 && !bNonAddRefThunk)
  2779.         _pModule->DeleteThunk(this);
  2780.     return l;
  2781. }
  2782. inline static void atlBadThunkCall()
  2783. {
  2784.     ATLASSERT(FALSE && "Call through deleted thunk");
  2785. }
  2786. #ifdef __BORLANDC__
  2787. #define IMPL_THUNK(n)\
  2788. __declspec(naked) inline HRESULT _QIThunk::f##n()\
  2789. {\
  2790.         __emit__(0x8b, 0x44, 0x24, 0x04);\
  2791.         if (*(unsigned long*)(_EAX + 8) <= 0) {\
  2792.           atlBadThunkCall();\
  2793.         }\
  2794.         \
  2795.         __emit__(0x8b, 0x44, 0x24, 0x04);\
  2796.         _EAX = *(unsigned long*)(_EAX + 4);\
  2797.         __emit__(0x89, 0x44, 0x24, 0x04);\
  2798.         _EAX = *(unsigned long*)(_EAX);\
  2799.         _EAX = *(unsigned long*)(_EAX + 4 * n);\
  2800.         __emit__(0xff, 0xe0);\
  2801.         return 0; /* can never be executed. suppresses warning. */ \
  2802. }
  2803. #else
  2804. #define IMPL_THUNK(n)\
  2805. __declspec(naked) inline HRESULT _QIThunk::f##n()\
  2806. {\
  2807.     __asm mov eax, [esp+4]\
  2808.     __asm cmp dword ptr [eax+8], 0\
  2809.     __asm jg goodref\
  2810.     __asm call atlBadThunkCall\
  2811.     __asm goodref:\
  2812.     __asm mov eax, [esp+4]\
  2813.     __asm mov eax, dword ptr [eax+4]\
  2814.     __asm mov [esp+4], eax\
  2815.     __asm mov eax, dword ptr [eax]\
  2816.     __asm mov eax, dword ptr [eax+4*n]\
  2817.     __asm jmp eax\
  2818. }
  2819. #endif
  2820.  
  2821. IMPL_THUNK(3)
  2822. IMPL_THUNK(4)
  2823. IMPL_THUNK(5)
  2824. IMPL_THUNK(6)
  2825. IMPL_THUNK(7)
  2826. IMPL_THUNK(8)
  2827. IMPL_THUNK(9)
  2828. IMPL_THUNK(10)
  2829. IMPL_THUNK(11)
  2830. IMPL_THUNK(12)
  2831. IMPL_THUNK(13)
  2832. IMPL_THUNK(14)
  2833. IMPL_THUNK(15)
  2834. IMPL_THUNK(16)
  2835. IMPL_THUNK(17)
  2836. IMPL_THUNK(18)
  2837. IMPL_THUNK(19)
  2838. IMPL_THUNK(20)
  2839. IMPL_THUNK(21)
  2840. IMPL_THUNK(22)
  2841. IMPL_THUNK(23)
  2842. IMPL_THUNK(24)
  2843. IMPL_THUNK(25)
  2844. IMPL_THUNK(26)
  2845. IMPL_THUNK(27)
  2846. IMPL_THUNK(28)
  2847. IMPL_THUNK(29)
  2848. IMPL_THUNK(30)
  2849. IMPL_THUNK(31)
  2850. IMPL_THUNK(32)
  2851. IMPL_THUNK(33)
  2852. IMPL_THUNK(34)
  2853. IMPL_THUNK(35)
  2854. IMPL_THUNK(36)
  2855. IMPL_THUNK(37)
  2856. IMPL_THUNK(38)
  2857. IMPL_THUNK(39)
  2858. IMPL_THUNK(40)
  2859. IMPL_THUNK(41)
  2860. IMPL_THUNK(42)
  2861. IMPL_THUNK(43)
  2862. IMPL_THUNK(44)
  2863. IMPL_THUNK(45)
  2864. IMPL_THUNK(46)
  2865. IMPL_THUNK(47)
  2866. IMPL_THUNK(48)
  2867. IMPL_THUNK(49)
  2868. IMPL_THUNK(50)
  2869. IMPL_THUNK(51)
  2870. IMPL_THUNK(52)
  2871. IMPL_THUNK(53)
  2872. IMPL_THUNK(54)
  2873. IMPL_THUNK(55)
  2874. IMPL_THUNK(56)
  2875. IMPL_THUNK(57)
  2876. IMPL_THUNK(58)
  2877. IMPL_THUNK(59)
  2878. IMPL_THUNK(60)
  2879. IMPL_THUNK(61)
  2880. IMPL_THUNK(62)
  2881. IMPL_THUNK(63)
  2882. IMPL_THUNK(64)
  2883. IMPL_THUNK(65)
  2884. IMPL_THUNK(66)
  2885. IMPL_THUNK(67)
  2886. IMPL_THUNK(68)
  2887. IMPL_THUNK(69)
  2888. IMPL_THUNK(70)
  2889. IMPL_THUNK(71)
  2890. IMPL_THUNK(72)
  2891. IMPL_THUNK(73)
  2892. IMPL_THUNK(74)
  2893. IMPL_THUNK(75)
  2894. IMPL_THUNK(76)
  2895. IMPL_THUNK(77)
  2896. IMPL_THUNK(78)
  2897. IMPL_THUNK(79)
  2898. IMPL_THUNK(80)
  2899. IMPL_THUNK(81)
  2900. IMPL_THUNK(82)
  2901. IMPL_THUNK(83)
  2902. IMPL_THUNK(84)
  2903. IMPL_THUNK(85)
  2904. IMPL_THUNK(86)
  2905. IMPL_THUNK(87)
  2906. IMPL_THUNK(88)
  2907. IMPL_THUNK(89)
  2908. IMPL_THUNK(90)
  2909. IMPL_THUNK(91)
  2910. IMPL_THUNK(92)
  2911. IMPL_THUNK(93)
  2912. IMPL_THUNK(94)
  2913. IMPL_THUNK(95)
  2914. IMPL_THUNK(96)
  2915. IMPL_THUNK(97)
  2916. IMPL_THUNK(98)
  2917. IMPL_THUNK(99)
  2918. IMPL_THUNK(100)
  2919. IMPL_THUNK(101)
  2920. IMPL_THUNK(102)
  2921. IMPL_THUNK(103)
  2922. IMPL_THUNK(104)
  2923. IMPL_THUNK(105)
  2924. IMPL_THUNK(106)
  2925. IMPL_THUNK(107)
  2926. IMPL_THUNK(108)
  2927. IMPL_THUNK(109)
  2928. IMPL_THUNK(110)
  2929. IMPL_THUNK(111)
  2930. IMPL_THUNK(112)
  2931. IMPL_THUNK(113)
  2932. IMPL_THUNK(114)
  2933. IMPL_THUNK(115)
  2934. IMPL_THUNK(116)
  2935. IMPL_THUNK(117)
  2936. IMPL_THUNK(118)
  2937. IMPL_THUNK(119)
  2938. IMPL_THUNK(120)
  2939. IMPL_THUNK(121)
  2940. IMPL_THUNK(122)
  2941. IMPL_THUNK(123)
  2942. IMPL_THUNK(124)
  2943. IMPL_THUNK(125)
  2944. IMPL_THUNK(126)
  2945. IMPL_THUNK(127)
  2946. IMPL_THUNK(128)
  2947. IMPL_THUNK(129)
  2948. IMPL_THUNK(130)
  2949. IMPL_THUNK(131)
  2950. IMPL_THUNK(132)
  2951. IMPL_THUNK(133)
  2952. IMPL_THUNK(134)
  2953. IMPL_THUNK(135)
  2954. IMPL_THUNK(136)
  2955. IMPL_THUNK(137)
  2956. IMPL_THUNK(138)
  2957. IMPL_THUNK(139)
  2958. IMPL_THUNK(140)
  2959. IMPL_THUNK(141)
  2960. IMPL_THUNK(142)
  2961. IMPL_THUNK(143)
  2962. IMPL_THUNK(144)
  2963. IMPL_THUNK(145)
  2964. IMPL_THUNK(146)
  2965. IMPL_THUNK(147)
  2966. IMPL_THUNK(148)
  2967. IMPL_THUNK(149)
  2968. IMPL_THUNK(150)
  2969. IMPL_THUNK(151)
  2970. IMPL_THUNK(152)
  2971. IMPL_THUNK(153)
  2972. IMPL_THUNK(154)
  2973. IMPL_THUNK(155)
  2974. IMPL_THUNK(156)
  2975. IMPL_THUNK(157)
  2976. IMPL_THUNK(158)
  2977. IMPL_THUNK(159)
  2978. IMPL_THUNK(160)
  2979. IMPL_THUNK(161)
  2980. IMPL_THUNK(162)
  2981. IMPL_THUNK(163)
  2982. IMPL_THUNK(164)
  2983. IMPL_THUNK(165)
  2984. IMPL_THUNK(166)
  2985. IMPL_THUNK(167)
  2986. IMPL_THUNK(168)
  2987. IMPL_THUNK(169)
  2988. IMPL_THUNK(170)
  2989. IMPL_THUNK(171)
  2990. IMPL_THUNK(172)
  2991. IMPL_THUNK(173)
  2992. IMPL_THUNK(174)
  2993. IMPL_THUNK(175)
  2994. IMPL_THUNK(176)
  2995. IMPL_THUNK(177)
  2996. IMPL_THUNK(178)
  2997. IMPL_THUNK(179)
  2998. IMPL_THUNK(180)
  2999. IMPL_THUNK(181)
  3000. IMPL_THUNK(182)
  3001. IMPL_THUNK(183)
  3002. IMPL_THUNK(184)
  3003. IMPL_THUNK(185)
  3004. IMPL_THUNK(186)
  3005. IMPL_THUNK(187)
  3006. IMPL_THUNK(188)
  3007. IMPL_THUNK(189)
  3008. IMPL_THUNK(190)
  3009. IMPL_THUNK(191)
  3010. IMPL_THUNK(192)
  3011. IMPL_THUNK(193)
  3012. IMPL_THUNK(194)
  3013. IMPL_THUNK(195)
  3014. IMPL_THUNK(196)
  3015. IMPL_THUNK(197)
  3016. IMPL_THUNK(198)
  3017. IMPL_THUNK(199)
  3018. IMPL_THUNK(200)
  3019. IMPL_THUNK(201)
  3020. IMPL_THUNK(202)
  3021. IMPL_THUNK(203)
  3022. IMPL_THUNK(204)
  3023. IMPL_THUNK(205)
  3024. IMPL_THUNK(206)
  3025. IMPL_THUNK(207)
  3026. IMPL_THUNK(208)
  3027. IMPL_THUNK(209)
  3028. IMPL_THUNK(210)
  3029. IMPL_THUNK(211)
  3030. IMPL_THUNK(212)
  3031. IMPL_THUNK(213)
  3032. IMPL_THUNK(214)
  3033. IMPL_THUNK(215)
  3034. IMPL_THUNK(216)
  3035. IMPL_THUNK(217)
  3036. IMPL_THUNK(218)
  3037. IMPL_THUNK(219)
  3038. IMPL_THUNK(220)
  3039. IMPL_THUNK(221)
  3040. IMPL_THUNK(222)
  3041. IMPL_THUNK(223)
  3042. IMPL_THUNK(224)
  3043. IMPL_THUNK(225)
  3044. IMPL_THUNK(226)
  3045. IMPL_THUNK(227)
  3046. IMPL_THUNK(228)
  3047. IMPL_THUNK(229)
  3048. IMPL_THUNK(230)
  3049. IMPL_THUNK(231)
  3050. IMPL_THUNK(232)
  3051. IMPL_THUNK(233)
  3052. IMPL_THUNK(234)
  3053. IMPL_THUNK(235)
  3054. IMPL_THUNK(236)
  3055. IMPL_THUNK(237)
  3056. IMPL_THUNK(238)
  3057. IMPL_THUNK(239)
  3058. IMPL_THUNK(240)
  3059. IMPL_THUNK(241)
  3060. IMPL_THUNK(242)
  3061. IMPL_THUNK(243)
  3062. IMPL_THUNK(244)
  3063. IMPL_THUNK(245)
  3064. IMPL_THUNK(246)
  3065. IMPL_THUNK(247)
  3066. IMPL_THUNK(248)
  3067. IMPL_THUNK(249)
  3068. IMPL_THUNK(250)
  3069. IMPL_THUNK(251)
  3070. IMPL_THUNK(252)
  3071. IMPL_THUNK(253)
  3072. IMPL_THUNK(254)
  3073. IMPL_THUNK(255)
  3074. IMPL_THUNK(256)
  3075. IMPL_THUNK(257)
  3076. IMPL_THUNK(258)
  3077. IMPL_THUNK(259)
  3078. IMPL_THUNK(260)
  3079. IMPL_THUNK(261)
  3080. IMPL_THUNK(262)
  3081. IMPL_THUNK(263)
  3082. IMPL_THUNK(264)
  3083. IMPL_THUNK(265)
  3084. IMPL_THUNK(266)
  3085. IMPL_THUNK(267)
  3086. IMPL_THUNK(268)
  3087. IMPL_THUNK(269)
  3088. IMPL_THUNK(270)
  3089. IMPL_THUNK(271)
  3090. IMPL_THUNK(272)
  3091. IMPL_THUNK(273)
  3092. IMPL_THUNK(274)
  3093. IMPL_THUNK(275)
  3094. IMPL_THUNK(276)
  3095. IMPL_THUNK(277)
  3096. IMPL_THUNK(278)
  3097. IMPL_THUNK(279)
  3098. IMPL_THUNK(280)
  3099. IMPL_THUNK(281)
  3100. IMPL_THUNK(282)
  3101. IMPL_THUNK(283)
  3102. IMPL_THUNK(284)
  3103. IMPL_THUNK(285)
  3104. IMPL_THUNK(286)
  3105. IMPL_THUNK(287)
  3106. IMPL_THUNK(288)
  3107. IMPL_THUNK(289)
  3108. IMPL_THUNK(290)
  3109. IMPL_THUNK(291)
  3110. IMPL_THUNK(292)
  3111. IMPL_THUNK(293)
  3112. IMPL_THUNK(294)
  3113. IMPL_THUNK(295)
  3114. IMPL_THUNK(296)
  3115. IMPL_THUNK(297)
  3116. IMPL_THUNK(298)
  3117. IMPL_THUNK(299)
  3118. IMPL_THUNK(300)
  3119. IMPL_THUNK(301)
  3120. IMPL_THUNK(302)
  3121. IMPL_THUNK(303)
  3122. IMPL_THUNK(304)
  3123. IMPL_THUNK(305)
  3124. IMPL_THUNK(306)
  3125. IMPL_THUNK(307)
  3126. IMPL_THUNK(308)
  3127. IMPL_THUNK(309)
  3128. IMPL_THUNK(310)
  3129. IMPL_THUNK(311)
  3130. IMPL_THUNK(312)
  3131. IMPL_THUNK(313)
  3132. IMPL_THUNK(314)
  3133. IMPL_THUNK(315)
  3134. IMPL_THUNK(316)
  3135. IMPL_THUNK(317)
  3136. IMPL_THUNK(318)
  3137. IMPL_THUNK(319)
  3138. IMPL_THUNK(320)
  3139. IMPL_THUNK(321)
  3140. IMPL_THUNK(322)
  3141. IMPL_THUNK(323)
  3142. IMPL_THUNK(324)
  3143. IMPL_THUNK(325)
  3144. IMPL_THUNK(326)
  3145. IMPL_THUNK(327)
  3146. IMPL_THUNK(328)
  3147. IMPL_THUNK(329)
  3148. IMPL_THUNK(330)
  3149. IMPL_THUNK(331)
  3150. IMPL_THUNK(332)
  3151. IMPL_THUNK(333)
  3152. IMPL_THUNK(334)
  3153. IMPL_THUNK(335)
  3154. IMPL_THUNK(336)
  3155. IMPL_THUNK(337)
  3156. IMPL_THUNK(338)
  3157. IMPL_THUNK(339)
  3158. IMPL_THUNK(340)
  3159. IMPL_THUNK(341)
  3160. IMPL_THUNK(342)
  3161. IMPL_THUNK(343)
  3162. IMPL_THUNK(344)
  3163. IMPL_THUNK(345)
  3164. IMPL_THUNK(346)
  3165. IMPL_THUNK(347)
  3166. IMPL_THUNK(348)
  3167. IMPL_THUNK(349)
  3168. IMPL_THUNK(350)
  3169. IMPL_THUNK(351)
  3170. IMPL_THUNK(352)
  3171. IMPL_THUNK(353)
  3172. IMPL_THUNK(354)
  3173. IMPL_THUNK(355)
  3174. IMPL_THUNK(356)
  3175. IMPL_THUNK(357)
  3176. IMPL_THUNK(358)
  3177. IMPL_THUNK(359)
  3178. IMPL_THUNK(360)
  3179. IMPL_THUNK(361)
  3180. IMPL_THUNK(362)
  3181. IMPL_THUNK(363)
  3182. IMPL_THUNK(364)
  3183. IMPL_THUNK(365)
  3184. IMPL_THUNK(366)
  3185. IMPL_THUNK(367)
  3186. IMPL_THUNK(368)
  3187. IMPL_THUNK(369)
  3188. IMPL_THUNK(370)
  3189. IMPL_THUNK(371)
  3190. IMPL_THUNK(372)
  3191. IMPL_THUNK(373)
  3192. IMPL_THUNK(374)
  3193. IMPL_THUNK(375)
  3194. IMPL_THUNK(376)
  3195. IMPL_THUNK(377)
  3196. IMPL_THUNK(378)
  3197. IMPL_THUNK(379)
  3198. IMPL_THUNK(380)
  3199. IMPL_THUNK(381)
  3200. IMPL_THUNK(382)
  3201. IMPL_THUNK(383)
  3202. IMPL_THUNK(384)
  3203. IMPL_THUNK(385)
  3204. IMPL_THUNK(386)
  3205. IMPL_THUNK(387)
  3206. IMPL_THUNK(388)
  3207. IMPL_THUNK(389)
  3208. IMPL_THUNK(390)
  3209. IMPL_THUNK(391)
  3210. IMPL_THUNK(392)
  3211. IMPL_THUNK(393)
  3212. IMPL_THUNK(394)
  3213. IMPL_THUNK(395)
  3214. IMPL_THUNK(396)
  3215. IMPL_THUNK(397)
  3216. IMPL_THUNK(398)
  3217. IMPL_THUNK(399)
  3218. IMPL_THUNK(400)
  3219. IMPL_THUNK(401)
  3220. IMPL_THUNK(402)
  3221. IMPL_THUNK(403)
  3222. IMPL_THUNK(404)
  3223. IMPL_THUNK(405)
  3224. IMPL_THUNK(406)
  3225. IMPL_THUNK(407)
  3226. IMPL_THUNK(408)
  3227. IMPL_THUNK(409)
  3228. IMPL_THUNK(410)
  3229. IMPL_THUNK(411)
  3230. IMPL_THUNK(412)
  3231. IMPL_THUNK(413)
  3232. IMPL_THUNK(414)
  3233. IMPL_THUNK(415)
  3234. IMPL_THUNK(416)
  3235. IMPL_THUNK(417)
  3236. IMPL_THUNK(418)
  3237. IMPL_THUNK(419)
  3238. IMPL_THUNK(420)
  3239. IMPL_THUNK(421)
  3240. IMPL_THUNK(422)
  3241. IMPL_THUNK(423)
  3242. IMPL_THUNK(424)
  3243. IMPL_THUNK(425)
  3244. IMPL_THUNK(426)
  3245. IMPL_THUNK(427)
  3246. IMPL_THUNK(428)
  3247. IMPL_THUNK(429)
  3248. IMPL_THUNK(430)
  3249. IMPL_THUNK(431)
  3250. IMPL_THUNK(432)
  3251. IMPL_THUNK(433)
  3252. IMPL_THUNK(434)
  3253. IMPL_THUNK(435)
  3254. IMPL_THUNK(436)
  3255. IMPL_THUNK(437)
  3256. IMPL_THUNK(438)
  3257. IMPL_THUNK(439)
  3258. IMPL_THUNK(440)
  3259. IMPL_THUNK(441)
  3260. IMPL_THUNK(442)
  3261. IMPL_THUNK(443)
  3262. IMPL_THUNK(444)
  3263. IMPL_THUNK(445)
  3264. IMPL_THUNK(446)
  3265. IMPL_THUNK(447)
  3266. IMPL_THUNK(448)
  3267. IMPL_THUNK(449)
  3268. IMPL_THUNK(450)
  3269. IMPL_THUNK(451)
  3270. IMPL_THUNK(452)
  3271. IMPL_THUNK(453)
  3272. IMPL_THUNK(454)
  3273. IMPL_THUNK(455)
  3274. IMPL_THUNK(456)
  3275. IMPL_THUNK(457)
  3276. IMPL_THUNK(458)
  3277. IMPL_THUNK(459)
  3278. IMPL_THUNK(460)
  3279. IMPL_THUNK(461)
  3280. IMPL_THUNK(462)
  3281. IMPL_THUNK(463)
  3282. IMPL_THUNK(464)
  3283. IMPL_THUNK(465)
  3284. IMPL_THUNK(466)
  3285. IMPL_THUNK(467)
  3286. IMPL_THUNK(468)
  3287. IMPL_THUNK(469)
  3288. IMPL_THUNK(470)
  3289. IMPL_THUNK(471)
  3290. IMPL_THUNK(472)
  3291. IMPL_THUNK(473)
  3292. IMPL_THUNK(474)
  3293. IMPL_THUNK(475)
  3294. IMPL_THUNK(476)
  3295. IMPL_THUNK(477)
  3296. IMPL_THUNK(478)
  3297. IMPL_THUNK(479)
  3298. IMPL_THUNK(480)
  3299. IMPL_THUNK(481)
  3300. IMPL_THUNK(482)
  3301. IMPL_THUNK(483)
  3302. IMPL_THUNK(484)
  3303. IMPL_THUNK(485)
  3304. IMPL_THUNK(486)
  3305. IMPL_THUNK(487)
  3306. IMPL_THUNK(488)
  3307. IMPL_THUNK(489)
  3308. IMPL_THUNK(490)
  3309. IMPL_THUNK(491)
  3310. IMPL_THUNK(492)
  3311. IMPL_THUNK(493)
  3312. IMPL_THUNK(494)
  3313. IMPL_THUNK(495)
  3314. IMPL_THUNK(496)
  3315. IMPL_THUNK(497)
  3316. IMPL_THUNK(498)
  3317. IMPL_THUNK(499)
  3318. IMPL_THUNK(500)
  3319. IMPL_THUNK(501)
  3320. IMPL_THUNK(502)
  3321. IMPL_THUNK(503)
  3322. IMPL_THUNK(504)
  3323. IMPL_THUNK(505)
  3324. IMPL_THUNK(506)
  3325. IMPL_THUNK(507)
  3326. IMPL_THUNK(508)
  3327. IMPL_THUNK(509)
  3328. IMPL_THUNK(510)
  3329. IMPL_THUNK(511)
  3330. IMPL_THUNK(512)
  3331. IMPL_THUNK(513)
  3332. IMPL_THUNK(514)
  3333. IMPL_THUNK(515)
  3334. IMPL_THUNK(516)
  3335. IMPL_THUNK(517)
  3336. IMPL_THUNK(518)
  3337. IMPL_THUNK(519)
  3338. IMPL_THUNK(520)
  3339. IMPL_THUNK(521)
  3340. IMPL_THUNK(522)
  3341. IMPL_THUNK(523)
  3342. IMPL_THUNK(524)
  3343. IMPL_THUNK(525)
  3344. IMPL_THUNK(526)
  3345. IMPL_THUNK(527)
  3346. IMPL_THUNK(528)
  3347. IMPL_THUNK(529)
  3348. IMPL_THUNK(530)
  3349. IMPL_THUNK(531)
  3350. IMPL_THUNK(532)
  3351. IMPL_THUNK(533)
  3352. IMPL_THUNK(534)
  3353. IMPL_THUNK(535)
  3354. IMPL_THUNK(536)
  3355. IMPL_THUNK(537)
  3356. IMPL_THUNK(538)
  3357. IMPL_THUNK(539)
  3358. IMPL_THUNK(540)
  3359. IMPL_THUNK(541)
  3360. IMPL_THUNK(542)
  3361. IMPL_THUNK(543)
  3362. IMPL_THUNK(544)
  3363. IMPL_THUNK(545)
  3364. IMPL_THUNK(546)
  3365. IMPL_THUNK(547)
  3366. IMPL_THUNK(548)
  3367. IMPL_THUNK(549)
  3368. IMPL_THUNK(550)
  3369. IMPL_THUNK(551)
  3370. IMPL_THUNK(552)
  3371. IMPL_THUNK(553)
  3372. IMPL_THUNK(554)
  3373. IMPL_THUNK(555)
  3374. IMPL_THUNK(556)
  3375. IMPL_THUNK(557)
  3376. IMPL_THUNK(558)
  3377. IMPL_THUNK(559)
  3378. IMPL_THUNK(560)
  3379. IMPL_THUNK(561)
  3380. IMPL_THUNK(562)
  3381. IMPL_THUNK(563)
  3382. IMPL_THUNK(564)
  3383. IMPL_THUNK(565)
  3384. IMPL_THUNK(566)
  3385. IMPL_THUNK(567)
  3386. IMPL_THUNK(568)
  3387. IMPL_THUNK(569)
  3388. IMPL_THUNK(570)
  3389. IMPL_THUNK(571)
  3390. IMPL_THUNK(572)
  3391. IMPL_THUNK(573)
  3392. IMPL_THUNK(574)
  3393. IMPL_THUNK(575)
  3394. IMPL_THUNK(576)
  3395. IMPL_THUNK(577)
  3396. IMPL_THUNK(578)
  3397. IMPL_THUNK(579)
  3398. IMPL_THUNK(580)
  3399. IMPL_THUNK(581)
  3400. IMPL_THUNK(582)
  3401. IMPL_THUNK(583)
  3402. IMPL_THUNK(584)
  3403. IMPL_THUNK(585)
  3404. IMPL_THUNK(586)
  3405. IMPL_THUNK(587)
  3406. IMPL_THUNK(588)
  3407. IMPL_THUNK(589)
  3408. IMPL_THUNK(590)
  3409. IMPL_THUNK(591)
  3410. IMPL_THUNK(592)
  3411. IMPL_THUNK(593)
  3412. IMPL_THUNK(594)
  3413. IMPL_THUNK(595)
  3414. IMPL_THUNK(596)
  3415. IMPL_THUNK(597)
  3416. IMPL_THUNK(598)
  3417. IMPL_THUNK(599)
  3418. IMPL_THUNK(600)
  3419. IMPL_THUNK(601)
  3420. IMPL_THUNK(602)
  3421. IMPL_THUNK(603)
  3422. IMPL_THUNK(604)
  3423. IMPL_THUNK(605)
  3424. IMPL_THUNK(606)
  3425. IMPL_THUNK(607)
  3426. IMPL_THUNK(608)
  3427. IMPL_THUNK(609)
  3428. IMPL_THUNK(610)
  3429. IMPL_THUNK(611)
  3430. IMPL_THUNK(612)
  3431. IMPL_THUNK(613)
  3432. IMPL_THUNK(614)
  3433. IMPL_THUNK(615)
  3434. IMPL_THUNK(616)
  3435. IMPL_THUNK(617)
  3436. IMPL_THUNK(618)
  3437. IMPL_THUNK(619)
  3438. IMPL_THUNK(620)
  3439. IMPL_THUNK(621)
  3440. IMPL_THUNK(622)
  3441. IMPL_THUNK(623)
  3442. IMPL_THUNK(624)
  3443. IMPL_THUNK(625)
  3444. IMPL_THUNK(626)
  3445. IMPL_THUNK(627)
  3446. IMPL_THUNK(628)
  3447. IMPL_THUNK(629)
  3448. IMPL_THUNK(630)
  3449. IMPL_THUNK(631)
  3450. IMPL_THUNK(632)
  3451. IMPL_THUNK(633)
  3452. IMPL_THUNK(634)
  3453. IMPL_THUNK(635)
  3454. IMPL_THUNK(636)
  3455. IMPL_THUNK(637)
  3456. IMPL_THUNK(638)
  3457. IMPL_THUNK(639)
  3458. IMPL_THUNK(640)
  3459. IMPL_THUNK(641)
  3460. IMPL_THUNK(642)
  3461. IMPL_THUNK(643)
  3462. IMPL_THUNK(644)
  3463. IMPL_THUNK(645)
  3464. IMPL_THUNK(646)
  3465. IMPL_THUNK(647)
  3466. IMPL_THUNK(648)
  3467. IMPL_THUNK(649)
  3468. IMPL_THUNK(650)
  3469. IMPL_THUNK(651)
  3470. IMPL_THUNK(652)
  3471. IMPL_THUNK(653)
  3472. IMPL_THUNK(654)
  3473. IMPL_THUNK(655)
  3474. IMPL_THUNK(656)
  3475. IMPL_THUNK(657)
  3476. IMPL_THUNK(658)
  3477. IMPL_THUNK(659)
  3478. IMPL_THUNK(660)
  3479. IMPL_THUNK(661)
  3480. IMPL_THUNK(662)
  3481. IMPL_THUNK(663)
  3482. IMPL_THUNK(664)
  3483. IMPL_THUNK(665)
  3484. IMPL_THUNK(666)
  3485. IMPL_THUNK(667)
  3486. IMPL_THUNK(668)
  3487. IMPL_THUNK(669)
  3488. IMPL_THUNK(670)
  3489. IMPL_THUNK(671)
  3490. IMPL_THUNK(672)
  3491. IMPL_THUNK(673)
  3492. IMPL_THUNK(674)
  3493. IMPL_THUNK(675)
  3494. IMPL_THUNK(676)
  3495. IMPL_THUNK(677)
  3496. IMPL_THUNK(678)
  3497. IMPL_THUNK(679)
  3498. IMPL_THUNK(680)
  3499. IMPL_THUNK(681)
  3500. IMPL_THUNK(682)
  3501. IMPL_THUNK(683)
  3502. IMPL_THUNK(684)
  3503. IMPL_THUNK(685)
  3504. IMPL_THUNK(686)
  3505. IMPL_THUNK(687)
  3506. IMPL_THUNK(688)
  3507. IMPL_THUNK(689)
  3508. IMPL_THUNK(690)
  3509. IMPL_THUNK(691)
  3510. IMPL_THUNK(692)
  3511. IMPL_THUNK(693)
  3512. IMPL_THUNK(694)
  3513. IMPL_THUNK(695)
  3514. IMPL_THUNK(696)
  3515. IMPL_THUNK(697)
  3516. IMPL_THUNK(698)
  3517. IMPL_THUNK(699)
  3518. IMPL_THUNK(700)
  3519. IMPL_THUNK(701)
  3520. IMPL_THUNK(702)
  3521. IMPL_THUNK(703)
  3522. IMPL_THUNK(704)
  3523. IMPL_THUNK(705)
  3524. IMPL_THUNK(706)
  3525. IMPL_THUNK(707)
  3526. IMPL_THUNK(708)
  3527. IMPL_THUNK(709)
  3528. IMPL_THUNK(710)
  3529. IMPL_THUNK(711)
  3530. IMPL_THUNK(712)
  3531. IMPL_THUNK(713)
  3532. IMPL_THUNK(714)
  3533. IMPL_THUNK(715)
  3534. IMPL_THUNK(716)
  3535. IMPL_THUNK(717)
  3536. IMPL_THUNK(718)
  3537. IMPL_THUNK(719)
  3538. IMPL_THUNK(720)
  3539. IMPL_THUNK(721)
  3540. IMPL_THUNK(722)
  3541. IMPL_THUNK(723)
  3542. IMPL_THUNK(724)
  3543. IMPL_THUNK(725)
  3544. IMPL_THUNK(726)
  3545. IMPL_THUNK(727)
  3546. IMPL_THUNK(728)
  3547. IMPL_THUNK(729)
  3548. IMPL_THUNK(730)
  3549. IMPL_THUNK(731)
  3550. IMPL_THUNK(732)
  3551. IMPL_THUNK(733)
  3552. IMPL_THUNK(734)
  3553. IMPL_THUNK(735)
  3554. IMPL_THUNK(736)
  3555. IMPL_THUNK(737)
  3556. IMPL_THUNK(738)
  3557. IMPL_THUNK(739)
  3558. IMPL_THUNK(740)
  3559. IMPL_THUNK(741)
  3560. IMPL_THUNK(742)
  3561. IMPL_THUNK(743)
  3562. IMPL_THUNK(744)
  3563. IMPL_THUNK(745)
  3564. IMPL_THUNK(746)
  3565. IMPL_THUNK(747)
  3566. IMPL_THUNK(748)
  3567. IMPL_THUNK(749)
  3568. IMPL_THUNK(750)
  3569. IMPL_THUNK(751)
  3570. IMPL_THUNK(752)
  3571. IMPL_THUNK(753)
  3572. IMPL_THUNK(754)
  3573. IMPL_THUNK(755)
  3574. IMPL_THUNK(756)
  3575. IMPL_THUNK(757)
  3576. IMPL_THUNK(758)
  3577. IMPL_THUNK(759)
  3578. IMPL_THUNK(760)
  3579. IMPL_THUNK(761)
  3580. IMPL_THUNK(762)
  3581. IMPL_THUNK(763)
  3582. IMPL_THUNK(764)
  3583. IMPL_THUNK(765)
  3584. IMPL_THUNK(766)
  3585. IMPL_THUNK(767)
  3586. IMPL_THUNK(768)
  3587. IMPL_THUNK(769)
  3588. IMPL_THUNK(770)
  3589. IMPL_THUNK(771)
  3590. IMPL_THUNK(772)
  3591. IMPL_THUNK(773)
  3592. IMPL_THUNK(774)
  3593. IMPL_THUNK(775)
  3594. IMPL_THUNK(776)
  3595. IMPL_THUNK(777)
  3596. IMPL_THUNK(778)
  3597. IMPL_THUNK(779)
  3598. IMPL_THUNK(780)
  3599. IMPL_THUNK(781)
  3600. IMPL_THUNK(782)
  3601. IMPL_THUNK(783)
  3602. IMPL_THUNK(784)
  3603. IMPL_THUNK(785)
  3604. IMPL_THUNK(786)
  3605. IMPL_THUNK(787)
  3606. IMPL_THUNK(788)
  3607. IMPL_THUNK(789)
  3608. IMPL_THUNK(790)
  3609. IMPL_THUNK(791)
  3610. IMPL_THUNK(792)
  3611. IMPL_THUNK(793)
  3612. IMPL_THUNK(794)
  3613. IMPL_THUNK(795)
  3614. IMPL_THUNK(796)
  3615. IMPL_THUNK(797)
  3616. IMPL_THUNK(798)
  3617. IMPL_THUNK(799)
  3618. IMPL_THUNK(800)
  3619. IMPL_THUNK(801)
  3620. IMPL_THUNK(802)
  3621. IMPL_THUNK(803)
  3622. IMPL_THUNK(804)
  3623. IMPL_THUNK(805)
  3624. IMPL_THUNK(806)
  3625. IMPL_THUNK(807)
  3626. IMPL_THUNK(808)
  3627. IMPL_THUNK(809)
  3628. IMPL_THUNK(810)
  3629. IMPL_THUNK(811)
  3630. IMPL_THUNK(812)
  3631. IMPL_THUNK(813)
  3632. IMPL_THUNK(814)
  3633. IMPL_THUNK(815)
  3634. IMPL_THUNK(816)
  3635. IMPL_THUNK(817)
  3636. IMPL_THUNK(818)
  3637. IMPL_THUNK(819)
  3638. IMPL_THUNK(820)
  3639. IMPL_THUNK(821)
  3640. IMPL_THUNK(822)
  3641. IMPL_THUNK(823)
  3642. IMPL_THUNK(824)
  3643. IMPL_THUNK(825)
  3644. IMPL_THUNK(826)
  3645. IMPL_THUNK(827)
  3646. IMPL_THUNK(828)
  3647. IMPL_THUNK(829)
  3648. IMPL_THUNK(830)
  3649. IMPL_THUNK(831)
  3650. IMPL_THUNK(832)
  3651. IMPL_THUNK(833)
  3652. IMPL_THUNK(834)
  3653. IMPL_THUNK(835)
  3654. IMPL_THUNK(836)
  3655. IMPL_THUNK(837)
  3656. IMPL_THUNK(838)
  3657. IMPL_THUNK(839)
  3658. IMPL_THUNK(840)
  3659. IMPL_THUNK(841)
  3660. IMPL_THUNK(842)
  3661. IMPL_THUNK(843)
  3662. IMPL_THUNK(844)
  3663. IMPL_THUNK(845)
  3664. IMPL_THUNK(846)
  3665. IMPL_THUNK(847)
  3666. IMPL_THUNK(848)
  3667. IMPL_THUNK(849)
  3668. IMPL_THUNK(850)
  3669. IMPL_THUNK(851)
  3670. IMPL_THUNK(852)
  3671. IMPL_THUNK(853)
  3672. IMPL_THUNK(854)
  3673. IMPL_THUNK(855)
  3674. IMPL_THUNK(856)
  3675. IMPL_THUNK(857)
  3676. IMPL_THUNK(858)
  3677. IMPL_THUNK(859)
  3678. IMPL_THUNK(860)
  3679. IMPL_THUNK(861)
  3680. IMPL_THUNK(862)
  3681. IMPL_THUNK(863)
  3682. IMPL_THUNK(864)
  3683. IMPL_THUNK(865)
  3684. IMPL_THUNK(866)
  3685. IMPL_THUNK(867)
  3686. IMPL_THUNK(868)
  3687. IMPL_THUNK(869)
  3688. IMPL_THUNK(870)
  3689. IMPL_THUNK(871)
  3690. IMPL_THUNK(872)
  3691. IMPL_THUNK(873)
  3692. IMPL_THUNK(874)
  3693. IMPL_THUNK(875)
  3694. IMPL_THUNK(876)
  3695. IMPL_THUNK(877)
  3696. IMPL_THUNK(878)
  3697. IMPL_THUNK(879)
  3698. IMPL_THUNK(880)
  3699. IMPL_THUNK(881)
  3700. IMPL_THUNK(882)
  3701. IMPL_THUNK(883)
  3702. IMPL_THUNK(884)
  3703. IMPL_THUNK(885)
  3704. IMPL_THUNK(886)
  3705. IMPL_THUNK(887)
  3706. IMPL_THUNK(888)
  3707. IMPL_THUNK(889)
  3708. IMPL_THUNK(890)
  3709. IMPL_THUNK(891)
  3710. IMPL_THUNK(892)
  3711. IMPL_THUNK(893)
  3712. IMPL_THUNK(894)
  3713. IMPL_THUNK(895)
  3714. IMPL_THUNK(896)
  3715. IMPL_THUNK(897)
  3716. IMPL_THUNK(898)
  3717. IMPL_THUNK(899)
  3718. IMPL_THUNK(900)
  3719. IMPL_THUNK(901)
  3720. IMPL_THUNK(902)
  3721. IMPL_THUNK(903)
  3722. IMPL_THUNK(904)
  3723. IMPL_THUNK(905)
  3724. IMPL_THUNK(906)
  3725. IMPL_THUNK(907)
  3726. IMPL_THUNK(908)
  3727. IMPL_THUNK(909)
  3728. IMPL_THUNK(910)
  3729. IMPL_THUNK(911)
  3730. IMPL_THUNK(912)
  3731. IMPL_THUNK(913)
  3732. IMPL_THUNK(914)
  3733. IMPL_THUNK(915)
  3734. IMPL_THUNK(916)
  3735. IMPL_THUNK(917)
  3736. IMPL_THUNK(918)
  3737. IMPL_THUNK(919)
  3738. IMPL_THUNK(920)
  3739. IMPL_THUNK(921)
  3740. IMPL_THUNK(922)
  3741. IMPL_THUNK(923)
  3742. IMPL_THUNK(924)
  3743. IMPL_THUNK(925)
  3744. IMPL_THUNK(926)
  3745. IMPL_THUNK(927)
  3746. IMPL_THUNK(928)
  3747. IMPL_THUNK(929)
  3748. IMPL_THUNK(930)
  3749. IMPL_THUNK(931)
  3750. IMPL_THUNK(932)
  3751. IMPL_THUNK(933)
  3752. IMPL_THUNK(934)
  3753. IMPL_THUNK(935)
  3754. IMPL_THUNK(936)
  3755. IMPL_THUNK(937)
  3756. IMPL_THUNK(938)
  3757. IMPL_THUNK(939)
  3758. IMPL_THUNK(940)
  3759. IMPL_THUNK(941)
  3760. IMPL_THUNK(942)
  3761. IMPL_THUNK(943)
  3762. IMPL_THUNK(944)
  3763. IMPL_THUNK(945)
  3764. IMPL_THUNK(946)
  3765. IMPL_THUNK(947)
  3766. IMPL_THUNK(948)
  3767. IMPL_THUNK(949)
  3768. IMPL_THUNK(950)
  3769. IMPL_THUNK(951)
  3770. IMPL_THUNK(952)
  3771. IMPL_THUNK(953)
  3772. IMPL_THUNK(954)
  3773. IMPL_THUNK(955)
  3774. IMPL_THUNK(956)
  3775. IMPL_THUNK(957)
  3776. IMPL_THUNK(958)
  3777. IMPL_THUNK(959)
  3778. IMPL_THUNK(960)
  3779. IMPL_THUNK(961)
  3780. IMPL_THUNK(962)
  3781. IMPL_THUNK(963)
  3782. IMPL_THUNK(964)
  3783. IMPL_THUNK(965)
  3784. IMPL_THUNK(966)
  3785. IMPL_THUNK(967)
  3786. IMPL_THUNK(968)
  3787. IMPL_THUNK(969)
  3788. IMPL_THUNK(970)
  3789. IMPL_THUNK(971)
  3790. IMPL_THUNK(972)
  3791. IMPL_THUNK(973)
  3792. IMPL_THUNK(974)
  3793. IMPL_THUNK(975)
  3794. IMPL_THUNK(976)
  3795. IMPL_THUNK(977)
  3796. IMPL_THUNK(978)
  3797. IMPL_THUNK(979)
  3798. IMPL_THUNK(980)
  3799. IMPL_THUNK(981)
  3800. IMPL_THUNK(982)
  3801. IMPL_THUNK(983)
  3802. IMPL_THUNK(984)
  3803. IMPL_THUNK(985)
  3804. IMPL_THUNK(986)
  3805. IMPL_THUNK(987)
  3806. IMPL_THUNK(988)
  3807. IMPL_THUNK(989)
  3808. IMPL_THUNK(990)
  3809. IMPL_THUNK(991)
  3810. IMPL_THUNK(992)
  3811. IMPL_THUNK(993)
  3812. IMPL_THUNK(994)
  3813. IMPL_THUNK(995)
  3814. IMPL_THUNK(996)
  3815. IMPL_THUNK(997)
  3816. IMPL_THUNK(998)
  3817. IMPL_THUNK(999)
  3818. IMPL_THUNK(1000)
  3819. IMPL_THUNK(1001)
  3820. IMPL_THUNK(1002)
  3821. IMPL_THUNK(1003)
  3822. IMPL_THUNK(1004)
  3823. IMPL_THUNK(1005)
  3824. IMPL_THUNK(1006)
  3825. IMPL_THUNK(1007)
  3826. IMPL_THUNK(1008)
  3827. IMPL_THUNK(1009)
  3828. IMPL_THUNK(1010)
  3829. IMPL_THUNK(1011)
  3830. IMPL_THUNK(1012)
  3831. IMPL_THUNK(1013)
  3832. IMPL_THUNK(1014)
  3833. IMPL_THUNK(1015)
  3834. IMPL_THUNK(1016)
  3835. IMPL_THUNK(1017)
  3836. IMPL_THUNK(1018)
  3837. IMPL_THUNK(1019)
  3838. IMPL_THUNK(1020)
  3839. IMPL_THUNK(1021)
  3840. IMPL_THUNK(1022)
  3841. IMPL_THUNK(1023)
  3842. IMPL_THUNK(1024)
  3843.  
  3844. #endif
  3845.  
  3846. #ifndef __BORLANDC__
  3847. __declspec(selectany) GUID CComModule::m_libid = {0x0,0x0,0x0,{0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0}};
  3848. #endif
  3849.  
  3850. #ifdef _ATL_STATIC_REGISTRY
  3851. #define UpdateRegistryFromResource UpdateRegistryFromResourceS
  3852. #else
  3853. #define UpdateRegistryFromResource UpdateRegistryFromResourceD
  3854. #endif
  3855.  
  3856. /////////////////////////////////////////////////////////////////////////////////////////////
  3857. // Thread Pooling classes
  3858.  
  3859. class _AtlAptCreateObjData
  3860. {
  3861. public:
  3862.     _ATL_CREATORFUNC* pfnCreateInstance;
  3863.     const IID* piid;
  3864.     HANDLE hEvent;
  3865.     LPSTREAM pStream;
  3866.     HRESULT hRes;
  3867. };
  3868.  
  3869. class CComApartment
  3870. {
  3871. public:
  3872.     CComApartment()
  3873.     {
  3874.         m_nLockCnt = 0;
  3875.     }
  3876.     static UINT ATL_CREATE_OBJECT;
  3877.     static DWORD WINAPI _Apartment(void* pv)
  3878.     {
  3879.         return ((CComApartment*)pv)->Apartment();
  3880.     }
  3881.     DWORD Apartment()
  3882.     {
  3883.         CoInitialize(NULL);
  3884.         MSG msg;
  3885.         while(GetMessage(&msg, 0, 0, 0))
  3886.         {
  3887.             if (msg.message == ATL_CREATE_OBJECT)
  3888.             {
  3889.                 _AtlAptCreateObjData* pdata = (_AtlAptCreateObjData*)msg.lParam;
  3890.                 IUnknown* pUnk = NULL;
  3891.                 pdata->hRes = pdata->pfnCreateInstance(NULL, IID_IUnknown, (void**)&pUnk);
  3892.                 if (SUCCEEDED(pdata->hRes))
  3893.                     pdata->hRes = CoMarshalInterThreadInterfaceInStream(*pdata->piid, pUnk, &pdata->pStream);
  3894.                 if (SUCCEEDED(pdata->hRes))
  3895.                 {
  3896.                     pUnk->Release();
  3897.                     ATLTRACE2(atlTraceCOM, 2, _T("Object created on thread = %d\n"), GetCurrentThreadId());
  3898.                 }
  3899.                 SetEvent(pdata->hEvent);
  3900.             }
  3901.             DispatchMessage(&msg);
  3902.         }
  3903.         CoUninitialize();
  3904.         return 0;
  3905.     }
  3906.     LONG Lock() {return CComGlobalsThreadModel::Increment(&m_nLockCnt);}
  3907.     LONG Unlock(){return CComGlobalsThreadModel::Decrement(&m_nLockCnt);
  3908.     }
  3909.     LONG GetLockCount() {return m_nLockCnt;}
  3910.  
  3911.     DWORD m_dwThreadID;
  3912.     HANDLE m_hThread;
  3913.     LONG m_nLockCnt;
  3914. };
  3915.  
  3916. #ifndef __BORLANDC__
  3917. __declspec(selectany) UINT CComApartment::ATL_CREATE_OBJECT = 0;
  3918. #endif
  3919.  
  3920. class CComSimpleThreadAllocator
  3921. {
  3922. public:
  3923.     CComSimpleThreadAllocator()
  3924.     {
  3925.         m_nThread = 0;
  3926.     }
  3927.     int GetThread(CComApartment* /*pApt*/, int nThreads)
  3928.     {
  3929.         if (++m_nThread == nThreads)
  3930.             m_nThread = 0;
  3931.         return m_nThread;
  3932.     }
  3933.     int m_nThread;
  3934. };
  3935.  
  3936. template <class ThreadAllocator = CComSimpleThreadAllocator>
  3937. class CComAutoThreadModule : public CComModule
  3938. {
  3939. public:
  3940.     HRESULT Init(_ATL_OBJMAP_ENTRY* p, HINSTANCE h, const GUID* plibid = NULL, int nThreads = GetDefaultThreads());
  3941.     ~CComAutoThreadModule();
  3942.     HRESULT CreateInstance(void* pfnCreateInstance, REFIID riid, void** ppvObj);
  3943.     LONG Lock();
  3944.     LONG Unlock();
  3945.     DWORD dwThreadID;
  3946.     int m_nThreads;
  3947.     CComApartment* m_pApartments;
  3948.     ThreadAllocator m_Allocator;
  3949.     static int GetDefaultThreads()
  3950.     {
  3951.         SYSTEM_INFO si;
  3952.         GetSystemInfo(&si);
  3953.         return si.dwNumberOfProcessors * 4;
  3954.     }
  3955. };
  3956.  
  3957. /////////////////////////////////////////////////////////////////////////////
  3958. // CComBSTR
  3959.  
  3960. class CComBSTR
  3961. {
  3962. public:
  3963.     BSTR m_str;
  3964.     CComBSTR()
  3965.     {
  3966.         m_str = NULL;
  3967.     }
  3968.     /*explicit*/ CComBSTR(int nSize)
  3969.     {
  3970.         m_str = ::SysAllocStringLen(NULL, nSize);
  3971.     }
  3972.     /*explicit*/ CComBSTR(int nSize, LPCOLESTR sz)
  3973.     {
  3974.         m_str = ::SysAllocStringLen(sz, nSize);
  3975.     }
  3976.     /*explicit*/ CComBSTR(LPCOLESTR pSrc)
  3977.     {
  3978.         m_str = ::SysAllocString(pSrc);
  3979.     }
  3980.     /*explicit*/ CComBSTR(const CComBSTR& src)
  3981.     {
  3982.         m_str = src.Copy();
  3983.     }
  3984.     /*explicit*/ CComBSTR(REFGUID src)
  3985.     {
  3986.         LPOLESTR szGuid;
  3987.         StringFromCLSID(src, &szGuid);
  3988.         m_str = ::SysAllocString(szGuid);
  3989.         CoTaskMemFree(szGuid);
  3990.     }
  3991.     CComBSTR& operator=(const CComBSTR& src)
  3992.     {
  3993.         if (m_str != src.m_str)
  3994.         {
  3995.             if (m_str)
  3996.                 ::SysFreeString(m_str);
  3997.             m_str = src.Copy();
  3998.         }
  3999.         return *this;
  4000.     }
  4001.  
  4002.     CComBSTR& operator=(LPCOLESTR pSrc)
  4003.     {
  4004.         ::SysFreeString(m_str);
  4005.         m_str = ::SysAllocString(pSrc);
  4006.         return *this;
  4007.     }
  4008.  
  4009.     ~CComBSTR()
  4010.     {
  4011.         ::SysFreeString(m_str);
  4012.     }
  4013.     unsigned int Length() const
  4014.     {
  4015.         return (m_str == NULL)? 0 : SysStringLen(m_str);
  4016.     }
  4017.     operator BSTR() const
  4018.     {
  4019.         return m_str;
  4020.     }
  4021.     BSTR* operator&()
  4022.     {
  4023.         return &m_str;
  4024.     }
  4025.     BSTR Copy() const
  4026.     {
  4027.         return ::SysAllocStringLen(m_str, ::SysStringLen(m_str));
  4028.     }
  4029.     HRESULT CopyTo(BSTR* pbstr)
  4030.     {
  4031.         ATLASSERT(pbstr != NULL);
  4032.         if (pbstr == NULL)
  4033.             return E_POINTER;
  4034.         *pbstr = ::SysAllocStringLen(m_str, ::SysStringLen(m_str));
  4035.         if (*pbstr == NULL)
  4036.             return E_OUTOFMEMORY;
  4037.         return S_OK;
  4038.     }
  4039.     void Attach(BSTR src)
  4040.     {
  4041.         ATLASSERT(m_str == NULL);
  4042.         m_str = src;
  4043.     }
  4044.     BSTR Detach()
  4045.     {
  4046.         BSTR s = m_str;
  4047.         m_str = NULL;
  4048.         return s;
  4049.     }
  4050.     void Empty()
  4051.     {
  4052.         ::SysFreeString(m_str);
  4053.         m_str = NULL;
  4054.     }
  4055.     bool operator!() const
  4056.     {
  4057.         return (m_str == NULL);
  4058.     }
  4059.     HRESULT Append(const CComBSTR& bstrSrc)
  4060.     {
  4061.         return Append(bstrSrc.m_str, SysStringLen(bstrSrc.m_str));
  4062.     }
  4063.     HRESULT Append(LPCOLESTR lpsz)
  4064.     {
  4065.         return Append(lpsz, ocslen(lpsz));
  4066.     }
  4067.     // a BSTR is just a LPCOLESTR so we need a special version to signify
  4068.     // that we are appending a BSTR
  4069.     HRESULT AppendBSTR(BSTR p)
  4070.     {
  4071.         return Append(p, SysStringLen(p));
  4072.     }
  4073.     HRESULT Append(LPCOLESTR lpsz, int nLen)
  4074.     {
  4075.         int n1 = Length();
  4076.         BSTR b;
  4077.         b = ::SysAllocStringLen(NULL, n1+nLen);
  4078.         if (b == NULL)
  4079.             return E_OUTOFMEMORY;
  4080.         memcpy(b, m_str, n1*sizeof(OLECHAR));
  4081.         memcpy(b+n1, lpsz, nLen*sizeof(OLECHAR));
  4082.         b[n1+nLen] = NULL;
  4083.         SysFreeString(m_str);
  4084.         m_str = b;
  4085.         return S_OK;
  4086.     }
  4087.     HRESULT ToLower()
  4088.     {
  4089.         USES_CONVERSION;
  4090.         if (m_str != NULL)
  4091.         {
  4092.             LPTSTR psz = CharLower(OLE2T(m_str));
  4093.             if (psz == NULL)
  4094.                 return E_OUTOFMEMORY;
  4095.             BSTR b = T2BSTR(psz);
  4096.             if (psz == NULL)
  4097.                 return E_OUTOFMEMORY;
  4098.             SysFreeString(m_str);
  4099.             m_str = b;
  4100.         }
  4101.         return S_OK;
  4102.     }
  4103.     HRESULT ToUpper()
  4104.     {
  4105.         USES_CONVERSION;
  4106.         if (m_str != NULL)
  4107.         {
  4108.             LPTSTR psz = CharUpper(OLE2T(m_str));
  4109.             if (psz == NULL)
  4110.                 return E_OUTOFMEMORY;
  4111.             BSTR b = T2BSTR(psz);
  4112.             if (psz == NULL)
  4113.                 return E_OUTOFMEMORY;
  4114.             SysFreeString(m_str);
  4115.             m_str = b;
  4116.         }
  4117.         return S_OK;
  4118.     }
  4119.     bool LoadString(HINSTANCE hInst, UINT nID)
  4120.     {
  4121.         USES_CONVERSION;
  4122.         TCHAR sz[512];
  4123.         UINT nLen = ::LoadString(hInst, nID, sz, 512);
  4124.         ATLASSERT(nLen < 511);
  4125.         SysFreeString(m_str);
  4126.         m_str = (nLen != 0) ? SysAllocString(T2OLE(sz)) : NULL;
  4127.         return (nLen != 0);
  4128.     }
  4129.     bool LoadString(UINT nID)
  4130.     {
  4131.         return LoadString(_pModule->m_hInstResource, nID);
  4132.     }
  4133.  
  4134.     CComBSTR& operator+=(const CComBSTR& bstrSrc)
  4135.     {
  4136.         AppendBSTR(bstrSrc.m_str);
  4137.         return *this;
  4138.     }
  4139.     bool operator<(BSTR bstrSrc) const
  4140.     {
  4141.         if (bstrSrc == NULL && m_str == NULL)
  4142.             return false;
  4143.         if (bstrSrc != NULL && m_str != NULL)
  4144.             return wcscmp(m_str, bstrSrc) < 0;
  4145.         return m_str == NULL;
  4146.     }
  4147.     bool operator==(BSTR bstrSrc) const
  4148.     {
  4149.         if (bstrSrc == NULL && m_str == NULL)
  4150.             return true;
  4151.         if (bstrSrc != NULL && m_str != NULL)
  4152.             return wcscmp(m_str, bstrSrc) == 0;
  4153.         return false;
  4154.     }
  4155.     bool operator<(LPCSTR pszSrc) const
  4156.     {
  4157.         if (pszSrc == NULL && m_str == NULL)
  4158.             return false;
  4159.         USES_CONVERSION;
  4160.         if (pszSrc != NULL && m_str != NULL)
  4161.             return wcscmp(m_str, A2W(pszSrc)) < 0;
  4162.         return m_str == NULL;
  4163.     }
  4164.     bool operator==(LPCSTR pszSrc) const
  4165.     {
  4166.         if (pszSrc == NULL && m_str == NULL)
  4167.             return true;
  4168.         USES_CONVERSION;
  4169.         if (pszSrc != NULL && m_str != NULL)
  4170.             return wcscmp(m_str, A2W(pszSrc)) == 0;
  4171.         return false;
  4172.     }
  4173. #ifndef OLE2ANSI
  4174.     CComBSTR(LPCSTR pSrc)
  4175.     {
  4176.         m_str = A2WBSTR(pSrc);
  4177.     }
  4178.  
  4179.     CComBSTR(int nSize, LPCSTR sz)
  4180.     {
  4181.         m_str = A2WBSTR(sz, nSize);
  4182.     }
  4183.  
  4184.     void Append(LPCSTR lpsz)
  4185.     {
  4186.         USES_CONVERSION;
  4187.         LPCOLESTR lpo = A2COLE(lpsz);
  4188.         Append(lpo, ocslen(lpo));
  4189.     }
  4190.  
  4191.     CComBSTR& operator=(LPCSTR pSrc)
  4192.     {
  4193.         ::SysFreeString(m_str);
  4194.         m_str = A2WBSTR(pSrc);
  4195.         return *this;
  4196.     }
  4197. #endif
  4198.     HRESULT WriteToStream(IStream* pStream)
  4199.     {
  4200.         ATLASSERT(pStream != NULL);
  4201.         ULONG cb;
  4202.         ULONG cbStrLen = m_str ? SysStringByteLen(m_str)+sizeof(OLECHAR) : 0;
  4203.         HRESULT hr = pStream->Write((void*) &cbStrLen, sizeof(cbStrLen), &cb);
  4204.         if (FAILED(hr))
  4205.             return hr;
  4206.         return cbStrLen ? pStream->Write((void*) m_str, cbStrLen, &cb) : S_OK;
  4207.     }
  4208.     HRESULT ReadFromStream(IStream* pStream)
  4209.     {
  4210.         ATLASSERT(pStream != NULL);
  4211.         ATLASSERT(m_str == NULL); // should be empty
  4212.         ULONG cbStrLen = 0;
  4213.         HRESULT hr = pStream->Read((void*) &cbStrLen, sizeof(cbStrLen), NULL);
  4214.         if ((hr == S_OK) && (cbStrLen != 0))
  4215.         {
  4216.             //subtract size for terminating NULL which we wrote out
  4217.             //since SysAllocStringByteLen overallocates for the NULL
  4218.             m_str = SysAllocStringByteLen(NULL, cbStrLen-sizeof(OLECHAR));
  4219.             if (m_str == NULL)
  4220.                 hr = E_OUTOFMEMORY;
  4221.             else
  4222.                 hr = pStream->Read((void*) m_str, cbStrLen, NULL);
  4223.         }
  4224.         if (hr == S_FALSE)
  4225.             hr = E_FAIL;
  4226.         return hr;
  4227.     }
  4228. };
  4229.  
  4230. /////////////////////////////////////////////////////////////////////////////
  4231. // CComVariant
  4232.  
  4233. class CComVariant : public tagVARIANT
  4234. {
  4235. // Constructors
  4236. public:
  4237.     CComVariant()
  4238.     {
  4239.         vt = VT_EMPTY;
  4240.     }
  4241.     ~CComVariant()
  4242.     {
  4243.         Clear();
  4244.     }
  4245.  
  4246.     CComVariant(const VARIANT& varSrc)
  4247.     {
  4248.         vt = VT_EMPTY;
  4249.         InternalCopy(&varSrc);
  4250.     }
  4251.  
  4252.     CComVariant(const CComVariant& varSrc)
  4253.     {
  4254.         vt = VT_EMPTY;
  4255.         InternalCopy(&varSrc);
  4256.     }
  4257.  
  4258.     CComVariant(BSTR bstrSrc)
  4259.     {
  4260.         vt = VT_EMPTY;
  4261.         *this = bstrSrc;
  4262.     }
  4263.     CComVariant(LPCOLESTR lpszSrc)
  4264.     {
  4265.         vt = VT_EMPTY;
  4266.         *this = lpszSrc;
  4267.     }
  4268.  
  4269. #ifndef OLE2ANSI
  4270.     CComVariant(LPCSTR lpszSrc)
  4271.     {
  4272.         vt = VT_EMPTY;
  4273.         *this = lpszSrc;
  4274.     }
  4275. #endif
  4276.  
  4277.     CComVariant(bool bSrc)
  4278.     {
  4279.         vt = VT_BOOL;
  4280. #pragma warning(disable: 4310) // cast truncates constant value
  4281.         boolVal = bSrc ? VARIANT_TRUE : VARIANT_FALSE;
  4282. #pragma warning(default: 4310) // cast truncates constant value
  4283.     }
  4284.  
  4285.     CComVariant(int nSrc)
  4286.     {
  4287.         vt = VT_I4;
  4288.         lVal = nSrc;
  4289.     }
  4290.     CComVariant(BYTE nSrc)
  4291.     {
  4292.         vt = VT_UI1;
  4293.         bVal = nSrc;
  4294.     }
  4295.     CComVariant(short nSrc)
  4296.     {
  4297.         vt = VT_I2;
  4298.         iVal = nSrc;
  4299.     }
  4300.     CComVariant(long nSrc, VARTYPE vtSrc = VT_I4)
  4301.     {
  4302.         ATLASSERT(vtSrc == VT_I4 || vtSrc == VT_ERROR);
  4303.         vt = vtSrc;
  4304.         lVal = nSrc;
  4305.     }
  4306.     CComVariant(float fltSrc)
  4307.     {
  4308.         vt = VT_R4;
  4309.         fltVal = fltSrc;
  4310.     }
  4311.     CComVariant(double dblSrc)
  4312.     {
  4313.         vt = VT_R8;
  4314.         dblVal = dblSrc;
  4315.     }
  4316.     CComVariant(CY cySrc)
  4317.     {
  4318.         vt = VT_CY;
  4319.         cyVal.Hi = cySrc.Hi;
  4320.         cyVal.Lo = cySrc.Lo;
  4321.     }
  4322.     CComVariant(IDispatch* pSrc)
  4323.     {
  4324.         vt = VT_DISPATCH;
  4325.         pdispVal = pSrc;
  4326.         // Need to AddRef as VariantClear will Release
  4327.         if (pdispVal != NULL)
  4328.             pdispVal->AddRef();
  4329.     }
  4330.     CComVariant(IUnknown* pSrc)
  4331.     {
  4332.         vt = VT_UNKNOWN;
  4333.         punkVal = pSrc;
  4334.         // Need to AddRef as VariantClear will Release
  4335.         if (punkVal != NULL)
  4336.             punkVal->AddRef();
  4337.     }
  4338.  
  4339. // Assignment Operators
  4340. public:
  4341.     CComVariant& operator=(const CComVariant& varSrc)
  4342.     {
  4343.         InternalCopy(&varSrc);
  4344.         return *this;
  4345.     }
  4346.     CComVariant& operator=(const VARIANT& varSrc)
  4347.     {
  4348.         InternalCopy(&varSrc);
  4349.         return *this;
  4350.     }
  4351.  
  4352.     CComVariant& operator=(BSTR bstrSrc)
  4353.     {
  4354.         InternalClear();
  4355.         vt = VT_BSTR;
  4356.         bstrVal = ::SysAllocString(bstrSrc);
  4357.         if (bstrVal == NULL && bstrSrc != NULL)
  4358.         {
  4359.             vt = VT_ERROR;
  4360.             scode = E_OUTOFMEMORY;
  4361.         }
  4362.         return *this;
  4363.     }
  4364.  
  4365.     CComVariant& operator=(LPCOLESTR lpszSrc)
  4366.     {
  4367.         InternalClear();
  4368.         vt = VT_BSTR;
  4369.         bstrVal = ::SysAllocString(lpszSrc);
  4370.  
  4371.         if (bstrVal == NULL && lpszSrc != NULL)
  4372.         {
  4373.             vt = VT_ERROR;
  4374.             scode = E_OUTOFMEMORY;
  4375.         }
  4376.         return *this;
  4377.     }
  4378.  
  4379.     #ifndef OLE2ANSI
  4380.     CComVariant& operator=(LPCSTR lpszSrc)
  4381.     {
  4382.         USES_CONVERSION;
  4383.         InternalClear();
  4384.         vt = VT_BSTR;
  4385.         bstrVal = ::SysAllocString(A2COLE(lpszSrc));
  4386.  
  4387.         if (bstrVal == NULL && lpszSrc != NULL)
  4388.         {
  4389.             vt = VT_ERROR;
  4390.             scode = E_OUTOFMEMORY;
  4391.         }
  4392.         return *this;
  4393.     }
  4394.     #endif
  4395.  
  4396.     CComVariant& operator=(bool bSrc)
  4397.     {
  4398.         if (vt != VT_BOOL)
  4399.         {
  4400.             InternalClear();
  4401.             vt = VT_BOOL;
  4402.         }
  4403.     #pragma warning(disable: 4310) // cast truncates constant value
  4404.         boolVal = bSrc ? VARIANT_TRUE : VARIANT_FALSE;
  4405.     #pragma warning(default: 4310) // cast truncates constant value
  4406.         return *this;
  4407.     }
  4408.  
  4409.     CComVariant& operator=(int nSrc)
  4410.     {
  4411.         if (vt != VT_I4)
  4412.         {
  4413.             InternalClear();
  4414.             vt = VT_I4;
  4415.         }
  4416.         lVal = nSrc;
  4417.  
  4418.         return *this;
  4419.     }
  4420.  
  4421.     CComVariant& operator=(BYTE nSrc)
  4422.     {
  4423.         if (vt != VT_UI1)
  4424.         {
  4425.             InternalClear();
  4426.             vt = VT_UI1;
  4427.         }
  4428.         bVal = nSrc;
  4429.         return *this;
  4430.     }
  4431.  
  4432.     CComVariant& operator=(short nSrc)
  4433.     {
  4434.         if (vt != VT_I2)
  4435.         {
  4436.             InternalClear();
  4437.             vt = VT_I2;
  4438.         }
  4439.         iVal = nSrc;
  4440.         return *this;
  4441.     }
  4442.  
  4443.     CComVariant& operator=(long nSrc)
  4444.     {
  4445.         if (vt != VT_I4)
  4446.         {
  4447.             InternalClear();
  4448.             vt = VT_I4;
  4449.         }
  4450.         lVal = nSrc;
  4451.         return *this;
  4452.     }
  4453.  
  4454.     CComVariant& operator=(float fltSrc)
  4455.     {
  4456.         if (vt != VT_R4)
  4457.         {
  4458.             InternalClear();
  4459.             vt = VT_R4;
  4460.         }
  4461.         fltVal = fltSrc;
  4462.         return *this;
  4463.     }
  4464.  
  4465.     CComVariant& operator=(double dblSrc)
  4466.     {
  4467.         if (vt != VT_R8)
  4468.         {
  4469.             InternalClear();
  4470.             vt = VT_R8;
  4471.         }
  4472.         dblVal = dblSrc;
  4473.         return *this;
  4474.     }
  4475.  
  4476.     CComVariant& operator=(CY cySrc)
  4477.     {
  4478.         if (vt != VT_CY)
  4479.         {
  4480.             InternalClear();
  4481.             vt = VT_CY;
  4482.         }
  4483.         cyVal.Hi = cySrc.Hi;
  4484.         cyVal.Lo = cySrc.Lo;
  4485.         return *this;
  4486.     }
  4487.  
  4488.     CComVariant& operator=(IDispatch* pSrc)
  4489.     {
  4490.         InternalClear();
  4491.         vt = VT_DISPATCH;
  4492.         pdispVal = pSrc;
  4493.         // Need to AddRef as VariantClear will Release
  4494.         if (pdispVal != NULL)
  4495.             pdispVal->AddRef();
  4496.         return *this;
  4497.     }
  4498.  
  4499.     CComVariant& operator=(IUnknown* pSrc)
  4500.     {
  4501.         InternalClear();
  4502.         vt = VT_UNKNOWN;
  4503.         punkVal = pSrc;
  4504.  
  4505.         // Need to AddRef as VariantClear will Release
  4506.         if (punkVal != NULL)
  4507.             punkVal->AddRef();
  4508.         return *this;
  4509.     }
  4510.  
  4511.  
  4512. // Comparison Operators
  4513. public:
  4514.     bool operator==(const VARIANT& varSrc) const
  4515.     {
  4516.         if (this == &varSrc)
  4517.             return true;
  4518.  
  4519.         // Variants not equal if types don't match
  4520.         if (vt != varSrc.vt)
  4521.             return false;
  4522.  
  4523.         // Check type specific values
  4524.         switch (vt)
  4525.         {
  4526.             case VT_EMPTY:
  4527.             case VT_NULL:
  4528.                 return true;
  4529.  
  4530.             case VT_BOOL:
  4531.                 return boolVal == varSrc.boolVal;
  4532.  
  4533.             case VT_UI1:
  4534.                 return bVal == varSrc.bVal;
  4535.  
  4536.             case VT_I2:
  4537.                 return iVal == varSrc.iVal;
  4538.  
  4539.             case VT_I4:
  4540.                 return lVal == varSrc.lVal;
  4541.  
  4542.             case VT_R4:
  4543.                 return fltVal == varSrc.fltVal;
  4544.  
  4545.             case VT_R8:
  4546.                 return dblVal == varSrc.dblVal;
  4547.  
  4548.             case VT_BSTR:
  4549.                 return (::SysStringByteLen(bstrVal) == ::SysStringByteLen(varSrc.bstrVal)) &&
  4550.                         (::memcmp(bstrVal, varSrc.bstrVal, ::SysStringByteLen(bstrVal)) == 0);
  4551.  
  4552.             case VT_ERROR:
  4553.                 return scode == varSrc.scode;
  4554.  
  4555.             case VT_DISPATCH:
  4556.                 return pdispVal == varSrc.pdispVal;
  4557.  
  4558.             case VT_UNKNOWN:
  4559.                 return punkVal == varSrc.punkVal;
  4560.  
  4561.             default:
  4562.                 ATLASSERT(false);
  4563.                 // fall through
  4564.         }
  4565.  
  4566.         return false;
  4567.     }
  4568.     bool operator!=(const VARIANT& varSrc) const {return !operator==(varSrc);}
  4569.     bool operator<(const VARIANT& varSrc) const {return VarCmp((VARIANT*)this, (VARIANT*)&varSrc, LOCALE_USER_DEFAULT)==VARCMP_LT;}
  4570.     bool operator>(const VARIANT& varSrc) const {return VarCmp((VARIANT*)this, (VARIANT*)&varSrc, LOCALE_USER_DEFAULT)==VARCMP_GT;}
  4571.  
  4572. // Operations
  4573. public:
  4574.     HRESULT Clear() { return ::VariantClear(this); }
  4575.     HRESULT Copy(const VARIANT* pSrc) { return ::VariantCopy(this, const_cast<VARIANT*>(pSrc)); }
  4576.     HRESULT Attach(VARIANT* pSrc)
  4577.     {
  4578.         // Clear out the variant
  4579.         HRESULT hr = Clear();
  4580.         if (!FAILED(hr))
  4581.         {
  4582.             // Copy the contents and give control to CComVariant
  4583.             memcpy(this, pSrc, sizeof(VARIANT));
  4584.             pSrc->vt = VT_EMPTY;
  4585.             hr = S_OK;
  4586.         }
  4587.         return hr;
  4588.     }
  4589.  
  4590.     HRESULT Detach(VARIANT* pDest)
  4591.     {
  4592.         // Clear out the variant
  4593.         HRESULT hr = ::VariantClear(pDest);
  4594.         if (!FAILED(hr))
  4595.         {
  4596.             // Copy the contents and remove control from CComVariant
  4597.             memcpy(pDest, this, sizeof(VARIANT));
  4598.             vt = VT_EMPTY;
  4599.             hr = S_OK;
  4600.         }
  4601.         return hr;
  4602.     }
  4603.  
  4604.     HRESULT ChangeType(VARTYPE vtNew, const VARIANT* pSrc = NULL)
  4605.     {
  4606.         VARIANT* pVar = const_cast<VARIANT*>(pSrc);
  4607.         // Convert in place if pSrc is NULL
  4608.         if (pVar == NULL)
  4609.             pVar = this;
  4610.         // Do nothing if doing in place convert and vts not different
  4611.         return ::VariantChangeType(this, pVar, 0, vtNew);
  4612.     }
  4613.  
  4614.     HRESULT WriteToStream(IStream* pStream);
  4615.     HRESULT ReadFromStream(IStream* pStream);
  4616.  
  4617. // Implementation
  4618. public:
  4619.     HRESULT InternalClear()
  4620.     {
  4621.         HRESULT hr = Clear();
  4622.         ATLASSERT(SUCCEEDED(hr));
  4623.         if (FAILED(hr))
  4624.         {
  4625.             vt = VT_ERROR;
  4626.             scode = hr;
  4627.         }
  4628.         return hr;
  4629.     }
  4630.  
  4631.     void InternalCopy(const VARIANT* pSrc)
  4632.     {
  4633.         HRESULT hr = Copy(pSrc);
  4634.         if (FAILED(hr))
  4635.         {
  4636.             vt = VT_ERROR;
  4637.             scode = hr;
  4638.         }
  4639.     }
  4640. };
  4641.  
  4642. inline HRESULT CComVariant::WriteToStream(IStream* pStream)
  4643. {
  4644.     HRESULT hr = pStream->Write(&vt, sizeof(VARTYPE), NULL);
  4645.     if (FAILED(hr))
  4646.         return hr;
  4647.  
  4648.     int cbWrite = 0;
  4649.     switch (vt)
  4650.     {
  4651.     case VT_UNKNOWN:
  4652.     case VT_DISPATCH:
  4653.         {
  4654.             CComPtr<IPersistStream> spStream;
  4655.             if (punkVal != NULL)
  4656.             {
  4657.                 hr = punkVal->QueryInterface(IID_IPersistStream, (void**)&spStream);
  4658.                 if (FAILED(hr))
  4659.                     return hr;
  4660.             }
  4661.             if (spStream != NULL)
  4662.                 return OleSaveToStream(spStream, pStream);
  4663.             else
  4664.                 return WriteClassStm(pStream, CLSID_NULL);
  4665.         }
  4666.     case VT_UI1:
  4667.     case VT_I1:
  4668.         cbWrite = sizeof(BYTE);
  4669.         break;
  4670.     case VT_I2:
  4671.     case VT_UI2:
  4672.     case VT_BOOL:
  4673.         cbWrite = sizeof(short);
  4674.         break;
  4675.     case VT_I4:
  4676.     case VT_UI4:
  4677.     case VT_R4:
  4678.     case VT_INT:
  4679.     case VT_UINT:
  4680.     case VT_ERROR:
  4681.         cbWrite = sizeof(long);
  4682.         break;
  4683.     case VT_R8:
  4684.     case VT_CY:
  4685.     case VT_DATE:
  4686.         cbWrite = sizeof(double);
  4687.         break;
  4688.     default:
  4689.         break;
  4690.     }
  4691.     if (cbWrite != 0)
  4692.         return pStream->Write((void*) &bVal, cbWrite, NULL);
  4693.  
  4694.     CComBSTR bstrWrite;
  4695.     CComVariant varBSTR;
  4696.     if (vt != VT_BSTR)
  4697.     {
  4698.         hr = VariantChangeType(&varBSTR, this, VARIANT_NOVALUEPROP, VT_BSTR);
  4699.         if (FAILED(hr))
  4700.             return hr;
  4701.         bstrWrite = varBSTR.bstrVal;
  4702.     }
  4703.     else
  4704.         bstrWrite = bstrVal;
  4705.  
  4706.     return bstrWrite.WriteToStream(pStream);
  4707. }
  4708.  
  4709. inline HRESULT CComVariant::ReadFromStream(IStream* pStream)
  4710. {
  4711.     ATLASSERT(pStream != NULL);
  4712.     HRESULT hr;
  4713.     hr = VariantClear(this);
  4714.     if (FAILED(hr))
  4715.         return hr;
  4716.     VARTYPE vtRead;
  4717.     hr = pStream->Read(&vtRead, sizeof(VARTYPE), NULL);
  4718.     if (hr == S_FALSE)
  4719.         hr = E_FAIL;
  4720.     if (FAILED(hr))
  4721.         return hr;
  4722.  
  4723.     vt = vtRead;
  4724.     int cbRead = 0;
  4725.     switch (vtRead)
  4726.     {
  4727.     case VT_UNKNOWN:
  4728.     case VT_DISPATCH:
  4729.         {
  4730.             punkVal = NULL;
  4731.             hr = OleLoadFromStream(pStream,
  4732.                 (vtRead == VT_UNKNOWN) ? IID_IUnknown : IID_IDispatch,
  4733.                 (void**)&punkVal);
  4734.             if (hr == REGDB_E_CLASSNOTREG)
  4735.                 hr = S_OK;
  4736.             return S_OK;
  4737.         }
  4738.     case VT_UI1:
  4739.     case VT_I1:
  4740.         cbRead = sizeof(BYTE);
  4741.         break;
  4742.     case VT_I2:
  4743.     case VT_UI2:
  4744.     case VT_BOOL:
  4745.         cbRead = sizeof(short);
  4746.         break;
  4747.     case VT_I4:
  4748.     case VT_UI4:
  4749.     case VT_R4:
  4750.     case VT_INT:
  4751.     case VT_UINT:
  4752.     case VT_ERROR:
  4753.         cbRead = sizeof(long);
  4754.         break;
  4755.     case VT_R8:
  4756.     case VT_CY:
  4757.     case VT_DATE:
  4758.         cbRead = sizeof(double);
  4759.         break;
  4760.     default:
  4761.         break;
  4762.     }
  4763.     if (cbRead != 0)
  4764.     {
  4765.         hr = pStream->Read((void*) &bVal, cbRead, NULL);
  4766.         if (hr == S_FALSE)
  4767.             hr = E_FAIL;
  4768.         return hr;
  4769.     }
  4770.     CComBSTR bstrRead;
  4771.  
  4772.     hr = bstrRead.ReadFromStream(pStream);
  4773.     if (FAILED(hr))
  4774.         return hr;
  4775.     vt = VT_BSTR;
  4776.     bstrVal = bstrRead.Detach();
  4777.     if (vtRead != VT_BSTR)
  4778.         hr = ChangeType(vtRead);
  4779.     return hr;
  4780. }
  4781.  
  4782. /////////////////////////////////////////////////////////////////////////////
  4783. // CRegKey
  4784.  
  4785. class CRegKey
  4786. {
  4787. public:
  4788.     CRegKey();
  4789.     ~CRegKey();
  4790.  
  4791. // Attributes
  4792. public:
  4793.     operator HKEY() const;
  4794.     HKEY m_hKey;
  4795.  
  4796. // Operations
  4797. public:
  4798.     LONG SetValue(DWORD dwValue, LPCTSTR lpszValueName);
  4799.     LONG QueryValue(DWORD& dwValue, LPCTSTR lpszValueName);
  4800.     LONG QueryValue(LPTSTR szValue, LPCTSTR lpszValueName, DWORD* pdwCount);
  4801.     LONG SetValue(LPCTSTR lpszValue, LPCTSTR lpszValueName = NULL);
  4802.  
  4803.     LONG SetKeyValue(LPCTSTR lpszKeyName, LPCTSTR lpszValue, LPCTSTR lpszValueName = NULL);
  4804.     static LONG WINAPI SetValue(HKEY hKeyParent, LPCTSTR lpszKeyName,
  4805.         LPCTSTR lpszValue, LPCTSTR lpszValueName = NULL);
  4806.  
  4807.     LONG Create(HKEY hKeyParent, LPCTSTR lpszKeyName,
  4808.         LPTSTR lpszClass = REG_NONE, DWORD dwOptions = REG_OPTION_NON_VOLATILE,
  4809.         REGSAM samDesired = KEY_ALL_ACCESS,
  4810.         LPSECURITY_ATTRIBUTES lpSecAttr = NULL,
  4811.         LPDWORD lpdwDisposition = NULL);
  4812.     LONG Open(HKEY hKeyParent, LPCTSTR lpszKeyName,
  4813.         REGSAM samDesired = KEY_ALL_ACCESS);
  4814.     LONG Close();
  4815.     HKEY Detach();
  4816.     void Attach(HKEY hKey);
  4817.     LONG DeleteSubKey(LPCTSTR lpszSubKey);
  4818.     LONG RecurseDeleteKey(LPCTSTR lpszKey);
  4819.     LONG DeleteValue(LPCTSTR lpszValue);
  4820. };
  4821.  
  4822. inline CRegKey::CRegKey()
  4823. {m_hKey = NULL;}
  4824.  
  4825. inline CRegKey::~CRegKey()
  4826. {Close();}
  4827.  
  4828. inline CRegKey::operator HKEY() const
  4829. {return m_hKey;}
  4830.  
  4831. inline HKEY CRegKey::Detach()
  4832. {
  4833.     HKEY hKey = m_hKey;
  4834.     m_hKey = NULL;
  4835.     return hKey;
  4836. }
  4837.  
  4838. inline void CRegKey::Attach(HKEY hKey)
  4839. {
  4840.     ATLASSERT(m_hKey == NULL);
  4841.     m_hKey = hKey;
  4842. }
  4843.  
  4844. inline LONG CRegKey::DeleteSubKey(LPCTSTR lpszSubKey)
  4845. {
  4846.     ATLASSERT(m_hKey != NULL);
  4847.     return RegDeleteKey(m_hKey, lpszSubKey);
  4848. }
  4849.  
  4850. inline LONG CRegKey::DeleteValue(LPCTSTR lpszValue)
  4851. {
  4852.     ATLASSERT(m_hKey != NULL);
  4853.     return RegDeleteValue(m_hKey, (LPTSTR)lpszValue);
  4854. }
  4855.  
  4856. inline LONG CRegKey::Close()
  4857. {
  4858.     LONG lRes = ERROR_SUCCESS;
  4859.     if (m_hKey != NULL)
  4860.     {
  4861.         lRes = RegCloseKey(m_hKey);
  4862.         m_hKey = NULL;
  4863.     }
  4864.     return lRes;
  4865. }
  4866.  
  4867. inline LONG CRegKey::Create(HKEY hKeyParent, LPCTSTR lpszKeyName,
  4868.     LPTSTR lpszClass, DWORD dwOptions, REGSAM samDesired,
  4869.     LPSECURITY_ATTRIBUTES lpSecAttr, LPDWORD lpdwDisposition)
  4870. {
  4871.     ATLASSERT(hKeyParent != NULL);
  4872.     DWORD dw;
  4873.     HKEY hKey = NULL;
  4874.     LONG lRes = RegCreateKeyEx(hKeyParent, lpszKeyName, 0,
  4875.         lpszClass, dwOptions, samDesired, lpSecAttr, &hKey, &dw);
  4876.     if (lpdwDisposition != NULL)
  4877.         *lpdwDisposition = dw;
  4878.     if (lRes == ERROR_SUCCESS)
  4879.     {
  4880.         lRes = Close();
  4881.         m_hKey = hKey;
  4882.     }
  4883.     return lRes;
  4884. }
  4885.  
  4886. inline LONG CRegKey::Open(HKEY hKeyParent, LPCTSTR lpszKeyName, REGSAM samDesired)
  4887. {
  4888.     ATLASSERT(hKeyParent != NULL);
  4889.     HKEY hKey = NULL;
  4890.     LONG lRes = RegOpenKeyEx(hKeyParent, lpszKeyName, 0, samDesired, &hKey);
  4891.     if (lRes == ERROR_SUCCESS)
  4892.     {
  4893.         lRes = Close();
  4894.         ATLASSERT(lRes == ERROR_SUCCESS);
  4895.         m_hKey = hKey;
  4896.     }
  4897.     return lRes;
  4898. }
  4899.  
  4900. inline LONG CRegKey::QueryValue(DWORD& dwValue, LPCTSTR lpszValueName)
  4901. {
  4902.     DWORD dwType = NULL;
  4903.     DWORD dwCount = sizeof(DWORD);
  4904.     LONG lRes = RegQueryValueEx(m_hKey, (LPTSTR)lpszValueName, NULL, &dwType,
  4905.         (LPBYTE)&dwValue, &dwCount);
  4906.     ATLASSERT((lRes!=ERROR_SUCCESS) || (dwType == REG_DWORD));
  4907.     ATLASSERT((lRes!=ERROR_SUCCESS) || (dwCount == sizeof(DWORD)));
  4908.     return lRes;
  4909. }
  4910.  
  4911. inline LONG CRegKey::QueryValue(LPTSTR szValue, LPCTSTR lpszValueName, DWORD* pdwCount)
  4912. {
  4913.     ATLASSERT(pdwCount != NULL);
  4914.     DWORD dwType = NULL;
  4915.     LONG lRes = RegQueryValueEx(m_hKey, (LPTSTR)lpszValueName, NULL, &dwType,
  4916.         (LPBYTE)szValue, pdwCount);
  4917.     ATLASSERT((lRes!=ERROR_SUCCESS) || (dwType == REG_SZ) ||
  4918.              (dwType == REG_MULTI_SZ) || (dwType == REG_EXPAND_SZ));
  4919.     return lRes;
  4920. }
  4921.  
  4922. inline LONG WINAPI CRegKey::SetValue(HKEY hKeyParent, LPCTSTR lpszKeyName, LPCTSTR lpszValue, LPCTSTR lpszValueName)
  4923. {
  4924.     ATLASSERT(lpszValue != NULL);
  4925.     CRegKey key;
  4926.     LONG lRes = key.Create(hKeyParent, lpszKeyName);
  4927.     if (lRes == ERROR_SUCCESS)
  4928.         lRes = key.SetValue(lpszValue, lpszValueName);
  4929.     return lRes;
  4930. }
  4931.  
  4932. inline LONG CRegKey::SetKeyValue(LPCTSTR lpszKeyName, LPCTSTR lpszValue, LPCTSTR lpszValueName)
  4933. {
  4934.     ATLASSERT(lpszValue != NULL);
  4935.     CRegKey key;
  4936.     LONG lRes = key.Create(m_hKey, lpszKeyName);
  4937.     if (lRes == ERROR_SUCCESS)
  4938.         lRes = key.SetValue(lpszValue, lpszValueName);
  4939.     return lRes;
  4940. }
  4941.  
  4942. inline LONG CRegKey::SetValue(DWORD dwValue, LPCTSTR lpszValueName)
  4943. {
  4944.     ATLASSERT(m_hKey != NULL);
  4945.     return RegSetValueEx(m_hKey, lpszValueName, NULL, REG_DWORD,
  4946.         (BYTE * const)&dwValue, sizeof(DWORD));
  4947. }
  4948.  
  4949. inline LONG CRegKey::SetValue(LPCTSTR lpszValue, LPCTSTR lpszValueName)
  4950. {
  4951.     ATLASSERT(lpszValue != NULL);
  4952.     ATLASSERT(m_hKey != NULL);
  4953.     return RegSetValueEx(m_hKey, lpszValueName, NULL, REG_SZ,
  4954.         (BYTE * const)lpszValue, (lstrlen(lpszValue)+1)*sizeof(TCHAR));
  4955. }
  4956.  
  4957. inline LONG CRegKey::RecurseDeleteKey(LPCTSTR lpszKey)
  4958. {
  4959.     CRegKey key;
  4960.     LONG lRes = key.Open(m_hKey, lpszKey, KEY_READ | KEY_WRITE);
  4961.     if (lRes != ERROR_SUCCESS)
  4962.         return lRes;
  4963.     FILETIME time;
  4964.     DWORD dwSize = 256;
  4965.     TCHAR szBuffer[256];
  4966.     while (RegEnumKeyEx(key.m_hKey, 0, szBuffer, &dwSize, NULL, NULL, NULL,
  4967.         &time)==ERROR_SUCCESS)
  4968.     {
  4969.         lRes = key.RecurseDeleteKey(szBuffer);
  4970.         if (lRes != ERROR_SUCCESS)
  4971.             return lRes;
  4972.         dwSize = 256;
  4973.     }
  4974.     key.Close();
  4975.     return DeleteSubKey(lpszKey);
  4976. }
  4977.  
  4978. inline HRESULT CComModule::RegisterProgID(LPCTSTR lpszCLSID, LPCTSTR lpszProgID, LPCTSTR lpszUserDesc)
  4979. {
  4980.     CRegKey keyProgID;
  4981.     LONG lRes = keyProgID.Create(HKEY_CLASSES_ROOT, lpszProgID, REG_NONE, REG_OPTION_NON_VOLATILE, KEY_READ);
  4982.     if (lRes == ERROR_SUCCESS)
  4983.     {
  4984.         keyProgID.SetValue(lpszUserDesc);
  4985.         keyProgID.SetKeyValue(_T("CLSID"), lpszCLSID);
  4986.         return S_OK;
  4987.     }
  4988.     return HRESULT_FROM_WIN32(lRes);
  4989. }
  4990.  
  4991. #ifdef _ATL_STATIC_REGISTRY
  4992. #include <statreg.h>
  4993.  
  4994. // Statically linking to Registry Ponent
  4995. inline HRESULT WINAPI CComModule::UpdateRegistryFromResourceS(UINT nResID, BOOL bRegister,
  4996.     struct _ATL_REGMAP_ENTRY* pMapEntries)
  4997. {
  4998.     USES_CONVERSION;
  4999.     ATL::CRegObject ro;
  5000.     TCHAR szModule[_MAX_PATH];
  5001.     GetModuleFileName(_pModule->GetModuleInstance(), szModule, _MAX_PATH);
  5002.  
  5003.    // Convert to short path to work around bug in NT4's CreateProcess
  5004.    TCHAR szModuleShort[_MAX_PATH];
  5005.    GetShortPathName(szModule, szModuleShort, _MAX_PATH);
  5006.    LPOLESTR pszModule = T2OLE(szModuleShort);
  5007.  
  5008.     int nLen = ocslen(pszModule);
  5009.     LPOLESTR pszModuleQuote = (LPOLESTR)alloca((nLen*2+1)*sizeof(OLECHAR));
  5010.     ReplaceSingleQuote(pszModuleQuote, pszModule);
  5011.     ro.AddReplacement(OLESTR("Module"), pszModuleQuote);
  5012.     if (NULL != pMapEntries)
  5013.     {
  5014.         while (NULL != pMapEntries->szKey)
  5015.         {
  5016.             ATLASSERT(NULL != pMapEntries->szData);
  5017.             ro.AddReplacement(pMapEntries->szKey, pMapEntries->szData);
  5018.             pMapEntries++;
  5019.         }
  5020.     }
  5021.  
  5022.     LPCOLESTR szType = OLESTR("REGISTRY");
  5023.     return (bRegister) ? ro.ResourceRegister(pszModule, nResID, szType) :
  5024.             ro.ResourceUnregister(pszModule, nResID, szType);
  5025. }
  5026.  
  5027. inline HRESULT WINAPI CComModule::UpdateRegistryFromResourceS(LPCTSTR lpszRes, BOOL bRegister,
  5028.     struct _ATL_REGMAP_ENTRY* pMapEntries)
  5029. {
  5030.     USES_CONVERSION;
  5031.     ATL::CRegObject ro;
  5032.     TCHAR szModule[_MAX_PATH];
  5033.     GetModuleFileName(_pModule->GetModuleInstance(), szModule, _MAX_PATH);
  5034.  
  5035.    // Convert to short path to work around bug in NT4's CreateProcess
  5036.    TCHAR szModuleShort[_MAX_PATH];
  5037.    GetShortPathName(szModule, szModuleShort, _MAX_PATH);
  5038.    LPOLESTR pszModule = T2OLE(szModuleShort);
  5039.  
  5040.     int nLen = ocslen(pszModule);
  5041.     LPOLESTR pszModuleQuote = (LPOLESTR)alloca((nLen*2+1)*sizeof(OLECHAR));
  5042.     ReplaceSingleQuote(pszModuleQuote, pszModule);
  5043.     ro.AddReplacement(OLESTR("Module"), pszModuleQuote);
  5044.     if (NULL != pMapEntries)
  5045.     {
  5046.         while (NULL != pMapEntries->szKey)
  5047.         {
  5048.             ATLASSERT(NULL != pMapEntries->szData);
  5049.             ro.AddReplacement(pMapEntries->szKey, pMapEntries->szData);
  5050.             pMapEntries++;
  5051.         }
  5052.     }
  5053.  
  5054.     LPCOLESTR szType = OLESTR("REGISTRY");
  5055.     LPCOLESTR pszRes = T2COLE(lpszRes);
  5056.     return (bRegister) ? ro.ResourceRegisterSz(pszModule, pszRes, szType) :
  5057.             ro.ResourceUnregisterSz(pszModule, pszRes, szType);
  5058. }
  5059. #endif //_ATL_STATIC_REGISTRY
  5060.  
  5061. inline HRESULT WINAPI CComModule::UpdateRegistryClass(const CLSID& clsid, LPCTSTR lpszProgID,
  5062.     LPCTSTR lpszVerIndProgID, UINT nDescID, DWORD dwFlags, BOOL bRegister)
  5063. {
  5064.     if (bRegister)
  5065.     {
  5066.         return RegisterClassHelper(clsid, lpszProgID, lpszVerIndProgID, nDescID,
  5067.             dwFlags);
  5068.     }
  5069.     else
  5070.         return UnregisterClassHelper(clsid, lpszProgID, lpszVerIndProgID);
  5071. }
  5072.  
  5073. inline HRESULT WINAPI CComModule::RegisterClassHelper(const CLSID& clsid, LPCTSTR lpszProgID,
  5074.     LPCTSTR lpszVerIndProgID, UINT nDescID, DWORD dwFlags)
  5075. {
  5076. #ifndef __BORLANDC__
  5077.     static const TCHAR szProgID[] = _T("ProgID");
  5078.     static const TCHAR szVIProgID[] = _T("VersionIndependentProgID");
  5079.     static const TCHAR szLS32[] = _T("LocalServer32");
  5080.     static const TCHAR szIPS32[] = _T("InprocServer32");
  5081.     static const TCHAR szThreadingModel[] = _T("ThreadingModel");
  5082.     static const TCHAR szAUTPRX32[] = _T("AUTPRX32.DLL");
  5083.     static const TCHAR szApartment[] = _T("Apartment");
  5084.     static const TCHAR szBoth[] = _T("both");
  5085. #else
  5086.     // Initialized data kills precompiled headers, but string literals
  5087.     // are fine.  macros are undef'd below.
  5088.     #define szProgID _T("ProgID")
  5089.     #define szVIProgID _T("VersionIndependentProgID")
  5090.     #define szLS32 _T("LocalServer32")
  5091.     #define szIPS32 _T("InprocServer32")
  5092.     #define szThreadingModel _T("ThreadingModel")
  5093.     #define szAUTPRX32 _T("AUTPRX32.DLL")
  5094.     #define szApartment _T("Apartment")
  5095.     #define szBoth _T("both")
  5096. #endif // ! __BORLANDC__
  5097.     USES_CONVERSION;
  5098.     HRESULT hRes = S_OK;
  5099.     TCHAR szDesc[256];
  5100.     LoadString(m_hInst, nDescID, szDesc, 256);
  5101.     TCHAR szModule[_MAX_PATH];
  5102.     GetModuleFileName(m_hInst, szModule, _MAX_PATH);
  5103.  
  5104.     LPOLESTR lpOleStr;
  5105.     StringFromCLSID(clsid, &lpOleStr);
  5106.     LPTSTR lpsz = OLE2T(lpOleStr);
  5107.  
  5108.     hRes = RegisterProgID(lpsz, lpszProgID, szDesc);
  5109.     if (hRes == S_OK)
  5110.         hRes = RegisterProgID(lpsz, lpszVerIndProgID, szDesc);
  5111.     LONG lRes = ERROR_SUCCESS;
  5112.     if (hRes == S_OK)
  5113.     {
  5114.         CRegKey key;
  5115.         lRes = key.Open(HKEY_CLASSES_ROOT, _T("CLSID"), KEY_READ);
  5116.         if (lRes == ERROR_SUCCESS)
  5117.         {
  5118.             lRes = key.Create(key, lpsz, REG_NONE, REG_OPTION_NON_VOLATILE, KEY_READ);
  5119.             if (lRes == ERROR_SUCCESS)
  5120.             {
  5121.                 key.SetValue(szDesc);
  5122.                 key.SetKeyValue(szProgID, lpszProgID);
  5123.                 key.SetKeyValue(szVIProgID, lpszVerIndProgID);
  5124.  
  5125.                 if ((m_hInst == NULL) || (m_hInst == GetModuleHandle(NULL))) // register as EXE
  5126.             {
  5127.                // Convert to short path to work around bug in NT4's CreateProcess
  5128.                TCHAR szModuleShort[_MAX_PATH];
  5129.                GetShortPathName(szModule, szModuleShort, _MAX_PATH);
  5130.                     key.SetKeyValue(szLS32, szModuleShort);
  5131.             }
  5132.                 else
  5133.                 {
  5134.                     key.SetKeyValue(szIPS32, (dwFlags & AUTPRXFLAG) ? szAUTPRX32 : szModule);
  5135.                     LPCTSTR lpszModel = (dwFlags & THREADFLAGS_BOTH) ? szBoth :
  5136.                         (dwFlags & THREADFLAGS_APARTMENT) ? szApartment : NULL;
  5137.                     if (lpszModel != NULL)
  5138.                         key.SetKeyValue(szIPS32, lpszModel, szThreadingModel);
  5139.                 }
  5140.             }
  5141.         }
  5142.     }
  5143.     CoTaskMemFree(lpOleStr);
  5144.     if (lRes != ERROR_SUCCESS)
  5145.         hRes = HRESULT_FROM_WIN32(lRes);
  5146.     return hRes;
  5147.  
  5148. #ifdef __BORLANDC__
  5149. #undef szProgID
  5150. #undef szVIProgID
  5151. #undef szLS32
  5152. #undef szIPS32
  5153. #undef szThreadingModel
  5154. #undef szAUTPRX32
  5155. #undef szApartment
  5156. #undef szBoth
  5157. #endif // __BORLANDC__
  5158. }
  5159.  
  5160.  
  5161. inline HRESULT WINAPI CComModule::UnregisterClassHelper(const CLSID& clsid, LPCTSTR lpszProgID,
  5162.     LPCTSTR lpszVerIndProgID)
  5163. {
  5164.     USES_CONVERSION;
  5165.     CRegKey key;
  5166.  
  5167.     key.Attach(HKEY_CLASSES_ROOT);
  5168.     if (lpszProgID != NULL && lstrcmpi(lpszProgID, _T("")))
  5169.         key.RecurseDeleteKey(lpszProgID);
  5170.     if (lpszVerIndProgID != NULL && lstrcmpi(lpszVerIndProgID, _T("")))
  5171.         key.RecurseDeleteKey(lpszVerIndProgID);
  5172.     LPOLESTR lpOleStr;
  5173.     StringFromCLSID(clsid, &lpOleStr);
  5174.     LPTSTR lpsz = OLE2T(lpOleStr);
  5175.     if (key.Open(key, _T("CLSID"), KEY_READ) == ERROR_SUCCESS)
  5176.         key.RecurseDeleteKey(lpsz);
  5177.     CoTaskMemFree(lpOleStr);
  5178.     return S_OK;
  5179. }
  5180.  
  5181. /////////////////////////////////////////////////////////////////////////////
  5182. // Large Block Allocation Helper - CVBufHelper & CVirtualBuffer
  5183.  
  5184.  
  5185. template <class T>
  5186. class CVBufHelper
  5187. {
  5188. public:
  5189.     virtual T* operator()(T* pCurrent) {return pCurrent;}
  5190. };
  5191.  
  5192. template <class T>
  5193. class CVirtualBuffer
  5194. {
  5195. protected:
  5196.     CVirtualBuffer() {}
  5197.     T* m_pBase;
  5198.     T* m_pCurrent;
  5199.     T* m_pTop;
  5200.     int m_nMaxElements;
  5201. public:
  5202.     CVirtualBuffer(int nMaxElements)
  5203.     {
  5204.         m_nMaxElements = nMaxElements;
  5205.         m_pBase = (T*) VirtualAlloc(NULL, sizeof(T) * nMaxElements,
  5206.             MEM_RESERVE, PAGE_READWRITE);
  5207.         m_pTop = m_pCurrent = m_pBase;
  5208.         // Commit first page - chances are this is all that will be used
  5209.         VirtualAlloc(m_pBase, sizeof(T), MEM_COMMIT, PAGE_READWRITE);
  5210.     }
  5211.     ~CVirtualBuffer()
  5212.     {
  5213.         VirtualFree(m_pBase, 0, MEM_RELEASE);
  5214.     }
  5215.     int Except(LPEXCEPTION_POINTERS lpEP)
  5216.     {
  5217.         EXCEPTION_RECORD* pExcept = lpEP->ExceptionRecord;
  5218.         if (pExcept->ExceptionCode != EXCEPTION_ACCESS_VIOLATION)
  5219.             return EXCEPTION_CONTINUE_SEARCH;
  5220.         BYTE* pAddress = (LPBYTE) pExcept->ExceptionInformation[1];
  5221.         VirtualAlloc(pAddress, ((BYTE*)m_pTop - (BYTE*)m_pBase), MEM_COMMIT, PAGE_READWRITE);
  5222.         return EXCEPTION_CONTINUE_EXECUTION;
  5223.     }
  5224.     void Seek(int nElement)
  5225.     {
  5226.         m_pCurrent = &m_pBase[nElement];
  5227.     }
  5228.     void SetAt(int nElement, const T& Element)
  5229.     {
  5230.         __try
  5231.         {
  5232.             T* p = &m_pBase[nElement]
  5233.             *p = Element;
  5234.             m_pTop = p > m_pTop ? p : m_pTop;
  5235.         }
  5236.         __except(Except(GetExceptionInformation()))
  5237.         {
  5238.         }
  5239.  
  5240.     }
  5241.     template <class Q>
  5242.     void WriteBulk(Q& helper)
  5243.     {
  5244.         __try
  5245.         {
  5246.             m_pCurrent = helper(m_pBase);
  5247.             m_pTop = m_pCurrent > m_pTop ? m_pCurrent : m_pTop;
  5248.         }
  5249.         __except(Except(GetExceptionInformation()))
  5250.         {
  5251.         }
  5252.     }
  5253.     void Write(const T& Element)
  5254.     {
  5255.         __try
  5256.         {
  5257.             *m_pCurrent = Element;
  5258.             m_pCurrent++;
  5259.             m_pTop = m_pCurrent > m_pTop ? m_pCurrent : m_pTop;
  5260.         }
  5261.         __except(Except(GetExceptionInformation()))
  5262.         {
  5263.         }
  5264.     }
  5265.     T& Read()
  5266.     {
  5267.         return *m_pCurrent;
  5268.     }
  5269.     operator BSTR()
  5270.     {
  5271.         BSTR bstrTemp;
  5272.         __try
  5273.         {
  5274.             bstrTemp = SysAllocStringByteLen((char*) m_pBase,
  5275.                 (UINT) ((BYTE*)m_pTop - (BYTE*)m_pBase));
  5276.         }
  5277.         __except(Except(GetExceptionInformation()))
  5278.         {
  5279.         }
  5280.         return bstrTemp;
  5281.     }
  5282.     const T& operator[](int nElement) const
  5283.     {
  5284.         return m_pBase[nElement];
  5285.     }
  5286.     operator T*()
  5287.     {
  5288.         return m_pBase;
  5289.     }
  5290. };
  5291.  
  5292. typedef CVirtualBuffer<BYTE> CVirtualBytes;
  5293.  
  5294.  
  5295. inline HRESULT WINAPI AtlDumpIID(REFIID iid, LPCTSTR pszClassName, HRESULT hr)
  5296. {
  5297.     if (atlTraceQI & ATL_TRACE_CATEGORY)
  5298.     {
  5299.         USES_CONVERSION;
  5300.         CRegKey key;
  5301.         TCHAR szName[100];
  5302.         DWORD dwType,dw = sizeof(szName);
  5303.  
  5304.         LPOLESTR pszGUID = NULL;
  5305.         StringFromCLSID(iid, &pszGUID);
  5306.         OutputDebugString(pszClassName);
  5307.         OutputDebugString(_T(" - "));
  5308.  
  5309.         // Attempt to find it in the interfaces section
  5310.         key.Open(HKEY_CLASSES_ROOT, _T("Interface"), KEY_READ);
  5311.         if (key.Open(key, OLE2T(pszGUID), KEY_READ) == S_OK)
  5312.         {
  5313.             *szName = 0;
  5314.             RegQueryValueEx(key.m_hKey, (LPTSTR)NULL, NULL, &dwType, (LPBYTE)szName, &dw);
  5315.             OutputDebugString(szName);
  5316.             goto cleanup;
  5317.         }
  5318.         // Attempt to find it in the clsid section
  5319.         key.Open(HKEY_CLASSES_ROOT, _T("CLSID"), KEY_READ);
  5320.         if (key.Open(key, OLE2T(pszGUID), KEY_READ) == S_OK)
  5321.         {
  5322.             *szName = 0;
  5323.             RegQueryValueEx(key.m_hKey, (LPTSTR)NULL, NULL, &dwType, (LPBYTE)szName, &dw);
  5324.             OutputDebugString(_T("(CLSID\?\?\?) "));
  5325.             OutputDebugString(szName);
  5326.             goto cleanup;
  5327.         }
  5328.         OutputDebugString(OLE2T(pszGUID));
  5329.     cleanup:
  5330.         if (hr != S_OK)
  5331.             OutputDebugString(_T(" - failed"));
  5332.         OutputDebugString(_T("\n"));
  5333.         CoTaskMemFree(pszGUID);
  5334.     }
  5335.     return hr;
  5336. }
  5337.  
  5338. #pragma pack(pop)
  5339.  
  5340. // WM_FORWARDMSG - used to forward a message to another window for processing
  5341. // WPARAM - DWORD dwUserData - defined by user
  5342. // LPARAM - LPMSG pMsg - a pointer to the MSG structure
  5343. // return value - 0 if the message was not processed, nonzero if it was
  5344. #define WM_FORWARDMSG       0x037F
  5345.  
  5346. }; //namespace ATL
  5347. using namespace ATL;
  5348.  
  5349. //only suck in definition if static linking
  5350. #ifndef _ATL_DLL_IMPL
  5351. #ifndef _ATL_DLL
  5352. #define _ATLBASE_IMPL
  5353. #endif
  5354. #endif
  5355.  
  5356. #ifdef _ATL_REDEF_NEW
  5357. #pragma pop_macro("new")
  5358. #undef _ATL_REDEF_NEW
  5359. #endif
  5360.  
  5361. #endif // __ATLBASE_H__
  5362.  
  5363. //All exports go here
  5364. #ifdef _ATLBASE_IMPL
  5365.  
  5366. #ifndef _ATL_DLL_IMPL
  5367. namespace ATL
  5368. {
  5369. #endif
  5370.  
  5371. /////////////////////////////////////////////////////////////////////////////
  5372. // statics
  5373.  
  5374. #ifndef __BORLANDC__
  5375. static UINT WINAPI AtlGetDirLen(LPCOLESTR lpszPathName)
  5376. {
  5377.     ATLASSERT(lpszPathName != NULL);
  5378.  
  5379.     // always capture the complete file name including extension (if present)
  5380.     LPCOLESTR lpszTemp = lpszPathName;
  5381.     for (LPCOLESTR lpsz = lpszPathName; *lpsz != NULL; )
  5382.     {
  5383.         LPCOLESTR lp = CharNextO(lpsz);
  5384.         // remember last directory/drive separator
  5385.         if (*lpsz == OLESTR('\\') || *lpsz == OLESTR('/') || *lpsz == OLESTR(':'))
  5386.             lpszTemp = lp;
  5387.         lpsz = lp;
  5388.     }
  5389.  
  5390.     return lpszTemp-lpszPathName;
  5391. }
  5392. #else
  5393. extern UINT WINAPI AtlGetDirLen(LPCOLESTR lpszPathName);
  5394. #endif
  5395.  
  5396. /////////////////////////////////////////////////////////////////////////////
  5397. // QI support
  5398.  
  5399. ATLINLINE ATLAPI AtlInternalQueryInterface(void* pThis,
  5400.     const _ATL_INTMAP_ENTRY* pEntries, REFIID iid, void** ppvObject)
  5401. {
  5402.     ATLASSERT(pThis != NULL);
  5403.     // First entry in the com map should be a simple map entry
  5404.     ATLASSERT(pEntries->pFunc == _ATL_SIMPLEMAPENTRY);
  5405.     if (ppvObject == NULL)
  5406.         return E_POINTER;
  5407.     *ppvObject = NULL;
  5408.     if (InlineIsEqualUnknown(iid)) // use first interface
  5409.     {
  5410.             IUnknown* pUnk = (IUnknown*)((int)pThis+pEntries->dw);
  5411.             pUnk->AddRef();
  5412.             *ppvObject = pUnk;
  5413.             return S_OK;
  5414.     }
  5415.     while (pEntries->pFunc != NULL)
  5416.     {
  5417.         BOOL bBlind = (pEntries->piid == NULL);
  5418.         if (bBlind || InlineIsEqualGUID(*(pEntries->piid), iid))
  5419.         {
  5420.             if (pEntries->pFunc == _ATL_SIMPLEMAPENTRY) //offset
  5421.             {
  5422.                 ATLASSERT(!bBlind);
  5423.                 IUnknown* pUnk = (IUnknown*)((int)pThis+pEntries->dw);
  5424.                 pUnk->AddRef();
  5425.                 *ppvObject = pUnk;
  5426.                 return S_OK;
  5427.             }
  5428.             else //actual function call
  5429.             {
  5430.                 HRESULT hRes = pEntries->pFunc(pThis,
  5431.                     iid, ppvObject, pEntries->dw);
  5432.                 if (hRes == S_OK || (!bBlind && FAILED(hRes)))
  5433.                     return hRes;
  5434.             }
  5435.         }
  5436.         pEntries++;
  5437.     }
  5438.     return E_NOINTERFACE;
  5439. }
  5440.  
  5441. /////////////////////////////////////////////////////////////////////////////
  5442. // Smart Pointer helpers
  5443.  
  5444. ATLINLINE ATLAPI_(IUnknown*) AtlComPtrAssign(IUnknown** pp, IUnknown* lp)
  5445. {
  5446.     if (lp != NULL)
  5447.         lp->AddRef();
  5448.     if (*pp)
  5449.         (*pp)->Release();
  5450.     *pp = lp;
  5451.     return lp;
  5452. }
  5453.  
  5454. ATLINLINE ATLAPI_(IUnknown*) AtlComQIPtrAssign(IUnknown** pp, IUnknown* lp, REFIID riid)
  5455. {
  5456.     IUnknown* pTemp = *pp;
  5457.     *pp = NULL;
  5458.     if (lp != NULL)
  5459.         lp->QueryInterface(riid, (void**)pp);
  5460.     if (pTemp)
  5461.         pTemp->Release();
  5462.     return *pp;
  5463. }
  5464.  
  5465. /////////////////////////////////////////////////////////////////////////////
  5466. // Inproc Marshaling helpers
  5467.  
  5468. //This API should be called from the same thread that called
  5469. //AtlMarshalPtrInProc
  5470. ATLINLINE ATLAPI AtlFreeMarshalStream(IStream* pStream)
  5471. {
  5472.     if (pStream != NULL)
  5473.     {
  5474.         LARGE_INTEGER l;
  5475.         l.QuadPart = 0;
  5476.         pStream->Seek(l, STREAM_SEEK_SET, NULL);
  5477.         CoReleaseMarshalData(pStream);
  5478.         pStream->Release();
  5479.     }
  5480.     return S_OK;
  5481. }
  5482.  
  5483. ATLINLINE ATLAPI AtlMarshalPtrInProc(IUnknown* pUnk, const IID& iid, IStream** ppStream)
  5484. {
  5485.     HRESULT hRes = CreateStreamOnHGlobal(NULL, TRUE, ppStream);
  5486.     if (SUCCEEDED(hRes))
  5487.     {
  5488.         hRes = CoMarshalInterface(*ppStream, iid,
  5489.             pUnk, MSHCTX_INPROC, NULL, MSHLFLAGS_TABLESTRONG);
  5490.         if (FAILED(hRes))
  5491.         {
  5492.             (*ppStream)->Release();
  5493.             *ppStream = NULL;
  5494.         }
  5495.     }
  5496.     return hRes;
  5497. }
  5498.  
  5499. ATLINLINE ATLAPI AtlUnmarshalPtr(IStream* pStream, const IID& iid, IUnknown** ppUnk)
  5500. {
  5501.     *ppUnk = NULL;
  5502.     HRESULT hRes = E_INVALIDARG;
  5503.     if (pStream != NULL)
  5504.     {
  5505.         LARGE_INTEGER l;
  5506.         l.QuadPart = 0;
  5507.         pStream->Seek(l, STREAM_SEEK_SET, NULL);
  5508.         hRes = CoUnmarshalInterface(pStream, iid, (void**)ppUnk);
  5509.     }
  5510.     return hRes;
  5511. }
  5512.  
  5513. ATLINLINE ATLAPI_(BOOL) AtlWaitWithMessageLoop(HANDLE hEvent)
  5514. {
  5515.     DWORD dwRet;
  5516.     MSG msg;
  5517.  
  5518.     while(1)
  5519.     {
  5520.         dwRet = MsgWaitForMultipleObjects(1, &hEvent, FALSE, INFINITE, QS_ALLINPUT);
  5521.  
  5522.         if (dwRet == WAIT_OBJECT_0)
  5523.             return TRUE;    // The event was signaled
  5524.  
  5525.         if (dwRet != WAIT_OBJECT_0 + 1)
  5526.             break;          // Something else happened
  5527.  
  5528.         // There is one or more window message available. Dispatch them
  5529.         while(PeekMessage(&msg,NULL,NULL,NULL,PM_REMOVE))
  5530.         {
  5531.             TranslateMessage(&msg);
  5532.             DispatchMessage(&msg);
  5533.             if (WaitForSingleObject(hEvent, 0) == WAIT_OBJECT_0)
  5534.                 return TRUE; // Event is now signaled.
  5535.         }
  5536.     }
  5537.     return FALSE;
  5538. }
  5539.  
  5540. /////////////////////////////////////////////////////////////////////////////
  5541. // Connection Point Helpers
  5542.  
  5543. ATLINLINE ATLAPI AtlAdvise(IUnknown* pUnkCP, IUnknown* pUnk, const IID& iid, LPDWORD pdw)
  5544. {
  5545.     CComPtr<IConnectionPointContainer> pCPC;
  5546.     CComPtr<IConnectionPoint> pCP;
  5547.     HRESULT hRes = pUnkCP->QueryInterface(IID_IConnectionPointContainer, (void**)&pCPC);
  5548.     if (SUCCEEDED(hRes))
  5549.         hRes = pCPC->FindConnectionPoint(iid, &pCP);
  5550.     if (SUCCEEDED(hRes))
  5551.         hRes = pCP->Advise(pUnk, pdw);
  5552.     return hRes;
  5553. }
  5554.  
  5555. ATLINLINE ATLAPI AtlUnadvise(IUnknown* pUnkCP, const IID& iid, DWORD dw)
  5556. {
  5557.     CComPtr<IConnectionPointContainer> pCPC;
  5558.     CComPtr<IConnectionPoint> pCP;
  5559.     HRESULT hRes = pUnkCP->QueryInterface(IID_IConnectionPointContainer, (void**)&pCPC);
  5560.     if (SUCCEEDED(hRes))
  5561.         hRes = pCPC->FindConnectionPoint(iid, &pCP);
  5562.     if (SUCCEEDED(hRes))
  5563.         hRes = pCP->Unadvise(dw);
  5564.     return hRes;
  5565. }
  5566.  
  5567. /////////////////////////////////////////////////////////////////////////////
  5568. // IDispatch Error handling
  5569.  
  5570. ATLINLINE ATLAPI AtlSetErrorInfo(const CLSID& clsid, LPCOLESTR lpszDesc, DWORD dwHelpID,
  5571.     LPCOLESTR lpszHelpFile, const IID& iid, HRESULT hRes, HINSTANCE hInst)
  5572. {
  5573.     USES_CONVERSION;
  5574.     TCHAR szDesc[1024];
  5575.     szDesc[0] = NULL;
  5576.     // For a valid HRESULT the id should be in the range [0x0200, 0xffff]
  5577.     if (HIWORD(lpszDesc) == 0) //id
  5578.     {
  5579.         UINT nID = LOWORD((DWORD)lpszDesc);
  5580.         ATLASSERT((nID >= 0x0200 && nID <= 0xffff) || hRes != 0);
  5581.         if (LoadString(hInst, nID, szDesc, 1024) == 0)
  5582.         {
  5583.             ATLASSERT(FALSE);
  5584.             lstrcpy(szDesc, _T("Unknown Error"));
  5585.         }
  5586.         lpszDesc = T2OLE(szDesc);
  5587.         if (hRes == 0)
  5588.             hRes = MAKE_HRESULT(3, FACILITY_ITF, nID);
  5589.     }
  5590.  
  5591.     CComPtr<ICreateErrorInfo> pICEI;
  5592.     if (SUCCEEDED(CreateErrorInfo(&pICEI)))
  5593.     {
  5594.         CComPtr<IErrorInfo> pErrorInfo;
  5595.         pICEI->SetGUID(iid);
  5596.         LPOLESTR lpsz;
  5597.         ProgIDFromCLSID(clsid, &lpsz);
  5598.         if (lpsz != NULL)
  5599.             pICEI->SetSource(lpsz);
  5600.         if (dwHelpID != 0 && lpszHelpFile != NULL)
  5601.         {
  5602.             pICEI->SetHelpContext(dwHelpID);
  5603.             pICEI->SetHelpFile(const_cast<LPOLESTR>(lpszHelpFile));
  5604.         }
  5605.         CoTaskMemFree(lpsz);
  5606.         pICEI->SetDescription((LPOLESTR)lpszDesc);
  5607.         if (SUCCEEDED(pICEI->QueryInterface(IID_IErrorInfo, (void**)&pErrorInfo)))
  5608.             SetErrorInfo(0, pErrorInfo);
  5609.     }
  5610.     return (hRes == 0) ? DISP_E_EXCEPTION : hRes;
  5611. }
  5612.  
  5613. /////////////////////////////////////////////////////////////////////////////
  5614. // Module
  5615.  
  5616. struct _ATL_MODULE20
  5617. {
  5618. // Attributes
  5619. public:
  5620.     UINT cbSize;
  5621.     HINSTANCE m_hInst;
  5622.     HINSTANCE m_hInstResource;
  5623.     HINSTANCE m_hInstTypeLib;
  5624.     _ATL_OBJMAP_ENTRY* m_pObjMap;
  5625.     LONG m_nLockCnt;
  5626.     HANDLE m_hHeap;
  5627.     CRITICAL_SECTION m_csTypeInfoHolder;
  5628.     CRITICAL_SECTION m_csWindowCreate;
  5629.     CRITICAL_SECTION m_csObjMap;
  5630. };
  5631.  
  5632. typedef _ATL_MODULE _ATL_MODULE30;
  5633.  
  5634. struct _ATL_OBJMAP_ENTRY20
  5635. {
  5636.     const CLSID* pclsid;
  5637.     HRESULT (WINAPI *pfnUpdateRegistry)(BOOL bRegister);
  5638.     _ATL_CREATORFUNC* pfnGetClassObject;
  5639.     _ATL_CREATORFUNC* pfnCreateInstance;
  5640.     IUnknown* pCF;
  5641.     DWORD dwRegister;
  5642.     _ATL_DESCRIPTIONFUNC* pfnGetObjectDescription;
  5643. };
  5644.  
  5645. typedef _ATL_OBJMAP_ENTRY _ATL_OBJMAP_ENTRY30;
  5646.  
  5647. inline _ATL_OBJMAP_ENTRY* _NextObjectMapEntry(_ATL_MODULE* pM, _ATL_OBJMAP_ENTRY* pEntry)
  5648. {
  5649.     if (pM->cbSize == sizeof(_ATL_MODULE20))
  5650.         return (_ATL_OBJMAP_ENTRY*)(((BYTE*)pEntry) + sizeof(_ATL_OBJMAP_ENTRY20));
  5651.     return pEntry+1;
  5652. }
  5653.  
  5654. //Although these functions are big, they are only used once in a module
  5655. //so we should make them inline.
  5656.  
  5657. ATLINLINE ATLAPI AtlModuleInit(_ATL_MODULE* pM, _ATL_OBJMAP_ENTRY* p, HINSTANCE h)
  5658. {
  5659.     ATLASSERT(pM != NULL);
  5660.     if (pM == NULL)
  5661.         return E_INVALIDARG;
  5662. #ifdef _ATL_DLL_IMPL
  5663.     if ((pM->cbSize != _nAtlModuleVer1Size) && (pM->cbSize != sizeof(_ATL_MODULE)))
  5664.         return E_INVALIDARG;
  5665. #else
  5666.     ATLASSERT(pM->cbSize == sizeof(_ATL_MODULE));
  5667. #endif
  5668.     pM->m_pObjMap = p;
  5669.     pM->m_hInst = pM->m_hInstTypeLib = pM->m_hInstResource = h;
  5670.     pM->m_nLockCnt=0L;
  5671.     pM->m_hHeap = NULL;
  5672.     InitializeCriticalSection(&pM->m_csTypeInfoHolder);
  5673.     InitializeCriticalSection(&pM->m_csWindowCreate);
  5674.     InitializeCriticalSection(&pM->m_csObjMap);
  5675. #ifdef _ATL_DLL_IMPL
  5676.     if (pM->cbSize > _nAtlModuleVer1Size)
  5677. #endif
  5678.     {
  5679.         pM->m_pCreateWndList = NULL;
  5680.         pM->m_bDestroyHeap = true;
  5681.         pM->m_dwHeaps = 0;
  5682.         pM->m_nHeap = 0;
  5683.         pM->m_phHeaps = NULL;
  5684.         pM->m_pTermFuncs = NULL;
  5685.         if (pM->m_pObjMap != NULL)
  5686.         {
  5687.             _ATL_OBJMAP_ENTRY* pEntry = pM->m_pObjMap;
  5688.             while (pEntry->pclsid != NULL)
  5689.             {
  5690.                 pEntry->pfnObjectMain(true); //initialize class resources
  5691.                 pEntry = _NextObjectMapEntry(pM, pEntry);
  5692.             }
  5693.         }
  5694.     }
  5695.  
  5696.     return S_OK;
  5697. }
  5698.  
  5699. ATLINLINE ATLAPI AtlModuleRegisterClassObjects(_ATL_MODULE* pM, DWORD dwClsContext, DWORD dwFlags)
  5700. {
  5701.     ATLASSERT(pM != NULL);
  5702.     if (pM == NULL)
  5703.         return E_INVALIDARG;
  5704.     ATLASSERT(pM->m_pObjMap != NULL);
  5705.     _ATL_OBJMAP_ENTRY* pEntry = pM->m_pObjMap;
  5706.     HRESULT hRes = S_OK;
  5707.     while (pEntry->pclsid != NULL && hRes == S_OK)
  5708.     {
  5709.         hRes = pEntry->RegisterClassObject(dwClsContext, dwFlags);
  5710.         pEntry = _NextObjectMapEntry(pM, pEntry);
  5711.     }
  5712.     return hRes;
  5713. }
  5714.  
  5715. ATLINLINE ATLAPI AtlModuleRevokeClassObjects(_ATL_MODULE* pM)
  5716. {
  5717.     ATLASSERT(pM != NULL);
  5718.     if (pM == NULL)
  5719.         return E_INVALIDARG;
  5720.     ATLASSERT(pM->m_pObjMap != NULL);
  5721.     _ATL_OBJMAP_ENTRY* pEntry = pM->m_pObjMap;
  5722.     HRESULT hRes = S_OK;
  5723.     while (pEntry->pclsid != NULL && hRes == S_OK)
  5724.     {
  5725.         hRes = pEntry->RevokeClassObject();
  5726.         pEntry = _NextObjectMapEntry(pM, pEntry);
  5727.     }
  5728.     return hRes;
  5729. }
  5730.  
  5731. ATLINLINE ATLAPI AtlModuleGetClassObject(_ATL_MODULE* pM, REFCLSID rclsid, REFIID riid, LPVOID* ppv)
  5732. {
  5733.     ATLASSERT(pM != NULL);
  5734.     if (pM == NULL)
  5735.         return E_INVALIDARG;
  5736.     ATLASSERT(pM->m_pObjMap != NULL);
  5737.     _ATL_OBJMAP_ENTRY* pEntry = pM->m_pObjMap;
  5738.     HRESULT hRes = S_OK;
  5739.     if (ppv == NULL)
  5740.         return E_POINTER;
  5741.     *ppv = NULL;
  5742.     while (pEntry->pclsid != NULL)
  5743.     {
  5744.         if ((pEntry->pfnGetClassObject != NULL) && InlineIsEqualGUID(rclsid, *pEntry->pclsid))
  5745.         {
  5746.             if (pEntry->pCF == NULL)
  5747.             {
  5748.                 EnterCriticalSection(&pM->m_csObjMap);
  5749.                 if (pEntry->pCF == NULL)
  5750.                     hRes = pEntry->pfnGetClassObject(pEntry->pfnCreateInstance, IID_IUnknown, (LPVOID*)&pEntry->pCF);
  5751.                 LeaveCriticalSection(&pM->m_csObjMap);
  5752.             }
  5753.             if (pEntry->pCF != NULL)
  5754.                 hRes = pEntry->pCF->QueryInterface(riid, ppv);
  5755.             break;
  5756.         }
  5757.         pEntry = _NextObjectMapEntry(pM, pEntry);
  5758.     }
  5759.     if (*ppv == NULL && hRes == S_OK)
  5760.         hRes = CLASS_E_CLASSNOTAVAILABLE;
  5761.     return hRes;
  5762. }
  5763.  
  5764. ATLINLINE ATLAPI AtlModuleTerm(_ATL_MODULE* pM)
  5765. {
  5766.     ATLASSERT(pM != NULL);
  5767.     if (pM == NULL)
  5768.         return E_INVALIDARG;
  5769.     ATLASSERT(pM->m_hInst != NULL);
  5770.     if (pM->m_pObjMap != NULL)
  5771.     {
  5772.         _ATL_OBJMAP_ENTRY* pEntry = pM->m_pObjMap;
  5773.         while (pEntry->pclsid != NULL)
  5774.         {
  5775.             if (pEntry->pCF != NULL)
  5776.                 pEntry->pCF->Release();
  5777.             pEntry->pCF = NULL;
  5778. #ifdef _ATL_DLL_IMPL
  5779.             if (pM->cbSize > _nAtlModuleVer1Size)
  5780. #endif
  5781.                 pEntry->pfnObjectMain(false); //cleanup class resources
  5782.             pEntry = _NextObjectMapEntry(pM, pEntry);
  5783.         }
  5784.     }
  5785.     DeleteCriticalSection(&pM->m_csTypeInfoHolder);
  5786.     DeleteCriticalSection(&pM->m_csWindowCreate);
  5787.     DeleteCriticalSection(&pM->m_csObjMap);
  5788.  
  5789. #ifdef _ATL_DLL_IMPL
  5790.     if (pM->cbSize > _nAtlModuleVer1Size)
  5791. #endif
  5792.     {
  5793.         _ATL_TERMFUNC_ELEM* pElem = pM->m_pTermFuncs;
  5794.         _ATL_TERMFUNC_ELEM* pNext = NULL;
  5795.         while (pElem != NULL)
  5796.         {
  5797.             pElem->pFunc(pElem->dw);
  5798.             pNext = pElem->pNext;
  5799.             delete pElem;
  5800.             pElem = pNext;
  5801.         }
  5802.         if (pM->m_hHeap != NULL && pM->m_bDestroyHeap)
  5803.         {
  5804. #ifndef _ATL_NO_MP_HEAP
  5805.             if (pM->m_phHeaps != NULL)
  5806.             {
  5807.                 for (DWORD i = 0; i <= pM->m_dwHeaps; i++)
  5808.                     HeapDestroy(pM->m_phHeaps[i]);
  5809.             }
  5810. #endif
  5811.             HeapDestroy(pM->m_hHeap);
  5812.         }
  5813.     }
  5814.     return S_OK;
  5815. }
  5816.  
  5817. ATLINLINE ATLAPI AtlModuleAddTermFunc(_ATL_MODULE* pM, _ATL_TERMFUNC* pFunc, DWORD dw)
  5818. {
  5819.     HRESULT hr = S_OK;
  5820.     _ATL_TERMFUNC_ELEM* pNew = NULL;
  5821.     ATLTRY(pNew = new _ATL_TERMFUNC_ELEM);
  5822.     if (pNew == NULL)
  5823.         hr = E_OUTOFMEMORY;
  5824.     else
  5825.     {
  5826.         pNew->pFunc = pFunc;
  5827.         pNew->dw = dw;
  5828.         EnterCriticalSection(&pM->m_csStaticDataInit);
  5829.         pNew->pNext = pM->m_pTermFuncs;
  5830.         pM->m_pTermFuncs = pNew;
  5831.         LeaveCriticalSection(&pM->m_csStaticDataInit);
  5832.     }
  5833.     return hr;
  5834. }
  5835.  
  5836. ATLINLINE ATLAPI AtlRegisterClassCategoriesHelper( REFCLSID clsid,
  5837.    const struct _ATL_CATMAP_ENTRY* pCatMap, BOOL bRegister )
  5838. {
  5839.    CComPtr< ICatRegister > pCatRegister;
  5840.    HRESULT hResult;
  5841.    const struct _ATL_CATMAP_ENTRY* pEntry;
  5842.    CATID catid;
  5843.  
  5844.    if( pCatMap == NULL )
  5845.    {
  5846.       return( S_OK );
  5847.    }
  5848.  
  5849.    hResult = CoCreateInstance( CLSID_StdComponentCategoriesMgr, NULL,
  5850.       CLSCTX_INPROC_SERVER, IID_ICatRegister, (void**)&pCatRegister );
  5851.    if( FAILED( hResult ) )
  5852.    {
  5853.       // Since not all systems have the category manager installed, we'll allow
  5854.       // the registration to succeed even though we didn't register our
  5855.       // categories.  If you really want to register categories on a system
  5856.       // without the category manager, you can either manually add the
  5857.       // appropriate entries to your registry script (.rgs), or you can
  5858.       // redistribute comcat.dll.
  5859.       return( S_OK );
  5860.    }
  5861.  
  5862.    hResult = S_OK;
  5863.    pEntry = pCatMap;
  5864.    while( pEntry->iType != _ATL_CATMAP_ENTRY_END )
  5865.    {
  5866.       catid = *pEntry->pcatid;
  5867.       if( bRegister )
  5868.       {
  5869.          if( pEntry->iType == _ATL_CATMAP_ENTRY_IMPLEMENTED )
  5870.          {
  5871.             hResult = pCatRegister->RegisterClassImplCategories( clsid, 1,
  5872.                &catid );
  5873.          }
  5874.          else
  5875.          {
  5876.             ATLASSERT( pEntry->iType == _ATL_CATMAP_ENTRY_REQUIRED );
  5877.             hResult = pCatRegister->RegisterClassReqCategories( clsid, 1,
  5878.                &catid );
  5879.          }
  5880.          if( FAILED( hResult ) )
  5881.          {
  5882.             return( hResult );
  5883.          }
  5884.       }
  5885.       else
  5886.       {
  5887.          if( pEntry->iType == _ATL_CATMAP_ENTRY_IMPLEMENTED )
  5888.          {
  5889.             pCatRegister->UnRegisterClassImplCategories( clsid, 1, &catid );
  5890.          }
  5891.          else
  5892.          {
  5893.             ATLASSERT( pEntry->iType == _ATL_CATMAP_ENTRY_REQUIRED );
  5894.             pCatRegister->UnRegisterClassReqCategories( clsid, 1, &catid );
  5895.          }
  5896.       }
  5897.       pEntry++;
  5898.    }
  5899.  
  5900.    return( S_OK );
  5901. }
  5902.  
  5903. ATLINLINE ATLAPI AtlModuleRegisterServer(_ATL_MODULE* pM, BOOL bRegTypeLib, const CLSID* pCLSID)
  5904. {
  5905.     ATLASSERT(pM != NULL);
  5906.     if (pM == NULL)
  5907.         return E_INVALIDARG;
  5908.     ATLASSERT(pM->m_hInst != NULL);
  5909.     ATLASSERT(pM->m_pObjMap != NULL);
  5910.     _ATL_OBJMAP_ENTRY* pEntry = pM->m_pObjMap;
  5911.     HRESULT hRes = S_OK;
  5912.     for (;pEntry->pclsid != NULL; pEntry = _NextObjectMapEntry(pM, pEntry))
  5913.     {
  5914.         if (pCLSID == NULL)
  5915.         {
  5916.             if (pEntry->pfnGetObjectDescription != NULL &&
  5917.                 pEntry->pfnGetObjectDescription() != NULL)
  5918.                     continue;
  5919.         }
  5920.         else
  5921.         {
  5922.             if (!IsEqualGUID(*pCLSID, *pEntry->pclsid))
  5923.                 continue;
  5924.         }
  5925.         hRes = pEntry->pfnUpdateRegistry(TRUE);
  5926.         if (FAILED(hRes))
  5927.             break;
  5928.         if (pM->cbSize == sizeof(_ATL_MODULE))
  5929.         {
  5930.             hRes = AtlRegisterClassCategoriesHelper( *pEntry->pclsid,
  5931.                 pEntry->pfnGetCategoryMap(), TRUE );
  5932.             if (FAILED(hRes))
  5933.                 break;
  5934.         }
  5935.     }
  5936.     if (SUCCEEDED(hRes) && bRegTypeLib)
  5937.         hRes = AtlModuleRegisterTypeLib(pM, 0);
  5938.     return hRes;
  5939. }
  5940.  
  5941. ATLINLINE ATLAPI AtlModuleUnregisterServerEx(_ATL_MODULE* pM, BOOL bUnRegTypeLib, const CLSID* pCLSID)
  5942. {
  5943.     ATLASSERT(pM != NULL);
  5944.     if (pM == NULL)
  5945.         return E_INVALIDARG;
  5946.     ATLASSERT(pM->m_hInst != NULL);
  5947.     ATLASSERT(pM->m_pObjMap != NULL);
  5948.     _ATL_OBJMAP_ENTRY* pEntry = pM->m_pObjMap;
  5949.     for (;pEntry->pclsid != NULL; pEntry = _NextObjectMapEntry(pM, pEntry))
  5950.     {
  5951.         if (pCLSID == NULL)
  5952.         {
  5953.             if (pEntry->pfnGetObjectDescription != NULL
  5954.                 && pEntry->pfnGetObjectDescription() != NULL)
  5955.                 continue;
  5956.         }
  5957.         else
  5958.         {
  5959.             if (!IsEqualGUID(*pCLSID, *pEntry->pclsid))
  5960.                 continue;
  5961.         }
  5962.         pEntry->pfnUpdateRegistry(FALSE); //unregister
  5963.         AtlRegisterClassCategoriesHelper( *pEntry->pclsid,
  5964.             pEntry->pfnGetCategoryMap(), FALSE );
  5965.     }
  5966.     if (bUnRegTypeLib)
  5967.         AtlModuleUnRegisterTypeLib(pM, 0);
  5968.     return S_OK;
  5969. }
  5970.  
  5971. ATLINLINE ATLAPI AtlModuleUnregisterServer(_ATL_MODULE* pM, const CLSID* pCLSID)
  5972. {
  5973.     return AtlModuleUnregisterServerEx(pM, FALSE, pCLSID);
  5974. }
  5975.  
  5976. ATLINLINE ATLAPI AtlModuleUpdateRegistryFromResourceD(_ATL_MODULE* pM, LPCOLESTR lpszRes,
  5977.     BOOL bRegister, struct _ATL_REGMAP_ENTRY* pMapEntries, IRegistrar* pReg)
  5978. {
  5979.     USES_CONVERSION;
  5980.     ATLASSERT(pM != NULL);
  5981.     HRESULT hRes = S_OK;
  5982.     CComPtr<IRegistrar> p;
  5983.     if (pReg != NULL)
  5984.         p = pReg;
  5985.     else
  5986.     {
  5987.         hRes = CoCreateInstance(CLSID_Registrar, NULL,
  5988.             CLSCTX_INPROC_SERVER, IID_IRegistrar, (void**)&p);
  5989.     }
  5990.     if (SUCCEEDED(hRes))
  5991.     {
  5992.         TCHAR szModule[_MAX_PATH];
  5993.         GetModuleFileName(pM->m_hInst, szModule, _MAX_PATH);
  5994.  
  5995.       // Convert to short path to work around bug in NT4's CreateProcess
  5996.       TCHAR szModuleShort[_MAX_PATH];
  5997.       GetShortPathName(szModule, szModuleShort, _MAX_PATH);
  5998.       LPOLESTR pszModule = T2OLE(szModuleShort);
  5999.  
  6000.         int nLen = ocslen(pszModule);
  6001.         LPOLESTR pszModuleQuote = (LPOLESTR)alloca((nLen*2+1)*sizeof(OLECHAR));
  6002.         CComModule::ReplaceSingleQuote(pszModuleQuote, pszModule);
  6003.         p->AddReplacement(OLESTR("Module"), pszModuleQuote);
  6004.  
  6005.         if (NULL != pMapEntries)
  6006.         {
  6007.             while (NULL != pMapEntries->szKey)
  6008.             {
  6009.                 ATLASSERT(NULL != pMapEntries->szData);
  6010.                 p->AddReplacement((LPOLESTR)pMapEntries->szKey, (LPOLESTR)pMapEntries->szData);
  6011.                 pMapEntries++;
  6012.             }
  6013.         }
  6014.         LPCOLESTR szType = OLESTR("REGISTRY");
  6015.         if (HIWORD(lpszRes)==0)
  6016.         {
  6017.             if (bRegister)
  6018.                 hRes = p->ResourceRegister(pszModule, ((UINT)LOWORD((DWORD)lpszRes)), szType);
  6019.             else
  6020.                 hRes = p->ResourceUnregister(pszModule, ((UINT)LOWORD((DWORD)lpszRes)), szType);
  6021.         }
  6022.         else
  6023.         {
  6024.             if (bRegister)
  6025.                 hRes = p->ResourceRegisterSz(pszModule, lpszRes, szType);
  6026.             else
  6027.                 hRes = p->ResourceUnregisterSz(pszModule, lpszRes, szType);
  6028.         }
  6029.  
  6030.     }
  6031.     return hRes;
  6032. }
  6033.  
  6034. /////////////////////////////////////////////////////////////////////////////
  6035. // TypeLib Support
  6036.  
  6037. ATLINLINE ATLAPI AtlModuleLoadTypeLib(_ATL_MODULE* pM, LPCOLESTR lpszIndex, BSTR* pbstrPath, ITypeLib** ppTypeLib)
  6038. {
  6039.     *pbstrPath = NULL;
  6040.     *ppTypeLib = NULL;
  6041.     ATLASSERT(pM != NULL);
  6042.     USES_CONVERSION;
  6043.     ATLASSERT(pM->m_hInstTypeLib != NULL);
  6044.     TCHAR szModule[_MAX_PATH+10];
  6045.     GetModuleFileName(pM->m_hInstTypeLib, szModule, _MAX_PATH);
  6046.     if (lpszIndex != NULL)
  6047.         lstrcat(szModule, OLE2CT(lpszIndex));
  6048.     LPOLESTR lpszModule = T2OLE(szModule);
  6049.     HRESULT hr = LoadTypeLib(lpszModule, ppTypeLib);
  6050.     if (!SUCCEEDED(hr))
  6051.     {
  6052.         // typelib not in module, try <module>.tlb instead
  6053.         LPTSTR lpszExt = NULL;
  6054.         LPTSTR lpsz;
  6055.         for (lpsz = szModule; *lpsz != NULL; lpsz = CharNext(lpsz))
  6056.         {
  6057.             if (*lpsz == _T('.'))
  6058.                 lpszExt = lpsz;
  6059.         }
  6060.         if (lpszExt == NULL)
  6061.             lpszExt = lpsz;
  6062.         lstrcpy(lpszExt, _T(".tlb"));
  6063.         lpszModule = T2OLE(szModule);
  6064.         hr = LoadTypeLib(lpszModule, ppTypeLib);
  6065.     }
  6066.     if (SUCCEEDED(hr))
  6067.         *pbstrPath = OLE2BSTR(lpszModule);
  6068.     return hr;
  6069. }
  6070.  
  6071. ATLINLINE ATLAPI AtlModuleUnRegisterTypeLib(_ATL_MODULE* pM, LPCOLESTR lpszIndex)
  6072. {
  6073.     typedef HRESULT (WINAPI *PFNRTL)(REFGUID, WORD, WORD, LCID, SYSKIND);
  6074.     CComBSTR bstrPath;
  6075.     CComPtr<ITypeLib> pTypeLib;
  6076.     HRESULT hr = AtlModuleLoadTypeLib(pM, lpszIndex, &bstrPath, &pTypeLib);
  6077.     if (SUCCEEDED(hr))
  6078.     {
  6079.         TLIBATTR* ptla;
  6080.         HRESULT hr = pTypeLib->GetLibAttr(&ptla);
  6081.         if (SUCCEEDED(hr))
  6082.         {
  6083.             HINSTANCE h = LoadLibrary(_T("oleaut32.dll"));
  6084.             if (h != NULL)
  6085.             {
  6086.                 PFNRTL pfn = (PFNRTL) GetProcAddress(h, "UnRegisterTypeLib");
  6087.                 if (pfn != NULL)
  6088.                     hr = pfn(ptla->guid, ptla->wMajorVerNum, ptla->wMinorVerNum, ptla->lcid, ptla->syskind);
  6089.                 FreeLibrary(h);
  6090.             }
  6091.             pTypeLib->ReleaseTLibAttr(ptla);
  6092.         }
  6093.     }
  6094.     return hr;
  6095. }
  6096.  
  6097. ATLINLINE ATLAPI AtlModuleRegisterTypeLib(_ATL_MODULE* pM, LPCOLESTR lpszIndex)
  6098. {
  6099.     CComBSTR bstrPath;
  6100.     CComPtr<ITypeLib> pTypeLib;
  6101.     HRESULT hr = AtlModuleLoadTypeLib(pM, lpszIndex, &bstrPath, &pTypeLib);
  6102.     if (SUCCEEDED(hr))
  6103.     {
  6104.         OLECHAR szDir[_MAX_PATH];
  6105.         ocscpy(szDir, bstrPath);
  6106.         szDir[AtlGetDirLen(szDir)] = 0;
  6107.         hr = ::RegisterTypeLib(pTypeLib, bstrPath, szDir);
  6108.     }
  6109.     return hr;
  6110. }
  6111.  
  6112. ATLINLINE ATLAPI_(DWORD) AtlGetVersion(void* /* pReserved */)
  6113. {
  6114.     return _ATL_VER;
  6115. }
  6116.  
  6117. ATLINLINE ATLAPI_(void) AtlModuleAddCreateWndData(_ATL_MODULE* pM, _AtlCreateWndData* pData, void* pObject)
  6118. {
  6119.     pData->m_pThis = pObject;
  6120.     pData->m_dwThreadID = ::GetCurrentThreadId();
  6121.     ::EnterCriticalSection(&pM->m_csWindowCreate);
  6122.     pData->m_pNext = pM->m_pCreateWndList;
  6123.     pM->m_pCreateWndList = pData;
  6124.     ::LeaveCriticalSection(&pM->m_csWindowCreate);
  6125. }
  6126.  
  6127. ATLINLINE ATLAPI_(void*) AtlModuleExtractCreateWndData(_ATL_MODULE* pM)
  6128. {
  6129.     void* pv = NULL;
  6130.     ::EnterCriticalSection(&pM->m_csWindowCreate);
  6131.     _AtlCreateWndData* pEntry = pM->m_pCreateWndList;
  6132.     if(pEntry != NULL)
  6133.     {
  6134.         DWORD dwThreadID = ::GetCurrentThreadId();
  6135.         _AtlCreateWndData* pPrev = NULL;
  6136.         while(pEntry != NULL)
  6137.         {
  6138.             if(pEntry->m_dwThreadID == dwThreadID)
  6139.             {
  6140.                 if(pPrev == NULL)
  6141.                     pM->m_pCreateWndList = pEntry->m_pNext;
  6142.                 else
  6143.                     pPrev->m_pNext = pEntry->m_pNext;
  6144.                 pv = pEntry->m_pThis;
  6145.                 break;
  6146.             }
  6147.             pPrev = pEntry;
  6148.             pEntry = pEntry->m_pNext;
  6149.         }
  6150.     }
  6151.     ::LeaveCriticalSection(&pM->m_csWindowCreate);
  6152.     return pv;
  6153. }
  6154.  
  6155. /////////////////////////////////////////////////////////////////////////////
  6156. // General DLL Version Helpers
  6157.  
  6158. inline HRESULT AtlGetDllVersion(HINSTANCE hInstDLL, DLLVERSIONINFO* pDllVersionInfo)
  6159. {
  6160.     ATLASSERT(pDllVersionInfo != NULL);
  6161.     if(::IsBadWritePtr(pDllVersionInfo, sizeof(DWORD)))
  6162.         return E_INVALIDARG;
  6163.  
  6164.     // We must get this function explicitly because some DLLs don't implement it.
  6165.     DLLGETVERSIONPROC pfnDllGetVersion = (DLLGETVERSIONPROC)::GetProcAddress(hInstDLL, "DllGetVersion");
  6166.     if(pfnDllGetVersion == NULL)
  6167.         return E_NOTIMPL;
  6168.  
  6169.     return (*pfnDllGetVersion)(pDllVersionInfo);
  6170. }
  6171.  
  6172. inline HRESULT AtlGetDllVersion(LPCTSTR lpstrDllName, DLLVERSIONINFO* pDllVersionInfo)
  6173. {
  6174.     HINSTANCE hInstDLL = ::LoadLibrary(lpstrDllName);
  6175.     if(hInstDLL == NULL)
  6176.         return E_FAIL;
  6177.     HRESULT hRet = AtlGetDllVersion(hInstDLL, pDllVersionInfo);
  6178.     ::FreeLibrary(hInstDLL);
  6179.     return hRet;
  6180. }
  6181.  
  6182. // Common Control Versions:
  6183. //   Win95/WinNT 4.0    maj=4 min=00
  6184. //   IE 3.x     maj=4 min=70
  6185. //   IE 4.0     maj=4 min=71
  6186. inline HRESULT AtlGetCommCtrlVersion(LPDWORD pdwMajor, LPDWORD pdwMinor)
  6187. {
  6188.     ATLASSERT(pdwMajor != NULL && pdwMinor != NULL);
  6189.     if(::IsBadWritePtr(pdwMajor, sizeof(DWORD)) || ::IsBadWritePtr(pdwMinor, sizeof(DWORD)))
  6190.         return E_INVALIDARG;
  6191.  
  6192.     DLLVERSIONINFO dvi;
  6193.     ::ZeroMemory(&dvi, sizeof(dvi));
  6194.     dvi.cbSize = sizeof(dvi);
  6195.     HRESULT hRet = AtlGetDllVersion(_T("comctl32.dll"), &dvi);
  6196.  
  6197.     if(SUCCEEDED(hRet))
  6198.     {
  6199.         *pdwMajor = dvi.dwMajorVersion;
  6200.         *pdwMinor = dvi.dwMinorVersion;
  6201.     }
  6202.     else if(hRet == E_NOTIMPL)
  6203.     {
  6204.         // If DllGetVersion is not there, then the DLL is a version
  6205.         // previous to the one shipped with IE 3.x
  6206.         *pdwMajor = 4;
  6207.         *pdwMinor = 0;
  6208.         hRet = S_OK;
  6209.     }
  6210.  
  6211.     return hRet;
  6212. }
  6213.  
  6214. // Shell Versions:
  6215. //   Win95/WinNT 4.0                    maj=4 min=00
  6216. //   IE 3.x, IE 4.0 without Web Integrated Desktop  maj=4 min=00
  6217. //   IE 4.0 with Web Integrated Desktop         maj=4 min=71
  6218. //   IE 4.01 with Web Integrated Desktop        maj=4 min=72
  6219. inline HRESULT AtlGetShellVersion(LPDWORD pdwMajor, LPDWORD pdwMinor)
  6220. {
  6221.     ATLASSERT(pdwMajor != NULL && pdwMinor != NULL);
  6222.     if(::IsBadWritePtr(pdwMajor, sizeof(DWORD)) || ::IsBadWritePtr(pdwMinor, sizeof(DWORD)))
  6223.         return E_INVALIDARG;
  6224.  
  6225.     DLLVERSIONINFO dvi;
  6226.     ::ZeroMemory(&dvi, sizeof(dvi));
  6227.     dvi.cbSize = sizeof(dvi);
  6228.     HRESULT hRet = AtlGetDllVersion(_T("shell32.dll"), &dvi);
  6229.  
  6230.     if(SUCCEEDED(hRet))
  6231.     {
  6232.         *pdwMajor = dvi.dwMajorVersion;
  6233.         *pdwMinor = dvi.dwMinorVersion;
  6234.     }
  6235.     else if(hRet == E_NOTIMPL)
  6236.     {
  6237.         // If DllGetVersion is not there, then the DLL is a version
  6238.         // previous to the one shipped with IE 4.x
  6239.         *pdwMajor = 4;
  6240.         *pdwMinor = 0;
  6241.         hRet = S_OK;
  6242.     }
  6243.  
  6244.     return hRet;
  6245. }
  6246.  
  6247. #ifndef _ATL_DLL_IMPL
  6248. }; //namespace ATL
  6249. #endif
  6250.  
  6251. //Prevent pulling in second time
  6252. #undef _ATLBASE_IMPL
  6253.  
  6254. #endif // _ATLBASE_IMPL
  6255.  
  6256. /////////////////////////////////////////////////////////////////////////////
  6257.