6385 lines
179 KiB
C
6385 lines
179 KiB
C
|
// 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")
|
||
|
#endif
|
||
|
|
||
|
extern "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_IMPL
|
||
|
namespace ATL
|
||
|
{
|
||
|
#endif
|
||
|
|
||
|
struct _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 2
|
||
|
|
||
|
typedef HRESULT (WINAPI _ATL_CREATORFUNC)(void* pv, REFIID riid, LPVOID* ppv);
|
||
|
typedef HRESULT (WINAPI _ATL_CREATORARGFUNC)(void* pv, REFIID riid, LPVOID* ppv, DWORD_PTR dw);
|
||
|
typedef HRESULT (WINAPI _ATL_MODULEFUNC)(DWORD_PTR dw);
|
||
|
typedef LPCTSTR (WINAPI _ATL_DESCRIPTIONFUNC)();
|
||
|
typedef const struct _ATL_CATMAP_ENTRY* (_ATL_CATMAPFUNC)();
|
||
|
typedef void (__stdcall _ATL_TERMFUNC)(DWORD_PTR dw);
|
||
|
|
||
|
struct _ATL_TERMFUNC_ELEM
|
||
|
{
|
||
|
_ATL_TERMFUNC* pFunc;
|
||
|
DWORD_PTR 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.0
|
||
|
void (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_21
|
||
|
{
|
||
|
// Attributes
|
||
|
public:
|
||
|
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;
|
||
|
};
|
||
|
|
||
|
struct _ATL_MODULE_30
|
||
|
{
|
||
|
// Attributes
|
||
|
public:
|
||
|
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.0
|
||
|
DWORD 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;
|
||
|
};
|
||
|
|
||
|
#if _ATL_VER == 0x0300
|
||
|
typedef _ATL_MODULE_30 _ATL_MODULE;
|
||
|
#else
|
||
|
struct _ATL_MODULE
|
||
|
{
|
||
|
// Attributes
|
||
|
public:
|
||
|
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.0
|
||
|
DWORD 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;
|
||
|
// Stuff added in ATL 6.1
|
||
|
LONG m_nNextWindowID;
|
||
|
};
|
||
|
#endif
|
||
|
|
||
|
const int _nAtlModuleVer21Size = sizeof( _ATL_MODULE_21 );
|
||
|
const int _nAtlModuleVer30Size = sizeof( _ATL_MODULE_30 );
|
||
|
|
||
|
//This define makes debugging asserts easier.
|
||
|
#define _ATL_SIMPLEMAPENTRY ((_ATL_CREATORARGFUNC*)1)
|
||
|
|
||
|
struct _ATL_INTMAP_ENTRY
|
||
|
{
|
||
|
const IID* piid; // the interface id (IID)
|
||
|
DWORD_PTR dw;
|
||
|
_ATL_CREATORARGFUNC* pFunc; //NULL:end, 1:offset, n:ptr
|
||
|
};
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
// Thunks for __stdcall member functions
|
||
|
|
||
|
|
||
|
#if defined(_M_IX86)
|
||
|
#pragma pack(push,1)
|
||
|
struct _stdcallthunk
|
||
|
{
|
||
|
DWORD m_mov; // mov dword ptr [esp+0x4], pThis (esp+0x4 is hWnd)
|
||
|
DWORD m_this; //
|
||
|
BYTE m_jmp; // jmp WndProc
|
||
|
DWORD m_relproc; // relative jmp
|
||
|
void Init(DWORD_PTR proc, void* pThis)
|
||
|
{
|
||
|
m_mov = 0x042444C7; //C7 44 24 0C
|
||
|
m_this = PtrToUlong(pThis);
|
||
|
m_jmp = 0xe9;
|
||
|
m_relproc = DWORD((INT_PTR)proc - ((INT_PTR)this+sizeof(_stdcallthunk)));
|
||
|
// write block from data cache and
|
||
|
// flush from instruction cache
|
||
|
FlushInstructionCache(GetCurrentProcess(), this, sizeof(_stdcallthunk));
|
||
|
}
|
||
|
};
|
||
|
#pragma pack(pop)
|
||
|
#elif defined (_M_AMD64)
|
||
|
#pragma pack(push,2)
|
||
|
struct _stdcallthunk
|
||
|
{
|
||
|
USHORT RcxMov; // mov rcx, pThis
|
||
|
ULONG64 RcxImm; //
|
||
|
USHORT RaxMov; // mov rax, target
|
||
|
ULONG64 RaxImm; //
|
||
|
USHORT RaxJmp; // jmp target
|
||
|
void Init(DWORD_PTR proc, void *pThis)
|
||
|
{
|
||
|
RcxMov = 0xb948; // mov rcx, pThis
|
||
|
RcxImm = (ULONG64)pThis; //
|
||
|
RaxMov = 0xb848; // mov rax, target
|
||
|
RaxImm = (ULONG64)proc; //
|
||
|
RaxJmp = 0xe0ff; // jmp rax
|
||
|
FlushInstructionCache(GetCurrentProcess(), this, sizeof(_stdcallthunk));
|
||
|
}
|
||
|
};
|
||
|
#pragma pack(pop)
|
||
|
#elif defined(_M_IA64)
|
||
|
#pragma pack(push,8)
|
||
|
extern "C" LRESULT CALLBACK _WndProcThunkProc( HWND, UINT, WPARAM, LPARAM );
|
||
|
struct _FuncDesc
|
||
|
{
|
||
|
void* pfn;
|
||
|
void* gp;
|
||
|
};
|
||
|
struct _stdcallthunk
|
||
|
{
|
||
|
_FuncDesc m_funcdesc;
|
||
|
void* m_pFunc;
|
||
|
void* m_pThis;
|
||
|
void Init(DWORD_PTR proc, void* pThis)
|
||
|
{
|
||
|
const _FuncDesc* pThunkProc;
|
||
|
|
||
|
pThunkProc = reinterpret_cast< const _FuncDesc* >( _WndProcThunkProc );
|
||
|
m_funcdesc.pfn = pThunkProc->pfn;
|
||
|
m_funcdesc.gp = &m_pFunc;
|
||
|
m_pFunc = reinterpret_cast< void* >( proc );
|
||
|
m_pThis = pThis;
|
||
|
::FlushInstructionCache( GetCurrentProcess(), this, sizeof( _stdcallthunk ) );
|
||
|
}
|
||
|
};
|
||
|
#pragma pack(pop)
|
||
|
#else
|
||
|
#error Only AMD64, IA64, and X86 supported
|
||
|
#endif
|
||
|
|
||
|
class CDynamicStdCallThunk
|
||
|
{
|
||
|
public:
|
||
|
_stdcallthunk *pThunk;
|
||
|
|
||
|
CDynamicStdCallThunk()
|
||
|
{
|
||
|
pThunk = NULL;
|
||
|
}
|
||
|
|
||
|
~CDynamicStdCallThunk()
|
||
|
{
|
||
|
if (pThunk)
|
||
|
HeapFree(GetProcessHeap(), 0, pThunk);
|
||
|
}
|
||
|
|
||
|
void Init(DWORD_PTR proc, void *pThis)
|
||
|
{
|
||
|
if (!pThunk) {
|
||
|
pThunk = static_cast<_stdcallthunk *>(HeapAlloc(GetProcessHeap(),
|
||
|
HEAP_GENERATE_EXCEPTIONS, sizeof(_stdcallthunk)));
|
||
|
}
|
||
|
ATLASSERT(pThunk);
|
||
|
pThunk->Init(proc, pThis);
|
||
|
}
|
||
|
};
|
||
|
typedef CDynamicStdCallThunk CStdCallThunk;
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
// QI Support
|
||
|
|
||
|
ATLAPI AtlInternalQueryInterface(void* pThis,
|
||
|
const _ATL_INTMAP_ENTRY* pEntries, REFIID iid, void** ppvObject);
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
// Smart Pointer helpers
|
||
|
|
||
|
ATLAPI_(IUnknown*) AtlComPtrAssign(IUnknown** pp, IUnknown* lp);
|
||
|
ATLAPI_(IUnknown*) AtlComQIPtrAssign(IUnknown** pp, IUnknown* lp, REFIID riid);
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
// Inproc Marshaling helpers
|
||
|
|
||
|
ATLAPI 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 Helpers
|
||
|
|
||
|
ATLAPI AtlAdvise(IUnknown* pUnkCP, IUnknown* pUnk, const IID& iid, LPDWORD pdw);
|
||
|
ATLAPI AtlUnadvise(IUnknown* pUnkCP, const IID& iid, DWORD dw);
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
// IDispatch Error handling
|
||
|
|
||
|
ATLAPI AtlSetErrorInfo(const CLSID& clsid, LPCOLESTR lpszDesc,
|
||
|
DWORD dwHelpID, LPCOLESTR lpszHelpFile, const IID& iid, HRESULT hRes,
|
||
|
HINSTANCE hInst);
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
// Module
|
||
|
|
||
|
ATLAPI 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_PTR dw);
|
||
|
|
||
|
#ifndef _ATL_DLL_IMPL
|
||
|
}; //namespace ATL
|
||
|
#endif
|
||
|
|
||
|
namespace ATL
|
||
|
{
|
||
|
|
||
|
enum atlTraceFlags
|
||
|
{
|
||
|
// Application defined categories
|
||
|
atlTraceUser = 0x00000001,
|
||
|
atlTraceUser2 = 0x00000002,
|
||
|
atlTraceUser3 = 0x00000004,
|
||
|
atlTraceUser4 = 0x00000008,
|
||
|
// ATL defined categories
|
||
|
atlTraceGeneral = 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
|
||
|
#endif
|
||
|
|
||
|
inline 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 OLE2ANSI
|
||
|
inline 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 // !DEBUG
|
||
|
inline void _cdecl AtlTrace(LPCSTR , ...){}
|
||
|
inline void _cdecl AtlTrace2(DWORD, UINT, LPCSTR , ...){}
|
||
|
#ifndef OLE2ANSI
|
||
|
inline 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")
|
||
|
#ifndef _WIN64
|
||
|
#pragma comment(lib, "olepro32.lib")
|
||
|
#endif
|
||
|
#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 equivalence
|
||
|
bool IsEqualObject(IUnknown* pOther)
|
||
|
{
|
||
|
if (p == NULL && pOther == NULL)
|
||
|
return true; // They are both NULL objects
|
||
|
|
||
|
if (p == NULL || pOther == NULL)
|
||
|
return false; // One is NULL the other is not
|
||
|
|
||
|
CComPtr<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 equivalence
|
||
|
bool IsEqualObject(IUnknown* pOther)
|
||
|
{
|
||
|
if (p == NULL && pOther == NULL)
|
||
|
return true; // They are both NULL objects
|
||
|
|
||
|
if (p == NULL || pOther == NULL)
|
||
|
return false; // One is NULL the other is not
|
||
|
|
||
|
CComPtr<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 work
|
||
|
template<>
|
||
|
class CComQIPtr<IUnknown, &IID_IUnknown>
|
||
|
{
|
||
|
public:
|
||
|
typedef IUnknown _PtrClass;
|
||
|
CComQIPtr()
|
||
|
{
|
||
|
p=NULL;
|
||
|
}
|
||
|
CComQIPtr(IUnknown* lp)
|
||
|
{
|
||
|
//Actually do a QI to get identity
|
||
|
p=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 identity
|
||
|
return (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 equivalence
|
||
|
bool IsEqualObject(IUnknown* pOther)
|
||
|
{
|
||
|
if (p == NULL && pOther == NULL)
|
||
|
return true; // They are both NULL objects
|
||
|
|
||
|
if (p == NULL || pOther == NULL)
|
||
|
return false; // One is NULL the other is not
|
||
|
|
||
|
CComPtr<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 comparison
|
||
|
|
||
|
#if 0
|
||
|
inline 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]);
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
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 Support
|
||
|
|
||
|
class 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;
|
||
|
#else
|
||
|
typedef CComMultiThreadModel CComObjectThreadModel;
|
||
|
typedef CComMultiThreadModel CComGlobalsThreadModel;
|
||
|
#endif
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
// CComModule
|
||
|
|
||
|
#define THREADFLAGS_APARTMENT 0x1
|
||
|
#define THREADFLAGS_BOTH 0x2
|
||
|
#define AUTPRXFLAG 0x4
|
||
|
|
||
|
HRESULT WINAPI AtlDumpIID(REFIID iid, LPCTSTR pszClassName, HRESULT hr);
|
||
|
|
||
|
#ifdef _ATL_DEBUG_INTERFACES
|
||
|
struct _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)();
|
||
|
#ifndef _WIN64
|
||
|
STDMETHOD(f1024)();
|
||
|
#endif
|
||
|
_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 & CSimpleMap
|
||
|
|
||
|
template <class T>
|
||
|
class CSimpleArray
|
||
|
{
|
||
|
public:
|
||
|
T* m_aT;
|
||
|
int m_nSize;
|
||
|
int m_nAllocSize;
|
||
|
|
||
|
// Construction/destruction
|
||
|
CSimpleArray() : m_aT(NULL), m_nSize(0), m_nAllocSize(0)
|
||
|
{ }
|
||
|
|
||
|
~CSimpleArray()
|
||
|
{
|
||
|
RemoveAll();
|
||
|
}
|
||
|
|
||
|
// Operations
|
||
|
int 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)
|
||
|
{
|
||
|
|
||
|
//---- always call the dtr ----
|
||
|
#if _MSC_VER >= 1200
|
||
|
m_aT[nIndex].~T();
|
||
|
#else
|
||
|
T* MyT;
|
||
|
MyT = &m_aT[nIndex];
|
||
|
MyT->~T();
|
||
|
#endif
|
||
|
|
||
|
//---- if target entry is not at end, compact the array ----
|
||
|
if(nIndex != (m_nSize - 1))
|
||
|
{
|
||
|
|
||
|
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++) {
|
||
|
#if _MSC_VER >= 1200
|
||
|
m_aT[i].~T();
|
||
|
#else
|
||
|
T* MyT;
|
||
|
MyT = &m_aT[i];
|
||
|
MyT->~T();
|
||
|
#endif
|
||
|
}
|
||
|
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;
|
||
|
}
|
||
|
|
||
|
// Implementation
|
||
|
class 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 types
|
||
|
template <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 pointers
|
||
|
template <class TKey, class TVal>
|
||
|
class CSimpleMap
|
||
|
{
|
||
|
public:
|
||
|
TKey* m_aKey;
|
||
|
TVal* m_aVal;
|
||
|
int m_nSize;
|
||
|
|
||
|
// Construction/destruction
|
||
|
CSimpleMap() : m_aKey(NULL), m_aVal(NULL), m_nSize(0)
|
||
|
{ }
|
||
|
|
||
|
~CSimpleMap()
|
||
|
{
|
||
|
RemoveAll();
|
||
|
}
|
||
|
|
||
|
// Operations
|
||
|
int 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();
|
||
|
#if _MSC_VER >= 1200
|
||
|
m_aVal[nIndex].~TVal();
|
||
|
#else
|
||
|
TVal * t1;
|
||
|
t1 = &m_aVal[nIndex];
|
||
|
t1->~TVal();
|
||
|
#endif
|
||
|
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();
|
||
|
#if _MSC_VER >= 1200
|
||
|
m_aVal[i].~TVal();
|
||
|
#else
|
||
|
TVal * t1;
|
||
|
t1 = &m_aVal[i];
|
||
|
t1->~TVal();
|
||
|
#endif
|
||
|
}
|
||
|
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 convert
|
||
|
return GetValueAt(nIndex);
|
||
|
}
|
||
|
TKey ReverseLookup(TVal val) const
|
||
|
{
|
||
|
int nIndex = FindVal(val);
|
||
|
if(nIndex == -1)
|
||
|
return NULL; // must be able to convert
|
||
|
return 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];
|
||
|
}
|
||
|
|
||
|
// Implementation
|
||
|
|
||
|
template <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
|
||
|
{
|
||
|
// Operations
|
||
|
public:
|
||
|
static GUID m_libid;
|
||
|
#ifdef _ATL_DEBUG_INTERFACES
|
||
|
UINT m_nIndexQI;
|
||
|
UINT m_nIndexBreakAt;
|
||
|
CSimpleArray<_QIThunk*>* m_paThunks;
|
||
|
#endif // _ATL_DEBUG_INTERFACES
|
||
|
|
||
|
void AddCreateWndData(_AtlCreateWndData* pData, void* pObject)
|
||
|
{
|
||
|
AtlModuleAddCreateWndData(this, pData, pObject);
|
||
|
}
|
||
|
void* ExtractCreateWndData()
|
||
|
{
|
||
|
return AtlModuleExtractCreateWndData(this);
|
||
|
}
|
||
|
|
||
|
#if _ATL_VER > 0x0300
|
||
|
LONG GetNextWindowID()
|
||
|
{
|
||
|
LONG nID;
|
||
|
|
||
|
nID = InterlockedIncrement(&m_nNextWindowID);
|
||
|
|
||
|
return nID;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
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));
|
||
|
#if _ATL_VER > 0x0300
|
||
|
m_nNextWindowID = 1;
|
||
|
#endif
|
||
|
#ifdef _ATL_MIN_CRT
|
||
|
// Create a base heap
|
||
|
m_hHeap = HeapCreate(0, 0, 0);
|
||
|
|
||
|
#ifndef _ATL_NO_MP_HEAP
|
||
|
SYSTEM_INFO si;
|
||
|
GetSystemInfo(&si);
|
||
|
if (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 processor
|
||
|
m_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_INTERFACES
|
||
|
m_nIndexQI = 0;
|
||
|
m_nIndexBreakAt = 0;
|
||
|
m_paThunks = NULL;
|
||
|
ATLTRY(m_paThunks = new CSimpleArray<_QIThunk*>);
|
||
|
if (m_paThunks == NULL)
|
||
|
return E_OUTOFMEMORY;
|
||
|
#endif // _ATL_DEBUG_INTERFACES
|
||
|
return S_OK;
|
||
|
}
|
||
|
#ifdef _ATL_DEBUG_INTERFACES
|
||
|
HRESULT 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 identity
|
||
|
if (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) {
|
||
|
LeaveCriticalSection(&m_csObjMap);
|
||
|
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 identity
|
||
|
for (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;
|
||
|
LeaveCriticalSection(&m_csObjMap);
|
||
|
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_INTERFACES
|
||
|
void Term()
|
||
|
{
|
||
|
#ifdef _ATL_DEBUG_INTERFACES
|
||
|
m_bDestroyHeap = false; // prevent heap from going away
|
||
|
AtlModuleTerm(this);
|
||
|
DumpLeakedThunks();
|
||
|
delete m_paThunks;
|
||
|
#ifndef _ATL_NO_MP_HEAP
|
||
|
if (m_phHeaps != NULL)
|
||
|
{
|
||
|
for (DWORD i = 0; i <= m_dwHeaps; i++)
|
||
|
HeapDestroy(m_phHeaps[i]);
|
||
|
}
|
||
|
#endif
|
||
|
if (m_hHeap != NULL)
|
||
|
HeapDestroy(m_hHeap);
|
||
|
#else
|
||
|
AtlModuleTerm(this);
|
||
|
#endif // _ATL_DEBUG_INTERFACES
|
||
|
}
|
||
|
|
||
|
HRESULT AddTermFunc(_ATL_TERMFUNC* pFunc, DWORD_PTR 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 Registration
|
||
|
HRESULT 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 Ponent
|
||
|
HRESULT 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 Registration
|
||
|
HRESULT 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 CComAutoThreadModule
|
||
|
HRESULT 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_INTERFACES
|
||
|
inline 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");
|
||
|
}
|
||
|
|
||
|
#ifdef _M_IX86
|
||
|
#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\
|
||
|
}
|
||
|
|
||
|
#else
|
||
|
#define IMPL_THUNK(x)
|
||
|
#endif
|
||
|
|
||
|
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 classes
|
||
|
|
||
|
class _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;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
// CComBSTR
|
||
|
|
||
|
class 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 BSTR
|
||
|
HRESULT 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 OLE2ANSI
|
||
|
CComBSTR(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;
|
||
|
}
|
||
|
#endif
|
||
|
HRESULT WriteToStream(IStream* pStream)
|
||
|
{
|
||
|
ATLASSERT(pStream != NULL);
|
||
|
ULONG cb;
|
||
|
ULONG cbStrLen = m_str ? SysStringByteLen(m_str)+(ULONG)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 empty
|
||
|
ULONG 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 NULL
|
||
|
m_str = SysAllocStringByteLen(NULL, cbStrLen-sizeof(OLECHAR));
|
||
|
if (m_str == NULL)
|
||
|
hr = E_OUTOFMEMORY;
|
||
|
else
|
||
|
hr = pStream->Read((void*) m_str, cbStrLen, NULL);
|
||
|
}
|
||
|
if (hr == S_FALSE)
|
||
|
hr = E_FAIL;
|
||
|
return hr;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
// CComVariant
|
||
|
|
||
|
class CComVariant : public tagVARIANT
|
||
|
{
|
||
|
// Constructors
|
||
|
public:
|
||
|
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 OLE2ANSI
|
||
|
CComVariant(LPCSTR lpszSrc)
|
||
|
{
|
||
|
vt = VT_EMPTY;
|
||
|
*this = lpszSrc;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
CComVariant(bool bSrc)
|
||
|
{
|
||
|
vt = VT_BOOL;
|
||
|
#pragma warning(disable: 4310) // cast truncates constant value
|
||
|
boolVal = 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 Release
|
||
|
if (pdispVal != NULL)
|
||
|
pdispVal->AddRef();
|
||
|
}
|
||
|
CComVariant(IUnknown* pSrc)
|
||
|
{
|
||
|
vt = VT_UNKNOWN;
|
||
|
punkVal = pSrc;
|
||
|
// Need to AddRef as VariantClear will Release
|
||
|
if (punkVal != NULL)
|
||
|
punkVal->AddRef();
|
||
|
}
|
||
|
|
||
|
// Assignment Operators
|
||
|
public:
|
||
|
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 OLE2ANSI
|
||
|
CComVariant& 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;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
CComVariant& operator=(bool bSrc)
|
||
|
{
|
||
|
if (vt != VT_BOOL)
|
||
|
{
|
||
|
InternalClear();
|
||
|
vt = VT_BOOL;
|
||
|
}
|
||
|
#pragma warning(disable: 4310) // cast truncates constant value
|
||
|
boolVal = bSrc ? VARIANT_TRUE : VARIANT_FALSE;
|
||
|
#pragma warning(default: 4310) // cast truncates constant value
|
||
|
return *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 Release
|
||
|
if (pdispVal != NULL)
|
||
|
pdispVal->AddRef();
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
CComVariant& operator=(IUnknown* pSrc)
|
||
|
{
|
||
|
InternalClear();
|
||
|
vt = VT_UNKNOWN;
|
||
|
punkVal = pSrc;
|
||
|
|
||
|
// Need to AddRef as VariantClear will Release
|
||
|
if (punkVal != NULL)
|
||
|
punkVal->AddRef();
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
|
||
|
// Comparison Operators
|
||
|
public:
|
||
|
bool operator==(const VARIANT& varSrc) const
|
||
|
{
|
||
|
if (this == &varSrc)
|
||
|
return true;
|
||
|
|
||
|
// Variants not equal if types don't match
|
||
|
if (vt != varSrc.vt)
|
||
|
return false;
|
||
|
|
||
|
// Check type specific values
|
||
|
switch (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;}
|
||
|
|
||
|
// Operations
|
||
|
public:
|
||
|
HRESULT Clear() { return ::VariantClear(this); }
|
||
|
HRESULT Copy(const VARIANT* pSrc) { return ::VariantCopy(this, const_cast<VARIANT*>(pSrc)); }
|
||
|
HRESULT Attach(VARIANT* pSrc)
|
||
|
{
|
||
|
// Clear out the variant
|
||
|
HRESULT hr = Clear();
|
||
|
if (!FAILED(hr))
|
||
|
{
|
||
|
// Copy the contents and give control to CComVariant
|
||
|
memcpy(this, pSrc, sizeof(VARIANT));
|
||
|
pSrc->vt = VT_EMPTY;
|
||
|
hr = S_OK;
|
||
|
}
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
HRESULT Detach(VARIANT* pDest)
|
||
|
{
|
||
|
// Clear out the variant
|
||
|
HRESULT hr = ::VariantClear(pDest);
|
||
|
if (!FAILED(hr))
|
||
|
{
|
||
|
// Copy the contents and remove control from CComVariant
|
||
|
memcpy(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 NULL
|
||
|
if (pVar == NULL)
|
||
|
pVar = this;
|
||
|
// Do nothing if doing in place convert and vts not different
|
||
|
return ::VariantChangeType(this, pVar, 0, vtNew);
|
||
|
}
|
||
|
|
||
|
HRESULT WriteToStream(IStream* pStream);
|
||
|
HRESULT ReadFromStream(IStream* pStream);
|
||
|
|
||
|
// Implementation
|
||
|
public:
|
||
|
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);
|
||
|
else
|
||
|
return 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;
|
||
|
}
|
||
|
else
|
||
|
bstrWrite = 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;
|
||
|
}
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
// CRegKey
|
||
|
|
||
|
class CRegKey
|
||
|
{
|
||
|
public:
|
||
|
CRegKey();
|
||
|
~CRegKey();
|
||
|
|
||
|
// Attributes
|
||
|
public:
|
||
|
operator HKEY() const;
|
||
|
HKEY m_hKey;
|
||
|
|
||
|
// Operations
|
||
|
public:
|
||
|
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_WRITE);
|
||
|
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 Ponent
|
||
|
inline 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);
|
||
|
|
||
|
// Convert to short path to work around bug in NT4's CreateProcess
|
||
|
TCHAR szModuleShort[_MAX_PATH];
|
||
|
GetShortPathName(szModule, szModuleShort, _MAX_PATH);
|
||
|
LPOLESTR pszModule = T2OLE(szModuleShort);
|
||
|
|
||
|
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);
|
||
|
|
||
|
// Convert to short path to work around bug in NT4's CreateProcess
|
||
|
TCHAR szModuleShort[_MAX_PATH];
|
||
|
GetShortPathName(szModule, szModuleShort, _MAX_PATH);
|
||
|
LPOLESTR pszModule = T2OLE(szModuleShort);
|
||
|
|
||
|
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_REGISTRY
|
||
|
|
||
|
inline 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);
|
||
|
}
|
||
|
else
|
||
|
return 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);
|
||
|
if (lRes == ERROR_SUCCESS)
|
||
|
{
|
||
|
lRes = key.Create(key, lpsz, REG_NONE, REG_OPTION_NON_VOLATILE, 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 CreateProcess
|
||
|
TCHAR szModuleShort[_MAX_PATH];
|
||
|
GetShortPathName(szModule, szModuleShort, _MAX_PATH);
|
||
|
key.SetKeyValue(szLS32, szModuleShort);
|
||
|
}
|
||
|
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) == ERROR_SUCCESS)
|
||
|
key.RecurseDeleteKey(lpsz);
|
||
|
CoTaskMemFree(lpOleStr);
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
// Large Block Allocation Helper - CVBufHelper & CVirtualBuffer
|
||
|
|
||
|
|
||
|
template <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 used
|
||
|
VirtualAlloc(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, ((BYTE*)m_pTop - (BYTE*)m_pBase), 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 section
|
||
|
key.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 section
|
||
|
key.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 ATL
|
||
|
using namespace ATL;
|
||
|
|
||
|
//only pull 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_IMPL
|
||
|
namespace ATL
|
||
|
{
|
||
|
#endif
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
// statics
|
||
|
|
||
|
static 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 separator
|
||
|
if (*lpsz == OLESTR('\\') || *lpsz == OLESTR('/') || *lpsz == OLESTR(':'))
|
||
|
lpszTemp = lp;
|
||
|
lpsz = lp;
|
||
|
}
|
||
|
|
||
|
return UINT(lpszTemp-lpszPathName);
|
||
|
}
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
// QI support
|
||
|
|
||
|
ATLINLINE 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 entry
|
||
|
ATLASSERT(pEntries->pFunc == _ATL_SIMPLEMAPENTRY);
|
||
|
if (ppvObject == NULL)
|
||
|
return E_POINTER;
|
||
|
*ppvObject = NULL;
|
||
|
if (InlineIsEqualUnknown(iid)) // use first interface
|
||
|
{
|
||
|
IUnknown* pUnk = (IUnknown*)((DWORD_PTR)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*)((DWORD_PTR)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 helpers
|
||
|
|
||
|
ATLINLINE 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
|
||
|
//AtlMarshalPtrInProc
|
||
|
ATLINLINE 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 signaled
|
||
|
|
||
|
if (dwRet != WAIT_OBJECT_0 + 1)
|
||
|
break; // Something else happened
|
||
|
|
||
|
// There is one or more window message available. Dispatch them
|
||
|
while(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 Helpers
|
||
|
|
||
|
ATLINLINE 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 handling
|
||
|
|
||
|
ATLINLINE 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 (IS_INTRESOURCE(lpszDesc)) //id
|
||
|
{
|
||
|
UINT nID = LOWORD((DWORD_PTR)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;
|
||
|
}
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
// Module
|
||
|
|
||
|
struct _ATL_MODULE20
|
||
|
{
|
||
|
// Attributes
|
||
|
public:
|
||
|
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_IMPL
|
||
|
if ((pM->cbSize != _nAtlModuleVer21Size) && (pM->cbSize != _nAtlModuleVer30Size) &&
|
||
|
(pM->cbSize != sizeof(_ATL_MODULE)))
|
||
|
return E_INVALIDARG;
|
||
|
#else
|
||
|
ATLASSERT(pM->cbSize == sizeof(_ATL_MODULE));
|
||
|
#endif
|
||
|
pM->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_IMPL
|
||
|
if (pM->cbSize > _nAtlModuleVer21Size)
|
||
|
#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 resources
|
||
|
pEntry = _NextObjectMapEntry(pM, pEntry);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
#ifdef _ATL_DLL_IMPL
|
||
|
if (pM->cbSize > _nAtlModuleVer30Size)
|
||
|
#endif
|
||
|
{
|
||
|
#if _ATL_VER > 0x0300
|
||
|
pM->m_nNextWindowID = 1;
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
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_IMPL
|
||
|
if (pM->cbSize > _nAtlModuleVer21Size)
|
||
|
#endif
|
||
|
pEntry->pfnObjectMain(false); //cleanup class resources
|
||
|
pEntry = _NextObjectMapEntry(pM, pEntry);
|
||
|
}
|
||
|
}
|
||
|
DeleteCriticalSection(&pM->m_csTypeInfoHolder);
|
||
|
DeleteCriticalSection(&pM->m_csWindowCreate);
|
||
|
DeleteCriticalSection(&pM->m_csObjMap);
|
||
|
|
||
|
#ifdef _ATL_DLL_IMPL
|
||
|
if (pM->cbSize > _nAtlModuleVer21Size)
|
||
|
#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_HEAP
|
||
|
if (pM->m_phHeaps != NULL)
|
||
|
{
|
||
|
for (DWORD i = 0; i <= pM->m_dwHeaps; i++)
|
||
|
HeapDestroy(pM->m_phHeaps[i]);
|
||
|
}
|
||
|
#endif
|
||
|
HeapDestroy(pM->m_hHeap);
|
||
|
}
|
||
|
}
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
ATLINLINE ATLAPI AtlModuleAddTermFunc(_ATL_MODULE* pM, _ATL_TERMFUNC* pFunc, DWORD_PTR 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); //unregister
|
||
|
if (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);
|
||
|
|
||
|
// Convert to short path to work around bug in NT4's CreateProcess
|
||
|
TCHAR szModuleShort[_MAX_PATH];
|
||
|
GetShortPathName(szModule, szModuleShort, _MAX_PATH);
|
||
|
LPOLESTR pszModule = T2OLE(szModuleShort);
|
||
|
|
||
|
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 (DWORD_PTR(lpszRes)<=0xffff)
|
||
|
{
|
||
|
if (bRegister)
|
||
|
hRes = p->ResourceRegister(pszModule, ((UINT)LOWORD((DWORD_PTR)lpszRes)), szType);
|
||
|
else
|
||
|
hRes = p->ResourceUnregister(pszModule, ((UINT)LOWORD((DWORD_PTR)lpszRes)), szType);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (bRegister)
|
||
|
hRes = p->ResourceRegisterSz(pszModule, lpszRes, szType);
|
||
|
else
|
||
|
hRes = p->ResourceUnregisterSz(pszModule, lpszRes, szType);
|
||
|
}
|
||
|
|
||
|
}
|
||
|
return hRes;
|
||
|
}
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
// TypeLib Support
|
||
|
|
||
|
ATLINLINE 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 instead
|
||
|
LPTSTR 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;
|
||
|
else
|
||
|
pPrev->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 Helpers
|
||
|
|
||
|
inline 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=71
|
||
|
inline 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=72
|
||
|
inline 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
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|