Fixed some warnings.
[wine.git] / dlls / shell32 / shellole.c
blob323af3dfd96b084b11668a8440b9eea448686009
1 /*
2 * handling of SHELL32.DLL OLE-Objects
4 * Copyright 1997 Marcus Meissner
5 * Copyright 1998 Juergen Schmied <juergen.schmied@metronet.de>
7 */
9 #include <stdlib.h>
10 #include <string.h>
12 #include "wine/obj_base.h"
13 #include "wine/obj_shelllink.h"
14 #include "wine/obj_shellfolder.h"
15 #include "wine/obj_shellbrowser.h"
16 #include "wine/obj_contextmenu.h"
17 #include "wine/obj_shellextinit.h"
18 #include "wine/obj_extracticon.h"
20 #include "shlguid.h"
21 #include "winreg.h"
22 #include "winerror.h"
23 #include "debugtools.h"
25 #include "shell32_main.h"
27 DEFAULT_DEBUG_CHANNEL(shell);
29 DWORD WINAPI SHCLSIDFromStringA (LPSTR clsid, CLSID *id);
30 extern IShellFolder * IShellFolder_Constructor(
31 IShellFolder * psf,
32 LPITEMIDLIST pidl);
33 extern HRESULT IFSFolder_Constructor(
34 IUnknown * pUnkOuter,
35 REFIID riid,
36 LPVOID * ppv);
38 /*************************************************************************
39 * SHCoCreateInstance [SHELL32.102]
41 * NOTES
42 * exported by ordinal
44 LRESULT WINAPI SHCoCreateInstance(
45 LPSTR aclsid,
46 REFCLSID clsid,
47 IUnknown * unknownouter,
48 REFIID refiid,
49 LPVOID *ppv)
51 DWORD hres;
52 IID iid;
53 CLSID * myclsid = (CLSID*)clsid;
55 if (!clsid)
57 if (!aclsid) return REGDB_E_CLASSNOTREG;
58 SHCLSIDFromStringA(aclsid, &iid);
59 myclsid = &iid;
62 TRACE("(%p,\n\tCLSID:\t%s, unk:%p\n\tIID:\t%s,%p)\n",
63 aclsid,debugstr_guid(myclsid),unknownouter,debugstr_guid(refiid),ppv);
65 if IsEqualCLSID(myclsid, &CLSID_ShellFSFolder)
67 hres = IFSFolder_Constructor(unknownouter, refiid, ppv);
69 else
71 hres = CoCreateInstance(myclsid, unknownouter, CLSCTX_INPROC_SERVER, refiid, ppv);
74 if(hres!=S_OK)
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);
82 return hres;
85 /*************************************************************************
86 * SHELL32_DllGetClassObject [SHELL32.128]
88 HRESULT WINAPI SHELL32_DllGetClassObject(REFCLSID rclsid, REFIID iid,LPVOID *ppv)
89 { HRESULT hres = E_OUTOFMEMORY;
90 LPCLASSFACTORY lpclf;
92 TRACE("\n\tCLSID:\t%s,\n\tIID:\t%s\n",debugstr_guid(rclsid),debugstr_guid(iid));
94 *ppv = NULL;
96 if(IsEqualCLSID(rclsid, &CLSID_ShellDesktop)||
97 IsEqualCLSID(rclsid, &CLSID_ShellLink))
99 lpclf = IClassFactory_Constructor( rclsid );
101 if(lpclf)
103 hres = IClassFactory_QueryInterface(lpclf,iid, ppv);
104 IClassFactory_Release(lpclf);
107 else
109 WARN("-- CLSID not found\n");
110 hres = CLASS_E_CLASSNOTAVAILABLE;
112 TRACE("-- pointer to class factory: %p\n",*ppv);
113 return hres;
116 /*************************************************************************
117 * SHCLSIDFromString [SHELL32.147]
119 * NOTES
120 * exported by ordinal
122 DWORD WINAPI SHCLSIDFromStringA (LPSTR clsid, CLSID *id)
124 WCHAR buffer[40];
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.220]
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(0,lpmal);
158 /*************************************************************************
159 * SHGetDesktopFolder [SHELL32.216]
161 LPSHELLFOLDER pdesktopfolder=NULL;
163 DWORD WINAPI SHGetDesktopFolder(IShellFolder **psf)
165 HRESULT hres = S_OK;
166 LPCLASSFACTORY lpclf;
167 TRACE("%p->(%p)\n",psf,*psf);
169 *psf=NULL;
171 if (!pdesktopfolder)
173 lpclf = IClassFactory_Constructor(&CLSID_ShellDesktop);
174 if(lpclf)
176 hres = IClassFactory_CreateInstance(lpclf,NULL,(REFIID)&IID_IShellFolder, (void*)&pdesktopfolder);
177 IClassFactory_Release(lpclf);
181 if (pdesktopfolder)
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);
189 return hres;
192 /**************************************************************************
193 * IClassFactory Implementation
196 typedef struct
198 /* IUnknown fields */
199 ICOM_VFIELD(IClassFactory);
200 DWORD ref;
201 CLSID *rclsid;
202 } IClassFactoryImpl;
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));
215 lpclf->ref = 1;
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));
232 *ppvObj = NULL;
234 if(IsEqualIID(riid, &IID_IUnknown)) /*IUnknown*/
235 { *ppvObj = This;
237 else if(IsEqualIID(riid, &IID_IClassFactory)) /*IClassFactory*/
238 { *ppvObj = (IClassFactory*)This;
241 if(*ppvObj)
242 { IUnknown_AddRef((LPUNKNOWN)*ppvObj);
243 TRACE("-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
244 return S_OK;
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);
273 return 0;
275 return This->ref;
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;
285 HRESULT hres;
287 TRACE("%p->(%p,\n\tIID:\t%s,%p)\n",This,pUnknown,debugstr_guid(riid),ppObject);
289 *ppObject = NULL;
291 if(pUnknown)
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);
304 else
306 ERR("unknown IID requested\n\tIID:\t%s\n",debugstr_guid(riid));
307 return(E_NOINTERFACE);
310 if (!pObj)
312 return(E_OUTOFMEMORY);
315 hres = IUnknown_QueryInterface(pObj,riid, ppObject);
316 IUnknown_Release(pObj);
318 TRACE("-- Object created: (%p)->%p\n",This,*ppObject);
320 return hres;
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);
329 return E_NOTIMPL;
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
347 * NOTES
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);
354 typedef struct
356 ICOM_VFIELD(IClassFactory);
357 DWORD ref;
358 CLSID *rclsid;
359 LPFNCREATEINSTANCE lpfnCI;
360 const IID * riidInst;
361 ULONG * pcRefDll; /* pointer to refcounter in external dll (ugrrr...) */
362 } IDefClFImpl;
364 static ICOM_VTABLE(IClassFactory) dclfvt;
366 /**************************************************************************
367 * IDefClF_fnConstructor
370 IClassFactory * IDefClF_fnConstructor(LPFNCREATEINSTANCE lpfnCI, PLONG pcRefDll, REFIID riidInst)
372 IDefClFImpl* lpclf;
374 lpclf = (IDefClFImpl*)HeapAlloc(GetProcessHeap(),0,sizeof(IDefClFImpl));
375 lpclf->ref = 1;
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));
397 *ppvObj = NULL;
399 if(IsEqualIID(riid, &IID_IUnknown)) /*IUnknown*/
400 { *ppvObj = This;
402 else if(IsEqualIID(riid, &IID_IClassFactory)) /*IClassFactory*/
403 { *ppvObj = (IClassFactory*)This;
406 if(*ppvObj)
407 { IUnknown_AddRef((LPUNKNOWN)*ppvObj);
408 TRACE("-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
409 return S_OK;
411 TRACE("-- Interface: %s E_NOINTERFACE\n", debugstr_guid(riid));
412 return E_NOINTERFACE;
414 /******************************************************************************
415 * IDefClF_fnAddRef
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 /******************************************************************************
426 * IDefClF_fnRelease
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);
441 return 0;
443 return This->ref;
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);
455 *ppvObject = NULL;
457 if(pUnkOuter)
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);
477 return E_NOTIMPL;
480 static ICOM_VTABLE(IClassFactory) dclfvt =
482 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
483 IDefClF_fnQueryInterface,
484 IDefClF_fnAddRef,
485 IDefClF_fnRelease,
486 IDefClF_fnCreateInstance,
487 IDefClF_fnLockServer
490 /******************************************************************************
491 * SHCreateDefClassObject [SHELL32.70]
493 HRESULT WINAPI SHCreateDefClassObject(
494 REFIID riid,
495 LPVOID* ppv,
496 LPFNCREATEINSTANCE lpfnCI, /* create instance callback entry */
497 PLONG pcRefDll, /* ref count of the dll */
498 REFIID riidInst) /* 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);
506 if (pcf)
508 *ppv = pcf;
509 return NOERROR;
511 return E_OUTOFMEMORY;
513 return E_NOINTERFACE;
516 /*************************************************************************
517 * DragAcceptFiles [SHELL32.54]
519 void WINAPI DragAcceptFiles(HWND hWnd, BOOL b)
521 LONG exstyle;
523 if( !IsWindow(hWnd) ) return;
524 exstyle = GetWindowLongA(hWnd,GWL_EXSTYLE);
525 if (b)
526 exstyle |= WS_EX_ACCEPTFILES;
527 else
528 exstyle &= ~WS_EX_ACCEPTFILES;
529 SetWindowLongA(hWnd,GWL_EXSTYLE,exstyle);
532 /*************************************************************************
533 * DragFinish [SHELL32.80]
535 void WINAPI DragFinish(HDROP h)
537 TRACE("\n");
538 GlobalFree((HGLOBAL)h);
541 /*************************************************************************
542 * DragQueryPoint [SHELL32.135]
544 BOOL WINAPI DragQueryPoint(HDROP hDrop, POINT *p)
546 LPDROPFILESTRUCT lpDropFileStruct;
547 BOOL bRet;
549 TRACE("\n");
551 lpDropFileStruct = (LPDROPFILESTRUCT) GlobalLock(hDrop);
553 memcpy(p,&lpDropFileStruct->ptMousePos,sizeof(POINT));
554 bRet = lpDropFileStruct->fInNonClientArea;
556 GlobalUnlock(hDrop);
557 return bRet;
560 /*************************************************************************
561 * DragQueryFileA [SHELL32.81] [shell32.82]
563 UINT WINAPI DragQueryFileA(
564 HDROP hDrop,
565 UINT lFile,
566 LPSTR lpszFile,
567 UINT lLength)
569 LPSTR lpDrop;
570 UINT i = 0;
571 LPDROPFILESTRUCT lpDropFileStruct = (LPDROPFILESTRUCT) GlobalLock(hDrop);
573 TRACE("(%08x, %x, %p, %u)\n", hDrop,lFile,lpszFile,lLength);
575 if(!lpDropFileStruct) goto end;
577 lpDrop = (LPSTR) lpDropFileStruct + lpDropFileStruct->lSize;
579 while (i++ < lFile)
581 while (*lpDrop++); /* skip filename */
582 if (!*lpDrop)
584 i = (lFile == 0xFFFFFFFF) ? i : 0;
585 goto end;
589 i = strlen(lpDrop);
590 i++;
591 if (!lpszFile ) goto end; /* needed buffer size */
592 i = (lLength > i) ? i : lLength;
593 lstrcpynA (lpszFile, lpDrop, i);
594 end:
595 GlobalUnlock(hDrop);
596 return i;
599 /*************************************************************************
600 * DragQueryFileW [shell32.133]
602 UINT WINAPI DragQueryFileW(
603 HDROP hDrop,
604 UINT lFile,
605 LPWSTR lpszwFile,
606 UINT lLength)
608 LPWSTR lpwDrop;
609 UINT i = 0;
610 LPDROPFILESTRUCT lpDropFileStruct = (LPDROPFILESTRUCT) GlobalLock(hDrop);
612 TRACE("(%08x, %x, %p, %u)\n", hDrop,lFile,lpszwFile,lLength);
614 if(!lpDropFileStruct) goto end;
616 lpwDrop = (LPWSTR) lpDropFileStruct + lpDropFileStruct->lSize;
618 i = 0;
619 while (i++ < lFile)
621 while (*lpwDrop++); /* skip filename */
622 if (!*lpwDrop)
624 i = (lFile == 0xFFFFFFFF) ? i : 0;
625 goto end;
629 i = lstrlenW(lpwDrop);
630 i++;
631 if ( !lpszwFile) goto end; /* needed buffer size */
633 i = (lLength > i) ? i : lLength;
634 lstrcpynW (lpszwFile, lpwDrop, i);
635 end:
636 GlobalUnlock(hDrop);
637 return i;