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
impl_from_IProvideClassInfo(IProvideClassInfo * iface)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
scrruncf_QueryInterface(IClassFactory * iface,REFIID riid,LPVOID * ppv)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
scrruncf_AddRef(IClassFactory * iface)66 static ULONG WINAPI scrruncf_AddRef(IClassFactory *iface )
67 {
68 TRACE("(%p)\n", iface);
69 return 2;
70 }
71
scrruncf_Release(IClassFactory * iface)72 static ULONG WINAPI scrruncf_Release(IClassFactory *iface )
73 {
74 TRACE("(%p)\n", iface);
75 return 1;
76 }
77
scrruncf_LockServer(IClassFactory * iface,BOOL fLock)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
load_typelib(void)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
get_typeinfo_of_guid(const GUID * guid,ITypeInfo ** tinfo)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
get_typeinfo(tid_t tid,ITypeInfo ** typeinfo)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
release_typelib(void)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
provideclassinfo_QueryInterface(IProvideClassInfo * iface,REFIID riid,void ** obj)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
provideclassinfo_AddRef(IProvideClassInfo * iface)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
provideclassinfo_Release(IProvideClassInfo * iface)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
provideclassinfo_GetClassInfo(IProvideClassInfo * iface,ITypeInfo ** ti)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
init_classinfo(const GUID * guid,IUnknown * outer,struct provideclassinfo * classinfo)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
DllMain(HINSTANCE hinst,DWORD reason,LPVOID reserved)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 */
DllRegisterServer(void)262 HRESULT WINAPI DllRegisterServer(void)
263 {
264 TRACE("()\n");
265 return __wine_register_resources(scrrun_instance);
266 }
267
268 /***********************************************************************
269 * DllUnregisterServer (scrrun.@)
270 */
DllUnregisterServer(void)271 HRESULT WINAPI DllUnregisterServer(void)
272 {
273 TRACE("()\n");
274 return __wine_unregister_resources(scrrun_instance);
275 }
276
277 /***********************************************************************
278 * DllGetClassObject (scrrun.@)
279 */
280
DllGetClassObject(REFCLSID rclsid,REFIID riid,LPVOID * ppv)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 */
DllCanUnloadNow(void)299 HRESULT WINAPI DllCanUnloadNow(void)
300 {
301 return S_FALSE;
302 }
303