source: trunk/src/shell32/new/shellole.cpp@ 1036

Last change on this file since 1036 was 873, checked in by phaller, 26 years ago

.

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