ATLBASE.H

来源:互联网 发布:isp 网络拓扑 编辑:程序博客网 时间:2024/05/21 05:37
// This is a part of the Active Template Library.// Copyright (C) 1996-1998 Microsoft Corporation// All rights reserved.//// This source code is only intended as a supplement to the// Active Template Library Reference and related// electronic documentation provided with the library.// See these sources for detailed information regarding the// Active Template Library product.#ifndef __ATLBASE_H__#define __ATLBASE_H__#ifndef __cplusplus#error ATL requires C++ compilation (use a .cpp suffix)#endif#ifndef _ATL_NO_PRAGMA_WARNINGS#pragma warning(disable: 4201) // nameless unions are part of C++#pragma warning(disable: 4127) // constant expression#pragma warning(disable: 4505) // unreferenced local function has been removed#pragma warning(disable: 4512) // can't generate assignment operator (so what?)#pragma warning(disable: 4514) // unreferenced inlines are common#pragma warning(disable: 4103) // pragma pack#pragma warning(disable: 4702) // unreachable code#pragma warning(disable: 4237) // bool#pragma warning(disable: 4710) // function couldn't be inlined#pragma warning(disable: 4355) // 'this' : used in base member initializer list#pragma warning(disable: 4097) // typedef name used as synonym for class-name#pragma warning(disable: 4786) // identifier was truncated in the debug information#pragma warning(disable: 4268) // const static/global data initialized to zeros#pragma warning(disable: 4291) // allow placement new#endif //!_ATL_NO_PRAGMA_WARNINGS#include <atldef.h>#include <windows.h>#include <winnls.h>#include <ole2.h>#include <comcat.h>#include <stddef.h>#ifdef new#pragma push_macro("new")#define _ATL_REDEF_NEW#undef new#endif#include <tchar.h>#include <malloc.h>#ifndef _ATL_NO_DEBUG_CRT// Warning: if you define the above symbol, you will have// to provide your own definition of the ATLASSERT(x) macro// in order to compile ATL#include <crtdbg.h>#endif#include <olectl.h>#include <winreg.h>#include <atliface.h>#ifdef _DEBUG#include <stdio.h>#include <stdarg.h>#endif#include <atlconv.h>#include <shlwapi.h>#pragma pack(push, _ATL_PACKING)#if defined(_ATL_DLL)#pragma comment(lib, "atl.lib")#endifextern "C" const __declspec(selectany) GUID LIBID_ATLLib = {0x44EC0535,0x400F,0x11D0,{0x9D,0xCD,0x00,0xA0,0xC9,0x03,0x91,0xD3}};extern "C" const __declspec(selectany) CLSID CLSID_Registrar = {0x44EC053A,0x400F,0x11D0,{0x9D,0xCD,0x00,0xA0,0xC9,0x03,0x91,0xD3}};extern "C" const __declspec(selectany) IID IID_IRegistrar = {0x44EC053B,0x400F,0x11D0,{0x9D,0xCD,0x00,0xA0,0xC9,0x03,0x91,0xD3}};extern "C" const __declspec(selectany) IID IID_IAxWinHostWindow = {0xb6ea2050,0x48a,0x11d1,{0x82,0xb9,0x0,0xc0,0x4f,0xb9,0x94,0x2e}};extern "C" const __declspec(selectany) IID IID_IAxWinAmbientDispatch = {0xb6ea2051,0x48a,0x11d1,{0x82,0xb9,0x0,0xc0,0x4f,0xb9,0x94,0x2e}};extern "C" const __declspec(selectany) IID IID_IInternalConnection = {0x72AD0770,0x6A9F,0x11d1,{0xBC,0xEC,0x00,0x60,0x08,0x8F,0x44,0x4E}};extern "C" const __declspec(selectany) IID IID_IDocHostUIHandlerDispatch = {0x425B5AF0,0x65F1,0x11d1,{0x96,0x11,0x00,0x00,0xF8,0x1E,0x0D,0x0D}};#ifndef _ATL_DLL_IMPLnamespace ATL{#endifstruct _ATL_CATMAP_ENTRY{   int iType;   const CATID* pcatid;};#define _ATL_CATMAP_ENTRY_END 0#define _ATL_CATMAP_ENTRY_IMPLEMENTED 1#define _ATL_CATMAP_ENTRY_REQUIRED 2typedef HRESULT (WINAPI _ATL_CREATORFUNC)(void* pv, REFIID riid, LPVOID* ppv);typedef HRESULT (WINAPI _ATL_CREATORARGFUNC)(void* pv, REFIID riid, LPVOID* ppv, DWORD dw);typedef HRESULT (WINAPI _ATL_MODULEFUNC)(DWORD dw);typedef LPCTSTR (WINAPI _ATL_DESCRIPTIONFUNC)();typedef const struct _ATL_CATMAP_ENTRY* (_ATL_CATMAPFUNC)();typedef void (__stdcall _ATL_TERMFUNC)(DWORD dw);struct _ATL_TERMFUNC_ELEM{_ATL_TERMFUNC* pFunc;DWORD dw;_ATL_TERMFUNC_ELEM* pNext;};struct _ATL_OBJMAP_ENTRY{const CLSID* pclsid;HRESULT (WINAPI *pfnUpdateRegistry)(BOOL bRegister);_ATL_CREATORFUNC* pfnGetClassObject;_ATL_CREATORFUNC* pfnCreateInstance;IUnknown* pCF;DWORD dwRegister;_ATL_DESCRIPTIONFUNC* pfnGetObjectDescription;_ATL_CATMAPFUNC* pfnGetCategoryMap;HRESULT WINAPI RevokeClassObject(){return CoRevokeClassObject(dwRegister);}HRESULT WINAPI RegisterClassObject(DWORD dwClsContext, DWORD dwFlags){IUnknown* p = NULL;if (pfnGetClassObject == NULL)return S_OK;HRESULT hRes = pfnGetClassObject(pfnCreateInstance, IID_IUnknown, (LPVOID*) &p);if (SUCCEEDED(hRes))hRes = CoRegisterClassObject(*pclsid, p, dwClsContext, dwFlags, &dwRegister);if (p != NULL)p->Release();return hRes;}// Added in ATL 3.0void (WINAPI *pfnObjectMain)(bool bStarting);};struct _ATL_REGMAP_ENTRY{LPCOLESTR     szKey;LPCOLESTR     szData;};struct _AtlCreateWndData{void* m_pThis;DWORD m_dwThreadID;_AtlCreateWndData* m_pNext;};struct _ATL_MODULE{// Attributespublic:UINT cbSize;HINSTANCE m_hInst;HINSTANCE m_hInstResource;HINSTANCE m_hInstTypeLib;_ATL_OBJMAP_ENTRY* m_pObjMap;LONG m_nLockCnt;HANDLE m_hHeap;union{CRITICAL_SECTION m_csTypeInfoHolder;CRITICAL_SECTION m_csStaticDataInit;};CRITICAL_SECTION m_csWindowCreate;CRITICAL_SECTION m_csObjMap;// Original Size = 100// Stuff added in ATL 3.0DWORD dwAtlBuildVer;_AtlCreateWndData* m_pCreateWndList;bool m_bDestroyHeap;GUID* pguidVer;DWORD m_dwHeaps;    // Number of heaps we have (-1)HANDLE* m_phHeaps;int m_nHeap;        // Which heap to choose from_ATL_TERMFUNC_ELEM* m_pTermFuncs;};const int _nAtlModuleVer1Size = 100;//This define makes debugging asserts easier.#define _ATL_SIMPLEMAPENTRY ((_ATL_CREATORARGFUNC*)1)struct _ATL_INTMAP_ENTRY{const IID* piid;       // the interface id (IID)DWORD dw;_ATL_CREATORARGFUNC* pFunc; //NULL:end, 1:offset, n:ptr};/////////////////////////////////////////////////////////////////////////////// QI SupportATLAPI AtlInternalQueryInterface(void* pThis,const _ATL_INTMAP_ENTRY* pEntries, REFIID iid, void** ppvObject);/////////////////////////////////////////////////////////////////////////////// Smart Pointer helpersATLAPI_(IUnknown*) AtlComPtrAssign(IUnknown** pp, IUnknown* lp);ATLAPI_(IUnknown*) AtlComQIPtrAssign(IUnknown** pp, IUnknown* lp, REFIID riid);/////////////////////////////////////////////////////////////////////////////// Inproc Marshaling helpersATLAPI AtlFreeMarshalStream(IStream* pStream);ATLAPI AtlMarshalPtrInProc(IUnknown* pUnk, const IID& iid, IStream** ppStream);ATLAPI AtlUnmarshalPtr(IStream* pStream, const IID& iid, IUnknown** ppUnk);ATLAPI_(BOOL) AtlWaitWithMessageLoop(HANDLE hEvent);/////////////////////////////////////////////////////////////////////////////// Connection Point HelpersATLAPI AtlAdvise(IUnknown* pUnkCP, IUnknown* pUnk, const IID& iid, LPDWORD pdw);ATLAPI AtlUnadvise(IUnknown* pUnkCP, const IID& iid, DWORD dw);/////////////////////////////////////////////////////////////////////////////// IDispatch Error handlingATLAPI AtlSetErrorInfo(const CLSID& clsid, LPCOLESTR lpszDesc,DWORD dwHelpID, LPCOLESTR lpszHelpFile, const IID& iid, HRESULT hRes,HINSTANCE hInst);/////////////////////////////////////////////////////////////////////////////// ModuleATLAPI AtlModuleRegisterClassObjects(_ATL_MODULE* pM, DWORD dwClsContext, DWORD dwFlags);ATLAPI AtlModuleRevokeClassObjects(_ATL_MODULE* pM);ATLAPI AtlModuleGetClassObject(_ATL_MODULE* pM, REFCLSID rclsid, REFIID riid, LPVOID* ppv);ATLAPI AtlModuleRegisterServer(_ATL_MODULE* pM, BOOL bRegTypeLib, const CLSID* pCLSID = NULL);ATLAPI AtlModuleUnregisterServer(_ATL_MODULE* pM, const CLSID* pCLSID = NULL);ATLAPI AtlModuleUnregisterServerEx(_ATL_MODULE* pM, BOOL bUnRegTypeLib, const CLSID* pCLSID = NULL);ATLAPI AtlModuleUpdateRegistryFromResourceD(_ATL_MODULE*pM, LPCOLESTR lpszRes,BOOL bRegister, struct _ATL_REGMAP_ENTRY* pMapEntries, IRegistrar* pReg = NULL);ATLAPI AtlModuleRegisterTypeLib(_ATL_MODULE* pM, LPCOLESTR lpszIndex);ATLAPI AtlModuleUnRegisterTypeLib(_ATL_MODULE* pM, LPCOLESTR lpszIndex);ATLAPI AtlModuleLoadTypeLib(_ATL_MODULE* pM, LPCOLESTR lpszIndex, BSTR* pbstrPath, ITypeLib** ppTypeLib);ATLAPI AtlModuleInit(_ATL_MODULE* pM, _ATL_OBJMAP_ENTRY* p, HINSTANCE h);ATLAPI AtlModuleTerm(_ATL_MODULE* pM);ATLAPI_(DWORD) AtlGetVersion(void* pReserved);ATLAPI_(void) AtlModuleAddCreateWndData(_ATL_MODULE* pM, _AtlCreateWndData* pData, void* pObject);ATLAPI_(void*) AtlModuleExtractCreateWndData(_ATL_MODULE* pM);ATLAPI AtlModuleAddTermFunc(_ATL_MODULE* pM, _ATL_TERMFUNC* pFunc, DWORD dw);#ifndef _ATL_DLL_IMPL}; //namespace ATL#endifnamespace ATL{enum atlTraceFlags{// Application defined categoriesatlTraceUser        = 0x00000001,atlTraceUser2       = 0x00000002,atlTraceUser3       = 0x00000004,atlTraceUser4       = 0x00000008,// ATL defined categoriesatlTraceGeneral     = 0x00000020,atlTraceCOM         = 0x00000040,atlTraceQI      = 0x00000080,atlTraceRegistrar   = 0x00000100,atlTraceRefcount    = 0x00000200,atlTraceWindowing   = 0x00000400,atlTraceControls    = 0x00000800,atlTraceHosting     = 0x00001000,atlTraceDBClient    = 0x00002000,atlTraceDBProvider  = 0x00004000,atlTraceSnapin      = 0x00008000,atlTraceNotImpl     = 0x00010000,};#ifndef ATL_TRACE_CATEGORY#define ATL_TRACE_CATEGORY 0xFFFFFFFF#endif#ifdef _DEBUG#ifndef ATL_TRACE_LEVEL#define ATL_TRACE_LEVEL 0#endifinline void _cdecl AtlTrace(LPCSTR lpszFormat, ...){va_list args;va_start(args, lpszFormat);int nBuf;char szBuffer[512];nBuf = _vsnprintf(szBuffer, sizeof(szBuffer), lpszFormat, args);ATLASSERT(nBuf < sizeof(szBuffer)); //Output truncated as it was > sizeof(szBuffer)OutputDebugStringA(szBuffer);va_end(args);}inline void _cdecl AtlTrace2(DWORD category, UINT level, LPCSTR lpszFormat, ...){if (category & ATL_TRACE_CATEGORY && level <= ATL_TRACE_LEVEL){va_list args;va_start(args, lpszFormat);int nBuf;char szBuffer[512];nBuf = _vsnprintf(szBuffer, sizeof(szBuffer), lpszFormat, args);ATLASSERT(nBuf < sizeof(szBuffer)); //Output truncated as it was > sizeof(szBuffer)OutputDebugStringA("ATL: ");OutputDebugStringA(szBuffer);va_end(args);}}#ifndef OLE2ANSIinline void _cdecl AtlTrace(LPCWSTR lpszFormat, ...){va_list args;va_start(args, lpszFormat);int nBuf;WCHAR szBuffer[512];nBuf = _vsnwprintf(szBuffer, sizeof(szBuffer) / sizeof(WCHAR), lpszFormat, args);ATLASSERT(nBuf < sizeof(szBuffer));//Output truncated as it was > sizeof(szBuffer)OutputDebugStringW(szBuffer);va_end(args);}inline void _cdecl AtlTrace2(DWORD category, UINT level, LPCWSTR lpszFormat, ...){if (category & ATL_TRACE_CATEGORY && level <= ATL_TRACE_LEVEL){va_list args;va_start(args, lpszFormat);int nBuf;WCHAR szBuffer[512];nBuf = _vsnwprintf(szBuffer, sizeof(szBuffer) / sizeof(WCHAR), lpszFormat, args);ATLASSERT(nBuf < sizeof(szBuffer));//Output truncated as it was > sizeof(szBuffer)OutputDebugStringW(L"ATL: ");OutputDebugStringW(szBuffer);va_end(args);}}#endif //!OLE2ANSI#ifndef ATLTRACE#define ATLTRACE            AtlTrace#define ATLTRACE2           AtlTrace2#endif#define ATLTRACENOTIMPL(funcname)   ATLTRACE2(atlTraceNotImpl, 2, _T("ATL: %s not implemented.\n"), funcname); return E_NOTIMPL#else // !DEBUGinline void _cdecl AtlTrace(LPCSTR , ...){}inline void _cdecl AtlTrace2(DWORD, UINT, LPCSTR , ...){}#ifndef OLE2ANSIinline void _cdecl AtlTrace(LPCWSTR , ...){}inline void _cdecl AtlTrace2(DWORD, UINT, LPCWSTR , ...){}#endif //OLE2ANSI#ifndef ATLTRACE#define ATLTRACE            1 ? (void)0 : AtlTrace#define ATLTRACE2           1 ? (void)0 : AtlTrace2#endif //ATLTRACE#define ATLTRACENOTIMPL(funcname)   return E_NOTIMPL#endif //_DEBUG/////////////////////////////////////////////////////////////////////////////// Win32 libraries#pragma comment(lib, "kernel32.lib")#pragma comment(lib, "user32.lib")#pragma comment(lib, "olepro32.lib")#pragma comment(lib, "advapi32.lib")#pragma comment(lib, "ole32.lib")#pragma comment(lib, "oleaut32.lib")#pragma comment(lib, "uuid.lib")static HRESULT AtlSetChildSite(IUnknown* punkChild, IUnknown* punkParent){if (punkChild == NULL)return E_POINTER;HRESULT hr;IObjectWithSite* pChildSite = NULL;hr = punkChild->QueryInterface(IID_IObjectWithSite, (void**)&pChildSite);if (SUCCEEDED(hr) && pChildSite != NULL){hr = pChildSite->SetSite(punkParent);pChildSite->Release();}return hr;}template <class T>class _NoAddRefReleaseOnCComPtr : public T{private:STDMETHOD_(ULONG, AddRef)()=0;STDMETHOD_(ULONG, Release)()=0;};template <class T>class CComPtr{public:typedef T _PtrClass;CComPtr(){p=NULL;}CComPtr(T* lp){if ((p = lp) != NULL)p->AddRef();}CComPtr(const CComPtr<T>& lp){if ((p = lp.p) != NULL)p->AddRef();}~CComPtr(){if (p)p->Release();}void Release(){IUnknown* pTemp = p;if (pTemp){p = NULL;pTemp->Release();}}operator T*() const{return (T*)p;}T& operator*() const{ATLASSERT(p!=NULL);return *p;}//The assert on operator& usually indicates a bug.  If this is really//what is needed, however, take the address of the p member explicitly.T** operator&(){ATLASSERT(p==NULL);return &p;}_NoAddRefReleaseOnCComPtr<T>* operator->() const{ATLASSERT(p!=NULL);return (_NoAddRefReleaseOnCComPtr<T>*)p;}T* operator=(T* lp){return (T*)AtlComPtrAssign((IUnknown**)&p, lp);}T* operator=(const CComPtr<T>& lp){return (T*)AtlComPtrAssign((IUnknown**)&p, lp.p);}bool operator!() const{return (p == NULL);}bool operator<(T* pT) const{return p < pT;}bool operator==(T* pT) const{return p == pT;}// Compare two objects for equivalencebool IsEqualObject(IUnknown* pOther){if (p == NULL && pOther == NULL)return true; // They are both NULL objectsif (p == NULL || pOther == NULL)return false; // One is NULL the other is notCComPtr<IUnknown> punk1;CComPtr<IUnknown> punk2;p->QueryInterface(IID_IUnknown, (void**)&punk1);pOther->QueryInterface(IID_IUnknown, (void**)&punk2);return punk1 == punk2;}void Attach(T* p2){if (p)p->Release();p = p2;}T* Detach(){T* pt = p;p = NULL;return pt;}HRESULT CopyTo(T** ppT){ATLASSERT(ppT != NULL);if (ppT == NULL)return E_POINTER;*ppT = p;if (p)p->AddRef();return S_OK;}HRESULT SetSite(IUnknown* punkParent){return AtlSetChildSite(p, punkParent);}HRESULT Advise(IUnknown* pUnk, const IID& iid, LPDWORD pdw){return AtlAdvise(p, pUnk, iid, pdw);}HRESULT CoCreateInstance(REFCLSID rclsid, LPUNKNOWN pUnkOuter = NULL, DWORD dwClsContext = CLSCTX_ALL){ATLASSERT(p == NULL);return ::CoCreateInstance(rclsid, pUnkOuter, dwClsContext, __uuidof(T), (void**)&p);}HRESULT CoCreateInstance(LPCOLESTR szProgID, LPUNKNOWN pUnkOuter = NULL, DWORD dwClsContext = CLSCTX_ALL){CLSID clsid;HRESULT hr = CLSIDFromProgID(szProgID, &clsid);ATLASSERT(p == NULL);if (SUCCEEDED(hr))hr = ::CoCreateInstance(clsid, pUnkOuter, dwClsContext, __uuidof(T), (void**)&p);return hr;}template <class Q>HRESULT QueryInterface(Q** pp) const{ATLASSERT(pp != NULL && *pp == NULL);return p->QueryInterface(__uuidof(Q), (void**)pp);}T* p;};template <class T, const IID* piid = &__uuidof(T)>class CComQIPtr{public:typedef T _PtrClass;CComQIPtr(){p=NULL;}CComQIPtr(T* lp){if ((p = lp) != NULL)p->AddRef();}CComQIPtr(const CComQIPtr<T,piid>& lp){if ((p = lp.p) != NULL)p->AddRef();}CComQIPtr(IUnknown* lp){p=NULL;if (lp != NULL)lp->QueryInterface(*piid, (void **)&p);}~CComQIPtr(){if (p)p->Release();}void Release(){IUnknown* pTemp = p;if (pTemp){p = NULL;pTemp->Release();}}operator T*() const{return p;}T& operator*() const{ATLASSERT(p!=NULL); return *p;}//The assert on operator& usually indicates a bug.  If this is really//what is needed, however, take the address of the p member explicitly.T** operator&(){ATLASSERT(p==NULL);return &p;}_NoAddRefReleaseOnCComPtr<T>* operator->() const{ATLASSERT(p!=NULL);return (_NoAddRefReleaseOnCComPtr<T>*)p;}T* operator=(T* lp){return (T*)AtlComPtrAssign((IUnknown**)&p, lp);}T* operator=(const CComQIPtr<T,piid>& lp){return (T*)AtlComPtrAssign((IUnknown**)&p, lp.p);}T* operator=(IUnknown* lp){return (T*)AtlComQIPtrAssign((IUnknown**)&p, lp, *piid);}bool operator!() const{return (p == NULL);}bool operator<(T* pT) const{return p < pT;}bool operator==(T* pT) const{return p == pT;}// Compare two objects for equivalencebool IsEqualObject(IUnknown* pOther){if (p == NULL && pOther == NULL)return true; // They are both NULL objectsif (p == NULL || pOther == NULL)return false; // One is NULL the other is notCComPtr<IUnknown> punk1;CComPtr<IUnknown> punk2;p->QueryInterface(IID_IUnknown, (void**)&punk1);pOther->QueryInterface(IID_IUnknown, (void**)&punk2);return punk1 == punk2;}void Attach(T* p2){if (p)p->Release();p = p2;}T* Detach(){T* pt = p;p = NULL;return pt;}HRESULT CopyTo(T** ppT){ATLASSERT(ppT != NULL);if (ppT == NULL)return E_POINTER;*ppT = p;if (p)p->AddRef();return S_OK;}HRESULT SetSite(IUnknown* punkParent){return AtlSetChildSite(p, punkParent);}HRESULT Advise(IUnknown* pUnk, const IID& iid, LPDWORD pdw){return AtlAdvise(p, pUnk, iid, pdw);}HRESULT CoCreateInstance(REFCLSID rclsid, LPUNKNOWN pUnkOuter = NULL, DWORD dwClsContext = CLSCTX_ALL){ATLASSERT(p == NULL);return ::CoCreateInstance(rclsid, pUnkOuter, dwClsContext, __uuidof(T), (void**)&p);}HRESULT CoCreateInstance(LPCOLESTR szProgID, LPUNKNOWN pUnkOuter = NULL, DWORD dwClsContext = CLSCTX_ALL){CLSID clsid;HRESULT hr = CLSIDFromProgID(szProgID, &clsid);ATLASSERT(p == NULL);if (SUCCEEDED(hr))hr = ::CoCreateInstance(clsid, pUnkOuter, dwClsContext, __uuidof(T), (void**)&p);return hr;}template <class Q>HRESULT QueryInterface(Q** pp){ATLASSERT(pp != NULL && *pp == NULL);return p->QueryInterface(__uuidof(Q), (void**)pp);}T* p;};//Specialization to make it worktemplate<>class CComQIPtr<IUnknown, &IID_IUnknown>{public:typedef IUnknown _PtrClass;CComQIPtr(){p=NULL;}CComQIPtr(IUnknown* lp){//Actually do a QI to get identityp=NULL;if (lp != NULL)lp->QueryInterface(IID_IUnknown, (void **)&p);}CComQIPtr(const CComQIPtr<IUnknown,&IID_IUnknown>& lp){if ((p = lp.p) != NULL)p->AddRef();}~CComQIPtr(){if (p)p->Release();}void Release(){IUnknown* pTemp = p;if (pTemp){p = NULL;pTemp->Release();}}operator IUnknown*() const{return p;}IUnknown& operator*() const{ATLASSERT(p!=NULL);return *p;}//The assert on operator& usually indicates a bug.  If this is really//what is needed, however, take the address of the p member explicitly.IUnknown** operator&(){ATLASSERT(p==NULL);return &p;}_NoAddRefReleaseOnCComPtr<T>* operator->() const{ATLASSERT(p!=NULL);return (_NoAddRefReleaseOnCComPtr<T>*)p;}IUnknown* operator=(IUnknown* lp){//Actually do a QI to get identityreturn (IUnknown*)AtlComQIPtrAssign((IUnknown**)&p, lp, IID_IUnknown);}IUnknown* operator=(const CComQIPtr<IUnknown,&IID_IUnknown>& lp){return (IUnknown*)AtlComPtrAssign((IUnknown**)&p, lp.p);}bool operator!() const{return (p == NULL);}bool operator<(IUnknown* pT) const{return p < pT;}bool operator==(IUnknown* pT) const{return p == pT;}// Compare two objects for equivalencebool IsEqualObject(IUnknown* pOther){if (p == NULL && pOther == NULL)return true; // They are both NULL objectsif (p == NULL || pOther == NULL)return false; // One is NULL the other is notCComPtr<IUnknown> punk1;CComPtr<IUnknown> punk2;p->QueryInterface(IID_IUnknown, (void**)&punk1);pOther->QueryInterface(IID_IUnknown, (void**)&punk2);return punk1 == punk2;}IUnknown* Detach(){IUnknown* pt = p;p = NULL;return pt;}HRESULT CopyTo(T** ppT){ATLASSERT(ppT != NULL);if (ppT == NULL)return E_POINTER;*ppT = p;if (p)p->AddRef();return S_OK;}HRESULT SetSite(IUnknown* punkParent){return AtlSetChildSite(p, punkParent);}HRESULT Advise(IUnknown* pUnk, const IID& iid, LPDWORD pdw){return AtlAdvise(p, pUnk, iid, pdw);}HRESULT CoCreateInstance(REFCLSID rclsid, LPUNKNOWN pUnkOuter = NULL, DWORD dwClsContext = CLSCTX_ALL){ATLASSERT(p == NULL);return ::CoCreateInstance(rclsid, pUnkOuter, dwClsContext, __uuidof(T), (void**)&p);}HRESULT CoCreateInstance(LPCOLESTR szProgID, LPUNKNOWN pUnkOuter = NULL, DWORD dwClsContext = CLSCTX_ALL){CLSID clsid;HRESULT hr = CLSIDFromProgID(szProgID, &clsid);ATLASSERT(p == NULL);if (SUCCEEDED(hr))hr = ::CoCreateInstance(clsid, pUnkOuter, dwClsContext, __uuidof(T), (void**)&p);return hr;}template <class Q>HRESULT QueryInterface(Q** pp){ATLASSERT(pp != NULL && *pp == NULL);return p->QueryInterface(__uuidof(Q), (void**)pp);}IUnknown* p;};#define com_cast CComQIPtr/////////////////////////////////////////////////////////////// Class to Adapt CComBSTR and CComPtr for use with STL containers// the syntax to use it is// std::vector< CAdapt <CComBSTR> > vect;template <class T>class CAdapt{public:CAdapt(){}CAdapt(const T& rSrc){m_T = rSrc;}CAdapt(const CAdapt& rSrCA){m_T = rSrCA.m_T;}CAdapt& operator=(const T& rSrc){m_T = rSrc;return *this;}bool operator<(const T& rSrc) const{return m_T < rSrc;}bool operator==(const T& rSrc) const{return m_T == rSrc;}operator T&(){return m_T;}operator const T&() const{return m_T;}T m_T;};/////////////////////////////////////////////////////////////////////////////// GUID comparisoninline BOOL InlineIsEqualGUID(REFGUID rguid1, REFGUID rguid2){   return (  ((PLONG) &rguid1)[0] == ((PLONG) &rguid2)[0] &&  ((PLONG) &rguid1)[1] == ((PLONG) &rguid2)[1] &&  ((PLONG) &rguid1)[2] == ((PLONG) &rguid2)[2] &&  ((PLONG) &rguid1)[3] == ((PLONG) &rguid2)[3]);}inline BOOL InlineIsEqualUnknown(REFGUID rguid1){   return (  ((PLONG) &rguid1)[0] == 0 &&  ((PLONG) &rguid1)[1] == 0 &&#ifdef _ATL_BYTESWAP  ((PLONG) &rguid1)[2] == 0xC0000000 &&  ((PLONG) &rguid1)[3] == 0x00000046);#else  ((PLONG) &rguid1)[2] == 0x000000C0 &&  ((PLONG) &rguid1)[3] == 0x46000000);#endif}/////////////////////////////////////////////////////////////////////////////// Threading Model Supportclass CComCriticalSection{public:void Lock() {EnterCriticalSection(&m_sec);}void Unlock() {LeaveCriticalSection(&m_sec);}void Init() {InitializeCriticalSection(&m_sec);}void Term() {DeleteCriticalSection(&m_sec);}CRITICAL_SECTION m_sec;};class CComAutoCriticalSection{public:void Lock() {EnterCriticalSection(&m_sec);}void Unlock() {LeaveCriticalSection(&m_sec);}CComAutoCriticalSection() {InitializeCriticalSection(&m_sec);}~CComAutoCriticalSection() {DeleteCriticalSection(&m_sec);}CRITICAL_SECTION m_sec;};class CComFakeCriticalSection{public:void Lock() {}void Unlock() {}void Init() {}void Term() {}};class CComMultiThreadModelNoCS{public:static ULONG WINAPI Increment(LPLONG p) {return InterlockedIncrement(p);}static ULONG WINAPI Decrement(LPLONG p) {return InterlockedDecrement(p);}typedef CComFakeCriticalSection AutoCriticalSection;typedef CComFakeCriticalSection CriticalSection;typedef CComMultiThreadModelNoCS ThreadModelNoCS;};class CComMultiThreadModel{public:static ULONG WINAPI Increment(LPLONG p) {return InterlockedIncrement(p);}static ULONG WINAPI Decrement(LPLONG p) {return InterlockedDecrement(p);}typedef CComAutoCriticalSection AutoCriticalSection;typedef CComCriticalSection CriticalSection;typedef CComMultiThreadModelNoCS ThreadModelNoCS;};class CComSingleThreadModel{public:static ULONG WINAPI Increment(LPLONG p) {return ++(*p);}static ULONG WINAPI Decrement(LPLONG p) {return --(*p);}typedef CComFakeCriticalSection AutoCriticalSection;typedef CComFakeCriticalSection CriticalSection;typedef CComSingleThreadModel ThreadModelNoCS;};#if defined(_ATL_SINGLE_THREADED)typedef CComSingleThreadModel CComObjectThreadModel;typedef CComSingleThreadModel CComGlobalsThreadModel;#elif defined(_ATL_APARTMENT_THREADED)typedef CComSingleThreadModel CComObjectThreadModel;typedef CComMultiThreadModel CComGlobalsThreadModel;#elsetypedef CComMultiThreadModel CComObjectThreadModel;typedef CComMultiThreadModel CComGlobalsThreadModel;#endif/////////////////////////////////////////////////////////////////////////////// CComModule#define THREADFLAGS_APARTMENT 0x1#define THREADFLAGS_BOTH 0x2#define AUTPRXFLAG 0x4HRESULT WINAPI AtlDumpIID(REFIID iid, LPCTSTR pszClassName, HRESULT hr);#ifdef _ATL_DEBUG_INTERFACESstruct _QIThunk{STDMETHOD(QueryInterface)(REFIID iid, void** pp){ATLASSERT(m_dwRef >= 0);return pUnk->QueryInterface(iid, pp);}STDMETHOD_(ULONG, AddRef)(){if (bBreak)DebugBreak();pUnk->AddRef();return InternalAddRef();}ULONG InternalAddRef(){if (bBreak)DebugBreak();ATLASSERT(m_dwRef >= 0);long l = InterlockedIncrement(&m_dwRef);ATLTRACE(_T("%d> "), m_dwRef);AtlDumpIID(iid, lpszClassName, S_OK);if (l > m_dwMaxRef)m_dwMaxRef = l;return l;}STDMETHOD_(ULONG, Release)();STDMETHOD(f3)();STDMETHOD(f4)();STDMETHOD(f5)();STDMETHOD(f6)();STDMETHOD(f7)();STDMETHOD(f8)();STDMETHOD(f9)();STDMETHOD(f10)();STDMETHOD(f11)();STDMETHOD(f12)();STDMETHOD(f13)();STDMETHOD(f14)();STDMETHOD(f15)();STDMETHOD(f16)();STDMETHOD(f17)();STDMETHOD(f18)();STDMETHOD(f19)();STDMETHOD(f20)();STDMETHOD(f21)();STDMETHOD(f22)();STDMETHOD(f23)();STDMETHOD(f24)();STDMETHOD(f25)();STDMETHOD(f26)();STDMETHOD(f27)();STDMETHOD(f28)();STDMETHOD(f29)();STDMETHOD(f30)();STDMETHOD(f31)();STDMETHOD(f32)();STDMETHOD(f33)();STDMETHOD(f34)();STDMETHOD(f35)();STDMETHOD(f36)();STDMETHOD(f37)();STDMETHOD(f38)();STDMETHOD(f39)();STDMETHOD(f40)();STDMETHOD(f41)();STDMETHOD(f42)();STDMETHOD(f43)();STDMETHOD(f44)();STDMETHOD(f45)();STDMETHOD(f46)();STDMETHOD(f47)();STDMETHOD(f48)();STDMETHOD(f49)();STDMETHOD(f50)();STDMETHOD(f51)();STDMETHOD(f52)();STDMETHOD(f53)();STDMETHOD(f54)();STDMETHOD(f55)();STDMETHOD(f56)();STDMETHOD(f57)();STDMETHOD(f58)();STDMETHOD(f59)();STDMETHOD(f60)();STDMETHOD(f61)();STDMETHOD(f62)();STDMETHOD(f63)();STDMETHOD(f64)();STDMETHOD(f65)();STDMETHOD(f66)();STDMETHOD(f67)();STDMETHOD(f68)();STDMETHOD(f69)();STDMETHOD(f70)();STDMETHOD(f71)();STDMETHOD(f72)();STDMETHOD(f73)();STDMETHOD(f74)();STDMETHOD(f75)();STDMETHOD(f76)();STDMETHOD(f77)();STDMETHOD(f78)();STDMETHOD(f79)();STDMETHOD(f80)();STDMETHOD(f81)();STDMETHOD(f82)();STDMETHOD(f83)();STDMETHOD(f84)();STDMETHOD(f85)();STDMETHOD(f86)();STDMETHOD(f87)();STDMETHOD(f88)();STDMETHOD(f89)();STDMETHOD(f90)();STDMETHOD(f91)();STDMETHOD(f92)();STDMETHOD(f93)();STDMETHOD(f94)();STDMETHOD(f95)();STDMETHOD(f96)();STDMETHOD(f97)();STDMETHOD(f98)();STDMETHOD(f99)();STDMETHOD(f100)();STDMETHOD(f101)();STDMETHOD(f102)();STDMETHOD(f103)();STDMETHOD(f104)();STDMETHOD(f105)();STDMETHOD(f106)();STDMETHOD(f107)();STDMETHOD(f108)();STDMETHOD(f109)();STDMETHOD(f110)();STDMETHOD(f111)();STDMETHOD(f112)();STDMETHOD(f113)();STDMETHOD(f114)();STDMETHOD(f115)();STDMETHOD(f116)();STDMETHOD(f117)();STDMETHOD(f118)();STDMETHOD(f119)();STDMETHOD(f120)();STDMETHOD(f121)();STDMETHOD(f122)();STDMETHOD(f123)();STDMETHOD(f124)();STDMETHOD(f125)();STDMETHOD(f126)();STDMETHOD(f127)();STDMETHOD(f128)();STDMETHOD(f129)();STDMETHOD(f130)();STDMETHOD(f131)();STDMETHOD(f132)();STDMETHOD(f133)();STDMETHOD(f134)();STDMETHOD(f135)();STDMETHOD(f136)();STDMETHOD(f137)();STDMETHOD(f138)();STDMETHOD(f139)();STDMETHOD(f140)();STDMETHOD(f141)();STDMETHOD(f142)();STDMETHOD(f143)();STDMETHOD(f144)();STDMETHOD(f145)();STDMETHOD(f146)();STDMETHOD(f147)();STDMETHOD(f148)();STDMETHOD(f149)();STDMETHOD(f150)();STDMETHOD(f151)();STDMETHOD(f152)();STDMETHOD(f153)();STDMETHOD(f154)();STDMETHOD(f155)();STDMETHOD(f156)();STDMETHOD(f157)();STDMETHOD(f158)();STDMETHOD(f159)();STDMETHOD(f160)();STDMETHOD(f161)();STDMETHOD(f162)();STDMETHOD(f163)();STDMETHOD(f164)();STDMETHOD(f165)();STDMETHOD(f166)();STDMETHOD(f167)();STDMETHOD(f168)();STDMETHOD(f169)();STDMETHOD(f170)();STDMETHOD(f171)();STDMETHOD(f172)();STDMETHOD(f173)();STDMETHOD(f174)();STDMETHOD(f175)();STDMETHOD(f176)();STDMETHOD(f177)();STDMETHOD(f178)();STDMETHOD(f179)();STDMETHOD(f180)();STDMETHOD(f181)();STDMETHOD(f182)();STDMETHOD(f183)();STDMETHOD(f184)();STDMETHOD(f185)();STDMETHOD(f186)();STDMETHOD(f187)();STDMETHOD(f188)();STDMETHOD(f189)();STDMETHOD(f190)();STDMETHOD(f191)();STDMETHOD(f192)();STDMETHOD(f193)();STDMETHOD(f194)();STDMETHOD(f195)();STDMETHOD(f196)();STDMETHOD(f197)();STDMETHOD(f198)();STDMETHOD(f199)();STDMETHOD(f200)();STDMETHOD(f201)();STDMETHOD(f202)();STDMETHOD(f203)();STDMETHOD(f204)();STDMETHOD(f205)();STDMETHOD(f206)();STDMETHOD(f207)();STDMETHOD(f208)();STDMETHOD(f209)();STDMETHOD(f210)();STDMETHOD(f211)();STDMETHOD(f212)();STDMETHOD(f213)();STDMETHOD(f214)();STDMETHOD(f215)();STDMETHOD(f216)();STDMETHOD(f217)();STDMETHOD(f218)();STDMETHOD(f219)();STDMETHOD(f220)();STDMETHOD(f221)();STDMETHOD(f222)();STDMETHOD(f223)();STDMETHOD(f224)();STDMETHOD(f225)();STDMETHOD(f226)();STDMETHOD(f227)();STDMETHOD(f228)();STDMETHOD(f229)();STDMETHOD(f230)();STDMETHOD(f231)();STDMETHOD(f232)();STDMETHOD(f233)();STDMETHOD(f234)();STDMETHOD(f235)();STDMETHOD(f236)();STDMETHOD(f237)();STDMETHOD(f238)();STDMETHOD(f239)();STDMETHOD(f240)();STDMETHOD(f241)();STDMETHOD(f242)();STDMETHOD(f243)();STDMETHOD(f244)();STDMETHOD(f245)();STDMETHOD(f246)();STDMETHOD(f247)();STDMETHOD(f248)();STDMETHOD(f249)();STDMETHOD(f250)();STDMETHOD(f251)();STDMETHOD(f252)();STDMETHOD(f253)();STDMETHOD(f254)();STDMETHOD(f255)();STDMETHOD(f256)();STDMETHOD(f257)();STDMETHOD(f258)();STDMETHOD(f259)();STDMETHOD(f260)();STDMETHOD(f261)();STDMETHOD(f262)();STDMETHOD(f263)();STDMETHOD(f264)();STDMETHOD(f265)();STDMETHOD(f266)();STDMETHOD(f267)();STDMETHOD(f268)();STDMETHOD(f269)();STDMETHOD(f270)();STDMETHOD(f271)();STDMETHOD(f272)();STDMETHOD(f273)();STDMETHOD(f274)();STDMETHOD(f275)();STDMETHOD(f276)();STDMETHOD(f277)();STDMETHOD(f278)();STDMETHOD(f279)();STDMETHOD(f280)();STDMETHOD(f281)();STDMETHOD(f282)();STDMETHOD(f283)();STDMETHOD(f284)();STDMETHOD(f285)();STDMETHOD(f286)();STDMETHOD(f287)();STDMETHOD(f288)();STDMETHOD(f289)();STDMETHOD(f290)();STDMETHOD(f291)();STDMETHOD(f292)();STDMETHOD(f293)();STDMETHOD(f294)();STDMETHOD(f295)();STDMETHOD(f296)();STDMETHOD(f297)();STDMETHOD(f298)();STDMETHOD(f299)();STDMETHOD(f300)();STDMETHOD(f301)();STDMETHOD(f302)();STDMETHOD(f303)();STDMETHOD(f304)();STDMETHOD(f305)();STDMETHOD(f306)();STDMETHOD(f307)();STDMETHOD(f308)();STDMETHOD(f309)();STDMETHOD(f310)();STDMETHOD(f311)();STDMETHOD(f312)();STDMETHOD(f313)();STDMETHOD(f314)();STDMETHOD(f315)();STDMETHOD(f316)();STDMETHOD(f317)();STDMETHOD(f318)();STDMETHOD(f319)();STDMETHOD(f320)();STDMETHOD(f321)();STDMETHOD(f322)();STDMETHOD(f323)();STDMETHOD(f324)();STDMETHOD(f325)();STDMETHOD(f326)();STDMETHOD(f327)();STDMETHOD(f328)();STDMETHOD(f329)();STDMETHOD(f330)();STDMETHOD(f331)();STDMETHOD(f332)();STDMETHOD(f333)();STDMETHOD(f334)();STDMETHOD(f335)();STDMETHOD(f336)();STDMETHOD(f337)();STDMETHOD(f338)();STDMETHOD(f339)();STDMETHOD(f340)();STDMETHOD(f341)();STDMETHOD(f342)();STDMETHOD(f343)();STDMETHOD(f344)();STDMETHOD(f345)();STDMETHOD(f346)();STDMETHOD(f347)();STDMETHOD(f348)();STDMETHOD(f349)();STDMETHOD(f350)();STDMETHOD(f351)();STDMETHOD(f352)();STDMETHOD(f353)();STDMETHOD(f354)();STDMETHOD(f355)();STDMETHOD(f356)();STDMETHOD(f357)();STDMETHOD(f358)();STDMETHOD(f359)();STDMETHOD(f360)();STDMETHOD(f361)();STDMETHOD(f362)();STDMETHOD(f363)();STDMETHOD(f364)();STDMETHOD(f365)();STDMETHOD(f366)();STDMETHOD(f367)();STDMETHOD(f368)();STDMETHOD(f369)();STDMETHOD(f370)();STDMETHOD(f371)();STDMETHOD(f372)();STDMETHOD(f373)();STDMETHOD(f374)();STDMETHOD(f375)();STDMETHOD(f376)();STDMETHOD(f377)();STDMETHOD(f378)();STDMETHOD(f379)();STDMETHOD(f380)();STDMETHOD(f381)();STDMETHOD(f382)();STDMETHOD(f383)();STDMETHOD(f384)();STDMETHOD(f385)();STDMETHOD(f386)();STDMETHOD(f387)();STDMETHOD(f388)();STDMETHOD(f389)();STDMETHOD(f390)();STDMETHOD(f391)();STDMETHOD(f392)();STDMETHOD(f393)();STDMETHOD(f394)();STDMETHOD(f395)();STDMETHOD(f396)();STDMETHOD(f397)();STDMETHOD(f398)();STDMETHOD(f399)();STDMETHOD(f400)();STDMETHOD(f401)();STDMETHOD(f402)();STDMETHOD(f403)();STDMETHOD(f404)();STDMETHOD(f405)();STDMETHOD(f406)();STDMETHOD(f407)();STDMETHOD(f408)();STDMETHOD(f409)();STDMETHOD(f410)();STDMETHOD(f411)();STDMETHOD(f412)();STDMETHOD(f413)();STDMETHOD(f414)();STDMETHOD(f415)();STDMETHOD(f416)();STDMETHOD(f417)();STDMETHOD(f418)();STDMETHOD(f419)();STDMETHOD(f420)();STDMETHOD(f421)();STDMETHOD(f422)();STDMETHOD(f423)();STDMETHOD(f424)();STDMETHOD(f425)();STDMETHOD(f426)();STDMETHOD(f427)();STDMETHOD(f428)();STDMETHOD(f429)();STDMETHOD(f430)();STDMETHOD(f431)();STDMETHOD(f432)();STDMETHOD(f433)();STDMETHOD(f434)();STDMETHOD(f435)();STDMETHOD(f436)();STDMETHOD(f437)();STDMETHOD(f438)();STDMETHOD(f439)();STDMETHOD(f440)();STDMETHOD(f441)();STDMETHOD(f442)();STDMETHOD(f443)();STDMETHOD(f444)();STDMETHOD(f445)();STDMETHOD(f446)();STDMETHOD(f447)();STDMETHOD(f448)();STDMETHOD(f449)();STDMETHOD(f450)();STDMETHOD(f451)();STDMETHOD(f452)();STDMETHOD(f453)();STDMETHOD(f454)();STDMETHOD(f455)();STDMETHOD(f456)();STDMETHOD(f457)();STDMETHOD(f458)();STDMETHOD(f459)();STDMETHOD(f460)();STDMETHOD(f461)();STDMETHOD(f462)();STDMETHOD(f463)();STDMETHOD(f464)();STDMETHOD(f465)();STDMETHOD(f466)();STDMETHOD(f467)();STDMETHOD(f468)();STDMETHOD(f469)();STDMETHOD(f470)();STDMETHOD(f471)();STDMETHOD(f472)();STDMETHOD(f473)();STDMETHOD(f474)();STDMETHOD(f475)();STDMETHOD(f476)();STDMETHOD(f477)();STDMETHOD(f478)();STDMETHOD(f479)();STDMETHOD(f480)();STDMETHOD(f481)();STDMETHOD(f482)();STDMETHOD(f483)();STDMETHOD(f484)();STDMETHOD(f485)();STDMETHOD(f486)();STDMETHOD(f487)();STDMETHOD(f488)();STDMETHOD(f489)();STDMETHOD(f490)();STDMETHOD(f491)();STDMETHOD(f492)();STDMETHOD(f493)();STDMETHOD(f494)();STDMETHOD(f495)();STDMETHOD(f496)();STDMETHOD(f497)();STDMETHOD(f498)();STDMETHOD(f499)();STDMETHOD(f500)();STDMETHOD(f501)();STDMETHOD(f502)();STDMETHOD(f503)();STDMETHOD(f504)();STDMETHOD(f505)();STDMETHOD(f506)();STDMETHOD(f507)();STDMETHOD(f508)();STDMETHOD(f509)();STDMETHOD(f510)();STDMETHOD(f511)();STDMETHOD(f512)();STDMETHOD(f513)();STDMETHOD(f514)();STDMETHOD(f515)();STDMETHOD(f516)();STDMETHOD(f517)();STDMETHOD(f518)();STDMETHOD(f519)();STDMETHOD(f520)();STDMETHOD(f521)();STDMETHOD(f522)();STDMETHOD(f523)();STDMETHOD(f524)();STDMETHOD(f525)();STDMETHOD(f526)();STDMETHOD(f527)();STDMETHOD(f528)();STDMETHOD(f529)();STDMETHOD(f530)();STDMETHOD(f531)();STDMETHOD(f532)();STDMETHOD(f533)();STDMETHOD(f534)();STDMETHOD(f535)();STDMETHOD(f536)();STDMETHOD(f537)();STDMETHOD(f538)();STDMETHOD(f539)();STDMETHOD(f540)();STDMETHOD(f541)();STDMETHOD(f542)();STDMETHOD(f543)();STDMETHOD(f544)();STDMETHOD(f545)();STDMETHOD(f546)();STDMETHOD(f547)();STDMETHOD(f548)();STDMETHOD(f549)();STDMETHOD(f550)();STDMETHOD(f551)();STDMETHOD(f552)();STDMETHOD(f553)();STDMETHOD(f554)();STDMETHOD(f555)();STDMETHOD(f556)();STDMETHOD(f557)();STDMETHOD(f558)();STDMETHOD(f559)();STDMETHOD(f560)();STDMETHOD(f561)();STDMETHOD(f562)();STDMETHOD(f563)();STDMETHOD(f564)();STDMETHOD(f565)();STDMETHOD(f566)();STDMETHOD(f567)();STDMETHOD(f568)();STDMETHOD(f569)();STDMETHOD(f570)();STDMETHOD(f571)();STDMETHOD(f572)();STDMETHOD(f573)();STDMETHOD(f574)();STDMETHOD(f575)();STDMETHOD(f576)();STDMETHOD(f577)();STDMETHOD(f578)();STDMETHOD(f579)();STDMETHOD(f580)();STDMETHOD(f581)();STDMETHOD(f582)();STDMETHOD(f583)();STDMETHOD(f584)();STDMETHOD(f585)();STDMETHOD(f586)();STDMETHOD(f587)();STDMETHOD(f588)();STDMETHOD(f589)();STDMETHOD(f590)();STDMETHOD(f591)();STDMETHOD(f592)();STDMETHOD(f593)();STDMETHOD(f594)();STDMETHOD(f595)();STDMETHOD(f596)();STDMETHOD(f597)();STDMETHOD(f598)();STDMETHOD(f599)();STDMETHOD(f600)();STDMETHOD(f601)();STDMETHOD(f602)();STDMETHOD(f603)();STDMETHOD(f604)();STDMETHOD(f605)();STDMETHOD(f606)();STDMETHOD(f607)();STDMETHOD(f608)();STDMETHOD(f609)();STDMETHOD(f610)();STDMETHOD(f611)();STDMETHOD(f612)();STDMETHOD(f613)();STDMETHOD(f614)();STDMETHOD(f615)();STDMETHOD(f616)();STDMETHOD(f617)();STDMETHOD(f618)();STDMETHOD(f619)();STDMETHOD(f620)();STDMETHOD(f621)();STDMETHOD(f622)();STDMETHOD(f623)();STDMETHOD(f624)();STDMETHOD(f625)();STDMETHOD(f626)();STDMETHOD(f627)();STDMETHOD(f628)();STDMETHOD(f629)();STDMETHOD(f630)();STDMETHOD(f631)();STDMETHOD(f632)();STDMETHOD(f633)();STDMETHOD(f634)();STDMETHOD(f635)();STDMETHOD(f636)();STDMETHOD(f637)();STDMETHOD(f638)();STDMETHOD(f639)();STDMETHOD(f640)();STDMETHOD(f641)();STDMETHOD(f642)();STDMETHOD(f643)();STDMETHOD(f644)();STDMETHOD(f645)();STDMETHOD(f646)();STDMETHOD(f647)();STDMETHOD(f648)();STDMETHOD(f649)();STDMETHOD(f650)();STDMETHOD(f651)();STDMETHOD(f652)();STDMETHOD(f653)();STDMETHOD(f654)();STDMETHOD(f655)();STDMETHOD(f656)();STDMETHOD(f657)();STDMETHOD(f658)();STDMETHOD(f659)();STDMETHOD(f660)();STDMETHOD(f661)();STDMETHOD(f662)();STDMETHOD(f663)();STDMETHOD(f664)();STDMETHOD(f665)();STDMETHOD(f666)();STDMETHOD(f667)();STDMETHOD(f668)();STDMETHOD(f669)();STDMETHOD(f670)();STDMETHOD(f671)();STDMETHOD(f672)();STDMETHOD(f673)();STDMETHOD(f674)();STDMETHOD(f675)();STDMETHOD(f676)();STDMETHOD(f677)();STDMETHOD(f678)();STDMETHOD(f679)();STDMETHOD(f680)();STDMETHOD(f681)();STDMETHOD(f682)();STDMETHOD(f683)();STDMETHOD(f684)();STDMETHOD(f685)();STDMETHOD(f686)();STDMETHOD(f687)();STDMETHOD(f688)();STDMETHOD(f689)();STDMETHOD(f690)();STDMETHOD(f691)();STDMETHOD(f692)();STDMETHOD(f693)();STDMETHOD(f694)();STDMETHOD(f695)();STDMETHOD(f696)();STDMETHOD(f697)();STDMETHOD(f698)();STDMETHOD(f699)();STDMETHOD(f700)();STDMETHOD(f701)();STDMETHOD(f702)();STDMETHOD(f703)();STDMETHOD(f704)();STDMETHOD(f705)();STDMETHOD(f706)();STDMETHOD(f707)();STDMETHOD(f708)();STDMETHOD(f709)();STDMETHOD(f710)();STDMETHOD(f711)();STDMETHOD(f712)();STDMETHOD(f713)();STDMETHOD(f714)();STDMETHOD(f715)();STDMETHOD(f716)();STDMETHOD(f717)();STDMETHOD(f718)();STDMETHOD(f719)();STDMETHOD(f720)();STDMETHOD(f721)();STDMETHOD(f722)();STDMETHOD(f723)();STDMETHOD(f724)();STDMETHOD(f725)();STDMETHOD(f726)();STDMETHOD(f727)();STDMETHOD(f728)();STDMETHOD(f729)();STDMETHOD(f730)();STDMETHOD(f731)();STDMETHOD(f732)();STDMETHOD(f733)();STDMETHOD(f734)();STDMETHOD(f735)();STDMETHOD(f736)();STDMETHOD(f737)();STDMETHOD(f738)();STDMETHOD(f739)();STDMETHOD(f740)();STDMETHOD(f741)();STDMETHOD(f742)();STDMETHOD(f743)();STDMETHOD(f744)();STDMETHOD(f745)();STDMETHOD(f746)();STDMETHOD(f747)();STDMETHOD(f748)();STDMETHOD(f749)();STDMETHOD(f750)();STDMETHOD(f751)();STDMETHOD(f752)();STDMETHOD(f753)();STDMETHOD(f754)();STDMETHOD(f755)();STDMETHOD(f756)();STDMETHOD(f757)();STDMETHOD(f758)();STDMETHOD(f759)();STDMETHOD(f760)();STDMETHOD(f761)();STDMETHOD(f762)();STDMETHOD(f763)();STDMETHOD(f764)();STDMETHOD(f765)();STDMETHOD(f766)();STDMETHOD(f767)();STDMETHOD(f768)();STDMETHOD(f769)();STDMETHOD(f770)();STDMETHOD(f771)();STDMETHOD(f772)();STDMETHOD(f773)();STDMETHOD(f774)();STDMETHOD(f775)();STDMETHOD(f776)();STDMETHOD(f777)();STDMETHOD(f778)();STDMETHOD(f779)();STDMETHOD(f780)();STDMETHOD(f781)();STDMETHOD(f782)();STDMETHOD(f783)();STDMETHOD(f784)();STDMETHOD(f785)();STDMETHOD(f786)();STDMETHOD(f787)();STDMETHOD(f788)();STDMETHOD(f789)();STDMETHOD(f790)();STDMETHOD(f791)();STDMETHOD(f792)();STDMETHOD(f793)();STDMETHOD(f794)();STDMETHOD(f795)();STDMETHOD(f796)();STDMETHOD(f797)();STDMETHOD(f798)();STDMETHOD(f799)();STDMETHOD(f800)();STDMETHOD(f801)();STDMETHOD(f802)();STDMETHOD(f803)();STDMETHOD(f804)();STDMETHOD(f805)();STDMETHOD(f806)();STDMETHOD(f807)();STDMETHOD(f808)();STDMETHOD(f809)();STDMETHOD(f810)();STDMETHOD(f811)();STDMETHOD(f812)();STDMETHOD(f813)();STDMETHOD(f814)();STDMETHOD(f815)();STDMETHOD(f816)();STDMETHOD(f817)();STDMETHOD(f818)();STDMETHOD(f819)();STDMETHOD(f820)();STDMETHOD(f821)();STDMETHOD(f822)();STDMETHOD(f823)();STDMETHOD(f824)();STDMETHOD(f825)();STDMETHOD(f826)();STDMETHOD(f827)();STDMETHOD(f828)();STDMETHOD(f829)();STDMETHOD(f830)();STDMETHOD(f831)();STDMETHOD(f832)();STDMETHOD(f833)();STDMETHOD(f834)();STDMETHOD(f835)();STDMETHOD(f836)();STDMETHOD(f837)();STDMETHOD(f838)();STDMETHOD(f839)();STDMETHOD(f840)();STDMETHOD(f841)();STDMETHOD(f842)();STDMETHOD(f843)();STDMETHOD(f844)();STDMETHOD(f845)();STDMETHOD(f846)();STDMETHOD(f847)();STDMETHOD(f848)();STDMETHOD(f849)();STDMETHOD(f850)();STDMETHOD(f851)();STDMETHOD(f852)();STDMETHOD(f853)();STDMETHOD(f854)();STDMETHOD(f855)();STDMETHOD(f856)();STDMETHOD(f857)();STDMETHOD(f858)();STDMETHOD(f859)();STDMETHOD(f860)();STDMETHOD(f861)();STDMETHOD(f862)();STDMETHOD(f863)();STDMETHOD(f864)();STDMETHOD(f865)();STDMETHOD(f866)();STDMETHOD(f867)();STDMETHOD(f868)();STDMETHOD(f869)();STDMETHOD(f870)();STDMETHOD(f871)();STDMETHOD(f872)();STDMETHOD(f873)();STDMETHOD(f874)();STDMETHOD(f875)();STDMETHOD(f876)();STDMETHOD(f877)();STDMETHOD(f878)();STDMETHOD(f879)();STDMETHOD(f880)();STDMETHOD(f881)();STDMETHOD(f882)();STDMETHOD(f883)();STDMETHOD(f884)();STDMETHOD(f885)();STDMETHOD(f886)();STDMETHOD(f887)();STDMETHOD(f888)();STDMETHOD(f889)();STDMETHOD(f890)();STDMETHOD(f891)();STDMETHOD(f892)();STDMETHOD(f893)();STDMETHOD(f894)();STDMETHOD(f895)();STDMETHOD(f896)();STDMETHOD(f897)();STDMETHOD(f898)();STDMETHOD(f899)();STDMETHOD(f900)();STDMETHOD(f901)();STDMETHOD(f902)();STDMETHOD(f903)();STDMETHOD(f904)();STDMETHOD(f905)();STDMETHOD(f906)();STDMETHOD(f907)();STDMETHOD(f908)();STDMETHOD(f909)();STDMETHOD(f910)();STDMETHOD(f911)();STDMETHOD(f912)();STDMETHOD(f913)();STDMETHOD(f914)();STDMETHOD(f915)();STDMETHOD(f916)();STDMETHOD(f917)();STDMETHOD(f918)();STDMETHOD(f919)();STDMETHOD(f920)();STDMETHOD(f921)();STDMETHOD(f922)();STDMETHOD(f923)();STDMETHOD(f924)();STDMETHOD(f925)();STDMETHOD(f926)();STDMETHOD(f927)();STDMETHOD(f928)();STDMETHOD(f929)();STDMETHOD(f930)();STDMETHOD(f931)();STDMETHOD(f932)();STDMETHOD(f933)();STDMETHOD(f934)();STDMETHOD(f935)();STDMETHOD(f936)();STDMETHOD(f937)();STDMETHOD(f938)();STDMETHOD(f939)();STDMETHOD(f940)();STDMETHOD(f941)();STDMETHOD(f942)();STDMETHOD(f943)();STDMETHOD(f944)();STDMETHOD(f945)();STDMETHOD(f946)();STDMETHOD(f947)();STDMETHOD(f948)();STDMETHOD(f949)();STDMETHOD(f950)();STDMETHOD(f951)();STDMETHOD(f952)();STDMETHOD(f953)();STDMETHOD(f954)();STDMETHOD(f955)();STDMETHOD(f956)();STDMETHOD(f957)();STDMETHOD(f958)();STDMETHOD(f959)();STDMETHOD(f960)();STDMETHOD(f961)();STDMETHOD(f962)();STDMETHOD(f963)();STDMETHOD(f964)();STDMETHOD(f965)();STDMETHOD(f966)();STDMETHOD(f967)();STDMETHOD(f968)();STDMETHOD(f969)();STDMETHOD(f970)();STDMETHOD(f971)();STDMETHOD(f972)();STDMETHOD(f973)();STDMETHOD(f974)();STDMETHOD(f975)();STDMETHOD(f976)();STDMETHOD(f977)();STDMETHOD(f978)();STDMETHOD(f979)();STDMETHOD(f980)();STDMETHOD(f981)();STDMETHOD(f982)();STDMETHOD(f983)();STDMETHOD(f984)();STDMETHOD(f985)();STDMETHOD(f986)();STDMETHOD(f987)();STDMETHOD(f988)();STDMETHOD(f989)();STDMETHOD(f990)();STDMETHOD(f991)();STDMETHOD(f992)();STDMETHOD(f993)();STDMETHOD(f994)();STDMETHOD(f995)();STDMETHOD(f996)();STDMETHOD(f997)();STDMETHOD(f998)();STDMETHOD(f999)();STDMETHOD(f1000)();STDMETHOD(f1001)();STDMETHOD(f1002)();STDMETHOD(f1003)();STDMETHOD(f1004)();STDMETHOD(f1005)();STDMETHOD(f1006)();STDMETHOD(f1007)();STDMETHOD(f1008)();STDMETHOD(f1009)();STDMETHOD(f1010)();STDMETHOD(f1011)();STDMETHOD(f1012)();STDMETHOD(f1013)();STDMETHOD(f1014)();STDMETHOD(f1015)();STDMETHOD(f1016)();STDMETHOD(f1017)();STDMETHOD(f1018)();STDMETHOD(f1019)();STDMETHOD(f1020)();STDMETHOD(f1021)();STDMETHOD(f1022)();STDMETHOD(f1023)();STDMETHOD(f1024)();_QIThunk(IUnknown* pOrig, LPCTSTR p, const IID& i, UINT n, bool b){lpszClassName = p;iid = i;nIndex = n;m_dwRef = 0;m_dwMaxRef = 0;pUnk = pOrig;bBreak = b;bNonAddRefThunk = false;}IUnknown* pUnk;long m_dwRef;long m_dwMaxRef;LPCTSTR lpszClassName;IID iid;UINT nIndex;bool bBreak;bool bNonAddRefThunk;void Dump(){TCHAR buf[256];if (m_dwRef != 0){wsprintf(buf, _T("INTERFACE LEAK: RefCount = %d, MaxRefCount = %d, {Allocation = %d} "), m_dwRef, m_dwMaxRef, nIndex);OutputDebugString(buf);AtlDumpIID(iid, lpszClassName, S_OK);}else{wsprintf(buf, _T("NonAddRef Thunk LEAK: {Allocation = %d}\n"), nIndex);OutputDebugString(buf);}}};#endif/////////////////////////////////////////////////////////////////////////////// Collection helpers - CSimpleArray & CSimpleMaptemplate <class T>class CSimpleArray{public:T* m_aT;int m_nSize;int m_nAllocSize;// Construction/destructionCSimpleArray() : m_aT(NULL), m_nSize(0), m_nAllocSize(0){ }~CSimpleArray(){RemoveAll();}// Operationsint GetSize() const{return m_nSize;}BOOL Add(T& t){if(m_nSize == m_nAllocSize){T* aT;int nNewAllocSize = (m_nAllocSize == 0) ? 1 : (m_nSize * 2);aT = (T*)realloc(m_aT, nNewAllocSize * sizeof(T));if(aT == NULL)return FALSE;m_nAllocSize = nNewAllocSize;m_aT = aT;}m_nSize++;SetAtIndex(m_nSize - 1, t);return TRUE;}BOOL Remove(T& t){int nIndex = Find(t);if(nIndex == -1)return FALSE;return RemoveAt(nIndex);}BOOL RemoveAt(int nIndex){if(nIndex != (m_nSize - 1)){m_aT[nIndex].~T();memmove((void*)&m_aT[nIndex], (void*)&m_aT[nIndex + 1], (m_nSize - (nIndex + 1)) * sizeof(T));}m_nSize--;return TRUE;}void RemoveAll(){if(m_aT != NULL){for(int i = 0; i < m_nSize; i++)m_aT[i].~T();free(m_aT);m_aT = NULL;}m_nSize = 0;m_nAllocSize = 0;}T& operator[] (int nIndex) const{ATLASSERT(nIndex >= 0 && nIndex < m_nSize);return m_aT[nIndex];}T* GetData() const{return m_aT;}// Implementationclass Wrapper{public:Wrapper(T& _t) : t(_t){}template <class _Ty>void *operator new(size_t, _Ty* p){return p;}T t;};void SetAtIndex(int nIndex, T& t){ATLASSERT(nIndex >= 0 && nIndex < m_nSize);new(&m_aT[nIndex]) Wrapper(t);}int Find(T& t) const{for(int i = 0; i < m_nSize; i++){if(m_aT[i] == t)return i;}return -1;  // not found}};// for arrays of simple typestemplate <class T>class CSimpleValArray : public CSimpleArray< T >{public:BOOL Add(T t){return CSimpleArray< T >::Add(t);}BOOL Remove(T t){return CSimpleArray< T >::Remove(t);}T operator[] (int nIndex) const{return CSimpleArray< T >::operator[](nIndex);}};// intended for small number of simple types or pointerstemplate <class TKey, class TVal>class CSimpleMap{public:TKey* m_aKey;TVal* m_aVal;int m_nSize;// Construction/destructionCSimpleMap() : m_aKey(NULL), m_aVal(NULL), m_nSize(0){ }~CSimpleMap(){RemoveAll();}// Operationsint GetSize() const{return m_nSize;}BOOL Add(TKey key, TVal val){TKey* pKey;pKey = (TKey*)realloc(m_aKey, (m_nSize + 1) * sizeof(TKey));if(pKey == NULL)return FALSE;m_aKey = pKey;TVal* pVal;pVal = (TVal*)realloc(m_aVal, (m_nSize + 1) * sizeof(TVal));if(pVal == NULL)return FALSE;m_aVal = pVal;m_nSize++;SetAtIndex(m_nSize - 1, key, val);return TRUE;}BOOL Remove(TKey key){int nIndex = FindKey(key);if(nIndex == -1)return FALSE;if(nIndex != (m_nSize - 1)){m_aKey[nIndex].~TKey();m_aVal[nIndex].~TVal();memmove((void*)&m_aKey[nIndex], (void*)&m_aKey[nIndex + 1], (m_nSize - (nIndex + 1)) * sizeof(TKey));memmove((void*)&m_aVal[nIndex], (void*)&m_aVal[nIndex + 1], (m_nSize - (nIndex + 1)) * sizeof(TVal));}TKey* pKey;pKey = (TKey*)realloc(m_aKey, (m_nSize - 1) * sizeof(TKey));if(pKey != NULL || m_nSize == 1)m_aKey = pKey;TVal* pVal;pVal = (TVal*)realloc(m_aVal, (m_nSize - 1) * sizeof(TVal));if(pVal != NULL || m_nSize == 1)m_aVal = pVal;m_nSize--;return TRUE;}void RemoveAll(){if(m_aKey != NULL){for(int i = 0; i < m_nSize; i++){m_aKey[i].~TKey();m_aVal[i].~TVal();}free(m_aKey);m_aKey = NULL;}if(m_aVal != NULL){free(m_aVal);m_aVal = NULL;}m_nSize = 0;}BOOL SetAt(TKey key, TVal val){int nIndex = FindKey(key);if(nIndex == -1)return FALSE;SetAtIndex(nIndex, key, val);return TRUE;}TVal Lookup(TKey key) const{int nIndex = FindKey(key);if(nIndex == -1)return NULL;    // must be able to convertreturn GetValueAt(nIndex);}TKey ReverseLookup(TVal val) const{int nIndex = FindVal(val);if(nIndex == -1)return NULL;    // must be able to convertreturn GetKeyAt(nIndex);}TKey& GetKeyAt(int nIndex) const{ATLASSERT(nIndex >= 0 && nIndex < m_nSize);return m_aKey[nIndex];}TVal& GetValueAt(int nIndex) const{ATLASSERT(nIndex >= 0 && nIndex < m_nSize);return m_aVal[nIndex];}// Implementationtemplate <typename T>class Wrapper{public:Wrapper(T& _t) : t(_t){}template <typename _Ty>void *operator new(size_t, _Ty* p){return p;}T t;};void SetAtIndex(int nIndex, TKey& key, TVal& val){ATLASSERT(nIndex >= 0 && nIndex < m_nSize);new(&m_aKey[nIndex]) Wrapper<TKey>(key);new(&m_aVal[nIndex]) Wrapper<TVal>(val);}int FindKey(TKey& key) const{for(int i = 0; i < m_nSize; i++){if(m_aKey[i] == key)return i;}return -1;  // not found}int FindVal(TVal& val) const{for(int i = 0; i < m_nSize; i++){if(m_aVal[i] == val)return i;}return -1;  // not found}};class CComModule;__declspec(selectany) CComModule* _pModule=NULL;// {B62F5910-6528-11d1-9611-0000F81E0D0D}_declspec(selectany) GUID GUID_ATLVer30 = { 0xb62f5910, 0x6528, 0x11d1, { 0x96, 0x11, 0x0, 0x0, 0xf8, 0x1e, 0xd, 0xd } };class CComModule : public _ATL_MODULE{// Operationspublic:static GUID m_libid;#ifdef _ATL_DEBUG_INTERFACESUINT m_nIndexQI;UINT m_nIndexBreakAt;CSimpleArray<_QIThunk*>* m_paThunks;#endif // _ATL_DEBUG_INTERFACESvoid AddCreateWndData(_AtlCreateWndData* pData, void* pObject){AtlModuleAddCreateWndData(this, pData, pObject);}void* ExtractCreateWndData(){return AtlModuleExtractCreateWndData(this);}HRESULT Init(_ATL_OBJMAP_ENTRY* p, HINSTANCE h, const GUID* plibid = NULL){pguidVer = &GUID_ATLVer30;_pModule = this;cbSize = sizeof(_ATL_MODULE);dwAtlBuildVer = _ATL_VER;AtlModuleInit(this, p, h);if (plibid != NULL)memcpy((void*)&m_libid, plibid, sizeof(GUID));#ifdef _ATL_MIN_CRT// Create a base heapm_hHeap = HeapCreate(0, 0, 0);#ifndef _ATL_NO_MP_HEAPOSVERSIONINFO ver;SYSTEM_INFO si;memset( &ver, 0, sizeof( ver ) );ver.dwOSVersionInfoSize = sizeof( ver );GetVersionEx( &ver );GetSystemInfo(&si);if( ((ver.dwPlatformId != VER_PLATFORM_WIN32_NT) ||(ver.dwMajorVersion < 5)) && (si.dwNumberOfProcessors > 1) ){DWORD dwHeaps = si.dwNumberOfProcessors * 2;m_dwHeaps = 0xFFFFFFFF;for (int bits = 0; bits < 32; bits++){if (dwHeaps & 0x80000000)break;dwHeaps <<= 1;m_dwHeaps >>= 1;}m_dwHeaps >>= 1;// Allocate more heaps for each processorm_phHeaps = (HANDLE*) HeapAlloc(m_hHeap, _ATL_HEAPFLAGS, sizeof(HANDLE) * (m_dwHeaps + 1));for (DWORD i = 0; i <= m_dwHeaps; i++)m_phHeaps[i] = HeapCreate(0, 0, 0);}else#endif{m_phHeaps = NULL;m_dwHeaps = 0;}#endif#ifdef _ATL_DEBUG_INTERFACESm_nIndexQI = 0;m_nIndexBreakAt = 0;m_paThunks = NULL;ATLTRY(m_paThunks = new CSimpleArray<_QIThunk*>);if (m_paThunks == NULL)return E_OUTOFMEMORY;#endif // _ATL_DEBUG_INTERFACESreturn S_OK;}#ifdef _ATL_DEBUG_INTERFACESHRESULT AddThunk(IUnknown** pp, LPCTSTR lpsz, REFIID iid){if ((pp == NULL) || (*pp == NULL))return E_POINTER;IUnknown* p = *pp;_QIThunk* pThunk = NULL;EnterCriticalSection(&m_csObjMap);// Check if exists already for identityif (InlineIsEqualUnknown(iid)){for (int i = 0; i < m_paThunks->GetSize(); i++){if (m_paThunks->operator[](i)->pUnk == p){m_paThunks->operator[](i)->InternalAddRef();pThunk = m_paThunks->operator[](i);break;}}}if (pThunk == NULL){++m_nIndexQI;if (m_nIndexBreakAt == m_nIndexQI)DebugBreak();ATLTRY(pThunk = new _QIThunk(p, lpsz, iid, m_nIndexQI, (m_nIndexBreakAt == m_nIndexQI)));if (pThunk == NULL)return E_OUTOFMEMORY;pThunk->InternalAddRef();m_paThunks->Add(pThunk);}LeaveCriticalSection(&m_csObjMap);*pp = (IUnknown*)pThunk;return S_OK;}HRESULT AddNonAddRefThunk(IUnknown* p, LPCTSTR lpsz, IUnknown** ppThunkRet){_QIThunk* pThunk = NULL;EnterCriticalSection(&m_csObjMap);// Check if exists already for identityfor (int i = 0; i < m_paThunks->GetSize(); i++){if (m_paThunks->operator[](i)->pUnk == p){m_paThunks->operator[](i)->bNonAddRefThunk = true;pThunk = m_paThunks->operator[](i);break;}}if (pThunk == NULL){++m_nIndexQI;if (m_nIndexBreakAt == m_nIndexQI)DebugBreak();ATLTRY(pThunk = new _QIThunk(p, lpsz, IID_IUnknown, m_nIndexQI, (m_nIndexBreakAt == m_nIndexQI)));if (pThunk == NULL){*ppThunkRet = NULL;return E_OUTOFMEMORY;}pThunk->bNonAddRefThunk = true;m_paThunks->Add(pThunk);}LeaveCriticalSection(&m_csObjMap);*ppThunkRet = (IUnknown*)pThunk;return S_OK;;}void DeleteNonAddRefThunk(IUnknown* pUnk){EnterCriticalSection(&m_csObjMap);for (int i = 0; i < m_paThunks->GetSize(); i++){if (m_paThunks->operator[](i)->pUnk == pUnk){delete m_paThunks->operator[](i);m_paThunks->RemoveAt(i);break;}}LeaveCriticalSection(&m_csObjMap);}void DeleteThunk(_QIThunk* p){EnterCriticalSection(&m_csObjMap);int nIndex = m_paThunks->Find(p);if (nIndex != -1){delete m_paThunks->operator[](nIndex);m_paThunks->RemoveAt(nIndex);}LeaveCriticalSection(&m_csObjMap);}bool DumpLeakedThunks(){bool b = false;for (int i = 0; i < m_paThunks->GetSize(); i++){b = true;m_paThunks->operator[](i)->Dump();delete m_paThunks->operator[](i);}m_paThunks->RemoveAll();return b;}#endif // _ATL_DEBUG_INTERFACESvoid Term(){#ifdef _ATL_DEBUG_INTERFACESm_bDestroyHeap = false; // prevent heap from going awayAtlModuleTerm(this);DumpLeakedThunks();delete m_paThunks;#ifndef _ATL_NO_MP_HEAPif (m_phHeaps != NULL){for (DWORD i = 0; i <= m_dwHeaps; i++)HeapDestroy(m_phHeaps[i]);}#endifif (m_hHeap != NULL)HeapDestroy(m_hHeap);#elseAtlModuleTerm(this);#endif // _ATL_DEBUG_INTERFACES}HRESULT AddTermFunc(_ATL_TERMFUNC* pFunc, DWORD dw){return AtlModuleAddTermFunc(this, pFunc, dw);}LONG Lock(){return CComGlobalsThreadModel::Increment(&m_nLockCnt);}LONG Unlock(){return CComGlobalsThreadModel::Decrement(&m_nLockCnt);}LONG GetLockCount(){return m_nLockCnt;}HINSTANCE GetModuleInstance() {return m_hInst;}HINSTANCE GetResourceInstance() {return m_hInstResource;}HINSTANCE GetTypeLibInstance() {return m_hInstTypeLib;}// Registry support (helpers)HRESULT RegisterTypeLib(){return AtlModuleRegisterTypeLib(this, NULL);}HRESULT RegisterTypeLib(LPCTSTR lpszIndex){USES_CONVERSION;return AtlModuleRegisterTypeLib(this, T2COLE(lpszIndex));}HRESULT UnRegisterTypeLib(){return AtlModuleUnRegisterTypeLib(this, NULL);}HRESULT UnRegisterTypeLib(LPCTSTR lpszIndex){USES_CONVERSION;return AtlModuleUnRegisterTypeLib(this, T2COLE(lpszIndex));}HRESULT RegisterServer(BOOL bRegTypeLib = FALSE, const CLSID* pCLSID = NULL){return AtlModuleRegisterServer(this, bRegTypeLib, pCLSID);}HRESULT UnregisterServer(const CLSID* pCLSID = NULL){return AtlModuleUnregisterServer(this, pCLSID);}HRESULT UnregisterServer(BOOL bUnRegTypeLib, const CLSID* pCLSID = NULL){return AtlModuleUnregisterServerEx(this, bUnRegTypeLib, pCLSID);}// Resource-based RegistrationHRESULT WINAPI UpdateRegistryFromResourceD(LPCTSTR lpszRes, BOOL bRegister,struct _ATL_REGMAP_ENTRY* pMapEntries = NULL){USES_CONVERSION;return AtlModuleUpdateRegistryFromResourceD(this, T2COLE(lpszRes), bRegister,pMapEntries);}HRESULT WINAPI UpdateRegistryFromResourceD(UINT nResID, BOOL bRegister,struct _ATL_REGMAP_ENTRY* pMapEntries = NULL){return AtlModuleUpdateRegistryFromResourceD(this,(LPCOLESTR)MAKEINTRESOURCE(nResID), bRegister, pMapEntries);}#ifdef _ATL_STATIC_REGISTRY// Statically linking to Registry PonentHRESULT WINAPI UpdateRegistryFromResourceS(LPCTSTR lpszRes, BOOL bRegister,struct _ATL_REGMAP_ENTRY* pMapEntries = NULL);HRESULT WINAPI UpdateRegistryFromResourceS(UINT nResID, BOOL bRegister,struct _ATL_REGMAP_ENTRY* pMapEntries = NULL);#endif// Standard RegistrationHRESULT WINAPI UpdateRegistryClass(const CLSID& clsid, LPCTSTR lpszProgID,LPCTSTR lpszVerIndProgID, UINT nDescID, DWORD dwFlags, BOOL bRegister);HRESULT WINAPI RegisterClassHelper(const CLSID& clsid, LPCTSTR lpszProgID,LPCTSTR lpszVerIndProgID, UINT nDescID, DWORD dwFlags);HRESULT WINAPI UnregisterClassHelper(const CLSID& clsid, LPCTSTR lpszProgID,LPCTSTR lpszVerIndProgID);// Register/Revoke All Class Factories with the OS (EXE only)HRESULT RegisterClassObjects(DWORD dwClsContext, DWORD dwFlags){return AtlModuleRegisterClassObjects(this, dwClsContext, dwFlags);}HRESULT RevokeClassObjects(){return AtlModuleRevokeClassObjects(this);}// Obtain a Class Factory (DLL only)HRESULT GetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv){return AtlModuleGetClassObject(this, rclsid, riid, ppv);}// Only used in CComAutoThreadModuleHRESULT CreateInstance(void* /*pfnCreateInstance*/, REFIID /*riid*/, void** /*ppvObj*/){ATLASSERT(FALSE);return E_NOTIMPL;}static HRESULT RegisterProgID(LPCTSTR lpszCLSID, LPCTSTR lpszProgID, LPCTSTR lpszUserDesc);static void ReplaceSingleQuote(LPOLESTR lpDest, LPCOLESTR lp){while (*lp){*lpDest++ = *lp;if (*lp == OLESTR('\''))*lpDest++ = *lp;lp++;}*lpDest = NULL;}};#ifdef _ATL_DEBUG_INTERFACESinline ULONG _QIThunk::Release(){if (bBreak)DebugBreak();ATLASSERT(m_dwRef > 0);ULONG l = InterlockedDecrement(&m_dwRef);ATLTRACE(_T("%d< "), m_dwRef);AtlDumpIID(iid, lpszClassName, S_OK);pUnk->Release();if (l == 0 && !bNonAddRefThunk)_pModule->DeleteThunk(this);return l;}inline static void atlBadThunkCall(){ATLASSERT(FALSE && "Call through deleted thunk");}#define IMPL_THUNK(n)\__declspec(naked) inline HRESULT _QIThunk::f##n()\{\__asm mov eax, [esp+4]\__asm cmp dword ptr [eax+8], 0\__asm jg goodref\__asm call atlBadThunkCall\__asm goodref:\__asm mov eax, [esp+4]\__asm mov eax, dword ptr [eax+4]\__asm mov [esp+4], eax\__asm mov eax, dword ptr [eax]\__asm mov eax, dword ptr [eax+4*n]\__asm jmp eax\}IMPL_THUNK(3)IMPL_THUNK(4)IMPL_THUNK(5)IMPL_THUNK(6)IMPL_THUNK(7)IMPL_THUNK(8)IMPL_THUNK(9)IMPL_THUNK(10)IMPL_THUNK(11)IMPL_THUNK(12)IMPL_THUNK(13)IMPL_THUNK(14)IMPL_THUNK(15)IMPL_THUNK(16)IMPL_THUNK(17)IMPL_THUNK(18)IMPL_THUNK(19)IMPL_THUNK(20)IMPL_THUNK(21)IMPL_THUNK(22)IMPL_THUNK(23)IMPL_THUNK(24)IMPL_THUNK(25)IMPL_THUNK(26)IMPL_THUNK(27)IMPL_THUNK(28)IMPL_THUNK(29)IMPL_THUNK(30)IMPL_THUNK(31)IMPL_THUNK(32)IMPL_THUNK(33)IMPL_THUNK(34)IMPL_THUNK(35)IMPL_THUNK(36)IMPL_THUNK(37)IMPL_THUNK(38)IMPL_THUNK(39)IMPL_THUNK(40)IMPL_THUNK(41)IMPL_THUNK(42)IMPL_THUNK(43)IMPL_THUNK(44)IMPL_THUNK(45)IMPL_THUNK(46)IMPL_THUNK(47)IMPL_THUNK(48)IMPL_THUNK(49)IMPL_THUNK(50)IMPL_THUNK(51)IMPL_THUNK(52)IMPL_THUNK(53)IMPL_THUNK(54)IMPL_THUNK(55)IMPL_THUNK(56)IMPL_THUNK(57)IMPL_THUNK(58)IMPL_THUNK(59)IMPL_THUNK(60)IMPL_THUNK(61)IMPL_THUNK(62)IMPL_THUNK(63)IMPL_THUNK(64)IMPL_THUNK(65)IMPL_THUNK(66)IMPL_THUNK(67)IMPL_THUNK(68)IMPL_THUNK(69)IMPL_THUNK(70)IMPL_THUNK(71)IMPL_THUNK(72)IMPL_THUNK(73)IMPL_THUNK(74)IMPL_THUNK(75)IMPL_THUNK(76)IMPL_THUNK(77)IMPL_THUNK(78)IMPL_THUNK(79)IMPL_THUNK(80)IMPL_THUNK(81)IMPL_THUNK(82)IMPL_THUNK(83)IMPL_THUNK(84)IMPL_THUNK(85)IMPL_THUNK(86)IMPL_THUNK(87)IMPL_THUNK(88)IMPL_THUNK(89)IMPL_THUNK(90)IMPL_THUNK(91)IMPL_THUNK(92)IMPL_THUNK(93)IMPL_THUNK(94)IMPL_THUNK(95)IMPL_THUNK(96)IMPL_THUNK(97)IMPL_THUNK(98)IMPL_THUNK(99)IMPL_THUNK(100)IMPL_THUNK(101)IMPL_THUNK(102)IMPL_THUNK(103)IMPL_THUNK(104)IMPL_THUNK(105)IMPL_THUNK(106)IMPL_THUNK(107)IMPL_THUNK(108)IMPL_THUNK(109)IMPL_THUNK(110)IMPL_THUNK(111)IMPL_THUNK(112)IMPL_THUNK(113)IMPL_THUNK(114)IMPL_THUNK(115)IMPL_THUNK(116)IMPL_THUNK(117)IMPL_THUNK(118)IMPL_THUNK(119)IMPL_THUNK(120)IMPL_THUNK(121)IMPL_THUNK(122)IMPL_THUNK(123)IMPL_THUNK(124)IMPL_THUNK(125)IMPL_THUNK(126)IMPL_THUNK(127)IMPL_THUNK(128)IMPL_THUNK(129)IMPL_THUNK(130)IMPL_THUNK(131)IMPL_THUNK(132)IMPL_THUNK(133)IMPL_THUNK(134)IMPL_THUNK(135)IMPL_THUNK(136)IMPL_THUNK(137)IMPL_THUNK(138)IMPL_THUNK(139)IMPL_THUNK(140)IMPL_THUNK(141)IMPL_THUNK(142)IMPL_THUNK(143)IMPL_THUNK(144)IMPL_THUNK(145)IMPL_THUNK(146)IMPL_THUNK(147)IMPL_THUNK(148)IMPL_THUNK(149)IMPL_THUNK(150)IMPL_THUNK(151)IMPL_THUNK(152)IMPL_THUNK(153)IMPL_THUNK(154)IMPL_THUNK(155)IMPL_THUNK(156)IMPL_THUNK(157)IMPL_THUNK(158)IMPL_THUNK(159)IMPL_THUNK(160)IMPL_THUNK(161)IMPL_THUNK(162)IMPL_THUNK(163)IMPL_THUNK(164)IMPL_THUNK(165)IMPL_THUNK(166)IMPL_THUNK(167)IMPL_THUNK(168)IMPL_THUNK(169)IMPL_THUNK(170)IMPL_THUNK(171)IMPL_THUNK(172)IMPL_THUNK(173)IMPL_THUNK(174)IMPL_THUNK(175)IMPL_THUNK(176)IMPL_THUNK(177)IMPL_THUNK(178)IMPL_THUNK(179)IMPL_THUNK(180)IMPL_THUNK(181)IMPL_THUNK(182)IMPL_THUNK(183)IMPL_THUNK(184)IMPL_THUNK(185)IMPL_THUNK(186)IMPL_THUNK(187)IMPL_THUNK(188)IMPL_THUNK(189)IMPL_THUNK(190)IMPL_THUNK(191)IMPL_THUNK(192)IMPL_THUNK(193)IMPL_THUNK(194)IMPL_THUNK(195)IMPL_THUNK(196)IMPL_THUNK(197)IMPL_THUNK(198)IMPL_THUNK(199)IMPL_THUNK(200)IMPL_THUNK(201)IMPL_THUNK(202)IMPL_THUNK(203)IMPL_THUNK(204)IMPL_THUNK(205)IMPL_THUNK(206)IMPL_THUNK(207)IMPL_THUNK(208)IMPL_THUNK(209)IMPL_THUNK(210)IMPL_THUNK(211)IMPL_THUNK(212)IMPL_THUNK(213)IMPL_THUNK(214)IMPL_THUNK(215)IMPL_THUNK(216)IMPL_THUNK(217)IMPL_THUNK(218)IMPL_THUNK(219)IMPL_THUNK(220)IMPL_THUNK(221)IMPL_THUNK(222)IMPL_THUNK(223)IMPL_THUNK(224)IMPL_THUNK(225)IMPL_THUNK(226)IMPL_THUNK(227)IMPL_THUNK(228)IMPL_THUNK(229)IMPL_THUNK(230)IMPL_THUNK(231)IMPL_THUNK(232)IMPL_THUNK(233)IMPL_THUNK(234)IMPL_THUNK(235)IMPL_THUNK(236)IMPL_THUNK(237)IMPL_THUNK(238)IMPL_THUNK(239)IMPL_THUNK(240)IMPL_THUNK(241)IMPL_THUNK(242)IMPL_THUNK(243)IMPL_THUNK(244)IMPL_THUNK(245)IMPL_THUNK(246)IMPL_THUNK(247)IMPL_THUNK(248)IMPL_THUNK(249)IMPL_THUNK(250)IMPL_THUNK(251)IMPL_THUNK(252)IMPL_THUNK(253)IMPL_THUNK(254)IMPL_THUNK(255)IMPL_THUNK(256)IMPL_THUNK(257)IMPL_THUNK(258)IMPL_THUNK(259)IMPL_THUNK(260)IMPL_THUNK(261)IMPL_THUNK(262)IMPL_THUNK(263)IMPL_THUNK(264)IMPL_THUNK(265)IMPL_THUNK(266)IMPL_THUNK(267)IMPL_THUNK(268)IMPL_THUNK(269)IMPL_THUNK(270)IMPL_THUNK(271)IMPL_THUNK(272)IMPL_THUNK(273)IMPL_THUNK(274)IMPL_THUNK(275)IMPL_THUNK(276)IMPL_THUNK(277)IMPL_THUNK(278)IMPL_THUNK(279)IMPL_THUNK(280)IMPL_THUNK(281)IMPL_THUNK(282)IMPL_THUNK(283)IMPL_THUNK(284)IMPL_THUNK(285)IMPL_THUNK(286)IMPL_THUNK(287)IMPL_THUNK(288)IMPL_THUNK(289)IMPL_THUNK(290)IMPL_THUNK(291)IMPL_THUNK(292)IMPL_THUNK(293)IMPL_THUNK(294)IMPL_THUNK(295)IMPL_THUNK(296)IMPL_THUNK(297)IMPL_THUNK(298)IMPL_THUNK(299)IMPL_THUNK(300)IMPL_THUNK(301)IMPL_THUNK(302)IMPL_THUNK(303)IMPL_THUNK(304)IMPL_THUNK(305)IMPL_THUNK(306)IMPL_THUNK(307)IMPL_THUNK(308)IMPL_THUNK(309)IMPL_THUNK(310)IMPL_THUNK(311)IMPL_THUNK(312)IMPL_THUNK(313)IMPL_THUNK(314)IMPL_THUNK(315)IMPL_THUNK(316)IMPL_THUNK(317)IMPL_THUNK(318)IMPL_THUNK(319)IMPL_THUNK(320)IMPL_THUNK(321)IMPL_THUNK(322)IMPL_THUNK(323)IMPL_THUNK(324)IMPL_THUNK(325)IMPL_THUNK(326)IMPL_THUNK(327)IMPL_THUNK(328)IMPL_THUNK(329)IMPL_THUNK(330)IMPL_THUNK(331)IMPL_THUNK(332)IMPL_THUNK(333)IMPL_THUNK(334)IMPL_THUNK(335)IMPL_THUNK(336)IMPL_THUNK(337)IMPL_THUNK(338)IMPL_THUNK(339)IMPL_THUNK(340)IMPL_THUNK(341)IMPL_THUNK(342)IMPL_THUNK(343)IMPL_THUNK(344)IMPL_THUNK(345)IMPL_THUNK(346)IMPL_THUNK(347)IMPL_THUNK(348)IMPL_THUNK(349)IMPL_THUNK(350)IMPL_THUNK(351)IMPL_THUNK(352)IMPL_THUNK(353)IMPL_THUNK(354)IMPL_THUNK(355)IMPL_THUNK(356)IMPL_THUNK(357)IMPL_THUNK(358)IMPL_THUNK(359)IMPL_THUNK(360)IMPL_THUNK(361)IMPL_THUNK(362)IMPL_THUNK(363)IMPL_THUNK(364)IMPL_THUNK(365)IMPL_THUNK(366)IMPL_THUNK(367)IMPL_THUNK(368)IMPL_THUNK(369)IMPL_THUNK(370)IMPL_THUNK(371)IMPL_THUNK(372)IMPL_THUNK(373)IMPL_THUNK(374)IMPL_THUNK(375)IMPL_THUNK(376)IMPL_THUNK(377)IMPL_THUNK(378)IMPL_THUNK(379)IMPL_THUNK(380)IMPL_THUNK(381)IMPL_THUNK(382)IMPL_THUNK(383)IMPL_THUNK(384)IMPL_THUNK(385)IMPL_THUNK(386)IMPL_THUNK(387)IMPL_THUNK(388)IMPL_THUNK(389)IMPL_THUNK(390)IMPL_THUNK(391)IMPL_THUNK(392)IMPL_THUNK(393)IMPL_THUNK(394)IMPL_THUNK(395)IMPL_THUNK(396)IMPL_THUNK(397)IMPL_THUNK(398)IMPL_THUNK(399)IMPL_THUNK(400)IMPL_THUNK(401)IMPL_THUNK(402)IMPL_THUNK(403)IMPL_THUNK(404)IMPL_THUNK(405)IMPL_THUNK(406)IMPL_THUNK(407)IMPL_THUNK(408)IMPL_THUNK(409)IMPL_THUNK(410)IMPL_THUNK(411)IMPL_THUNK(412)IMPL_THUNK(413)IMPL_THUNK(414)IMPL_THUNK(415)IMPL_THUNK(416)IMPL_THUNK(417)IMPL_THUNK(418)IMPL_THUNK(419)IMPL_THUNK(420)IMPL_THUNK(421)IMPL_THUNK(422)IMPL_THUNK(423)IMPL_THUNK(424)IMPL_THUNK(425)IMPL_THUNK(426)IMPL_THUNK(427)IMPL_THUNK(428)IMPL_THUNK(429)IMPL_THUNK(430)IMPL_THUNK(431)IMPL_THUNK(432)IMPL_THUNK(433)IMPL_THUNK(434)IMPL_THUNK(435)IMPL_THUNK(436)IMPL_THUNK(437)IMPL_THUNK(438)IMPL_THUNK(439)IMPL_THUNK(440)IMPL_THUNK(441)IMPL_THUNK(442)IMPL_THUNK(443)IMPL_THUNK(444)IMPL_THUNK(445)IMPL_THUNK(446)IMPL_THUNK(447)IMPL_THUNK(448)IMPL_THUNK(449)IMPL_THUNK(450)IMPL_THUNK(451)IMPL_THUNK(452)IMPL_THUNK(453)IMPL_THUNK(454)IMPL_THUNK(455)IMPL_THUNK(456)IMPL_THUNK(457)IMPL_THUNK(458)IMPL_THUNK(459)IMPL_THUNK(460)IMPL_THUNK(461)IMPL_THUNK(462)IMPL_THUNK(463)IMPL_THUNK(464)IMPL_THUNK(465)IMPL_THUNK(466)IMPL_THUNK(467)IMPL_THUNK(468)IMPL_THUNK(469)IMPL_THUNK(470)IMPL_THUNK(471)IMPL_THUNK(472)IMPL_THUNK(473)IMPL_THUNK(474)IMPL_THUNK(475)IMPL_THUNK(476)IMPL_THUNK(477)IMPL_THUNK(478)IMPL_THUNK(479)IMPL_THUNK(480)IMPL_THUNK(481)IMPL_THUNK(482)IMPL_THUNK(483)IMPL_THUNK(484)IMPL_THUNK(485)IMPL_THUNK(486)IMPL_THUNK(487)IMPL_THUNK(488)IMPL_THUNK(489)IMPL_THUNK(490)IMPL_THUNK(491)IMPL_THUNK(492)IMPL_THUNK(493)IMPL_THUNK(494)IMPL_THUNK(495)IMPL_THUNK(496)IMPL_THUNK(497)IMPL_THUNK(498)IMPL_THUNK(499)IMPL_THUNK(500)IMPL_THUNK(501)IMPL_THUNK(502)IMPL_THUNK(503)IMPL_THUNK(504)IMPL_THUNK(505)IMPL_THUNK(506)IMPL_THUNK(507)IMPL_THUNK(508)IMPL_THUNK(509)IMPL_THUNK(510)IMPL_THUNK(511)IMPL_THUNK(512)IMPL_THUNK(513)IMPL_THUNK(514)IMPL_THUNK(515)IMPL_THUNK(516)IMPL_THUNK(517)IMPL_THUNK(518)IMPL_THUNK(519)IMPL_THUNK(520)IMPL_THUNK(521)IMPL_THUNK(522)IMPL_THUNK(523)IMPL_THUNK(524)IMPL_THUNK(525)IMPL_THUNK(526)IMPL_THUNK(527)IMPL_THUNK(528)IMPL_THUNK(529)IMPL_THUNK(530)IMPL_THUNK(531)IMPL_THUNK(532)IMPL_THUNK(533)IMPL_THUNK(534)IMPL_THUNK(535)IMPL_THUNK(536)IMPL_THUNK(537)IMPL_THUNK(538)IMPL_THUNK(539)IMPL_THUNK(540)IMPL_THUNK(541)IMPL_THUNK(542)IMPL_THUNK(543)IMPL_THUNK(544)IMPL_THUNK(545)IMPL_THUNK(546)IMPL_THUNK(547)IMPL_THUNK(548)IMPL_THUNK(549)IMPL_THUNK(550)IMPL_THUNK(551)IMPL_THUNK(552)IMPL_THUNK(553)IMPL_THUNK(554)IMPL_THUNK(555)IMPL_THUNK(556)IMPL_THUNK(557)IMPL_THUNK(558)IMPL_THUNK(559)IMPL_THUNK(560)IMPL_THUNK(561)IMPL_THUNK(562)IMPL_THUNK(563)IMPL_THUNK(564)IMPL_THUNK(565)IMPL_THUNK(566)IMPL_THUNK(567)IMPL_THUNK(568)IMPL_THUNK(569)IMPL_THUNK(570)IMPL_THUNK(571)IMPL_THUNK(572)IMPL_THUNK(573)IMPL_THUNK(574)IMPL_THUNK(575)IMPL_THUNK(576)IMPL_THUNK(577)IMPL_THUNK(578)IMPL_THUNK(579)IMPL_THUNK(580)IMPL_THUNK(581)IMPL_THUNK(582)IMPL_THUNK(583)IMPL_THUNK(584)IMPL_THUNK(585)IMPL_THUNK(586)IMPL_THUNK(587)IMPL_THUNK(588)IMPL_THUNK(589)IMPL_THUNK(590)IMPL_THUNK(591)IMPL_THUNK(592)IMPL_THUNK(593)IMPL_THUNK(594)IMPL_THUNK(595)IMPL_THUNK(596)IMPL_THUNK(597)IMPL_THUNK(598)IMPL_THUNK(599)IMPL_THUNK(600)IMPL_THUNK(601)IMPL_THUNK(602)IMPL_THUNK(603)IMPL_THUNK(604)IMPL_THUNK(605)IMPL_THUNK(606)IMPL_THUNK(607)IMPL_THUNK(608)IMPL_THUNK(609)IMPL_THUNK(610)IMPL_THUNK(611)IMPL_THUNK(612)IMPL_THUNK(613)IMPL_THUNK(614)IMPL_THUNK(615)IMPL_THUNK(616)IMPL_THUNK(617)IMPL_THUNK(618)IMPL_THUNK(619)IMPL_THUNK(620)IMPL_THUNK(621)IMPL_THUNK(622)IMPL_THUNK(623)IMPL_THUNK(624)IMPL_THUNK(625)IMPL_THUNK(626)IMPL_THUNK(627)IMPL_THUNK(628)IMPL_THUNK(629)IMPL_THUNK(630)IMPL_THUNK(631)IMPL_THUNK(632)IMPL_THUNK(633)IMPL_THUNK(634)IMPL_THUNK(635)IMPL_THUNK(636)IMPL_THUNK(637)IMPL_THUNK(638)IMPL_THUNK(639)IMPL_THUNK(640)IMPL_THUNK(641)IMPL_THUNK(642)IMPL_THUNK(643)IMPL_THUNK(644)IMPL_THUNK(645)IMPL_THUNK(646)IMPL_THUNK(647)IMPL_THUNK(648)IMPL_THUNK(649)IMPL_THUNK(650)IMPL_THUNK(651)IMPL_THUNK(652)IMPL_THUNK(653)IMPL_THUNK(654)IMPL_THUNK(655)IMPL_THUNK(656)IMPL_THUNK(657)IMPL_THUNK(658)IMPL_THUNK(659)IMPL_THUNK(660)IMPL_THUNK(661)IMPL_THUNK(662)IMPL_THUNK(663)IMPL_THUNK(664)IMPL_THUNK(665)IMPL_THUNK(666)IMPL_THUNK(667)IMPL_THUNK(668)IMPL_THUNK(669)IMPL_THUNK(670)IMPL_THUNK(671)IMPL_THUNK(672)IMPL_THUNK(673)IMPL_THUNK(674)IMPL_THUNK(675)IMPL_THUNK(676)IMPL_THUNK(677)IMPL_THUNK(678)IMPL_THUNK(679)IMPL_THUNK(680)IMPL_THUNK(681)IMPL_THUNK(682)IMPL_THUNK(683)IMPL_THUNK(684)IMPL_THUNK(685)IMPL_THUNK(686)IMPL_THUNK(687)IMPL_THUNK(688)IMPL_THUNK(689)IMPL_THUNK(690)IMPL_THUNK(691)IMPL_THUNK(692)IMPL_THUNK(693)IMPL_THUNK(694)IMPL_THUNK(695)IMPL_THUNK(696)IMPL_THUNK(697)IMPL_THUNK(698)IMPL_THUNK(699)IMPL_THUNK(700)IMPL_THUNK(701)IMPL_THUNK(702)IMPL_THUNK(703)IMPL_THUNK(704)IMPL_THUNK(705)IMPL_THUNK(706)IMPL_THUNK(707)IMPL_THUNK(708)IMPL_THUNK(709)IMPL_THUNK(710)IMPL_THUNK(711)IMPL_THUNK(712)IMPL_THUNK(713)IMPL_THUNK(714)IMPL_THUNK(715)IMPL_THUNK(716)IMPL_THUNK(717)IMPL_THUNK(718)IMPL_THUNK(719)IMPL_THUNK(720)IMPL_THUNK(721)IMPL_THUNK(722)IMPL_THUNK(723)IMPL_THUNK(724)IMPL_THUNK(725)IMPL_THUNK(726)IMPL_THUNK(727)IMPL_THUNK(728)IMPL_THUNK(729)IMPL_THUNK(730)IMPL_THUNK(731)IMPL_THUNK(732)IMPL_THUNK(733)IMPL_THUNK(734)IMPL_THUNK(735)IMPL_THUNK(736)IMPL_THUNK(737)IMPL_THUNK(738)IMPL_THUNK(739)IMPL_THUNK(740)IMPL_THUNK(741)IMPL_THUNK(742)IMPL_THUNK(743)IMPL_THUNK(744)IMPL_THUNK(745)IMPL_THUNK(746)IMPL_THUNK(747)IMPL_THUNK(748)IMPL_THUNK(749)IMPL_THUNK(750)IMPL_THUNK(751)IMPL_THUNK(752)IMPL_THUNK(753)IMPL_THUNK(754)IMPL_THUNK(755)IMPL_THUNK(756)IMPL_THUNK(757)IMPL_THUNK(758)IMPL_THUNK(759)IMPL_THUNK(760)IMPL_THUNK(761)IMPL_THUNK(762)IMPL_THUNK(763)IMPL_THUNK(764)IMPL_THUNK(765)IMPL_THUNK(766)IMPL_THUNK(767)IMPL_THUNK(768)IMPL_THUNK(769)IMPL_THUNK(770)IMPL_THUNK(771)IMPL_THUNK(772)IMPL_THUNK(773)IMPL_THUNK(774)IMPL_THUNK(775)IMPL_THUNK(776)IMPL_THUNK(777)IMPL_THUNK(778)IMPL_THUNK(779)IMPL_THUNK(780)IMPL_THUNK(781)IMPL_THUNK(782)IMPL_THUNK(783)IMPL_THUNK(784)IMPL_THUNK(785)IMPL_THUNK(786)IMPL_THUNK(787)IMPL_THUNK(788)IMPL_THUNK(789)IMPL_THUNK(790)IMPL_THUNK(791)IMPL_THUNK(792)IMPL_THUNK(793)IMPL_THUNK(794)IMPL_THUNK(795)IMPL_THUNK(796)IMPL_THUNK(797)IMPL_THUNK(798)IMPL_THUNK(799)IMPL_THUNK(800)IMPL_THUNK(801)IMPL_THUNK(802)IMPL_THUNK(803)IMPL_THUNK(804)IMPL_THUNK(805)IMPL_THUNK(806)IMPL_THUNK(807)IMPL_THUNK(808)IMPL_THUNK(809)IMPL_THUNK(810)IMPL_THUNK(811)IMPL_THUNK(812)IMPL_THUNK(813)IMPL_THUNK(814)IMPL_THUNK(815)IMPL_THUNK(816)IMPL_THUNK(817)IMPL_THUNK(818)IMPL_THUNK(819)IMPL_THUNK(820)IMPL_THUNK(821)IMPL_THUNK(822)IMPL_THUNK(823)IMPL_THUNK(824)IMPL_THUNK(825)IMPL_THUNK(826)IMPL_THUNK(827)IMPL_THUNK(828)IMPL_THUNK(829)IMPL_THUNK(830)IMPL_THUNK(831)IMPL_THUNK(832)IMPL_THUNK(833)IMPL_THUNK(834)IMPL_THUNK(835)IMPL_THUNK(836)IMPL_THUNK(837)IMPL_THUNK(838)IMPL_THUNK(839)IMPL_THUNK(840)IMPL_THUNK(841)IMPL_THUNK(842)IMPL_THUNK(843)IMPL_THUNK(844)IMPL_THUNK(845)IMPL_THUNK(846)IMPL_THUNK(847)IMPL_THUNK(848)IMPL_THUNK(849)IMPL_THUNK(850)IMPL_THUNK(851)IMPL_THUNK(852)IMPL_THUNK(853)IMPL_THUNK(854)IMPL_THUNK(855)IMPL_THUNK(856)IMPL_THUNK(857)IMPL_THUNK(858)IMPL_THUNK(859)IMPL_THUNK(860)IMPL_THUNK(861)IMPL_THUNK(862)IMPL_THUNK(863)IMPL_THUNK(864)IMPL_THUNK(865)IMPL_THUNK(866)IMPL_THUNK(867)IMPL_THUNK(868)IMPL_THUNK(869)IMPL_THUNK(870)IMPL_THUNK(871)IMPL_THUNK(872)IMPL_THUNK(873)IMPL_THUNK(874)IMPL_THUNK(875)IMPL_THUNK(876)IMPL_THUNK(877)IMPL_THUNK(878)IMPL_THUNK(879)IMPL_THUNK(880)IMPL_THUNK(881)IMPL_THUNK(882)IMPL_THUNK(883)IMPL_THUNK(884)IMPL_THUNK(885)IMPL_THUNK(886)IMPL_THUNK(887)IMPL_THUNK(888)IMPL_THUNK(889)IMPL_THUNK(890)IMPL_THUNK(891)IMPL_THUNK(892)IMPL_THUNK(893)IMPL_THUNK(894)IMPL_THUNK(895)IMPL_THUNK(896)IMPL_THUNK(897)IMPL_THUNK(898)IMPL_THUNK(899)IMPL_THUNK(900)IMPL_THUNK(901)IMPL_THUNK(902)IMPL_THUNK(903)IMPL_THUNK(904)IMPL_THUNK(905)IMPL_THUNK(906)IMPL_THUNK(907)IMPL_THUNK(908)IMPL_THUNK(909)IMPL_THUNK(910)IMPL_THUNK(911)IMPL_THUNK(912)IMPL_THUNK(913)IMPL_THUNK(914)IMPL_THUNK(915)IMPL_THUNK(916)IMPL_THUNK(917)IMPL_THUNK(918)IMPL_THUNK(919)IMPL_THUNK(920)IMPL_THUNK(921)IMPL_THUNK(922)IMPL_THUNK(923)IMPL_THUNK(924)IMPL_THUNK(925)IMPL_THUNK(926)IMPL_THUNK(927)IMPL_THUNK(928)IMPL_THUNK(929)IMPL_THUNK(930)IMPL_THUNK(931)IMPL_THUNK(932)IMPL_THUNK(933)IMPL_THUNK(934)IMPL_THUNK(935)IMPL_THUNK(936)IMPL_THUNK(937)IMPL_THUNK(938)IMPL_THUNK(939)IMPL_THUNK(940)IMPL_THUNK(941)IMPL_THUNK(942)IMPL_THUNK(943)IMPL_THUNK(944)IMPL_THUNK(945)IMPL_THUNK(946)IMPL_THUNK(947)IMPL_THUNK(948)IMPL_THUNK(949)IMPL_THUNK(950)IMPL_THUNK(951)IMPL_THUNK(952)IMPL_THUNK(953)IMPL_THUNK(954)IMPL_THUNK(955)IMPL_THUNK(956)IMPL_THUNK(957)IMPL_THUNK(958)IMPL_THUNK(959)IMPL_THUNK(960)IMPL_THUNK(961)IMPL_THUNK(962)IMPL_THUNK(963)IMPL_THUNK(964)IMPL_THUNK(965)IMPL_THUNK(966)IMPL_THUNK(967)IMPL_THUNK(968)IMPL_THUNK(969)IMPL_THUNK(970)IMPL_THUNK(971)IMPL_THUNK(972)IMPL_THUNK(973)IMPL_THUNK(974)IMPL_THUNK(975)IMPL_THUNK(976)IMPL_THUNK(977)IMPL_THUNK(978)IMPL_THUNK(979)IMPL_THUNK(980)IMPL_THUNK(981)IMPL_THUNK(982)IMPL_THUNK(983)IMPL_THUNK(984)IMPL_THUNK(985)IMPL_THUNK(986)IMPL_THUNK(987)IMPL_THUNK(988)IMPL_THUNK(989)IMPL_THUNK(990)IMPL_THUNK(991)IMPL_THUNK(992)IMPL_THUNK(993)IMPL_THUNK(994)IMPL_THUNK(995)IMPL_THUNK(996)IMPL_THUNK(997)IMPL_THUNK(998)IMPL_THUNK(999)IMPL_THUNK(1000)IMPL_THUNK(1001)IMPL_THUNK(1002)IMPL_THUNK(1003)IMPL_THUNK(1004)IMPL_THUNK(1005)IMPL_THUNK(1006)IMPL_THUNK(1007)IMPL_THUNK(1008)IMPL_THUNK(1009)IMPL_THUNK(1010)IMPL_THUNK(1011)IMPL_THUNK(1012)IMPL_THUNK(1013)IMPL_THUNK(1014)IMPL_THUNK(1015)IMPL_THUNK(1016)IMPL_THUNK(1017)IMPL_THUNK(1018)IMPL_THUNK(1019)IMPL_THUNK(1020)IMPL_THUNK(1021)IMPL_THUNK(1022)IMPL_THUNK(1023)IMPL_THUNK(1024)#endif__declspec(selectany) GUID CComModule::m_libid = {0x0,0x0,0x0,{0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0}};#ifdef _ATL_STATIC_REGISTRY#define UpdateRegistryFromResource UpdateRegistryFromResourceS#else#define UpdateRegistryFromResource UpdateRegistryFromResourceD#endif/////////////////////////////////////////////////////////////////////////////////////////////// Thread Pooling classesclass _AtlAptCreateObjData{public:_ATL_CREATORFUNC* pfnCreateInstance;const IID* piid;HANDLE hEvent;LPSTREAM pStream;HRESULT hRes;};class CComApartment{public:CComApartment(){m_nLockCnt = 0;}static UINT ATL_CREATE_OBJECT;static DWORD WINAPI _Apartment(void* pv){return ((CComApartment*)pv)->Apartment();}DWORD Apartment(){CoInitialize(NULL);MSG msg;while(GetMessage(&msg, 0, 0, 0)){if (msg.message == ATL_CREATE_OBJECT){_AtlAptCreateObjData* pdata = (_AtlAptCreateObjData*)msg.lParam;IUnknown* pUnk = NULL;pdata->hRes = pdata->pfnCreateInstance(NULL, IID_IUnknown, (void**)&pUnk);if (SUCCEEDED(pdata->hRes))pdata->hRes = CoMarshalInterThreadInterfaceInStream(*pdata->piid, pUnk, &pdata->pStream);if (SUCCEEDED(pdata->hRes)){pUnk->Release();ATLTRACE2(atlTraceCOM, 2, _T("Object created on thread = %d\n"), GetCurrentThreadId());}SetEvent(pdata->hEvent);}DispatchMessage(&msg);}CoUninitialize();return 0;}LONG Lock() {return CComGlobalsThreadModel::Increment(&m_nLockCnt);}LONG Unlock(){return CComGlobalsThreadModel::Decrement(&m_nLockCnt);}LONG GetLockCount() {return m_nLockCnt;}DWORD m_dwThreadID;HANDLE m_hThread;LONG m_nLockCnt;};__declspec(selectany) UINT CComApartment::ATL_CREATE_OBJECT = 0;class CComSimpleThreadAllocator{public:CComSimpleThreadAllocator(){m_nThread = 0;}int GetThread(CComApartment* /*pApt*/, int nThreads){if (++m_nThread == nThreads)m_nThread = 0;return m_nThread;}int m_nThread;};template <class ThreadAllocator = CComSimpleThreadAllocator>class CComAutoThreadModule : public CComModule{public:HRESULT Init(_ATL_OBJMAP_ENTRY* p, HINSTANCE h, const GUID* plibid = NULL, int nThreads = GetDefaultThreads());~CComAutoThreadModule();HRESULT CreateInstance(void* pfnCreateInstance, REFIID riid, void** ppvObj);LONG Lock();LONG Unlock();DWORD dwThreadID;int m_nThreads;CComApartment* m_pApartments;ThreadAllocator m_Allocator;static int GetDefaultThreads(){SYSTEM_INFO si;GetSystemInfo(&si);return si.dwNumberOfProcessors * 4;}};/////////////////////////////////////////////////////////////////////////////// CComBSTRclass CComBSTR{public:BSTR m_str;CComBSTR(){m_str = NULL;}/*explicit*/ CComBSTR(int nSize){m_str = ::SysAllocStringLen(NULL, nSize);}/*explicit*/ CComBSTR(int nSize, LPCOLESTR sz){m_str = ::SysAllocStringLen(sz, nSize);}/*explicit*/ CComBSTR(LPCOLESTR pSrc){m_str = ::SysAllocString(pSrc);}/*explicit*/ CComBSTR(const CComBSTR& src){m_str = src.Copy();}/*explicit*/ CComBSTR(REFGUID src){LPOLESTR szGuid;StringFromCLSID(src, &szGuid);m_str = ::SysAllocString(szGuid);CoTaskMemFree(szGuid);}CComBSTR& operator=(const CComBSTR& src){if (m_str != src.m_str){if (m_str)::SysFreeString(m_str);m_str = src.Copy();}return *this;}CComBSTR& operator=(LPCOLESTR pSrc){::SysFreeString(m_str);m_str = ::SysAllocString(pSrc);return *this;}~CComBSTR(){::SysFreeString(m_str);}unsigned int Length() const{return (m_str == NULL)? 0 : SysStringLen(m_str);}operator BSTR() const{return m_str;}BSTR* operator&(){return &m_str;}BSTR Copy() const{return ::SysAllocStringLen(m_str, ::SysStringLen(m_str));}HRESULT CopyTo(BSTR* pbstr){ATLASSERT(pbstr != NULL);if (pbstr == NULL)return E_POINTER;*pbstr = ::SysAllocStringLen(m_str, ::SysStringLen(m_str));if (*pbstr == NULL)return E_OUTOFMEMORY;return S_OK;}void Attach(BSTR src){ATLASSERT(m_str == NULL);m_str = src;}BSTR Detach(){BSTR s = m_str;m_str = NULL;return s;}void Empty(){::SysFreeString(m_str);m_str = NULL;}bool operator!() const{return (m_str == NULL);}HRESULT Append(const CComBSTR& bstrSrc){return Append(bstrSrc.m_str, SysStringLen(bstrSrc.m_str));}HRESULT Append(LPCOLESTR lpsz){return Append(lpsz, ocslen(lpsz));}// a BSTR is just a LPCOLESTR so we need a special version to signify// that we are appending a BSTRHRESULT AppendBSTR(BSTR p){return Append(p, SysStringLen(p));}HRESULT Append(LPCOLESTR lpsz, int nLen){int n1 = Length();BSTR b;b = ::SysAllocStringLen(NULL, n1+nLen);if (b == NULL)return E_OUTOFMEMORY;memcpy(b, m_str, n1*sizeof(OLECHAR));memcpy(b+n1, lpsz, nLen*sizeof(OLECHAR));b[n1+nLen] = NULL;SysFreeString(m_str);m_str = b;return S_OK;}HRESULT ToLower(){USES_CONVERSION;if (m_str != NULL){LPTSTR psz = CharLower(OLE2T(m_str));if (psz == NULL)return E_OUTOFMEMORY;BSTR b = T2BSTR(psz);if (psz == NULL)return E_OUTOFMEMORY;SysFreeString(m_str);m_str = b;}return S_OK;}HRESULT ToUpper(){USES_CONVERSION;if (m_str != NULL){LPTSTR psz = CharUpper(OLE2T(m_str));if (psz == NULL)return E_OUTOFMEMORY;BSTR b = T2BSTR(psz);if (psz == NULL)return E_OUTOFMEMORY;SysFreeString(m_str);m_str = b;}return S_OK;}bool LoadString(HINSTANCE hInst, UINT nID){USES_CONVERSION;TCHAR sz[512];UINT nLen = ::LoadString(hInst, nID, sz, 512);ATLASSERT(nLen < 511);SysFreeString(m_str);m_str = (nLen != 0) ? SysAllocString(T2OLE(sz)) : NULL;return (nLen != 0);}bool LoadString(UINT nID){return LoadString(_pModule->m_hInstResource, nID);}CComBSTR& operator+=(const CComBSTR& bstrSrc){AppendBSTR(bstrSrc.m_str);return *this;}bool operator<(BSTR bstrSrc) const{if (bstrSrc == NULL && m_str == NULL)return false;if (bstrSrc != NULL && m_str != NULL)return wcscmp(m_str, bstrSrc) < 0;return m_str == NULL;}bool operator==(BSTR bstrSrc) const{if (bstrSrc == NULL && m_str == NULL)return true;if (bstrSrc != NULL && m_str != NULL)return wcscmp(m_str, bstrSrc) == 0;return false;}bool operator<(LPCSTR pszSrc) const{if (pszSrc == NULL && m_str == NULL)return false;USES_CONVERSION;if (pszSrc != NULL && m_str != NULL)return wcscmp(m_str, A2W(pszSrc)) < 0;return m_str == NULL;}bool operator==(LPCSTR pszSrc) const{if (pszSrc == NULL && m_str == NULL)return true;USES_CONVERSION;if (pszSrc != NULL && m_str != NULL)return wcscmp(m_str, A2W(pszSrc)) == 0;return false;}#ifndef OLE2ANSICComBSTR(LPCSTR pSrc){m_str = A2WBSTR(pSrc);}CComBSTR(int nSize, LPCSTR sz){m_str = A2WBSTR(sz, nSize);}void Append(LPCSTR lpsz){USES_CONVERSION;LPCOLESTR lpo = A2COLE(lpsz);Append(lpo, ocslen(lpo));}CComBSTR& operator=(LPCSTR pSrc){::SysFreeString(m_str);m_str = A2WBSTR(pSrc);return *this;}#endifHRESULT WriteToStream(IStream* pStream){ATLASSERT(pStream != NULL);ULONG cb;ULONG cbStrLen = m_str ? SysStringByteLen(m_str)+sizeof(OLECHAR) : 0;HRESULT hr = pStream->Write((void*) &cbStrLen, sizeof(cbStrLen), &cb);if (FAILED(hr))return hr;return cbStrLen ? pStream->Write((void*) m_str, cbStrLen, &cb) : S_OK;}HRESULT ReadFromStream(IStream* pStream){ATLASSERT(pStream != NULL);ATLASSERT(m_str == NULL); // should be emptyULONG cbStrLen = 0;HRESULT hr = pStream->Read((void*) &cbStrLen, sizeof(cbStrLen), NULL);if ((hr == S_OK) && (cbStrLen != 0)){//subtract size for terminating NULL which we wrote out//since SysAllocStringByteLen overallocates for the NULLm_str = SysAllocStringByteLen(NULL, cbStrLen-sizeof(OLECHAR));if (m_str == NULL)hr = E_OUTOFMEMORY;elsehr = pStream->Read((void*) m_str, cbStrLen, NULL);}if (hr == S_FALSE)hr = E_FAIL;return hr;}};/////////////////////////////////////////////////////////////////////////////// CComVariantclass CComVariant : public tagVARIANT{// Constructorspublic:CComVariant(){vt = VT_EMPTY;}~CComVariant(){Clear();}CComVariant(const VARIANT& varSrc){vt = VT_EMPTY;InternalCopy(&varSrc);}CComVariant(const CComVariant& varSrc){vt = VT_EMPTY;InternalCopy(&varSrc);}CComVariant(BSTR bstrSrc){vt = VT_EMPTY;*this = bstrSrc;}CComVariant(LPCOLESTR lpszSrc){vt = VT_EMPTY;*this = lpszSrc;}#ifndef OLE2ANSICComVariant(LPCSTR lpszSrc){vt = VT_EMPTY;*this = lpszSrc;}#endifCComVariant(bool bSrc){vt = VT_BOOL;#pragma warning(disable: 4310) // cast truncates constant valueboolVal = bSrc ? VARIANT_TRUE : VARIANT_FALSE;#pragma warning(default: 4310) // cast truncates constant value}CComVariant(int nSrc){vt = VT_I4;lVal = nSrc;}CComVariant(BYTE nSrc){vt = VT_UI1;bVal = nSrc;}CComVariant(short nSrc){vt = VT_I2;iVal = nSrc;}CComVariant(long nSrc, VARTYPE vtSrc = VT_I4){ATLASSERT(vtSrc == VT_I4 || vtSrc == VT_ERROR);vt = vtSrc;lVal = nSrc;}CComVariant(float fltSrc){vt = VT_R4;fltVal = fltSrc;}CComVariant(double dblSrc){vt = VT_R8;dblVal = dblSrc;}CComVariant(CY cySrc){vt = VT_CY;cyVal.Hi = cySrc.Hi;cyVal.Lo = cySrc.Lo;}CComVariant(IDispatch* pSrc){vt = VT_DISPATCH;pdispVal = pSrc;// Need to AddRef as VariantClear will Releaseif (pdispVal != NULL)pdispVal->AddRef();}CComVariant(IUnknown* pSrc){vt = VT_UNKNOWN;punkVal = pSrc;// Need to AddRef as VariantClear will Releaseif (punkVal != NULL)punkVal->AddRef();}// Assignment Operatorspublic:CComVariant& operator=(const CComVariant& varSrc){InternalCopy(&varSrc);return *this;}CComVariant& operator=(const VARIANT& varSrc){InternalCopy(&varSrc);return *this;}CComVariant& operator=(BSTR bstrSrc){InternalClear();vt = VT_BSTR;bstrVal = ::SysAllocString(bstrSrc);if (bstrVal == NULL && bstrSrc != NULL){vt = VT_ERROR;scode = E_OUTOFMEMORY;}return *this;}CComVariant& operator=(LPCOLESTR lpszSrc){InternalClear();vt = VT_BSTR;bstrVal = ::SysAllocString(lpszSrc);if (bstrVal == NULL && lpszSrc != NULL){vt = VT_ERROR;scode = E_OUTOFMEMORY;}return *this;}#ifndef OLE2ANSICComVariant& operator=(LPCSTR lpszSrc){USES_CONVERSION;InternalClear();vt = VT_BSTR;bstrVal = ::SysAllocString(A2COLE(lpszSrc));if (bstrVal == NULL && lpszSrc != NULL){vt = VT_ERROR;scode = E_OUTOFMEMORY;}return *this;}#endifCComVariant& operator=(bool bSrc){if (vt != VT_BOOL){InternalClear();vt = VT_BOOL;}#pragma warning(disable: 4310) // cast truncates constant valueboolVal = bSrc ? VARIANT_TRUE : VARIANT_FALSE;#pragma warning(default: 4310) // cast truncates constant valuereturn *this;}CComVariant& operator=(int nSrc){if (vt != VT_I4){InternalClear();vt = VT_I4;}lVal = nSrc;return *this;}CComVariant& operator=(BYTE nSrc){if (vt != VT_UI1){InternalClear();vt = VT_UI1;}bVal = nSrc;return *this;}CComVariant& operator=(short nSrc){if (vt != VT_I2){InternalClear();vt = VT_I2;}iVal = nSrc;return *this;}CComVariant& operator=(long nSrc){if (vt != VT_I4){InternalClear();vt = VT_I4;}lVal = nSrc;return *this;}CComVariant& operator=(float fltSrc){if (vt != VT_R4){InternalClear();vt = VT_R4;}fltVal = fltSrc;return *this;}CComVariant& operator=(double dblSrc){if (vt != VT_R8){InternalClear();vt = VT_R8;}dblVal = dblSrc;return *this;}CComVariant& operator=(CY cySrc){if (vt != VT_CY){InternalClear();vt = VT_CY;}cyVal.Hi = cySrc.Hi;cyVal.Lo = cySrc.Lo;return *this;}CComVariant& operator=(IDispatch* pSrc){InternalClear();vt = VT_DISPATCH;pdispVal = pSrc;// Need to AddRef as VariantClear will Releaseif (pdispVal != NULL)pdispVal->AddRef();return *this;}CComVariant& operator=(IUnknown* pSrc){InternalClear();vt = VT_UNKNOWN;punkVal = pSrc;// Need to AddRef as VariantClear will Releaseif (punkVal != NULL)punkVal->AddRef();return *this;}// Comparison Operatorspublic:bool operator==(const VARIANT& varSrc) const{if (this == &varSrc)return true;// Variants not equal if types don't matchif (vt != varSrc.vt)return false;// Check type specific valuesswitch (vt){case VT_EMPTY:case VT_NULL:return true;case VT_BOOL:return boolVal == varSrc.boolVal;case VT_UI1:return bVal == varSrc.bVal;case VT_I2:return iVal == varSrc.iVal;case VT_I4:return lVal == varSrc.lVal;case VT_R4:return fltVal == varSrc.fltVal;case VT_R8:return dblVal == varSrc.dblVal;case VT_BSTR:return (::SysStringByteLen(bstrVal) == ::SysStringByteLen(varSrc.bstrVal)) &&(::memcmp(bstrVal, varSrc.bstrVal, ::SysStringByteLen(bstrVal)) == 0);case VT_ERROR:return scode == varSrc.scode;case VT_DISPATCH:return pdispVal == varSrc.pdispVal;case VT_UNKNOWN:return punkVal == varSrc.punkVal;default:ATLASSERT(false);// fall through}return false;}bool operator!=(const VARIANT& varSrc) const {return !operator==(varSrc);}bool operator<(const VARIANT& varSrc) const {return VarCmp((VARIANT*)this, (VARIANT*)&varSrc, LOCALE_USER_DEFAULT, 0)==VARCMP_LT;}bool operator>(const VARIANT& varSrc) const {return VarCmp((VARIANT*)this, (VARIANT*)&varSrc, LOCALE_USER_DEFAULT, 0)==VARCMP_GT;}// Operationspublic:HRESULT Clear() { return ::VariantClear(this); }HRESULT Copy(const VARIANT* pSrc) { return ::VariantCopy(this, const_cast<VARIANT*>(pSrc)); }HRESULT Attach(VARIANT* pSrc){// Clear out the variantHRESULT hr = Clear();if (!FAILED(hr)){// Copy the contents and give control to CComVariantmemcpy(this, pSrc, sizeof(VARIANT));pSrc->vt = VT_EMPTY;hr = S_OK;}return hr;}HRESULT Detach(VARIANT* pDest){// Clear out the variantHRESULT hr = ::VariantClear(pDest);if (!FAILED(hr)){// Copy the contents and remove control from CComVariantmemcpy(pDest, this, sizeof(VARIANT));vt = VT_EMPTY;hr = S_OK;}return hr;}HRESULT ChangeType(VARTYPE vtNew, const VARIANT* pSrc = NULL){VARIANT* pVar = const_cast<VARIANT*>(pSrc);// Convert in place if pSrc is NULLif (pVar == NULL)pVar = this;// Do nothing if doing in place convert and vts not differentreturn ::VariantChangeType(this, pVar, 0, vtNew);}HRESULT WriteToStream(IStream* pStream);HRESULT ReadFromStream(IStream* pStream);// Implementationpublic:HRESULT InternalClear(){HRESULT hr = Clear();ATLASSERT(SUCCEEDED(hr));if (FAILED(hr)){vt = VT_ERROR;scode = hr;}return hr;}void InternalCopy(const VARIANT* pSrc){HRESULT hr = Copy(pSrc);if (FAILED(hr)){vt = VT_ERROR;scode = hr;}}};inline HRESULT CComVariant::WriteToStream(IStream* pStream){HRESULT hr = pStream->Write(&vt, sizeof(VARTYPE), NULL);if (FAILED(hr))return hr;int cbWrite = 0;switch (vt){case VT_UNKNOWN:case VT_DISPATCH:{CComPtr<IPersistStream> spStream;if (punkVal != NULL){hr = punkVal->QueryInterface(IID_IPersistStream, (void**)&spStream);if (FAILED(hr))return hr;}if (spStream != NULL)return OleSaveToStream(spStream, pStream);elsereturn WriteClassStm(pStream, CLSID_NULL);}case VT_UI1:case VT_I1:cbWrite = sizeof(BYTE);break;case VT_I2:case VT_UI2:case VT_BOOL:cbWrite = sizeof(short);break;case VT_I4:case VT_UI4:case VT_R4:case VT_INT:case VT_UINT:case VT_ERROR:cbWrite = sizeof(long);break;case VT_R8:case VT_CY:case VT_DATE:cbWrite = sizeof(double);break;default:break;}if (cbWrite != 0)return pStream->Write((void*) &bVal, cbWrite, NULL);CComBSTR bstrWrite;CComVariant varBSTR;if (vt != VT_BSTR){hr = VariantChangeType(&varBSTR, this, VARIANT_NOVALUEPROP, VT_BSTR);if (FAILED(hr))return hr;bstrWrite = varBSTR.bstrVal;}elsebstrWrite = bstrVal;return bstrWrite.WriteToStream(pStream);}inline HRESULT CComVariant::ReadFromStream(IStream* pStream){ATLASSERT(pStream != NULL);HRESULT hr;hr = VariantClear(this);if (FAILED(hr))return hr;VARTYPE vtRead;hr = pStream->Read(&vtRead, sizeof(VARTYPE), NULL);if (hr == S_FALSE)hr = E_FAIL;if (FAILED(hr))return hr;vt = vtRead;int cbRead = 0;switch (vtRead){case VT_UNKNOWN:case VT_DISPATCH:{punkVal = NULL;hr = OleLoadFromStream(pStream,(vtRead == VT_UNKNOWN) ? IID_IUnknown : IID_IDispatch,(void**)&punkVal);if (hr == REGDB_E_CLASSNOTREG)hr = S_OK;return S_OK;}case VT_UI1:case VT_I1:cbRead = sizeof(BYTE);break;case VT_I2:case VT_UI2:case VT_BOOL:cbRead = sizeof(short);break;case VT_I4:case VT_UI4:case VT_R4:case VT_INT:case VT_UINT:case VT_ERROR:cbRead = sizeof(long);break;case VT_R8:case VT_CY:case VT_DATE:cbRead = sizeof(double);break;default:break;}if (cbRead != 0){hr = pStream->Read((void*) &bVal, cbRead, NULL);if (hr == S_FALSE)hr = E_FAIL;return hr;}CComBSTR bstrRead;hr = bstrRead.ReadFromStream(pStream);if (FAILED(hr))return hr;vt = VT_BSTR;bstrVal = bstrRead.Detach();if (vtRead != VT_BSTR)hr = ChangeType(vtRead);return hr;}/////////////////////////////////////////////////////////////////////////////// CRegKeyclass CRegKey{public:CRegKey();~CRegKey();// Attributespublic:operator HKEY() const;HKEY m_hKey;// Operationspublic:LONG SetValue(DWORD dwValue, LPCTSTR lpszValueName);LONG QueryValue(DWORD& dwValue, LPCTSTR lpszValueName);LONG QueryValue(LPTSTR szValue, LPCTSTR lpszValueName, DWORD* pdwCount);LONG SetValue(LPCTSTR lpszValue, LPCTSTR lpszValueName = NULL);LONG SetKeyValue(LPCTSTR lpszKeyName, LPCTSTR lpszValue, LPCTSTR lpszValueName = NULL);static LONG WINAPI SetValue(HKEY hKeyParent, LPCTSTR lpszKeyName,LPCTSTR lpszValue, LPCTSTR lpszValueName = NULL);LONG Create(HKEY hKeyParent, LPCTSTR lpszKeyName,LPTSTR lpszClass = REG_NONE, DWORD dwOptions = REG_OPTION_NON_VOLATILE,REGSAM samDesired = KEY_ALL_ACCESS,LPSECURITY_ATTRIBUTES lpSecAttr = NULL,LPDWORD lpdwDisposition = NULL);LONG Open(HKEY hKeyParent, LPCTSTR lpszKeyName,REGSAM samDesired = KEY_ALL_ACCESS);LONG Close();HKEY Detach();void Attach(HKEY hKey);LONG DeleteSubKey(LPCTSTR lpszSubKey);LONG RecurseDeleteKey(LPCTSTR lpszKey);LONG DeleteValue(LPCTSTR lpszValue);};inline CRegKey::CRegKey(){m_hKey = NULL;}inline CRegKey::~CRegKey(){Close();}inline CRegKey::operator HKEY() const{return m_hKey;}inline HKEY CRegKey::Detach(){HKEY hKey = m_hKey;m_hKey = NULL;return hKey;}inline void CRegKey::Attach(HKEY hKey){ATLASSERT(m_hKey == NULL);m_hKey = hKey;}inline LONG CRegKey::DeleteSubKey(LPCTSTR lpszSubKey){ATLASSERT(m_hKey != NULL);return RegDeleteKey(m_hKey, lpszSubKey);}inline LONG CRegKey::DeleteValue(LPCTSTR lpszValue){ATLASSERT(m_hKey != NULL);return RegDeleteValue(m_hKey, (LPTSTR)lpszValue);}inline LONG CRegKey::Close(){LONG lRes = ERROR_SUCCESS;if (m_hKey != NULL){lRes = RegCloseKey(m_hKey);m_hKey = NULL;}return lRes;}inline LONG CRegKey::Create(HKEY hKeyParent, LPCTSTR lpszKeyName,LPTSTR lpszClass, DWORD dwOptions, REGSAM samDesired,LPSECURITY_ATTRIBUTES lpSecAttr, LPDWORD lpdwDisposition){ATLASSERT(hKeyParent != NULL);DWORD dw;HKEY hKey = NULL;LONG lRes = RegCreateKeyEx(hKeyParent, lpszKeyName, 0,lpszClass, dwOptions, samDesired, lpSecAttr, &hKey, &dw);if (lpdwDisposition != NULL)*lpdwDisposition = dw;if (lRes == ERROR_SUCCESS){lRes = Close();m_hKey = hKey;}return lRes;}inline LONG CRegKey::Open(HKEY hKeyParent, LPCTSTR lpszKeyName, REGSAM samDesired){ATLASSERT(hKeyParent != NULL);HKEY hKey = NULL;LONG lRes = RegOpenKeyEx(hKeyParent, lpszKeyName, 0, samDesired, &hKey);if (lRes == ERROR_SUCCESS){lRes = Close();ATLASSERT(lRes == ERROR_SUCCESS);m_hKey = hKey;}return lRes;}inline LONG CRegKey::QueryValue(DWORD& dwValue, LPCTSTR lpszValueName){DWORD dwType = NULL;DWORD dwCount = sizeof(DWORD);LONG lRes = RegQueryValueEx(m_hKey, (LPTSTR)lpszValueName, NULL, &dwType,(LPBYTE)&dwValue, &dwCount);ATLASSERT((lRes!=ERROR_SUCCESS) || (dwType == REG_DWORD));ATLASSERT((lRes!=ERROR_SUCCESS) || (dwCount == sizeof(DWORD)));return lRes;}inline LONG CRegKey::QueryValue(LPTSTR szValue, LPCTSTR lpszValueName, DWORD* pdwCount){ATLASSERT(pdwCount != NULL);DWORD dwType = NULL;LONG lRes = RegQueryValueEx(m_hKey, (LPTSTR)lpszValueName, NULL, &dwType,(LPBYTE)szValue, pdwCount);ATLASSERT((lRes!=ERROR_SUCCESS) || (dwType == REG_SZ) || (dwType == REG_MULTI_SZ) || (dwType == REG_EXPAND_SZ));return lRes;}inline LONG WINAPI CRegKey::SetValue(HKEY hKeyParent, LPCTSTR lpszKeyName, LPCTSTR lpszValue, LPCTSTR lpszValueName){ATLASSERT(lpszValue != NULL);CRegKey key;LONG lRes = key.Create(hKeyParent, lpszKeyName);if (lRes == ERROR_SUCCESS)lRes = key.SetValue(lpszValue, lpszValueName);return lRes;}inline LONG CRegKey::SetKeyValue(LPCTSTR lpszKeyName, LPCTSTR lpszValue, LPCTSTR lpszValueName){ATLASSERT(lpszValue != NULL);CRegKey key;LONG lRes = key.Create(m_hKey, lpszKeyName);if (lRes == ERROR_SUCCESS)lRes = key.SetValue(lpszValue, lpszValueName);return lRes;}inline LONG CRegKey::SetValue(DWORD dwValue, LPCTSTR lpszValueName){ATLASSERT(m_hKey != NULL);return RegSetValueEx(m_hKey, lpszValueName, NULL, REG_DWORD,(BYTE * const)&dwValue, sizeof(DWORD));}inline LONG CRegKey::SetValue(LPCTSTR lpszValue, LPCTSTR lpszValueName){ATLASSERT(lpszValue != NULL);ATLASSERT(m_hKey != NULL);return RegSetValueEx(m_hKey, lpszValueName, NULL, REG_SZ,(BYTE * const)lpszValue, (lstrlen(lpszValue)+1)*sizeof(TCHAR));}inline LONG CRegKey::RecurseDeleteKey(LPCTSTR lpszKey){CRegKey key;LONG lRes = key.Open(m_hKey, lpszKey, KEY_READ | KEY_WRITE);if (lRes != ERROR_SUCCESS)return lRes;FILETIME time;DWORD dwSize = 256;TCHAR szBuffer[256];while (RegEnumKeyEx(key.m_hKey, 0, szBuffer, &dwSize, NULL, NULL, NULL,&time)==ERROR_SUCCESS){lRes = key.RecurseDeleteKey(szBuffer);if (lRes != ERROR_SUCCESS)return lRes;dwSize = 256;}key.Close();return DeleteSubKey(lpszKey);}inline HRESULT CComModule::RegisterProgID(LPCTSTR lpszCLSID, LPCTSTR lpszProgID, LPCTSTR lpszUserDesc){CRegKey keyProgID;LONG lRes = keyProgID.Create(HKEY_CLASSES_ROOT, lpszProgID, REG_NONE, REG_OPTION_NON_VOLATILE, KEY_SET_VALUE);if (lRes == ERROR_SUCCESS){keyProgID.SetValue(lpszUserDesc);keyProgID.SetKeyValue(_T("CLSID"), lpszCLSID);return S_OK;}return HRESULT_FROM_WIN32(lRes);}#ifdef _ATL_STATIC_REGISTRY#include <statreg.h>// Statically linking to Registry Ponentinline HRESULT WINAPI CComModule::UpdateRegistryFromResourceS(UINT nResID, BOOL bRegister,struct _ATL_REGMAP_ENTRY* pMapEntries){USES_CONVERSION;ATL::CRegObject ro;TCHAR szModule[_MAX_PATH];GetModuleFileName(_pModule->GetModuleInstance(), szModule, _MAX_PATH);LPOLESTR pszModule;if ((m_hInst == NULL) || (m_hInst == GetModuleHandle(NULL))) // register as EXE{// Convert to short path to work around bug in NT4's CreateProcessTCHAR szModuleShort[_MAX_PATH];int cbShortName = GetShortPathName(szModule, szModuleShort, _MAX_PATH);if (cbShortName == _MAX_PATH)return E_OUTOFMEMORY;pszModule = (cbShortName == 0 || cbShortName == ERROR_INVALID_PARAMETER) ? T2OLE(szModule) : T2OLE(szModuleShort);}elsepszModule = T2OLE(szModule);int nLen = ocslen(pszModule);LPOLESTR pszModuleQuote = (LPOLESTR)alloca((nLen*2+1)*sizeof(OLECHAR));ReplaceSingleQuote(pszModuleQuote, pszModule);ro.AddReplacement(OLESTR("Module"), pszModuleQuote);if (NULL != pMapEntries){while (NULL != pMapEntries->szKey){ATLASSERT(NULL != pMapEntries->szData);ro.AddReplacement(pMapEntries->szKey, pMapEntries->szData);pMapEntries++;}}LPCOLESTR szType = OLESTR("REGISTRY");return (bRegister) ? ro.ResourceRegister(pszModule, nResID, szType) :ro.ResourceUnregister(pszModule, nResID, szType);}inline HRESULT WINAPI CComModule::UpdateRegistryFromResourceS(LPCTSTR lpszRes, BOOL bRegister,struct _ATL_REGMAP_ENTRY* pMapEntries){USES_CONVERSION;ATL::CRegObject ro;TCHAR szModule[_MAX_PATH];GetModuleFileName(_pModule->GetModuleInstance(), szModule, _MAX_PATH);LPOLESTR pszModule;if ((m_hInst == NULL) || (m_hInst == GetModuleHandle(NULL))) // register as EXE{// Convert to short path to work around bug in NT4's CreateProcessTCHAR szModuleShort[_MAX_PATH];int cbShortName = GetShortPathName(szModule, szModuleShort, _MAX_PATH);if (cbShortName == _MAX_PATH)return E_OUTOFMEMORY;pszModule = (cbShortName == 0 || cbShortName == ERROR_INVALID_PARAMETER) ? T2OLE(szModule) : T2OLE(szModuleShort);}elsepszModule = T2OLE(szModule);int nLen = ocslen(pszModule);LPOLESTR pszModuleQuote = (LPOLESTR)alloca((nLen*2+1)*sizeof(OLECHAR));ReplaceSingleQuote(pszModuleQuote, pszModule);ro.AddReplacement(OLESTR("Module"), pszModuleQuote);if (NULL != pMapEntries){while (NULL != pMapEntries->szKey){ATLASSERT(NULL != pMapEntries->szData);ro.AddReplacement(pMapEntries->szKey, pMapEntries->szData);pMapEntries++;}}LPCOLESTR szType = OLESTR("REGISTRY");LPCOLESTR pszRes = T2COLE(lpszRes);return (bRegister) ? ro.ResourceRegisterSz(pszModule, pszRes, szType) :ro.ResourceUnregisterSz(pszModule, pszRes, szType);}#endif //_ATL_STATIC_REGISTRYinline HRESULT WINAPI CComModule::UpdateRegistryClass(const CLSID& clsid, LPCTSTR lpszProgID,LPCTSTR lpszVerIndProgID, UINT nDescID, DWORD dwFlags, BOOL bRegister){if (bRegister){return RegisterClassHelper(clsid, lpszProgID, lpszVerIndProgID, nDescID,dwFlags);}elsereturn UnregisterClassHelper(clsid, lpszProgID, lpszVerIndProgID);}inline HRESULT WINAPI CComModule::RegisterClassHelper(const CLSID& clsid, LPCTSTR lpszProgID,LPCTSTR lpszVerIndProgID, UINT nDescID, DWORD dwFlags){static const TCHAR szProgID[] = _T("ProgID");static const TCHAR szVIProgID[] = _T("VersionIndependentProgID");static const TCHAR szLS32[] = _T("LocalServer32");static const TCHAR szIPS32[] = _T("InprocServer32");static const TCHAR szThreadingModel[] = _T("ThreadingModel");static const TCHAR szAUTPRX32[] = _T("AUTPRX32.DLL");static const TCHAR szApartment[] = _T("Apartment");static const TCHAR szBoth[] = _T("both");USES_CONVERSION;HRESULT hRes = S_OK;TCHAR szDesc[256];LoadString(m_hInst, nDescID, szDesc, 256);TCHAR szModule[_MAX_PATH];GetModuleFileName(m_hInst, szModule, _MAX_PATH);LPOLESTR lpOleStr;StringFromCLSID(clsid, &lpOleStr);LPTSTR lpsz = OLE2T(lpOleStr);hRes = RegisterProgID(lpsz, lpszProgID, szDesc);if (hRes == S_OK)hRes = RegisterProgID(lpsz, lpszVerIndProgID, szDesc);LONG lRes = ERROR_SUCCESS;if (hRes == S_OK){CRegKey key;lRes = key.Open(HKEY_CLASSES_ROOT, _T("CLSID"), KEY_READ | KEY_WRITE);if (lRes == ERROR_SUCCESS){lRes = key.Create(key, lpsz, REG_NONE, REG_OPTION_NON_VOLATILE, KEY_READ | KEY_WRITE);if (lRes == ERROR_SUCCESS){key.SetValue(szDesc);key.SetKeyValue(szProgID, lpszProgID);key.SetKeyValue(szVIProgID, lpszVerIndProgID);if ((m_hInst == NULL) || (m_hInst == GetModuleHandle(NULL))) // register as EXE{// Convert to short path to work around bug in NT4's CreateProcessTCHAR szModuleShort[_MAX_PATH];int cbShortName = GetShortPathName(szModule, szModuleShort, _MAX_PATH);TCHAR* pszModule;if (cbShortName == _MAX_PATH)return E_OUTOFMEMORY;pszModule = (cbShortName == 0 || cbShortName == ERROR_INVALID_PARAMETER) ? szModule : szModuleShort;key.SetKeyValue(szLS32, pszModule);}else{key.SetKeyValue(szIPS32, (dwFlags & AUTPRXFLAG) ? szAUTPRX32 : szModule);LPCTSTR lpszModel = (dwFlags & THREADFLAGS_BOTH) ? szBoth :(dwFlags & THREADFLAGS_APARTMENT) ? szApartment : NULL;if (lpszModel != NULL)key.SetKeyValue(szIPS32, lpszModel, szThreadingModel);}}}}CoTaskMemFree(lpOleStr);if (lRes != ERROR_SUCCESS)hRes = HRESULT_FROM_WIN32(lRes);return hRes;}inline HRESULT WINAPI CComModule::UnregisterClassHelper(const CLSID& clsid, LPCTSTR lpszProgID,LPCTSTR lpszVerIndProgID){USES_CONVERSION;CRegKey key;key.Attach(HKEY_CLASSES_ROOT);if (lpszProgID != NULL && lstrcmpi(lpszProgID, _T("")))key.RecurseDeleteKey(lpszProgID);if (lpszVerIndProgID != NULL && lstrcmpi(lpszVerIndProgID, _T("")))key.RecurseDeleteKey(lpszVerIndProgID);LPOLESTR lpOleStr;StringFromCLSID(clsid, &lpOleStr);LPTSTR lpsz = OLE2T(lpOleStr);if (key.Open(key, _T("CLSID"), KEY_READ | KEY_WRITE) == ERROR_SUCCESS)key.RecurseDeleteKey(lpsz);CoTaskMemFree(lpOleStr);return S_OK;}/////////////////////////////////////////////////////////////////////////////// Large Block Allocation Helper - CVBufHelper & CVirtualBuffertemplate <class T>class CVBufHelper{public:virtual T* operator()(T* pCurrent) {return pCurrent;}};template <class T>class CVirtualBuffer{protected:CVirtualBuffer() {}T* m_pBase;T* m_pCurrent;T* m_pTop;int m_nMaxElements;public:CVirtualBuffer(int nMaxElements){m_nMaxElements = nMaxElements;m_pBase = (T*) VirtualAlloc(NULL, sizeof(T) * nMaxElements,MEM_RESERVE, PAGE_READWRITE);m_pTop = m_pCurrent = m_pBase;// Commit first page - chances are this is all that will be usedVirtualAlloc(m_pBase, sizeof(T), MEM_COMMIT, PAGE_READWRITE);}~CVirtualBuffer(){VirtualFree(m_pBase, 0, MEM_RELEASE);}int Except(LPEXCEPTION_POINTERS lpEP){EXCEPTION_RECORD* pExcept = lpEP->ExceptionRecord;if (pExcept->ExceptionCode != EXCEPTION_ACCESS_VIOLATION)return EXCEPTION_CONTINUE_SEARCH;BYTE* pAddress = (LPBYTE) pExcept->ExceptionInformation[1];VirtualAlloc(pAddress, sizeof(T), MEM_COMMIT, PAGE_READWRITE);return EXCEPTION_CONTINUE_EXECUTION;}void Seek(int nElement){m_pCurrent = &m_pBase[nElement];}void SetAt(int nElement, const T& Element){__try{T* p = &m_pBase[nElement]*p = Element;m_pTop = p > m_pTop ? p : m_pTop;}__except(Except(GetExceptionInformation())){}}template <class Q>void WriteBulk(Q& helper){__try{m_pCurrent = helper(m_pBase);m_pTop = m_pCurrent > m_pTop ? m_pCurrent : m_pTop;}__except(Except(GetExceptionInformation())){}}void Write(const T& Element){__try{*m_pCurrent = Element;m_pCurrent++;m_pTop = m_pCurrent > m_pTop ? m_pCurrent : m_pTop;}__except(Except(GetExceptionInformation())){}}T& Read(){return *m_pCurrent;}operator BSTR(){BSTR bstrTemp;__try{bstrTemp = SysAllocStringByteLen((char*) m_pBase,(UINT) ((BYTE*)m_pTop - (BYTE*)m_pBase));}__except(Except(GetExceptionInformation())){}return bstrTemp;}const T& operator[](int nElement) const{return m_pBase[nElement];}operator T*(){return m_pBase;}};typedef CVirtualBuffer<BYTE> CVirtualBytes;inline HRESULT WINAPI AtlDumpIID(REFIID iid, LPCTSTR pszClassName, HRESULT hr){if (atlTraceQI & ATL_TRACE_CATEGORY){USES_CONVERSION;CRegKey key;TCHAR szName[100];DWORD dwType,dw = sizeof(szName);LPOLESTR pszGUID = NULL;StringFromCLSID(iid, &pszGUID);OutputDebugString(pszClassName);OutputDebugString(_T(" - "));// Attempt to find it in the interfaces sectionkey.Open(HKEY_CLASSES_ROOT, _T("Interface"), KEY_READ);if (key.Open(key, OLE2T(pszGUID), KEY_READ) == S_OK){*szName = 0;RegQueryValueEx(key.m_hKey, (LPTSTR)NULL, NULL, &dwType, (LPBYTE)szName, &dw);OutputDebugString(szName);goto cleanup;}// Attempt to find it in the clsid sectionkey.Open(HKEY_CLASSES_ROOT, _T("CLSID"), KEY_READ);if (key.Open(key, OLE2T(pszGUID), KEY_READ) == S_OK){*szName = 0;RegQueryValueEx(key.m_hKey, (LPTSTR)NULL, NULL, &dwType, (LPBYTE)szName, &dw);OutputDebugString(_T("(CLSID\?\?\?) "));OutputDebugString(szName);goto cleanup;}OutputDebugString(OLE2T(pszGUID));cleanup:if (hr != S_OK)OutputDebugString(_T(" - failed"));OutputDebugString(_T("\n"));CoTaskMemFree(pszGUID);}return hr;}#pragma pack(pop)// WM_FORWARDMSG - used to forward a message to another window for processing// WPARAM - DWORD dwUserData - defined by user// LPARAM - LPMSG pMsg - a pointer to the MSG structure// return value - 0 if the message was not processed, nonzero if it was#define WM_FORWARDMSG       0x037F}; //namespace ATLusing namespace ATL;//only suck in definition if static linking#ifndef _ATL_DLL_IMPL#ifndef _ATL_DLL#define _ATLBASE_IMPL#endif#endif#ifdef _ATL_REDEF_NEW#pragma pop_macro("new")#undef _ATL_REDEF_NEW#endif#endif // __ATLBASE_H__//All exports go here#ifdef _ATLBASE_IMPL#ifndef _ATL_DLL_IMPLnamespace ATL{#endif/////////////////////////////////////////////////////////////////////////////// staticsstatic UINT WINAPI AtlGetDirLen(LPCOLESTR lpszPathName){ATLASSERT(lpszPathName != NULL);// always capture the complete file name including extension (if present)LPCOLESTR lpszTemp = lpszPathName;for (LPCOLESTR lpsz = lpszPathName; *lpsz != NULL; ){LPCOLESTR lp = CharNextO(lpsz);// remember last directory/drive separatorif (*lpsz == OLESTR('\\') || *lpsz == OLESTR('/') || *lpsz == OLESTR(':'))lpszTemp = lp;lpsz = lp;}return lpszTemp-lpszPathName;}/////////////////////////////////////////////////////////////////////////////// QI supportATLINLINE ATLAPI AtlInternalQueryInterface(void* pThis,const _ATL_INTMAP_ENTRY* pEntries, REFIID iid, void** ppvObject){ATLASSERT(pThis != NULL);// First entry in the com map should be a simple map entryATLASSERT(pEntries->pFunc == _ATL_SIMPLEMAPENTRY);if (ppvObject == NULL)return E_POINTER;*ppvObject = NULL;if (InlineIsEqualUnknown(iid)) // use first interface{IUnknown* pUnk = (IUnknown*)((int)pThis+pEntries->dw);pUnk->AddRef();*ppvObject = pUnk;return S_OK;}while (pEntries->pFunc != NULL){BOOL bBlind = (pEntries->piid == NULL);if (bBlind || InlineIsEqualGUID(*(pEntries->piid), iid)){if (pEntries->pFunc == _ATL_SIMPLEMAPENTRY) //offset{ATLASSERT(!bBlind);IUnknown* pUnk = (IUnknown*)((int)pThis+pEntries->dw);pUnk->AddRef();*ppvObject = pUnk;return S_OK;}else //actual function call{HRESULT hRes = pEntries->pFunc(pThis,iid, ppvObject, pEntries->dw);if (hRes == S_OK || (!bBlind && FAILED(hRes)))return hRes;}}pEntries++;}return E_NOINTERFACE;}/////////////////////////////////////////////////////////////////////////////// Smart Pointer helpersATLINLINE ATLAPI_(IUnknown*) AtlComPtrAssign(IUnknown** pp, IUnknown* lp){if (lp != NULL)lp->AddRef();if (*pp)(*pp)->Release();*pp = lp;return lp;}ATLINLINE ATLAPI_(IUnknown*) AtlComQIPtrAssign(IUnknown** pp, IUnknown* lp, REFIID riid){IUnknown* pTemp = *pp;*pp = NULL;if (lp != NULL)lp->QueryInterface(riid, (void**)pp);if (pTemp)pTemp->Release();return *pp;}/////////////////////////////////////////////////////////////////////////////// Inproc Marshaling helpers//This API should be called from the same thread that called//AtlMarshalPtrInProcATLINLINE ATLAPI AtlFreeMarshalStream(IStream* pStream){if (pStream != NULL){LARGE_INTEGER l;l.QuadPart = 0;pStream->Seek(l, STREAM_SEEK_SET, NULL);CoReleaseMarshalData(pStream);pStream->Release();}return S_OK;}ATLINLINE ATLAPI AtlMarshalPtrInProc(IUnknown* pUnk, const IID& iid, IStream** ppStream){HRESULT hRes = CreateStreamOnHGlobal(NULL, TRUE, ppStream);if (SUCCEEDED(hRes)){hRes = CoMarshalInterface(*ppStream, iid,pUnk, MSHCTX_INPROC, NULL, MSHLFLAGS_TABLESTRONG);if (FAILED(hRes)){(*ppStream)->Release();*ppStream = NULL;}}return hRes;}ATLINLINE ATLAPI AtlUnmarshalPtr(IStream* pStream, const IID& iid, IUnknown** ppUnk){*ppUnk = NULL;HRESULT hRes = E_INVALIDARG;if (pStream != NULL){LARGE_INTEGER l;l.QuadPart = 0;pStream->Seek(l, STREAM_SEEK_SET, NULL);hRes = CoUnmarshalInterface(pStream, iid, (void**)ppUnk);}return hRes;}ATLINLINE ATLAPI_(BOOL) AtlWaitWithMessageLoop(HANDLE hEvent){DWORD dwRet;MSG msg;while(1){dwRet = MsgWaitForMultipleObjects(1, &hEvent, FALSE, INFINITE, QS_ALLINPUT);if (dwRet == WAIT_OBJECT_0)return TRUE;    // The event was signaledif (dwRet != WAIT_OBJECT_0 + 1)break;          // Something else happened// There is one or more window message available. Dispatch themwhile(PeekMessage(&msg,NULL,NULL,NULL,PM_REMOVE)){TranslateMessage(&msg);DispatchMessage(&msg);if (WaitForSingleObject(hEvent, 0) == WAIT_OBJECT_0)return TRUE; // Event is now signaled.}}return FALSE;}/////////////////////////////////////////////////////////////////////////////// Connection Point HelpersATLINLINE ATLAPI AtlAdvise(IUnknown* pUnkCP, IUnknown* pUnk, const IID& iid, LPDWORD pdw){CComPtr<IConnectionPointContainer> pCPC;CComPtr<IConnectionPoint> pCP;HRESULT hRes = pUnkCP->QueryInterface(IID_IConnectionPointContainer, (void**)&pCPC);if (SUCCEEDED(hRes))hRes = pCPC->FindConnectionPoint(iid, &pCP);if (SUCCEEDED(hRes))hRes = pCP->Advise(pUnk, pdw);return hRes;}ATLINLINE ATLAPI AtlUnadvise(IUnknown* pUnkCP, const IID& iid, DWORD dw){CComPtr<IConnectionPointContainer> pCPC;CComPtr<IConnectionPoint> pCP;HRESULT hRes = pUnkCP->QueryInterface(IID_IConnectionPointContainer, (void**)&pCPC);if (SUCCEEDED(hRes))hRes = pCPC->FindConnectionPoint(iid, &pCP);if (SUCCEEDED(hRes))hRes = pCP->Unadvise(dw);return hRes;}/////////////////////////////////////////////////////////////////////////////// IDispatch Error handlingATLINLINE ATLAPI AtlSetErrorInfo(const CLSID& clsid, LPCOLESTR lpszDesc, DWORD dwHelpID,LPCOLESTR lpszHelpFile, const IID& iid, HRESULT hRes, HINSTANCE hInst){USES_CONVERSION;TCHAR szDesc[1024];szDesc[0] = NULL;// For a valid HRESULT the id should be in the range [0x0200, 0xffff]if (HIWORD(lpszDesc) == 0) //id{UINT nID = LOWORD((DWORD)lpszDesc);ATLASSERT((nID >= 0x0200 && nID <= 0xffff) || hRes != 0);if (LoadString(hInst, nID, szDesc, 1024) == 0){ATLASSERT(FALSE);lstrcpy(szDesc, _T("Unknown Error"));}lpszDesc = T2OLE(szDesc);if (hRes == 0)hRes = MAKE_HRESULT(3, FACILITY_ITF, nID);}CComPtr<ICreateErrorInfo> pICEI;if (SUCCEEDED(CreateErrorInfo(&pICEI))){CComPtr<IErrorInfo> pErrorInfo;pICEI->SetGUID(iid);LPOLESTR lpsz;ProgIDFromCLSID(clsid, &lpsz);if (lpsz != NULL)pICEI->SetSource(lpsz);if (dwHelpID != 0 && lpszHelpFile != NULL){pICEI->SetHelpContext(dwHelpID);pICEI->SetHelpFile(const_cast<LPOLESTR>(lpszHelpFile));}CoTaskMemFree(lpsz);pICEI->SetDescription((LPOLESTR)lpszDesc);if (SUCCEEDED(pICEI->QueryInterface(IID_IErrorInfo, (void**)&pErrorInfo)))SetErrorInfo(0, pErrorInfo);}return (hRes == 0) ? DISP_E_EXCEPTION : hRes;}/////////////////////////////////////////////////////////////////////////////// Modulestruct _ATL_MODULE20{// Attributespublic:UINT cbSize;HINSTANCE m_hInst;HINSTANCE m_hInstResource;HINSTANCE m_hInstTypeLib;_ATL_OBJMAP_ENTRY* m_pObjMap;LONG m_nLockCnt;HANDLE m_hHeap;CRITICAL_SECTION m_csTypeInfoHolder;CRITICAL_SECTION m_csWindowCreate;CRITICAL_SECTION m_csObjMap;};typedef _ATL_MODULE _ATL_MODULE30;struct _ATL_OBJMAP_ENTRY20{const CLSID* pclsid;HRESULT (WINAPI *pfnUpdateRegistry)(BOOL bRegister);_ATL_CREATORFUNC* pfnGetClassObject;_ATL_CREATORFUNC* pfnCreateInstance;IUnknown* pCF;DWORD dwRegister;_ATL_DESCRIPTIONFUNC* pfnGetObjectDescription;};typedef _ATL_OBJMAP_ENTRY _ATL_OBJMAP_ENTRY30;inline _ATL_OBJMAP_ENTRY* _NextObjectMapEntry(_ATL_MODULE* pM, _ATL_OBJMAP_ENTRY* pEntry){if (pM->cbSize == sizeof(_ATL_MODULE20))return (_ATL_OBJMAP_ENTRY*)(((BYTE*)pEntry) + sizeof(_ATL_OBJMAP_ENTRY20));return pEntry+1;}//Although these functions are big, they are only used once in a module//so we should make them inline.ATLINLINE ATLAPI AtlModuleInit(_ATL_MODULE* pM, _ATL_OBJMAP_ENTRY* p, HINSTANCE h){ATLASSERT(pM != NULL);if (pM == NULL)return E_INVALIDARG;#ifdef _ATL_DLL_IMPLif ((pM->cbSize != _nAtlModuleVer1Size) && (pM->cbSize != sizeof(_ATL_MODULE)))return E_INVALIDARG;#elseATLASSERT(pM->cbSize == sizeof(_ATL_MODULE));#endifpM->m_pObjMap = p;pM->m_hInst = pM->m_hInstTypeLib = pM->m_hInstResource = h;pM->m_nLockCnt=0L;pM->m_hHeap = NULL;InitializeCriticalSection(&pM->m_csTypeInfoHolder);InitializeCriticalSection(&pM->m_csWindowCreate);InitializeCriticalSection(&pM->m_csObjMap);#ifdef _ATL_DLL_IMPLif (pM->cbSize > _nAtlModuleVer1Size)#endif{pM->m_pCreateWndList = NULL;pM->m_bDestroyHeap = true;pM->m_dwHeaps = 0;pM->m_nHeap = 0;pM->m_phHeaps = NULL;pM->m_pTermFuncs = NULL;if (pM->m_pObjMap != NULL){_ATL_OBJMAP_ENTRY* pEntry = pM->m_pObjMap;while (pEntry->pclsid != NULL){pEntry->pfnObjectMain(true); //initialize class resourcespEntry = _NextObjectMapEntry(pM, pEntry);}}}return S_OK;}ATLINLINE ATLAPI AtlModuleRegisterClassObjects(_ATL_MODULE* pM, DWORD dwClsContext, DWORD dwFlags){ATLASSERT(pM != NULL);if (pM == NULL)return E_INVALIDARG;ATLASSERT(pM->m_pObjMap != NULL);_ATL_OBJMAP_ENTRY* pEntry = pM->m_pObjMap;HRESULT hRes = S_OK;while (pEntry->pclsid != NULL && hRes == S_OK){hRes = pEntry->RegisterClassObject(dwClsContext, dwFlags);pEntry = _NextObjectMapEntry(pM, pEntry);}return hRes;}ATLINLINE ATLAPI AtlModuleRevokeClassObjects(_ATL_MODULE* pM){ATLASSERT(pM != NULL);if (pM == NULL)return E_INVALIDARG;ATLASSERT(pM->m_pObjMap != NULL);_ATL_OBJMAP_ENTRY* pEntry = pM->m_pObjMap;HRESULT hRes = S_OK;while (pEntry->pclsid != NULL && hRes == S_OK){hRes = pEntry->RevokeClassObject();pEntry = _NextObjectMapEntry(pM, pEntry);}return hRes;}ATLINLINE ATLAPI AtlModuleGetClassObject(_ATL_MODULE* pM, REFCLSID rclsid, REFIID riid, LPVOID* ppv){ATLASSERT(pM != NULL);if (pM == NULL)return E_INVALIDARG;ATLASSERT(pM->m_pObjMap != NULL);_ATL_OBJMAP_ENTRY* pEntry = pM->m_pObjMap;HRESULT hRes = S_OK;if (ppv == NULL)return E_POINTER;*ppv = NULL;while (pEntry->pclsid != NULL){if ((pEntry->pfnGetClassObject != NULL) && InlineIsEqualGUID(rclsid, *pEntry->pclsid)){if (pEntry->pCF == NULL){EnterCriticalSection(&pM->m_csObjMap);if (pEntry->pCF == NULL)hRes = pEntry->pfnGetClassObject(pEntry->pfnCreateInstance, IID_IUnknown, (LPVOID*)&pEntry->pCF);LeaveCriticalSection(&pM->m_csObjMap);}if (pEntry->pCF != NULL)hRes = pEntry->pCF->QueryInterface(riid, ppv);break;}pEntry = _NextObjectMapEntry(pM, pEntry);}if (*ppv == NULL && hRes == S_OK)hRes = CLASS_E_CLASSNOTAVAILABLE;return hRes;}ATLINLINE ATLAPI AtlModuleTerm(_ATL_MODULE* pM){ATLASSERT(pM != NULL);if (pM == NULL)return E_INVALIDARG;ATLASSERT(pM->m_hInst != NULL);if (pM->m_pObjMap != NULL){_ATL_OBJMAP_ENTRY* pEntry = pM->m_pObjMap;while (pEntry->pclsid != NULL){if (pEntry->pCF != NULL)pEntry->pCF->Release();pEntry->pCF = NULL;#ifdef _ATL_DLL_IMPLif (pM->cbSize > _nAtlModuleVer1Size)#endifpEntry->pfnObjectMain(false); //cleanup class resourcespEntry = _NextObjectMapEntry(pM, pEntry);}}DeleteCriticalSection(&pM->m_csTypeInfoHolder);DeleteCriticalSection(&pM->m_csWindowCreate);DeleteCriticalSection(&pM->m_csObjMap);#ifdef _ATL_DLL_IMPLif (pM->cbSize > _nAtlModuleVer1Size)#endif{_ATL_TERMFUNC_ELEM* pElem = pM->m_pTermFuncs;_ATL_TERMFUNC_ELEM* pNext = NULL;while (pElem != NULL){pElem->pFunc(pElem->dw);pNext = pElem->pNext;delete pElem;pElem = pNext;}if (pM->m_hHeap != NULL && pM->m_bDestroyHeap){#ifndef _ATL_NO_MP_HEAPif (pM->m_phHeaps != NULL){for (DWORD i = 0; i <= pM->m_dwHeaps; i++)HeapDestroy(pM->m_phHeaps[i]);}#endifHeapDestroy(pM->m_hHeap);}}return S_OK;}ATLINLINE ATLAPI AtlModuleAddTermFunc(_ATL_MODULE* pM, _ATL_TERMFUNC* pFunc, DWORD dw){HRESULT hr = S_OK;_ATL_TERMFUNC_ELEM* pNew = NULL;ATLTRY(pNew = new _ATL_TERMFUNC_ELEM);if (pNew == NULL)hr = E_OUTOFMEMORY;else{pNew->pFunc = pFunc;pNew->dw = dw;EnterCriticalSection(&pM->m_csStaticDataInit);pNew->pNext = pM->m_pTermFuncs;pM->m_pTermFuncs = pNew;LeaveCriticalSection(&pM->m_csStaticDataInit);}return hr;}ATLINLINE ATLAPI AtlRegisterClassCategoriesHelper( REFCLSID clsid,   const struct _ATL_CATMAP_ENTRY* pCatMap, BOOL bRegister ){   CComPtr< ICatRegister > pCatRegister;   HRESULT hResult;   const struct _ATL_CATMAP_ENTRY* pEntry;   CATID catid;   if( pCatMap == NULL )   {  return( S_OK );   }   hResult = CoCreateInstance( CLSID_StdComponentCategoriesMgr, NULL,  CLSCTX_INPROC_SERVER, IID_ICatRegister, (void**)&pCatRegister );   if( FAILED( hResult ) )   {  // Since not all systems have the category manager installed, we'll allow  // the registration to succeed even though we didn't register our  // categories.  If you really want to register categories on a system  // without the category manager, you can either manually add the  // appropriate entries to your registry script (.rgs), or you can  // redistribute comcat.dll.  return( S_OK );   }   hResult = S_OK;   pEntry = pCatMap;   while( pEntry->iType != _ATL_CATMAP_ENTRY_END )   {  catid = *pEntry->pcatid;  if( bRegister )  { if( pEntry->iType == _ATL_CATMAP_ENTRY_IMPLEMENTED ) {hResult = pCatRegister->RegisterClassImplCategories( clsid, 1,   &catid ); } else {ATLASSERT( pEntry->iType == _ATL_CATMAP_ENTRY_REQUIRED );hResult = pCatRegister->RegisterClassReqCategories( clsid, 1,   &catid ); } if( FAILED( hResult ) ) {return( hResult ); }  }  else  { if( pEntry->iType == _ATL_CATMAP_ENTRY_IMPLEMENTED ) {pCatRegister->UnRegisterClassImplCategories( clsid, 1, &catid ); } else {ATLASSERT( pEntry->iType == _ATL_CATMAP_ENTRY_REQUIRED );pCatRegister->UnRegisterClassReqCategories( clsid, 1, &catid ); }  }  pEntry++;   }   return( S_OK );}ATLINLINE ATLAPI AtlModuleRegisterServer(_ATL_MODULE* pM, BOOL bRegTypeLib, const CLSID* pCLSID){ATLASSERT(pM != NULL);if (pM == NULL)return E_INVALIDARG;ATLASSERT(pM->m_hInst != NULL);ATLASSERT(pM->m_pObjMap != NULL);_ATL_OBJMAP_ENTRY* pEntry = pM->m_pObjMap;HRESULT hRes = S_OK;for (;pEntry->pclsid != NULL; pEntry = _NextObjectMapEntry(pM, pEntry)){if (pCLSID == NULL){if (pEntry->pfnGetObjectDescription != NULL &&pEntry->pfnGetObjectDescription() != NULL)continue;}else{if (!IsEqualGUID(*pCLSID, *pEntry->pclsid))continue;}hRes = pEntry->pfnUpdateRegistry(TRUE);if (FAILED(hRes))break;if (pM->cbSize == sizeof(_ATL_MODULE)){hRes = AtlRegisterClassCategoriesHelper( *pEntry->pclsid,pEntry->pfnGetCategoryMap(), TRUE );if (FAILED(hRes))break;}}if (SUCCEEDED(hRes) && bRegTypeLib)hRes = AtlModuleRegisterTypeLib(pM, 0);return hRes;}ATLINLINE ATLAPI AtlModuleUnregisterServerEx(_ATL_MODULE* pM, BOOL bUnRegTypeLib, const CLSID* pCLSID){ATLASSERT(pM != NULL);if (pM == NULL)return E_INVALIDARG;ATLASSERT(pM->m_hInst != NULL);ATLASSERT(pM->m_pObjMap != NULL);_ATL_OBJMAP_ENTRY* pEntry = pM->m_pObjMap;for (;pEntry->pclsid != NULL; pEntry = _NextObjectMapEntry(pM, pEntry)){if (pCLSID == NULL){if (pEntry->pfnGetObjectDescription != NULL&& pEntry->pfnGetObjectDescription() != NULL)continue;}else{if (!IsEqualGUID(*pCLSID, *pEntry->pclsid))continue;}pEntry->pfnUpdateRegistry(FALSE); //unregisterif (pM->cbSize == sizeof(_ATL_MODULE) && pEntry->pfnGetCategoryMap != NULL)AtlRegisterClassCategoriesHelper( *pEntry->pclsid,pEntry->pfnGetCategoryMap(), FALSE );}if (bUnRegTypeLib)AtlModuleUnRegisterTypeLib(pM, 0);return S_OK;}ATLINLINE ATLAPI AtlModuleUnregisterServer(_ATL_MODULE* pM, const CLSID* pCLSID){return AtlModuleUnregisterServerEx(pM, FALSE, pCLSID);}ATLINLINE ATLAPI AtlModuleUpdateRegistryFromResourceD(_ATL_MODULE* pM, LPCOLESTR lpszRes,BOOL bRegister, struct _ATL_REGMAP_ENTRY* pMapEntries, IRegistrar* pReg){USES_CONVERSION;ATLASSERT(pM != NULL);HRESULT hRes = S_OK;CComPtr<IRegistrar> p;if (pReg != NULL)p = pReg;else{hRes = CoCreateInstance(CLSID_Registrar, NULL,CLSCTX_INPROC_SERVER, IID_IRegistrar, (void**)&p);}if (SUCCEEDED(hRes)){TCHAR szModule[_MAX_PATH];GetModuleFileName(pM->m_hInst, szModule, _MAX_PATH);LPOLESTR pszModule;if ((pM->m_hInst == NULL) || (pM->m_hInst == GetModuleHandle(NULL))) // register as EXE{// Convert to short path to work around bug in NT4's CreateProcessTCHAR szModuleShort[_MAX_PATH];int cbShortName = GetShortPathName(szModule, szModuleShort, _MAX_PATH);if (cbShortName == _MAX_PATH)return E_OUTOFMEMORY;pszModule = (cbShortName == 0 || cbShortName == ERROR_INVALID_PARAMETER) ? T2OLE(szModule) : T2OLE(szModuleShort);}elsepszModule = T2OLE(szModule);int nLen = ocslen(pszModule);LPOLESTR pszModuleQuote = (LPOLESTR)alloca((nLen*2+1)*sizeof(OLECHAR));CComModule::ReplaceSingleQuote(pszModuleQuote, pszModule);p->AddReplacement(OLESTR("Module"), pszModuleQuote);if (NULL != pMapEntries){while (NULL != pMapEntries->szKey){ATLASSERT(NULL != pMapEntries->szData);p->AddReplacement((LPOLESTR)pMapEntries->szKey, (LPOLESTR)pMapEntries->szData);pMapEntries++;}}LPCOLESTR szType = OLESTR("REGISTRY");if (HIWORD(lpszRes)==0){if (bRegister)hRes = p->ResourceRegister(pszModule, ((UINT)LOWORD((DWORD)lpszRes)), szType);elsehRes = p->ResourceUnregister(pszModule, ((UINT)LOWORD((DWORD)lpszRes)), szType);}else{if (bRegister)hRes = p->ResourceRegisterSz(pszModule, lpszRes, szType);elsehRes = p->ResourceUnregisterSz(pszModule, lpszRes, szType);}}return hRes;}/////////////////////////////////////////////////////////////////////////////// TypeLib SupportATLINLINE ATLAPI AtlModuleLoadTypeLib(_ATL_MODULE* pM, LPCOLESTR lpszIndex, BSTR* pbstrPath, ITypeLib** ppTypeLib){*pbstrPath = NULL;*ppTypeLib = NULL;ATLASSERT(pM != NULL);USES_CONVERSION;ATLASSERT(pM->m_hInstTypeLib != NULL);TCHAR szModule[_MAX_PATH+10];GetModuleFileName(pM->m_hInstTypeLib, szModule, _MAX_PATH);if (lpszIndex != NULL)lstrcat(szModule, OLE2CT(lpszIndex));LPOLESTR lpszModule = T2OLE(szModule);HRESULT hr = LoadTypeLib(lpszModule, ppTypeLib);if (!SUCCEEDED(hr)){// typelib not in module, try <module>.tlb insteadLPTSTR lpszExt = NULL;LPTSTR lpsz;for (lpsz = szModule; *lpsz != NULL; lpsz = CharNext(lpsz)){if (*lpsz == _T('.'))lpszExt = lpsz;}if (lpszExt == NULL)lpszExt = lpsz;lstrcpy(lpszExt, _T(".tlb"));lpszModule = T2OLE(szModule);hr = LoadTypeLib(lpszModule, ppTypeLib);}if (SUCCEEDED(hr))*pbstrPath = OLE2BSTR(lpszModule);return hr;}ATLINLINE ATLAPI AtlModuleUnRegisterTypeLib(_ATL_MODULE* pM, LPCOLESTR lpszIndex){typedef HRESULT (WINAPI *PFNRTL)(REFGUID, WORD, WORD, LCID, SYSKIND);CComBSTR bstrPath;CComPtr<ITypeLib> pTypeLib;HRESULT hr = AtlModuleLoadTypeLib(pM, lpszIndex, &bstrPath, &pTypeLib);if (SUCCEEDED(hr)){TLIBATTR* ptla;HRESULT hr = pTypeLib->GetLibAttr(&ptla);if (SUCCEEDED(hr)){HINSTANCE h = LoadLibrary(_T("oleaut32.dll"));if (h != NULL){PFNRTL pfn = (PFNRTL) GetProcAddress(h, "UnRegisterTypeLib");if (pfn != NULL)hr = pfn(ptla->guid, ptla->wMajorVerNum, ptla->wMinorVerNum, ptla->lcid, ptla->syskind);FreeLibrary(h);}pTypeLib->ReleaseTLibAttr(ptla);}}return hr;}ATLINLINE ATLAPI AtlModuleRegisterTypeLib(_ATL_MODULE* pM, LPCOLESTR lpszIndex){CComBSTR bstrPath;CComPtr<ITypeLib> pTypeLib;HRESULT hr = AtlModuleLoadTypeLib(pM, lpszIndex, &bstrPath, &pTypeLib);if (SUCCEEDED(hr)){OLECHAR szDir[_MAX_PATH];ocscpy(szDir, bstrPath);szDir[AtlGetDirLen(szDir)] = 0;hr = ::RegisterTypeLib(pTypeLib, bstrPath, szDir);}return hr;}ATLINLINE ATLAPI_(DWORD) AtlGetVersion(void* /* pReserved */){return _ATL_VER;}ATLINLINE ATLAPI_(void) AtlModuleAddCreateWndData(_ATL_MODULE* pM, _AtlCreateWndData* pData, void* pObject){pData->m_pThis = pObject;pData->m_dwThreadID = ::GetCurrentThreadId();::EnterCriticalSection(&pM->m_csWindowCreate);pData->m_pNext = pM->m_pCreateWndList;pM->m_pCreateWndList = pData;::LeaveCriticalSection(&pM->m_csWindowCreate);}ATLINLINE ATLAPI_(void*) AtlModuleExtractCreateWndData(_ATL_MODULE* pM){void* pv = NULL;::EnterCriticalSection(&pM->m_csWindowCreate);_AtlCreateWndData* pEntry = pM->m_pCreateWndList;if(pEntry != NULL){DWORD dwThreadID = ::GetCurrentThreadId();_AtlCreateWndData* pPrev = NULL;while(pEntry != NULL){if(pEntry->m_dwThreadID == dwThreadID){if(pPrev == NULL)pM->m_pCreateWndList = pEntry->m_pNext;elsepPrev->m_pNext = pEntry->m_pNext;pv = pEntry->m_pThis;break;}pPrev = pEntry;pEntry = pEntry->m_pNext;}}::LeaveCriticalSection(&pM->m_csWindowCreate);return pv;}/////////////////////////////////////////////////////////////////////////////// General DLL Version Helpersinline HRESULT AtlGetDllVersion(HINSTANCE hInstDLL, DLLVERSIONINFO* pDllVersionInfo){ATLASSERT(pDllVersionInfo != NULL);if(::IsBadWritePtr(pDllVersionInfo, sizeof(DWORD)))return E_INVALIDARG;// We must get this function explicitly because some DLLs don't implement it.DLLGETVERSIONPROC pfnDllGetVersion = (DLLGETVERSIONPROC)::GetProcAddress(hInstDLL, "DllGetVersion");if(pfnDllGetVersion == NULL)return E_NOTIMPL;return (*pfnDllGetVersion)(pDllVersionInfo);}inline HRESULT AtlGetDllVersion(LPCTSTR lpstrDllName, DLLVERSIONINFO* pDllVersionInfo){HINSTANCE hInstDLL = ::LoadLibrary(lpstrDllName);if(hInstDLL == NULL)return E_FAIL;HRESULT hRet = AtlGetDllVersion(hInstDLL, pDllVersionInfo);::FreeLibrary(hInstDLL);return hRet;}// Common Control Versions://   Win95/WinNT 4.0    maj=4 min=00//   IE 3.x     maj=4 min=70//   IE 4.0     maj=4 min=71inline HRESULT AtlGetCommCtrlVersion(LPDWORD pdwMajor, LPDWORD pdwMinor){ATLASSERT(pdwMajor != NULL && pdwMinor != NULL);if(::IsBadWritePtr(pdwMajor, sizeof(DWORD)) || ::IsBadWritePtr(pdwMinor, sizeof(DWORD)))return E_INVALIDARG;DLLVERSIONINFO dvi;::ZeroMemory(&dvi, sizeof(dvi));dvi.cbSize = sizeof(dvi);HRESULT hRet = AtlGetDllVersion(_T("comctl32.dll"), &dvi);if(SUCCEEDED(hRet)){*pdwMajor = dvi.dwMajorVersion;*pdwMinor = dvi.dwMinorVersion;}else if(hRet == E_NOTIMPL){// If DllGetVersion is not there, then the DLL is a version// previous to the one shipped with IE 3.x*pdwMajor = 4;*pdwMinor = 0;hRet = S_OK;}return hRet;}// Shell Versions://   Win95/WinNT 4.0                    maj=4 min=00//   IE 3.x, IE 4.0 without Web Integrated Desktop  maj=4 min=00//   IE 4.0 with Web Integrated Desktop         maj=4 min=71//   IE 4.01 with Web Integrated Desktop        maj=4 min=72inline HRESULT AtlGetShellVersion(LPDWORD pdwMajor, LPDWORD pdwMinor){ATLASSERT(pdwMajor != NULL && pdwMinor != NULL);if(::IsBadWritePtr(pdwMajor, sizeof(DWORD)) || ::IsBadWritePtr(pdwMinor, sizeof(DWORD)))return E_INVALIDARG;DLLVERSIONINFO dvi;::ZeroMemory(&dvi, sizeof(dvi));dvi.cbSize = sizeof(dvi);HRESULT hRet = AtlGetDllVersion(_T("shell32.dll"), &dvi);if(SUCCEEDED(hRet)){*pdwMajor = dvi.dwMajorVersion;*pdwMinor = dvi.dwMinorVersion;}else if(hRet == E_NOTIMPL){// If DllGetVersion is not there, then the DLL is a version// previous to the one shipped with IE 4.x*pdwMajor = 4;*pdwMinor = 0;hRet = S_OK;}return hRet;}#ifndef _ATL_DLL_IMPL}; //namespace ATL#endif//Prevent pulling in second time#undef _ATLBASE_IMPL#endif // _ATLBASE_IMPL/////////////////////////////////////////////////////////////////////////////