source: trunk/src/shell32/shellole.cpp@ 2012

Last change on this file since 2012 was 1353, checked in by phaller, 26 years ago

Fix: debug info

File size: 16.2 KB
Line 
1/* $Id: shellole.cpp,v 1.3 1999-10-19 10:23:27 phaller Exp $ */
2
3/*
4 * Win32 SHELL32 for OS/2
5 *
6 * Copyright 1999 Patrick Haller (haller@zebra.fh-weingarten.de)
7 * Project Odin Software License can be found in LICENSE.TXT
8 *
9 * handling of SHELL32.DLL OLE-Objects
10 *
11 * Copyright 1997 Marcus Meissner
12 * Copyright 1998 Juergen Schmied <juergen.schmied@metronet.de>
13 *
14 */
15
16
17/*****************************************************************************
18 * Includes *
19 *****************************************************************************/
20
21#include <odin.h>
22#include <odinwrap.h>
23#include <os2sel.h>
24
25#include <stdlib.h>
26#include <string.h>
27
28#define ICOM_CINTERFACE 1
29#define CINTERFACE 1
30
31#include "wine/obj_base.h"
32#include "wine/obj_shelllink.h"
33#include "wine/obj_shellfolder.h"
34#include "wine/obj_shellbrowser.h"
35#include "wine/obj_contextmenu.h"
36#include "wine/obj_shellextinit.h"
37#include "wine/obj_extracticon.h"
38
39#include "shlguid.h"
40#include "winversion.h"
41#include "winreg.h"
42#include "winerror.h"
43#include "debugtools.h"
44
45#include "shell32_main.h"
46
47#include <misc.h>
48
49
50/*****************************************************************************
51 * Implementation *
52 *****************************************************************************/
53
54ODINDEBUGCHANNEL(SHELL32-SHELLOLE)
55
56
57DWORD WINAPI SHCLSIDFromStringA (LPSTR clsid, CLSID *id);
58
59/*************************************************************************
60 * SHCoCreateInstance [SHELL32.102]
61 *
62 * NOTES
63 * exported by ordinal
64 */
65
66ODINFUNCTION5(LRESULT, SHCoCreateInstance, LPSTR, aclsid,
67 REFCLSID, clsid,
68 IUnknown*, unknownouter,
69 REFIID, refiid,
70 LPVOID*, ppv)
71{
72 char xclsid[48], xiid[48], xuout[48];
73 DWORD hres;
74 IID iid;
75 CLSID * myclsid = (CLSID*)clsid;
76
77 WINE_StringFromCLSID(refiid,xiid);
78
79 if (!clsid)
80 {
81 if (!aclsid) return REGDB_E_CLASSNOTREG;
82 SHCLSIDFromStringA(aclsid, &iid);
83 myclsid = &iid;
84 }
85
86 WINE_StringFromCLSID(myclsid,xclsid);
87 WINE_StringFromCLSID(refiid,xiid);
88 if (unknownouter)
89 WINE_StringFromCLSID((const CLSID*)unknownouter,xuout);
90
91 dprintf(("SHELL32:SHCoCreateInstance (%p,CLSID:%s UOUT:%s IID:%s,%p)\n",
92 aclsid,
93 xclsid,
94 unknownouter?xuout:"nil",xiid,ppv));
95
96 hres = CoCreateInstance(myclsid, NULL, CLSCTX_INPROC_SERVER, refiid, ppv);
97
98 if(hres!=S_OK)
99 {
100 dprintf(("SHELL32:SHCoCreateInstance failed (0x%08lx) to create CLSID:%s IID:%s\n",
101 hres,
102 xclsid,
103 xiid));
104 dprintf(("SHELL32:SHCoCreateInstance you might need to import the winedefault.reg\n"));
105 }
106
107 return hres;
108}
109
110/*************************************************************************
111 * SHELL32_DllGetClassObject [SHELL32.128]
112 */
113
114ODINFUNCTION3(HRESULT, SHELL32_DllGetClassObject, REFCLSID, rclsid,
115 REFIID, iid,
116 LPVOID*, ppv)
117{
118 HRESULT hres = E_OUTOFMEMORY;
119 LPCLASSFACTORY lpclf;
120
121 char xclsid[50],xiid[50];
122 WINE_StringFromCLSID((LPCLSID)rclsid,xclsid);
123 WINE_StringFromCLSID((LPCLSID)iid,xiid);
124 dprintf(("SHELL32:SHELL32_DllGetClassObject CLSID:%s, IID:%s\n",
125 xclsid,
126 xiid));
127
128 *ppv = NULL;
129
130 if(IsEqualCLSID(rclsid, &CLSID_PaperBin))
131 {
132 dprintf(("SHELL32:SHELL32_DllGetClassObject paper bin not implemented\n"));
133 return CLASS_E_CLASSNOTAVAILABLE;
134 }
135 if(IsEqualCLSID(rclsid, &CLSID_ShellDesktop)||
136 IsEqualCLSID(rclsid, &CLSID_ShellLink))
137 {
138 lpclf = IClassFactory_Constructor( rclsid );
139
140 if(lpclf)
141 {
142 hres = IClassFactory_QueryInterface(lpclf,iid, ppv);
143 IClassFactory_Release(lpclf);
144 }
145 }
146 else
147 {
148 dprintf(("SHELL32:SHELL32_DllGetClassObject -- CLSID not found\n"));
149 hres = CLASS_E_CLASSNOTAVAILABLE;
150 }
151 dprintf(("SHELL32:SHELL32_DllGetClassObject -- pointer to class factory: %p\n",
152 *ppv));
153 return hres;
154}
155
156/*************************************************************************
157 * SHCLSIDFromString [SHELL32.147]
158 *
159 * NOTES
160 * exported by ordinal
161 */
162ODINFUNCTION2(DWORD, SHCLSIDFromStringA, LPSTR, clsid,
163 CLSID*, id)
164{
165 return CLSIDFromStringA(clsid, id);
166}
167
168
169ODINFUNCTION2(DWORD, SHCLSIDFromStringW, LPWSTR, clsid,
170 CLSID*, id)
171{
172 return CLSIDFromString(clsid, id);
173}
174
175
176ODINFUNCTION2(DWORD, SHCLSIDFromStringAW, LPVOID, clsid,
177 CLSID*, id)
178{
179 if (VERSION_OsIsUnicode())
180 return SHCLSIDFromStringW ((LPWSTR)clsid, id);
181 return SHCLSIDFromStringA ((LPSTR)clsid, id);
182}
183
184
185/*************************************************************************
186 * SHGetMalloc [SHELL32.220]
187 * returns the interface to shell malloc.
188 *
189 * [SDK header win95/shlobj.h:
190 * equivalent to: #define SHGetMalloc(ppmem) CoGetMalloc(MEMCTX_TASK, ppmem)
191 * ]
192 * What we are currently doing is not very wrong, since we always use the same
193 * heap (ProcessHeap).
194 */
195
196ODINFUNCTION1(DWORD, SHGetMalloc, LPMALLOC*, lpmal)
197{
198 return CoGetMalloc(0,lpmal);
199}
200
201
202/*************************************************************************
203 * SHGetDesktopFolder [SHELL32.216]
204 */
205LPSHELLFOLDER pdesktopfolder=NULL;
206
207ODINFUNCTION1(DWORD, SHGetDesktopFolder, IShellFolder**, psf)
208{
209 HRESULT hres = S_OK;
210 LPCLASSFACTORY lpclf;
211 dprintf(("SHELL32: SHGetDesktopFolder %p->(%p)\n",psf,*psf));
212
213 *psf=NULL;
214
215 if (!pdesktopfolder)
216 {
217 lpclf = IClassFactory_Constructor(&CLSID_ShellDesktop);
218 if(lpclf)
219 {
220 hres = IClassFactory_CreateInstance(lpclf,NULL,(REFIID)&IID_IShellFolder, (LPVOID*)&pdesktopfolder);
221 IClassFactory_Release(lpclf);
222 }
223 }
224
225 if (pdesktopfolder)
226 {
227 /* even if we create the folder, add a ref so the application canŽt destroy the folder*/
228 IShellFolder_AddRef(pdesktopfolder);
229 *psf = pdesktopfolder;
230 }
231
232 dprintf(("SHELL32: SHGetDesktopFolder-- %p->(%p)\n",psf, *psf));
233 return hres;
234}
235
236/**************************************************************************
237* IClassFactory Implementation
238*/
239
240typedef struct
241{
242 /* IUnknown fields */
243 ICOM_VTABLE(IClassFactory)* lpvtbl;
244 DWORD ref;
245 CLSID *rclsid;
246} IClassFactoryImpl;
247
248//static ICOM_VTABLE(IClassFactory) clfvt;
249
250/**************************************************************************
251 * IClassFactory_QueryInterface
252 */
253static HRESULT WINAPI IClassFactory_fnQueryInterface(
254 LPCLASSFACTORY iface, REFIID riid, LPVOID *ppvObj)
255{
256 ICOM_THIS(IClassFactoryImpl,iface);
257 char xriid[50];
258 WINE_StringFromCLSID((LPCLSID)riid,xriid);
259
260 dprintf(("SHELL32: IClassFactory_fnQueryInterface (%p)->(\n\tIID:\t%s)\n",This,xriid));
261
262 *ppvObj = NULL;
263
264 if(IsEqualIID(riid, &IID_IUnknown)) /*IUnknown*/
265 { *ppvObj = This;
266 }
267 else if(IsEqualIID(riid, &IID_IClassFactory)) /*IClassFactory*/
268 { *ppvObj = (IClassFactory*)This;
269 }
270
271 if(*ppvObj)
272 { IUnknown_AddRef((LPUNKNOWN)*ppvObj);
273 dprintf(("SHELL32: IClassFactory_fnQueryInterface -- Interface: (%p)->(%p)\n",ppvObj,*ppvObj));
274 return S_OK;
275 }
276 dprintf(("SHELL32: IClassFactory_fnQueryInterface -- Interface: %s E_NOINTERFACE\n", xriid));
277 return E_NOINTERFACE;
278}
279/******************************************************************************
280 * IClassFactory_AddRef
281 */
282static ULONG WINAPI IClassFactory_fnAddRef(LPCLASSFACTORY iface)
283{
284 ICOM_THIS(IClassFactoryImpl,iface);
285 dprintf(("SHELL32: IClassFactory_fnAddRef (%p)->(count=%lu)\n",This,This->ref));
286
287 shell32_ObjCount++;
288 return ++(This->ref);
289}
290/******************************************************************************
291 * IClassFactory_Release
292 */
293static ULONG WINAPI IClassFactory_fnRelease(LPCLASSFACTORY iface)
294{
295 ICOM_THIS(IClassFactoryImpl,iface);
296 dprintf(("SHELL32: IClassFactory_fnRelease (%p)->(count=%lu)\n",This,This->ref));
297
298 shell32_ObjCount--;
299 if (!--(This->ref))
300 { dprintf(("SHELL32: IClassFactory_fnRelease -- destroying IClassFactory(%p)\n",This));
301 HeapFree(GetProcessHeap(),0,This);
302 return 0;
303 }
304 return This->ref;
305}
306/******************************************************************************
307 * IClassFactory_CreateInstance
308 */
309static HRESULT WINAPI IClassFactory_fnCreateInstance(
310 LPCLASSFACTORY iface, LPUNKNOWN pUnknown, REFIID riid, LPVOID *ppObject)
311{
312 ICOM_THIS(IClassFactoryImpl,iface);
313 IUnknown *pObj = NULL;
314 HRESULT hres;
315 char xriid[50];
316
317 WINE_StringFromCLSID((LPCLSID)riid,xriid);
318 dprintf(("SHELL32: IClassFactory_fnCreateInstance %p->(%p,\n\tIID:\t%s,%p)\n",This,pUnknown,xriid,ppObject));
319
320 *ppObject = NULL;
321
322 if(pUnknown)
323 {
324 return(CLASS_E_NOAGGREGATION);
325 }
326
327 if (IsEqualCLSID(This->rclsid, &CLSID_ShellDesktop))
328 {
329 pObj = (IUnknown *)ISF_Desktop_Constructor();
330 }
331 else if (IsEqualCLSID(This->rclsid, &CLSID_ShellLink))
332 {
333 pObj = (IUnknown *)IShellLink_Constructor(FALSE);
334 }
335 else
336 {
337 dprintf(("SHELL32: IClassFactory_fnCreateInstance unknown IID requested\n\tIID:\t%s\n",xriid));
338 return(E_NOINTERFACE);
339 }
340
341 if (!pObj)
342 {
343 return(E_OUTOFMEMORY);
344 }
345
346 hres = IUnknown_QueryInterface(pObj,riid, ppObject);
347 IUnknown_Release(pObj);
348
349 dprintf(("SHELL32: IClassFactory_fnCreateInstance -- Object created: (%p)->%p\n",This,*ppObject));
350
351 return hres;
352}
353/******************************************************************************
354 * IClassFactory_LockServer
355 */
356static HRESULT WINAPI IClassFactory_fnLockServer(LPCLASSFACTORY iface, BOOL fLock)
357{
358 ICOM_THIS(IClassFactoryImpl,iface);
359 dprintf(("SHELL32: IClassFactory_fnLockServer %p->(0x%x), not implemented\n",This, fLock));
360 return E_NOTIMPL;
361}
362
363static ICOM_VTABLE(IClassFactory) clfvt =
364{
365 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
366 IClassFactory_fnQueryInterface,
367 IClassFactory_fnAddRef,
368 IClassFactory_fnRelease,
369 IClassFactory_fnCreateInstance,
370 IClassFactory_fnLockServer
371};
372
373/**************************************************************************
374 * IClassFactory_Constructor
375 */
376
377LPCLASSFACTORY IClassFactory_Constructor(REFCLSID rclsid)
378{
379 IClassFactoryImpl* lpclf;
380
381 lpclf= (IClassFactoryImpl*)HeapAlloc(GetProcessHeap(),0,sizeof(IClassFactoryImpl));
382 lpclf->ref = 1;
383 lpclf->lpvtbl = &clfvt;
384 lpclf->rclsid = (CLSID*)rclsid;
385
386 dprintf(("SHELL32: IClassFactory_Constructor (%p)->()\n",lpclf));
387 shell32_ObjCount++;
388 return (LPCLASSFACTORY)lpclf;
389}
390
391
392/**************************************************************************
393 * Default ClassFactory Implementation
394 *
395 * SHCreateDefClassObject
396 *
397 * NOTES
398 * helper function for dll's without a own classfactory
399 * a generic classfactory is returned
400 * when the CreateInstance of the cf is called the callback is executed
401 */
402typedef HRESULT (CALLBACK * LPFNCREATEINSTANCE)(IUnknown* pUnkOuter, REFIID riid, LPVOID* ppvObject);
403
404typedef struct
405{
406 ICOM_VTABLE(IClassFactory)* lpvtbl;
407 DWORD ref;
408 CLSID *rclsid;
409 LPFNCREATEINSTANCE lpfnCI;
410 const IID * riidInst;
411 UINT * pcRefDll; /* pointer to refcounter in external dll (ugrrr...) */
412} IDefClFImpl;
413
414//static ICOM_VTABLE(IClassFactory) dclfvt;
415
416/**************************************************************************
417 * IDefClF_fnQueryInterface
418 */
419static HRESULT WINAPI IDefClF_fnQueryInterface(
420 LPCLASSFACTORY iface, REFIID riid, LPVOID *ppvObj)
421{
422 ICOM_THIS(IDefClFImpl,iface);
423 char xriid[50];
424 WINE_StringFromCLSID((LPCLSID)riid,xriid);
425 dprintf(("SHELL32: IDefClF_fnQueryInterface (%p)->(\n\tIID:\t%s)\n",This,xriid));
426
427 *ppvObj = NULL;
428
429 if(IsEqualIID(riid, &IID_IUnknown)) /*IUnknown*/
430 { *ppvObj = This;
431 }
432 else if(IsEqualIID(riid, &IID_IClassFactory)) /*IClassFactory*/
433 { *ppvObj = (IClassFactory*)This;
434 }
435
436 if(*ppvObj)
437 { IUnknown_AddRef((LPUNKNOWN)*ppvObj);
438 dprintf(("SHELL32: IDefClF_fnQueryInterface -- Interface: (%p)->(%p)\n",ppvObj,*ppvObj));
439 return S_OK;
440 }
441 dprintf(("SHELL32: IDefClF_fnQueryInterface -- Interface: %s E_NOINTERFACE\n", xriid));
442 return E_NOINTERFACE;
443}
444/******************************************************************************
445 * IDefClF_fnAddRef
446 */
447static ULONG WINAPI IDefClF_fnAddRef(LPCLASSFACTORY iface)
448{
449 ICOM_THIS(IDefClFImpl,iface);
450 dprintf(("SHELL32: IDefClF_fnAddRef (%p)->(count=%lu)\n",This,This->ref));
451
452 shell32_ObjCount++;
453
454 return ++(This->ref);
455}
456/******************************************************************************
457 * IDefClF_fnRelease
458 */
459static ULONG WINAPI IDefClF_fnRelease(LPCLASSFACTORY iface)
460{
461 ICOM_THIS(IDefClFImpl,iface);
462 dprintf(("SHELL32: IDefClF_fnRelease (%p)->(count=%lu)\n",This,This->ref));
463
464 shell32_ObjCount--;
465
466 if (!--(This->ref))
467 {
468 if (This->pcRefDll)
469 (*This->pcRefDll)--;
470
471 dprintf(("SHELL32: IDefClF_fn -- destroying IClassFactory(%p)\n",This));
472 HeapFree(GetProcessHeap(),0,This);
473 return 0;
474 }
475 return This->ref;
476}
477/******************************************************************************
478 * IDefClF_fnCreateInstance
479 */
480static HRESULT WINAPI IDefClF_fnCreateInstance(
481 LPCLASSFACTORY iface, LPUNKNOWN pUnkOuter, REFIID riid, LPVOID *ppvObject)
482{
483 ICOM_THIS(IDefClFImpl,iface);
484 char xriid[50];
485
486 WINE_StringFromCLSID((LPCLSID)riid,xriid);
487 dprintf(("SHELL32: IDefClF_fnCreateInterface %p->(%p,\n\tIID:\t%s,%p)\n",This,pUnkOuter,xriid,ppvObject));
488
489 *ppvObject = NULL;
490
491 if(pUnkOuter)
492 return(CLASS_E_NOAGGREGATION);
493
494 if ( This->riidInst==NULL ||
495 IsEqualCLSID(riid, This->riidInst) ||
496 IsEqualCLSID(riid, &IID_IUnknown) )
497 {
498 return This->lpfnCI(pUnkOuter, riid, ppvObject);
499 }
500
501 dprintf(("SHELL32: IDefClF_fn unknown IID requested\n\tIID:\t%s\n",xriid));
502 return E_NOINTERFACE;
503}
504/******************************************************************************
505 * IDefClF_fnLockServer
506 */
507static HRESULT WINAPI IDefClF_fnLockServer(LPCLASSFACTORY iface, BOOL fLock)
508{
509 ICOM_THIS(IDefClFImpl,iface);
510 dprintf(("SHELL32: IDefClF_fnLockServer %p->(0x%x), not implemented\n",This, fLock));
511 return E_NOTIMPL;
512}
513
514static ICOM_VTABLE(IClassFactory) dclfvt =
515{
516 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
517 IDefClF_fnQueryInterface,
518 IDefClF_fnAddRef,
519 IDefClF_fnRelease,
520 IDefClF_fnCreateInstance,
521 IDefClF_fnLockServer
522};
523
524/**************************************************************************
525 * IDefClF_fnConstructor
526 */
527
528IClassFactory * IDefClF_fnConstructor(LPFNCREATEINSTANCE lpfnCI, UINT * pcRefDll, REFIID riidInst)
529{
530 IDefClFImpl* lpclf;
531 char xriidInst[50];
532
533 WINE_StringFromCLSID((LPCLSID)riidInst,xriidInst);
534
535 lpclf = (IDefClFImpl*)HeapAlloc(GetProcessHeap(),0,sizeof(IDefClFImpl));
536 lpclf->ref = 1;
537 lpclf->lpvtbl = &dclfvt;
538 lpclf->lpfnCI = lpfnCI;
539 lpclf->pcRefDll = pcRefDll;
540
541 if (pcRefDll)
542 (*pcRefDll)++;
543
544 lpclf->riidInst = riidInst;
545
546 dprintf(("SHELL32: IDefClF_fnConstructor (%p)\n\tIID:\t%s\n",lpclf, xriidInst));
547 shell32_ObjCount++;
548 return (LPCLASSFACTORY)lpclf;
549}
550
551
552/******************************************************************************
553 * SHCreateDefClassObject [SHELL32.70]
554 */
555
556ODINFUNCTION5(HRESULT, SHCreateDefClassObject, REFIID, riid,
557 LPVOID*, ppv,
558 LPFNCREATEINSTANCE,lpfnCI,
559 UINT*, pcRefDll,
560 REFIID, riidInst)
561{
562
563 char xriid[50],xriidInst[50];
564 WINE_StringFromCLSID((LPCLSID)riid,xriid);
565 WINE_StringFromCLSID((LPCLSID)riidInst,xriidInst);
566
567 dprintf(("SHELL32: SHCreateDefClassObject \n\tIID:\t%s %p %p %p \n\tIIDIns:\t%s\n",
568 xriid, ppv, lpfnCI, pcRefDll, xriidInst));
569
570 if ( IsEqualCLSID(riid, &IID_IClassFactory) )
571 {
572 IClassFactory * pcf = IDefClF_fnConstructor(lpfnCI, pcRefDll, riidInst);
573 if (pcf)
574 {
575 *ppv = pcf;
576 return NOERROR;
577 }
578 return E_OUTOFMEMORY;
579 }
580 return E_NOINTERFACE;
581}
582
Note: See TracBrowser for help on using the repository browser.