2 * handling of SHELL32.DLL OLE-Objects
4 * Copyright 1997 Marcus Meissner
5 * Copyright 1998 Juergen Schmied <juergen.schmied@metronet.de>
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"
21 #include "winversion.h"
24 #include "debugtools.h"
26 #include "shell32_main.h"
28 DEFAULT_DEBUG_CHANNEL(shell)
30 /*************************************************************************
33 typedef DWORD (* WINAPI GetClassPtr)(REFCLSID,REFIID,LPVOID);
35 static GetClassPtr SH_find_moduleproc(LPSTR dllname,HMODULE *xhmod,LPSTR name)
37 FARPROC dllunload,nameproc;
39 TRACE("dll=%s, hmodule=%p, name=%s\n",dllname, xhmod, name);
45 if (!strcasecmp(PathFindFilenameA(dllname),"shell32.dll"))
46 { return (GetClassPtr)SHELL32_DllGetClassObject;
49 hmod = LoadLibraryExA(dllname,0,LOAD_WITH_ALTERED_SEARCH_PATH);
55 dllunload = GetProcAddress(hmod,"DllCanUnloadNow");
63 nameproc = GetProcAddress(hmod,name);
70 /* register unloadable dll with unloadproc ... */
71 return (GetClassPtr)nameproc;
73 /*************************************************************************
76 static DWORD SH_get_instance(REFCLSID clsid,LPSTR dllname,LPVOID unknownouter,REFIID refiid,LPVOID *ppv)
77 { GetClassPtr dllgetclassob;
79 LPCLASSFACTORY classfac;
81 char xclsid[50],xrefiid[50];
82 WINE_StringFromCLSID((LPCLSID)clsid,xclsid);
83 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
85 TRACE("\n\tCLSID:%s,%s,%p,\n\tIID:%s,%p\n",xclsid, dllname,unknownouter,xrefiid,ppv);
87 dllgetclassob = SH_find_moduleproc(dllname,NULL,"DllGetClassObject");
90 { return 0x80070000|GetLastError();
93 hres = (*dllgetclassob)(clsid,(REFIID)&IID_IClassFactory,&classfac);
95 if ((hres<0) || (hres>=0x80000000))
99 { FIXME("no classfactory, but hres is 0x%ld!\n",hres);
103 IClassFactory_CreateInstance(classfac,unknownouter,refiid,ppv);
104 IClassFactory_Release(classfac);
108 /*************************************************************************
109 * SHCoCreateInstance [SHELL32.102]
112 * exported by ordinal
114 LRESULT WINAPI SHCoCreateInstance(
117 LPUNKNOWN unknownouter,
121 char buffer[256],xclsid[48],xiid[48],path[260],tmodel[100];
123 DWORD pathlen,type,tmodellen;
126 WINE_StringFromCLSID(refiid,xiid);
129 { WINE_StringFromCLSID(clsid,xclsid);
133 { return REGDB_E_CLASSNOTREG;
135 strcpy(xclsid,aclsid);
138 TRACE("(%p,\n\tSID:\t%s,%p,\n\tIID:\t%s,%p)\n",aclsid,xclsid,unknownouter,xiid,ppv);
140 sprintf(buffer,"CLSID\\%s\\InProcServer32",xclsid);
142 if (RegOpenKeyExA(HKEY_CLASSES_ROOT,buffer,0,0x02000000,&inprockey))
143 { return SH_get_instance(clsid,"shell32.dll",unknownouter,refiid,ppv);
145 pathlen=sizeof(path);
147 if (RegQueryValueA(inprockey,NULL,path,&pathlen))
148 { RegCloseKey(inprockey);
149 return SH_get_instance(clsid,"shell32.dll",unknownouter,refiid,ppv);
152 TRACE("Server dll is %s\n",path);
153 tmodellen=sizeof(tmodel);
156 if (RegQueryValueExA(inprockey,"ThreadingModel",NULL,&type,tmodel,&tmodellen))
157 { RegCloseKey(inprockey);
158 return SH_get_instance(clsid,"shell32.dll",unknownouter,refiid,ppv);
161 TRACE("Threading model is %s\n",tmodel);
163 hres=SH_get_instance(clsid,path,unknownouter,refiid,ppv);
164 if (hres<0 || (hres>0x80000000))
165 { hres=SH_get_instance(clsid,"shell32.dll",unknownouter,refiid,ppv);
167 RegCloseKey(inprockey);
169 TRACE("-- interface is %p\n", *ppv);
174 /*************************************************************************
175 * SHELL32_DllGetClassObject [SHELL32.128]
177 * [Standart OLE/COM Interface Method]
178 * This Function retrives the pointer to a specified interface (iid) of
179 * a given class (rclsid).
180 * With this pointer it's possible to call the IClassFactory_CreateInstance
181 * method to get a instance of the requested Class.
182 * This function does NOT instantiate the Class!!!
185 HRESULT WINAPI SHELL32_DllGetClassObject(REFCLSID rclsid, REFIID iid,LPVOID *ppv)
186 { HRESULT hres = E_OUTOFMEMORY;
187 LPCLASSFACTORY lpclf;
189 char xclsid[50],xiid[50];
190 WINE_StringFromCLSID((LPCLSID)rclsid,xclsid);
191 WINE_StringFromCLSID((LPCLSID)iid,xiid);
192 TRACE("\n\tCLSID:\t%s,\n\tIID:\t%s\n",xclsid,xiid);
195 if(IsEqualCLSID(rclsid, &CLSID_ShellDesktop)||
196 IsEqualCLSID(rclsid, &CLSID_ShellLink))
198 lpclf = IClassFactory_Constructor( rclsid );
202 hres = IClassFactory_QueryInterface(lpclf,iid, ppv);
203 IClassFactory_Release(lpclf);
207 { WARN("-- CLSID not found\n");
208 hres = CLASS_E_CLASSNOTAVAILABLE;
210 TRACE("-- pointer to class factory: %p\n",*ppv);
214 /*************************************************************************
215 * SHCLSIDFromString [SHELL32.147]
218 * exported by ordinal
220 DWORD WINAPI SHCLSIDFromString (LPSTR clsid, CLSID *id)
222 TRACE("(%p(%s) %p)\n", clsid, clsid, id);
223 return CLSIDFromString16(clsid, id);
226 /*************************************************************************
227 * SHGetMalloc [SHELL32.220]
228 * returns the interface to shell malloc.
230 * [SDK header win95/shlobj.h:
231 * equivalent to: #define SHGetMalloc(ppmem) CoGetMalloc(MEMCTX_TASK, ppmem)
233 * What we are currently doing is not very wrong, since we always use the same
234 * heap (ProcessHeap).
236 DWORD WINAPI SHGetMalloc(LPMALLOC *lpmal)
237 { TRACE("(%p)\n", lpmal);
238 return CoGetMalloc(0,lpmal);
241 /**************************************************************************
242 * IClassFactory Implementation
247 /* IUnknown fields */
248 ICOM_VTABLE(IClassFactory)* lpvtbl;
253 static ICOM_VTABLE(IClassFactory) clfvt;
255 /**************************************************************************
256 * IClassFactory_Constructor
259 LPCLASSFACTORY IClassFactory_Constructor(REFCLSID rclsid)
261 IClassFactoryImpl* lpclf;
263 lpclf= (IClassFactoryImpl*)HeapAlloc(GetProcessHeap(),0,sizeof(IClassFactoryImpl));
265 lpclf->lpvtbl = &clfvt;
266 lpclf->rclsid = (CLSID*)rclsid;
268 TRACE("(%p)->()\n",lpclf);
270 return (LPCLASSFACTORY)lpclf;
272 /**************************************************************************
273 * IClassFactory_QueryInterface
275 static HRESULT WINAPI IClassFactory_fnQueryInterface(
276 LPCLASSFACTORY iface, REFIID riid, LPVOID *ppvObj)
278 ICOM_THIS(IClassFactoryImpl,iface);
280 WINE_StringFromCLSID((LPCLSID)riid,xriid);
281 TRACE("(%p)->(\n\tIID:\t%s)\n",This,xriid);
285 if(IsEqualIID(riid, &IID_IUnknown)) /*IUnknown*/
288 else if(IsEqualIID(riid, &IID_IClassFactory)) /*IClassFactory*/
289 { *ppvObj = (IClassFactory*)This;
293 { IUnknown_AddRef((LPUNKNOWN)*ppvObj);
294 TRACE("-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
297 TRACE("-- Interface: %s E_NOINTERFACE\n", xriid);
298 return E_NOINTERFACE;
300 /******************************************************************************
301 * IClassFactory_AddRef
303 static ULONG WINAPI IClassFactory_fnAddRef(LPCLASSFACTORY iface)
305 ICOM_THIS(IClassFactoryImpl,iface);
306 TRACE("(%p)->(count=%lu)\n",This,This->ref);
309 return ++(This->ref);
311 /******************************************************************************
312 * IClassFactory_Release
314 static ULONG WINAPI IClassFactory_fnRelease(LPCLASSFACTORY iface)
316 ICOM_THIS(IClassFactoryImpl,iface);
317 TRACE("(%p)->(count=%lu)\n",This,This->ref);
321 { TRACE("-- destroying IClassFactory(%p)\n",This);
322 HeapFree(GetProcessHeap(),0,This);
327 /******************************************************************************
328 * IClassFactory_CreateInstance
330 static HRESULT WINAPI IClassFactory_fnCreateInstance(
331 LPCLASSFACTORY iface, LPUNKNOWN pUnknown, REFIID riid, LPVOID *ppObject)
333 ICOM_THIS(IClassFactoryImpl,iface);
334 IUnknown *pObj = NULL;
338 WINE_StringFromCLSID((LPCLSID)riid,xriid);
339 TRACE("%p->(%p,\n\tIID:\t%s,%p)\n",This,pUnknown,xriid,ppObject);
345 return(CLASS_E_NOAGGREGATION);
348 if (IsEqualCLSID(This->rclsid, &CLSID_ShellDesktop))
350 pObj = (IUnknown *)IShellFolder_Constructor(NULL,NULL);
352 else if (IsEqualCLSID(This->rclsid, &CLSID_ShellLink))
354 pObj = (IUnknown *)IShellLink_Constructor(FALSE);
358 ERR("unknown IID requested\n\tIID:\t%s\n",xriid);
359 return(E_NOINTERFACE);
364 return(E_OUTOFMEMORY);
367 hres = IUnknown_QueryInterface(pObj,riid, ppObject);
368 IUnknown_Release(pObj);
370 TRACE("-- Object created: (%p)->%p\n",This,*ppObject);
374 /******************************************************************************
375 * IClassFactory_LockServer
377 static HRESULT WINAPI IClassFactory_fnLockServer(LPCLASSFACTORY iface, BOOL fLock)
379 ICOM_THIS(IClassFactoryImpl,iface);
380 TRACE("%p->(0x%x), not implemented\n",This, fLock);
384 static ICOM_VTABLE(IClassFactory) clfvt =
386 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
387 IClassFactory_fnQueryInterface,
388 IClassFactory_fnAddRef,
389 IClassFactory_fnRelease,
390 IClassFactory_fnCreateInstance,
391 IClassFactory_fnLockServer