2 * handling of SHELL32.DLL OLE-Objects
4 * Copyright 1997 Marcus Meissner
5 * Copyright 1998 Juergen Schmied <juergen.schmied@metronet.de>
20 #include "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);
71 hres = CoCreateInstance(myclsid, unknownouter, CLSCTX_INPROC_SERVER, refiid, ppv);
76 ERR("failed (0x%08lx) to create \n\tCLSID:\t%s\n\tIID:\t%s\n",
77 hres, debugstr_guid(myclsid), debugstr_guid(refiid));
78 ERR("class not found in registry\n");
81 TRACE("-- instance: %p\n",*ppv);
85 /*************************************************************************
86 * DllGetClassObject [SHELL32.128]
88 HRESULT WINAPI SHELL32_DllGetClassObject(REFCLSID rclsid, REFIID iid,LPVOID *ppv)
89 { HRESULT hres = E_OUTOFMEMORY;
92 TRACE("\n\tCLSID:\t%s,\n\tIID:\t%s\n",debugstr_guid(rclsid),debugstr_guid(iid));
96 if(IsEqualCLSID(rclsid, &CLSID_ShellDesktop)||
97 IsEqualCLSID(rclsid, &CLSID_ShellLink))
99 lpclf = IClassFactory_Constructor( rclsid );
103 hres = IClassFactory_QueryInterface(lpclf,iid, ppv);
104 IClassFactory_Release(lpclf);
109 WARN("-- CLSID not found\n");
110 hres = CLASS_E_CLASSNOTAVAILABLE;
112 TRACE("-- pointer to class factory: %p\n",*ppv);
116 /*************************************************************************
117 * SHCLSIDFromString [SHELL32.147]
120 * exported by ordinal
122 DWORD WINAPI SHCLSIDFromStringA (LPCSTR clsid, CLSID *id)
125 TRACE("(%p(%s) %p)\n", clsid, clsid, id);
126 if (!MultiByteToWideChar( CP_ACP, 0, clsid, -1, buffer, sizeof(buffer)/sizeof(WCHAR) ))
127 return CO_E_CLASSSTRING;
128 return CLSIDFromString( buffer, id );
130 DWORD WINAPI SHCLSIDFromStringW (LPWSTR clsid, CLSID *id)
132 TRACE("(%p(%s) %p)\n", clsid, debugstr_w(clsid), id);
133 return CLSIDFromString(clsid, id);
135 DWORD WINAPI SHCLSIDFromStringAW (LPVOID clsid, CLSID *id)
137 if (SHELL_OsIsUnicode())
138 return SHCLSIDFromStringW (clsid, id);
139 return SHCLSIDFromStringA (clsid, id);
142 /*************************************************************************
143 * SHGetMalloc [SHELL32.@]
144 * returns the interface to shell malloc.
146 * [SDK header win95/shlobj.h:
147 * equivalent to: #define SHGetMalloc(ppmem) CoGetMalloc(MEMCTX_TASK, ppmem)
149 * What we are currently doing is not very wrong, since we always use the same
150 * heap (ProcessHeap).
152 DWORD WINAPI SHGetMalloc(LPMALLOC *lpmal)
154 TRACE("(%p)\n", lpmal);
155 return CoGetMalloc(MEMCTX_TASK, lpmal);
158 /*************************************************************************
159 * SHGetDesktopFolder [SHELL32.@]
161 LPSHELLFOLDER pdesktopfolder=NULL;
163 DWORD WINAPI SHGetDesktopFolder(IShellFolder **psf)
166 LPCLASSFACTORY lpclf;
167 TRACE("%p->(%p)\n",psf,*psf);
173 lpclf = IClassFactory_Constructor(&CLSID_ShellDesktop);
176 hres = IClassFactory_CreateInstance(lpclf,NULL,(REFIID)&IID_IShellFolder, (void*)&pdesktopfolder);
177 IClassFactory_Release(lpclf);
183 /* even if we create the folder, add a ref so the application can“t destroy the folder*/
184 IShellFolder_AddRef(pdesktopfolder);
185 *psf = pdesktopfolder;
188 TRACE("-- %p->(%p)\n",psf, *psf);
192 /**************************************************************************
193 * IClassFactory Implementation
198 /* IUnknown fields */
199 ICOM_VFIELD(IClassFactory);
204 static ICOM_VTABLE(IClassFactory) clfvt;
206 /**************************************************************************
207 * IClassFactory_Constructor
210 LPCLASSFACTORY IClassFactory_Constructor(REFCLSID rclsid)
212 IClassFactoryImpl* lpclf;
214 lpclf= (IClassFactoryImpl*)HeapAlloc(GetProcessHeap(),0,sizeof(IClassFactoryImpl));
216 ICOM_VTBL(lpclf) = &clfvt;
217 lpclf->rclsid = (CLSID*)rclsid;
219 TRACE("(%p)->()\n",lpclf);
220 InterlockedIncrement(&shell32_ObjCount);
221 return (LPCLASSFACTORY)lpclf;
223 /**************************************************************************
224 * IClassFactory_QueryInterface
226 static HRESULT WINAPI IClassFactory_fnQueryInterface(
227 LPCLASSFACTORY iface, REFIID riid, LPVOID *ppvObj)
229 ICOM_THIS(IClassFactoryImpl,iface);
230 TRACE("(%p)->(\n\tIID:\t%s)\n",This,debugstr_guid(riid));
234 if(IsEqualIID(riid, &IID_IUnknown)) /*IUnknown*/
237 else if(IsEqualIID(riid, &IID_IClassFactory)) /*IClassFactory*/
238 { *ppvObj = (IClassFactory*)This;
242 { IUnknown_AddRef((LPUNKNOWN)*ppvObj);
243 TRACE("-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
246 TRACE("-- Interface: %s E_NOINTERFACE\n", debugstr_guid(riid));
247 return E_NOINTERFACE;
249 /******************************************************************************
250 * IClassFactory_AddRef
252 static ULONG WINAPI IClassFactory_fnAddRef(LPCLASSFACTORY iface)
254 ICOM_THIS(IClassFactoryImpl,iface);
255 TRACE("(%p)->(count=%lu)\n",This,This->ref);
257 InterlockedIncrement(&shell32_ObjCount);
258 return InterlockedIncrement(&This->ref);
260 /******************************************************************************
261 * IClassFactory_Release
263 static ULONG WINAPI IClassFactory_fnRelease(LPCLASSFACTORY iface)
265 ICOM_THIS(IClassFactoryImpl,iface);
266 TRACE("(%p)->(count=%lu)\n",This,This->ref);
268 InterlockedDecrement(&shell32_ObjCount);
269 if (!InterlockedDecrement(&This->ref))
271 TRACE("-- destroying IClassFactory(%p)\n",This);
272 HeapFree(GetProcessHeap(),0,This);
277 /******************************************************************************
278 * IClassFactory_CreateInstance
280 static HRESULT WINAPI IClassFactory_fnCreateInstance(
281 LPCLASSFACTORY iface, LPUNKNOWN pUnknown, REFIID riid, LPVOID *ppObject)
283 ICOM_THIS(IClassFactoryImpl,iface);
284 IUnknown *pObj = NULL;
287 TRACE("%p->(%p,\n\tIID:\t%s,%p)\n",This,pUnknown,debugstr_guid(riid),ppObject);
293 return(CLASS_E_NOAGGREGATION);
296 if (IsEqualCLSID(This->rclsid, &CLSID_ShellDesktop))
298 pObj = (IUnknown *)ISF_Desktop_Constructor();
300 else if (IsEqualCLSID(This->rclsid, &CLSID_ShellLink))
302 pObj = (IUnknown *)IShellLink_Constructor(FALSE);
306 ERR("unknown IID requested\n\tIID:\t%s\n",debugstr_guid(riid));
307 return(E_NOINTERFACE);
312 return(E_OUTOFMEMORY);
315 hres = IUnknown_QueryInterface(pObj,riid, ppObject);
316 IUnknown_Release(pObj);
318 TRACE("-- Object created: (%p)->%p\n",This,*ppObject);
322 /******************************************************************************
323 * IClassFactory_LockServer
325 static HRESULT WINAPI IClassFactory_fnLockServer(LPCLASSFACTORY iface, BOOL fLock)
327 ICOM_THIS(IClassFactoryImpl,iface);
328 TRACE("%p->(0x%x), not implemented\n",This, fLock);
332 static ICOM_VTABLE(IClassFactory) clfvt =
334 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
335 IClassFactory_fnQueryInterface,
336 IClassFactory_fnAddRef,
337 IClassFactory_fnRelease,
338 IClassFactory_fnCreateInstance,
339 IClassFactory_fnLockServer
342 /**************************************************************************
343 * Default ClassFactory Implementation
345 * SHCreateDefClassObject
348 * helper function for dll's without a own classfactory
349 * a generic classfactory is returned
350 * when the CreateInstance of the cf is called the callback is executed
352 typedef HRESULT CALLBACK (*LPFNCREATEINSTANCE)(IUnknown* pUnkOuter, REFIID riid, LPVOID* ppvObject);
356 ICOM_VFIELD(IClassFactory);
359 LPFNCREATEINSTANCE lpfnCI;
360 const IID * riidInst;
361 ULONG * pcRefDll; /* pointer to refcounter in external dll (ugrrr...) */
364 static ICOM_VTABLE(IClassFactory) dclfvt;
366 /**************************************************************************
367 * IDefClF_fnConstructor
370 IClassFactory * IDefClF_fnConstructor(LPFNCREATEINSTANCE lpfnCI, PLONG pcRefDll, REFIID riidInst)
374 lpclf = (IDefClFImpl*)HeapAlloc(GetProcessHeap(),0,sizeof(IDefClFImpl));
376 ICOM_VTBL(lpclf) = &dclfvt;
377 lpclf->lpfnCI = lpfnCI;
378 lpclf->pcRefDll = pcRefDll;
380 if (pcRefDll) InterlockedIncrement(pcRefDll);
381 lpclf->riidInst = riidInst;
383 TRACE("(%p)\n\tIID:\t%s\n",lpclf, debugstr_guid(riidInst));
384 InterlockedIncrement(&shell32_ObjCount);
385 return (LPCLASSFACTORY)lpclf;
387 /**************************************************************************
388 * IDefClF_fnQueryInterface
390 static HRESULT WINAPI IDefClF_fnQueryInterface(
391 LPCLASSFACTORY iface, REFIID riid, LPVOID *ppvObj)
393 ICOM_THIS(IDefClFImpl,iface);
395 TRACE("(%p)->(\n\tIID:\t%s)\n",This,debugstr_guid(riid));
399 if(IsEqualIID(riid, &IID_IUnknown)) /*IUnknown*/
402 else if(IsEqualIID(riid, &IID_IClassFactory)) /*IClassFactory*/
403 { *ppvObj = (IClassFactory*)This;
407 { IUnknown_AddRef((LPUNKNOWN)*ppvObj);
408 TRACE("-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
411 TRACE("-- Interface: %s E_NOINTERFACE\n", debugstr_guid(riid));
412 return E_NOINTERFACE;
414 /******************************************************************************
417 static ULONG WINAPI IDefClF_fnAddRef(LPCLASSFACTORY iface)
419 ICOM_THIS(IDefClFImpl,iface);
420 TRACE("(%p)->(count=%lu)\n",This,This->ref);
422 InterlockedIncrement(&shell32_ObjCount);
423 return InterlockedIncrement(&This->ref);
425 /******************************************************************************
428 static ULONG WINAPI IDefClF_fnRelease(LPCLASSFACTORY iface)
430 ICOM_THIS(IDefClFImpl,iface);
431 TRACE("(%p)->(count=%lu)\n",This,This->ref);
433 InterlockedDecrement(&shell32_ObjCount);
435 if (!InterlockedDecrement(&This->ref))
437 if (This->pcRefDll) InterlockedDecrement(This->pcRefDll);
439 TRACE("-- destroying IClassFactory(%p)\n",This);
440 HeapFree(GetProcessHeap(),0,This);
445 /******************************************************************************
446 * IDefClF_fnCreateInstance
448 static HRESULT WINAPI IDefClF_fnCreateInstance(
449 LPCLASSFACTORY iface, LPUNKNOWN pUnkOuter, REFIID riid, LPVOID *ppvObject)
451 ICOM_THIS(IDefClFImpl,iface);
453 TRACE("%p->(%p,\n\tIID:\t%s,%p)\n",This,pUnkOuter,debugstr_guid(riid),ppvObject);
458 return(CLASS_E_NOAGGREGATION);
460 if ( This->riidInst==NULL ||
461 IsEqualCLSID(riid, This->riidInst) ||
462 IsEqualCLSID(riid, &IID_IUnknown) )
464 return This->lpfnCI(pUnkOuter, riid, ppvObject);
467 ERR("unknown IID requested\n\tIID:\t%s\n",debugstr_guid(riid));
468 return E_NOINTERFACE;
470 /******************************************************************************
471 * IDefClF_fnLockServer
473 static HRESULT WINAPI IDefClF_fnLockServer(LPCLASSFACTORY iface, BOOL fLock)
475 ICOM_THIS(IDefClFImpl,iface);
476 TRACE("%p->(0x%x), not implemented\n",This, fLock);
480 static ICOM_VTABLE(IClassFactory) dclfvt =
482 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
483 IDefClF_fnQueryInterface,
486 IDefClF_fnCreateInstance,
490 /******************************************************************************
491 * SHCreateDefClassObject [SHELL32.70]
493 HRESULT WINAPI SHCreateDefClassObject(
496 LPFNCREATEINSTANCE lpfnCI, /* [in] create instance callback entry */
497 LPDWORD pcRefDll, /* [in/out] ref count of the dll */
498 REFIID riidInst) /* [in] optional interface to the instance */
500 TRACE("\n\tIID:\t%s %p %p %p \n\tIIDIns:\t%s\n",
501 debugstr_guid(riid), ppv, lpfnCI, pcRefDll, debugstr_guid(riidInst));
503 if ( IsEqualCLSID(riid, &IID_IClassFactory) )
505 IClassFactory * pcf = IDefClF_fnConstructor(lpfnCI, pcRefDll, riidInst);
511 return E_OUTOFMEMORY;
513 return E_NOINTERFACE;
516 /*************************************************************************
517 * DragAcceptFiles [SHELL32.54]
519 void WINAPI DragAcceptFiles(HWND hWnd, BOOL b)
523 if( !IsWindow(hWnd) ) return;
524 exstyle = GetWindowLongA(hWnd,GWL_EXSTYLE);
526 exstyle |= WS_EX_ACCEPTFILES;
528 exstyle &= ~WS_EX_ACCEPTFILES;
529 SetWindowLongA(hWnd,GWL_EXSTYLE,exstyle);
532 /*************************************************************************
533 * DragFinish [SHELL32.80]
535 void WINAPI DragFinish(HDROP h)
538 GlobalFree((HGLOBAL)h);
541 /*************************************************************************
542 * DragQueryPoint [SHELL32.135]
544 BOOL WINAPI DragQueryPoint(HDROP hDrop, POINT *p)
546 DROPFILES *lpDropFileStruct;
551 lpDropFileStruct = (DROPFILES *) GlobalLock(hDrop);
553 *p = lpDropFileStruct->pt;
554 bRet = lpDropFileStruct->fNC;
560 /*************************************************************************
561 * DragQueryFile [SHELL32.81]
562 * DragQueryFileA [SHELL32.82]
564 UINT WINAPI DragQueryFileA(
572 DROPFILES *lpDropFileStruct = (DROPFILES *) GlobalLock(hDrop);
574 TRACE("(%08x, %x, %p, %u)\n", hDrop,lFile,lpszFile,lLength);
576 if(!lpDropFileStruct) goto end;
578 lpDrop = (LPSTR) lpDropFileStruct + lpDropFileStruct->pFiles;
582 while (*lpDrop++); /* skip filename */
585 i = (lFile == 0xFFFFFFFF) ? i : 0;
592 if (!lpszFile ) goto end; /* needed buffer size */
593 i = (lLength > i) ? i : lLength;
594 lstrcpynA (lpszFile, lpDrop, i);
600 /*************************************************************************
601 * DragQueryFileW [SHELL32.133]
603 UINT WINAPI DragQueryFileW(
611 DROPFILES *lpDropFileStruct = (DROPFILES *) GlobalLock(hDrop);
613 TRACE("(%08x, %x, %p, %u)\n", hDrop,lFile,lpszwFile,lLength);
615 if(!lpDropFileStruct) goto end;
617 lpwDrop = (LPWSTR) lpDropFileStruct + lpDropFileStruct->pFiles;
622 while (*lpwDrop++); /* skip filename */
625 i = (lFile == 0xFFFFFFFF) ? i : 0;
630 i = strlenW(lpwDrop);
632 if ( !lpszwFile) goto end; /* needed buffer size */
634 i = (lLength > i) ? i : lLength;
635 lstrcpynW (lpszwFile, lpwDrop, i);