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