2 * Shell Folder stuff (...and all the OLE-Objects of SHELL32.DLL)
4 * Copyright 1997 Marcus Meissner
5 * Copyright 1998 Juergen Schmied <juergen.schmied@metronet.de>
16 #include "interfaces.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(PathFindFilename(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 classfac
->lpvtbl
->fnCreateInstance(classfac
,unknownouter
,refiid
,inst
);
87 classfac
->lpvtbl
->fnRelease(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");
176 if(IsEqualCLSID(rclsid
, &CLSID_ShellLink
)) /*debug*/
177 { TRACE(shell
,"-- requested CLSID_ShellLink\n");
179 lpclf
= IClassFactory_Constructor();
181 { hres
= lpclf
->lpvtbl
->fnQueryInterface(lpclf
,iid
, ppv
);
182 lpclf
->lpvtbl
->fnRelease(lpclf
);
186 { WARN(shell
, "-- CLSID not found\n");
187 hres
= CLASS_E_CLASSNOTAVAILABLE
;
189 TRACE(shell
,"-- return pointer to interface: %p\n",*ppv
);
193 /*************************************************************************
194 * SHGetMalloc [SHELL32.220]
195 * returns the interface to shell malloc.
197 * [SDK header win95/shlobj.h:
198 * equivalent to: #define SHGetMalloc(ppmem) CoGetMalloc(MEMCTX_TASK, ppmem)
200 * What we are currently doing is not very wrong, since we always use the same
201 * heap (ProcessHeap).
203 DWORD WINAPI
SHGetMalloc(LPMALLOC32
*lpmal
)
204 { TRACE(shell
,"(%p)\n", lpmal
);
205 return CoGetMalloc32(0,lpmal
);
208 /**************************************************************************
209 * IClassFactory Implementation
211 static HRESULT WINAPI
IClassFactory_QueryInterface(LPCLASSFACTORY
,REFIID
,LPVOID
*);
212 static ULONG WINAPI
IClassFactory_AddRef(LPCLASSFACTORY
);
213 static ULONG WINAPI
IClassFactory_Release(LPCLASSFACTORY
);
214 static HRESULT WINAPI
IClassFactory_CreateInstance();
215 static HRESULT WINAPI
IClassFactory_LockServer();
216 /**************************************************************************
217 * IClassFactory_VTable
219 static IClassFactory_VTable clfvt
=
220 { IClassFactory_QueryInterface
,
221 IClassFactory_AddRef
,
222 IClassFactory_Release
,
223 IClassFactory_CreateInstance
,
224 IClassFactory_LockServer
227 /**************************************************************************
228 * IClassFactory_Constructor
231 LPCLASSFACTORY
IClassFactory_Constructor()
232 { LPCLASSFACTORY lpclf
;
234 lpclf
= (LPCLASSFACTORY
)HeapAlloc(GetProcessHeap(),0,sizeof(IClassFactory
));
236 lpclf
->lpvtbl
= &clfvt
;
237 TRACE(shell
,"(%p)->()\n",lpclf
);
240 /**************************************************************************
241 * IClassFactory_QueryInterface
243 static HRESULT WINAPI
IClassFactory_QueryInterface(
244 LPCLASSFACTORY
this, REFIID riid
, LPVOID
*ppvObj
)
246 WINE_StringFromCLSID((LPCLSID
)riid
,xriid
);
247 TRACE(shell
,"(%p)->(\n\tIID:\t%s)\n",this,xriid
);
251 if(IsEqualIID(riid
, &IID_IUnknown
)) /*IUnknown*/
254 else if(IsEqualIID(riid
, &IID_IClassFactory
)) /*IClassFactory*/
255 { *ppvObj
= (IClassFactory
*)this;
259 { (*(LPCLASSFACTORY
*)ppvObj
)->lpvtbl
->fnAddRef(this);
260 TRACE(shell
,"-- Interface: (%p)->(%p)\n",ppvObj
,*ppvObj
);
263 TRACE(shell
,"-- Interface: E_NOINTERFACE\n");
264 return E_NOINTERFACE
;
266 /******************************************************************************
267 * IClassFactory_AddRef
269 static ULONG WINAPI
IClassFactory_AddRef(LPCLASSFACTORY
this)
270 { TRACE(shell
,"(%p)->(count=%lu)\n",this,this->ref
);
271 return ++(this->ref
);
273 /******************************************************************************
274 * IClassFactory_Release
276 static ULONG WINAPI
IClassFactory_Release(LPCLASSFACTORY
this)
277 { TRACE(shell
,"(%p)->(count=%lu)\n",this,this->ref
);
279 { TRACE(shell
,"-- destroying IClassFactory(%p)\n",this);
280 HeapFree(GetProcessHeap(),0,this);
285 /******************************************************************************
286 * IClassFactory_CreateInstance
288 static HRESULT WINAPI
IClassFactory_CreateInstance(
289 LPCLASSFACTORY
this, LPUNKNOWN pUnknown
, REFIID riid
, LPVOID
*ppObject
)
290 { IUnknown
*pObj
= NULL
;
294 WINE_StringFromCLSID((LPCLSID
)riid
,xriid
);
295 TRACE(shell
,"%p->(%p,\n\tIID:\t%s,%p)\n",this,pUnknown
,xriid
,ppObject
);
300 { return(CLASS_E_NOAGGREGATION
);
303 if (IsEqualIID(riid
, &IID_IShellFolder
))
304 { pObj
= (IUnknown
*)IShellFolder_Constructor(NULL
,NULL
);
306 else if (IsEqualIID(riid
, &IID_IShellView
))
307 { pObj
= (IUnknown
*)IShellView_Constructor(NULL
,NULL
);
309 else if (IsEqualIID(riid
, &IID_IShellLink
))
310 { pObj
= (IUnknown
*)IShellLink_Constructor();
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();
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_LockServer(LPCLASSFACTORY
this, BOOL32 fLock
)
340 { TRACE(shell
,"%p->(0x%x), not implemented\n",this, fLock
);