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