* Sync up to trunk head (r64377).
[reactos.git] / dll / win32 / ieframe / ieframe_main.c
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 "ieframe.h"
20
21 #include <rpcproxy.h>
22
23 LONG module_ref = 0;
24 HINSTANCE ieframe_instance;
25
26 static ITypeLib *typelib;
27 static ITypeInfo *typeinfos[LAST_tid];
28
29 static REFIID tid_ids[] = {
30 #define XIID(iface) &IID_ ## iface,
31 #define XCLSID(class) &CLSID_ ## class,
32 TID_LIST
33 #undef XIID
34 #undef XCLSID
35 };
36
37 static HRESULT load_typelib(void)
38 {
39 HRESULT hres;
40 ITypeLib *tl;
41
42 hres = LoadRegTypeLib(&LIBID_SHDocVw, 1, 1, LOCALE_SYSTEM_DEFAULT, &tl);
43 if(FAILED(hres)) {
44 ERR("LoadRegTypeLib failed: %08x\n", hres);
45 return hres;
46 }
47
48 if(InterlockedCompareExchangePointer((void**)&typelib, tl, NULL))
49 ITypeLib_Release(tl);
50 return hres;
51 }
52
53 HRESULT get_typeinfo(tid_t tid, ITypeInfo **typeinfo)
54 {
55 HRESULT hres;
56
57 if(!typelib)
58 hres = load_typelib();
59 if(!typelib)
60 return hres;
61
62 if(!typeinfos[tid]) {
63 ITypeInfo *ti;
64
65 hres = ITypeLib_GetTypeInfoOfGuid(typelib, tid_ids[tid], &ti);
66 if(FAILED(hres)) {
67 ERR("GetTypeInfoOfGuid(%s) failed: %08x\n", debugstr_guid(tid_ids[tid]), hres);
68 return hres;
69 }
70
71 if(InterlockedCompareExchangePointer((void**)(typeinfos+tid), ti, NULL))
72 ITypeInfo_Release(ti);
73 }
74
75 *typeinfo = typeinfos[tid];
76 return S_OK;
77 }
78
79 static void release_typelib(void)
80 {
81 unsigned i;
82
83 if(!typelib)
84 return;
85
86 for(i=0; i < sizeof(typeinfos)/sizeof(*typeinfos); i++) {
87 if(typeinfos[i])
88 ITypeInfo_Release(typeinfos[i]);
89 }
90
91 ITypeLib_Release(typelib);
92 }
93
94 static HRESULT WINAPI ClassFactory_QueryInterface(IClassFactory *iface, REFIID riid, void **ppv)
95 {
96 *ppv = NULL;
97
98 if(IsEqualGUID(&IID_IUnknown, riid)) {
99 TRACE("(%p)->(IID_IUnknown %p)\n", iface, ppv);
100 *ppv = iface;
101 }else if(IsEqualGUID(&IID_IClassFactory, riid)) {
102 TRACE("(%p)->(IID_IClassFactory %p)\n", iface, ppv);
103 *ppv = iface;
104 }
105
106 if(*ppv) {
107 IUnknown_AddRef((IUnknown*)*ppv);
108 return S_OK;
109 }
110
111 FIXME("(%p)->(%s %p)\n", iface, debugstr_guid(riid), ppv);
112 return E_NOINTERFACE;
113 }
114
115 static ULONG WINAPI ClassFactory_AddRef(IClassFactory *iface)
116 {
117 TRACE("(%p)\n", iface);
118 return 2;
119 }
120
121 static ULONG WINAPI ClassFactory_Release(IClassFactory *iface)
122 {
123 TRACE("(%p)\n", iface);
124 return 1;
125 }
126
127 static HRESULT WINAPI ClassFactory_LockServer(IClassFactory *iface, BOOL fLock)
128 {
129 TRACE("(%p)->(%x)\n", iface, fLock);
130 return S_OK;
131 }
132
133 static const IClassFactoryVtbl WebBrowserFactoryVtbl = {
134 ClassFactory_QueryInterface,
135 ClassFactory_AddRef,
136 ClassFactory_Release,
137 WebBrowser_Create,
138 ClassFactory_LockServer
139 };
140
141 static IClassFactory WebBrowserFactory = { &WebBrowserFactoryVtbl };
142
143 static const IClassFactoryVtbl WebBrowserV1FactoryVtbl = {
144 ClassFactory_QueryInterface,
145 ClassFactory_AddRef,
146 ClassFactory_Release,
147 WebBrowserV1_Create,
148 ClassFactory_LockServer
149 };
150
151 static IClassFactory WebBrowserV1Factory = { &WebBrowserV1FactoryVtbl };
152
153 static const IClassFactoryVtbl InternetShortcutFactoryVtbl = {
154 ClassFactory_QueryInterface,
155 ClassFactory_AddRef,
156 ClassFactory_Release,
157 InternetShortcut_Create,
158 ClassFactory_LockServer
159 };
160
161 static IClassFactory InternetShortcutFactory = { &InternetShortcutFactoryVtbl };
162
163 static const IClassFactoryVtbl CUrlHistoryFactoryVtbl = {
164 ClassFactory_QueryInterface,
165 ClassFactory_AddRef,
166 ClassFactory_Release,
167 CUrlHistory_Create,
168 ClassFactory_LockServer
169 };
170
171 static IClassFactory CUrlHistoryFactory = { &CUrlHistoryFactoryVtbl };
172
173 /******************************************************************
174 * DllMain (ieframe.@)
175 */
176 BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv)
177 {
178 TRACE("(%p %d %p)\n", hInstDLL, fdwReason, lpv);
179
180 switch(fdwReason)
181 {
182 case DLL_WINE_PREATTACH:
183 return FALSE; /* prefer native version */
184 case DLL_PROCESS_ATTACH:
185 ieframe_instance = hInstDLL;
186 register_iewindow_class();
187 DisableThreadLibraryCalls(ieframe_instance);
188 break;
189 case DLL_PROCESS_DETACH:
190 if (lpv) break;
191 unregister_iewindow_class();
192 release_typelib();
193 }
194
195 return TRUE;
196 }
197
198 /***********************************************************************
199 * DllGetClassObject (ieframe.@)
200 */
201 HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
202 {
203 if(IsEqualGUID(&CLSID_WebBrowser, rclsid)) {
204 TRACE("(CLSID_WebBrowser %s %p)\n", debugstr_guid(riid), ppv);
205 return IClassFactory_QueryInterface(&WebBrowserFactory, riid, ppv);
206 }
207
208 if(IsEqualGUID(&CLSID_WebBrowser_V1, rclsid)) {
209 TRACE("(CLSID_WebBrowser_V1 %s %p)\n", debugstr_guid(riid), ppv);
210 return IClassFactory_QueryInterface(&WebBrowserV1Factory, riid, ppv);
211 }
212
213 if(IsEqualGUID(rclsid, &CLSID_InternetShortcut)) {
214 TRACE("(CLSID_InternetShortcut %s %p)\n", debugstr_guid(riid), ppv);
215 return IClassFactory_QueryInterface(&InternetShortcutFactory, riid, ppv);
216 }
217
218 if(IsEqualGUID(&CLSID_CUrlHistory, rclsid)) {
219 TRACE("(CLSID_CUrlHistory %s %p)\n", debugstr_guid(riid), ppv);
220 return IClassFactory_QueryInterface(&CUrlHistoryFactory, riid, ppv);
221 }
222
223 FIXME("%s %s %p\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);
224 return CLASS_E_CLASSNOTAVAILABLE;
225 }
226
227 static const IClassFactoryVtbl InternetExplorerFactoryVtbl = {
228 ClassFactory_QueryInterface,
229 ClassFactory_AddRef,
230 ClassFactory_Release,
231 InternetExplorer_Create,
232 ClassFactory_LockServer
233 };
234
235 static IClassFactory InternetExplorerFactory = { &InternetExplorerFactoryVtbl };
236
237 HRESULT register_class_object(BOOL do_reg)
238 {
239 HRESULT hres;
240
241 static DWORD cookie;
242
243 if(do_reg) {
244 hres = CoRegisterClassObject(&CLSID_InternetExplorer,
245 (IUnknown*)&InternetExplorerFactory, CLSCTX_SERVER,
246 REGCLS_MULTIPLEUSE|REGCLS_SUSPENDED, &cookie);
247 if (FAILED(hres)) {
248 ERR("failed to register object %08x\n", hres);
249 return hres;
250 }
251
252 hres = CoResumeClassObjects();
253 if(SUCCEEDED(hres))
254 return hres;
255
256 ERR("failed to resume object %08x\n", hres);
257 }
258
259 return CoRevokeClassObject(cookie);
260 }
261
262 /***********************************************************************
263 * DllCanUnloadNow (ieframe.@)
264 */
265 HRESULT WINAPI DllCanUnloadNow(void)
266 {
267 TRACE("()\n");
268 return module_ref ? S_FALSE : S_OK;
269 }
270
271 /***********************************************************************
272 * DllRegisterServer (ieframe.@)
273 */
274 HRESULT WINAPI DllRegisterServer(void)
275 {
276 TRACE("()\n");
277 return __wine_register_resources(ieframe_instance);
278 }
279
280 /***********************************************************************
281 * DllUnregisterServer (ieframe.@)
282 */
283 HRESULT WINAPI DllUnregisterServer(void)
284 {
285 TRACE("()\n");
286 return __wine_unregister_resources(ieframe_instance);
287 }
288
289 /***********************************************************************
290 * IEGetWriteableHKCU (ieframe.@)
291 */
292 HRESULT WINAPI IEGetWriteableHKCU(HKEY *pkey)
293 {
294 FIXME("(%p) stub\n", pkey);
295 return E_NOTIMPL;
296 }