2 * handling of SHELL32.DLL OLE-Objects
4 * Copyright 1997 Marcus Meissner
5 * Copyright 1998 Juergen Schmied <juergen.schmied@metronet.de>
15 #include "wine/unicode.h"
17 #include "debugtools.h"
19 #include "shell32_main.h"
21 DEFAULT_DEBUG_CHANNEL(shell
);
23 DWORD WINAPI
SHCLSIDFromStringA (LPSTR clsid
, CLSID
*id
);
24 extern IShellFolder
* IShellFolder_Constructor(
27 extern HRESULT
IFSFolder_Constructor(
32 /*************************************************************************
33 * SHCoCreateInstance [SHELL32.102]
38 LRESULT WINAPI
SHCoCreateInstance(
41 IUnknown
* unknownouter
,
47 CLSID
* myclsid
= (CLSID
*)clsid
;
51 if (!aclsid
) return REGDB_E_CLASSNOTREG
;
52 SHCLSIDFromStringA(aclsid
, &iid
);
56 TRACE("(%p,\n\tCLSID:\t%s, unk:%p\n\tIID:\t%s,%p)\n",
57 aclsid
,debugstr_guid(myclsid
),unknownouter
,debugstr_guid(refiid
),ppv
);
59 if IsEqualCLSID(myclsid
, &CLSID_ShellFSFolder
)
61 hres
= IFSFolder_Constructor(unknownouter
, refiid
, ppv
);
65 hres
= CoCreateInstance(myclsid
, unknownouter
, CLSCTX_INPROC_SERVER
, refiid
, ppv
);
70 ERR("failed (0x%08lx) to create \n\tCLSID:\t%s\n\tIID:\t%s\n",
71 hres
, debugstr_guid(myclsid
), debugstr_guid(refiid
));
72 ERR("class not found in registry\n");
75 TRACE("-- instance: %p\n",*ppv
);
79 /*************************************************************************
80 * SHELL32_DllGetClassObject [SHELL32.128]
82 HRESULT WINAPI
SHELL32_DllGetClassObject(REFCLSID rclsid
, REFIID iid
,LPVOID
*ppv
)
83 { HRESULT hres
= E_OUTOFMEMORY
;
86 TRACE("\n\tCLSID:\t%s,\n\tIID:\t%s\n",debugstr_guid(rclsid
),debugstr_guid(iid
));
90 if(IsEqualCLSID(rclsid
, &CLSID_ShellDesktop
)||
91 IsEqualCLSID(rclsid
, &CLSID_ShellLink
))
93 lpclf
= IClassFactory_Constructor( rclsid
);
97 hres
= IClassFactory_QueryInterface(lpclf
,iid
, ppv
);
98 IClassFactory_Release(lpclf
);
103 WARN("-- CLSID not found\n");
104 hres
= CLASS_E_CLASSNOTAVAILABLE
;
106 TRACE("-- pointer to class factory: %p\n",*ppv
);
110 /*************************************************************************
111 * SHCLSIDFromString [SHELL32.147]
114 * exported by ordinal
116 DWORD WINAPI
SHCLSIDFromStringA (LPSTR clsid
, CLSID
*id
)
119 TRACE("(%p(%s) %p)\n", clsid
, clsid
, id
);
120 if (!MultiByteToWideChar( CP_ACP
, 0, clsid
, -1, buffer
, sizeof(buffer
)/sizeof(WCHAR
) ))
121 return CO_E_CLASSSTRING
;
122 return CLSIDFromString( buffer
, id
);
124 DWORD WINAPI
SHCLSIDFromStringW (LPWSTR clsid
, CLSID
*id
)
126 TRACE("(%p(%s) %p)\n", clsid
, debugstr_w(clsid
), id
);
127 return CLSIDFromString(clsid
, id
);
129 DWORD WINAPI
SHCLSIDFromStringAW (LPVOID clsid
, CLSID
*id
)
131 if (SHELL_OsIsUnicode())
132 return SHCLSIDFromStringW (clsid
, id
);
133 return SHCLSIDFromStringA (clsid
, id
);
136 /*************************************************************************
137 * SHGetMalloc [SHELL32.220]
138 * returns the interface to shell malloc.
140 * [SDK header win95/shlobj.h:
141 * equivalent to: #define SHGetMalloc(ppmem) CoGetMalloc(MEMCTX_TASK, ppmem)
143 * What we are currently doing is not very wrong, since we always use the same
144 * heap (ProcessHeap).
146 DWORD WINAPI
SHGetMalloc(LPMALLOC
*lpmal
)
148 TRACE("(%p)\n", lpmal
);
149 return CoGetMalloc(0,lpmal
);
152 /*************************************************************************
153 * SHGetDesktopFolder [SHELL32.216]
155 LPSHELLFOLDER pdesktopfolder
=NULL
;
157 DWORD WINAPI
SHGetDesktopFolder(IShellFolder
**psf
)
160 LPCLASSFACTORY lpclf
;
161 TRACE("%p->(%p)\n",psf
,*psf
);
167 lpclf
= IClassFactory_Constructor(&CLSID_ShellDesktop
);
170 hres
= IClassFactory_CreateInstance(lpclf
,NULL
,(REFIID
)&IID_IShellFolder
, (void*)&pdesktopfolder
);
171 IClassFactory_Release(lpclf
);
177 /* even if we create the folder, add a ref so the application canĀ“t destroy the folder*/
178 IShellFolder_AddRef(pdesktopfolder
);
179 *psf
= pdesktopfolder
;
182 TRACE("-- %p->(%p)\n",psf
, *psf
);
186 /**************************************************************************
187 * IClassFactory Implementation
192 /* IUnknown fields */
193 ICOM_VFIELD(IClassFactory
);
198 static ICOM_VTABLE(IClassFactory
) clfvt
;
200 /**************************************************************************
201 * IClassFactory_Constructor
204 LPCLASSFACTORY
IClassFactory_Constructor(REFCLSID rclsid
)
206 IClassFactoryImpl
* lpclf
;
208 lpclf
= (IClassFactoryImpl
*)HeapAlloc(GetProcessHeap(),0,sizeof(IClassFactoryImpl
));
210 ICOM_VTBL(lpclf
) = &clfvt
;
211 lpclf
->rclsid
= (CLSID
*)rclsid
;
213 TRACE("(%p)->()\n",lpclf
);
214 InterlockedIncrement(&shell32_ObjCount
);
215 return (LPCLASSFACTORY
)lpclf
;
217 /**************************************************************************
218 * IClassFactory_QueryInterface
220 static HRESULT WINAPI
IClassFactory_fnQueryInterface(
221 LPCLASSFACTORY iface
, REFIID riid
, LPVOID
*ppvObj
)
223 ICOM_THIS(IClassFactoryImpl
,iface
);
224 TRACE("(%p)->(\n\tIID:\t%s)\n",This
,debugstr_guid(riid
));
228 if(IsEqualIID(riid
, &IID_IUnknown
)) /*IUnknown*/
231 else if(IsEqualIID(riid
, &IID_IClassFactory
)) /*IClassFactory*/
232 { *ppvObj
= (IClassFactory
*)This
;
236 { IUnknown_AddRef((LPUNKNOWN
)*ppvObj
);
237 TRACE("-- Interface: (%p)->(%p)\n",ppvObj
,*ppvObj
);
240 TRACE("-- Interface: %s E_NOINTERFACE\n", debugstr_guid(riid
));
241 return E_NOINTERFACE
;
243 /******************************************************************************
244 * IClassFactory_AddRef
246 static ULONG WINAPI
IClassFactory_fnAddRef(LPCLASSFACTORY iface
)
248 ICOM_THIS(IClassFactoryImpl
,iface
);
249 TRACE("(%p)->(count=%lu)\n",This
,This
->ref
);
251 InterlockedIncrement(&shell32_ObjCount
);
252 return InterlockedIncrement(&This
->ref
);
254 /******************************************************************************
255 * IClassFactory_Release
257 static ULONG WINAPI
IClassFactory_fnRelease(LPCLASSFACTORY iface
)
259 ICOM_THIS(IClassFactoryImpl
,iface
);
260 TRACE("(%p)->(count=%lu)\n",This
,This
->ref
);
262 InterlockedDecrement(&shell32_ObjCount
);
263 if (!InterlockedDecrement(&This
->ref
))
265 TRACE("-- destroying IClassFactory(%p)\n",This
);
266 HeapFree(GetProcessHeap(),0,This
);
271 /******************************************************************************
272 * IClassFactory_CreateInstance
274 static HRESULT WINAPI
IClassFactory_fnCreateInstance(
275 LPCLASSFACTORY iface
, LPUNKNOWN pUnknown
, REFIID riid
, LPVOID
*ppObject
)
277 ICOM_THIS(IClassFactoryImpl
,iface
);
278 IUnknown
*pObj
= NULL
;
281 TRACE("%p->(%p,\n\tIID:\t%s,%p)\n",This
,pUnknown
,debugstr_guid(riid
),ppObject
);
287 return(CLASS_E_NOAGGREGATION
);
290 if (IsEqualCLSID(This
->rclsid
, &CLSID_ShellDesktop
))
292 pObj
= (IUnknown
*)ISF_Desktop_Constructor();
294 else if (IsEqualCLSID(This
->rclsid
, &CLSID_ShellLink
))
296 pObj
= (IUnknown
*)IShellLink_Constructor(FALSE
);
300 ERR("unknown IID requested\n\tIID:\t%s\n",debugstr_guid(riid
));
301 return(E_NOINTERFACE
);
306 return(E_OUTOFMEMORY
);
309 hres
= IUnknown_QueryInterface(pObj
,riid
, ppObject
);
310 IUnknown_Release(pObj
);
312 TRACE("-- Object created: (%p)->%p\n",This
,*ppObject
);
316 /******************************************************************************
317 * IClassFactory_LockServer
319 static HRESULT WINAPI
IClassFactory_fnLockServer(LPCLASSFACTORY iface
, BOOL fLock
)
321 ICOM_THIS(IClassFactoryImpl
,iface
);
322 TRACE("%p->(0x%x), not implemented\n",This
, fLock
);
326 static ICOM_VTABLE(IClassFactory
) clfvt
=
328 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
329 IClassFactory_fnQueryInterface
,
330 IClassFactory_fnAddRef
,
331 IClassFactory_fnRelease
,
332 IClassFactory_fnCreateInstance
,
333 IClassFactory_fnLockServer
336 /**************************************************************************
337 * Default ClassFactory Implementation
339 * SHCreateDefClassObject
342 * helper function for dll's without a own classfactory
343 * a generic classfactory is returned
344 * when the CreateInstance of the cf is called the callback is executed
346 typedef HRESULT (CALLBACK
* LPFNCREATEINSTANCE
)(IUnknown
* pUnkOuter
, REFIID riid
, LPVOID
* ppvObject
);
350 ICOM_VFIELD(IClassFactory
);
353 LPFNCREATEINSTANCE lpfnCI
;
354 const IID
* riidInst
;
355 ULONG
* pcRefDll
; /* pointer to refcounter in external dll (ugrrr...) */
358 static ICOM_VTABLE(IClassFactory
) dclfvt
;
360 /**************************************************************************
361 * IDefClF_fnConstructor
364 IClassFactory
* IDefClF_fnConstructor(LPFNCREATEINSTANCE lpfnCI
, PLONG pcRefDll
, REFIID riidInst
)
368 lpclf
= (IDefClFImpl
*)HeapAlloc(GetProcessHeap(),0,sizeof(IDefClFImpl
));
370 ICOM_VTBL(lpclf
) = &dclfvt
;
371 lpclf
->lpfnCI
= lpfnCI
;
372 lpclf
->pcRefDll
= pcRefDll
;
374 if (pcRefDll
) InterlockedIncrement(pcRefDll
);
375 lpclf
->riidInst
= riidInst
;
377 TRACE("(%p)\n\tIID:\t%s\n",lpclf
, debugstr_guid(riidInst
));
378 InterlockedIncrement(&shell32_ObjCount
);
379 return (LPCLASSFACTORY
)lpclf
;
381 /**************************************************************************
382 * IDefClF_fnQueryInterface
384 static HRESULT WINAPI
IDefClF_fnQueryInterface(
385 LPCLASSFACTORY iface
, REFIID riid
, LPVOID
*ppvObj
)
387 ICOM_THIS(IDefClFImpl
,iface
);
389 TRACE("(%p)->(\n\tIID:\t%s)\n",This
,debugstr_guid(riid
));
393 if(IsEqualIID(riid
, &IID_IUnknown
)) /*IUnknown*/
396 else if(IsEqualIID(riid
, &IID_IClassFactory
)) /*IClassFactory*/
397 { *ppvObj
= (IClassFactory
*)This
;
401 { IUnknown_AddRef((LPUNKNOWN
)*ppvObj
);
402 TRACE("-- Interface: (%p)->(%p)\n",ppvObj
,*ppvObj
);
405 TRACE("-- Interface: %s E_NOINTERFACE\n", debugstr_guid(riid
));
406 return E_NOINTERFACE
;
408 /******************************************************************************
411 static ULONG WINAPI
IDefClF_fnAddRef(LPCLASSFACTORY iface
)
413 ICOM_THIS(IDefClFImpl
,iface
);
414 TRACE("(%p)->(count=%lu)\n",This
,This
->ref
);
416 InterlockedIncrement(&shell32_ObjCount
);
417 return InterlockedIncrement(&This
->ref
);
419 /******************************************************************************
422 static ULONG WINAPI
IDefClF_fnRelease(LPCLASSFACTORY iface
)
424 ICOM_THIS(IDefClFImpl
,iface
);
425 TRACE("(%p)->(count=%lu)\n",This
,This
->ref
);
427 InterlockedDecrement(&shell32_ObjCount
);
429 if (!InterlockedDecrement(&This
->ref
))
431 if (This
->pcRefDll
) InterlockedDecrement(This
->pcRefDll
);
433 TRACE("-- destroying IClassFactory(%p)\n",This
);
434 HeapFree(GetProcessHeap(),0,This
);
439 /******************************************************************************
440 * IDefClF_fnCreateInstance
442 static HRESULT WINAPI
IDefClF_fnCreateInstance(
443 LPCLASSFACTORY iface
, LPUNKNOWN pUnkOuter
, REFIID riid
, LPVOID
*ppvObject
)
445 ICOM_THIS(IDefClFImpl
,iface
);
447 TRACE("%p->(%p,\n\tIID:\t%s,%p)\n",This
,pUnkOuter
,debugstr_guid(riid
),ppvObject
);
452 return(CLASS_E_NOAGGREGATION
);
454 if ( This
->riidInst
==NULL
||
455 IsEqualCLSID(riid
, This
->riidInst
) ||
456 IsEqualCLSID(riid
, &IID_IUnknown
) )
458 return This
->lpfnCI(pUnkOuter
, riid
, ppvObject
);
461 ERR("unknown IID requested\n\tIID:\t%s\n",debugstr_guid(riid
));
462 return E_NOINTERFACE
;
464 /******************************************************************************
465 * IDefClF_fnLockServer
467 static HRESULT WINAPI
IDefClF_fnLockServer(LPCLASSFACTORY iface
, BOOL fLock
)
469 ICOM_THIS(IDefClFImpl
,iface
);
470 TRACE("%p->(0x%x), not implemented\n",This
, fLock
);
474 static ICOM_VTABLE(IClassFactory
) dclfvt
=
476 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
477 IDefClF_fnQueryInterface
,
480 IDefClF_fnCreateInstance
,
484 /******************************************************************************
485 * SHCreateDefClassObject [SHELL32.70]
487 HRESULT WINAPI
SHCreateDefClassObject(
490 LPFNCREATEINSTANCE lpfnCI
, /* create instance callback entry */
491 PLONG pcRefDll
, /* ref count of the dll */
492 REFIID riidInst
) /* optional interface to the instance */
494 TRACE("\n\tIID:\t%s %p %p %p \n\tIIDIns:\t%s\n",
495 debugstr_guid(riid
), ppv
, lpfnCI
, pcRefDll
, debugstr_guid(riidInst
));
497 if ( IsEqualCLSID(riid
, &IID_IClassFactory
) )
499 IClassFactory
* pcf
= IDefClF_fnConstructor(lpfnCI
, pcRefDll
, riidInst
);
505 return E_OUTOFMEMORY
;
507 return E_NOINTERFACE
;
510 /*************************************************************************
511 * DragAcceptFiles [SHELL32.54]
513 void WINAPI
DragAcceptFiles(HWND hWnd
, BOOL b
)
517 if( !IsWindow(hWnd
) ) return;
518 exstyle
= GetWindowLongA(hWnd
,GWL_EXSTYLE
);
520 exstyle
|= WS_EX_ACCEPTFILES
;
522 exstyle
&= ~WS_EX_ACCEPTFILES
;
523 SetWindowLongA(hWnd
,GWL_EXSTYLE
,exstyle
);
526 /*************************************************************************
527 * DragFinish [SHELL32.80]
529 void WINAPI
DragFinish(HDROP h
)
532 GlobalFree((HGLOBAL
)h
);
535 /*************************************************************************
536 * DragQueryPoint [SHELL32.135]
538 BOOL WINAPI
DragQueryPoint(HDROP hDrop
, POINT
*p
)
540 DROPFILES
*lpDropFileStruct
;
545 lpDropFileStruct
= (DROPFILES
*) GlobalLock(hDrop
);
547 *p
= lpDropFileStruct
->pt
;
548 bRet
= lpDropFileStruct
->fNC
;
554 /*************************************************************************
555 * DragQueryFileA [SHELL32.81] [shell32.82]
557 UINT WINAPI
DragQueryFileA(
565 DROPFILES
*lpDropFileStruct
= (DROPFILES
*) GlobalLock(hDrop
);
567 TRACE("(%08x, %x, %p, %u)\n", hDrop
,lFile
,lpszFile
,lLength
);
569 if(!lpDropFileStruct
) goto end
;
571 lpDrop
= (LPSTR
) lpDropFileStruct
+ lpDropFileStruct
->pFiles
;
575 while (*lpDrop
++); /* skip filename */
578 i
= (lFile
== 0xFFFFFFFF) ? i
: 0;
585 if (!lpszFile
) goto end
; /* needed buffer size */
586 i
= (lLength
> i
) ? i
: lLength
;
587 lstrcpynA (lpszFile
, lpDrop
, i
);
593 /*************************************************************************
594 * DragQueryFileW [shell32.133]
596 UINT WINAPI
DragQueryFileW(
604 DROPFILES
*lpDropFileStruct
= (DROPFILES
*) GlobalLock(hDrop
);
606 TRACE("(%08x, %x, %p, %u)\n", hDrop
,lFile
,lpszwFile
,lLength
);
608 if(!lpDropFileStruct
) goto end
;
610 lpwDrop
= (LPWSTR
) lpDropFileStruct
+ lpDropFileStruct
->pFiles
;
615 while (*lpwDrop
++); /* skip filename */
618 i
= (lFile
== 0xFFFFFFFF) ? i
: 0;
623 i
= strlenW(lpwDrop
);
625 if ( !lpszwFile
) goto end
; /* needed buffer size */
627 i
= (lLength
> i
) ? i
: lLength
;
628 lstrcpynW (lpszwFile
, lpwDrop
, i
);