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