2 * Copyright 2012 Stefan Leichter
3 * Copyright 2012 Jacek Caban for CodeWeavers
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 #include "wine/atlbase.h"
23 #include "wine/atlcom.h"
25 #include "wine/debug.h"
26 #include "wine/heap.h"
27 #include "wine/unicode.h"
33 WINE_DEFAULT_DEBUG_CHANNEL(atl
);
35 #define ATLVer1Size FIELD_OFFSET(_ATL_MODULEW, dwAtlBuildVer)
37 HINSTANCE atl_instance
;
39 typedef unsigned char cpp_bool
;
41 static ICatRegister
*catreg
;
43 /***********************************************************************
44 * AtlAdvise [atl100.@]
46 HRESULT WINAPI
AtlAdvise(IUnknown
*pUnkCP
, IUnknown
*pUnk
, const IID
*iid
, DWORD
*pdw
)
48 IConnectionPointContainer
*container
;
52 TRACE("%p %p %p %p\n", pUnkCP
, pUnk
, iid
, pdw
);
57 hres
= IUnknown_QueryInterface(pUnkCP
, &IID_IConnectionPointContainer
, (void**)&container
);
61 hres
= IConnectionPointContainer_FindConnectionPoint(container
, iid
, &cp
);
62 IConnectionPointContainer_Release(container
);
66 hres
= IConnectionPoint_Advise(cp
, pUnk
, pdw
);
67 IConnectionPoint_Release(cp
);
71 /***********************************************************************
72 * AtlUnadvise [atl100.@]
74 HRESULT WINAPI
AtlUnadvise(IUnknown
*pUnkCP
, const IID
*iid
, DWORD dw
)
76 IConnectionPointContainer
*container
;
80 TRACE("%p %p %d\n", pUnkCP
, iid
, dw
);
85 hres
= IUnknown_QueryInterface(pUnkCP
, &IID_IConnectionPointContainer
, (void**)&container
);
89 hres
= IConnectionPointContainer_FindConnectionPoint(container
, iid
, &cp
);
90 IConnectionPointContainer_Release(container
);
94 hres
= IConnectionPoint_Unadvise(cp
, dw
);
95 IConnectionPoint_Release(cp
);
99 /***********************************************************************
100 * AtlFreeMarshalStream [atl100.@]
102 HRESULT WINAPI
AtlFreeMarshalStream(IStream
*stm
)
108 /***********************************************************************
109 * AtlMarshalPtrInProc [atl100.@]
111 HRESULT WINAPI
AtlMarshalPtrInProc(IUnknown
*pUnk
, const IID
*iid
, IStream
**pstm
)
113 FIXME("%p %p %p\n", pUnk
, iid
, pstm
);
117 /***********************************************************************
118 * AtlUnmarshalPtr [atl100.@]
120 HRESULT WINAPI
AtlUnmarshalPtr(IStream
*stm
, const IID
*iid
, IUnknown
**ppUnk
)
122 FIXME("%p %p %p\n", stm
, iid
, ppUnk
);
126 /***********************************************************************
127 * AtlCreateTargetDC [atl100.@]
129 HDC WINAPI
AtlCreateTargetDC( HDC hdc
, DVTARGETDEVICE
*dv
)
131 static const WCHAR displayW
[] = {'d','i','s','p','l','a','y',0};
132 const WCHAR
*driver
= NULL
, *device
= NULL
, *port
= NULL
;
133 DEVMODEW
*devmode
= NULL
;
135 TRACE( "(%p, %p)\n", hdc
, dv
);
139 if (dv
->tdDriverNameOffset
) driver
= (WCHAR
*)((char *)dv
+ dv
->tdDriverNameOffset
);
140 if (dv
->tdDeviceNameOffset
) device
= (WCHAR
*)((char *)dv
+ dv
->tdDeviceNameOffset
);
141 if (dv
->tdPortNameOffset
) port
= (WCHAR
*)((char *)dv
+ dv
->tdPortNameOffset
);
142 if (dv
->tdExtDevmodeOffset
) devmode
= (DEVMODEW
*)((char *)dv
+ dv
->tdExtDevmodeOffset
);
149 return CreateDCW( driver
, device
, port
, devmode
);
152 /***********************************************************************
153 * AtlHiMetricToPixel [atl100.@]
155 void WINAPI
AtlHiMetricToPixel(const SIZEL
* lpHiMetric
, SIZEL
* lpPix
)
157 HDC dc
= GetDC(NULL
);
158 lpPix
->cx
= lpHiMetric
->cx
* GetDeviceCaps( dc
, LOGPIXELSX
) / 100;
159 lpPix
->cy
= lpHiMetric
->cy
* GetDeviceCaps( dc
, LOGPIXELSY
) / 100;
160 ReleaseDC( NULL
, dc
);
163 /***********************************************************************
164 * AtlPixelToHiMetric [atl100.@]
166 void WINAPI
AtlPixelToHiMetric(const SIZEL
* lpPix
, SIZEL
* lpHiMetric
)
168 HDC dc
= GetDC(NULL
);
169 lpHiMetric
->cx
= 100 * lpPix
->cx
/ GetDeviceCaps( dc
, LOGPIXELSX
);
170 lpHiMetric
->cy
= 100 * lpPix
->cy
/ GetDeviceCaps( dc
, LOGPIXELSY
);
171 ReleaseDC( NULL
, dc
);
174 /***********************************************************************
175 * AtlComPtrAssign [atl100.@]
177 IUnknown
* WINAPI
AtlComPtrAssign(IUnknown
** pp
, IUnknown
*p
)
179 TRACE("(%p %p)\n", pp
, p
);
181 if (p
) IUnknown_AddRef(p
);
182 if (*pp
) IUnknown_Release(*pp
);
187 /***********************************************************************
188 * AtlComQIPtrAssign [atl100.@]
190 IUnknown
* WINAPI
AtlComQIPtrAssign(IUnknown
** pp
, IUnknown
*p
, REFIID riid
)
192 IUnknown
*new_p
= NULL
;
194 TRACE("(%p %p %s)\n", pp
, p
, debugstr_guid(riid
));
196 if (p
) IUnknown_QueryInterface(p
, riid
, (void **)&new_p
);
197 if (*pp
) IUnknown_Release(*pp
);
202 /***********************************************************************
203 * AtlInternalQueryInterface [atl100.@]
205 HRESULT WINAPI
AtlInternalQueryInterface(void* this, const _ATL_INTMAP_ENTRY
* pEntries
, REFIID iid
, void** ppvObject
)
208 HRESULT rc
= E_NOINTERFACE
;
209 TRACE("(%p, %p, %s, %p)\n",this, pEntries
, debugstr_guid(iid
), ppvObject
);
211 if (IsEqualGUID(iid
,&IID_IUnknown
))
213 TRACE("Returning IUnknown\n");
214 *ppvObject
= ((LPSTR
)this+pEntries
[0].dw
);
215 IUnknown_AddRef((IUnknown
*)*ppvObject
);
219 while (pEntries
[i
].pFunc
!= 0)
221 TRACE("Trying entry %i (%s %i %p)\n",i
,debugstr_guid(pEntries
[i
].piid
),
222 pEntries
[i
].dw
, pEntries
[i
].pFunc
);
224 if (!pEntries
[i
].piid
|| IsEqualGUID(iid
,pEntries
[i
].piid
))
227 if (pEntries
[i
].pFunc
== (_ATL_CREATORARGFUNC
*)1)
230 *ppvObject
= ((LPSTR
)this+pEntries
[i
].dw
);
231 IUnknown_AddRef((IUnknown
*)*ppvObject
);
237 rc
= pEntries
[i
].pFunc(this, iid
, ppvObject
, pEntries
[i
].dw
);
238 if(rc
==S_OK
|| pEntries
[i
].piid
)
244 TRACE("Done returning (0x%x)\n",rc
);
248 /***********************************************************************
249 * AtlIPersistStreamInit_Load [atl100.@]
251 HRESULT WINAPI
AtlIPersistStreamInit_Load( LPSTREAM pStm
, ATL_PROPMAP_ENTRY
*pMap
,
252 void *pThis
, IUnknown
*pUnk
)
254 FIXME("(%p, %p, %p, %p)\n", pStm
, pMap
, pThis
, pUnk
);
259 /***********************************************************************
260 * AtlIPersistStreamInit_Save [atl100.@]
262 HRESULT WINAPI
AtlIPersistStreamInit_Save(LPSTREAM pStm
, BOOL fClearDirty
,
263 ATL_PROPMAP_ENTRY
*pMap
, void *pThis
,
266 FIXME("(%p, %d, %p, %p, %p)\n", pStm
, fClearDirty
, pMap
, pThis
, pUnk
);
271 /***********************************************************************
272 * AtlIPersistPropertyBag_Load [atl100.@]
274 HRESULT WINAPI
AtlIPersistPropertyBag_Load(LPPROPERTYBAG pPropBag
, LPERRORLOG pErrorLog
,
275 ATL_PROPMAP_ENTRY
*pMap
, void *pThis
,
278 FIXME("(%p, %p, %p, %p, %p)\n", pPropBag
, pErrorLog
, pMap
, pThis
, pUnk
);
283 /***********************************************************************
284 * AtlIPersistPropertyBag_Save [atl100.@]
286 HRESULT WINAPI
AtlIPersistPropertyBag_Save(LPPROPERTYBAG pPropBag
, BOOL fClearDirty
,
287 BOOL fSaveAll
, ATL_PROPMAP_ENTRY
*pMap
,
288 void *pThis
, IUnknown
*pUnk
)
290 FIXME("(%p, %d, %d, %p, %p, %p)\n", pPropBag
, fClearDirty
, fSaveAll
, pMap
, pThis
, pUnk
);
295 /***********************************************************************
296 * AtlModuleAddTermFunc [atl100.@]
298 HRESULT WINAPI
AtlModuleAddTermFunc(_ATL_MODULE
*pM
, _ATL_TERMFUNC
*pFunc
, DWORD_PTR dw
)
300 _ATL_TERMFUNC_ELEM
*termfunc_elem
;
302 TRACE("version %04x (%p %p %ld)\n", _ATL_VER
, pM
, pFunc
, dw
);
304 if (_ATL_VER
> _ATL_VER_30
|| pM
->cbSize
> ATLVer1Size
) {
305 termfunc_elem
= HeapAlloc(GetProcessHeap(), 0, sizeof(_ATL_TERMFUNC_ELEM
));
306 termfunc_elem
->pFunc
= pFunc
;
307 termfunc_elem
->dw
= dw
;
308 termfunc_elem
->pNext
= pM
->m_pTermFuncs
;
310 pM
->m_pTermFuncs
= termfunc_elem
;
316 #if _ATL_VER > _ATL_VER_30
318 /***********************************************************************
319 * AtlCallTermFunc [atl100.@]
321 void WINAPI
AtlCallTermFunc(_ATL_MODULE
*pM
)
323 _ATL_TERMFUNC_ELEM
*iter
= pM
->m_pTermFuncs
, *tmp
;
328 iter
->pFunc(iter
->dw
);
331 HeapFree(GetProcessHeap(), 0, tmp
);
334 pM
->m_pTermFuncs
= NULL
;
339 /***********************************************************************
340 * AtlLoadTypeLib [atl100.56]
342 HRESULT WINAPI
AtlLoadTypeLib(HINSTANCE inst
, LPCOLESTR lpszIndex
,
343 BSTR
*pbstrPath
, ITypeLib
**ppTypeLib
)
345 size_t path_len
, index_len
;
346 ITypeLib
*typelib
= NULL
;
350 static const WCHAR tlb_extW
[] = {'.','t','l','b',0};
352 TRACE("(%p %s %p %p)\n", inst
, debugstr_w(lpszIndex
), pbstrPath
, ppTypeLib
);
354 index_len
= lpszIndex
? strlenW(lpszIndex
) : 0;
355 path
= heap_alloc((MAX_PATH
+index_len
)*sizeof(WCHAR
) + sizeof(tlb_extW
));
357 return E_OUTOFMEMORY
;
359 path_len
= GetModuleFileNameW(inst
, path
, MAX_PATH
);
362 return HRESULT_FROM_WIN32(GetLastError());
366 memcpy(path
+path_len
, lpszIndex
, (index_len
+1)*sizeof(WCHAR
));
368 hres
= LoadTypeLib(path
, &typelib
);
372 for(ptr
= path
+path_len
-1; ptr
> path
&& *ptr
!= '\\' && *ptr
!= '.'; ptr
--);
375 memcpy(ptr
, tlb_extW
, sizeof(tlb_extW
));
376 hres
= LoadTypeLib(path
, &typelib
);
379 if(SUCCEEDED(hres
)) {
380 *pbstrPath
= SysAllocString(path
);
382 ITypeLib_Release(typelib
);
383 hres
= E_OUTOFMEMORY
;
391 *ppTypeLib
= typelib
;
395 #if _ATL_VER <= _ATL_VER_80
397 /***********************************************************************
398 * AtlRegisterTypeLib [atl80.19]
400 HRESULT WINAPI
AtlRegisterTypeLib(HINSTANCE inst
, const WCHAR
*index
)
406 TRACE("(%p %s)\n", inst
, debugstr_w(index
));
408 hres
= AtlLoadTypeLib(inst
, index
, &path
, &typelib
);
412 hres
= RegisterTypeLib(typelib
, path
, NULL
); /* FIXME: pass help directory */
413 ITypeLib_Release(typelib
);
420 #if _ATL_VER > _ATL_VER_30
422 /***********************************************************************
423 * AtlWinModuleInit [atl100.65]
425 HRESULT WINAPI
AtlWinModuleInit(_ATL_WIN_MODULE
*winmod
)
427 TRACE("(%p)\n", winmod
);
429 if(winmod
->cbSize
!= sizeof(*winmod
))
432 InitializeCriticalSection(&winmod
->m_csWindowCreate
);
433 winmod
->m_pCreateWndList
= NULL
;
437 /***********************************************************************
438 * AtlWinModuleAddCreateWndData [atl100.43]
440 void WINAPI
AtlWinModuleAddCreateWndData(_ATL_WIN_MODULE
*pM
, _AtlCreateWndData
*pData
, void *pvObject
)
442 TRACE("(%p, %p, %p)\n", pM
, pData
, pvObject
);
444 pData
->m_pThis
= pvObject
;
445 pData
->m_dwThreadID
= GetCurrentThreadId();
447 EnterCriticalSection(&pM
->m_csWindowCreate
);
448 pData
->m_pNext
= pM
->m_pCreateWndList
;
449 pM
->m_pCreateWndList
= pData
;
450 LeaveCriticalSection(&pM
->m_csWindowCreate
);
453 /***********************************************************************
454 * AtlWinModuleExtractCreateWndData [atl100.44]
456 void* WINAPI
AtlWinModuleExtractCreateWndData(_ATL_WIN_MODULE
*winmod
)
458 _AtlCreateWndData
*iter
, *prev
= NULL
;
461 TRACE("(%p)\n", winmod
);
463 thread_id
= GetCurrentThreadId();
465 EnterCriticalSection(&winmod
->m_csWindowCreate
);
467 for(iter
= winmod
->m_pCreateWndList
; iter
&& iter
->m_dwThreadID
!= thread_id
; iter
= iter
->m_pNext
)
471 prev
->m_pNext
= iter
->m_pNext
;
473 winmod
->m_pCreateWndList
= iter
->m_pNext
;
476 LeaveCriticalSection(&winmod
->m_csWindowCreate
);
478 return iter
? iter
->m_pThis
: NULL
;
481 /***********************************************************************
482 * AtlComModuleGetClassObject [atl100.15]
484 #if _ATL_VER < _ATL_VER_110
485 HRESULT WINAPI
AtlComModuleGetClassObject(_ATL_COM_MODULE
*pm
, REFCLSID rclsid
, REFIID riid
, void **ppv
)
487 _ATL_OBJMAP_ENTRY
**iter
;
490 TRACE("(%p %s %s %p)\n", pm
, debugstr_guid(rclsid
), debugstr_guid(riid
), ppv
);
495 for(iter
= pm
->m_ppAutoObjMapFirst
; iter
< pm
->m_ppAutoObjMapLast
; iter
++) {
496 if(IsEqualCLSID((*iter
)->pclsid
, rclsid
) && (*iter
)->pfnGetClassObject
) {
498 hres
= (*iter
)->pfnGetClassObject((*iter
)->pfnCreateInstance
, &IID_IUnknown
, (void**)&(*iter
)->pCF
);
500 hres
= IUnknown_QueryInterface((*iter
)->pCF
, riid
, ppv
);
501 TRACE("returning %p (%08x)\n", *ppv
, hres
);
506 WARN("Class %s not found\n", debugstr_guid(rclsid
));
507 return CLASS_E_CLASSNOTAVAILABLE
;
510 HRESULT WINAPI
AtlComModuleGetClassObject(_ATL_COM_MODULE
*pm
, REFCLSID rclsid
, REFIID riid
, void **ppv
)
512 _ATL_OBJMAP_ENTRY_EX
**iter
;
515 TRACE("(%p %s %s %p)\n", pm
, debugstr_guid(rclsid
), debugstr_guid(riid
), ppv
);
520 for(iter
= pm
->m_ppAutoObjMapFirst
; iter
< pm
->m_ppAutoObjMapLast
; iter
++) {
521 if(IsEqualCLSID((*iter
)->pclsid
, rclsid
) && (*iter
)->pfnGetClassObject
) {
522 if(!(*iter
)->pCache
->pCF
)
523 hres
= (*iter
)->pfnGetClassObject((*iter
)->pfnCreateInstance
, &IID_IUnknown
, (void**)&(*iter
)->pCache
->pCF
);
524 if((*iter
)->pCache
->pCF
)
525 hres
= IUnknown_QueryInterface((*iter
)->pCache
->pCF
, riid
, ppv
);
526 TRACE("returning %p (%08x)\n", *ppv
, hres
);
531 WARN("Class %s not found\n", debugstr_guid(rclsid
));
532 return CLASS_E_CLASSNOTAVAILABLE
;
536 /***********************************************************************
537 * AtlComModuleRegisterClassObjects [atl100.17]
539 #if _ATL_VER < _ATL_VER_110
540 HRESULT WINAPI
AtlComModuleRegisterClassObjects(_ATL_COM_MODULE
*module
, DWORD context
, DWORD flags
)
542 _ATL_OBJMAP_ENTRY
**iter
;
546 TRACE("(%p %x %x)\n", module
, context
, flags
);
551 for(iter
= module
->m_ppAutoObjMapFirst
; iter
< module
->m_ppAutoObjMapLast
; iter
++) {
552 if(!(*iter
)->pfnGetClassObject
)
555 hres
= (*iter
)->pfnGetClassObject((*iter
)->pfnCreateInstance
, &IID_IUnknown
, (void**)&unk
);
559 hres
= CoRegisterClassObject((*iter
)->pclsid
, unk
, context
, flags
, &(*iter
)->dwRegister
);
560 IUnknown_Release(unk
);
568 HRESULT WINAPI
AtlComModuleRegisterClassObjects(_ATL_COM_MODULE
*module
, DWORD context
, DWORD flags
)
570 _ATL_OBJMAP_ENTRY_EX
**iter
;
574 TRACE("(%p %x %x)\n", module
, context
, flags
);
579 for(iter
= module
->m_ppAutoObjMapFirst
; iter
< module
->m_ppAutoObjMapLast
; iter
++) {
580 if(!(*iter
)->pfnGetClassObject
)
583 hres
= (*iter
)->pfnGetClassObject((*iter
)->pfnCreateInstance
, &IID_IUnknown
, (void**)&unk
);
587 hres
= CoRegisterClassObject((*iter
)->pclsid
, unk
, context
, flags
, &(*iter
)->pCache
->dwRegister
);
588 IUnknown_Release(unk
);
597 /***********************************************************************
598 * AtlComModuleRevokeClassObjects [atl100.20]
600 #if _ATL_VER < _ATL_VER_110
601 HRESULT WINAPI
AtlComModuleRevokeClassObjects(_ATL_COM_MODULE
*module
)
603 _ATL_OBJMAP_ENTRY
**iter
;
606 TRACE("(%p)\n", module
);
611 for(iter
= module
->m_ppAutoObjMapFirst
; iter
< module
->m_ppAutoObjMapLast
; iter
++) {
612 hres
= CoRevokeClassObject((*iter
)->dwRegister
);
620 HRESULT WINAPI
AtlComModuleRevokeClassObjects(_ATL_COM_MODULE
*module
)
622 _ATL_OBJMAP_ENTRY_EX
**iter
;
625 TRACE("(%p)\n", module
);
630 for(iter
= module
->m_ppAutoObjMapFirst
; iter
< module
->m_ppAutoObjMapLast
; iter
++) {
631 hres
= CoRevokeClassObject((*iter
)->pCache
->dwRegister
);
640 /***********************************************************************
641 * AtlComModuleUnregisterServer [atl100.22]
643 #if _ATL_VER < _ATL_VER_110
644 HRESULT WINAPI
AtlComModuleUnregisterServer(_ATL_COM_MODULE
*mod
, BOOL bRegTypeLib
, const CLSID
*clsid
)
646 const struct _ATL_CATMAP_ENTRY
*catmap
;
647 _ATL_OBJMAP_ENTRY
**iter
;
650 TRACE("(%p %x %s)\n", mod
, bRegTypeLib
, debugstr_guid(clsid
));
652 for(iter
= mod
->m_ppAutoObjMapFirst
; iter
< mod
->m_ppAutoObjMapLast
; iter
++) {
653 if(!*iter
|| (clsid
&& !IsEqualCLSID((*iter
)->pclsid
, clsid
)))
656 TRACE("Unregistering clsid %s\n", debugstr_guid((*iter
)->pclsid
));
658 catmap
= (*iter
)->pfnGetCategoryMap();
660 hres
= AtlRegisterClassCategoriesHelper((*iter
)->pclsid
, catmap
, FALSE
);
665 hres
= (*iter
)->pfnUpdateRegistry(FALSE
);
675 hres
= AtlLoadTypeLib(mod
->m_hInstTypeLib
, NULL
, &path
, &typelib
);
680 hres
= ITypeLib_GetLibAttr(typelib
, &attr
);
681 if(SUCCEEDED(hres
)) {
682 hres
= UnRegisterTypeLib(&attr
->guid
, attr
->wMajorVerNum
, attr
->wMinorVerNum
, attr
->lcid
, attr
->syskind
);
683 ITypeLib_ReleaseTLibAttr(typelib
, attr
);
685 ITypeLib_Release(typelib
);
693 HRESULT WINAPI
AtlComModuleUnregisterServer(_ATL_COM_MODULE
*mod
, BOOL bRegTypeLib
, const CLSID
*clsid
)
695 const struct _ATL_CATMAP_ENTRY
*catmap
;
696 _ATL_OBJMAP_ENTRY_EX
**iter
;
699 TRACE("(%p %x %s)\n", mod
, bRegTypeLib
, debugstr_guid(clsid
));
701 for(iter
= mod
->m_ppAutoObjMapFirst
; iter
< mod
->m_ppAutoObjMapLast
; iter
++) {
702 if(!*iter
|| (clsid
&& !IsEqualCLSID((*iter
)->pclsid
, clsid
)))
705 TRACE("Unregistering clsid %s\n", debugstr_guid((*iter
)->pclsid
));
707 catmap
= (*iter
)->pfnGetCategoryMap();
709 hres
= AtlRegisterClassCategoriesHelper((*iter
)->pclsid
, catmap
, FALSE
);
714 hres
= (*iter
)->pfnUpdateRegistry(FALSE
);
724 hres
= AtlLoadTypeLib(mod
->m_hInstTypeLib
, NULL
, &path
, &typelib
);
729 hres
= ITypeLib_GetLibAttr(typelib
, &attr
);
730 if(SUCCEEDED(hres
)) {
731 hres
= UnRegisterTypeLib(&attr
->guid
, attr
->wMajorVerNum
, attr
->wMinorVerNum
, attr
->lcid
, attr
->syskind
);
732 ITypeLib_ReleaseTLibAttr(typelib
, attr
);
734 ITypeLib_Release(typelib
);
745 /***********************************************************************
746 * AtlRegisterClassCategoriesHelper [atl100.49]
748 HRESULT WINAPI
AtlRegisterClassCategoriesHelper(REFCLSID clsid
, const struct _ATL_CATMAP_ENTRY
*catmap
, BOOL reg
)
750 const struct _ATL_CATMAP_ENTRY
*iter
;
753 TRACE("(%s %p %x)\n", debugstr_guid(clsid
), catmap
, reg
);
759 ICatRegister
*new_catreg
;
761 hres
= CoCreateInstance(&CLSID_StdComponentCategoriesMgr
, NULL
, CLSCTX_INPROC_SERVER
,
762 &IID_ICatRegister
, (void**)&new_catreg
);
766 if(InterlockedCompareExchangePointer((void**)&catreg
, new_catreg
, NULL
))
767 ICatRegister_Release(new_catreg
);
770 for(iter
= catmap
; iter
->iType
!= _ATL_CATMAP_ENTRY_END
; iter
++) {
771 CATID catid
= *iter
->pcatid
; /* For stupid lack of const in ICatRegister declaration. */
773 if(iter
->iType
== _ATL_CATMAP_ENTRY_IMPLEMENTED
) {
775 hres
= ICatRegister_RegisterClassImplCategories(catreg
, clsid
, 1, &catid
);
777 hres
= ICatRegister_UnRegisterClassImplCategories(catreg
, clsid
, 1, &catid
);
780 hres
= ICatRegister_RegisterClassReqCategories(catreg
, clsid
, 1, &catid
);
782 hres
= ICatRegister_UnRegisterClassReqCategories(catreg
, clsid
, 1, &catid
);
789 WCHAR reg_path
[256] = {'C','L','S','I','D','\\'}, *ptr
= reg_path
+6;
791 static const WCHAR implemented_catW
[] =
792 {'I','m','p','l','e','m','e','n','t','e','d',' ','C','a','t','e','g','o','r','i','e','s',0};
793 static const WCHAR required_catW
[] =
794 {'R','e','q','u','i','r','e','d',' ','C','a','t','e','g','o','r','i','e','s',0};
796 ptr
+= StringFromGUID2(clsid
, ptr
, 64)-1;
799 memcpy(ptr
, implemented_catW
, sizeof(implemented_catW
));
800 RegDeleteKeyW(HKEY_CLASSES_ROOT
, reg_path
);
802 memcpy(ptr
, required_catW
, sizeof(required_catW
));
803 RegDeleteKeyW(HKEY_CLASSES_ROOT
, reg_path
);
809 /***********************************************************************
810 * AtlWaitWithMessageLoop [atl100.24]
812 BOOL WINAPI
AtlWaitWithMessageLoop(HANDLE handle
)
817 TRACE("(%p)\n", handle
);
820 res
= MsgWaitForMultipleObjects(1, &handle
, FALSE
, INFINITE
, QS_ALLINPUT
);
824 case WAIT_OBJECT_0
+1:
825 if(GetMessageW(&msg
, NULL
, 0, 0) < 0)
828 TranslateMessage(&msg
);
829 DispatchMessageW(&msg
);
837 static HRESULT
get_default_source(ITypeLib
*typelib
, const CLSID
*clsid
, IID
*iid
)
839 ITypeInfo
*typeinfo
, *src_typeinfo
= NULL
;
845 hres
= ITypeLib_GetTypeInfoOfGuid(typelib
, clsid
, &typeinfo
);
849 hres
= ITypeInfo_GetTypeAttr(typeinfo
, &attr
);
851 ITypeInfo_Release(typeinfo
);
855 for(i
=0; i
< attr
->cImplTypes
; i
++) {
856 hres
= ITypeInfo_GetImplTypeFlags(typeinfo
, i
, &type_flags
);
857 if(SUCCEEDED(hres
) && type_flags
== (IMPLTYPEFLAG_FSOURCE
|IMPLTYPEFLAG_FDEFAULT
)) {
860 hres
= ITypeInfo_GetRefTypeOfImplType(typeinfo
, i
, &ref
);
862 hres
= ITypeInfo_GetRefTypeInfo(typeinfo
, ref
, &src_typeinfo
);
867 ITypeInfo_ReleaseTypeAttr(typeinfo
, attr
);
868 ITypeInfo_Release(typeinfo
);
877 hres
= ITypeInfo_GetTypeAttr(src_typeinfo
, &attr
);
878 if(SUCCEEDED(hres
)) {
880 ITypeInfo_ReleaseTypeAttr(src_typeinfo
, attr
);
882 ITypeInfo_Release(src_typeinfo
);
886 /***********************************************************************
887 * AtlGetObjectSourceInterface [atl100.54]
889 HRESULT WINAPI
AtlGetObjectSourceInterface(IUnknown
*unk
, GUID
*libid
, IID
*iid
, unsigned short *major
, unsigned short *minor
)
891 IProvideClassInfo2
*classinfo
;
898 TRACE("(%p %p %p %p %p)\n", unk
, libid
, iid
, major
, minor
);
900 hres
= IUnknown_QueryInterface(unk
, &IID_IDispatch
, (void**)&disp
);
904 hres
= IDispatch_GetTypeInfo(disp
, 0, 0, &typeinfo
);
905 IDispatch_Release(disp
);
909 hres
= ITypeInfo_GetContainingTypeLib(typeinfo
, &typelib
, 0);
910 ITypeInfo_Release(typeinfo
);
911 if(SUCCEEDED(hres
)) {
914 hres
= ITypeLib_GetLibAttr(typelib
, &attr
);
915 if(SUCCEEDED(hres
)) {
917 *major
= attr
->wMajorVerNum
;
918 *minor
= attr
->wMinorVerNum
;
919 ITypeLib_ReleaseTLibAttr(typelib
, attr
);
921 ITypeLib_Release(typelib
);
927 hres
= IUnknown_QueryInterface(unk
, &IID_IProvideClassInfo2
, (void**)&classinfo
);
928 if(SUCCEEDED(hres
)) {
929 hres
= IProvideClassInfo2_GetGUID(classinfo
, GUIDKIND_DEFAULT_SOURCE_DISP_IID
, iid
);
930 IProvideClassInfo2_Release(classinfo
);
931 ITypeLib_Release(typelib
);
935 hres
= IUnknown_QueryInterface(unk
, &IID_IPersist
, (void**)&persist
);
936 if(SUCCEEDED(hres
)) {
939 hres
= IPersist_GetClassID(persist
, &clsid
);
941 hres
= get_default_source(typelib
, &clsid
, iid
);
942 IPersist_Release(persist
);
948 #if _ATL_VER >= _ATL_VER90
950 /***********************************************************************
951 * AtlSetPerUserRegistration [atl100.67]
953 HRESULT WINAPI
AtlSetPerUserRegistration(cpp_bool bEnable
)
955 FIXME("stub: bEnable: %d\n", bEnable
);
959 /***********************************************************************
960 * AtlGetPerUserRegistration [atl100.68]
962 HRESULT WINAPI
AtlGetPerUserRegistration(cpp_bool
*pbEnabled
)
964 FIXME("stub: returning false\n");
971 /***********************************************************************
972 * AtlGetVersion [atl100.@]
974 DWORD WINAPI
AtlGetVersion(void *pReserved
)
976 TRACE("version %04x (%p)\n", _ATL_VER
, pReserved
);
980 BOOL WINAPI
DllMain(HINSTANCE hinstDLL
, DWORD fdwReason
, LPVOID lpvReserved
)
982 TRACE("(0x%p, %d, %p)\n", hinstDLL
, fdwReason
, lpvReserved
);
985 case DLL_PROCESS_ATTACH
:
986 atl_instance
= hinstDLL
;
987 DisableThreadLibraryCalls(hinstDLL
);
989 case DLL_PROCESS_DETACH
:
990 if (lpvReserved
) break;
992 ICatRegister_Release(catreg
);