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