2 * handling of SHELL32.DLL OLE-Objects
4 * Copyright 1997 Marcus Meissner
5 * Copyright 1998 Juergen Schmied <juergen.schmied@metronet.de>
13 #include "wine/obj_base.h"
14 #include "winversion.h"
18 #include "shell32_main.h"
22 /*************************************************************************
25 typedef DWORD (* WINAPI GetClassPtr
)(REFCLSID
,REFIID
,LPVOID
);
27 static GetClassPtr
SH_find_moduleproc(LPSTR dllname
,HMODULE
*xhmod
,LPSTR name
)
29 FARPROC dllunload
,nameproc
;
31 TRACE(shell
,"dll=%s, hmodule=%p, name=%s\n",dllname
, xhmod
, name
);
35 if (!strcasecmp(PathFindFilenameA(dllname
),"shell32.dll"))
36 { return (GetClassPtr
)SHELL32_DllGetClassObject
;
39 hmod
= LoadLibraryExA(dllname
,0,LOAD_WITH_ALTERED_SEARCH_PATH
);
43 dllunload
= GetProcAddress(hmod
,"DllCanUnloadNow");
49 nameproc
= GetProcAddress(hmod
,name
);
54 /* register unloadable dll with unloadproc ... */
55 return (GetClassPtr
)nameproc
;
57 /*************************************************************************
60 static DWORD
SH_get_instance(REFCLSID clsid
,LPSTR dllname
,LPVOID unknownouter
,REFIID refiid
,LPVOID inst
)
61 { GetClassPtr dllgetclassob
;
63 LPCLASSFACTORY classfac
;
65 char xclsid
[50],xrefiid
[50];
66 WINE_StringFromCLSID((LPCLSID
)clsid
,xclsid
);
67 WINE_StringFromCLSID((LPCLSID
)refiid
,xrefiid
);
68 TRACE(shell
,"\n\tCLSID:%s,%s,%p,\n\tIID:%s,%p\n",xclsid
, dllname
,unknownouter
,xrefiid
,inst
);
70 dllgetclassob
= SH_find_moduleproc(dllname
,NULL
,"DllGetClassObject");
72 { return 0x80070000|GetLastError();
75 hres
= (*dllgetclassob
)(clsid
,(REFIID
)&IID_IClassFactory
,&classfac
);
76 if ((hres
<0) || (hres
>=0x80000000))
79 { FIXME(shell
,"no classfactory, but hres is 0x%ld!\n",hres
);
82 IClassFactory_CreateInstance(classfac
,unknownouter
,refiid
,inst
);
83 IClassFactory_Release(classfac
);
87 /*************************************************************************
88 * SHCoCreateInstance [SHELL32.102]
93 LRESULT WINAPI
SHCoCreateInstance(LPSTR aclsid
,CLSID
*clsid
,LPUNKNOWN unknownouter
,REFIID refiid
,LPVOID inst
)
94 { char buffer
[256],xclsid
[48],xiid
[48],path
[260],tmodel
[100];
96 DWORD pathlen
,type
,tmodellen
;
99 WINE_StringFromCLSID(refiid
,xiid
);
102 { WINE_StringFromCLSID(clsid
,xclsid
);
108 strcpy(xclsid
,aclsid
);
110 TRACE(shell
,"(%p,\n\tSID:\t%s,%p,\n\tIID:\t%s,%p)\n",aclsid
,xclsid
,unknownouter
,xiid
,inst
);
112 sprintf(buffer
,"CLSID\\%s\\InProcServer32",xclsid
);
114 if (RegOpenKeyExA(HKEY_CLASSES_ROOT
,buffer
,0,0x02000000,&inprockey
))
115 { return SH_get_instance(clsid
,"shell32.dll",unknownouter
,refiid
,inst
);
117 pathlen
=sizeof(path
);
119 if (RegQueryValueA(inprockey
,NULL
,path
,&pathlen
))
120 { RegCloseKey(inprockey
);
121 return SH_get_instance(clsid
,"shell32.dll",unknownouter
,refiid
,inst
);
124 TRACE(shell
, "Server dll is %s\n",path
);
125 tmodellen
=sizeof(tmodel
);
127 if (RegQueryValueExA(inprockey
,"ThreadingModel",NULL
,&type
,tmodel
,&tmodellen
))
128 { RegCloseKey(inprockey
);
129 return SH_get_instance(clsid
,"shell32.dll",unknownouter
,refiid
,inst
);
132 TRACE(shell
, "Threading model is %s\n",tmodel
);
134 hres
=SH_get_instance(clsid
,path
,unknownouter
,refiid
,inst
);
135 if (hres
<0 || (hres
>0x80000000))
136 { hres
=SH_get_instance(clsid
,"shell32.dll",unknownouter
,refiid
,inst
);
138 RegCloseKey(inprockey
);
143 /*************************************************************************
144 * SHELL32_DllGetClassObject [SHELL32.128]
146 * [Standart OLE/COM Interface Method]
147 * This Function retrives the pointer to a specified interface (iid) of
148 * a given class (rclsid).
149 * With this pointer it's possible to call the IClassFactory_CreateInstance
150 * method to get a instance of the requested Class.
151 * This function does NOT instantiate the Class!!!
157 DWORD WINAPI
SHELL32_DllGetClassObject(REFCLSID rclsid
,REFIID iid
,LPVOID
*ppv
)
158 { HRESULT hres
= E_OUTOFMEMORY
;
159 LPCLASSFACTORY lpclf
;
161 char xclsid
[50],xiid
[50];
162 WINE_StringFromCLSID((LPCLSID
)rclsid
,xclsid
);
163 WINE_StringFromCLSID((LPCLSID
)iid
,xiid
);
164 TRACE(shell
,"\n\tCLSID:\t%s,\n\tIID:\t%s\n",xclsid
,xiid
);
167 if(IsEqualCLSID(rclsid
, &CLSID_ShellDesktop
)||
168 IsEqualCLSID(rclsid
, &CLSID_ShellLink
))
169 { if(IsEqualCLSID(rclsid
, &CLSID_ShellDesktop
)) /*debug*/
170 { TRACE(shell
,"-- requested CLSID_ShellDesktop\n");
173 if (IsEqualCLSID(rclsid
, &CLSID_ShellLink
))
174 { if (VERSION_OsIsUnicode ())
175 lpclf
= IShellLinkW_CF_Constructor();
177 lpclf
= IShellLink_CF_Constructor();
180 { lpclf
= IClassFactory_Constructor();
184 hres
= IClassFactory_QueryInterface(lpclf
,iid
, ppv
);
185 IClassFactory_Release(lpclf
);
189 { WARN(shell
, "-- CLSID not found\n");
190 hres
= CLASS_E_CLASSNOTAVAILABLE
;
192 TRACE(shell
,"-- pointer to class factory: %p\n",*ppv
);
196 /*************************************************************************
197 * SHGetMalloc [SHELL32.220]
198 * returns the interface to shell malloc.
200 * [SDK header win95/shlobj.h:
201 * equivalent to: #define SHGetMalloc(ppmem) CoGetMalloc(MEMCTX_TASK, ppmem)
203 * What we are currently doing is not very wrong, since we always use the same
204 * heap (ProcessHeap).
206 DWORD WINAPI
SHGetMalloc(LPMALLOC
*lpmal
)
207 { TRACE(shell
,"(%p)\n", lpmal
);
208 return CoGetMalloc(0,lpmal
);
211 /**************************************************************************
212 * IClassFactory Implementation
217 /* IUnknown fields */
218 ICOM_VTABLE(IClassFactory
)* lpvtbl
;
222 static ICOM_VTABLE(IClassFactory
) clfvt
;
224 /**************************************************************************
225 * IClassFactory_Constructor
228 LPCLASSFACTORY
IClassFactory_Constructor(void)
230 IClassFactoryImpl
* lpclf
;
232 lpclf
= (IClassFactoryImpl
*)HeapAlloc(GetProcessHeap(),0,sizeof(IClassFactoryImpl
));
234 lpclf
->lpvtbl
= &clfvt
;
236 TRACE(shell
,"(%p)->()\n",lpclf
);
238 return (LPCLASSFACTORY
)lpclf
;
240 /**************************************************************************
241 * IClassFactory_QueryInterface
243 static HRESULT WINAPI
IClassFactory_fnQueryInterface(
244 LPCLASSFACTORY iface
, REFIID riid
, LPVOID
*ppvObj
)
246 ICOM_THIS(IClassFactoryImpl
,iface
);
248 WINE_StringFromCLSID((LPCLSID
)riid
,xriid
);
249 TRACE(shell
,"(%p)->(\n\tIID:\t%s)\n",This
,xriid
);
253 if(IsEqualIID(riid
, &IID_IUnknown
)) /*IUnknown*/
256 else if(IsEqualIID(riid
, &IID_IClassFactory
)) /*IClassFactory*/
257 { *ppvObj
= (IClassFactory
*)This
;
261 { IUnknown_AddRef((LPUNKNOWN
)*ppvObj
);
262 TRACE(shell
,"-- Interface: (%p)->(%p)\n",ppvObj
,*ppvObj
);
265 TRACE(shell
,"-- Interface: E_NOINTERFACE\n");
266 return E_NOINTERFACE
;
268 /******************************************************************************
269 * IClassFactory_AddRef
271 static ULONG WINAPI
IClassFactory_fnAddRef(LPCLASSFACTORY iface
)
273 ICOM_THIS(IClassFactoryImpl
,iface
);
274 TRACE(shell
,"(%p)->(count=%lu)\n",This
,This
->ref
);
277 return ++(This
->ref
);
279 /******************************************************************************
280 * IClassFactory_Release
282 static ULONG WINAPI
IClassFactory_fnRelease(LPCLASSFACTORY iface
)
284 ICOM_THIS(IClassFactoryImpl
,iface
);
285 TRACE(shell
,"(%p)->(count=%lu)\n",This
,This
->ref
);
289 { TRACE(shell
,"-- destroying IClassFactory(%p)\n",This
);
290 HeapFree(GetProcessHeap(),0,This
);
295 /******************************************************************************
296 * IClassFactory_CreateInstance
298 static HRESULT WINAPI
IClassFactory_fnCreateInstance(
299 LPCLASSFACTORY iface
, LPUNKNOWN pUnknown
, REFIID riid
, LPVOID
*ppObject
)
301 ICOM_THIS(IClassFactoryImpl
,iface
);
302 IUnknown
*pObj
= NULL
;
306 WINE_StringFromCLSID((LPCLSID
)riid
,xriid
);
307 TRACE(shell
,"%p->(%p,\n\tIID:\t%s,%p)\n",This
,pUnknown
,xriid
,ppObject
);
312 { return(CLASS_E_NOAGGREGATION
);
315 if (IsEqualIID(riid
, &IID_IShellFolder
))
316 { pObj
= (IUnknown
*)IShellFolder_Constructor(NULL
,NULL
);
318 else if (IsEqualIID(riid
, &IID_IShellView
))
319 { pObj
= (IUnknown
*)IShellView_Constructor(NULL
,NULL
);
321 else if (IsEqualIID(riid
, &IID_IExtractIcon
))
322 { pObj
= (IUnknown
*)IExtractIcon_Constructor(NULL
);
324 else if (IsEqualIID(riid
, &IID_IContextMenu
))
325 { pObj
= (IUnknown
*)IContextMenu_Constructor(NULL
, NULL
, 0);
327 else if (IsEqualIID(riid
, &IID_IDataObject
))
328 { pObj
= (IUnknown
*)IDataObject_Constructor(0,NULL
,NULL
,0);
331 { ERR(shell
,"unknown IID requested\n\tIID:\t%s\n",xriid
);
332 return(E_NOINTERFACE
);
336 { return(E_OUTOFMEMORY
);
339 hres
= pObj
->lpvtbl
->fnQueryInterface(pObj
,riid
, ppObject
);
340 pObj
->lpvtbl
->fnRelease(pObj
);
341 TRACE(shell
,"-- Object created: (%p)->%p\n",This
,*ppObject
);
345 /******************************************************************************
346 * IClassFactory_LockServer
348 static HRESULT WINAPI
IClassFactory_fnLockServer(LPCLASSFACTORY iface
, BOOL fLock
)
350 ICOM_THIS(IClassFactoryImpl
,iface
);
351 TRACE(shell
,"%p->(0x%x), not implemented\n",This
, fLock
);
355 static ICOM_VTABLE(IClassFactory
) clfvt
=
357 IClassFactory_fnQueryInterface
,
358 IClassFactory_fnAddRef
,
359 IClassFactory_fnRelease
,
360 IClassFactory_fnCreateInstance
,
361 IClassFactory_fnLockServer