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

Last change on this file since 1330 was 1215, checked in by sandervl, 26 years ago

Added $Id$

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