Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
wine-mirror
GitHub Repository: wine-mirror/wine
Path: blob/master/dlls/atl/atl30.c
4389 views
1
/*
2
* Implementation of Active Template Library (atl.dll)
3
*
4
* Copyright 2004 Aric Stewart for CodeWeavers
5
* Copyright 2005 Jacek Caban
6
*
7
* This library is free software; you can redistribute it and/or
8
* modify it under the terms of the GNU Lesser General Public
9
* License as published by the Free Software Foundation; either
10
* version 2.1 of the License, or (at your option) any later version.
11
*
12
* This library is distributed in the hope that it will be useful,
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15
* Lesser General Public License for more details.
16
*
17
* You should have received a copy of the GNU Lesser General Public
18
* License along with this library; if not, write to the Free Software
19
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20
*/
21
22
#include <stdio.h>
23
24
#define COBJMACROS
25
26
#include "objidl.h"
27
#include "rpcproxy.h"
28
#include "atlbase.h"
29
#include "atlwin.h"
30
31
#include "wine/debug.h"
32
33
WINE_DEFAULT_DEBUG_CHANNEL(atl);
34
35
#define ATLVer1Size FIELD_OFFSET(_ATL_MODULEW, dwAtlBuildVer)
36
37
HRESULT WINAPI AtlModuleInit(_ATL_MODULEW* pM, _ATL_OBJMAP_ENTRYW* p, HINSTANCE h)
38
{
39
INT i;
40
UINT size;
41
42
TRACE("(%p %p %p)\n", pM, p, h);
43
44
size = pM->cbSize;
45
switch (size)
46
{
47
case ATLVer1Size:
48
case sizeof(_ATL_MODULEW):
49
#ifdef _WIN64
50
case sizeof(_ATL_MODULEW) + sizeof(void *):
51
#endif
52
break;
53
default:
54
WARN("Unknown structure version (size %i)\n",size);
55
return E_INVALIDARG;
56
}
57
58
memset(pM,0,pM->cbSize);
59
pM->cbSize = size;
60
pM->m_hInst = h;
61
pM->m_hInstResource = h;
62
pM->m_hInstTypeLib = h;
63
pM->m_pObjMap = p;
64
pM->m_hHeap = GetProcessHeap();
65
66
InitializeCriticalSection(&pM->u.m_csTypeInfoHolder);
67
InitializeCriticalSection(&pM->m_csWindowCreate);
68
InitializeCriticalSection(&pM->m_csObjMap);
69
70
/* call mains */
71
i = 0;
72
if (pM->m_pObjMap != NULL && size > ATLVer1Size)
73
{
74
while (pM->m_pObjMap[i].pclsid != NULL)
75
{
76
TRACE("Initializing object %i %p\n",i,p[i].pfnObjectMain);
77
if (p[i].pfnObjectMain)
78
p[i].pfnObjectMain(TRUE);
79
i++;
80
}
81
}
82
83
return S_OK;
84
}
85
86
static _ATL_OBJMAP_ENTRYW_V1 *get_objmap_entry( _ATL_MODULEW *mod, unsigned int index )
87
{
88
_ATL_OBJMAP_ENTRYW_V1 *ret;
89
90
if (mod->cbSize == ATLVer1Size)
91
ret = (_ATL_OBJMAP_ENTRYW_V1 *)mod->m_pObjMap + index;
92
else
93
ret = (_ATL_OBJMAP_ENTRYW_V1 *)(mod->m_pObjMap + index);
94
95
if (!ret->pclsid) ret = NULL;
96
return ret;
97
}
98
99
HRESULT WINAPI AtlModuleLoadTypeLib(_ATL_MODULEW *pM, LPCOLESTR lpszIndex,
100
BSTR *pbstrPath, ITypeLib **ppTypeLib)
101
{
102
TRACE("(%p, %s, %p, %p)\n", pM, debugstr_w(lpszIndex), pbstrPath, ppTypeLib);
103
104
if (!pM)
105
return E_INVALIDARG;
106
107
return AtlLoadTypeLib(pM->m_hInstTypeLib, lpszIndex, pbstrPath, ppTypeLib);
108
}
109
110
HRESULT WINAPI AtlModuleTerm(_ATL_MODULE *pM)
111
{
112
_ATL_TERMFUNC_ELEM *iter, *tmp;
113
114
TRACE("(%p)\n", pM);
115
116
if (pM->cbSize > ATLVer1Size)
117
{
118
iter = pM->m_pTermFuncs;
119
120
while(iter) {
121
iter->pFunc(iter->dw);
122
tmp = iter;
123
iter = iter->pNext;
124
free(tmp);
125
}
126
}
127
128
return S_OK;
129
}
130
131
HRESULT WINAPI AtlModuleRegisterClassObjects(_ATL_MODULEW *pM, DWORD dwClsContext,
132
DWORD dwFlags)
133
{
134
_ATL_OBJMAP_ENTRYW_V1 *obj;
135
int i=0;
136
137
TRACE("(%p %li %li)\n",pM, dwClsContext, dwFlags);
138
139
if (pM == NULL)
140
return E_INVALIDARG;
141
142
while ((obj = get_objmap_entry( pM, i++ )))
143
{
144
IUnknown* pUnknown;
145
HRESULT rc;
146
147
TRACE("Registering object %i\n",i);
148
if (obj->pfnGetClassObject)
149
{
150
rc = obj->pfnGetClassObject(obj->pfnCreateInstance, &IID_IUnknown,
151
(LPVOID*)&pUnknown);
152
if (SUCCEEDED (rc) )
153
{
154
rc = CoRegisterClassObject(obj->pclsid, pUnknown, dwClsContext,
155
dwFlags, &obj->dwRegister);
156
157
if (FAILED (rc) )
158
WARN("Failed to register object %i: 0x%08lx\n", i, rc);
159
160
if (pUnknown)
161
IUnknown_Release(pUnknown);
162
}
163
}
164
}
165
166
return S_OK;
167
}
168
169
HRESULT WINAPI AtlModuleUnregisterServerEx(_ATL_MODULEW* pM, BOOL bUnRegTypeLib, const CLSID* pCLSID)
170
{
171
FIXME("(%p, %i, %p) stub\n", pM, bUnRegTypeLib, pCLSID);
172
return S_OK;
173
}
174
175
/***********************************************************************
176
* AtlModuleRegisterServer [ATL.@]
177
*
178
*/
179
HRESULT WINAPI AtlModuleRegisterServer(_ATL_MODULEW* pM, BOOL bRegTypeLib, const CLSID* clsid)
180
{
181
const _ATL_OBJMAP_ENTRYW_V1 *obj;
182
int i;
183
HRESULT hRes;
184
185
TRACE("%p %d %s\n", pM, bRegTypeLib, debugstr_guid(clsid));
186
187
if (pM == NULL)
188
return E_INVALIDARG;
189
190
for (i = 0; (obj = get_objmap_entry( pM, i )) != NULL; i++) /* register CLSIDs */
191
{
192
if (!clsid || IsEqualCLSID(obj->pclsid, clsid))
193
{
194
TRACE("Registering clsid %s\n", debugstr_guid(obj->pclsid));
195
hRes = obj->pfnUpdateRegistry(TRUE); /* register */
196
if (FAILED(hRes))
197
return hRes;
198
199
if(pM->cbSize > ATLVer1Size) {
200
const struct _ATL_CATMAP_ENTRY *catmap;
201
202
catmap = ((const _ATL_OBJMAP_ENTRYW*)obj)->pfnGetCategoryMap();
203
if(catmap) {
204
hRes = AtlRegisterClassCategoriesHelper(obj->pclsid, catmap, TRUE);
205
if(FAILED(hRes))
206
return hRes;
207
}
208
}
209
}
210
}
211
212
if (bRegTypeLib)
213
{
214
hRes = AtlRegisterTypeLib(pM->m_hInstTypeLib, NULL);
215
if (FAILED(hRes))
216
return hRes;
217
}
218
219
return S_OK;
220
}
221
222
/***********************************************************************
223
* AtlModuleGetClassObject [ATL.@]
224
*/
225
HRESULT WINAPI AtlModuleGetClassObject(_ATL_MODULEW *pm, REFCLSID rclsid,
226
REFIID riid, LPVOID *ppv)
227
{
228
_ATL_OBJMAP_ENTRYW_V1 *obj;
229
int i;
230
HRESULT hres = CLASS_E_CLASSNOTAVAILABLE;
231
232
TRACE("%p %s %s %p\n", pm, debugstr_guid(rclsid), debugstr_guid(riid), ppv);
233
234
if (pm == NULL)
235
return E_INVALIDARG;
236
237
for (i = 0; (obj = get_objmap_entry( pm, i )) != NULL; i++)
238
{
239
if (IsEqualCLSID(obj->pclsid, rclsid))
240
{
241
TRACE("found object %i\n", i);
242
if (obj->pfnGetClassObject)
243
{
244
if (!obj->pCF)
245
hres = obj->pfnGetClassObject(obj->pfnCreateInstance,
246
&IID_IUnknown,
247
(void **)&obj->pCF);
248
if (obj->pCF)
249
hres = IUnknown_QueryInterface(obj->pCF, riid, ppv);
250
return hres;
251
}
252
}
253
}
254
255
WARN("no class object found for %s\n", debugstr_guid(rclsid));
256
257
return hres;
258
}
259
260
/***********************************************************************
261
* AtlModuleRegisterTypeLib [ATL.@]
262
*/
263
HRESULT WINAPI AtlModuleRegisterTypeLib(_ATL_MODULEW *pm, LPCOLESTR lpszIndex)
264
{
265
TRACE("%p %s\n", pm, debugstr_w(lpszIndex));
266
267
if (!pm)
268
return E_INVALIDARG;
269
270
return AtlRegisterTypeLib(pm->m_hInstTypeLib, lpszIndex);
271
}
272
273
/***********************************************************************
274
* AtlModuleRevokeClassObjects [ATL.@]
275
*/
276
HRESULT WINAPI AtlModuleRevokeClassObjects(_ATL_MODULEW *pm)
277
{
278
FIXME("%p\n", pm);
279
return E_FAIL;
280
}
281
282
/***********************************************************************
283
* AtlModuleUnregisterServer [ATL.@]
284
*/
285
HRESULT WINAPI AtlModuleUnregisterServer(_ATL_MODULEW *pm, const CLSID *clsid)
286
{
287
FIXME("%p %s\n", pm, debugstr_guid(clsid));
288
return E_FAIL;
289
}
290
291
/***********************************************************************
292
* AtlModuleRegisterWndClassInfoA [ATL.@]
293
*
294
* See AtlModuleRegisterWndClassInfoW.
295
*/
296
ATOM WINAPI AtlModuleRegisterWndClassInfoA(_ATL_MODULEA *pm, _ATL_WNDCLASSINFOA *wci, WNDPROC *pProc)
297
{
298
ATOM atom;
299
300
FIXME("%p %p %p semi-stub\n", pm, wci, pProc);
301
302
atom = wci->m_atom;
303
if (!atom)
304
{
305
WNDCLASSEXA wc;
306
307
TRACE("wci->m_wc.lpszClassName = %s\n", wci->m_wc.lpszClassName);
308
309
if (wci->m_lpszOrigName)
310
FIXME( "subclassing %s not implemented\n", debugstr_a(wci->m_lpszOrigName));
311
312
if (!wci->m_wc.lpszClassName)
313
{
314
sprintf(wci->m_szAutoName, "ATL:%p", wci);
315
TRACE("auto-generated class name %s\n", wci->m_szAutoName);
316
wci->m_wc.lpszClassName = wci->m_szAutoName;
317
}
318
319
atom = GetClassInfoExA(pm->m_hInst, wci->m_wc.lpszClassName, &wc);
320
if (!atom)
321
{
322
wci->m_wc.hInstance = pm->m_hInst;
323
wci->m_wc.hCursor = LoadCursorA( wci->m_bSystemCursor ? NULL : pm->m_hInst,
324
wci->m_lpszCursorID );
325
atom = RegisterClassExA(&wci->m_wc);
326
}
327
wci->pWndProc = wci->m_wc.lpfnWndProc;
328
wci->m_atom = atom;
329
}
330
331
if (wci->m_lpszOrigName) *pProc = wci->pWndProc;
332
333
TRACE("returning 0x%04x\n", atom);
334
return atom;
335
}
336
337
/***********************************************************************
338
* AtlModuleRegisterWndClassInfoW [ATL.@]
339
*
340
* PARAMS
341
* pm [IO] Information about the module registering the window.
342
* wci [IO] Information about the window being registered.
343
* pProc [O] Window procedure of the registered class.
344
*
345
* RETURNS
346
* Atom representing the registered class.
347
*
348
* NOTES
349
* Can be called multiple times without error, unlike RegisterClassEx().
350
*
351
* If the class name is NULL, then a class with a name of "ATL:xxxxxxxx" is
352
* registered, where 'xxxxxxxx' represents a unique hexadecimal value.
353
*
354
*/
355
ATOM WINAPI AtlModuleRegisterWndClassInfoW(_ATL_MODULEW *pm, _ATL_WNDCLASSINFOW *wci, WNDPROC *pProc)
356
{
357
ATOM atom;
358
359
FIXME("%p %p %p semi-stub\n", pm, wci, pProc);
360
361
atom = wci->m_atom;
362
if (!atom)
363
{
364
WNDCLASSEXW wc;
365
366
TRACE("wci->m_wc.lpszClassName = %s\n", debugstr_w(wci->m_wc.lpszClassName));
367
368
if (wci->m_lpszOrigName)
369
FIXME( "subclassing %s not implemented\n", debugstr_w(wci->m_lpszOrigName));
370
371
if (!wci->m_wc.lpszClassName)
372
{
373
swprintf(wci->m_szAutoName, ARRAY_SIZE(wci->m_szAutoName), L"ATL:%p", wci);
374
TRACE("auto-generated class name %s\n", debugstr_w(wci->m_szAutoName));
375
wci->m_wc.lpszClassName = wci->m_szAutoName;
376
}
377
378
atom = GetClassInfoExW(pm->m_hInst, wci->m_wc.lpszClassName, &wc);
379
if (!atom)
380
{
381
wci->m_wc.hInstance = pm->m_hInst;
382
wci->m_wc.hCursor = LoadCursorW( wci->m_bSystemCursor ? NULL : pm->m_hInst,
383
wci->m_lpszCursorID );
384
atom = RegisterClassExW(&wci->m_wc);
385
}
386
wci->pWndProc = wci->m_wc.lpfnWndProc;
387
wci->m_atom = atom;
388
}
389
390
if (wci->m_lpszOrigName) *pProc = wci->pWndProc;
391
392
TRACE("returning 0x%04x\n", atom);
393
return atom;
394
}
395
396
/***********************************************************************
397
* AtlModuleAddCreateWndData [ATL.@]
398
*/
399
void WINAPI AtlModuleAddCreateWndData(_ATL_MODULEW *pM, _AtlCreateWndData *pData, void* pvObject)
400
{
401
TRACE("(%p, %p, %p)\n", pM, pData, pvObject);
402
403
pData->m_pThis = pvObject;
404
pData->m_dwThreadID = GetCurrentThreadId();
405
406
EnterCriticalSection(&pM->m_csWindowCreate);
407
pData->m_pNext = pM->m_pCreateWndList;
408
pM->m_pCreateWndList = pData;
409
LeaveCriticalSection(&pM->m_csWindowCreate);
410
}
411
412
/***********************************************************************
413
* AtlModuleExtractCreateWndData [ATL.@]
414
*
415
* NOTE: Tests show that this function extracts one of _AtlCreateWndData
416
* records from the current thread from a list
417
*
418
*/
419
void* WINAPI AtlModuleExtractCreateWndData(_ATL_MODULEW *pM)
420
{
421
_AtlCreateWndData **ppData;
422
void *ret = NULL;
423
424
TRACE("(%p)\n", pM);
425
426
EnterCriticalSection(&pM->m_csWindowCreate);
427
428
for(ppData = &pM->m_pCreateWndList; *ppData!=NULL; ppData = &(*ppData)->m_pNext)
429
{
430
if ((*ppData)->m_dwThreadID == GetCurrentThreadId())
431
{
432
_AtlCreateWndData *pData = *ppData;
433
*ppData = pData->m_pNext;
434
ret = pData->m_pThis;
435
break;
436
}
437
}
438
439
LeaveCriticalSection(&pM->m_csWindowCreate);
440
return ret;
441
}
442
443
/***********************************************************************
444
* AtlModuleUpdateRegistryFromResourceD [ATL.@]
445
*
446
*/
447
HRESULT WINAPI AtlModuleUpdateRegistryFromResourceD(_ATL_MODULEW* pM, LPCOLESTR lpszRes,
448
BOOL bRegister, struct _ATL_REGMAP_ENTRY* pMapEntries, IRegistrar* pReg)
449
{
450
TRACE("(%p %s %d %p %p)\n", pM, debugstr_w(lpszRes), bRegister, pMapEntries, pReg);
451
452
return AtlUpdateRegistryFromResourceD(pM->m_hInst, lpszRes, bRegister, pMapEntries, pReg);
453
}
454
455
static HRESULT WINAPI RegistrarCF_QueryInterface(IClassFactory *iface, REFIID riid, void **ppvObject)
456
{
457
TRACE("(%p)->(%s %p)\n", iface, debugstr_guid(riid), ppvObject);
458
459
if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IClassFactory, riid)) {
460
*ppvObject = iface;
461
IClassFactory_AddRef( iface );
462
return S_OK;
463
}
464
465
return E_NOINTERFACE;
466
}
467
468
static ULONG WINAPI RegistrarCF_AddRef(IClassFactory *iface)
469
{
470
return 2;
471
}
472
473
static ULONG WINAPI RegistrarCF_Release(IClassFactory *iface)
474
{
475
return 1;
476
}
477
478
static HRESULT WINAPI RegistrarCF_CreateInstance(IClassFactory *iface, LPUNKNOWN pUnkOuter,
479
REFIID riid, void **ppv)
480
{
481
IRegistrar *registrar;
482
HRESULT hres;
483
484
TRACE("(%p)->(%s %p)\n", iface, debugstr_guid(riid), ppv);
485
486
if(pUnkOuter) {
487
*ppv = NULL;
488
return CLASS_E_NOAGGREGATION;
489
}
490
491
hres = AtlCreateRegistrar(&registrar);
492
if(FAILED(hres))
493
return hres;
494
495
hres = IRegistrar_QueryInterface(registrar, riid, ppv);
496
IRegistrar_Release(registrar);
497
return hres;
498
}
499
500
static HRESULT WINAPI RegistrarCF_LockServer(IClassFactory *iface, BOOL lock)
501
{
502
TRACE("(%p)->(%x)\n", iface, lock);
503
return S_OK;
504
}
505
506
static const IClassFactoryVtbl IRegistrarCFVtbl = {
507
RegistrarCF_QueryInterface,
508
RegistrarCF_AddRef,
509
RegistrarCF_Release,
510
RegistrarCF_CreateInstance,
511
RegistrarCF_LockServer
512
};
513
514
static IClassFactory RegistrarCF = { &IRegistrarCFVtbl };
515
516
/**************************************************************
517
* DllGetClassObject (ATL.2)
518
*/
519
HRESULT WINAPI DllGetClassObject(REFCLSID clsid, REFIID riid, LPVOID *ppvObject)
520
{
521
TRACE("(%s %s %p)\n", debugstr_guid(clsid), debugstr_guid(riid), ppvObject);
522
523
if(IsEqualGUID(&CLSID_Registrar, clsid))
524
return IClassFactory_QueryInterface( &RegistrarCF, riid, ppvObject );
525
526
FIXME("Not supported class %s\n", debugstr_guid(clsid));
527
return CLASS_E_CLASSNOTAVAILABLE;
528
}
529
530