d3d10: Return the read value from read_dword().
[wine.git] / dlls / atl / atl.c
blobed6afe4ea2e77c20bca71adaa5ac0f6f9fca5a89
1 /*
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
20 #define COBJMACROS
22 #include "atlbase.h"
23 #include "atlcom.h"
25 #include "wine/debug.h"
26 #include "wine/heap.h"
28 WINE_DEFAULT_DEBUG_CHANNEL(atl);
30 #define ATLVer1Size FIELD_OFFSET(_ATL_MODULEW, dwAtlBuildVer)
32 typedef unsigned char cpp_bool;
34 static ICatRegister *catreg;
36 /***********************************************************************
37 * AtlAdvise [atl100.@]
39 HRESULT WINAPI AtlAdvise(IUnknown *pUnkCP, IUnknown *pUnk, const IID *iid, DWORD *pdw)
41 IConnectionPointContainer *container;
42 IConnectionPoint *cp;
43 HRESULT hres;
45 TRACE("%p %p %p %p\n", pUnkCP, pUnk, iid, pdw);
47 if(!pUnkCP)
48 return E_INVALIDARG;
50 hres = IUnknown_QueryInterface(pUnkCP, &IID_IConnectionPointContainer, (void**)&container);
51 if(FAILED(hres))
52 return hres;
54 hres = IConnectionPointContainer_FindConnectionPoint(container, iid, &cp);
55 IConnectionPointContainer_Release(container);
56 if(FAILED(hres))
57 return hres;
59 hres = IConnectionPoint_Advise(cp, pUnk, pdw);
60 IConnectionPoint_Release(cp);
61 return hres;
64 /***********************************************************************
65 * AtlUnadvise [atl100.@]
67 HRESULT WINAPI AtlUnadvise(IUnknown *pUnkCP, const IID *iid, DWORD dw)
69 IConnectionPointContainer *container;
70 IConnectionPoint *cp;
71 HRESULT hres;
73 TRACE("%p %p %ld\n", pUnkCP, iid, dw);
75 if(!pUnkCP)
76 return E_INVALIDARG;
78 hres = IUnknown_QueryInterface(pUnkCP, &IID_IConnectionPointContainer, (void**)&container);
79 if(FAILED(hres))
80 return hres;
82 hres = IConnectionPointContainer_FindConnectionPoint(container, iid, &cp);
83 IConnectionPointContainer_Release(container);
84 if(FAILED(hres))
85 return hres;
87 hres = IConnectionPoint_Unadvise(cp, dw);
88 IConnectionPoint_Release(cp);
89 return hres;
92 /***********************************************************************
93 * AtlFreeMarshalStream [atl100.@]
95 HRESULT WINAPI AtlFreeMarshalStream(IStream *stm)
97 FIXME("%p\n", stm);
98 return S_OK;
101 /***********************************************************************
102 * AtlMarshalPtrInProc [atl100.@]
104 HRESULT WINAPI AtlMarshalPtrInProc(IUnknown *pUnk, const IID *iid, IStream **pstm)
106 FIXME("%p %p %p\n", pUnk, iid, pstm);
107 return E_FAIL;
110 /***********************************************************************
111 * AtlUnmarshalPtr [atl100.@]
113 HRESULT WINAPI AtlUnmarshalPtr(IStream *stm, const IID *iid, IUnknown **ppUnk)
115 FIXME("%p %p %p\n", stm, iid, ppUnk);
116 return E_FAIL;
119 /***********************************************************************
120 * AtlCreateTargetDC [atl100.@]
122 HDC WINAPI AtlCreateTargetDC( HDC hdc, DVTARGETDEVICE *dv )
124 const WCHAR *driver = NULL, *device = NULL, *port = NULL;
125 DEVMODEW *devmode = NULL;
127 TRACE( "(%p, %p)\n", hdc, dv );
129 if (dv)
131 if (dv->tdDriverNameOffset) driver = (WCHAR *)((char *)dv + dv->tdDriverNameOffset);
132 if (dv->tdDeviceNameOffset) device = (WCHAR *)((char *)dv + dv->tdDeviceNameOffset);
133 if (dv->tdPortNameOffset) port = (WCHAR *)((char *)dv + dv->tdPortNameOffset);
134 if (dv->tdExtDevmodeOffset) devmode = (DEVMODEW *)((char *)dv + dv->tdExtDevmodeOffset);
136 else
138 if (hdc) return hdc;
139 driver = L"display";
141 return CreateDCW( driver, device, port, devmode );
144 /***********************************************************************
145 * AtlHiMetricToPixel [atl100.@]
147 void WINAPI AtlHiMetricToPixel(const SIZEL* lpHiMetric, SIZEL* lpPix)
149 HDC dc = GetDC(NULL);
150 lpPix->cx = lpHiMetric->cx * GetDeviceCaps( dc, LOGPIXELSX ) / 100;
151 lpPix->cy = lpHiMetric->cy * GetDeviceCaps( dc, LOGPIXELSY ) / 100;
152 ReleaseDC( NULL, dc );
155 /***********************************************************************
156 * AtlPixelToHiMetric [atl100.@]
158 void WINAPI AtlPixelToHiMetric(const SIZEL* lpPix, SIZEL* lpHiMetric)
160 HDC dc = GetDC(NULL);
161 lpHiMetric->cx = 100 * lpPix->cx / GetDeviceCaps( dc, LOGPIXELSX );
162 lpHiMetric->cy = 100 * lpPix->cy / GetDeviceCaps( dc, LOGPIXELSY );
163 ReleaseDC( NULL, dc );
166 /***********************************************************************
167 * AtlComPtrAssign [atl100.@]
169 IUnknown* WINAPI AtlComPtrAssign(IUnknown** pp, IUnknown *p)
171 TRACE("(%p %p)\n", pp, p);
173 if (p) IUnknown_AddRef(p);
174 if (*pp) IUnknown_Release(*pp);
175 *pp = p;
176 return p;
179 /***********************************************************************
180 * AtlComQIPtrAssign [atl100.@]
182 IUnknown* WINAPI AtlComQIPtrAssign(IUnknown** pp, IUnknown *p, REFIID riid)
184 IUnknown *new_p = NULL;
186 TRACE("(%p %p %s)\n", pp, p, debugstr_guid(riid));
188 if (p) IUnknown_QueryInterface(p, riid, (void **)&new_p);
189 if (*pp) IUnknown_Release(*pp);
190 *pp = new_p;
191 return new_p;
194 /***********************************************************************
195 * AtlInternalQueryInterface [atl100.@]
197 HRESULT WINAPI AtlInternalQueryInterface(void* this, const _ATL_INTMAP_ENTRY* pEntries, REFIID iid, void** ppvObject)
199 int i = 0;
200 HRESULT rc = E_NOINTERFACE;
201 TRACE("(%p, %p, %s, %p)\n",this, pEntries, debugstr_guid(iid), ppvObject);
203 if (IsEqualGUID(iid,&IID_IUnknown))
205 TRACE("Returning IUnknown\n");
206 *ppvObject = ((LPSTR)this+pEntries[0].dw);
207 IUnknown_AddRef((IUnknown*)*ppvObject);
208 return S_OK;
211 while (pEntries[i].pFunc != 0)
213 TRACE("Trying entry %i (%s %Ix %p)\n",i,debugstr_guid(pEntries[i].piid),
214 pEntries[i].dw, pEntries[i].pFunc);
216 if (!pEntries[i].piid || IsEqualGUID(iid,pEntries[i].piid))
218 TRACE("MATCH\n");
219 if (pEntries[i].pFunc == (_ATL_CREATORARGFUNC*)1)
221 TRACE("Offset\n");
222 *ppvObject = ((LPSTR)this+pEntries[i].dw);
223 IUnknown_AddRef((IUnknown*)*ppvObject);
224 return S_OK;
226 else
228 TRACE("Function\n");
229 rc = pEntries[i].pFunc(this, iid, ppvObject, pEntries[i].dw);
230 if(rc==S_OK || pEntries[i].piid)
231 return rc;
234 i++;
236 TRACE("Done returning (0x%lx)\n",rc);
237 return rc;
240 /***********************************************************************
241 * AtlIPersistStreamInit_Load [atl100.@]
243 HRESULT WINAPI AtlIPersistStreamInit_Load( LPSTREAM pStm, ATL_PROPMAP_ENTRY *pMap,
244 void *pThis, IUnknown *pUnk)
246 FIXME("(%p, %p, %p, %p)\n", pStm, pMap, pThis, pUnk);
248 return S_OK;
251 /***********************************************************************
252 * AtlIPersistStreamInit_Save [atl100.@]
254 HRESULT WINAPI AtlIPersistStreamInit_Save(LPSTREAM pStm, BOOL fClearDirty,
255 ATL_PROPMAP_ENTRY *pMap, void *pThis,
256 IUnknown *pUnk)
258 FIXME("(%p, %d, %p, %p, %p)\n", pStm, fClearDirty, pMap, pThis, pUnk);
260 return S_OK;
263 /***********************************************************************
264 * AtlIPersistPropertyBag_Load [atl100.@]
266 HRESULT WINAPI AtlIPersistPropertyBag_Load(LPPROPERTYBAG pPropBag, LPERRORLOG pErrorLog,
267 ATL_PROPMAP_ENTRY *pMap, void *pThis,
268 IUnknown *pUnk)
270 FIXME("(%p, %p, %p, %p, %p)\n", pPropBag, pErrorLog, pMap, pThis, pUnk);
272 return S_OK;
275 /***********************************************************************
276 * AtlIPersistPropertyBag_Save [atl100.@]
278 HRESULT WINAPI AtlIPersistPropertyBag_Save(LPPROPERTYBAG pPropBag, BOOL fClearDirty,
279 BOOL fSaveAll, ATL_PROPMAP_ENTRY *pMap,
280 void *pThis, IUnknown *pUnk)
282 FIXME("(%p, %d, %d, %p, %p, %p)\n", pPropBag, fClearDirty, fSaveAll, pMap, pThis, pUnk);
284 return S_OK;
287 /***********************************************************************
288 * AtlModuleAddTermFunc [atl100.@]
290 HRESULT WINAPI AtlModuleAddTermFunc(_ATL_MODULE *pM, _ATL_TERMFUNC *pFunc, DWORD_PTR dw)
292 _ATL_TERMFUNC_ELEM *termfunc_elem;
294 TRACE("version %04x (%p %p %Id)\n", _ATL_VER, pM, pFunc, dw);
296 if (_ATL_VER > _ATL_VER_30 || pM->cbSize > ATLVer1Size) {
297 termfunc_elem = HeapAlloc(GetProcessHeap(), 0, sizeof(_ATL_TERMFUNC_ELEM));
298 termfunc_elem->pFunc = pFunc;
299 termfunc_elem->dw = dw;
300 termfunc_elem->pNext = pM->m_pTermFuncs;
302 pM->m_pTermFuncs = termfunc_elem;
305 return S_OK;
308 #if _ATL_VER > _ATL_VER_30
310 /***********************************************************************
311 * AtlCallTermFunc [atl100.@]
313 void WINAPI AtlCallTermFunc(_ATL_MODULE *pM)
315 _ATL_TERMFUNC_ELEM *iter = pM->m_pTermFuncs, *tmp;
317 TRACE("(%p)\n", pM);
319 while(iter) {
320 iter->pFunc(iter->dw);
321 tmp = iter;
322 iter = iter->pNext;
323 HeapFree(GetProcessHeap(), 0, tmp);
326 pM->m_pTermFuncs = NULL;
329 #endif
331 /***********************************************************************
332 * AtlLoadTypeLib [atl100.56]
334 HRESULT WINAPI AtlLoadTypeLib(HINSTANCE inst, LPCOLESTR lpszIndex,
335 BSTR *pbstrPath, ITypeLib **ppTypeLib)
337 size_t path_len, index_len;
338 ITypeLib *typelib = NULL;
339 WCHAR *path;
340 HRESULT hres;
342 TRACE("(%p %s %p %p)\n", inst, debugstr_w(lpszIndex), pbstrPath, ppTypeLib);
344 index_len = lpszIndex ? lstrlenW(lpszIndex) : 0;
345 path = heap_alloc((MAX_PATH+index_len)*sizeof(WCHAR) + sizeof(L".tlb"));
346 if(!path)
347 return E_OUTOFMEMORY;
349 path_len = GetModuleFileNameW(inst, path, MAX_PATH);
350 if(!path_len) {
351 heap_free(path);
352 return HRESULT_FROM_WIN32(GetLastError());
355 if(index_len)
356 memcpy(path+path_len, lpszIndex, (index_len+1)*sizeof(WCHAR));
358 hres = LoadTypeLib(path, &typelib);
359 if(FAILED(hres)) {
360 WCHAR *ptr;
362 for(ptr = path+path_len-1; ptr > path && *ptr != '\\' && *ptr != '.'; ptr--);
363 if(*ptr != '.')
364 ptr = path+path_len;
365 lstrcpyW(ptr, L".tlb");
366 hres = LoadTypeLib(path, &typelib);
369 if(SUCCEEDED(hres)) {
370 *pbstrPath = SysAllocString(path);
371 if(!*pbstrPath) {
372 ITypeLib_Release(typelib);
373 hres = E_OUTOFMEMORY;
377 heap_free(path);
378 if(FAILED(hres))
379 return hres;
381 *ppTypeLib = typelib;
382 return S_OK;
385 #if _ATL_VER <= _ATL_VER_80
387 /***********************************************************************
388 * AtlRegisterTypeLib [atl80.19]
390 HRESULT WINAPI AtlRegisterTypeLib(HINSTANCE inst, const WCHAR *index)
392 ITypeLib *typelib;
393 BSTR path;
394 HRESULT hres;
396 TRACE("(%p %s)\n", inst, debugstr_w(index));
398 hres = AtlLoadTypeLib(inst, index, &path, &typelib);
399 if(FAILED(hres))
400 return hres;
402 hres = RegisterTypeLib(typelib, path, NULL); /* FIXME: pass help directory */
403 ITypeLib_Release(typelib);
404 SysFreeString(path);
405 return hres;
408 #endif
410 #if _ATL_VER > _ATL_VER_30
412 /***********************************************************************
413 * AtlWinModuleInit [atl100.65]
415 HRESULT WINAPI AtlWinModuleInit(_ATL_WIN_MODULE *winmod)
417 TRACE("(%p)\n", winmod);
419 if(winmod->cbSize != sizeof(*winmod))
420 return E_INVALIDARG;
422 InitializeCriticalSection(&winmod->m_csWindowCreate);
423 winmod->m_pCreateWndList = NULL;
424 return S_OK;
427 /***********************************************************************
428 * AtlWinModuleAddCreateWndData [atl100.43]
430 void WINAPI AtlWinModuleAddCreateWndData(_ATL_WIN_MODULE *pM, _AtlCreateWndData *pData, void *pvObject)
432 TRACE("(%p, %p, %p)\n", pM, pData, pvObject);
434 pData->m_pThis = pvObject;
435 pData->m_dwThreadID = GetCurrentThreadId();
437 EnterCriticalSection(&pM->m_csWindowCreate);
438 pData->m_pNext = pM->m_pCreateWndList;
439 pM->m_pCreateWndList = pData;
440 LeaveCriticalSection(&pM->m_csWindowCreate);
443 /***********************************************************************
444 * AtlWinModuleExtractCreateWndData [atl100.44]
446 void* WINAPI AtlWinModuleExtractCreateWndData(_ATL_WIN_MODULE *winmod)
448 _AtlCreateWndData *iter, *prev = NULL;
449 DWORD thread_id;
451 TRACE("(%p)\n", winmod);
453 thread_id = GetCurrentThreadId();
455 EnterCriticalSection(&winmod->m_csWindowCreate);
457 for(iter = winmod->m_pCreateWndList; iter && iter->m_dwThreadID != thread_id; iter = iter->m_pNext)
458 prev = iter;
459 if(iter) {
460 if(prev)
461 prev->m_pNext = iter->m_pNext;
462 else
463 winmod->m_pCreateWndList = iter->m_pNext;
466 LeaveCriticalSection(&winmod->m_csWindowCreate);
468 return iter ? iter->m_pThis : NULL;
471 /***********************************************************************
472 * AtlComModuleGetClassObject [atl100.15]
474 #if _ATL_VER < _ATL_VER_110
475 HRESULT WINAPI AtlComModuleGetClassObject(_ATL_COM_MODULE *pm, REFCLSID rclsid, REFIID riid, void **ppv)
477 _ATL_OBJMAP_ENTRY **iter;
478 HRESULT hres;
480 TRACE("(%p %s %s %p)\n", pm, debugstr_guid(rclsid), debugstr_guid(riid), ppv);
482 if(!pm)
483 return E_INVALIDARG;
485 for(iter = pm->m_ppAutoObjMapFirst; iter < pm->m_ppAutoObjMapLast; iter++) {
486 if(IsEqualCLSID((*iter)->pclsid, rclsid) && (*iter)->pfnGetClassObject) {
487 if(!(*iter)->pCF)
488 hres = (*iter)->pfnGetClassObject((*iter)->pfnCreateInstance, &IID_IUnknown, (void**)&(*iter)->pCF);
489 if((*iter)->pCF)
490 hres = IUnknown_QueryInterface((*iter)->pCF, riid, ppv);
491 TRACE("returning %p (%08lx)\n", *ppv, hres);
492 return hres;
496 WARN("Class %s not found\n", debugstr_guid(rclsid));
497 return CLASS_E_CLASSNOTAVAILABLE;
499 #else
500 HRESULT WINAPI AtlComModuleGetClassObject(_ATL_COM_MODULE *pm, REFCLSID rclsid, REFIID riid, void **ppv)
502 _ATL_OBJMAP_ENTRY_EX **iter;
503 HRESULT hres;
505 TRACE("(%p %s %s %p)\n", pm, debugstr_guid(rclsid), debugstr_guid(riid), ppv);
507 if(!pm)
508 return E_INVALIDARG;
510 for(iter = pm->m_ppAutoObjMapFirst; iter < pm->m_ppAutoObjMapLast; iter++) {
511 if(IsEqualCLSID((*iter)->pclsid, rclsid) && (*iter)->pfnGetClassObject) {
512 if(!(*iter)->pCache->pCF)
513 hres = (*iter)->pfnGetClassObject((*iter)->pfnCreateInstance, &IID_IUnknown, (void**)&(*iter)->pCache->pCF);
514 if((*iter)->pCache->pCF)
515 hres = IUnknown_QueryInterface((*iter)->pCache->pCF, riid, ppv);
516 TRACE("returning %p (%08lx)\n", *ppv, hres);
517 return hres;
521 WARN("Class %s not found\n", debugstr_guid(rclsid));
522 return CLASS_E_CLASSNOTAVAILABLE;
524 #endif
526 /***********************************************************************
527 * AtlComModuleRegisterClassObjects [atl100.17]
529 #if _ATL_VER < _ATL_VER_110
530 HRESULT WINAPI AtlComModuleRegisterClassObjects(_ATL_COM_MODULE *module, DWORD context, DWORD flags)
532 _ATL_OBJMAP_ENTRY **iter;
533 IUnknown *unk;
534 HRESULT hres;
536 TRACE("(%p %lx %lx)\n", module, context, flags);
538 if(!module)
539 return E_INVALIDARG;
541 for(iter = module->m_ppAutoObjMapFirst; iter < module->m_ppAutoObjMapLast; iter++) {
542 if(!(*iter)->pfnGetClassObject)
543 continue;
545 hres = (*iter)->pfnGetClassObject((*iter)->pfnCreateInstance, &IID_IUnknown, (void**)&unk);
546 if(FAILED(hres))
547 return hres;
549 hres = CoRegisterClassObject((*iter)->pclsid, unk, context, flags, &(*iter)->dwRegister);
550 IUnknown_Release(unk);
551 if(FAILED(hres))
552 return hres;
555 return S_OK;
557 #else
558 HRESULT WINAPI AtlComModuleRegisterClassObjects(_ATL_COM_MODULE *module, DWORD context, DWORD flags)
560 _ATL_OBJMAP_ENTRY_EX **iter;
561 IUnknown *unk;
562 HRESULT hres;
564 TRACE("(%p %lx %lx)\n", module, context, flags);
566 if(!module)
567 return E_INVALIDARG;
569 for(iter = module->m_ppAutoObjMapFirst; iter < module->m_ppAutoObjMapLast; iter++) {
570 if(!(*iter)->pfnGetClassObject)
571 continue;
573 hres = (*iter)->pfnGetClassObject((*iter)->pfnCreateInstance, &IID_IUnknown, (void**)&unk);
574 if(FAILED(hres))
575 return hres;
577 hres = CoRegisterClassObject((*iter)->pclsid, unk, context, flags, &(*iter)->pCache->dwRegister);
578 IUnknown_Release(unk);
579 if(FAILED(hres))
580 return hres;
583 return S_OK;
585 #endif
587 /***********************************************************************
588 * AtlComModuleRevokeClassObjects [atl100.20]
590 #if _ATL_VER < _ATL_VER_110
591 HRESULT WINAPI AtlComModuleRevokeClassObjects(_ATL_COM_MODULE *module)
593 _ATL_OBJMAP_ENTRY **iter;
594 HRESULT hres;
596 TRACE("(%p)\n", module);
598 if(!module)
599 return E_INVALIDARG;
601 for(iter = module->m_ppAutoObjMapFirst; iter < module->m_ppAutoObjMapLast; iter++) {
602 hres = CoRevokeClassObject((*iter)->dwRegister);
603 if(FAILED(hres))
604 return hres;
607 return S_OK;
609 #else
610 HRESULT WINAPI AtlComModuleRevokeClassObjects(_ATL_COM_MODULE *module)
612 _ATL_OBJMAP_ENTRY_EX **iter;
613 HRESULT hres;
615 TRACE("(%p)\n", module);
617 if(!module)
618 return E_INVALIDARG;
620 for(iter = module->m_ppAutoObjMapFirst; iter < module->m_ppAutoObjMapLast; iter++) {
621 hres = CoRevokeClassObject((*iter)->pCache->dwRegister);
622 if(FAILED(hres))
623 return hres;
626 return S_OK;
628 #endif
630 /***********************************************************************
631 * AtlComModuleUnregisterServer [atl100.22]
633 #if _ATL_VER < _ATL_VER_110
634 HRESULT WINAPI AtlComModuleUnregisterServer(_ATL_COM_MODULE *mod, BOOL bRegTypeLib, const CLSID *clsid)
636 const struct _ATL_CATMAP_ENTRY *catmap;
637 _ATL_OBJMAP_ENTRY **iter;
638 HRESULT hres;
640 TRACE("(%p %x %s)\n", mod, bRegTypeLib, debugstr_guid(clsid));
642 for(iter = mod->m_ppAutoObjMapFirst; iter < mod->m_ppAutoObjMapLast; iter++) {
643 if(!*iter || (clsid && !IsEqualCLSID((*iter)->pclsid, clsid)))
644 continue;
646 TRACE("Unregistering clsid %s\n", debugstr_guid((*iter)->pclsid));
648 catmap = (*iter)->pfnGetCategoryMap();
649 if(catmap) {
650 hres = AtlRegisterClassCategoriesHelper((*iter)->pclsid, catmap, FALSE);
651 if(FAILED(hres))
652 return hres;
655 hres = (*iter)->pfnUpdateRegistry(FALSE);
656 if(FAILED(hres))
657 return hres;
660 if(bRegTypeLib) {
661 ITypeLib *typelib;
662 TLIBATTR *attr;
663 BSTR path;
665 hres = AtlLoadTypeLib(mod->m_hInstTypeLib, NULL, &path, &typelib);
666 if(FAILED(hres))
667 return hres;
669 SysFreeString(path);
670 hres = ITypeLib_GetLibAttr(typelib, &attr);
671 if(SUCCEEDED(hres)) {
672 hres = UnRegisterTypeLib(&attr->guid, attr->wMajorVerNum, attr->wMinorVerNum, attr->lcid, attr->syskind);
673 ITypeLib_ReleaseTLibAttr(typelib, attr);
675 ITypeLib_Release(typelib);
676 if(FAILED(hres))
677 return hres;
680 return S_OK;
682 #else
683 HRESULT WINAPI AtlComModuleUnregisterServer(_ATL_COM_MODULE *mod, BOOL bRegTypeLib, const CLSID *clsid)
685 const struct _ATL_CATMAP_ENTRY *catmap;
686 _ATL_OBJMAP_ENTRY_EX **iter;
687 HRESULT hres;
689 TRACE("(%p %x %s)\n", mod, bRegTypeLib, debugstr_guid(clsid));
691 for(iter = mod->m_ppAutoObjMapFirst; iter < mod->m_ppAutoObjMapLast; iter++) {
692 if(!*iter || (clsid && !IsEqualCLSID((*iter)->pclsid, clsid)))
693 continue;
695 TRACE("Unregistering clsid %s\n", debugstr_guid((*iter)->pclsid));
697 catmap = (*iter)->pfnGetCategoryMap();
698 if(catmap) {
699 hres = AtlRegisterClassCategoriesHelper((*iter)->pclsid, catmap, FALSE);
700 if(FAILED(hres))
701 return hres;
704 hres = (*iter)->pfnUpdateRegistry(FALSE);
705 if(FAILED(hres))
706 return hres;
709 if(bRegTypeLib) {
710 ITypeLib *typelib;
711 TLIBATTR *attr;
712 BSTR path;
714 hres = AtlLoadTypeLib(mod->m_hInstTypeLib, NULL, &path, &typelib);
715 if(FAILED(hres))
716 return hres;
718 SysFreeString(path);
719 hres = ITypeLib_GetLibAttr(typelib, &attr);
720 if(SUCCEEDED(hres)) {
721 hres = UnRegisterTypeLib(&attr->guid, attr->wMajorVerNum, attr->wMinorVerNum, attr->lcid, attr->syskind);
722 ITypeLib_ReleaseTLibAttr(typelib, attr);
724 ITypeLib_Release(typelib);
725 if(FAILED(hres))
726 return hres;
729 return S_OK;
731 #endif
733 #endif
735 /***********************************************************************
736 * AtlRegisterClassCategoriesHelper [atl100.49]
738 HRESULT WINAPI AtlRegisterClassCategoriesHelper(REFCLSID clsid, const struct _ATL_CATMAP_ENTRY *catmap, BOOL reg)
740 const struct _ATL_CATMAP_ENTRY *iter;
741 HRESULT hres;
743 TRACE("(%s %p %x)\n", debugstr_guid(clsid), catmap, reg);
745 if(!catmap)
746 return S_OK;
748 if(!catreg) {
749 ICatRegister *new_catreg;
751 hres = CoCreateInstance(&CLSID_StdComponentCategoriesMgr, NULL, CLSCTX_INPROC_SERVER,
752 &IID_ICatRegister, (void**)&new_catreg);
753 if(FAILED(hres))
754 return hres;
756 if(InterlockedCompareExchangePointer((void**)&catreg, new_catreg, NULL))
757 ICatRegister_Release(new_catreg);
760 for(iter = catmap; iter->iType != _ATL_CATMAP_ENTRY_END; iter++) {
761 CATID catid = *iter->pcatid; /* For stupid lack of const in ICatRegister declaration. */
763 if(iter->iType == _ATL_CATMAP_ENTRY_IMPLEMENTED) {
764 if(reg)
765 hres = ICatRegister_RegisterClassImplCategories(catreg, clsid, 1, &catid);
766 else
767 hres = ICatRegister_UnRegisterClassImplCategories(catreg, clsid, 1, &catid);
768 }else {
769 if(reg)
770 hres = ICatRegister_RegisterClassReqCategories(catreg, clsid, 1, &catid);
771 else
772 hres = ICatRegister_UnRegisterClassReqCategories(catreg, clsid, 1, &catid);
774 if(FAILED(hres))
775 return hres;
778 if(!reg) {
779 WCHAR reg_path[256] = L"CLSID\\", *ptr = reg_path+6;
781 ptr += StringFromGUID2(clsid, ptr, 64)-1;
782 *ptr++ = '\\';
784 lstrcpyW(ptr, L"Implemented Categories");
785 RegDeleteKeyW(HKEY_CLASSES_ROOT, reg_path);
787 lstrcpyW(ptr, L"Required Categories");
788 RegDeleteKeyW(HKEY_CLASSES_ROOT, reg_path);
791 return S_OK;
794 /***********************************************************************
795 * AtlWaitWithMessageLoop [atl100.24]
797 BOOL WINAPI AtlWaitWithMessageLoop(HANDLE handle)
799 MSG msg;
800 DWORD res;
802 TRACE("(%p)\n", handle);
804 while(1) {
805 res = MsgWaitForMultipleObjects(1, &handle, FALSE, INFINITE, QS_ALLINPUT);
806 switch(res) {
807 case WAIT_OBJECT_0:
808 return TRUE;
809 case WAIT_OBJECT_0+1:
810 if(GetMessageW(&msg, NULL, 0, 0) < 0)
811 return FALSE;
813 TranslateMessage(&msg);
814 DispatchMessageW(&msg);
815 break;
816 default:
817 return FALSE;
822 static HRESULT get_default_source(ITypeLib *typelib, const CLSID *clsid, IID *iid)
824 ITypeInfo *typeinfo, *src_typeinfo = NULL;
825 TYPEATTR *attr;
826 int type_flags;
827 unsigned i;
828 HRESULT hres;
830 hres = ITypeLib_GetTypeInfoOfGuid(typelib, clsid, &typeinfo);
831 if(FAILED(hres))
832 return hres;
834 hres = ITypeInfo_GetTypeAttr(typeinfo, &attr);
835 if(FAILED(hres)) {
836 ITypeInfo_Release(typeinfo);
837 return hres;
840 for(i=0; i < attr->cImplTypes; i++) {
841 hres = ITypeInfo_GetImplTypeFlags(typeinfo, i, &type_flags);
842 if(SUCCEEDED(hres) && type_flags == (IMPLTYPEFLAG_FSOURCE|IMPLTYPEFLAG_FDEFAULT)) {
843 HREFTYPE ref;
845 hres = ITypeInfo_GetRefTypeOfImplType(typeinfo, i, &ref);
846 if(SUCCEEDED(hres))
847 hres = ITypeInfo_GetRefTypeInfo(typeinfo, ref, &src_typeinfo);
848 break;
852 ITypeInfo_ReleaseTypeAttr(typeinfo, attr);
853 ITypeInfo_Release(typeinfo);
854 if(FAILED(hres))
855 return hres;
857 if(!src_typeinfo) {
858 *iid = IID_NULL;
859 return S_OK;
862 hres = ITypeInfo_GetTypeAttr(src_typeinfo, &attr);
863 if(SUCCEEDED(hres)) {
864 *iid = attr->guid;
865 ITypeInfo_ReleaseTypeAttr(src_typeinfo, attr);
867 ITypeInfo_Release(src_typeinfo);
868 return hres;
871 /***********************************************************************
872 * AtlGetObjectSourceInterface [atl100.54]
874 HRESULT WINAPI AtlGetObjectSourceInterface(IUnknown *unk, GUID *libid, IID *iid, unsigned short *major, unsigned short *minor)
876 IProvideClassInfo2 *classinfo;
877 ITypeInfo *typeinfo;
878 ITypeLib *typelib;
879 IPersist *persist;
880 IDispatch *disp;
881 HRESULT hres;
883 TRACE("(%p %p %p %p %p)\n", unk, libid, iid, major, minor);
885 hres = IUnknown_QueryInterface(unk, &IID_IDispatch, (void**)&disp);
886 if(FAILED(hres))
887 return hres;
889 hres = IDispatch_GetTypeInfo(disp, 0, 0, &typeinfo);
890 IDispatch_Release(disp);
891 if(FAILED(hres))
892 return hres;
894 hres = ITypeInfo_GetContainingTypeLib(typeinfo, &typelib, 0);
895 ITypeInfo_Release(typeinfo);
896 if(SUCCEEDED(hres)) {
897 TLIBATTR *attr;
899 hres = ITypeLib_GetLibAttr(typelib, &attr);
900 if(SUCCEEDED(hres)) {
901 *libid = attr->guid;
902 *major = attr->wMajorVerNum;
903 *minor = attr->wMinorVerNum;
904 ITypeLib_ReleaseTLibAttr(typelib, attr);
905 }else {
906 ITypeLib_Release(typelib);
909 if(FAILED(hres))
910 return hres;
912 hres = IUnknown_QueryInterface(unk, &IID_IProvideClassInfo2, (void**)&classinfo);
913 if(SUCCEEDED(hres)) {
914 hres = IProvideClassInfo2_GetGUID(classinfo, GUIDKIND_DEFAULT_SOURCE_DISP_IID, iid);
915 IProvideClassInfo2_Release(classinfo);
916 ITypeLib_Release(typelib);
917 return hres;
920 hres = IUnknown_QueryInterface(unk, &IID_IPersist, (void**)&persist);
921 if(SUCCEEDED(hres)) {
922 CLSID clsid;
924 hres = IPersist_GetClassID(persist, &clsid);
925 if(SUCCEEDED(hres))
926 hres = get_default_source(typelib, &clsid, iid);
927 IPersist_Release(persist);
930 return hres;
933 #if _ATL_VER >= _ATL_VER90
935 /***********************************************************************
936 * AtlSetPerUserRegistration [atl100.67]
938 HRESULT WINAPI AtlSetPerUserRegistration(cpp_bool bEnable)
940 FIXME("stub: bEnable: %d\n", bEnable);
941 return E_NOTIMPL;
944 /***********************************************************************
945 * AtlGetPerUserRegistration [atl100.68]
947 HRESULT WINAPI AtlGetPerUserRegistration(cpp_bool *pbEnabled)
949 FIXME("stub: returning false\n");
950 *pbEnabled = 0;
951 return S_OK;
954 #endif
956 /***********************************************************************
957 * AtlGetVersion [atl100.@]
959 DWORD WINAPI AtlGetVersion(void *pReserved)
961 TRACE("version %04x (%p)\n", _ATL_VER, pReserved);
962 return _ATL_VER;
965 BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
967 TRACE("(0x%p, %ld, %p)\n", hinstDLL, fdwReason, lpvReserved);
969 switch(fdwReason) {
970 case DLL_PROCESS_ATTACH:
971 DisableThreadLibraryCalls(hinstDLL);
972 break;
973 case DLL_PROCESS_DETACH:
974 if (lpvReserved) break;
975 if(catreg)
976 ICatRegister_Release(catreg);
979 return TRUE;