mshtml: Added IOmNavigator::get_cpuClass implementation.
[wine] / dlls / mshtml / omnavigator.c
1 /*
2  * Copyright 2008 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 <stdarg.h>
20
21 #define COBJMACROS
22
23 #include "windef.h"
24 #include "winbase.h"
25 #include "winuser.h"
26 #include "ole2.h"
27
28 #include "wine/debug.h"
29
30 #include "mshtml_private.h"
31
32 WINE_DEFAULT_DEBUG_CHANNEL(mshtml);
33
34 typedef struct HTMLPluginsCollection HTMLPluginsCollection;
35
36 typedef struct {
37     DispatchEx dispex;
38     IOmNavigator IOmNavigator_iface;
39
40     LONG ref;
41
42     HTMLPluginsCollection *plugins;
43 } OmNavigator;
44
45 static inline OmNavigator *impl_from_IOmNavigator(IOmNavigator *iface)
46 {
47     return CONTAINING_RECORD(iface, OmNavigator, IOmNavigator_iface);
48 }
49
50 struct HTMLPluginsCollection {
51     DispatchEx dispex;
52     IHTMLPluginsCollection IHTMLPluginsCollection_iface;
53
54     LONG ref;
55
56     OmNavigator *navigator;
57 };
58
59 static inline HTMLPluginsCollection *impl_from_IHTMLPluginsCollection(IHTMLPluginsCollection *iface)
60 {
61     return CONTAINING_RECORD(iface, HTMLPluginsCollection, IHTMLPluginsCollection_iface);
62 }
63
64 static HRESULT WINAPI HTMLPluginsCollection_QueryInterface(IHTMLPluginsCollection *iface, REFIID riid, void **ppv)
65 {
66     HTMLPluginsCollection *This = impl_from_IHTMLPluginsCollection(iface);
67
68     if(IsEqualGUID(&IID_IUnknown, riid)) {
69         TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
70         *ppv = &This->IHTMLPluginsCollection_iface;
71     }else if(IsEqualGUID(&IID_IHTMLPluginsCollection, riid)) {
72         TRACE("(%p)->(IID_IHTMLPluginCollection %p)\n", This, ppv);
73         *ppv = &This->IHTMLPluginsCollection_iface;
74     }else if(dispex_query_interface(&This->dispex, riid, ppv)) {
75         return *ppv ? S_OK : E_NOINTERFACE;
76     }else {
77         *ppv = NULL;
78         WARN("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
79         return E_NOINTERFACE;
80     }
81
82     IUnknown_AddRef((IUnknown*)*ppv);
83     return S_OK;
84 }
85
86 static ULONG WINAPI HTMLPluginsCollection_AddRef(IHTMLPluginsCollection *iface)
87 {
88     HTMLPluginsCollection *This = impl_from_IHTMLPluginsCollection(iface);
89     LONG ref = InterlockedIncrement(&This->ref);
90
91     TRACE("(%p) ref=%d\n", This, ref);
92
93     return ref;
94 }
95
96 static ULONG WINAPI HTMLPluginsCollection_Release(IHTMLPluginsCollection *iface)
97 {
98     HTMLPluginsCollection *This = impl_from_IHTMLPluginsCollection(iface);
99     LONG ref = InterlockedDecrement(&This->ref);
100
101     TRACE("(%p) ref=%d\n", This, ref);
102
103     if(!ref) {
104         if(This->navigator)
105             This->navigator->plugins = NULL;
106         release_dispex(&This->dispex);
107         heap_free(This);
108     }
109
110     return ref;
111 }
112
113 static HRESULT WINAPI HTMLPluginsCollection_GetTypeInfoCount(IHTMLPluginsCollection *iface, UINT *pctinfo)
114 {
115     HTMLPluginsCollection *This = impl_from_IHTMLPluginsCollection(iface);
116     return IDispatchEx_GetTypeInfoCount(&This->dispex.IDispatchEx_iface, pctinfo);
117 }
118
119 static HRESULT WINAPI HTMLPluginsCollection_GetTypeInfo(IHTMLPluginsCollection *iface, UINT iTInfo,
120                                               LCID lcid, ITypeInfo **ppTInfo)
121 {
122     HTMLPluginsCollection *This = impl_from_IHTMLPluginsCollection(iface);
123     return IDispatchEx_GetTypeInfo(&This->dispex.IDispatchEx_iface, iTInfo, lcid, ppTInfo);
124 }
125
126 static HRESULT WINAPI HTMLPluginsCollection_GetIDsOfNames(IHTMLPluginsCollection *iface, REFIID riid,
127         LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
128 {
129     HTMLPluginsCollection *This = impl_from_IHTMLPluginsCollection(iface);
130     return IDispatchEx_GetIDsOfNames(&This->dispex.IDispatchEx_iface, riid, rgszNames, cNames,
131             lcid, rgDispId);
132 }
133
134 static HRESULT WINAPI HTMLPluginsCollection_Invoke(IHTMLPluginsCollection *iface, DISPID dispIdMember,
135         REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult,
136         EXCEPINFO *pExcepInfo, UINT *puArgErr)
137 {
138     HTMLPluginsCollection *This = impl_from_IHTMLPluginsCollection(iface);
139     return IDispatchEx_Invoke(&This->dispex.IDispatchEx_iface, dispIdMember, riid, lcid,
140             wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
141 }
142
143 static HRESULT WINAPI HTMLPluginsCollection_get_length(IHTMLPluginsCollection *iface, LONG *p)
144 {
145     HTMLPluginsCollection *This = impl_from_IHTMLPluginsCollection(iface);
146     FIXME("(%p)->(%p)\n", This, p);
147     return E_NOTIMPL;
148 }
149
150 static HRESULT WINAPI HTMLPluginsCollection_refresh(IHTMLPluginsCollection *iface, VARIANT_BOOL reload)
151 {
152     HTMLPluginsCollection *This = impl_from_IHTMLPluginsCollection(iface);
153     FIXME("(%p)->(%x)\n", This, reload);
154     return E_NOTIMPL;
155 }
156
157 static const IHTMLPluginsCollectionVtbl HTMLPluginsCollectionVtbl = {
158     HTMLPluginsCollection_QueryInterface,
159     HTMLPluginsCollection_AddRef,
160     HTMLPluginsCollection_Release,
161     HTMLPluginsCollection_GetTypeInfoCount,
162     HTMLPluginsCollection_GetTypeInfo,
163     HTMLPluginsCollection_GetIDsOfNames,
164     HTMLPluginsCollection_Invoke,
165     HTMLPluginsCollection_get_length,
166     HTMLPluginsCollection_refresh
167 };
168
169 static const tid_t HTMLPluginsCollection_iface_tids[] = {
170     IHTMLPluginsCollection_tid,
171     0
172 };
173 static dispex_static_data_t HTMLPluginsCollection_dispex = {
174     NULL,
175     DispCPlugins_tid,
176     NULL,
177     HTMLPluginsCollection_iface_tids
178 };
179
180 static HRESULT create_plugins_collection(OmNavigator *navigator, HTMLPluginsCollection **ret)
181 {
182     HTMLPluginsCollection *col;
183
184     col = heap_alloc_zero(sizeof(*col));
185     if(!col)
186         return E_OUTOFMEMORY;
187
188     col->IHTMLPluginsCollection_iface.lpVtbl = &HTMLPluginsCollectionVtbl;
189     col->ref = 1;
190     col->navigator = navigator;
191
192     init_dispex(&col->dispex, (IUnknown*)&col->IHTMLPluginsCollection_iface,
193                 &HTMLPluginsCollection_dispex);
194
195     *ret = col;
196     return S_OK;
197 }
198
199 static HRESULT WINAPI OmNavigator_QueryInterface(IOmNavigator *iface, REFIID riid, void **ppv)
200 {
201     OmNavigator *This = impl_from_IOmNavigator(iface);
202
203     *ppv = NULL;
204
205     if(IsEqualGUID(&IID_IUnknown, riid)) {
206         TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
207         *ppv = &This->IOmNavigator_iface;
208     }else if(IsEqualGUID(&IID_IOmNavigator, riid)) {
209         TRACE("(%p)->(IID_IOmNavigator %p)\n", This, ppv);
210         *ppv = &This->IOmNavigator_iface;
211     }else if(dispex_query_interface(&This->dispex, riid, ppv)) {
212         return *ppv ? S_OK : E_NOINTERFACE;
213     }
214
215     if(*ppv) {
216         IUnknown_AddRef((IUnknown*)*ppv);
217         return S_OK;
218     }
219
220     WARN("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
221     return E_NOINTERFACE;
222 }
223
224 static ULONG WINAPI OmNavigator_AddRef(IOmNavigator *iface)
225 {
226     OmNavigator *This = impl_from_IOmNavigator(iface);
227     LONG ref = InterlockedIncrement(&This->ref);
228
229     TRACE("(%p) ref=%d\n", This, ref);
230
231     return ref;
232 }
233
234 static ULONG WINAPI OmNavigator_Release(IOmNavigator *iface)
235 {
236     OmNavigator *This = impl_from_IOmNavigator(iface);
237     LONG ref = InterlockedDecrement(&This->ref);
238
239     TRACE("(%p) ref=%d\n", This, ref);
240
241     if(!ref) {
242         if(This->plugins) {
243             This->plugins->navigator = NULL;
244             IHTMLPluginsCollection_Release(&This->plugins->IHTMLPluginsCollection_iface);
245         }
246         release_dispex(&This->dispex);
247         heap_free(This);
248     }
249
250     return ref;
251 }
252
253 static HRESULT WINAPI OmNavigator_GetTypeInfoCount(IOmNavigator *iface, UINT *pctinfo)
254 {
255     OmNavigator *This = impl_from_IOmNavigator(iface);
256     FIXME("(%p)->(%p)\n", This, pctinfo);
257     return E_NOTIMPL;
258 }
259
260 static HRESULT WINAPI OmNavigator_GetTypeInfo(IOmNavigator *iface, UINT iTInfo,
261                                               LCID lcid, ITypeInfo **ppTInfo)
262 {
263     OmNavigator *This = impl_from_IOmNavigator(iface);
264
265     return IDispatchEx_GetTypeInfo(&This->dispex.IDispatchEx_iface, iTInfo, lcid, ppTInfo);
266 }
267
268 static HRESULT WINAPI OmNavigator_GetIDsOfNames(IOmNavigator *iface, REFIID riid,
269                                                 LPOLESTR *rgszNames, UINT cNames,
270                                                 LCID lcid, DISPID *rgDispId)
271 {
272     OmNavigator *This = impl_from_IOmNavigator(iface);
273
274     return IDispatchEx_GetIDsOfNames(&This->dispex.IDispatchEx_iface, riid, rgszNames, cNames,
275             lcid, rgDispId);
276 }
277
278 static HRESULT WINAPI OmNavigator_Invoke(IOmNavigator *iface, DISPID dispIdMember,
279                             REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
280                             VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
281 {
282     OmNavigator *This = impl_from_IOmNavigator(iface);
283
284     return IDispatchEx_Invoke(&This->dispex.IDispatchEx_iface, dispIdMember, riid, lcid, wFlags,
285             pDispParams, pVarResult, pExcepInfo, puArgErr);
286 }
287
288 static HRESULT WINAPI OmNavigator_get_appCodeName(IOmNavigator *iface, BSTR *p)
289 {
290     OmNavigator *This = impl_from_IOmNavigator(iface);
291
292     static const WCHAR mozillaW[] = {'M','o','z','i','l','l','a',0};
293
294     TRACE("(%p)->(%p)\n", This, p);
295
296     *p = SysAllocString(mozillaW);
297     return S_OK;
298 }
299
300 static HRESULT WINAPI OmNavigator_get_appName(IOmNavigator *iface, BSTR *p)
301 {
302     OmNavigator *This = impl_from_IOmNavigator(iface);
303
304     static const WCHAR app_nameW[] =
305         {'M','i','c','r','o','s','o','f','t',' ',
306          'I','n','t','e','r','n','e','t',' ',
307          'E','x','p','l','o','r','e','r',0};
308
309     TRACE("(%p)->(%p)\n", This, p);
310
311     *p = SysAllocString(app_nameW);
312     if(!*p)
313         return E_OUTOFMEMORY;
314
315     return S_OK;
316 }
317
318 static HRESULT WINAPI OmNavigator_get_appVersion(IOmNavigator *iface, BSTR *p)
319 {
320     OmNavigator *This = impl_from_IOmNavigator(iface);
321
322     char user_agent[512];
323     DWORD size;
324     HRESULT hres;
325
326     TRACE("(%p)->(%p)\n", This, p);
327
328     size = sizeof(user_agent);
329     hres = ObtainUserAgentString(0, user_agent, &size);
330     if(FAILED(hres))
331         return hres;
332
333     if(strncmp(user_agent, "Mozilla/", 8)) {
334         FIXME("Unsupported user agent\n");
335         return E_FAIL;
336     }
337
338     size = MultiByteToWideChar(CP_ACP, 0, user_agent+8, -1, NULL, 0);
339     *p = SysAllocStringLen(NULL, size-1);
340     if(!*p)
341         return E_OUTOFMEMORY;
342
343     MultiByteToWideChar(CP_ACP, 0, user_agent+8, -1, *p, size);
344     return S_OK;
345 }
346
347 static HRESULT WINAPI OmNavigator_get_userAgent(IOmNavigator *iface, BSTR *p)
348 {
349     OmNavigator *This = impl_from_IOmNavigator(iface);
350     char user_agent[512];
351     DWORD size;
352     HRESULT hres;
353
354     TRACE("(%p)->(%p)\n", This, p);
355
356     size = sizeof(user_agent);
357     hres = ObtainUserAgentString(0, user_agent, &size);
358     if(FAILED(hres))
359         return hres;
360
361     size = MultiByteToWideChar(CP_ACP, 0, user_agent, -1, NULL, 0);
362     *p = SysAllocStringLen(NULL, size-1);
363     if(!*p)
364         return E_OUTOFMEMORY;
365
366     MultiByteToWideChar(CP_ACP, 0, user_agent, -1, *p, size);
367     return S_OK;
368 }
369
370 static HRESULT WINAPI OmNavigator_javaEnabled(IOmNavigator *iface, VARIANT_BOOL *enabled)
371 {
372     OmNavigator *This = impl_from_IOmNavigator(iface);
373
374     FIXME("(%p)->(%p) semi-stub\n", This, enabled);
375
376     *enabled = VARIANT_FALSE;
377     return S_OK;
378 }
379
380 static HRESULT WINAPI OmNavigator_taintEnabled(IOmNavigator *iface, VARIANT_BOOL *enabled)
381 {
382     OmNavigator *This = impl_from_IOmNavigator(iface);
383     FIXME("(%p)->(%p)\n", This, enabled);
384     return E_NOTIMPL;
385 }
386
387 static HRESULT WINAPI OmNavigator_get_mimeTypes(IOmNavigator *iface, IHTMLMimeTypesCollection **p)
388 {
389     OmNavigator *This = impl_from_IOmNavigator(iface);
390     FIXME("(%p)->(%p)\n", This, p);
391     return E_NOTIMPL;
392 }
393
394 static HRESULT WINAPI OmNavigator_get_plugins(IOmNavigator *iface, IHTMLPluginsCollection **p)
395 {
396     OmNavigator *This = impl_from_IOmNavigator(iface);
397
398     TRACE("(%p)->(%p)\n", This, p);
399
400     if(!This->plugins) {
401         HRESULT hres;
402
403         hres = create_plugins_collection(This, &This->plugins);
404         if(FAILED(hres))
405             return hres;
406     }else {
407         IHTMLPluginsCollection_AddRef(&This->plugins->IHTMLPluginsCollection_iface);
408     }
409
410     *p = &This->plugins->IHTMLPluginsCollection_iface;
411     return S_OK;
412 }
413
414 static HRESULT WINAPI OmNavigator_get_cookieEnabled(IOmNavigator *iface, VARIANT_BOOL *p)
415 {
416     OmNavigator *This = impl_from_IOmNavigator(iface);
417     FIXME("(%p)->(%p)\n", This, p);
418     return E_NOTIMPL;
419 }
420
421 static HRESULT WINAPI OmNavigator_get_opsProfile(IOmNavigator *iface, IHTMLOpsProfile **p)
422 {
423     OmNavigator *This = impl_from_IOmNavigator(iface);
424     FIXME("(%p)->(%p)\n", This, p);
425     return E_NOTIMPL;
426 }
427
428 static HRESULT WINAPI OmNavigator_toString(IOmNavigator *iface, BSTR *String)
429 {
430     OmNavigator *This = impl_from_IOmNavigator(iface);
431
432     static const WCHAR objectW[] = {'[','o','b','j','e','c','t',']',0};
433
434     TRACE("(%p)->(%p)\n", This, String);
435
436     if(!String)
437         return E_INVALIDARG;
438
439     *String = SysAllocString(objectW);
440     return *String ? S_OK : E_OUTOFMEMORY;
441 }
442
443 static HRESULT WINAPI OmNavigator_get_cpuClass(IOmNavigator *iface, BSTR *p)
444 {
445     OmNavigator *This = impl_from_IOmNavigator(iface);
446
447     static const WCHAR cpu_classW[] =
448 #ifdef _WIN64
449         {'x','6','4',0};
450 #else
451         {'x','8','6',0};
452 #endif
453
454     TRACE("(%p)->(%p)\n", This, p);
455
456     *p = SysAllocString(cpu_classW);
457     return *p ? S_OK : E_OUTOFMEMORY;
458 }
459
460 static HRESULT WINAPI OmNavigator_get_systemLanguage(IOmNavigator *iface, BSTR *p)
461 {
462     OmNavigator *This = impl_from_IOmNavigator(iface);
463     FIXME("(%p)->(%p)\n", This, p);
464     return E_NOTIMPL;
465 }
466
467 static HRESULT WINAPI OmNavigator_get_browserLanguage(IOmNavigator *iface, BSTR *p)
468 {
469     OmNavigator *This = impl_from_IOmNavigator(iface);
470     FIXME("(%p)->(%p)\n", This, p);
471     return E_NOTIMPL;
472 }
473
474 static HRESULT WINAPI OmNavigator_get_userLanguage(IOmNavigator *iface, BSTR *p)
475 {
476     OmNavigator *This = impl_from_IOmNavigator(iface);
477     FIXME("(%p)->(%p)\n", This, p);
478     return E_NOTIMPL;
479 }
480
481 static HRESULT WINAPI OmNavigator_get_platform(IOmNavigator *iface, BSTR *p)
482 {
483     OmNavigator *This = impl_from_IOmNavigator(iface);
484
485 #ifdef _WIN64
486     static const WCHAR platformW[] = {'W','i','n','6','4',0};
487 #else
488     static const WCHAR platformW[] = {'W','i','n','3','2',0};
489 #endif
490
491     TRACE("(%p)->(%p)\n", This, p);
492
493     *p = SysAllocString(platformW);
494     return S_OK;
495 }
496
497 static HRESULT WINAPI OmNavigator_get_appMinorVersion(IOmNavigator *iface, BSTR *p)
498 {
499     OmNavigator *This = impl_from_IOmNavigator(iface);
500     FIXME("(%p)->(%p)\n", This, p);
501     return E_NOTIMPL;
502 }
503
504 static HRESULT WINAPI OmNavigator_get_connectionSpeed(IOmNavigator *iface, LONG *p)
505 {
506     OmNavigator *This = impl_from_IOmNavigator(iface);
507     FIXME("(%p)->(%p)\n", This, p);
508     return E_NOTIMPL;
509 }
510
511 static HRESULT WINAPI OmNavigator_get_onLine(IOmNavigator *iface, VARIANT_BOOL *p)
512 {
513     OmNavigator *This = impl_from_IOmNavigator(iface);
514     FIXME("(%p)->(%p)\n", This, p);
515     return E_NOTIMPL;
516 }
517
518 static HRESULT WINAPI OmNavigator_get_userProfile(IOmNavigator *iface, IHTMLOpsProfile **p)
519 {
520     OmNavigator *This = impl_from_IOmNavigator(iface);
521     FIXME("(%p)->(%p)\n", This, p);
522     return E_NOTIMPL;
523 }
524
525 static const IOmNavigatorVtbl OmNavigatorVtbl = {
526     OmNavigator_QueryInterface,
527     OmNavigator_AddRef,
528     OmNavigator_Release,
529     OmNavigator_GetTypeInfoCount,
530     OmNavigator_GetTypeInfo,
531     OmNavigator_GetIDsOfNames,
532     OmNavigator_Invoke,
533     OmNavigator_get_appCodeName,
534     OmNavigator_get_appName,
535     OmNavigator_get_appVersion,
536     OmNavigator_get_userAgent,
537     OmNavigator_javaEnabled,
538     OmNavigator_taintEnabled,
539     OmNavigator_get_mimeTypes,
540     OmNavigator_get_plugins,
541     OmNavigator_get_cookieEnabled,
542     OmNavigator_get_opsProfile,
543     OmNavigator_toString,
544     OmNavigator_get_cpuClass,
545     OmNavigator_get_systemLanguage,
546     OmNavigator_get_browserLanguage,
547     OmNavigator_get_userLanguage,
548     OmNavigator_get_platform,
549     OmNavigator_get_appMinorVersion,
550     OmNavigator_get_connectionSpeed,
551     OmNavigator_get_onLine,
552     OmNavigator_get_userProfile
553 };
554
555 static const tid_t OmNavigator_iface_tids[] = {
556     IOmNavigator_tid,
557     0
558 };
559 static dispex_static_data_t OmNavigator_dispex = {
560     NULL,
561     DispHTMLNavigator_tid,
562     NULL,
563     OmNavigator_iface_tids
564 };
565
566 IOmNavigator *OmNavigator_Create(void)
567 {
568     OmNavigator *ret;
569
570     ret = heap_alloc_zero(sizeof(*ret));
571     ret->IOmNavigator_iface.lpVtbl = &OmNavigatorVtbl;
572     ret->ref = 1;
573
574     init_dispex(&ret->dispex, (IUnknown*)&ret->IOmNavigator_iface, &OmNavigator_dispex);
575
576     return &ret->IOmNavigator_iface;
577 }