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

Last change on this file since 3243 was 3243, checked in by cbratschi, 25 years ago

merged with Corel WINE 20000324

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