2 * handling of SHELL32.DLL OLE-Objects
4 * Copyright 1997 Marcus Meissner
5 * Copyright 1998 Juergen Schmied <juergen.schmied@metronet.de>
20 #include "wine/undocshell.h"
21 #include "wine/unicode.h"
22 #include "shell32_main.h"
24 #include "debugtools.h"
26 DEFAULT_DEBUG_CHANNEL(shell);
28 DWORD WINAPI SHCLSIDFromStringA (LPCSTR clsid, CLSID *id);
29 extern IShellFolder * IShellFolder_Constructor(
32 extern HRESULT IFSFolder_Constructor(
37 /*************************************************************************
38 * SHCoCreateInstance [SHELL32.102]
43 LRESULT WINAPI SHCoCreateInstance(
46 LPUNKNOWN unknownouter,
52 CLSID * myclsid = (CLSID*)clsid;
56 if (!aclsid) return REGDB_E_CLASSNOTREG;
57 SHCLSIDFromStringA(aclsid, &iid);
61 TRACE("(%p,\n\tCLSID:\t%s, unk:%p\n\tIID:\t%s,%p)\n",
62 aclsid,debugstr_guid(myclsid),unknownouter,debugstr_guid(refiid),ppv);
64 if IsEqualCLSID(myclsid, &CLSID_ShellFSFolder)
66 hres = IFSFolder_Constructor(unknownouter, refiid, ppv);
70 hres = CoCreateInstance(myclsid, unknownouter, CLSCTX_INPROC_SERVER, refiid, ppv);
75 ERR("failed (0x%08lx) to create \n\tCLSID:\t%s\n\tIID:\t%s\n",
76 hres, debugstr_guid(myclsid), debugstr_guid(refiid));
77 ERR("class not found in registry\n");
80 TRACE("-- instance: %p\n",*ppv);
84 /*************************************************************************
85 * DllGetClassObject [SHELL32.128]
87 HRESULT WINAPI SHELL32_DllGetClassObject(REFCLSID rclsid, REFIID iid,LPVOID *ppv)
88 { HRESULT hres = E_OUTOFMEMORY;
91 TRACE("\n\tCLSID:\t%s,\n\tIID:\t%s\n",debugstr_guid(rclsid),debugstr_guid(iid));
95 if(IsEqualCLSID(rclsid, &CLSID_ShellDesktop)||
96 IsEqualCLSID(rclsid, &CLSID_ShellLink))
98 lpclf = IClassFactory_Constructor( rclsid );
102 hres = IClassFactory_QueryInterface(lpclf,iid, ppv);
103 IClassFactory_Release(lpclf);
108 WARN("-- CLSID not found\n");
109 hres = CLASS_E_CLASSNOTAVAILABLE;
111 TRACE("-- pointer to class factory: %p\n",*ppv);
115 /*************************************************************************
116 * SHCLSIDFromString [SHELL32.147]
119 * exported by ordinal
121 DWORD WINAPI SHCLSIDFromStringA (LPCSTR clsid, CLSID *id)
124 TRACE("(%p(%s) %p)\n", clsid, clsid, id);
125 if (!MultiByteToWideChar( CP_ACP, 0, clsid, -1, buffer, sizeof(buffer)/sizeof(WCHAR) ))
126 return CO_E_CLASSSTRING;
127 return CLSIDFromString( buffer, id );
129 DWORD WINAPI SHCLSIDFromStringW (LPWSTR clsid, CLSID *id)
131 TRACE("(%p(%s) %p)\n", clsid, debugstr_w(clsid), id);
132 return CLSIDFromString(clsid, id);
134 DWORD WINAPI SHCLSIDFromStringAW (LPVOID clsid, CLSID *id)
136 if (SHELL_OsIsUnicode())
137 return SHCLSIDFromStringW (clsid, id);
138 return SHCLSIDFromStringA (clsid, id);
141 /*************************************************************************
142 * SHGetMalloc [SHELL32.@]
143 * returns the interface to shell malloc.
145 * [SDK header win95/shlobj.h:
146 * equivalent to: #define SHGetMalloc(ppmem) CoGetMalloc(MEMCTX_TASK, ppmem)
148 * What we are currently doing is not very wrong, since we always use the same
149 * heap (ProcessHeap).
151 DWORD WINAPI SHGetMalloc(LPMALLOC *lpmal)
153 TRACE("(%p)\n", lpmal);
154 return CoGetMalloc(MEMCTX_TASK, lpmal);
157 /*************************************************************************
158 * SHGetDesktopFolder [SHELL32.@]
160 LPSHELLFOLDER pdesktopfolder=NULL;
162 DWORD WINAPI SHGetDesktopFolder(IShellFolder **psf)
165 LPCLASSFACTORY lpclf;
166 TRACE("%p->(%p)\n",psf,*psf);
172 lpclf = IClassFactory_Constructor(&CLSID_ShellDesktop);
175 hres = IClassFactory_CreateInstance(lpclf,NULL,(REFIID)&IID_IShellFolder, (void*)&pdesktopfolder);
176 IClassFactory_Release(lpclf);
182 /* even if we create the folder, add a ref so the application can“t destroy the folder*/
183 IShellFolder_AddRef(pdesktopfolder);
184 *psf = pdesktopfolder;
187 TRACE("-- %p->(%p)\n",psf, *psf);
191 /**************************************************************************
192 * IClassFactory Implementation
197 /* IUnknown fields */
198 ICOM_VFIELD(IClassFactory);
203 static ICOM_VTABLE(IClassFactory) clfvt;
205 /**************************************************************************
206 * IClassFactory_Constructor
209 LPCLASSFACTORY IClassFactory_Constructor(REFCLSID rclsid)
211 IClassFactoryImpl* lpclf;
213 lpclf= (IClassFactoryImpl*)HeapAlloc(GetProcessHeap(),0,sizeof(IClassFactoryImpl));
215 ICOM_VTBL(lpclf) = &clfvt;
216 lpclf->rclsid = (CLSID*)rclsid;
218 TRACE("(%p)->()\n",lpclf);
219 InterlockedIncrement(&shell32_ObjCount);
220 return (LPCLASSFACTORY)lpclf;
222 /**************************************************************************
223 * IClassFactory_QueryInterface
225 static HRESULT WINAPI IClassFactory_fnQueryInterface(
226 LPCLASSFACTORY iface, REFIID riid, LPVOID *ppvObj)
228 ICOM_THIS(IClassFactoryImpl,iface);
229 TRACE("(%p)->(\n\tIID:\t%s)\n",This,debugstr_guid(riid));
233 if(IsEqualIID(riid, &IID_IUnknown)) /*IUnknown*/
236 else if(IsEqualIID(riid, &IID_IClassFactory)) /*IClassFactory*/
237 { *ppvObj = (IClassFactory*)This;
241 { IUnknown_AddRef((LPUNKNOWN)*ppvObj);
242 TRACE("-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
245 TRACE("-- Interface: %s E_NOINTERFACE\n", debugstr_guid(riid));
246 return E_NOINTERFACE;
248 /******************************************************************************
249 * IClassFactory_AddRef
251 static ULONG WINAPI IClassFactory_fnAddRef(LPCLASSFACTORY iface)
253 ICOM_THIS(IClassFactoryImpl,iface);
254 TRACE("(%p)->(count=%lu)\n",This,This->ref);
256 InterlockedIncrement(&shell32_ObjCount);
257 return InterlockedIncrement(&This->ref);
259 /******************************************************************************
260 * IClassFactory_Release
262 static ULONG WINAPI IClassFactory_fnRelease(LPCLASSFACTORY iface)
264 ICOM_THIS(IClassFactoryImpl,iface);
265 TRACE("(%p)->(count=%lu)\n",This,This->ref);
267 InterlockedDecrement(&shell32_ObjCount);
268 if (!InterlockedDecrement(&This->ref))
270 TRACE("-- destroying IClassFactory(%p)\n",This);
271 HeapFree(GetProcessHeap(),0,This);
276 /******************************************************************************
277 * IClassFactory_CreateInstance
279 static HRESULT WINAPI IClassFactory_fnCreateInstance(
280 LPCLASSFACTORY iface, LPUNKNOWN pUnknown, REFIID riid, LPVOID *ppObject)
282 ICOM_THIS(IClassFactoryImpl,iface);
283 IUnknown *pObj = NULL;
286 TRACE("%p->(%p,\n\tIID:\t%s,%p)\n",This,pUnknown,debugstr_guid(riid),ppObject);
292 return(CLASS_E_NOAGGREGATION);
295 if (IsEqualCLSID(This->rclsid, &CLSID_ShellDesktop))
297 pObj = (IUnknown *)ISF_Desktop_Constructor();
299 else if (IsEqualCLSID(This->rclsid, &CLSID_ShellLink))
301 pObj = (IUnknown *)IShellLink_Constructor(FALSE);
305 ERR("unknown IID requested\n\tIID:\t%s\n",debugstr_guid(riid));
306 return(E_NOINTERFACE);
311 return(E_OUTOFMEMORY);
314 hres = IUnknown_QueryInterface(pObj,riid, ppObject);
315 IUnknown_Release(pObj);
317 TRACE("-- Object created: (%p)->%p\n",This,*ppObject);
321 /******************************************************************************
322 * IClassFactory_LockServer
324 static HRESULT WINAPI IClassFactory_fnLockServer(LPCLASSFACTORY iface, BOOL fLock)
326 ICOM_THIS(IClassFactoryImpl,iface);
327 TRACE("%p->(0x%x), not implemented\n",This, fLock);
331 static ICOM_VTABLE(IClassFactory) clfvt =
333 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
334 IClassFactory_fnQueryInterface,
335 IClassFactory_fnAddRef,
336 IClassFactory_fnRelease,
337 IClassFactory_fnCreateInstance,
338 IClassFactory_fnLockServer
341 /**************************************************************************
342 * Default ClassFactory Implementation
344 * SHCreateDefClassObject
347 * helper function for dll's without a own classfactory
348 * a generic classfactory is returned
349 * when the CreateInstance of the cf is called the callback is executed
351 typedef HRESULT CALLBACK (*LPFNCREATEINSTANCE)(IUnknown* pUnkOuter, REFIID riid, LPVOID* ppvObject);
355 ICOM_VFIELD(IClassFactory);
358 LPFNCREATEINSTANCE lpfnCI;
359 const IID * riidInst;
360 ULONG * pcRefDll; /* pointer to refcounter in external dll (ugrrr...) */
363 static ICOM_VTABLE(IClassFactory) dclfvt;
365 /**************************************************************************
366 * IDefClF_fnConstructor
369 IClassFactory * IDefClF_fnConstructor(LPFNCREATEINSTANCE lpfnCI, PLONG pcRefDll, REFIID riidInst)
373 lpclf = (IDefClFImpl*)HeapAlloc(GetProcessHeap(),0,sizeof(IDefClFImpl));
375 ICOM_VTBL(lpclf) = &dclfvt;
376 lpclf->lpfnCI = lpfnCI;
377 lpclf->pcRefDll = pcRefDll;
379 if (pcRefDll) InterlockedIncrement(pcRefDll);
380 lpclf->riidInst = riidInst;
382 TRACE("(%p)\n\tIID:\t%s\n",lpclf, debugstr_guid(riidInst));
383 InterlockedIncrement(&shell32_ObjCount);
384 return (LPCLASSFACTORY)lpclf;
386 /**************************************************************************
387 * IDefClF_fnQueryInterface
389 static HRESULT WINAPI IDefClF_fnQueryInterface(
390 LPCLASSFACTORY iface, REFIID riid, LPVOID *ppvObj)
392 ICOM_THIS(IDefClFImpl,iface);
394 TRACE("(%p)->(\n\tIID:\t%s)\n",This,debugstr_guid(riid));
398 if(IsEqualIID(riid, &IID_IUnknown)) /*IUnknown*/
401 else if(IsEqualIID(riid, &IID_IClassFactory)) /*IClassFactory*/
402 { *ppvObj = (IClassFactory*)This;
406 { IUnknown_AddRef((LPUNKNOWN)*ppvObj);
407 TRACE("-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
410 TRACE("-- Interface: %s E_NOINTERFACE\n", debugstr_guid(riid));
411 return E_NOINTERFACE;
413 /******************************************************************************
416 static ULONG WINAPI IDefClF_fnAddRef(LPCLASSFACTORY iface)
418 ICOM_THIS(IDefClFImpl,iface);
419 TRACE("(%p)->(count=%lu)\n",This,This->ref);
421 InterlockedIncrement(&shell32_ObjCount);
422 return InterlockedIncrement(&This->ref);
424 /******************************************************************************
427 static ULONG WINAPI IDefClF_fnRelease(LPCLASSFACTORY iface)
429 ICOM_THIS(IDefClFImpl,iface);
430 TRACE("(%p)->(count=%lu)\n",This,This->ref);
432 InterlockedDecrement(&shell32_ObjCount);
434 if (!InterlockedDecrement(&This->ref))
436 if (This->pcRefDll) InterlockedDecrement(This->pcRefDll);
438 TRACE("-- destroying IClassFactory(%p)\n",This);
439 HeapFree(GetProcessHeap(),0,This);
444 /******************************************************************************
445 * IDefClF_fnCreateInstance
447 static HRESULT WINAPI IDefClF_fnCreateInstance(
448 LPCLASSFACTORY iface, LPUNKNOWN pUnkOuter, REFIID riid, LPVOID *ppvObject)
450 ICOM_THIS(IDefClFImpl,iface);
452 TRACE("%p->(%p,\n\tIID:\t%s,%p)\n",This,pUnkOuter,debugstr_guid(riid),ppvObject);
457 return(CLASS_E_NOAGGREGATION);
459 if ( This->riidInst==NULL ||
460 IsEqualCLSID(riid, This->riidInst) ||
461 IsEqualCLSID(riid, &IID_IUnknown) )
463 return This->lpfnCI(pUnkOuter, riid, ppvObject);
466 ERR("unknown IID requested\n\tIID:\t%s\n",debugstr_guid(riid));
467 return E_NOINTERFACE;
469 /******************************************************************************
470 * IDefClF_fnLockServer
472 static HRESULT WINAPI IDefClF_fnLockServer(LPCLASSFACTORY iface, BOOL fLock)
474 ICOM_THIS(IDefClFImpl,iface);
475 TRACE("%p->(0x%x), not implemented\n",This, fLock);
479 static ICOM_VTABLE(IClassFactory) dclfvt =
481 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
482 IDefClF_fnQueryInterface,
485 IDefClF_fnCreateInstance,
489 /******************************************************************************
490 * SHCreateDefClassObject [SHELL32.70]
492 HRESULT WINAPI SHCreateDefClassObject(
495 LPFNCREATEINSTANCE lpfnCI, /* [in] create instance callback entry */
496 LPDWORD pcRefDll, /* [in/out] ref count of the dll */
497 REFIID riidInst) /* [in] optional interface to the instance */
499 TRACE("\n\tIID:\t%s %p %p %p \n\tIIDIns:\t%s\n",
500 debugstr_guid(riid), ppv, lpfnCI, pcRefDll, debugstr_guid(riidInst));
502 if ( IsEqualCLSID(riid, &IID_IClassFactory) )
504 IClassFactory * pcf = IDefClF_fnConstructor(lpfnCI, pcRefDll, riidInst);
510 return E_OUTOFMEMORY;
512 return E_NOINTERFACE;
515 /*************************************************************************
516 * DragAcceptFiles [SHELL32.54]
518 void WINAPI DragAcceptFiles(HWND hWnd, BOOL b)
522 if( !IsWindow(hWnd) ) return;
523 exstyle = GetWindowLongA(hWnd,GWL_EXSTYLE);
525 exstyle |= WS_EX_ACCEPTFILES;
527 exstyle &= ~WS_EX_ACCEPTFILES;
528 SetWindowLongA(hWnd,GWL_EXSTYLE,exstyle);
531 /*************************************************************************
532 * DragFinish [SHELL32.80]
534 void WINAPI DragFinish(HDROP h)
537 GlobalFree((HGLOBAL)h);
540 /*************************************************************************
541 * DragQueryPoint [SHELL32.135]
543 BOOL WINAPI DragQueryPoint(HDROP hDrop, POINT *p)
545 DROPFILES *lpDropFileStruct;
550 lpDropFileStruct = (DROPFILES *) GlobalLock(hDrop);
552 *p = lpDropFileStruct->pt;
553 bRet = lpDropFileStruct->fNC;
559 /*************************************************************************
560 * DragQueryFile [SHELL32.81]
561 * DragQueryFileA [SHELL32.82]
563 UINT WINAPI DragQueryFileA(
571 DROPFILES *lpDropFileStruct = (DROPFILES *) GlobalLock(hDrop);
573 TRACE("(%08x, %x, %p, %u)\n", hDrop,lFile,lpszFile,lLength);
575 if(!lpDropFileStruct) goto end;
577 lpDrop = (LPSTR) lpDropFileStruct + lpDropFileStruct->pFiles;
581 while (*lpDrop++); /* skip filename */
584 i = (lFile == 0xFFFFFFFF) ? i : 0;
591 if (!lpszFile ) goto end; /* needed buffer size */
592 i = (lLength > i) ? i : lLength;
593 lstrcpynA (lpszFile, lpDrop, i);
599 /*************************************************************************
600 * DragQueryFileW [SHELL32.133]
602 UINT WINAPI DragQueryFileW(
610 DROPFILES *lpDropFileStruct = (DROPFILES *) GlobalLock(hDrop);
612 TRACE("(%08x, %x, %p, %u)\n", hDrop,lFile,lpszwFile,lLength);
614 if(!lpDropFileStruct) goto end;
616 lpwDrop = (LPWSTR) lpDropFileStruct + lpDropFileStruct->pFiles;
621 while (*lpwDrop++); /* skip filename */
624 i = (lFile == 0xFFFFFFFF) ? i : 0;
629 i = strlenW(lpwDrop);
631 if ( !lpszwFile) goto end; /* needed buffer size */
633 i = (lLength > i) ? i : lLength;
634 lstrcpynW (lpszwFile, lpwDrop, i);