xref: /reactos/dll/win32/scrrun/scrrun.c (revision 7115d7ba)
1 /*
2  * Copyright 2011 Hans Leidekker for CodeWeavers
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17  */
18 #define COBJMACROS
19 
20 #include <stdarg.h>
21 
22 #include "windef.h"
23 #include "winbase.h"
24 #include "ole2.h"
25 #include "olectl.h"
26 #include "rpcproxy.h"
27 
28 #include <initguid.h>
29 #include "scrrun.h"
30 #include "scrrun_private.h"
31 
32 #include "wine/debug.h"
33 
34 WINE_DEFAULT_DEBUG_CHANNEL(scrrun);
35 
36 static HINSTANCE scrrun_instance;
37 
38 static inline struct provideclassinfo *impl_from_IProvideClassInfo(IProvideClassInfo *iface)
39 {
40     return CONTAINING_RECORD(iface, struct provideclassinfo, IProvideClassInfo_iface);
41 }
42 
43 typedef HRESULT (*fnCreateInstance)(LPVOID *ppObj);
44 
45 static HRESULT WINAPI scrruncf_QueryInterface(IClassFactory *iface, REFIID riid, LPVOID *ppv )
46 {
47     *ppv = NULL;
48 
49     if(IsEqualGUID(&IID_IUnknown, riid)) {
50         TRACE("(%p)->(IID_IUnknown %p)\n", iface, ppv);
51         *ppv = iface;
52     }else if(IsEqualGUID(&IID_IClassFactory, riid)) {
53         TRACE("(%p)->(IID_IClassFactory %p)\n", iface, ppv);
54         *ppv = iface;
55     }
56 
57     if(*ppv) {
58         IUnknown_AddRef((IUnknown*)*ppv);
59         return S_OK;
60     }
61 
62     WARN("(%p)->(%s %p)\n", iface, debugstr_guid(riid), ppv);
63     return E_NOINTERFACE;
64 }
65 
66 static ULONG WINAPI scrruncf_AddRef(IClassFactory *iface )
67 {
68     TRACE("(%p)\n", iface);
69     return 2;
70 }
71 
72 static ULONG WINAPI scrruncf_Release(IClassFactory *iface )
73 {
74     TRACE("(%p)\n", iface);
75     return 1;
76 }
77 
78 static HRESULT WINAPI scrruncf_LockServer(IClassFactory *iface, BOOL fLock)
79 {
80     TRACE("(%p)->(%x)\n", iface, fLock);
81     return S_OK;
82 }
83 
84 static const struct IClassFactoryVtbl scrruncf_vtbl =
85 {
86     scrruncf_QueryInterface,
87     scrruncf_AddRef,
88     scrruncf_Release,
89     FileSystem_CreateInstance,
90     scrruncf_LockServer
91 };
92 
93 static const struct IClassFactoryVtbl dictcf_vtbl =
94 {
95     scrruncf_QueryInterface,
96     scrruncf_AddRef,
97     scrruncf_Release,
98     Dictionary_CreateInstance,
99     scrruncf_LockServer
100 };
101 
102 static IClassFactory FileSystemFactory = { &scrruncf_vtbl };
103 static IClassFactory DictionaryFactory = { &dictcf_vtbl };
104 
105 static ITypeLib *typelib;
106 static ITypeInfo *typeinfos[LAST_tid];
107 
108 static REFIID tid_ids[] = {
109     &IID_NULL,
110     &IID_IDictionary,
111     &IID_IDrive,
112     &IID_IDriveCollection,
113     &IID_IFile,
114     &IID_IFileCollection,
115     &IID_IFileSystem3,
116     &IID_IFolder,
117     &IID_IFolderCollection,
118     &IID_ITextStream
119 };
120 
121 static HRESULT load_typelib(void)
122 {
123     HRESULT hres;
124     ITypeLib *tl;
125 
126     if(typelib)
127         return S_OK;
128 
129     hres = LoadRegTypeLib(&LIBID_Scripting, 1, 0, LOCALE_SYSTEM_DEFAULT, &tl);
130     if(FAILED(hres)) {
131         ERR("LoadRegTypeLib failed: %08x\n", hres);
132         return hres;
133     }
134 
135     if(InterlockedCompareExchangePointer((void**)&typelib, tl, NULL))
136         ITypeLib_Release(tl);
137     return hres;
138 }
139 
140 static HRESULT get_typeinfo_of_guid(const GUID *guid, ITypeInfo **tinfo)
141 {
142     HRESULT hres;
143 
144     if(FAILED(hres = load_typelib()))
145         return hres;
146 
147     return ITypeLib_GetTypeInfoOfGuid(typelib, guid, tinfo);
148 }
149 
150 HRESULT get_typeinfo(tid_t tid, ITypeInfo **typeinfo)
151 {
152     HRESULT hres;
153 
154     if (FAILED(hres = load_typelib()))
155         return hres;
156 
157     if(!typeinfos[tid]) {
158         ITypeInfo *ti;
159 
160         hres = ITypeLib_GetTypeInfoOfGuid(typelib, tid_ids[tid], &ti);
161         if(FAILED(hres)) {
162             ERR("GetTypeInfoOfGuid(%s) failed: %08x\n", debugstr_guid(tid_ids[tid]), hres);
163             return hres;
164         }
165 
166         if(InterlockedCompareExchangePointer((void**)(typeinfos+tid), ti, NULL))
167             ITypeInfo_Release(ti);
168     }
169 
170     *typeinfo = typeinfos[tid];
171     ITypeInfo_AddRef(typeinfos[tid]);
172     return S_OK;
173 }
174 
175 static void release_typelib(void)
176 {
177     unsigned i;
178 
179     if(!typelib)
180         return;
181 
182     for (i = 0; i < ARRAY_SIZE(typeinfos); i++)
183         if(typeinfos[i])
184             ITypeInfo_Release(typeinfos[i]);
185 
186     ITypeLib_Release(typelib);
187 }
188 
189 static HRESULT WINAPI provideclassinfo_QueryInterface(IProvideClassInfo *iface, REFIID riid, void **obj)
190 {
191     struct provideclassinfo *This = impl_from_IProvideClassInfo(iface);
192 
193     TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), obj);
194 
195     if (IsEqualIID(riid, &IID_IProvideClassInfo)) {
196         *obj = iface;
197         IProvideClassInfo_AddRef(iface);
198         return S_OK;
199     }
200     else
201         return IUnknown_QueryInterface(This->outer, riid, obj);
202 }
203 
204 static ULONG WINAPI provideclassinfo_AddRef(IProvideClassInfo *iface)
205 {
206     struct provideclassinfo *This = impl_from_IProvideClassInfo(iface);
207     return IUnknown_AddRef(This->outer);
208 }
209 
210 static ULONG WINAPI provideclassinfo_Release(IProvideClassInfo *iface)
211 {
212     struct provideclassinfo *This = impl_from_IProvideClassInfo(iface);
213     return IUnknown_Release(This->outer);
214 }
215 
216 static HRESULT WINAPI provideclassinfo_GetClassInfo(IProvideClassInfo *iface, ITypeInfo **ti)
217 {
218     struct provideclassinfo *This = impl_from_IProvideClassInfo(iface);
219 
220     TRACE("(%p)->(%p)\n", This, ti);
221 
222     return get_typeinfo_of_guid(This->guid, ti);
223 }
224 
225 static const IProvideClassInfoVtbl provideclassinfovtbl = {
226     provideclassinfo_QueryInterface,
227     provideclassinfo_AddRef,
228     provideclassinfo_Release,
229     provideclassinfo_GetClassInfo
230 };
231 
232 void init_classinfo(const GUID *guid, IUnknown *outer, struct provideclassinfo *classinfo)
233 {
234     classinfo->IProvideClassInfo_iface.lpVtbl = &provideclassinfovtbl;
235     classinfo->outer = outer;
236     classinfo->guid = guid;
237 }
238 
239 BOOL WINAPI DllMain( HINSTANCE hinst, DWORD reason, LPVOID reserved )
240 {
241     TRACE("%p, %u, %p\n", hinst, reason, reserved);
242 
243     switch (reason)
244     {
245         case DLL_WINE_PREATTACH:
246             return FALSE;    /* prefer native version */
247         case DLL_PROCESS_ATTACH:
248             DisableThreadLibraryCalls( hinst );
249             scrrun_instance = hinst;
250             break;
251         case DLL_PROCESS_DETACH:
252             if (reserved) break;
253             release_typelib();
254             break;
255     }
256     return TRUE;
257 }
258 
259 /***********************************************************************
260  *      DllRegisterServer (scrrun.@)
261  */
262 HRESULT WINAPI DllRegisterServer(void)
263 {
264     TRACE("()\n");
265     return __wine_register_resources(scrrun_instance);
266 }
267 
268 /***********************************************************************
269  *      DllUnregisterServer (scrrun.@)
270  */
271 HRESULT WINAPI DllUnregisterServer(void)
272 {
273     TRACE("()\n");
274     return __wine_unregister_resources(scrrun_instance);
275 }
276 
277 /***********************************************************************
278  *      DllGetClassObject (scrrun.@)
279  */
280 
281 HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv)
282 {
283     if(IsEqualGUID(&CLSID_FileSystemObject, rclsid)) {
284         TRACE("(CLSID_FileSystemObject %s %p)\n", debugstr_guid(riid), ppv);
285         return IClassFactory_QueryInterface(&FileSystemFactory, riid, ppv);
286     }
287     else if(IsEqualGUID(&CLSID_Dictionary, rclsid)) {
288         TRACE("(CLSID_Dictionary %s %p)\n", debugstr_guid(riid), ppv);
289         return IClassFactory_QueryInterface(&DictionaryFactory, riid, ppv);
290     }
291 
292     FIXME("%s %s %p\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);
293     return CLASS_E_CLASSNOTAVAILABLE;
294 }
295 
296 /***********************************************************************
297  *      DllCanUnloadNow (scrrun.@)
298  */
299 HRESULT WINAPI DllCanUnloadNow(void)
300 {
301     return S_FALSE;
302 }
303