2 * handling of SHELL32.DLL OLE-Objects
4 * Copyright 1997 Marcus Meissner
5 * Copyright 1998 Juergen Schmied <juergen.schmied@metronet.de>
21 #include "winversion.h"
24 #include "shell32_main.h"
26 /*************************************************************************
29 typedef DWORD (* WINAPI GetClassPtr
)(REFCLSID
,REFIID
,LPVOID
);
31 static GetClassPtr
SH_find_moduleproc(LPSTR dllname
,HMODULE32
*xhmod
,LPSTR name
)
33 FARPROC32 dllunload
,nameproc
;
35 TRACE(shell
,"dll=%s, hmodule=%p, name=%s\n",dllname
, xhmod
, name
);
39 if (!strcasecmp(PathFindFilename32A(dllname
),"shell32.dll"))
40 { return (GetClassPtr
)SHELL32_DllGetClassObject
;
43 hmod
= LoadLibraryEx32A(dllname
,0,LOAD_WITH_ALTERED_SEARCH_PATH
);
47 dllunload
= GetProcAddress32(hmod
,"DllCanUnloadNow");
53 nameproc
= GetProcAddress32(hmod
,name
);
55 { FreeLibrary32(hmod
);
58 /* register unloadable dll with unloadproc ... */
59 return (GetClassPtr
)nameproc
;
61 /*************************************************************************
64 static DWORD
SH_get_instance(REFCLSID clsid
,LPSTR dllname
,LPVOID unknownouter
,REFIID refiid
,LPVOID inst
)
65 { GetClassPtr dllgetclassob
;
67 LPCLASSFACTORY classfac
;
69 char xclsid
[50],xrefiid
[50];
70 WINE_StringFromCLSID((LPCLSID
)clsid
,xclsid
);
71 WINE_StringFromCLSID((LPCLSID
)refiid
,xrefiid
);
72 TRACE(shell
,"\n\tCLSID:%s,%s,%p,\n\tIID:%s,%p\n",xclsid
, dllname
,unknownouter
,xrefiid
,inst
);
74 dllgetclassob
= SH_find_moduleproc(dllname
,NULL
,"DllGetClassObject");
76 { return 0x80070000|GetLastError();
79 hres
= (*dllgetclassob
)(clsid
,(REFIID
)&IID_IClassFactory
,&classfac
);
80 if ((hres
<0) || (hres
>=0x80000000))
83 { FIXME(shell
,"no classfactory, but hres is 0x%ld!\n",hres
);
86 IClassFactory_CreateInstance(classfac
,unknownouter
,refiid
,inst
);
87 IClassFactory_Release(classfac
);
91 /*************************************************************************
92 * SHCoCreateInstance [SHELL32.102]
97 LRESULT WINAPI
SHCoCreateInstance(LPSTR aclsid
,CLSID
*clsid
,LPUNKNOWN unknownouter
,REFIID refiid
,LPVOID inst
)
98 { char buffer
[256],xclsid
[48],xiid
[48],path
[260],tmodel
[100];
100 DWORD pathlen
,type
,tmodellen
;
103 WINE_StringFromCLSID(refiid
,xiid
);
106 { WINE_StringFromCLSID(clsid
,xclsid
);
112 strcpy(xclsid
,aclsid
);
114 TRACE(shell
,"(%p,\n\tSID:\t%s,%p,\n\tIID:\t%s,%p)\n",aclsid
,xclsid
,unknownouter
,xiid
,inst
);
116 sprintf(buffer
,"CLSID\\%s\\InProcServer32",xclsid
);
118 if (RegOpenKeyEx32A(HKEY_CLASSES_ROOT
,buffer
,0,0x02000000,&inprockey
))
119 { return SH_get_instance(clsid
,"shell32.dll",unknownouter
,refiid
,inst
);
121 pathlen
=sizeof(path
);
123 if (RegQueryValue32A(inprockey
,NULL
,path
,&pathlen
))
124 { RegCloseKey(inprockey
);
125 return SH_get_instance(clsid
,"shell32.dll",unknownouter
,refiid
,inst
);
128 TRACE(shell
, "Server dll is %s\n",path
);
129 tmodellen
=sizeof(tmodel
);
131 if (RegQueryValueEx32A(inprockey
,"ThreadingModel",NULL
,&type
,tmodel
,&tmodellen
))
132 { RegCloseKey(inprockey
);
133 return SH_get_instance(clsid
,"shell32.dll",unknownouter
,refiid
,inst
);
136 TRACE(shell
, "Threading model is %s\n",tmodel
);
138 hres
=SH_get_instance(clsid
,path
,unknownouter
,refiid
,inst
);
139 if (hres
<0 || (hres
>0x80000000))
140 { hres
=SH_get_instance(clsid
,"shell32.dll",unknownouter
,refiid
,inst
);
142 RegCloseKey(inprockey
);
147 /*************************************************************************
148 * SHELL32_DllGetClassObject [SHELL32.128]
150 * [Standart OLE/COM Interface Method]
151 * This Function retrives the pointer to a specified interface (iid) of
152 * a given class (rclsid).
153 * With this pointer it's possible to call the IClassFactory_CreateInstance
154 * method to get a instance of the requested Class.
155 * This function does NOT instantiate the Class!!!
161 DWORD WINAPI
SHELL32_DllGetClassObject(REFCLSID rclsid
,REFIID iid
,LPVOID
*ppv
)
162 { HRESULT hres
= E_OUTOFMEMORY
;
163 LPCLASSFACTORY lpclf
;
165 char xclsid
[50],xiid
[50];
166 WINE_StringFromCLSID((LPCLSID
)rclsid
,xclsid
);
167 WINE_StringFromCLSID((LPCLSID
)iid
,xiid
);
168 TRACE(shell
,"\n\tCLSID:\t%s,\n\tIID:\t%s\n",xclsid
,xiid
);
171 if(IsEqualCLSID(rclsid
, &CLSID_ShellDesktop
)||
172 IsEqualCLSID(rclsid
, &CLSID_ShellLink
))
173 { if(IsEqualCLSID(rclsid
, &CLSID_ShellDesktop
)) /*debug*/
174 { TRACE(shell
,"-- requested CLSID_ShellDesktop\n");
177 if (IsEqualCLSID(rclsid
, &CLSID_ShellLink
))
178 { if (VERSION_OsIsUnicode ())
179 lpclf
= IShellLinkW_CF_Constructor();
181 lpclf
= IShellLink_CF_Constructor();
184 { lpclf
= IClassFactory_Constructor();
188 hres
= IClassFactory_QueryInterface(lpclf
,iid
, ppv
);
189 IClassFactory_Release(lpclf
);
193 { WARN(shell
, "-- CLSID not found\n");
194 hres
= CLASS_E_CLASSNOTAVAILABLE
;
196 TRACE(shell
,"-- pointer to class factory: %p\n",*ppv
);
200 /*************************************************************************
201 * SHGetMalloc [SHELL32.220]
202 * returns the interface to shell malloc.
204 * [SDK header win95/shlobj.h:
205 * equivalent to: #define SHGetMalloc(ppmem) CoGetMalloc(MEMCTX_TASK, ppmem)
207 * What we are currently doing is not very wrong, since we always use the same
208 * heap (ProcessHeap).
210 DWORD WINAPI
SHGetMalloc(LPMALLOC32
*lpmal
)
211 { TRACE(shell
,"(%p)\n", lpmal
);
212 return CoGetMalloc32(0,lpmal
);
215 /**************************************************************************
216 * IClassFactory Implementation
219 static ICOM_VTABLE(IClassFactory
) clfvt
;
221 /**************************************************************************
222 * IClassFactory_Constructor
225 LPCLASSFACTORY
IClassFactory_Constructor(void)
227 _IClassFactory
* lpclf
;
229 lpclf
= (_IClassFactory
*)HeapAlloc(GetProcessHeap(),0,sizeof(_IClassFactory
));
231 lpclf
->lpvtbl
= &clfvt
;
232 TRACE(shell
,"(%p)->()\n",lpclf
);
233 return (LPCLASSFACTORY
)lpclf
;
235 /**************************************************************************
236 * IClassFactory_QueryInterface
238 static HRESULT WINAPI
IClassFactory_fnQueryInterface(
239 LPUNKNOWN iface
, REFIID riid
, LPVOID
*ppvObj
)
241 ICOM_THIS(IClassFactory
,iface
);
243 WINE_StringFromCLSID((LPCLSID
)riid
,xriid
);
244 TRACE(shell
,"(%p)->(\n\tIID:\t%s)\n",this,xriid
);
248 if(IsEqualIID(riid
, &IID_IUnknown
)) /*IUnknown*/
251 else if(IsEqualIID(riid
, &IID_IClassFactory
)) /*IClassFactory*/
252 { *ppvObj
= (IClassFactory
*)this;
256 { IUnknown_AddRef((LPUNKNOWN
)*ppvObj
);
257 TRACE(shell
,"-- Interface: (%p)->(%p)\n",ppvObj
,*ppvObj
);
260 TRACE(shell
,"-- Interface: E_NOINTERFACE\n");
261 return E_NOINTERFACE
;
263 /******************************************************************************
264 * IClassFactory_AddRef
266 static ULONG WINAPI
IClassFactory_fnAddRef(LPUNKNOWN iface
)
268 ICOM_THIS(IClassFactory
,iface
);
269 TRACE(shell
,"(%p)->(count=%lu)\n",this,this->ref
);
270 return ++(this->ref
);
272 /******************************************************************************
273 * IClassFactory_Release
275 static ULONG WINAPI
IClassFactory_fnRelease(LPUNKNOWN iface
)
277 ICOM_THIS(IClassFactory
,iface
);
278 TRACE(shell
,"(%p)->(count=%lu)\n",this,this->ref
);
280 { TRACE(shell
,"-- destroying IClassFactory(%p)\n",this);
281 HeapFree(GetProcessHeap(),0,this);
286 /******************************************************************************
287 * IClassFactory_CreateInstance
289 static HRESULT WINAPI
IClassFactory_fnCreateInstance(
290 LPCLASSFACTORY iface
, LPUNKNOWN pUnknown
, REFIID riid
, LPVOID
*ppObject
)
292 ICOM_THIS(IClassFactory
,iface
);
293 IUnknown
*pObj
= NULL
;
297 WINE_StringFromCLSID((LPCLSID
)riid
,xriid
);
298 TRACE(shell
,"%p->(%p,\n\tIID:\t%s,%p)\n",this,pUnknown
,xriid
,ppObject
);
303 { return(CLASS_E_NOAGGREGATION
);
306 if (IsEqualIID(riid
, &IID_IShellFolder
))
307 { pObj
= (IUnknown
*)IShellFolder_Constructor(NULL
,NULL
);
309 else if (IsEqualIID(riid
, &IID_IShellView
))
310 { pObj
= (IUnknown
*)IShellView_Constructor(NULL
,NULL
);
312 else if (IsEqualIID(riid
, &IID_IExtractIcon
))
313 { pObj
= (IUnknown
*)IExtractIcon_Constructor(NULL
);
315 else if (IsEqualIID(riid
, &IID_IContextMenu
))
316 { pObj
= (IUnknown
*)IContextMenu_Constructor(NULL
, NULL
, 0);
318 else if (IsEqualIID(riid
, &IID_IDataObject
))
319 { pObj
= (IUnknown
*)IDataObject_Constructor(0,NULL
,NULL
,0);
322 { ERR(shell
,"unknown IID requested\n\tIID:\t%s\n",xriid
);
323 return(E_NOINTERFACE
);
327 { return(E_OUTOFMEMORY
);
330 hres
= pObj
->lpvtbl
->fnQueryInterface(pObj
,riid
, ppObject
);
331 pObj
->lpvtbl
->fnRelease(pObj
);
332 TRACE(shell
,"-- Object created: (%p)->%p\n",this,*ppObject
);
336 /******************************************************************************
337 * IClassFactory_LockServer
339 static HRESULT WINAPI
IClassFactory_fnLockServer(LPCLASSFACTORY iface
, BOOL32 fLock
)
341 ICOM_THIS(IClassFactory
,iface
);
342 TRACE(shell
,"%p->(0x%x), not implemented\n",this, fLock
);
346 static ICOM_VTABLE(IClassFactory
) clfvt
=
349 IClassFactory_fnQueryInterface
,
350 IClassFactory_fnAddRef
,
351 IClassFactory_fnRelease
353 IClassFactory_fnCreateInstance
,
354 IClassFactory_fnLockServer