4 * Copyright 2009 Andrew Hill <ash77@reactos.org>
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
25 #include "atlcomcli.h"
31 // It is common to use this in ATL constructors. They only store this for later use, so the usage is safe.
32 #pragma warning(disable:4355)
36 #define _ATL_PACKING 8
39 #ifndef _ATL_FREE_THREADED
40 #ifndef _ATL_APARTMENT_THREADED
41 #ifndef _ATL_SINGLE_THREADED
42 #define _ATL_FREE_THREADED
51 #ifdef _ATL_DISABLE_NO_VTABLE
54 #define ATL_NO_VTABLE __declspec(novtable)
57 #ifndef ATL_DEPRECATED
58 #define ATL_DEPRECATED __declspec(deprecated)
61 #define offsetofclass(base, derived) (reinterpret_cast<DWORD_PTR>(static_cast<base *>(reinterpret_cast<derived *>(_ATL_PACKING))) - _ATL_PACKING)
69 __declspec(selectany
) CAtlModule
*_pAtlModule
= NULL
;
70 __declspec(selectany
) CComModule
*_pModule
= NULL
;
71 extern CAtlComModule _AtlComModule
;
74 struct _ATL_CATMAP_ENTRY
80 #define _ATL_CATMAP_ENTRY_END 0
81 #define _ATL_CATMAP_ENTRY_IMPLEMENTED 1
82 #define _ATL_CATMAP_ENTRY_REQUIRED 2
85 typedef HRESULT (WINAPI _ATL_CREATORFUNC
)(void *pv
, REFIID riid
, LPVOID
*ppv
);
86 typedef LPCTSTR (WINAPI _ATL_DESCRIPTIONFUNC
)();
87 typedef const struct _ATL_CATMAP_ENTRY
* (_ATL_CATMAPFUNC
)();
89 struct _ATL_OBJMAP_ENTRY30
92 HRESULT (WINAPI
*pfnUpdateRegistry
)(BOOL bRegister
);
93 _ATL_CREATORFUNC
*pfnGetClassObject
;
94 _ATL_CREATORFUNC
*pfnCreateInstance
;
97 _ATL_DESCRIPTIONFUNC
*pfnGetObjectDescription
;
98 _ATL_CATMAPFUNC
*pfnGetCategoryMap
;
99 void (WINAPI
*pfnObjectMain
)(bool bStarting
);
101 HRESULT WINAPI
RevokeClassObject()
105 return CoRevokeClassObject(dwRegister
);
108 HRESULT WINAPI
RegisterClassObject(DWORD dwClsContext
, DWORD dwFlags
)
114 if (pfnGetClassObject
== NULL
)
117 hResult
= pfnGetClassObject(reinterpret_cast<LPVOID
*>(pfnCreateInstance
), IID_IUnknown
, reinterpret_cast<LPVOID
*>(&p
));
118 if (SUCCEEDED(hResult
))
119 hResult
= CoRegisterClassObject(*pclsid
, p
, dwClsContext
, dwFlags
, &dwRegister
);
128 typedef _ATL_OBJMAP_ENTRY30 _ATL_OBJMAP_ENTRY
;
130 typedef void (__stdcall _ATL_TERMFUNC
)(DWORD_PTR dw
);
132 struct _ATL_TERMFUNC_ELEM
134 _ATL_TERMFUNC
*pFunc
;
136 _ATL_TERMFUNC_ELEM
*pNext
;
143 _ATL_TERMFUNC_ELEM
*m_pTermFuncs
;
144 CComCriticalSection m_csStaticDataInitAndTypeInfo
;
146 typedef _ATL_MODULE70 _ATL_MODULE
;
148 typedef HRESULT (WINAPI _ATL_CREATORARGFUNC
)(void *pv
, REFIID riid
, LPVOID
*ppv
, DWORD_PTR dw
);
150 #define _ATL_SIMPLEMAPENTRY ((ATL::_ATL_CREATORARGFUNC *)1)
152 struct _ATL_INTMAP_ENTRY
156 _ATL_CREATORARGFUNC
*pFunc
;
159 struct _AtlCreateWndData
163 _AtlCreateWndData
*m_pNext
;
166 struct _ATL_COM_MODULE70
169 HINSTANCE m_hInstTypeLib
;
170 _ATL_OBJMAP_ENTRY
**m_ppAutoObjMapFirst
;
171 _ATL_OBJMAP_ENTRY
**m_ppAutoObjMapLast
;
172 CComCriticalSection m_csObjMap
;
174 typedef _ATL_COM_MODULE70 _ATL_COM_MODULE
;
176 struct _ATL_WIN_MODULE70
179 CComCriticalSection m_csWindowCreate
;
180 _AtlCreateWndData
*m_pCreateWndList
;
182 CSimpleArray
<ATOM
> m_rgWindowClassAtoms
;
185 typedef _ATL_WIN_MODULE70 _ATL_WIN_MODULE
;
187 struct _ATL_REGMAP_ENTRY
193 HRESULT WINAPI
AtlWinModuleInit(_ATL_WIN_MODULE
*pWinModule
);
194 HRESULT WINAPI
AtlWinModuleTerm(_ATL_WIN_MODULE
*pWinModule
, HINSTANCE hInst
);
195 HRESULT WINAPI
AtlInternalQueryInterface(void *pThis
, const _ATL_INTMAP_ENTRY
*pEntries
, REFIID iid
, void **ppvObject
);
196 void WINAPI
AtlWinModuleAddCreateWndData(_ATL_WIN_MODULE
*pWinModule
, _AtlCreateWndData
*pData
, void *pObject
);
197 void *WINAPI
AtlWinModuleExtractCreateWndData(_ATL_WIN_MODULE
*pWinModule
);
198 HRESULT WINAPI
AtlComModuleGetClassObject(_ATL_COM_MODULE
*pComModule
, REFCLSID rclsid
, REFIID riid
, LPVOID
*ppv
);
200 HRESULT WINAPI
AtlComModuleRegisterServer(_ATL_COM_MODULE
*mod
, BOOL bRegTypeLib
, const CLSID
*clsid
);
201 HRESULT WINAPI
AtlComModuleUnregisterServer(_ATL_COM_MODULE
*mod
, BOOL bRegTypeLib
, const CLSID
*clsid
);
203 HRESULT WINAPI
AtlComModuleRegisterClassObjects(_ATL_COM_MODULE
*module
, DWORD context
, DWORD flags
);
204 HRESULT WINAPI
AtlComModuleRevokeClassObjects(_ATL_COM_MODULE
*module
);
207 template<class TLock
>
208 class CComCritSecLock
214 CComCritSecLock(TLock
&cs
, bool bInitialLock
= true) : m_cs(cs
)
239 ATLASSERT(!m_bLocked
);
240 hResult
= m_cs
.Lock();
252 ATLASSERT(m_bLocked
);
253 hResult
= m_cs
.Unlock();
274 CHandle(_Inout_ CHandle
& handle
) :
277 Attach(handle
.Detach());
280 explicit CHandle(_In_ HANDLE handle
) :
293 CHandle
& operator=(_Inout_ CHandle
& handle
)
301 Attach(handle
.Detach());
307 operator HANDLE() const
312 void Attach(_In_ HANDLE handle
)
314 ATLASSERT(m_handle
== NULL
);
320 HANDLE handle
= m_handle
;
329 ::CloseHandle(m_handle
);
336 inline BOOL WINAPI
InlineIsEqualUnknown(REFGUID rguid1
)
339 ((unsigned long *)&rguid1
)[0] == 0 &&
340 ((unsigned long *)&rguid1
)[1] == 0 &&
341 ((unsigned long *)&rguid1
)[2] == 0x000000C0 &&
342 ((unsigned long *)&rguid1
)[3] == 0x46000000);
345 class CComMultiThreadModelNoCS
348 typedef CComFakeCriticalSection AutoCriticalSection
;
349 typedef CComFakeCriticalSection CriticalSection
;
350 typedef CComMultiThreadModelNoCS ThreadModelNoCS
;
351 typedef CComFakeCriticalSection AutoDeleteCriticalSection
;
353 static ULONG WINAPI
Increment(LPLONG p
)
355 return InterlockedIncrement(p
);
358 static ULONG WINAPI
Decrement(LPLONG p
)
360 return InterlockedDecrement(p
);
364 class CComMultiThreadModel
367 typedef CComAutoCriticalSection AutoCriticalSection
;
368 typedef CComCriticalSection CriticalSection
;
369 typedef CComMultiThreadModelNoCS ThreadModelNoCS
;
370 typedef CComAutoDeleteCriticalSection AutoDeleteCriticalSection
;
372 static ULONG WINAPI
Increment(LPLONG p
)
374 return InterlockedIncrement(p
);
377 static ULONG WINAPI
Decrement(LPLONG p
)
379 return InterlockedDecrement(p
);
383 class CComSingleThreadModel
386 typedef CComFakeCriticalSection AutoCriticalSection
;
387 typedef CComFakeCriticalSection CriticalSection
;
388 typedef CComSingleThreadModel ThreadModelNoCS
;
389 typedef CComFakeCriticalSection AutoDeleteCriticalSection
;
391 static ULONG WINAPI
Increment(LPLONG p
)
396 static ULONG WINAPI
Decrement(LPLONG p
)
402 #if defined(_ATL_FREE_THREADED)
404 typedef CComMultiThreadModel CComObjectThreadModel
;
405 typedef CComMultiThreadModel CComGlobalsThreadModel
;
407 #elif defined(_ATL_APARTMENT_THREADED)
409 typedef CComSingleThreadModel CComObjectThreadModel
;
410 typedef CComMultiThreadModel CComGlobalsThreadModel
;
412 #elif defined(_ATL_SINGLE_THREADED)
414 typedef CComSingleThreadModel CComObjectThreadModel
;
415 typedef CComSingleThreadModel CComGlobalsThreadModel
;
418 #error No threading model
421 class CAtlModule
: public _ATL_MODULE
428 ATLASSERT(_pAtlModule
== NULL
);
430 cbSize
= sizeof(_ATL_MODULE
);
434 virtual LONG
GetLockCount()
441 return CComGlobalsThreadModel::Increment(&m_nLockCnt
);
444 virtual LONG
Unlock()
446 return CComGlobalsThreadModel::Decrement(&m_nLockCnt
);
449 virtual HRESULT
AddCommonRGSReplacements(IRegistrarBase
* /*pRegistrar*/) = 0;
451 HRESULT WINAPI
UpdateRegistryFromResource(LPCTSTR lpszRes
, BOOL bRegister
, struct _ATL_REGMAP_ENTRY
*pMapEntries
= NULL
)
453 CRegObject registrar
;
454 WCHAR modulePath
[MAX_PATH
];
458 hResult
= CommonInitRegistrar(registrar
, modulePath
, sizeof(modulePath
) / sizeof(modulePath
[0]), pMapEntries
);
464 /* FIXME: this is a bit of a hack, need to re-evaluate */
465 WCHAR resid
[MAX_PATH
];
466 MultiByteToWideChar(CP_ACP
, 0, lpszRes
, -1, resid
, MAX_PATH
);
469 if (bRegister
!= FALSE
)
470 hResult
= registrar
.ResourceRegisterSz(modulePath
, lpwszRes
, L
"REGISTRY");
472 hResult
= registrar
.ResourceUnregisterSz(modulePath
, lpwszRes
, L
"REGISTRY");
477 HRESULT WINAPI
UpdateRegistryFromResource(UINT nResID
, BOOL bRegister
, struct _ATL_REGMAP_ENTRY
*pMapEntries
= NULL
)
479 CRegObject registrar
;
480 WCHAR modulePath
[MAX_PATH
];
483 hResult
= CommonInitRegistrar(registrar
, modulePath
, sizeof(modulePath
) / sizeof(modulePath
[0]), pMapEntries
);
487 if (bRegister
!= FALSE
)
488 hResult
= registrar
.ResourceRegister(modulePath
, nResID
, L
"REGISTRY");
490 hResult
= registrar
.ResourceUnregister(modulePath
, nResID
, L
"REGISTRY");
496 HRESULT
CommonInitRegistrar(CRegObject
®istrar
, WCHAR
*modulePath
, DWORD modulePathCount
, struct _ATL_REGMAP_ENTRY
*pMapEntries
)
502 hInstance
= _AtlBaseModule
.GetModuleInstance();
503 dwFLen
= GetModuleFileNameW(hInstance
, modulePath
, modulePathCount
);
504 if (dwFLen
== modulePathCount
)
505 return HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER
);
506 else if (dwFLen
== 0)
507 return HRESULT_FROM_WIN32(GetLastError());
509 if (pMapEntries
!= NULL
)
511 while (pMapEntries
->szKey
!= NULL
)
513 ATLASSERT(pMapEntries
->szData
!= NULL
);
514 hResult
= registrar
.AddReplacement(pMapEntries
->szKey
, pMapEntries
->szData
);
521 hResult
= AddCommonRGSReplacements(®istrar
);
525 hResult
= registrar
.AddReplacement(L
"Module", modulePath
);
529 hResult
= registrar
.AddReplacement(L
"Module_Raw", modulePath
);
537 __declspec(selectany
) GUID
CAtlModule::m_libid
= {0x0, 0x0, 0x0, {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0} };
540 class CAtlModuleT
: public CAtlModule
544 HRESULT
RegisterServer(BOOL bRegTypeLib
= FALSE
, const CLSID
*pCLSID
= NULL
);
545 HRESULT
UnregisterServer(BOOL bUnRegTypeLib
, const CLSID
*pCLSID
= NULL
);
548 virtual HRESULT
AddCommonRGSReplacements(IRegistrarBase
*pRegistrar
)
550 return pRegistrar
->AddReplacement(L
"APPID", T::GetAppId());
553 static LPCOLESTR
GetAppId()
559 class CAtlComModule
: public _ATL_COM_MODULE
564 GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS
, (LPCWSTR
)this, &m_hInstTypeLib
);
565 m_ppAutoObjMapFirst
= NULL
;
566 m_ppAutoObjMapLast
= NULL
;
567 if (FAILED(m_csObjMap
.Init()))
570 CAtlBaseModule::m_bInitFailed
= true;
573 cbSize
= sizeof(_ATL_COM_MODULE
);
581 HRESULT
RegisterServer(BOOL bRegTypeLib
= FALSE
, const CLSID
*pCLSID
= NULL
)
583 return AtlComModuleRegisterServer(this, bRegTypeLib
, pCLSID
);
586 HRESULT
UnregisterServer(BOOL bUnRegTypeLib
, const CLSID
*pCLSID
= NULL
)
588 return AtlComModuleUnregisterServer(this, bUnRegTypeLib
, pCLSID
);
596 ATLASSERT(m_ppAutoObjMapFirst
== NULL
);
597 ATLASSERT(m_ppAutoObjMapLast
== NULL
);
605 HRESULT CAtlModuleT
<T
>::RegisterServer(BOOL bRegTypeLib
, const CLSID
*pCLSID
)
607 return _AtlComModule
.RegisterServer(bRegTypeLib
, pCLSID
);
611 HRESULT CAtlModuleT
<T
>::UnregisterServer(BOOL bUnRegTypeLib
, const CLSID
*pCLSID
)
613 return _AtlComModule
.UnregisterServer(bUnRegTypeLib
, pCLSID
);
617 class CAtlDllModuleT
: public CAtlModuleT
<T
>
624 HRESULT
DllCanUnloadNow()
628 pThis
= static_cast<T
*>(this);
629 if (pThis
->GetLockCount() == 0)
634 HRESULT
DllGetClassObject(REFCLSID rclsid
, REFIID riid
, LPVOID
*ppv
)
638 pThis
= static_cast<T
*>(this);
639 return pThis
->GetClassObject(rclsid
, riid
, ppv
);
642 HRESULT
DllRegisterServer(BOOL bRegTypeLib
= TRUE
)
647 pThis
= static_cast<T
*>(this);
648 hResult
= pThis
->RegisterServer(bRegTypeLib
);
652 HRESULT
DllUnregisterServer(BOOL bUnRegTypeLib
= TRUE
)
657 pThis
= static_cast<T
*>(this);
658 hResult
= pThis
->UnregisterServer(bUnRegTypeLib
);
662 HRESULT
GetClassObject(REFCLSID rclsid
, REFIID riid
, LPVOID
*ppv
)
664 return AtlComModuleGetClassObject(&_AtlComModule
, rclsid
, riid
, ppv
);
670 class CAtlExeModuleT
: public CAtlModuleT
<T
>
673 DWORD m_dwMainThreadID
;
676 //bool m_bDelayShutdown;
679 :m_dwMainThreadID(::GetCurrentThreadId())
687 int WinMain(int nShowCmd
)
689 HRESULT hr
= T::InitializeCom();
693 T
* pThis
= static_cast<T
*>(this);
695 LPCTSTR lpCommandLine
= GetCommandLine();
696 if (pThis
->ParseCommandLine(lpCommandLine
, &hr
))
698 hr
= pThis
->Run(nShowCmd
);
701 T::UninitializeCom();
706 HRESULT
Run(int nShowCmd
= SW_HIDE
)
710 T
* pThis
= static_cast<T
*>(this);
711 hr
= pThis
->PreMessageLoop(nShowCmd
);
715 pThis
->RunMessageLoop();
716 hr
= pThis
->PostMessageLoop();
724 return CoAddRefServerProcess();
729 LONG lRet
= CoReleaseServerProcess();
732 ::PostThreadMessage(m_dwMainThreadID
, WM_QUIT
, 0, 0);
737 bool ParseCommandLine(LPCTSTR lpCmdLine
, HRESULT
* pnRetCode
)
743 HRESULT
PreMessageLoop(int nShowCmd
)
745 T
* pThis
= static_cast<T
*>(this);
746 return pThis
->RegisterClassObjects(CLSCTX_LOCAL_SERVER
, REGCLS_MULTIPLEUSE
);
749 void RunMessageLoop()
752 while (GetMessage(&msg
, 0, 0, 0) > 0)
754 TranslateMessage(&msg
);
755 DispatchMessage(&msg
);
759 HRESULT
PostMessageLoop()
761 T
* pThis
= static_cast<T
*>(this);
762 return pThis
->RevokeClassObjects();
765 HRESULT
RegisterClassObjects(DWORD dwClsContext
, DWORD dwFlags
)
767 return AtlComModuleRegisterClassObjects(&_AtlComModule
, dwClsContext
, dwFlags
);
770 HRESULT
RevokeClassObjects()
772 return AtlComModuleRevokeClassObjects(&_AtlComModule
);
775 static HRESULT
InitializeCom()
777 return ::CoInitializeEx(NULL
, COINIT_MULTITHREADED
);
780 static void UninitializeCom()
789 class CComModule
: public CAtlModuleT
<CComModule
>
792 _ATL_OBJMAP_ENTRY
*m_pObjMap
;
796 ATLASSERT(_pModule
== NULL
);
798 _pModule
->m_pObjMap
= NULL
;
806 HRESULT
Init(_ATL_OBJMAP_ENTRY
*p
, HINSTANCE
/* h */, const GUID
*plibid
)
808 _ATL_OBJMAP_ENTRY
*objectMapEntry
;
813 if (p
!= reinterpret_cast<_ATL_OBJMAP_ENTRY
*>(-1))
819 while (objectMapEntry
->pclsid
!= NULL
)
821 objectMapEntry
->pfnObjectMain(true);
831 _ATL_OBJMAP_ENTRY
*objectMapEntry
;
833 if (m_pObjMap
!= NULL
)
835 objectMapEntry
= m_pObjMap
;
836 while (objectMapEntry
->pclsid
!= NULL
)
838 if (objectMapEntry
->pCF
!= NULL
)
839 objectMapEntry
->pCF
->Release();
840 objectMapEntry
->pCF
= NULL
;
841 objectMapEntry
->pfnObjectMain(false);
847 HRESULT
GetClassObject(REFCLSID rclsid
, REFIID riid
, LPVOID
*ppv
)
849 _ATL_OBJMAP_ENTRY
*objectMapEntry
;
852 ATLASSERT(ppv
!= NULL
);
857 if (m_pObjMap
!= NULL
)
859 objectMapEntry
= m_pObjMap
;
860 while (objectMapEntry
->pclsid
!= NULL
)
862 if (objectMapEntry
->pfnGetClassObject
!= NULL
&& InlineIsEqualGUID(rclsid
, *objectMapEntry
->pclsid
) != FALSE
)
864 if (objectMapEntry
->pCF
== NULL
)
866 CComCritSecLock
<CComCriticalSection
> lock(_AtlComModule
.m_csObjMap
, true);
868 if (objectMapEntry
->pCF
== NULL
)
869 hResult
= objectMapEntry
->pfnGetClassObject(reinterpret_cast<void *>(objectMapEntry
->pfnCreateInstance
), IID_IUnknown
, reinterpret_cast<LPVOID
*>(&objectMapEntry
->pCF
));
871 if (objectMapEntry
->pCF
!= NULL
)
872 hResult
= objectMapEntry
->pCF
->QueryInterface(riid
, ppv
);
878 if (hResult
== S_OK
&& *ppv
== NULL
)
880 // FIXME: call AtlComModuleGetClassObject
881 hResult
= CLASS_E_CLASSNOTAVAILABLE
;
886 HRESULT
RegisterServer(BOOL bRegTypeLib
= FALSE
, const CLSID
*pCLSID
= NULL
)
888 _ATL_OBJMAP_ENTRY
*objectMapEntry
;
892 objectMapEntry
= m_pObjMap
;
893 if (objectMapEntry
!= NULL
)
895 while (objectMapEntry
->pclsid
!= NULL
)
897 if (pCLSID
== NULL
|| IsEqualGUID(*pCLSID
, *objectMapEntry
->pclsid
) != FALSE
)
899 hResult
= objectMapEntry
->pfnUpdateRegistry(TRUE
);
906 if (SUCCEEDED(hResult
))
907 hResult
= CAtlModuleT
<CComModule
>::RegisterServer(bRegTypeLib
, pCLSID
);
911 HRESULT
UnregisterServer(BOOL bUnRegTypeLib
, const CLSID
*pCLSID
= NULL
)
913 _ATL_OBJMAP_ENTRY
*objectMapEntry
;
917 objectMapEntry
= m_pObjMap
;
918 if (objectMapEntry
!= NULL
)
920 while (objectMapEntry
->pclsid
!= NULL
)
922 if (pCLSID
== NULL
|| IsEqualGUID(*pCLSID
, *objectMapEntry
->pclsid
) != FALSE
)
924 hResult
= objectMapEntry
->pfnUpdateRegistry(FALSE
); //unregister
931 if (SUCCEEDED(hResult
))
932 hResult
= CAtlModuleT
<CComModule
>::UnregisterServer(bUnRegTypeLib
, pCLSID
);
937 HRESULT
DllCanUnloadNow()
939 if (GetLockCount() == 0)
944 HRESULT
DllGetClassObject(REFCLSID rclsid
, REFIID riid
, LPVOID
*ppv
)
946 return GetClassObject(rclsid
, riid
, ppv
);
949 HRESULT
DllRegisterServer(BOOL bRegTypeLib
= TRUE
)
951 return RegisterServer(bRegTypeLib
);
954 HRESULT
DllUnregisterServer(BOOL bUnRegTypeLib
= TRUE
)
956 return UnregisterServer(bUnRegTypeLib
);
961 class CAtlWinModule
: public _ATL_WIN_MODULE
968 hResult
= AtlWinModuleInit(this);
971 CAtlBaseModule::m_bInitFailed
= true;
983 AtlWinModuleTerm(this, _AtlBaseModule
.GetModuleInstance());
986 void AddCreateWndData(_AtlCreateWndData
*pData
, void *pObject
)
988 AtlWinModuleAddCreateWndData(this, pData
, pObject
);
991 void *ExtractCreateWndData()
993 return AtlWinModuleExtractCreateWndData(this);
997 extern CAtlWinModule _AtlWinModule
;
1002 static void* Allocate(_In_
size_t size
)
1004 return ::CoTaskMemAlloc(size
);
1007 static void* Reallocate(_In_opt_
void* ptr
, _In_
size_t size
)
1009 return ::CoTaskMemRealloc(ptr
, size
);
1012 static void Free(_In_opt_
void* ptr
)
1014 ::CoTaskMemFree(ptr
);
1024 CAtlTransactionManager
* m_pTM
;
1034 CRegKey(CRegKey
& key
) throw()
1035 : m_hKey(key
.Detach())
1039 explicit CRegKey(HKEY hKey
) throw()
1046 CRegKey(CAtlTransactionManager
* pTM
) throw()
1056 void Attach(HKEY hKey
) throw()
1061 LONG
Close() throw()
1065 HKEY hKey
= Detach();
1066 return ::RegCloseKey(hKey
);
1068 return ERROR_SUCCESS
;
1071 HKEY
Detach() throw()
1078 LONG
Open(HKEY hKeyParent
, LPCTSTR lpszKeyName
,
1079 REGSAM samDesired
= KEY_READ
| KEY_WRITE
) throw()
1081 ATLASSERT(hKeyParent
);
1082 ATLASSERT(lpszKeyName
);
1085 LONG lRes
= ::RegOpenKeyEx(hKeyParent
, lpszKeyName
, NULL
, samDesired
, &hKey
);
1086 if (lRes
!= ERROR_SUCCESS
)
1088 samDesired
|= KEY_WOW64_64KEY
;
1089 lRes
= ::RegOpenKeyEx(hKeyParent
, lpszKeyName
, NULL
, samDesired
, &hKey
);
1091 if (lRes
== ERROR_SUCCESS
)
1099 LONG
Create(HKEY hKeyParent
, LPCTSTR lpszKeyName
,
1100 LPTSTR lpszClass
= REG_NONE
,
1101 DWORD dwOptions
= REG_OPTION_NON_VOLATILE
,
1102 REGSAM samDesired
= KEY_READ
| KEY_WRITE
,
1103 LPSECURITY_ATTRIBUTES lpSecAttr
= NULL
,
1104 LPDWORD lpdwDisposition
= NULL
) throw()
1106 ATLASSERT(hKeyParent
);
1107 ATLASSERT(lpszKeyName
);
1110 LONG lRes
= ::RegCreateKeyEx(hKeyParent
, lpszKeyName
, NULL
, lpszClass
,
1111 dwOptions
, samDesired
, lpSecAttr
, &hKey
,
1113 if (lRes
!= ERROR_SUCCESS
)
1115 samDesired
|= KEY_WOW64_64KEY
;
1116 lRes
= ::RegCreateKeyEx(hKeyParent
, lpszKeyName
, NULL
, lpszClass
,
1117 dwOptions
, samDesired
, lpSecAttr
, &hKey
,
1120 if (lRes
== ERROR_SUCCESS
)
1128 LONG
QueryValue(LPCTSTR pszValueName
, DWORD
* pdwType
, void* pData
, ULONG
* pnBytes
) throw()
1131 return ::RegQueryValueEx(m_hKey
, pszValueName
, NULL
, pdwType
, (LPBYTE
)pData
, pnBytes
);
1134 LONG
QueryDWORDValue(LPCTSTR pszValueName
, DWORD
& dwValue
) throw()
1136 ULONG size
= sizeof(DWORD
);
1138 LONG lRet
= QueryValue(pszValueName
, &type
, &dwValue
, &size
);
1140 if (lRet
== ERROR_SUCCESS
&& type
!= REG_DWORD
)
1141 lRet
= ERROR_INVALID_DATA
;
1146 LONG
QueryBinaryValue(LPCTSTR pszValueName
, void* pValue
, ULONG
* pnBytes
) throw()
1149 LONG lRet
= QueryValue(pszValueName
, &type
, pValue
, pnBytes
);
1151 if (lRet
== ERROR_SUCCESS
&& type
!= REG_BINARY
)
1152 lRet
= ERROR_INVALID_DATA
;
1157 LONG
QueryStringValue(LPCTSTR pszValueName
, LPTSTR pszValue
, ULONG
* pnChars
) throw()
1159 ULONG size
= (*pnChars
) * sizeof(TCHAR
);
1161 LONG lRet
= QueryValue(pszValueName
, &type
, pszValue
, &size
);
1163 if (lRet
== ERROR_SUCCESS
&& type
!= REG_SZ
&& type
!= REG_EXPAND_SZ
)
1164 lRet
= ERROR_INVALID_DATA
;
1166 *pnChars
= size
/ sizeof(TCHAR
);
1170 LONG
QueryGUIDValue(LPCTSTR pszValueName
, GUID
& guidValue
) throw()
1172 OLECHAR buf
[40] = {0};
1177 lRet
= QueryStringValue(pszValueName
, buf
, &nChars
);
1179 CHAR bufA
[40] = {0};
1180 lRet
= QueryStringValue(pszValueName
, bufA
, &nChars
);
1181 if (lRet
!= ERROR_SUCCESS
)
1183 if (!::MultiByteToWideChar(CP_THREAD_ACP
, 0, bufA
, -1, buf
, 39))
1184 lRet
= ERROR_INVALID_DATA
;
1186 if (lRet
!= ERROR_SUCCESS
)
1189 if (!SUCCEEDED(::CLSIDFromString(buf
, &guidValue
)))
1190 return ERROR_INVALID_DATA
;
1195 LONG
QueryQWORDValue(LPCTSTR pszValueName
, ULONGLONG
& qwValue
) throw()
1197 ULONG size
= sizeof(ULONGLONG
);
1199 LONG lRet
= QueryValue(pszValueName
, &type
, &qwValue
, &size
);
1201 if (lRet
== ERROR_SUCCESS
&& type
!= REG_QWORD
)
1202 lRet
= ERROR_INVALID_DATA
;
1207 LONG
QueryMultiStringValue(LPCTSTR pszValueName
, LPTSTR pszValue
,
1208 ULONG
* pnChars
) throw()
1210 ULONG size
= (*pnChars
) * sizeof(TCHAR
);
1212 LONG lRet
= QueryValue(pszValueName
, &type
, pszValue
, &size
);
1214 if (lRet
== ERROR_SUCCESS
&& type
!= REG_MULTI_SZ
)
1215 lRet
= ERROR_INVALID_DATA
;
1217 *pnChars
= size
/ sizeof(TCHAR
);
1221 LONG
SetValue(LPCTSTR pszValueName
, DWORD dwType
, const void* pValue
, ULONG nBytes
) throw()
1224 return ::RegSetValueEx(m_hKey
, pszValueName
, NULL
, dwType
, (const BYTE
*)pValue
, nBytes
);
1227 LONG
SetDWORDValue(LPCTSTR pszValueName
, DWORD dwValue
) throw()
1229 return SetValue(pszValueName
, REG_DWORD
, &dwValue
, sizeof(DWORD
));
1232 LONG
SetStringValue(LPCTSTR pszValueName
, LPCTSTR pszValue
, DWORD dwType
= REG_SZ
) throw()
1239 length
= (_tcslen(pszValue
) + 1) * sizeof(TCHAR
);
1240 return SetValue(pszValueName
, dwType
, pszValue
, length
);
1242 return SetMultiStringValue(pszValueName
, pszValue
);
1244 return ERROR_INVALID_DATA
;
1248 LONG
SetGUIDValue(LPCTSTR pszValueName
, REFGUID guidValue
) throw()
1250 OLECHAR buf
[40] = {0};
1251 ::StringFromGUID2(guidValue
, buf
, 39);
1253 return SetStringValue(pszValueName
, buf
);
1255 CHAR bufA
[40] = {0};
1256 ::WideCharToMultiByte(CP_THREAD_ACP
, 0, buf
, -1, bufA
, 40, NULL
, NULL
);
1257 return SetStringValue(pszValueName
, bufA
);
1261 LONG
SetBinaryValue(LPCTSTR pszValueName
, const void* pValue
, ULONG nBytes
) throw()
1263 return SetValue(pszValueName
, REG_BINARY
, pValue
, nBytes
);
1266 LONG
SetMultiStringValue(LPCTSTR pszValueName
, LPCTSTR pszValue
) throw()
1268 ULONG dwSize
= CRegKey::_GetMultiStringSize(pszValue
);
1269 return SetValue(pszValueName
, REG_MULTI_SZ
, pszValue
, dwSize
);
1272 LONG
SetQWORDValue(LPCTSTR pszValueName
, ULONGLONG qwValue
) throw()
1274 ULONG dwSize
= sizeof(ULONGLONG
);
1275 return SetValue(pszValueName
, REG_QWORD
, &qwValue
, dwSize
);
1278 LONG
NotifyChangeKeyValue(BOOL bWatchSubtree
, DWORD dwNotifyFilter
,
1279 HANDLE hEvent
, BOOL bAsync
= TRUE
) throw()
1282 LONG ret
= ::RegNotifyChangeKeyValue(m_hKey
, bWatchSubtree
,
1283 dwNotifyFilter
, hEvent
, bAsync
);
1287 LONG
Flush() throw()
1290 LONG ret
= ::RegFlushKey(m_hKey
);
1294 static LONG WINAPI
SetValue(HKEY hKeyParent
, LPCTSTR lpszKeyName
,
1295 LPCTSTR lpszValue
, LPCTSTR lpszValueName
= NULL
)
1298 LONG lRet
= key
.Create(hKeyParent
, lpszKeyName
);
1299 if (lRet
== ERROR_SUCCESS
)
1301 lRet
= key
.SetStringValue(lpszValueName
, lpszValue
);
1306 LONG
SetKeyValue(LPCTSTR lpszKeyName
, LPCTSTR lpszValue
,
1307 LPCTSTR lpszValueName
= NULL
) throw()
1310 LONG lRet
= key
.Create(m_hKey
, lpszKeyName
);
1311 if (lRet
== ERROR_SUCCESS
)
1313 lRet
= key
.SetStringValue(lpszValueName
, lpszValue
);
1318 LONG
DeleteValue(LPCTSTR lpszValue
) throw()
1321 return ::RegDeleteValue(m_hKey
, lpszValue
);
1324 LONG
DeleteSubKey(LPCTSTR lpszSubKey
) throw()
1327 ATLASSERT(lpszSubKey
);
1328 return ::RegDeleteKey(m_hKey
, lpszSubKey
);
1331 LONG
RecurseDeleteKey(LPCTSTR lpszKey
) throw()
1335 return CRegKey::_DoDeleteKeyTree(m_hKey
, lpszKey
);
1338 LONG
EnumKey(DWORD iIndex
, LPTSTR pszName
, LPDWORD pnNameLength
,
1339 FILETIME
* pftLastWriteTime
= NULL
) throw()
1342 LONG ret
= ::RegEnumKeyEx(m_hKey
, iIndex
, pszName
, pnNameLength
, NULL
,
1343 NULL
, NULL
, pftLastWriteTime
);
1347 LONG
GetKeySecurity(SECURITY_INFORMATION si
, PSECURITY_DESCRIPTOR psd
,
1348 LPDWORD pnBytes
) throw()
1351 LONG ret
= ::RegGetKeySecurity(m_hKey
, si
, psd
, pnBytes
);
1355 LONG
SetKeySecurity(SECURITY_INFORMATION si
,
1356 PSECURITY_DESCRIPTOR psd
) throw()
1359 LONG ret
= ::RegSetKeySecurity(m_hKey
, si
, psd
);
1363 operator HKEY() const throw()
1368 CRegKey
& operator=(CRegKey
& key
) throw()
1370 Attach(key
.Detach());
1375 // get the total size of a multistring
1376 static ULONG
_GetMultiStringSize(LPCTSTR pszz
)
1381 int len
= _tcslen(pszz
);
1384 } while (*pszz
!= TEXT('\0'));
1386 return count
* sizeof(TCHAR
);
1389 // delete key recursively
1390 static LONG
_DoDeleteKeyTree(HKEY hParentKey
, LPCTSTR lpszKey
)
1392 ATLASSERT(hParentKey
);
1397 LONG ret
= key
.Open(hParentKey
, lpszKey
);
1398 if (ret
!= ERROR_SUCCESS
)
1400 return ret
; // failure
1403 // get the longest length of subkey names
1405 ret
= ::RegQueryInfoKey(key
, NULL
, NULL
, NULL
, NULL
, &NameMax
, NULL
,
1406 NULL
, NULL
, NULL
, NULL
, NULL
);
1407 if (ret
!= ERROR_SUCCESS
)
1409 return ret
; // failure
1411 ++NameMax
; // for NUL
1413 // allocate the string buffer for names if necessary
1414 TCHAR szNameBuf
[MAX_PATH
], *pszName
;
1415 if (NameMax
> MAX_PATH
)
1417 pszName
= (TCHAR
*)malloc(NameMax
* sizeof(TCHAR
));
1419 if (pszName
== NULL
)
1421 return ERROR_OUTOFMEMORY
; // failure
1427 pszName
= szNameBuf
;
1430 // enumerate every subkey and delete
1433 DWORD Count
= NameMax
;
1434 ret
= key
.EnumKey(0, pszName
, &Count
);
1435 if (ret
!= ERROR_SUCCESS
)
1437 if (ret
== ERROR_NO_MORE_ITEMS
)
1438 ret
= ERROR_SUCCESS
;
1442 ret
= CRegKey::_DoDeleteKeyTree(key
, pszName
);
1443 if (ret
!= ERROR_SUCCESS
)
1450 // delete the subkey
1451 if (ret
== ERROR_SUCCESS
)
1452 ret
= ::RegDeleteKey(hParentKey
, lpszKey
);
1454 // delete the buffer if any
1455 if (pszName
!= szNameBuf
)
1463 class CComHeapPtr
: public CHeapPtr
<T
, CComAllocator
>
1470 explicit CComHeapPtr(T
*lp
) :
1471 CHeapPtr
<T
, CComAllocator
>(lp
)
1477 inline HRESULT __stdcall
AtlAdvise(IUnknown
*pUnkCP
, IUnknown
*pUnk
, const IID
&iid
, LPDWORD pdw
)
1479 CComPtr
<IConnectionPointContainer
> container
;
1480 CComPtr
<IConnectionPoint
> connectionPoint
;
1484 return E_INVALIDARG
;
1485 hResult
= pUnkCP
->QueryInterface(IID_IConnectionPointContainer
, (void **)&container
);
1486 if (FAILED(hResult
))
1488 hResult
= container
->FindConnectionPoint(iid
, &connectionPoint
);
1489 if (FAILED(hResult
))
1491 return connectionPoint
->Advise(pUnk
, pdw
);
1494 inline HRESULT __stdcall
AtlUnadvise(IUnknown
*pUnkCP
, const IID
&iid
, DWORD dw
)
1496 CComPtr
<IConnectionPointContainer
> container
;
1497 CComPtr
<IConnectionPoint
> connectionPoint
;
1501 return E_INVALIDARG
;
1502 hResult
= pUnkCP
->QueryInterface(IID_IConnectionPointContainer
, (void **)&container
);
1503 if (FAILED(hResult
))
1505 hResult
= container
->FindConnectionPoint(iid
, &connectionPoint
);
1506 if (FAILED(hResult
))
1508 return connectionPoint
->Unadvise(dw
);
1511 inline HRESULT __stdcall
AtlInternalQueryInterface(void *pThis
, const _ATL_INTMAP_ENTRY
*pEntries
, REFIID iid
, void **ppvObject
)
1514 IUnknown
*resultInterface
;
1517 ATLASSERT(pThis
!= NULL
&& pEntries
!= NULL
);
1518 if (pThis
== NULL
|| pEntries
== NULL
)
1519 return E_INVALIDARG
;
1520 ATLASSERT(ppvObject
!= NULL
);
1521 if (ppvObject
== NULL
)
1524 if (InlineIsEqualUnknown(iid
))
1526 resultInterface
= reinterpret_cast<IUnknown
*>(reinterpret_cast<char *>(pThis
) + pEntries
[0].dw
);
1527 *ppvObject
= resultInterface
;
1528 resultInterface
->AddRef();
1533 while (pEntries
[i
].pFunc
!= 0)
1535 if (pEntries
[i
].piid
== NULL
|| InlineIsEqualGUID(iid
, *pEntries
[i
].piid
))
1537 if (pEntries
[i
].pFunc
== reinterpret_cast<_ATL_CREATORARGFUNC
*>(1))
1539 ATLASSERT(pEntries
[i
].piid
!= NULL
);
1540 resultInterface
= reinterpret_cast<IUnknown
*>(reinterpret_cast<char *>(pThis
) + pEntries
[i
].dw
);
1541 *ppvObject
= resultInterface
;
1542 resultInterface
->AddRef();
1547 hResult
= pEntries
[i
].pFunc(pThis
, iid
, ppvObject
, 0);
1548 if (hResult
== S_OK
)
1550 if (FAILED(hResult
) && pEntries
[i
].piid
!= NULL
)
1557 return E_NOINTERFACE
;
1560 inline HRESULT __stdcall
AtlWinModuleInit(_ATL_WIN_MODULE
*pWinModule
)
1562 if (pWinModule
== NULL
)
1563 return E_INVALIDARG
;
1564 pWinModule
->m_pCreateWndList
= NULL
;
1565 return pWinModule
->m_csWindowCreate
.Init();
1568 inline HRESULT __stdcall
AtlWinModuleTerm(_ATL_WIN_MODULE
*pWinModule
, HINSTANCE hInst
)
1570 if (pWinModule
== NULL
)
1571 return E_INVALIDARG
;
1572 pWinModule
->m_csWindowCreate
.Term();
1576 inline void __stdcall
AtlWinModuleAddCreateWndData(_ATL_WIN_MODULE
*pWinModule
, _AtlCreateWndData
*pData
, void *pObject
)
1578 CComCritSecLock
<CComCriticalSection
> lock(pWinModule
->m_csWindowCreate
, true);
1580 ATLASSERT(pWinModule
!= NULL
);
1581 ATLASSERT(pObject
!= NULL
);
1583 pData
->m_pThis
= pObject
;
1584 pData
->m_dwThreadID
= ::GetCurrentThreadId();
1585 pData
->m_pNext
= pWinModule
->m_pCreateWndList
;
1586 pWinModule
->m_pCreateWndList
= pData
;
1589 inline void *__stdcall
AtlWinModuleExtractCreateWndData(_ATL_WIN_MODULE
*pWinModule
)
1591 CComCritSecLock
<CComCriticalSection
> lock(pWinModule
->m_csWindowCreate
, true);
1593 _AtlCreateWndData
*currentEntry
;
1594 _AtlCreateWndData
**previousLink
;
1597 ATLASSERT(pWinModule
!= NULL
);
1600 threadID
= GetCurrentThreadId();
1601 currentEntry
= pWinModule
->m_pCreateWndList
;
1602 previousLink
= &pWinModule
->m_pCreateWndList
;
1603 while (currentEntry
!= NULL
)
1605 if (currentEntry
->m_dwThreadID
== threadID
)
1607 *previousLink
= currentEntry
->m_pNext
;
1608 result
= currentEntry
->m_pThis
;
1611 previousLink
= ¤tEntry
->m_pNext
;
1612 currentEntry
= currentEntry
->m_pNext
;
1617 // Adapted from dll/win32/atl/atl.c
1618 inline HRESULT WINAPI
AtlLoadTypeLib(HINSTANCE inst
, LPCOLESTR lpszIndex
,
1619 BSTR
*pbstrPath
, ITypeLib
**ppTypeLib
)
1621 size_t index_len
= lpszIndex
? wcslen(lpszIndex
) : 0;
1622 CComHeapPtr
<WCHAR
> path
;
1623 path
.Allocate(MAX_PATH
+ index_len
+ wcslen(L
".tlb"));
1626 return E_OUTOFMEMORY
;
1628 size_t path_len
= GetModuleFileNameW(inst
, path
, MAX_PATH
);
1630 return HRESULT_FROM_WIN32(GetLastError());
1633 wcscat(path
, lpszIndex
);
1635 CComPtr
<ITypeLib
> typelib
;
1636 HRESULT hResult
= LoadTypeLib(path
, &typelib
);
1637 if (FAILED(hResult
))
1640 for (ptr
= path
+path_len
-1; ptr
> path
&& *ptr
!= '\\' && *ptr
!= '.'; ptr
--)
1643 ptr
= (WCHAR
*)path
+ path_len
;
1644 wcscpy(ptr
, L
".tlb");
1646 hResult
= LoadTypeLib(path
, &typelib
);
1649 if (SUCCEEDED(hResult
))
1651 *pbstrPath
= SysAllocString(path
);
1655 hResult
= E_OUTOFMEMORY
;
1659 if (FAILED(hResult
))
1662 *ppTypeLib
= typelib
.Detach();
1666 // Adapted from dll/win32/atl/atl.c
1667 inline HRESULT WINAPI
AtlRegisterTypeLib(HINSTANCE inst
, const WCHAR
*index
)
1670 CComPtr
<ITypeLib
> typelib
;
1671 HRESULT hResult
= AtlLoadTypeLib(inst
, index
, &path
, &typelib
);
1672 if (FAILED(hResult
))
1675 return RegisterTypeLib(typelib
, path
, NULL
); /* FIXME: pass help directory */
1678 // Adapted from dll/win32/atl/atl.c
1679 inline HRESULT WINAPI
AtlRegisterClassCategoriesHelper(REFCLSID clsid
, const _ATL_CATMAP_ENTRY
*catmap
, BOOL reg
)
1684 CComPtr
<ICatRegister
> catreg
;
1686 HRESULT hResult
= CoCreateInstance(CLSID_StdComponentCategoriesMgr
, NULL
, CLSCTX_INPROC_SERVER
, IID_ICatRegister
, (void**)&catreg
);
1687 if (FAILED(hResult
))
1690 for (const _ATL_CATMAP_ENTRY
*iter
= catmap
; iter
->iType
!= _ATL_CATMAP_ENTRY_END
; iter
++)
1692 CATID catid
= *iter
->pcatid
;
1694 if (iter
->iType
== _ATL_CATMAP_ENTRY_IMPLEMENTED
)
1697 hResult
= catreg
->RegisterClassImplCategories(clsid
, 1, &catid
);
1699 hResult
= catreg
->UnRegisterClassImplCategories(clsid
, 1, &catid
);
1704 hResult
= catreg
->RegisterClassReqCategories(clsid
, 1, &catid
);
1706 hResult
= catreg
->UnRegisterClassReqCategories(clsid
, 1, &catid
);
1708 if (FAILED(hResult
))
1714 WCHAR reg_path
[256] = L
"CLSID\\";
1716 StringFromGUID2(clsid
, reg_path
+ wcslen(reg_path
), 64);
1717 wcscat(reg_path
, L
"\\");
1718 WCHAR
* ptr
= reg_path
+ wcslen(reg_path
);
1720 wcscpy(ptr
, L
"Implemented Categories");
1721 RegDeleteKeyW(HKEY_CLASSES_ROOT
, reg_path
);
1723 wcscpy(ptr
, L
"Required Categories");
1724 RegDeleteKeyW(HKEY_CLASSES_ROOT
, reg_path
);
1731 // Adapted from dll/win32/atl80/atl80.c
1732 inline HRESULT __stdcall
AtlComModuleRegisterServer(_ATL_COM_MODULE
*mod
, BOOL bRegTypeLib
, const CLSID
*clsid
)
1734 HRESULT hResult
= S_OK
;
1736 for (_ATL_OBJMAP_ENTRY
** iter
= mod
->m_ppAutoObjMapFirst
; iter
< mod
->m_ppAutoObjMapLast
; iter
++)
1740 _ATL_OBJMAP_ENTRY
* entry
= *iter
;
1741 if (clsid
&& !IsEqualCLSID(*entry
->pclsid
, *clsid
))
1744 hResult
= entry
->pfnUpdateRegistry(TRUE
);
1745 if (FAILED(hResult
))
1748 const _ATL_CATMAP_ENTRY
*catmap
= entry
->pfnGetCategoryMap();
1751 hResult
= AtlRegisterClassCategoriesHelper(*entry
->pclsid
, catmap
, TRUE
);
1752 if (FAILED(hResult
))
1759 hResult
= AtlRegisterTypeLib(mod
->m_hInstTypeLib
, NULL
);
1765 // Adapted from dll/win32/atl/atl.c
1766 inline HRESULT WINAPI
AtlComModuleUnregisterServer(_ATL_COM_MODULE
*mod
, BOOL bUnRegTypeLib
, const CLSID
*clsid
)
1768 HRESULT hResult
= S_OK
;
1770 for (_ATL_OBJMAP_ENTRY
**iter
= mod
->m_ppAutoObjMapFirst
; iter
< mod
->m_ppAutoObjMapLast
; iter
++)
1774 _ATL_OBJMAP_ENTRY
* entry
= *iter
;
1775 if (clsid
&& !IsEqualCLSID(*entry
->pclsid
, *clsid
))
1778 const _ATL_CATMAP_ENTRY
*catmap
= entry
->pfnGetCategoryMap();
1781 hResult
= AtlRegisterClassCategoriesHelper(*entry
->pclsid
, catmap
, FALSE
);
1782 if (FAILED(hResult
))
1786 hResult
= entry
->pfnUpdateRegistry(FALSE
);
1787 if (FAILED(hResult
))
1793 CComPtr
<ITypeLib
> typelib
;
1797 hResult
= AtlLoadTypeLib(mod
->m_hInstTypeLib
, NULL
, &path
, &typelib
);
1798 if (FAILED(hResult
))
1801 hResult
= typelib
->GetLibAttr(&attr
);
1802 if (SUCCEEDED(hResult
))
1804 hResult
= UnRegisterTypeLib(attr
->guid
, attr
->wMajorVerNum
, attr
->wMinorVerNum
, attr
->lcid
, attr
->syskind
);
1805 typelib
->ReleaseTLibAttr(attr
);
1813 // Adapted from dll/win32/atl/atl.c
1814 inline HRESULT WINAPI
AtlComModuleRegisterClassObjects(_ATL_COM_MODULE
*module
, DWORD context
, DWORD flags
)
1816 _ATL_OBJMAP_ENTRY
**iter
;
1817 IUnknown
* unk
= NULL
;
1821 return E_INVALIDARG
;
1823 for (iter
= module
->m_ppAutoObjMapFirst
; iter
< module
->m_ppAutoObjMapLast
; iter
++)
1825 if (!(*iter
)->pfnGetClassObject
)
1828 hr
= (*iter
)->pfnGetClassObject((void*)(*iter
)->pfnCreateInstance
, IID_IUnknown
, (void**)&unk
);
1832 hr
= CoRegisterClassObject(*(*iter
)->pclsid
, unk
, context
, flags
, &(*iter
)->dwRegister
);
1842 // Adapted from dll/win32/atl/atl.c
1843 inline HRESULT WINAPI
AtlComModuleRevokeClassObjects(_ATL_COM_MODULE
*module
)
1845 _ATL_OBJMAP_ENTRY
**iter
;
1849 return E_INVALIDARG
;
1851 for (iter
= module
->m_ppAutoObjMapFirst
; iter
< module
->m_ppAutoObjMapLast
; iter
++)
1853 hr
= CoRevokeClassObject((*iter
)->dwRegister
);
1864 #ifndef _ATL_NO_AUTOMATIC_NAMESPACE
1865 using namespace ATL
;
1866 #endif //!_ATL_NO_AUTOMATIC_NAMESPACE