Large-scale renaming of all Win32 functions and types to use the
[wine/multimedia.git] / dlls / shell32 / shellole.c
blobf34435d3a36c0e9b43a2943c2d4d9f33c53e4b81
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>
11 #include "winreg.h"
12 #include "winerror.h"
13 #include "wine/obj_base.h"
14 #include "winversion.h"
16 #include "shlguid.h"
17 #include "shlobj.h"
18 #include "shell32_main.h"
20 #include "debug.h"
22 /*************************************************************************
25 typedef DWORD (* WINAPI GetClassPtr)(REFCLSID,REFIID,LPVOID);
27 static GetClassPtr SH_find_moduleproc(LPSTR dllname,HMODULE *xhmod,LPSTR name)
28 { HMODULE hmod;
29 FARPROC dllunload,nameproc;
31 TRACE(shell,"dll=%s, hmodule=%p, name=%s\n",dllname, xhmod, name);
32 if (xhmod)
33 { *xhmod = 0;
35 if (!strcasecmp(PathFindFilenameA(dllname),"shell32.dll"))
36 { return (GetClassPtr)SHELL32_DllGetClassObject;
39 hmod = LoadLibraryExA(dllname,0,LOAD_WITH_ALTERED_SEARCH_PATH);
40 if (!hmod)
41 { return NULL;
43 dllunload = GetProcAddress(hmod,"DllCanUnloadNow");
44 if (!dllunload)
45 { if (xhmod)
46 { *xhmod = hmod;
49 nameproc = GetProcAddress(hmod,name);
50 if (!nameproc)
51 { FreeLibrary(hmod);
52 return NULL;
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;
62 DWORD hres;
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");
71 if (!dllgetclassob)
72 { return 0x80070000|GetLastError();
75 hres = (*dllgetclassob)(clsid,(REFIID)&IID_IClassFactory,&classfac);
76 if ((hres<0) || (hres>=0x80000000))
77 return hres;
78 if (!classfac)
79 { FIXME(shell,"no classfactory, but hres is 0x%ld!\n",hres);
80 return E_FAIL;
82 IClassFactory_CreateInstance(classfac,unknownouter,refiid,inst);
83 IClassFactory_Release(classfac);
84 return 0;
87 /*************************************************************************
88 * SHCoCreateInstance [SHELL32.102]
90 * NOTES
91 * exported by ordinal
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];
95 HKEY inprockey;
96 DWORD pathlen,type,tmodellen;
97 DWORD hres;
99 WINE_StringFromCLSID(refiid,xiid);
101 if (clsid)
102 { WINE_StringFromCLSID(clsid,xclsid);
104 else
105 { if (!aclsid)
106 { return 0x80040154;
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);
126 type=REG_SZ;
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);
139 return hres;
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!!!
153 * RETURNS
154 * HRESULT
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);
166 *ppv = NULL;
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();
176 else
177 lpclf = IShellLink_CF_Constructor();
179 else
180 { lpclf = IClassFactory_Constructor();
183 if(lpclf) {
184 hres = IClassFactory_QueryInterface(lpclf,iid, ppv);
185 IClassFactory_Release(lpclf);
188 else
189 { WARN(shell, "-- CLSID not found\n");
190 hres = CLASS_E_CLASSNOTAVAILABLE;
192 TRACE(shell,"-- pointer to class factory: %p\n",*ppv);
193 return hres;
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
215 typedef struct
217 /* IUnknown fields */
218 ICOM_VTABLE(IClassFactory)* lpvtbl;
219 DWORD ref;
220 } IClassFactoryImpl;
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));
233 lpclf->ref = 1;
234 lpclf->lpvtbl = &clfvt;
236 TRACE(shell,"(%p)->()\n",lpclf);
237 shell32_ObjCount++;
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);
247 char xriid[50];
248 WINE_StringFromCLSID((LPCLSID)riid,xriid);
249 TRACE(shell,"(%p)->(\n\tIID:\t%s)\n",This,xriid);
251 *ppvObj = NULL;
253 if(IsEqualIID(riid, &IID_IUnknown)) /*IUnknown*/
254 { *ppvObj = This;
256 else if(IsEqualIID(riid, &IID_IClassFactory)) /*IClassFactory*/
257 { *ppvObj = (IClassFactory*)This;
260 if(*ppvObj)
261 { IUnknown_AddRef((LPUNKNOWN)*ppvObj);
262 TRACE(shell,"-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
263 return S_OK;
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);
276 shell32_ObjCount++;
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);
287 shell32_ObjCount--;
288 if (!--(This->ref))
289 { TRACE(shell,"-- destroying IClassFactory(%p)\n",This);
290 HeapFree(GetProcessHeap(),0,This);
291 return 0;
293 return This->ref;
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;
303 HRESULT hres;
304 char xriid[50];
306 WINE_StringFromCLSID((LPCLSID)riid,xriid);
307 TRACE(shell,"%p->(%p,\n\tIID:\t%s,%p)\n",This,pUnknown,xriid,ppObject);
309 *ppObject = NULL;
311 if(pUnknown)
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);
330 else
331 { ERR(shell,"unknown IID requested\n\tIID:\t%s\n",xriid);
332 return(E_NOINTERFACE);
335 if (!pObj)
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);
343 return hres;
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);
352 return E_NOTIMPL;
355 static ICOM_VTABLE(IClassFactory) clfvt =
357 IClassFactory_fnQueryInterface,
358 IClassFactory_fnAddRef,
359 IClassFactory_fnRelease,
360 IClassFactory_fnCreateInstance,
361 IClassFactory_fnLockServer