msxml3: CDATA nodes can't have children.
[wine.git] / dlls / atl100 / atl.c
blobebb47a167ad1ef5b3cd49c4e71ccb67dbb5c3d7d
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"
24 #include "wine/debug.h"
25 #include "wine/unicode.h"
27 WINE_DEFAULT_DEBUG_CHANNEL(atl100);
29 typedef unsigned char cpp_bool;
31 static inline void *heap_alloc(size_t len)
33 return HeapAlloc(GetProcessHeap(), 0, len);
36 static inline BOOL heap_free(void *mem)
38 return HeapFree(GetProcessHeap(), 0, mem);
41 static ICatRegister *catreg;
43 /***********************************************************************
44 * AtlAdvise [atl100.@]
46 HRESULT WINAPI AtlAdvise(IUnknown *pUnkCP, IUnknown *pUnk, const IID *iid, DWORD *pdw)
48 IConnectionPointContainer *container;
49 IConnectionPoint *cp;
50 HRESULT hres;
52 TRACE("%p %p %p %p\n", pUnkCP, pUnk, iid, pdw);
54 hres = IUnknown_QueryInterface(pUnkCP, &IID_IConnectionPointContainer, (void**)&container);
55 if(FAILED(hres))
56 return hres;
58 hres = IConnectionPointContainer_FindConnectionPoint(container, iid, &cp);
59 IConnectionPointContainer_Release(container);
60 if(FAILED(hres))
61 return hres;
63 hres = IConnectionPoint_Advise(cp, pUnk, pdw);
64 IConnectionPoint_Release(cp);
65 return hres;
68 /***********************************************************************
69 * AtlUnadvise [atl100.@]
71 HRESULT WINAPI AtlUnadvise(IUnknown *pUnkCP, const IID *iid, DWORD dw)
73 IConnectionPointContainer *container;
74 IConnectionPoint *cp;
75 HRESULT hres;
77 TRACE("%p %p %d\n", pUnkCP, iid, dw);
79 hres = IUnknown_QueryInterface(pUnkCP, &IID_IConnectionPointContainer, (void**)&container);
80 if(FAILED(hres))
81 return hres;
83 hres = IConnectionPointContainer_FindConnectionPoint(container, iid, &cp);
84 IConnectionPointContainer_Release(container);
85 if(FAILED(hres))
86 return hres;
88 hres = IConnectionPoint_Unadvise(cp, dw);
89 IConnectionPoint_Release(cp);
90 return hres;
93 /***********************************************************************
94 * AtlFreeMarshalStream [atl100.@]
96 HRESULT WINAPI AtlFreeMarshalStream(IStream *stm)
98 FIXME("%p\n", stm);
99 return S_OK;
102 /***********************************************************************
103 * AtlMarshalPtrInProc [atl100.@]
105 HRESULT WINAPI AtlMarshalPtrInProc(IUnknown *pUnk, const IID *iid, IStream **pstm)
107 FIXME("%p %p %p\n", pUnk, iid, pstm);
108 return E_FAIL;
111 /***********************************************************************
112 * AtlUnmarshalPtr [atl100.@]
114 HRESULT WINAPI AtlUnmarshalPtr(IStream *stm, const IID *iid, IUnknown **ppUnk)
116 FIXME("%p %p %p\n", stm, iid, ppUnk);
117 return E_FAIL;
120 /***********************************************************************
121 * AtlCreateTargetDC [atl100.@]
123 HDC WINAPI AtlCreateTargetDC( HDC hdc, DVTARGETDEVICE *dv )
125 static const WCHAR displayW[] = {'d','i','s','p','l','a','y',0};
126 const WCHAR *driver = NULL, *device = NULL, *port = NULL;
127 DEVMODEW *devmode = NULL;
129 TRACE( "(%p, %p)\n", hdc, dv );
131 if (dv)
133 if (dv->tdDriverNameOffset) driver = (WCHAR *)((char *)dv + dv->tdDriverNameOffset);
134 if (dv->tdDeviceNameOffset) device = (WCHAR *)((char *)dv + dv->tdDeviceNameOffset);
135 if (dv->tdPortNameOffset) port = (WCHAR *)((char *)dv + dv->tdPortNameOffset);
136 if (dv->tdExtDevmodeOffset) devmode = (DEVMODEW *)((char *)dv + dv->tdExtDevmodeOffset);
138 else
140 if (hdc) return hdc;
141 driver = displayW;
143 return CreateDCW( driver, device, port, devmode );
146 /***********************************************************************
147 * AtlHiMetricToPixel [atl100.@]
149 void WINAPI AtlHiMetricToPixel(const SIZEL* lpHiMetric, SIZEL* lpPix)
151 HDC dc = GetDC(NULL);
152 lpPix->cx = lpHiMetric->cx * GetDeviceCaps( dc, LOGPIXELSX ) / 100;
153 lpPix->cy = lpHiMetric->cy * GetDeviceCaps( dc, LOGPIXELSY ) / 100;
154 ReleaseDC( NULL, dc );
157 /***********************************************************************
158 * AtlPixelToHiMetric [atl100.@]
160 void WINAPI AtlPixelToHiMetric(const SIZEL* lpPix, SIZEL* lpHiMetric)
162 HDC dc = GetDC(NULL);
163 lpHiMetric->cx = 100 * lpPix->cx / GetDeviceCaps( dc, LOGPIXELSX );
164 lpHiMetric->cy = 100 * lpPix->cy / GetDeviceCaps( dc, LOGPIXELSY );
165 ReleaseDC( NULL, dc );
168 /***********************************************************************
169 * AtlComPtrAssign [atl100.@]
171 IUnknown* WINAPI AtlComPtrAssign(IUnknown** pp, IUnknown *p)
173 TRACE("(%p %p)\n", pp, p);
175 if (p) IUnknown_AddRef(p);
176 if (*pp) IUnknown_Release(*pp);
177 *pp = p;
178 return p;
181 /***********************************************************************
182 * AtlComQIPtrAssign [atl100.@]
184 IUnknown* WINAPI AtlComQIPtrAssign(IUnknown** pp, IUnknown *p, REFIID riid)
186 IUnknown *new_p = NULL;
188 TRACE("(%p %p %s)\n", pp, p, debugstr_guid(riid));
190 if (p) IUnknown_QueryInterface(p, riid, (void **)&new_p);
191 if (*pp) IUnknown_Release(*pp);
192 *pp = new_p;
193 return new_p;
196 /***********************************************************************
197 * AtlInternalQueryInterface [atl100.@]
199 HRESULT WINAPI AtlInternalQueryInterface(void* this, const _ATL_INTMAP_ENTRY* pEntries, REFIID iid, void** ppvObject)
201 int i = 0;
202 HRESULT rc = E_NOINTERFACE;
203 TRACE("(%p, %p, %s, %p)\n",this, pEntries, debugstr_guid(iid), ppvObject);
205 if (IsEqualGUID(iid,&IID_IUnknown))
207 TRACE("Returning IUnknown\n");
208 *ppvObject = ((LPSTR)this+pEntries[0].dw);
209 IUnknown_AddRef((IUnknown*)*ppvObject);
210 return S_OK;
213 while (pEntries[i].pFunc != 0)
215 TRACE("Trying entry %i (%s %i %p)\n",i,debugstr_guid(pEntries[i].piid),
216 pEntries[i].dw, pEntries[i].pFunc);
218 if (!pEntries[i].piid || IsEqualGUID(iid,pEntries[i].piid))
220 TRACE("MATCH\n");
221 if (pEntries[i].pFunc == (_ATL_CREATORARGFUNC*)1)
223 TRACE("Offset\n");
224 *ppvObject = ((LPSTR)this+pEntries[i].dw);
225 IUnknown_AddRef((IUnknown*)*ppvObject);
226 return S_OK;
228 else
230 TRACE("Function\n");
231 rc = pEntries[i].pFunc(this, iid, ppvObject, pEntries[i].dw);
232 if(rc==S_OK || pEntries[i].piid)
233 return rc;
236 i++;
238 TRACE("Done returning (0x%x)\n",rc);
239 return rc;
242 /* FIXME: should be in a header file */
243 typedef struct ATL_PROPMAP_ENTRY
245 LPCOLESTR szDesc;
246 DISPID dispid;
247 const CLSID* pclsidPropPage;
248 const IID* piidDispatch;
249 DWORD dwOffsetData;
250 DWORD dwSizeData;
251 VARTYPE vt;
252 } ATL_PROPMAP_ENTRY;
254 /***********************************************************************
255 * AtlIPersistStreamInit_Load [atl100.@]
257 HRESULT WINAPI AtlIPersistStreamInit_Load( LPSTREAM pStm, ATL_PROPMAP_ENTRY *pMap,
258 void *pThis, IUnknown *pUnk)
260 FIXME("(%p, %p, %p, %p)\n", pStm, pMap, pThis, pUnk);
262 return S_OK;
265 /***********************************************************************
266 * AtlIPersistStreamInit_Save [atl100.@]
268 HRESULT WINAPI AtlIPersistStreamInit_Save(LPSTREAM pStm, BOOL fClearDirty,
269 ATL_PROPMAP_ENTRY *pMap, void *pThis,
270 IUnknown *pUnk)
272 FIXME("(%p, %d, %p, %p, %p)\n", pStm, fClearDirty, pMap, pThis, pUnk);
274 return S_OK;
277 /***********************************************************************
278 * AtlModuleAddTermFunc [atl100.@]
280 HRESULT WINAPI AtlModuleAddTermFunc(_ATL_MODULE *pM, _ATL_TERMFUNC *pFunc, DWORD_PTR dw)
282 _ATL_TERMFUNC_ELEM *termfunc_elem;
284 TRACE("(%p %p %ld)\n", pM, pFunc, dw);
286 termfunc_elem = HeapAlloc(GetProcessHeap(), 0, sizeof(_ATL_TERMFUNC_ELEM));
287 termfunc_elem->pFunc = pFunc;
288 termfunc_elem->dw = dw;
289 termfunc_elem->pNext = pM->m_pTermFuncs;
291 pM->m_pTermFuncs = termfunc_elem;
293 return S_OK;
296 /***********************************************************************
297 * AtlCallTermFunc [atl100.@]
299 void WINAPI AtlCallTermFunc(_ATL_MODULE *pM)
301 _ATL_TERMFUNC_ELEM *iter = pM->m_pTermFuncs, *tmp;
303 TRACE("(%p)\n", pM);
305 while(iter) {
306 iter->pFunc(iter->dw);
307 tmp = iter;
308 iter = iter->pNext;
309 HeapFree(GetProcessHeap(), 0, tmp);
312 pM->m_pTermFuncs = NULL;
315 /***********************************************************************
316 * AtlLoadTypeLib [atl100.56]
318 HRESULT WINAPI AtlLoadTypeLib(HINSTANCE inst, LPCOLESTR lpszIndex,
319 BSTR *pbstrPath, ITypeLib **ppTypeLib)
321 size_t path_len, index_len;
322 ITypeLib *typelib = NULL;
323 WCHAR *path;
324 HRESULT hres;
326 static const WCHAR tlb_extW[] = {'.','t','l','b',0};
328 TRACE("(%p %s %p %p)\n", inst, debugstr_w(lpszIndex), pbstrPath, ppTypeLib);
330 index_len = lpszIndex ? strlenW(lpszIndex) : 0;
331 path = heap_alloc((MAX_PATH+index_len)*sizeof(WCHAR) + sizeof(tlb_extW));
332 if(!path)
333 return E_OUTOFMEMORY;
335 path_len = GetModuleFileNameW(inst, path, MAX_PATH);
336 if(!path_len) {
337 heap_free(path);
338 return HRESULT_FROM_WIN32(GetLastError());
341 if(index_len)
342 memcpy(path+path_len, lpszIndex, (index_len+1)*sizeof(WCHAR));
344 hres = LoadTypeLib(path, &typelib);
345 if(FAILED(hres)) {
346 WCHAR *ptr;
348 for(ptr = path+path_len-1; ptr > path && *ptr != '\\' && *ptr != '.'; ptr--);
349 if(*ptr != '.')
350 ptr = path+path_len;
351 memcpy(ptr, tlb_extW, sizeof(tlb_extW));
352 hres = LoadTypeLib(path, &typelib);
355 if(SUCCEEDED(hres)) {
356 *pbstrPath = SysAllocString(path);
357 if(!*pbstrPath) {
358 ITypeLib_Release(typelib);
359 hres = E_OUTOFMEMORY;
363 heap_free(path);
364 if(FAILED(hres))
365 return hres;
367 *ppTypeLib = typelib;
368 return S_OK;
371 /***********************************************************************
372 * AtlWinModuleInit [atl100.65]
374 HRESULT WINAPI AtlWinModuleInit(_ATL_WIN_MODULE *winmod)
376 TRACE("(%p\n", winmod);
378 if(winmod->cbSize != sizeof(*winmod))
379 return E_INVALIDARG;
381 InitializeCriticalSection(&winmod->m_csWindowCreate);
382 winmod->m_pCreateWndList = NULL;
383 return S_OK;
386 /***********************************************************************
387 * AtlWinModuleAddCreateWndData [atl100.43]
389 void WINAPI AtlWinModuleAddCreateWndData(_ATL_WIN_MODULE *pM, _AtlCreateWndData *pData, void *pvObject)
391 TRACE("(%p, %p, %p)\n", pM, pData, pvObject);
393 pData->m_pThis = pvObject;
394 pData->m_dwThreadID = GetCurrentThreadId();
396 EnterCriticalSection(&pM->m_csWindowCreate);
397 pData->m_pNext = pM->m_pCreateWndList;
398 pM->m_pCreateWndList = pData;
399 LeaveCriticalSection(&pM->m_csWindowCreate);
402 /***********************************************************************
403 * AtlWinModuleExtractCreateWndData [atl100.44]
405 void* WINAPI AtlWinModuleExtractCreateWndData(_ATL_WIN_MODULE *winmod)
407 _AtlCreateWndData *iter, *prev = NULL;
408 DWORD thread_id;
410 TRACE("(%p)\n", winmod);
412 thread_id = GetCurrentThreadId();
414 EnterCriticalSection(&winmod->m_csWindowCreate);
416 for(iter = winmod->m_pCreateWndList; iter && iter->m_dwThreadID != thread_id; iter = iter->m_pNext)
417 prev = iter;
418 if(iter) {
419 if(prev)
420 prev->m_pNext = iter->m_pNext;
421 else
422 winmod->m_pCreateWndList = iter->m_pNext;
425 LeaveCriticalSection(&winmod->m_csWindowCreate);
427 return iter ? iter->m_pThis : NULL;
430 /***********************************************************************
431 * AtlComModuleGetClassObject [atl100.15]
433 HRESULT WINAPI AtlComModuleGetClassObject(_ATL_COM_MODULE *pm, REFCLSID rclsid, REFIID riid, void **ppv)
435 _ATL_OBJMAP_ENTRY **iter;
436 HRESULT hres;
438 TRACE("(%p %s %s %p)\n", pm, debugstr_guid(rclsid), debugstr_guid(riid), ppv);
440 if(!pm)
441 return E_INVALIDARG;
443 for(iter = pm->m_ppAutoObjMapFirst; iter < pm->m_ppAutoObjMapLast; iter++) {
444 if(IsEqualCLSID((*iter)->pclsid, rclsid) && (*iter)->pfnGetClassObject) {
445 if(!(*iter)->pCF)
446 hres = (*iter)->pfnGetClassObject((*iter)->pfnCreateInstance, &IID_IUnknown, (void**)&(*iter)->pCF);
447 if((*iter)->pCF)
448 hres = IUnknown_QueryInterface((*iter)->pCF, riid, ppv);
449 TRACE("returning %p (%08x)\n", *ppv, hres);
450 return hres;
454 WARN("Class %s not found\n", debugstr_guid(rclsid));
455 return CLASS_E_CLASSNOTAVAILABLE;
458 /***********************************************************************
459 * AtlComModuleRegisterClassObjects [atl100.17]
461 HRESULT WINAPI AtlComModuleRegisterClassObjects(_ATL_COM_MODULE *module, DWORD context, DWORD flags)
463 _ATL_OBJMAP_ENTRY **iter;
464 IUnknown *unk;
465 HRESULT hres;
467 TRACE("(%p %x %x)\n", module, context, flags);
469 if(!module)
470 return E_INVALIDARG;
472 for(iter = module->m_ppAutoObjMapFirst; iter < module->m_ppAutoObjMapLast; iter++) {
473 if(!(*iter)->pfnGetClassObject)
474 continue;
476 hres = (*iter)->pfnGetClassObject((*iter)->pfnCreateInstance, &IID_IUnknown, (void**)&unk);
477 if(FAILED(hres))
478 return hres;
480 hres = CoRegisterClassObject((*iter)->pclsid, unk, context, flags, &(*iter)->dwRegister);
481 IUnknown_Release(unk);
482 if(FAILED(hres))
483 return hres;
486 return S_OK;
490 /***********************************************************************
491 * AtlComModuleUnregisterServer [atl100.22]
493 HRESULT WINAPI AtlComModuleUnregisterServer(_ATL_COM_MODULE *mod, BOOL bRegTypeLib, const CLSID *clsid)
495 const struct _ATL_CATMAP_ENTRY *catmap;
496 _ATL_OBJMAP_ENTRY **iter;
497 HRESULT hres;
499 TRACE("(%p %x %s)\n", mod, bRegTypeLib, debugstr_guid(clsid));
501 for(iter = mod->m_ppAutoObjMapFirst; iter < mod->m_ppAutoObjMapLast; iter++) {
502 if(!*iter || (clsid && !IsEqualCLSID((*iter)->pclsid, clsid)))
503 continue;
505 TRACE("Unregistering clsid %s\n", debugstr_guid((*iter)->pclsid));
507 catmap = (*iter)->pfnGetCategoryMap();
508 if(catmap) {
509 hres = AtlRegisterClassCategoriesHelper((*iter)->pclsid, catmap, FALSE);
510 if(FAILED(hres))
511 return hres;
514 hres = (*iter)->pfnUpdateRegistry(FALSE);
515 if(FAILED(hres))
516 return hres;
519 if(bRegTypeLib) {
520 ITypeLib *typelib;
521 TLIBATTR *attr;
522 BSTR path;
524 hres = AtlLoadTypeLib(mod->m_hInstTypeLib, NULL, &path, &typelib);
525 if(FAILED(hres))
526 return hres;
528 SysFreeString(path);
529 hres = ITypeLib_GetLibAttr(typelib, &attr);
530 if(SUCCEEDED(hres)) {
531 hres = UnRegisterTypeLib(&attr->guid, attr->wMajorVerNum, attr->wMinorVerNum, attr->lcid, attr->syskind);
532 ITypeLib_ReleaseTLibAttr(typelib, attr);
534 ITypeLib_Release(typelib);
535 if(FAILED(hres))
536 return hres;
539 return S_OK;
542 /***********************************************************************
543 * AtlRegisterClassCategoriesHelper [atl100.49]
545 HRESULT WINAPI AtlRegisterClassCategoriesHelper(REFCLSID clsid, const struct _ATL_CATMAP_ENTRY *catmap, BOOL reg)
547 const struct _ATL_CATMAP_ENTRY *iter;
548 HRESULT hres;
550 TRACE("(%s %p %x)\n", debugstr_guid(clsid), catmap, reg);
552 if(!catmap)
553 return S_OK;
555 if(!catreg) {
556 ICatRegister *new_catreg;
558 hres = CoCreateInstance(&CLSID_StdComponentCategoriesMgr, NULL, CLSCTX_INPROC_SERVER,
559 &IID_ICatRegister, (void**)&new_catreg);
560 if(FAILED(hres))
561 return hres;
563 if(InterlockedCompareExchangePointer((void**)&catreg, new_catreg, NULL))
564 ICatRegister_Release(new_catreg);
567 for(iter = catmap; iter->iType != _ATL_CATMAP_ENTRY_END; iter++) {
568 CATID catid = *iter->pcatid; /* For stupid lack of const in ICatRegister declaration. */
570 if(iter->iType == _ATL_CATMAP_ENTRY_IMPLEMENTED) {
571 if(reg)
572 hres = ICatRegister_RegisterClassImplCategories(catreg, clsid, 1, &catid);
573 else
574 hres = ICatRegister_UnRegisterClassImplCategories(catreg, clsid, 1, &catid);
575 }else {
576 if(reg)
577 hres = ICatRegister_RegisterClassReqCategories(catreg, clsid, 1, &catid);
578 else
579 hres = ICatRegister_UnRegisterClassReqCategories(catreg, clsid, 1, &catid);
581 if(FAILED(hres))
582 return hres;
585 if(!reg) {
586 WCHAR reg_path[256] = {'C','L','S','I','D','\\'}, *ptr = reg_path+6;
588 static const WCHAR implemented_catW[] =
589 {'I','m','p','l','e','m','e','n','t','e','d',' ','C','a','t','e','g','o','r','i','e','s',0};
590 static const WCHAR required_catW[] =
591 {'R','e','q','u','i','r','e','d',' ','C','a','t','e','g','o','r','i','e','s',0};
593 ptr += StringFromGUID2(clsid, ptr, 64)-1;
594 *ptr++ = '\\';
596 memcpy(ptr, implemented_catW, sizeof(implemented_catW));
597 RegDeleteKeyW(HKEY_CLASSES_ROOT, reg_path);
599 memcpy(ptr, required_catW, sizeof(required_catW));
600 RegDeleteKeyW(HKEY_CLASSES_ROOT, reg_path);
603 return S_OK;
606 /***********************************************************************
607 * AtlWaitWithMessageLoop [atl100.24]
609 BOOL WINAPI AtlWaitWithMessageLoop(HANDLE handle)
611 MSG msg;
612 DWORD res;
614 TRACE("(%p)\n", handle);
616 while(1) {
617 res = MsgWaitForMultipleObjects(1, &handle, FALSE, INFINITE, QS_ALLINPUT);
618 switch(res) {
619 case WAIT_OBJECT_0:
620 return TRUE;
621 case WAIT_OBJECT_0+1:
622 if(GetMessageW(&msg, NULL, 0, 0) < 0)
623 return FALSE;
625 TranslateMessage(&msg);
626 DispatchMessageW(&msg);
627 break;
628 default:
629 return FALSE;
634 static HRESULT get_default_source(ITypeLib *typelib, const CLSID *clsid, IID *iid)
636 ITypeInfo *typeinfo, *src_typeinfo = NULL;
637 TYPEATTR *attr;
638 int type_flags;
639 unsigned i;
640 HRESULT hres;
642 hres = ITypeLib_GetTypeInfoOfGuid(typelib, clsid, &typeinfo);
643 if(FAILED(hres))
644 return hres;
646 hres = ITypeInfo_GetTypeAttr(typeinfo, &attr);
647 if(FAILED(hres)) {
648 ITypeInfo_Release(typeinfo);
649 return hres;
652 for(i=0; i < attr->cImplTypes; i++) {
653 hres = ITypeInfo_GetImplTypeFlags(typeinfo, i, &type_flags);
654 if(SUCCEEDED(hres) && type_flags == (IMPLTYPEFLAG_FSOURCE|IMPLTYPEFLAG_FDEFAULT)) {
655 HREFTYPE ref;
657 hres = ITypeInfo_GetRefTypeOfImplType(typeinfo, i, &ref);
658 if(SUCCEEDED(hres))
659 hres = ITypeInfo_GetRefTypeInfo(typeinfo, ref, &src_typeinfo);
660 break;
664 ITypeInfo_ReleaseTypeAttr(typeinfo, attr);
665 ITypeInfo_Release(typeinfo);
666 if(FAILED(hres))
667 return hres;
669 if(!src_typeinfo) {
670 *iid = IID_NULL;
671 return S_OK;
674 hres = ITypeInfo_GetTypeAttr(src_typeinfo, &attr);
675 if(SUCCEEDED(hres)) {
676 *iid = attr->guid;
677 ITypeInfo_ReleaseTypeAttr(src_typeinfo, attr);
679 ITypeInfo_Release(src_typeinfo);
680 return hres;
683 /***********************************************************************
684 * AtlGetObjectSourceInterface [atl100.54]
686 HRESULT WINAPI AtlGetObjectSourceInterface(IUnknown *unk, GUID *libid, IID *iid, unsigned short *major, unsigned short *minor)
688 IProvideClassInfo2 *classinfo;
689 ITypeInfo *typeinfo;
690 ITypeLib *typelib;
691 IPersist *persist;
692 IDispatch *disp;
693 HRESULT hres;
695 TRACE("(%p %p %p %p %p)\n", unk, libid, iid, major, minor);
697 hres = IUnknown_QueryInterface(unk, &IID_IDispatch, (void**)&disp);
698 if(FAILED(hres))
699 return hres;
701 hres = IDispatch_GetTypeInfo(disp, 0, 0, &typeinfo);
702 IDispatch_Release(disp);
703 if(FAILED(hres))
704 return hres;
706 hres = ITypeInfo_GetContainingTypeLib(typeinfo, &typelib, 0);
707 ITypeInfo_Release(typeinfo);
708 if(SUCCEEDED(hres)) {
709 TLIBATTR *attr;
711 hres = ITypeLib_GetLibAttr(typelib, &attr);
712 if(SUCCEEDED(hres)) {
713 *libid = attr->guid;
714 *major = attr->wMajorVerNum;
715 *minor = attr->wMinorVerNum;
716 ITypeLib_ReleaseTLibAttr(typelib, attr);
717 }else {
718 ITypeLib_Release(typelib);
721 if(FAILED(hres))
722 return hres;
724 hres = IUnknown_QueryInterface(unk, &IID_IProvideClassInfo2, (void**)&classinfo);
725 if(SUCCEEDED(hres)) {
726 hres = IProvideClassInfo2_GetGUID(classinfo, GUIDKIND_DEFAULT_SOURCE_DISP_IID, iid);
727 IProvideClassInfo2_Release(classinfo);
728 ITypeLib_Release(typelib);
729 return hres;
732 hres = IUnknown_QueryInterface(unk, &IID_IPersist, (void**)&persist);
733 if(SUCCEEDED(hres)) {
734 CLSID clsid;
736 hres = IPersist_GetClassID(persist, &clsid);
737 if(SUCCEEDED(hres))
738 hres = get_default_source(typelib, &clsid, iid);
739 IPersist_Release(persist);
742 return hres;
745 /***********************************************************************
746 * AtlGetPerUserRegistration [atl100.68]
748 HRESULT WINAPI AtlGetPerUserRegistration(cpp_bool *pbEnabled)
750 FIXME("stub: returning false\n");
751 *pbEnabled = 0;
752 return S_OK;
755 /***********************************************************************
756 * AtlGetVersion [atl100.@]
758 DWORD WINAPI AtlGetVersion(void *pReserved)
760 return _ATL_VER;
763 BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
765 TRACE("(0x%p, %d, %p)\n", hinstDLL, fdwReason, lpvReserved);
767 switch(fdwReason) {
768 case DLL_PROCESS_ATTACH:
769 DisableThreadLibraryCalls(hinstDLL);
770 break;
771 case DLL_PROCESS_DETACH:
772 if(catreg)
773 ICatRegister_Release(catreg);
776 return TRUE;