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);