Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
wine-mirror
GitHub Repository: wine-mirror/wine
Path: blob/master/dlls/atl/atl.c
4388 views
1
/*
2
* Copyright 2012 Stefan Leichter
3
* Copyright 2012 Jacek Caban for CodeWeavers
4
*
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.
9
*
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.
14
*
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
18
*/
19
20
#define COBJMACROS
21
22
#include "atlbase.h"
23
#include "atlcom.h"
24
25
#include "wine/debug.h"
26
27
WINE_DEFAULT_DEBUG_CHANNEL(atl);
28
29
#define ATLVer1Size FIELD_OFFSET(_ATL_MODULEW, dwAtlBuildVer)
30
31
typedef unsigned char cpp_bool;
32
33
static ICatRegister *catreg;
34
35
/***********************************************************************
36
* AtlAdvise [atl100.@]
37
*/
38
HRESULT WINAPI AtlAdvise(IUnknown *pUnkCP, IUnknown *pUnk, const IID *iid, DWORD *pdw)
39
{
40
IConnectionPointContainer *container;
41
IConnectionPoint *cp;
42
HRESULT hres;
43
44
TRACE("%p %p %p %p\n", pUnkCP, pUnk, iid, pdw);
45
46
if(!pUnkCP)
47
return E_INVALIDARG;
48
49
hres = IUnknown_QueryInterface(pUnkCP, &IID_IConnectionPointContainer, (void**)&container);
50
if(FAILED(hres))
51
return hres;
52
53
hres = IConnectionPointContainer_FindConnectionPoint(container, iid, &cp);
54
IConnectionPointContainer_Release(container);
55
if(FAILED(hres))
56
return hres;
57
58
hres = IConnectionPoint_Advise(cp, pUnk, pdw);
59
IConnectionPoint_Release(cp);
60
return hres;
61
}
62
63
/***********************************************************************
64
* AtlUnadvise [atl100.@]
65
*/
66
HRESULT WINAPI AtlUnadvise(IUnknown *pUnkCP, const IID *iid, DWORD dw)
67
{
68
IConnectionPointContainer *container;
69
IConnectionPoint *cp;
70
HRESULT hres;
71
72
TRACE("%p %p %ld\n", pUnkCP, iid, dw);
73
74
if(!pUnkCP)
75
return E_INVALIDARG;
76
77
hres = IUnknown_QueryInterface(pUnkCP, &IID_IConnectionPointContainer, (void**)&container);
78
if(FAILED(hres))
79
return hres;
80
81
hres = IConnectionPointContainer_FindConnectionPoint(container, iid, &cp);
82
IConnectionPointContainer_Release(container);
83
if(FAILED(hres))
84
return hres;
85
86
hres = IConnectionPoint_Unadvise(cp, dw);
87
IConnectionPoint_Release(cp);
88
return hres;
89
}
90
91
/***********************************************************************
92
* AtlFreeMarshalStream [atl100.@]
93
*/
94
HRESULT WINAPI AtlFreeMarshalStream(IStream *stm)
95
{
96
FIXME("%p\n", stm);
97
return S_OK;
98
}
99
100
/***********************************************************************
101
* AtlMarshalPtrInProc [atl100.@]
102
*/
103
HRESULT WINAPI AtlMarshalPtrInProc(IUnknown *pUnk, const IID *iid, IStream **pstm)
104
{
105
FIXME("%p %p %p\n", pUnk, iid, pstm);
106
return E_FAIL;
107
}
108
109
/***********************************************************************
110
* AtlUnmarshalPtr [atl100.@]
111
*/
112
HRESULT WINAPI AtlUnmarshalPtr(IStream *stm, const IID *iid, IUnknown **ppUnk)
113
{
114
FIXME("%p %p %p\n", stm, iid, ppUnk);
115
return E_FAIL;
116
}
117
118
/***********************************************************************
119
* AtlCreateTargetDC [atl100.@]
120
*/
121
HDC WINAPI AtlCreateTargetDC( HDC hdc, DVTARGETDEVICE *dv )
122
{
123
const WCHAR *driver = NULL, *device = NULL, *port = NULL;
124
DEVMODEW *devmode = NULL;
125
126
TRACE( "(%p, %p)\n", hdc, dv );
127
128
if (dv)
129
{
130
if (dv->tdDriverNameOffset) driver = (WCHAR *)((char *)dv + dv->tdDriverNameOffset);
131
if (dv->tdDeviceNameOffset) device = (WCHAR *)((char *)dv + dv->tdDeviceNameOffset);
132
if (dv->tdPortNameOffset) port = (WCHAR *)((char *)dv + dv->tdPortNameOffset);
133
if (dv->tdExtDevmodeOffset) devmode = (DEVMODEW *)((char *)dv + dv->tdExtDevmodeOffset);
134
}
135
else
136
{
137
if (hdc) return hdc;
138
driver = L"display";
139
}
140
return CreateDCW( driver, device, port, devmode );
141
}
142
143
/***********************************************************************
144
* AtlHiMetricToPixel [atl100.@]
145
*/
146
void WINAPI AtlHiMetricToPixel(const SIZEL* lpHiMetric, SIZEL* lpPix)
147
{
148
HDC dc = GetDC(NULL);
149
lpPix->cx = lpHiMetric->cx * GetDeviceCaps( dc, LOGPIXELSX ) / 100;
150
lpPix->cy = lpHiMetric->cy * GetDeviceCaps( dc, LOGPIXELSY ) / 100;
151
ReleaseDC( NULL, dc );
152
}
153
154
/***********************************************************************
155
* AtlPixelToHiMetric [atl100.@]
156
*/
157
void WINAPI AtlPixelToHiMetric(const SIZEL* lpPix, SIZEL* lpHiMetric)
158
{
159
HDC dc = GetDC(NULL);
160
lpHiMetric->cx = 100 * lpPix->cx / GetDeviceCaps( dc, LOGPIXELSX );
161
lpHiMetric->cy = 100 * lpPix->cy / GetDeviceCaps( dc, LOGPIXELSY );
162
ReleaseDC( NULL, dc );
163
}
164
165
/***********************************************************************
166
* AtlComPtrAssign [atl100.@]
167
*/
168
IUnknown* WINAPI AtlComPtrAssign(IUnknown** pp, IUnknown *p)
169
{
170
TRACE("(%p %p)\n", pp, p);
171
172
if (p) IUnknown_AddRef(p);
173
if (*pp) IUnknown_Release(*pp);
174
*pp = p;
175
return p;
176
}
177
178
/***********************************************************************
179
* AtlComQIPtrAssign [atl100.@]
180
*/
181
IUnknown* WINAPI AtlComQIPtrAssign(IUnknown** pp, IUnknown *p, REFIID riid)
182
{
183
IUnknown *new_p = NULL;
184
185
TRACE("(%p %p %s)\n", pp, p, debugstr_guid(riid));
186
187
if (p) IUnknown_QueryInterface(p, riid, (void **)&new_p);
188
if (*pp) IUnknown_Release(*pp);
189
*pp = new_p;
190
return new_p;
191
}
192
193
/***********************************************************************
194
* AtlInternalQueryInterface [atl100.@]
195
*/
196
HRESULT WINAPI AtlInternalQueryInterface(void* this, const _ATL_INTMAP_ENTRY* pEntries, REFIID iid, void** ppvObject)
197
{
198
int i = 0;
199
HRESULT rc = E_NOINTERFACE;
200
TRACE("(%p, %p, %s, %p)\n",this, pEntries, debugstr_guid(iid), ppvObject);
201
202
if (IsEqualGUID(iid,&IID_IUnknown))
203
{
204
TRACE("Returning IUnknown\n");
205
*ppvObject = ((LPSTR)this+pEntries[0].dw);
206
IUnknown_AddRef((IUnknown*)*ppvObject);
207
return S_OK;
208
}
209
210
while (pEntries[i].pFunc != 0)
211
{
212
TRACE("Trying entry %i (%s %Ix %p)\n",i,debugstr_guid(pEntries[i].piid),
213
pEntries[i].dw, pEntries[i].pFunc);
214
215
if (!pEntries[i].piid || IsEqualGUID(iid,pEntries[i].piid))
216
{
217
TRACE("MATCH\n");
218
if (pEntries[i].pFunc == (_ATL_CREATORARGFUNC*)1)
219
{
220
TRACE("Offset\n");
221
*ppvObject = ((LPSTR)this+pEntries[i].dw);
222
IUnknown_AddRef((IUnknown*)*ppvObject);
223
return S_OK;
224
}
225
else
226
{
227
TRACE("Function\n");
228
rc = pEntries[i].pFunc(this, iid, ppvObject, pEntries[i].dw);
229
if(rc==S_OK || pEntries[i].piid)
230
return rc;
231
}
232
}
233
i++;
234
}
235
TRACE("Done returning (0x%lx)\n",rc);
236
return rc;
237
}
238
239
/***********************************************************************
240
* AtlIPersistStreamInit_Load [atl100.@]
241
*/
242
HRESULT WINAPI AtlIPersistStreamInit_Load( LPSTREAM pStm, ATL_PROPMAP_ENTRY *pMap,
243
void *pThis, IUnknown *pUnk)
244
{
245
FIXME("(%p, %p, %p, %p)\n", pStm, pMap, pThis, pUnk);
246
247
return S_OK;
248
}
249
250
/***********************************************************************
251
* AtlIPersistStreamInit_Save [atl100.@]
252
*/
253
HRESULT WINAPI AtlIPersistStreamInit_Save(LPSTREAM pStm, BOOL fClearDirty,
254
ATL_PROPMAP_ENTRY *pMap, void *pThis,
255
IUnknown *pUnk)
256
{
257
FIXME("(%p, %d, %p, %p, %p)\n", pStm, fClearDirty, pMap, pThis, pUnk);
258
259
return S_OK;
260
}
261
262
/***********************************************************************
263
* AtlIPersistPropertyBag_Load [atl100.@]
264
*/
265
HRESULT WINAPI AtlIPersistPropertyBag_Load(LPPROPERTYBAG pPropBag, LPERRORLOG pErrorLog,
266
ATL_PROPMAP_ENTRY *pMap, void *pThis,
267
IUnknown *pUnk)
268
{
269
FIXME("(%p, %p, %p, %p, %p)\n", pPropBag, pErrorLog, pMap, pThis, pUnk);
270
271
return S_OK;
272
}
273
274
/***********************************************************************
275
* AtlIPersistPropertyBag_Save [atl100.@]
276
*/
277
HRESULT WINAPI AtlIPersistPropertyBag_Save(LPPROPERTYBAG pPropBag, BOOL fClearDirty,
278
BOOL fSaveAll, ATL_PROPMAP_ENTRY *pMap,
279
void *pThis, IUnknown *pUnk)
280
{
281
FIXME("(%p, %d, %d, %p, %p, %p)\n", pPropBag, fClearDirty, fSaveAll, pMap, pThis, pUnk);
282
283
return S_OK;
284
}
285
286
/***********************************************************************
287
* AtlModuleAddTermFunc [atl100.@]
288
*/
289
HRESULT WINAPI AtlModuleAddTermFunc(_ATL_MODULE *pM, _ATL_TERMFUNC *pFunc, DWORD_PTR dw)
290
{
291
_ATL_TERMFUNC_ELEM *termfunc_elem;
292
293
TRACE("version %04x (%p %p %Id)\n", _ATL_VER, pM, pFunc, dw);
294
295
if (_ATL_VER > _ATL_VER_30 || pM->cbSize > ATLVer1Size) {
296
termfunc_elem = malloc(sizeof(*termfunc_elem));
297
termfunc_elem->pFunc = pFunc;
298
termfunc_elem->dw = dw;
299
termfunc_elem->pNext = pM->m_pTermFuncs;
300
301
pM->m_pTermFuncs = termfunc_elem;
302
}
303
304
return S_OK;
305
}
306
307
#if _ATL_VER > _ATL_VER_30
308
309
/***********************************************************************
310
* AtlCallTermFunc [atl100.@]
311
*/
312
void WINAPI AtlCallTermFunc(_ATL_MODULE *pM)
313
{
314
_ATL_TERMFUNC_ELEM *iter = pM->m_pTermFuncs, *tmp;
315
316
TRACE("(%p)\n", pM);
317
318
while(iter) {
319
iter->pFunc(iter->dw);
320
tmp = iter;
321
iter = iter->pNext;
322
free(tmp);
323
}
324
325
pM->m_pTermFuncs = NULL;
326
}
327
328
#endif
329
330
/***********************************************************************
331
* AtlLoadTypeLib [atl100.56]
332
*/
333
HRESULT WINAPI AtlLoadTypeLib(HINSTANCE inst, LPCOLESTR lpszIndex,
334
BSTR *pbstrPath, ITypeLib **ppTypeLib)
335
{
336
size_t path_len, index_len;
337
ITypeLib *typelib = NULL;
338
WCHAR *path;
339
HRESULT hres;
340
341
TRACE("(%p %s %p %p)\n", inst, debugstr_w(lpszIndex), pbstrPath, ppTypeLib);
342
343
index_len = lpszIndex ? lstrlenW(lpszIndex) : 0;
344
path = malloc((MAX_PATH+index_len)*sizeof(WCHAR) + sizeof(L".tlb"));
345
if(!path)
346
return E_OUTOFMEMORY;
347
348
path_len = GetModuleFileNameW(inst, path, MAX_PATH);
349
if(!path_len) {
350
free(path);
351
return HRESULT_FROM_WIN32(GetLastError());
352
}
353
354
if(index_len)
355
memcpy(path+path_len, lpszIndex, (index_len+1)*sizeof(WCHAR));
356
357
hres = LoadTypeLib(path, &typelib);
358
if(FAILED(hres)) {
359
WCHAR *ptr;
360
361
for(ptr = path+path_len-1; ptr > path && *ptr != '\\' && *ptr != '.'; ptr--);
362
if(*ptr != '.')
363
ptr = path+path_len;
364
lstrcpyW(ptr, L".tlb");
365
hres = LoadTypeLib(path, &typelib);
366
}
367
368
if(SUCCEEDED(hres)) {
369
*pbstrPath = SysAllocString(path);
370
if(!*pbstrPath) {
371
ITypeLib_Release(typelib);
372
hres = E_OUTOFMEMORY;
373
}
374
}
375
376
free(path);
377
if(FAILED(hres))
378
return hres;
379
380
*ppTypeLib = typelib;
381
return S_OK;
382
}
383
384
#if _ATL_VER <= _ATL_VER_80
385
386
/***********************************************************************
387
* AtlRegisterTypeLib [atl80.19]
388
*/
389
HRESULT WINAPI AtlRegisterTypeLib(HINSTANCE inst, const WCHAR *index)
390
{
391
ITypeLib *typelib;
392
BSTR path;
393
HRESULT hres;
394
395
TRACE("(%p %s)\n", inst, debugstr_w(index));
396
397
hres = AtlLoadTypeLib(inst, index, &path, &typelib);
398
if(FAILED(hres))
399
return hres;
400
401
hres = RegisterTypeLib(typelib, path, NULL); /* FIXME: pass help directory */
402
ITypeLib_Release(typelib);
403
SysFreeString(path);
404
return hres;
405
}
406
407
#endif
408
409
#if _ATL_VER > _ATL_VER_30
410
411
/***********************************************************************
412
* AtlWinModuleInit [atl100.65]
413
*/
414
HRESULT WINAPI AtlWinModuleInit(_ATL_WIN_MODULE *winmod)
415
{
416
TRACE("(%p)\n", winmod);
417
418
if(winmod->cbSize != sizeof(*winmod))
419
return E_INVALIDARG;
420
421
InitializeCriticalSection(&winmod->m_csWindowCreate);
422
winmod->m_pCreateWndList = NULL;
423
return S_OK;
424
}
425
426
/***********************************************************************
427
* AtlWinModuleAddCreateWndData [atl100.43]
428
*/
429
void WINAPI AtlWinModuleAddCreateWndData(_ATL_WIN_MODULE *pM, _AtlCreateWndData *pData, void *pvObject)
430
{
431
TRACE("(%p, %p, %p)\n", pM, pData, pvObject);
432
433
pData->m_pThis = pvObject;
434
pData->m_dwThreadID = GetCurrentThreadId();
435
436
EnterCriticalSection(&pM->m_csWindowCreate);
437
pData->m_pNext = pM->m_pCreateWndList;
438
pM->m_pCreateWndList = pData;
439
LeaveCriticalSection(&pM->m_csWindowCreate);
440
}
441
442
/***********************************************************************
443
* AtlWinModuleExtractCreateWndData [atl100.44]
444
*/
445
void* WINAPI AtlWinModuleExtractCreateWndData(_ATL_WIN_MODULE *winmod)
446
{
447
_AtlCreateWndData *iter, *prev = NULL;
448
DWORD thread_id;
449
450
TRACE("(%p)\n", winmod);
451
452
thread_id = GetCurrentThreadId();
453
454
EnterCriticalSection(&winmod->m_csWindowCreate);
455
456
for(iter = winmod->m_pCreateWndList; iter && iter->m_dwThreadID != thread_id; iter = iter->m_pNext)
457
prev = iter;
458
if(iter) {
459
if(prev)
460
prev->m_pNext = iter->m_pNext;
461
else
462
winmod->m_pCreateWndList = iter->m_pNext;
463
}
464
465
LeaveCriticalSection(&winmod->m_csWindowCreate);
466
467
return iter ? iter->m_pThis : NULL;
468
}
469
470
/***********************************************************************
471
* AtlComModuleGetClassObject [atl100.15]
472
*/
473
#if _ATL_VER < _ATL_VER_110
474
HRESULT WINAPI AtlComModuleGetClassObject(_ATL_COM_MODULE *pm, REFCLSID rclsid, REFIID riid, void **ppv)
475
{
476
_ATL_OBJMAP_ENTRY **iter;
477
HRESULT hres;
478
479
TRACE("(%p %s %s %p)\n", pm, debugstr_guid(rclsid), debugstr_guid(riid), ppv);
480
481
if(!pm)
482
return E_INVALIDARG;
483
484
for(iter = pm->m_ppAutoObjMapFirst; iter < pm->m_ppAutoObjMapLast; iter++) {
485
if(*iter && IsEqualCLSID((*iter)->pclsid, rclsid) && (*iter)->pfnGetClassObject) {
486
if(!(*iter)->pCF)
487
hres = (*iter)->pfnGetClassObject((*iter)->pfnCreateInstance, &IID_IUnknown, (void**)&(*iter)->pCF);
488
if((*iter)->pCF)
489
hres = IUnknown_QueryInterface((*iter)->pCF, riid, ppv);
490
TRACE("returning %p (%08lx)\n", *ppv, hres);
491
return hres;
492
}
493
}
494
495
WARN("Class %s not found\n", debugstr_guid(rclsid));
496
return CLASS_E_CLASSNOTAVAILABLE;
497
}
498
#else
499
HRESULT WINAPI AtlComModuleGetClassObject(_ATL_COM_MODULE *pm, REFCLSID rclsid, REFIID riid, void **ppv)
500
{
501
_ATL_OBJMAP_ENTRY_EX **iter;
502
HRESULT hres;
503
504
TRACE("(%p %s %s %p)\n", pm, debugstr_guid(rclsid), debugstr_guid(riid), ppv);
505
506
if(!pm)
507
return E_INVALIDARG;
508
509
for(iter = pm->m_ppAutoObjMapFirst; iter < pm->m_ppAutoObjMapLast; iter++) {
510
if(*iter && IsEqualCLSID((*iter)->pclsid, rclsid) && (*iter)->pfnGetClassObject) {
511
if(!(*iter)->pCache->pCF)
512
hres = (*iter)->pfnGetClassObject((*iter)->pfnCreateInstance, &IID_IUnknown, (void**)&(*iter)->pCache->pCF);
513
if((*iter)->pCache->pCF)
514
hres = IUnknown_QueryInterface((*iter)->pCache->pCF, riid, ppv);
515
TRACE("returning %p (%08lx)\n", *ppv, hres);
516
return hres;
517
}
518
}
519
520
WARN("Class %s not found\n", debugstr_guid(rclsid));
521
return CLASS_E_CLASSNOTAVAILABLE;
522
}
523
#endif
524
525
/***********************************************************************
526
* AtlComModuleRegisterClassObjects [atl100.17]
527
*/
528
#if _ATL_VER < _ATL_VER_110
529
HRESULT WINAPI AtlComModuleRegisterClassObjects(_ATL_COM_MODULE *module, DWORD context, DWORD flags)
530
{
531
_ATL_OBJMAP_ENTRY **iter;
532
IUnknown *unk;
533
HRESULT hres;
534
535
TRACE("(%p %lx %lx)\n", module, context, flags);
536
537
if(!module)
538
return E_INVALIDARG;
539
540
for(iter = module->m_ppAutoObjMapFirst; iter < module->m_ppAutoObjMapLast; iter++) {
541
if(!(*iter) || !(*iter)->pfnGetClassObject)
542
continue;
543
544
hres = (*iter)->pfnGetClassObject((*iter)->pfnCreateInstance, &IID_IUnknown, (void**)&unk);
545
if(FAILED(hres))
546
return hres;
547
548
hres = CoRegisterClassObject((*iter)->pclsid, unk, context, flags, &(*iter)->dwRegister);
549
IUnknown_Release(unk);
550
if(FAILED(hres))
551
return hres;
552
}
553
554
return S_OK;
555
}
556
#else
557
HRESULT WINAPI AtlComModuleRegisterClassObjects(_ATL_COM_MODULE *module, DWORD context, DWORD flags)
558
{
559
_ATL_OBJMAP_ENTRY_EX **iter;
560
IUnknown *unk;
561
HRESULT hres;
562
563
TRACE("(%p %lx %lx)\n", module, context, flags);
564
565
if(!module)
566
return E_INVALIDARG;
567
568
for(iter = module->m_ppAutoObjMapFirst; iter < module->m_ppAutoObjMapLast; iter++) {
569
if(!(*iter) || !(*iter)->pfnGetClassObject)
570
continue;
571
572
hres = (*iter)->pfnGetClassObject((*iter)->pfnCreateInstance, &IID_IUnknown, (void**)&unk);
573
if(FAILED(hres))
574
return hres;
575
576
hres = CoRegisterClassObject((*iter)->pclsid, unk, context, flags, &(*iter)->pCache->dwRegister);
577
IUnknown_Release(unk);
578
if(FAILED(hres))
579
return hres;
580
}
581
582
return S_OK;
583
}
584
#endif
585
586
/***********************************************************************
587
* AtlComModuleRevokeClassObjects [atl100.20]
588
*/
589
#if _ATL_VER < _ATL_VER_110
590
HRESULT WINAPI AtlComModuleRevokeClassObjects(_ATL_COM_MODULE *module)
591
{
592
_ATL_OBJMAP_ENTRY **iter;
593
HRESULT hres;
594
595
TRACE("(%p)\n", module);
596
597
if(!module)
598
return E_INVALIDARG;
599
600
for(iter = module->m_ppAutoObjMapFirst; iter < module->m_ppAutoObjMapLast; iter++) {
601
if(!(*iter))
602
continue;
603
604
hres = CoRevokeClassObject((*iter)->dwRegister);
605
if(FAILED(hres))
606
return hres;
607
}
608
609
return S_OK;
610
}
611
#else
612
HRESULT WINAPI AtlComModuleRevokeClassObjects(_ATL_COM_MODULE *module)
613
{
614
_ATL_OBJMAP_ENTRY_EX **iter;
615
HRESULT hres;
616
617
TRACE("(%p)\n", module);
618
619
if(!module)
620
return E_INVALIDARG;
621
622
for(iter = module->m_ppAutoObjMapFirst; iter < module->m_ppAutoObjMapLast; iter++) {
623
if(!(*iter))
624
continue;
625
626
hres = CoRevokeClassObject((*iter)->pCache->dwRegister);
627
if(FAILED(hres))
628
return hres;
629
}
630
631
return S_OK;
632
}
633
#endif
634
635
/***********************************************************************
636
* AtlComModuleUnregisterServer [atl100.22]
637
*/
638
#if _ATL_VER < _ATL_VER_110
639
HRESULT WINAPI AtlComModuleUnregisterServer(_ATL_COM_MODULE *mod, BOOL bRegTypeLib, const CLSID *clsid)
640
{
641
const struct _ATL_CATMAP_ENTRY *catmap;
642
_ATL_OBJMAP_ENTRY **iter;
643
HRESULT hres;
644
645
TRACE("(%p %x %s)\n", mod, bRegTypeLib, debugstr_guid(clsid));
646
647
for(iter = mod->m_ppAutoObjMapFirst; iter < mod->m_ppAutoObjMapLast; iter++) {
648
if(!*iter || (clsid && !IsEqualCLSID((*iter)->pclsid, clsid)))
649
continue;
650
651
TRACE("Unregistering clsid %s\n", debugstr_guid((*iter)->pclsid));
652
653
catmap = (*iter)->pfnGetCategoryMap();
654
if(catmap) {
655
hres = AtlRegisterClassCategoriesHelper((*iter)->pclsid, catmap, FALSE);
656
if(FAILED(hres))
657
return hres;
658
}
659
660
hres = (*iter)->pfnUpdateRegistry(FALSE);
661
if(FAILED(hres))
662
return hres;
663
}
664
665
if(bRegTypeLib) {
666
ITypeLib *typelib;
667
TLIBATTR *attr;
668
BSTR path;
669
670
hres = AtlLoadTypeLib(mod->m_hInstTypeLib, NULL, &path, &typelib);
671
if(FAILED(hres))
672
return hres;
673
674
SysFreeString(path);
675
hres = ITypeLib_GetLibAttr(typelib, &attr);
676
if(SUCCEEDED(hres)) {
677
hres = UnRegisterTypeLib(&attr->guid, attr->wMajorVerNum, attr->wMinorVerNum, attr->lcid, attr->syskind);
678
ITypeLib_ReleaseTLibAttr(typelib, attr);
679
}
680
ITypeLib_Release(typelib);
681
if(FAILED(hres))
682
return hres;
683
}
684
685
return S_OK;
686
}
687
#else
688
HRESULT WINAPI AtlComModuleUnregisterServer(_ATL_COM_MODULE *mod, BOOL bRegTypeLib, const CLSID *clsid)
689
{
690
const struct _ATL_CATMAP_ENTRY *catmap;
691
_ATL_OBJMAP_ENTRY_EX **iter;
692
HRESULT hres;
693
694
TRACE("(%p %x %s)\n", mod, bRegTypeLib, debugstr_guid(clsid));
695
696
for(iter = mod->m_ppAutoObjMapFirst; iter < mod->m_ppAutoObjMapLast; iter++) {
697
if(!*iter || (clsid && !IsEqualCLSID((*iter)->pclsid, clsid)))
698
continue;
699
700
TRACE("Unregistering clsid %s\n", debugstr_guid((*iter)->pclsid));
701
702
catmap = (*iter)->pfnGetCategoryMap();
703
if(catmap) {
704
hres = AtlRegisterClassCategoriesHelper((*iter)->pclsid, catmap, FALSE);
705
if(FAILED(hres))
706
return hres;
707
}
708
709
hres = (*iter)->pfnUpdateRegistry(FALSE);
710
if(FAILED(hres))
711
return hres;
712
}
713
714
if(bRegTypeLib) {
715
ITypeLib *typelib;
716
TLIBATTR *attr;
717
BSTR path;
718
719
hres = AtlLoadTypeLib(mod->m_hInstTypeLib, NULL, &path, &typelib);
720
if(FAILED(hres))
721
return hres;
722
723
SysFreeString(path);
724
hres = ITypeLib_GetLibAttr(typelib, &attr);
725
if(SUCCEEDED(hres)) {
726
hres = UnRegisterTypeLib(&attr->guid, attr->wMajorVerNum, attr->wMinorVerNum, attr->lcid, attr->syskind);
727
ITypeLib_ReleaseTLibAttr(typelib, attr);
728
}
729
ITypeLib_Release(typelib);
730
if(FAILED(hres))
731
return hres;
732
}
733
734
return S_OK;
735
}
736
#endif
737
738
#endif
739
740
/***********************************************************************
741
* AtlRegisterClassCategoriesHelper [atl100.49]
742
*/
743
HRESULT WINAPI AtlRegisterClassCategoriesHelper(REFCLSID clsid, const struct _ATL_CATMAP_ENTRY *catmap, BOOL reg)
744
{
745
const struct _ATL_CATMAP_ENTRY *iter;
746
HRESULT hres;
747
748
TRACE("(%s %p %x)\n", debugstr_guid(clsid), catmap, reg);
749
750
if(!catmap)
751
return S_OK;
752
753
if(!catreg) {
754
ICatRegister *new_catreg;
755
756
hres = CoCreateInstance(&CLSID_StdComponentCategoriesMgr, NULL, CLSCTX_INPROC_SERVER,
757
&IID_ICatRegister, (void**)&new_catreg);
758
if(FAILED(hres))
759
return hres;
760
761
if(InterlockedCompareExchangePointer((void**)&catreg, new_catreg, NULL))
762
ICatRegister_Release(new_catreg);
763
}
764
765
for(iter = catmap; iter->iType != _ATL_CATMAP_ENTRY_END; iter++) {
766
CATID catid = *iter->pcatid; /* For stupid lack of const in ICatRegister declaration. */
767
768
if(iter->iType == _ATL_CATMAP_ENTRY_IMPLEMENTED) {
769
if(reg)
770
hres = ICatRegister_RegisterClassImplCategories(catreg, clsid, 1, &catid);
771
else
772
hres = ICatRegister_UnRegisterClassImplCategories(catreg, clsid, 1, &catid);
773
}else {
774
if(reg)
775
hres = ICatRegister_RegisterClassReqCategories(catreg, clsid, 1, &catid);
776
else
777
hres = ICatRegister_UnRegisterClassReqCategories(catreg, clsid, 1, &catid);
778
}
779
if(FAILED(hres))
780
return hres;
781
}
782
783
if(!reg) {
784
WCHAR reg_path[256] = L"CLSID\\", *ptr = reg_path+6;
785
786
ptr += StringFromGUID2(clsid, ptr, 64)-1;
787
*ptr++ = '\\';
788
789
lstrcpyW(ptr, L"Implemented Categories");
790
RegDeleteKeyW(HKEY_CLASSES_ROOT, reg_path);
791
792
lstrcpyW(ptr, L"Required Categories");
793
RegDeleteKeyW(HKEY_CLASSES_ROOT, reg_path);
794
}
795
796
return S_OK;
797
}
798
799
/***********************************************************************
800
* AtlWaitWithMessageLoop [atl100.24]
801
*/
802
BOOL WINAPI AtlWaitWithMessageLoop(HANDLE handle)
803
{
804
MSG msg;
805
DWORD res;
806
807
TRACE("(%p)\n", handle);
808
809
while(1) {
810
res = MsgWaitForMultipleObjects(1, &handle, FALSE, INFINITE, QS_ALLINPUT);
811
switch(res) {
812
case WAIT_OBJECT_0:
813
return TRUE;
814
case WAIT_OBJECT_0+1:
815
if(GetMessageW(&msg, NULL, 0, 0) < 0)
816
return FALSE;
817
818
TranslateMessage(&msg);
819
DispatchMessageW(&msg);
820
break;
821
default:
822
return FALSE;
823
}
824
}
825
}
826
827
static HRESULT get_default_source(ITypeLib *typelib, const CLSID *clsid, IID *iid)
828
{
829
ITypeInfo *typeinfo, *src_typeinfo = NULL;
830
TYPEATTR *attr;
831
int type_flags;
832
unsigned i;
833
HRESULT hres;
834
835
hres = ITypeLib_GetTypeInfoOfGuid(typelib, clsid, &typeinfo);
836
if(FAILED(hres))
837
return hres;
838
839
hres = ITypeInfo_GetTypeAttr(typeinfo, &attr);
840
if(FAILED(hres)) {
841
ITypeInfo_Release(typeinfo);
842
return hres;
843
}
844
845
for(i=0; i < attr->cImplTypes; i++) {
846
hres = ITypeInfo_GetImplTypeFlags(typeinfo, i, &type_flags);
847
if(SUCCEEDED(hres) && type_flags == (IMPLTYPEFLAG_FSOURCE|IMPLTYPEFLAG_FDEFAULT)) {
848
HREFTYPE ref;
849
850
hres = ITypeInfo_GetRefTypeOfImplType(typeinfo, i, &ref);
851
if(SUCCEEDED(hres))
852
hres = ITypeInfo_GetRefTypeInfo(typeinfo, ref, &src_typeinfo);
853
break;
854
}
855
}
856
857
ITypeInfo_ReleaseTypeAttr(typeinfo, attr);
858
ITypeInfo_Release(typeinfo);
859
if(FAILED(hres))
860
return hres;
861
862
if(!src_typeinfo) {
863
*iid = IID_NULL;
864
return S_OK;
865
}
866
867
hres = ITypeInfo_GetTypeAttr(src_typeinfo, &attr);
868
if(SUCCEEDED(hres)) {
869
*iid = attr->guid;
870
ITypeInfo_ReleaseTypeAttr(src_typeinfo, attr);
871
}
872
ITypeInfo_Release(src_typeinfo);
873
return hres;
874
}
875
876
/***********************************************************************
877
* AtlGetObjectSourceInterface [atl100.54]
878
*/
879
HRESULT WINAPI AtlGetObjectSourceInterface(IUnknown *unk, GUID *libid, IID *iid, unsigned short *major, unsigned short *minor)
880
{
881
IProvideClassInfo2 *classinfo;
882
ITypeInfo *typeinfo;
883
ITypeLib *typelib;
884
IPersist *persist;
885
IDispatch *disp;
886
HRESULT hres;
887
888
TRACE("(%p %p %p %p %p)\n", unk, libid, iid, major, minor);
889
890
hres = IUnknown_QueryInterface(unk, &IID_IDispatch, (void**)&disp);
891
if(FAILED(hres))
892
return hres;
893
894
hres = IDispatch_GetTypeInfo(disp, 0, 0, &typeinfo);
895
IDispatch_Release(disp);
896
if(FAILED(hres))
897
return hres;
898
899
hres = ITypeInfo_GetContainingTypeLib(typeinfo, &typelib, 0);
900
ITypeInfo_Release(typeinfo);
901
if(SUCCEEDED(hres)) {
902
TLIBATTR *attr;
903
904
hres = ITypeLib_GetLibAttr(typelib, &attr);
905
if(SUCCEEDED(hres)) {
906
*libid = attr->guid;
907
*major = attr->wMajorVerNum;
908
*minor = attr->wMinorVerNum;
909
ITypeLib_ReleaseTLibAttr(typelib, attr);
910
}else {
911
ITypeLib_Release(typelib);
912
}
913
}
914
if(FAILED(hres))
915
return hres;
916
917
hres = IUnknown_QueryInterface(unk, &IID_IProvideClassInfo2, (void**)&classinfo);
918
if(SUCCEEDED(hres)) {
919
hres = IProvideClassInfo2_GetGUID(classinfo, GUIDKIND_DEFAULT_SOURCE_DISP_IID, iid);
920
IProvideClassInfo2_Release(classinfo);
921
ITypeLib_Release(typelib);
922
return hres;
923
}
924
925
hres = IUnknown_QueryInterface(unk, &IID_IPersist, (void**)&persist);
926
if(SUCCEEDED(hres)) {
927
CLSID clsid;
928
929
hres = IPersist_GetClassID(persist, &clsid);
930
if(SUCCEEDED(hres))
931
hres = get_default_source(typelib, &clsid, iid);
932
IPersist_Release(persist);
933
}
934
935
return hres;
936
}
937
938
#if _ATL_VER >= _ATL_VER90
939
940
/***********************************************************************
941
* AtlSetPerUserRegistration [atl100.67]
942
*/
943
HRESULT WINAPI AtlSetPerUserRegistration(cpp_bool bEnable)
944
{
945
FIXME("stub: bEnable: %d\n", bEnable);
946
return E_NOTIMPL;
947
}
948
949
/***********************************************************************
950
* AtlGetPerUserRegistration [atl100.68]
951
*/
952
HRESULT WINAPI AtlGetPerUserRegistration(cpp_bool *pbEnabled)
953
{
954
FIXME("stub: returning false\n");
955
*pbEnabled = 0;
956
return S_OK;
957
}
958
959
#endif
960
961
/***********************************************************************
962
* AtlGetVersion [atl100.@]
963
*/
964
DWORD WINAPI AtlGetVersion(void *pReserved)
965
{
966
TRACE("version %04x (%p)\n", _ATL_VER, pReserved);
967
return _ATL_VER;
968
}
969
970
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
971
{
972
TRACE("(0x%p, %ld, %p)\n", hinstDLL, fdwReason, lpvReserved);
973
974
switch(fdwReason) {
975
case DLL_PROCESS_ATTACH:
976
DisableThreadLibraryCalls(hinstDLL);
977
break;
978
case DLL_PROCESS_DETACH:
979
if (lpvReserved) break;
980
if(catreg)
981
ICatRegister_Release(catreg);
982
}
983
984
return TRUE;
985
}
986
987