Commit | Line | Data |
---|---|---|
4bd374fa AS |
1 | /* |
2 | * Implementation of Active Template Library (atl.dll) | |
3 | * | |
4 | * Copyright 2004 Aric Stewart for CodeWeavers | |
5 | * | |
6 | * This library is free software; you can redistribute it and/or | |
7 | * modify it under the terms of the GNU Lesser General Public | |
8 | * License as published by the Free Software Foundation; either | |
9 | * version 2.1 of the License, or (at your option) any later version. | |
10 | * | |
11 | * This library is distributed in the hope that it will be useful, | |
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
14 | * Lesser General Public License for more details. | |
15 | * | |
16 | * You should have received a copy of the GNU Lesser General Public | |
17 | * License along with this library; if not, write to the Free Software | |
360a3f91 | 18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA |
4bd374fa AS |
19 | */ |
20 | ||
21 | #include <stdarg.h> | |
22 | #include <stdio.h> | |
23 | ||
486d020c FG |
24 | #define COBJMACROS |
25 | ||
4bd374fa AS |
26 | #include "windef.h" |
27 | #include "winbase.h" | |
28 | #include "winerror.h" | |
abc3769a | 29 | #include "wingdi.h" |
4bd374fa AS |
30 | #include "winuser.h" |
31 | #include "wine/debug.h" | |
32 | #include "objbase.h" | |
33 | #include "objidl.h" | |
34 | #include "ole2.h" | |
35 | #include "atlbase.h" | |
00f72a32 | 36 | #include "atliface.h" |
124c3a8f | 37 | #include "atlwin.h" |
4bd374fa | 38 | |
da5cc563 RS |
39 | #include "wine/unicode.h" |
40 | ||
4bd374fa AS |
41 | WINE_DEFAULT_DEBUG_CHANNEL(atl); |
42 | ||
d12cb306 JC |
43 | HINSTANCE hInst; |
44 | ||
4bd374fa AS |
45 | BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) |
46 | { | |
32f42f2d | 47 | TRACE("(0x%p, %d, %p)\n",hinstDLL,fdwReason,lpvReserved); |
4bd374fa | 48 | |
d12cb306 JC |
49 | if (fdwReason == DLL_PROCESS_ATTACH) { |
50 | DisableThreadLibraryCalls(hinstDLL); | |
51 | hInst = hinstDLL; | |
52 | } | |
4bd374fa AS |
53 | return TRUE; |
54 | } | |
55 | ||
9306cc52 AS |
56 | #define ATLVer1Size 100 |
57 | ||
19c2b0bb | 58 | HRESULT WINAPI AtlModuleInit(_ATL_MODULEW* pM, _ATL_OBJMAP_ENTRYW* p, HINSTANCE h) |
4bd374fa AS |
59 | { |
60 | INT i; | |
9306cc52 | 61 | UINT size; |
4bd374fa AS |
62 | |
63 | FIXME("SEMI-STUB (%p %p %p)\n",pM,p,h); | |
64 | ||
9306cc52 | 65 | size = pM->cbSize; |
19c2b0bb | 66 | if (size != sizeof(_ATL_MODULEW) && size != ATLVer1Size) |
9306cc52 AS |
67 | { |
68 | FIXME("Unknown structure version (size %i)\n",size); | |
69 | return E_INVALIDARG; | |
70 | } | |
8141b99d | 71 | |
9306cc52 AS |
72 | memset(pM,0,pM->cbSize); |
73 | pM->cbSize = size; | |
4bd374fa AS |
74 | pM->m_hInst = h; |
75 | pM->m_hInstResource = h; | |
76 | pM->m_hInstTypeLib = h; | |
77 | pM->m_pObjMap = p; | |
78 | pM->m_hHeap = GetProcessHeap(); | |
79 | ||
9da8128e UC |
80 | InitializeCriticalSection(&pM->u.m_csTypeInfoHolder); |
81 | InitializeCriticalSection(&pM->m_csWindowCreate); | |
82 | InitializeCriticalSection(&pM->m_csObjMap); | |
83 | ||
4bd374fa AS |
84 | /* call mains */ |
85 | i = 0; | |
9306cc52 | 86 | if (pM->m_pObjMap != NULL && size > ATLVer1Size) |
4bd374fa | 87 | { |
62e1a0f2 AS |
88 | while (pM->m_pObjMap[i].pclsid != NULL) |
89 | { | |
90 | TRACE("Initializing object %i %p\n",i,p[i].pfnObjectMain); | |
91 | if (p[i].pfnObjectMain) | |
92 | p[i].pfnObjectMain(TRUE); | |
93 | i++; | |
94 | } | |
4bd374fa AS |
95 | } |
96 | ||
97 | return S_OK; | |
98 | } | |
99 | ||
8141b99d | 100 | HRESULT WINAPI AtlModuleLoadTypeLib(_ATL_MODULEW *pM, LPCOLESTR lpszIndex, |
b865c07d JH |
101 | BSTR *pbstrPath, ITypeLib **ppTypeLib) |
102 | { | |
8141b99d AT |
103 | HRESULT hRes; |
104 | OLECHAR path[MAX_PATH+8]; /* leave some space for index */ | |
105 | ||
106 | TRACE("(%p, %s, %p, %p)\n", pM, debugstr_w(lpszIndex), pbstrPath, ppTypeLib); | |
107 | ||
108 | if (!pM) | |
109 | return E_INVALIDARG; | |
110 | ||
111 | GetModuleFileNameW(pM->m_hInstTypeLib, path, MAX_PATH); | |
112 | if (lpszIndex) | |
113 | lstrcatW(path, lpszIndex); | |
114 | ||
115 | hRes = LoadTypeLib(path, ppTypeLib); | |
116 | if (FAILED(hRes)) | |
117 | return hRes; | |
118 | ||
119 | *pbstrPath = SysAllocString(path); | |
120 | ||
121 | return S_OK; | |
b865c07d JH |
122 | } |
123 | ||
19c2b0bb | 124 | HRESULT WINAPI AtlModuleTerm(_ATL_MODULEW* pM) |
9719aace | 125 | { |
a54da42e JC |
126 | _ATL_TERMFUNC_ELEM *iter = pM->m_pTermFuncs, *tmp; |
127 | ||
128 | TRACE("(%p)\n", pM); | |
129 | ||
130 | while(iter) { | |
131 | iter->pFunc(iter->dw); | |
132 | tmp = iter; | |
133 | iter = iter->pNext; | |
134 | HeapFree(GetProcessHeap(), 0, tmp); | |
135 | } | |
136 | ||
9719aace | 137 | HeapFree(GetProcessHeap(), 0, pM); |
a54da42e JC |
138 | |
139 | return S_OK; | |
140 | } | |
141 | ||
0be88a04 | 142 | HRESULT WINAPI AtlModuleAddTermFunc(_ATL_MODULEW *pM, _ATL_TERMFUNC *pFunc, DWORD_PTR dw) |
a54da42e JC |
143 | { |
144 | _ATL_TERMFUNC_ELEM *termfunc_elem; | |
145 | ||
146 | TRACE("(%p %p %ld)\n", pM, pFunc, dw); | |
147 | ||
148 | termfunc_elem = HeapAlloc(GetProcessHeap(), 0, sizeof(_ATL_TERMFUNC_ELEM)); | |
149 | termfunc_elem->pFunc = pFunc; | |
150 | termfunc_elem->dw = dw; | |
151 | termfunc_elem->pNext = pM->m_pTermFuncs; | |
152 | ||
153 | pM->m_pTermFuncs = termfunc_elem; | |
154 | ||
9719aace SE |
155 | return S_OK; |
156 | } | |
157 | ||
19c2b0bb | 158 | HRESULT WINAPI AtlModuleRegisterClassObjects(_ATL_MODULEW *pM, DWORD dwClsContext, |
4bd374fa AS |
159 | DWORD dwFlags) |
160 | { | |
161 | HRESULT hRes = S_OK; | |
162 | int i=0; | |
163 | ||
32f42f2d | 164 | TRACE("(%p %i %i)\n",pM, dwClsContext, dwFlags); |
4bd374fa AS |
165 | |
166 | if (pM == NULL) | |
167 | return E_INVALIDARG; | |
168 | ||
169 | while(pM->m_pObjMap[i].pclsid != NULL) | |
170 | { | |
171 | IUnknown* pUnknown; | |
19c2b0bb | 172 | _ATL_OBJMAP_ENTRYW *obj = &(pM->m_pObjMap[i]); |
4bd374fa AS |
173 | HRESULT rc; |
174 | ||
175 | TRACE("Registering object %i\n",i); | |
176 | if (obj->pfnGetClassObject) | |
177 | { | |
178 | rc = obj->pfnGetClassObject(obj->pfnCreateInstance, &IID_IUnknown, | |
179 | (LPVOID*)&pUnknown); | |
180 | if (SUCCEEDED (rc) ) | |
181 | { | |
182 | CoRegisterClassObject(obj->pclsid, pUnknown, dwClsContext, | |
183 | dwFlags, &obj->dwRegister); | |
184 | if (pUnknown) | |
185 | IUnknown_Release(pUnknown); | |
186 | } | |
187 | } | |
188 | i++; | |
189 | } | |
190 | ||
191 | return hRes; | |
192 | } | |
193 | ||
19c2b0bb | 194 | HRESULT WINAPI AtlModuleUnregisterServerEx(_ATL_MODULEW* pM, BOOL bUnRegTypeLib, const CLSID* pCLSID) |
407c84e5 JH |
195 | { |
196 | FIXME("(%p, %i, %p) stub\n", pM, bUnRegTypeLib, pCLSID); | |
197 | return S_OK; | |
198 | } | |
199 | ||
63ad7110 | 200 | |
9da8128e UC |
201 | IUnknown* WINAPI AtlComPtrAssign(IUnknown** pp, IUnknown *p) |
202 | { | |
203 | TRACE("(%p %p)\n", pp, p); | |
204 | ||
205 | if (p) IUnknown_AddRef(p); | |
206 | if (*pp) IUnknown_Release(*pp); | |
207 | *pp = p; | |
208 | return p; | |
209 | } | |
210 | ||
fec8156c RS |
211 | IUnknown* WINAPI AtlComQIPtrAssign(IUnknown** pp, IUnknown *p, REFIID riid) |
212 | { | |
213 | IUnknown *new_p = NULL; | |
214 | ||
215 | TRACE("(%p %p %s)\n", pp, p, debugstr_guid(riid)); | |
216 | ||
217 | if (p) IUnknown_QueryInterface(p, riid, (void **)&new_p); | |
218 | if (*pp) IUnknown_Release(*pp); | |
219 | *pp = new_p; | |
220 | return new_p; | |
221 | } | |
222 | ||
9da8128e | 223 | |
1fbd417c | 224 | HRESULT WINAPI AtlInternalQueryInterface(void* this, const _ATL_INTMAP_ENTRY* pEntries, REFIID iid, void** ppvObject) |
4bd374fa AS |
225 | { |
226 | int i = 0; | |
227 | HRESULT rc = E_NOINTERFACE; | |
3af74c5e | 228 | TRACE("(%p, %p, %s, %p)\n",this, pEntries, debugstr_guid(iid), ppvObject); |
4bd374fa AS |
229 | |
230 | if (IsEqualGUID(iid,&IID_IUnknown)) | |
231 | { | |
232 | TRACE("Returning IUnknown\n"); | |
3af74c5e RS |
233 | *ppvObject = ((LPSTR)this+pEntries[0].dw); |
234 | IUnknown_AddRef((IUnknown*)*ppvObject); | |
4bd374fa AS |
235 | return S_OK; |
236 | } | |
237 | ||
238 | while (pEntries[i].pFunc != 0) | |
239 | { | |
3af74c5e | 240 | TRACE("Trying entry %i (%s %i %p)\n",i,debugstr_guid(pEntries[i].piid), |
4bd374fa AS |
241 | pEntries[i].dw, pEntries[i].pFunc); |
242 | ||
3cc00b50 | 243 | if (pEntries[i].piid && IsEqualGUID(iid,pEntries[i].piid)) |
4bd374fa AS |
244 | { |
245 | TRACE("MATCH\n"); | |
246 | if (pEntries[i].pFunc == (_ATL_CREATORARGFUNC*)1) | |
247 | { | |
248 | TRACE("Offset\n"); | |
249 | *ppvObject = ((LPSTR)this+pEntries[i].dw); | |
99c03352 | 250 | IUnknown_AddRef((IUnknown*)*ppvObject); |
4bd374fa AS |
251 | rc = S_OK; |
252 | } | |
253 | else | |
254 | { | |
255 | TRACE("Function\n"); | |
256 | rc = pEntries[i].pFunc(this, iid, ppvObject,0); | |
257 | } | |
258 | break; | |
259 | } | |
260 | i++; | |
261 | } | |
32f42f2d | 262 | TRACE("Done returning (0x%x)\n",rc); |
4bd374fa AS |
263 | return rc; |
264 | } | |
26e61684 | 265 | |
4effec14 MM |
266 | /*********************************************************************** |
267 | * AtlModuleRegisterServer [ATL.@] | |
268 | * | |
269 | */ | |
8141b99d | 270 | HRESULT WINAPI AtlModuleRegisterServer(_ATL_MODULEW* pM, BOOL bRegTypeLib, const CLSID* clsid) |
4effec14 | 271 | { |
131d9964 AT |
272 | int i; |
273 | HRESULT hRes; | |
274 | ||
275 | TRACE("%p %d %s\n", pM, bRegTypeLib, debugstr_guid(clsid)); | |
276 | ||
277 | if (pM == NULL) | |
278 | return E_INVALIDARG; | |
279 | ||
280 | for (i = 0; pM->m_pObjMap[i].pclsid != NULL; i++) /* register CLSIDs */ | |
281 | { | |
282 | if (!clsid || IsEqualCLSID(pM->m_pObjMap[i].pclsid, clsid)) | |
283 | { | |
284 | const _ATL_OBJMAP_ENTRYW *obj = &pM->m_pObjMap[i]; | |
285 | ||
286 | TRACE("Registering clsid %s\n", debugstr_guid(obj->pclsid)); | |
287 | hRes = obj->pfnUpdateRegistry(TRUE); /* register */ | |
288 | if (FAILED(hRes)) | |
289 | return hRes; | |
290 | } | |
291 | } | |
292 | ||
293 | if (bRegTypeLib) | |
294 | { | |
295 | hRes = AtlModuleRegisterTypeLib(pM, NULL); | |
296 | if (FAILED(hRes)) | |
297 | return hRes; | |
298 | } | |
299 | ||
4effec14 MM |
300 | return S_OK; |
301 | } | |
a5fb277f MM |
302 | |
303 | /*********************************************************************** | |
304 | * AtlAdvise [ATL.@] | |
305 | */ | |
306 | HRESULT WINAPI AtlAdvise(IUnknown *pUnkCP, IUnknown *pUnk, const IID *iid, LPDWORD pdw) | |
307 | { | |
308 | FIXME("%p %p %p %p\n", pUnkCP, pUnk, iid, pdw); | |
309 | return E_FAIL; | |
310 | } | |
311 | ||
312 | /*********************************************************************** | |
313 | * AtlUnadvise [ATL.@] | |
314 | */ | |
315 | HRESULT WINAPI AtlUnadvise(IUnknown *pUnkCP, const IID *iid, DWORD dw) | |
316 | { | |
32f42f2d | 317 | FIXME("%p %p %d\n", pUnkCP, iid, dw); |
a5fb277f MM |
318 | return S_OK; |
319 | } | |
320 | ||
321 | /*********************************************************************** | |
322 | * AtlFreeMarshalStream [ATL.@] | |
323 | */ | |
324 | HRESULT WINAPI AtlFreeMarshalStream(IStream *stm) | |
325 | { | |
326 | FIXME("%p\n", stm); | |
327 | return S_OK; | |
328 | } | |
329 | ||
330 | /*********************************************************************** | |
331 | * AtlMarshalPtrInProc [ATL.@] | |
332 | */ | |
333 | HRESULT WINAPI AtlMarshalPtrInProc(IUnknown *pUnk, const IID *iid, IStream **pstm) | |
334 | { | |
335 | FIXME("%p %p %p\n", pUnk, iid, pstm); | |
336 | return E_FAIL; | |
337 | } | |
338 | ||
339 | /*********************************************************************** | |
340 | * AtlUnmarshalPtr [ATL.@] | |
341 | */ | |
342 | HRESULT WINAPI AtlUnmarshalPtr(IStream *stm, const IID *iid, IUnknown **ppUnk) | |
343 | { | |
344 | FIXME("%p %p %p\n", stm, iid, ppUnk); | |
345 | return E_FAIL; | |
346 | } | |
347 | ||
348 | /*********************************************************************** | |
349 | * AtlModuleGetClassObject [ATL.@] | |
350 | */ | |
351 | HRESULT WINAPI AtlModuleGetClassObject(_ATL_MODULEW *pm, REFCLSID rclsid, | |
352 | REFIID riid, LPVOID *ppv) | |
353 | { | |
be35acf0 | 354 | int i; |
72ddcb5f | 355 | HRESULT hres = CLASS_E_CLASSNOTAVAILABLE; |
be35acf0 RS |
356 | |
357 | TRACE("%p %s %s %p\n", pm, debugstr_guid(rclsid), debugstr_guid(riid), ppv); | |
358 | ||
359 | if (pm == NULL) | |
360 | return E_INVALIDARG; | |
361 | ||
362 | for (i = 0; pm->m_pObjMap[i].pclsid != NULL; i++) | |
363 | { | |
364 | if (IsEqualCLSID(pm->m_pObjMap[i].pclsid, rclsid)) | |
365 | { | |
366 | _ATL_OBJMAP_ENTRYW *obj = &pm->m_pObjMap[i]; | |
367 | ||
368 | TRACE("found object %i\n", i); | |
369 | if (obj->pfnGetClassObject) | |
72ddcb5f RS |
370 | { |
371 | if (!obj->pCF) | |
372 | hres = obj->pfnGetClassObject(obj->pfnCreateInstance, | |
373 | &IID_IUnknown, | |
374 | (void **)&obj->pCF); | |
375 | if (obj->pCF) | |
376 | hres = IUnknown_QueryInterface(obj->pCF, riid, ppv); | |
377 | break; | |
378 | } | |
be35acf0 RS |
379 | } |
380 | } | |
381 | ||
382 | WARN("no class object found for %s\n", debugstr_guid(rclsid)); | |
383 | ||
72ddcb5f | 384 | return hres; |
a5fb277f MM |
385 | } |
386 | ||
387 | /*********************************************************************** | |
388 | * AtlModuleGetClassObject [ATL.@] | |
389 | */ | |
390 | HRESULT WINAPI AtlModuleRegisterTypeLib(_ATL_MODULEW *pm, LPCOLESTR lpszIndex) | |
391 | { | |
da7bdf74 AT |
392 | HRESULT hRes; |
393 | BSTR path; | |
394 | ITypeLib *typelib; | |
395 | ||
396 | TRACE("%p %s\n", pm, debugstr_w(lpszIndex)); | |
397 | ||
398 | if (!pm) | |
399 | return E_INVALIDARG; | |
400 | ||
401 | hRes = AtlModuleLoadTypeLib(pm, lpszIndex, &path, &typelib); | |
402 | ||
403 | if (SUCCEEDED(hRes)) | |
404 | { | |
405 | hRes = RegisterTypeLib(typelib, path, NULL); /* FIXME: pass help directory */ | |
406 | ITypeLib_Release(typelib); | |
407 | SysFreeString(path); | |
408 | } | |
409 | ||
410 | return hRes; | |
a5fb277f MM |
411 | } |
412 | ||
413 | /*********************************************************************** | |
414 | * AtlModuleRevokeClassObjects [ATL.@] | |
415 | */ | |
416 | HRESULT WINAPI AtlModuleRevokeClassObjects(_ATL_MODULEW *pm) | |
417 | { | |
418 | FIXME("%p\n", pm); | |
419 | return E_FAIL; | |
420 | } | |
421 | ||
422 | /*********************************************************************** | |
423 | * AtlModuleUnregisterServer [ATL.@] | |
424 | */ | |
425 | HRESULT WINAPI AtlModuleUnregisterServer(_ATL_MODULEW *pm, const CLSID *clsid) | |
426 | { | |
427 | FIXME("%p %s\n", pm, debugstr_guid(clsid)); | |
428 | return E_FAIL; | |
429 | } | |
69b54d4e | 430 | |
124c3a8f RS |
431 | /*********************************************************************** |
432 | * AtlModuleRegisterWndClassInfoW [ATL.@] | |
da5cc563 RS |
433 | * |
434 | * PARAMS | |
435 | * pm [IO] Information about the module registering the window. | |
436 | * wci [IO] Information about the window being registered. | |
437 | * pProc [O] Window procedure of the registered class. | |
438 | * | |
439 | * RETURNS | |
440 | * Atom representing the registered class. | |
441 | * | |
442 | * NOTES | |
443 | * Can be called multiple times without error, unlike RegisterClassEx(). | |
444 | * | |
536e7385 FG |
445 | * If the class name is NULL, then a class with a name of "ATLxxxxxxxx" is |
446 | * registered, where the 'x's represent a unique value. | |
8141b99d | 447 | * |
124c3a8f RS |
448 | */ |
449 | ATOM WINAPI AtlModuleRegisterWndClassInfoW(_ATL_MODULEW *pm, _ATL_WNDCLASSINFOW *wci, WNDPROC *pProc) | |
450 | { | |
da5cc563 RS |
451 | ATOM atom; |
452 | ||
453 | FIXME("%p %p %p semi-stub\n", pm, wci, pProc); | |
454 | ||
455 | atom = wci->m_atom; | |
456 | if (!atom) | |
457 | { | |
458 | WNDCLASSEXW wc; | |
459 | ||
460 | TRACE("wci->m_wc.lpszClassName = %s\n", debugstr_w(wci->m_wc.lpszClassName)); | |
461 | ||
462 | if (!wci->m_wc.lpszClassName) | |
463 | { | |
464 | static const WCHAR szFormat[] = {'A','T','L','%','0','8','x',0}; | |
465 | sprintfW(wci->m_szAutoName, szFormat, (UINT)(UINT_PTR)wci); | |
466 | TRACE("auto-generated class name %s\n", debugstr_w(wci->m_szAutoName)); | |
467 | wci->m_wc.lpszClassName = wci->m_szAutoName; | |
468 | } | |
469 | ||
470 | atom = GetClassInfoExW(pm->m_hInst, wci->m_wc.lpszClassName, &wc); | |
471 | if (!atom) | |
472 | atom = RegisterClassExW(&wci->m_wc); | |
473 | ||
474 | wci->pWndProc = wci->m_wc.lpfnWndProc; | |
475 | wci->m_atom = atom; | |
476 | } | |
477 | *pProc = wci->pWndProc; | |
478 | ||
479 | TRACE("returning 0x%04x\n", atom); | |
480 | return atom; | |
124c3a8f | 481 | } |
abc3769a AT |
482 | |
483 | void WINAPI AtlHiMetricToPixel(const SIZEL* lpHiMetric, SIZEL* lpPix) | |
484 | { | |
485 | HDC dc = GetDC(NULL); | |
486 | lpPix->cx = lpHiMetric->cx * GetDeviceCaps( dc, LOGPIXELSX ) / 100; | |
487 | lpPix->cy = lpHiMetric->cy * GetDeviceCaps( dc, LOGPIXELSY ) / 100; | |
488 | ReleaseDC( NULL, dc ); | |
489 | } | |
490 | ||
491 | void WINAPI AtlPixelToHiMetric(const SIZEL* lpPix, SIZEL* lpHiMetric) | |
492 | { | |
493 | HDC dc = GetDC(NULL); | |
494 | lpHiMetric->cx = 100 * lpPix->cx / GetDeviceCaps( dc, LOGPIXELSX ); | |
495 | lpHiMetric->cy = 100 * lpPix->cy / GetDeviceCaps( dc, LOGPIXELSY ); | |
496 | ReleaseDC( NULL, dc ); | |
497 | } | |
b7ec4de7 AT |
498 | |
499 | /*********************************************************************** | |
500 | * AtlModuleAddCreateWndData [ATL.@] | |
501 | */ | |
1fbd417c | 502 | void WINAPI AtlModuleAddCreateWndData(_ATL_MODULEW *pM, _AtlCreateWndData *pData, void* pvObject) |
b7ec4de7 AT |
503 | { |
504 | TRACE("(%p, %p, %p)\n", pM, pData, pvObject); | |
505 | ||
506 | pData->m_pThis = pvObject; | |
507 | pData->m_dwThreadID = GetCurrentThreadId(); | |
508 | pData->m_pNext = pM->m_pCreateWndList; | |
509 | pM->m_pCreateWndList = pData; | |
510 | } | |
511 | ||
512 | /*********************************************************************** | |
513 | * AtlModuleExtractCreateWndData [ATL.@] | |
514 | * | |
515 | * NOTE: I failed to find any good description of this function. | |
516 | * Tests show that this function extracts one of _AtlCreateWndData | |
8141b99d AT |
517 | * records from the current thread from a list |
518 | * | |
b7ec4de7 | 519 | */ |
1fbd417c | 520 | void* WINAPI AtlModuleExtractCreateWndData(_ATL_MODULEW *pM) |
b7ec4de7 AT |
521 | { |
522 | _AtlCreateWndData **ppData; | |
523 | ||
524 | TRACE("(%p)\n", pM); | |
525 | ||
526 | for(ppData = &pM->m_pCreateWndList; *ppData!=NULL; ppData = &(*ppData)->m_pNext) | |
527 | { | |
528 | if ((*ppData)->m_dwThreadID == GetCurrentThreadId()) | |
529 | { | |
530 | _AtlCreateWndData *pData = *ppData; | |
531 | *ppData = pData->m_pNext; | |
532 | return pData->m_pThis; | |
533 | } | |
534 | } | |
535 | return NULL; | |
536 | } | |
be164751 RS |
537 | |
538 | /* FIXME: should be in a header file */ | |
539 | typedef struct ATL_PROPMAP_ENTRY | |
540 | { | |
541 | LPCOLESTR szDesc; | |
542 | DISPID dispid; | |
543 | const CLSID* pclsidPropPage; | |
544 | const IID* piidDispatch; | |
545 | DWORD dwOffsetData; | |
546 | DWORD dwSizeData; | |
547 | VARTYPE vt; | |
548 | } ATL_PROPMAP_ENTRY; | |
549 | ||
9012d4e7 FG |
550 | /*********************************************************************** |
551 | * AtlIPersistStreamInit_Load [ATL.@] | |
552 | */ | |
be164751 RS |
553 | HRESULT WINAPI AtlIPersistStreamInit_Load( LPSTREAM pStm, ATL_PROPMAP_ENTRY *pMap, |
554 | void *pThis, IUnknown *pUnk) | |
555 | { | |
556 | FIXME("(%p, %p, %p, %p)\n", pStm, pMap, pThis, pUnk); | |
557 | ||
558 | return S_OK; | |
559 | } | |
560 | ||
561 | HRESULT WINAPI AtlIPersistStreamInit_Save(LPSTREAM pStm, BOOL fClearDirty, | |
562 | ATL_PROPMAP_ENTRY *pMap, void *pThis, | |
563 | IUnknown *pUnk) | |
564 | { | |
565 | FIXME("(%p, %d, %p, %p, %p)\n", pStm, fClearDirty, pMap, pThis, pUnk); | |
566 | ||
567 | return S_OK; | |
568 | } |