mshtml: Don't overwrite type of result if property type is VT_VARIANT.
[wine/multimedia.git] / dlls / mshtml / omnavigator.c
blobbfc3d23cee44ea9d2517fce8c2ae920a1dd59bc2
1 /*
2 * Copyright 2008 Jacek Caban for CodeWeavers
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.
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.
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
19 #include <stdarg.h>
21 #define COBJMACROS
23 #include "windef.h"
24 #include "winbase.h"
25 #include "winuser.h"
26 #include "ole2.h"
28 #include "wine/debug.h"
30 #include "mshtml_private.h"
32 WINE_DEFAULT_DEBUG_CHANNEL(mshtml);
34 typedef struct HTMLPluginsCollection HTMLPluginsCollection;
35 typedef struct HTMLMimeTypesCollection HTMLMimeTypesCollection;
37 typedef struct {
38 DispatchEx dispex;
39 IOmNavigator IOmNavigator_iface;
41 LONG ref;
43 HTMLPluginsCollection *plugins;
44 HTMLMimeTypesCollection *mime_types;
45 } OmNavigator;
47 static inline OmNavigator *impl_from_IOmNavigator(IOmNavigator *iface)
49 return CONTAINING_RECORD(iface, OmNavigator, IOmNavigator_iface);
52 struct HTMLPluginsCollection {
53 DispatchEx dispex;
54 IHTMLPluginsCollection IHTMLPluginsCollection_iface;
56 LONG ref;
58 OmNavigator *navigator;
61 static inline HTMLPluginsCollection *impl_from_IHTMLPluginsCollection(IHTMLPluginsCollection *iface)
63 return CONTAINING_RECORD(iface, HTMLPluginsCollection, IHTMLPluginsCollection_iface);
66 static HRESULT WINAPI HTMLPluginsCollection_QueryInterface(IHTMLPluginsCollection *iface, REFIID riid, void **ppv)
68 HTMLPluginsCollection *This = impl_from_IHTMLPluginsCollection(iface);
70 if(IsEqualGUID(&IID_IUnknown, riid)) {
71 TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
72 *ppv = &This->IHTMLPluginsCollection_iface;
73 }else if(IsEqualGUID(&IID_IHTMLPluginsCollection, riid)) {
74 TRACE("(%p)->(IID_IHTMLPluginCollection %p)\n", This, ppv);
75 *ppv = &This->IHTMLPluginsCollection_iface;
76 }else if(dispex_query_interface(&This->dispex, riid, ppv)) {
77 return *ppv ? S_OK : E_NOINTERFACE;
78 }else {
79 *ppv = NULL;
80 WARN("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
81 return E_NOINTERFACE;
84 IUnknown_AddRef((IUnknown*)*ppv);
85 return S_OK;
88 static ULONG WINAPI HTMLPluginsCollection_AddRef(IHTMLPluginsCollection *iface)
90 HTMLPluginsCollection *This = impl_from_IHTMLPluginsCollection(iface);
91 LONG ref = InterlockedIncrement(&This->ref);
93 TRACE("(%p) ref=%d\n", This, ref);
95 return ref;
98 static ULONG WINAPI HTMLPluginsCollection_Release(IHTMLPluginsCollection *iface)
100 HTMLPluginsCollection *This = impl_from_IHTMLPluginsCollection(iface);
101 LONG ref = InterlockedDecrement(&This->ref);
103 TRACE("(%p) ref=%d\n", This, ref);
105 if(!ref) {
106 if(This->navigator)
107 This->navigator->plugins = NULL;
108 release_dispex(&This->dispex);
109 heap_free(This);
112 return ref;
115 static HRESULT WINAPI HTMLPluginsCollection_GetTypeInfoCount(IHTMLPluginsCollection *iface, UINT *pctinfo)
117 HTMLPluginsCollection *This = impl_from_IHTMLPluginsCollection(iface);
118 return IDispatchEx_GetTypeInfoCount(&This->dispex.IDispatchEx_iface, pctinfo);
121 static HRESULT WINAPI HTMLPluginsCollection_GetTypeInfo(IHTMLPluginsCollection *iface, UINT iTInfo,
122 LCID lcid, ITypeInfo **ppTInfo)
124 HTMLPluginsCollection *This = impl_from_IHTMLPluginsCollection(iface);
125 return IDispatchEx_GetTypeInfo(&This->dispex.IDispatchEx_iface, iTInfo, lcid, ppTInfo);
128 static HRESULT WINAPI HTMLPluginsCollection_GetIDsOfNames(IHTMLPluginsCollection *iface, REFIID riid,
129 LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
131 HTMLPluginsCollection *This = impl_from_IHTMLPluginsCollection(iface);
132 return IDispatchEx_GetIDsOfNames(&This->dispex.IDispatchEx_iface, riid, rgszNames, cNames,
133 lcid, rgDispId);
136 static HRESULT WINAPI HTMLPluginsCollection_Invoke(IHTMLPluginsCollection *iface, DISPID dispIdMember,
137 REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult,
138 EXCEPINFO *pExcepInfo, UINT *puArgErr)
140 HTMLPluginsCollection *This = impl_from_IHTMLPluginsCollection(iface);
141 return IDispatchEx_Invoke(&This->dispex.IDispatchEx_iface, dispIdMember, riid, lcid,
142 wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
145 static HRESULT WINAPI HTMLPluginsCollection_get_length(IHTMLPluginsCollection *iface, LONG *p)
147 HTMLPluginsCollection *This = impl_from_IHTMLPluginsCollection(iface);
149 TRACE("(%p)->(%p)\n", This, p);
151 /* IE always returns 0 here */
152 *p = 0;
153 return S_OK;
156 static HRESULT WINAPI HTMLPluginsCollection_refresh(IHTMLPluginsCollection *iface, VARIANT_BOOL reload)
158 HTMLPluginsCollection *This = impl_from_IHTMLPluginsCollection(iface);
159 FIXME("(%p)->(%x)\n", This, reload);
160 return E_NOTIMPL;
163 static const IHTMLPluginsCollectionVtbl HTMLPluginsCollectionVtbl = {
164 HTMLPluginsCollection_QueryInterface,
165 HTMLPluginsCollection_AddRef,
166 HTMLPluginsCollection_Release,
167 HTMLPluginsCollection_GetTypeInfoCount,
168 HTMLPluginsCollection_GetTypeInfo,
169 HTMLPluginsCollection_GetIDsOfNames,
170 HTMLPluginsCollection_Invoke,
171 HTMLPluginsCollection_get_length,
172 HTMLPluginsCollection_refresh
175 static const tid_t HTMLPluginsCollection_iface_tids[] = {
176 IHTMLPluginsCollection_tid,
179 static dispex_static_data_t HTMLPluginsCollection_dispex = {
180 NULL,
181 DispCPlugins_tid,
182 NULL,
183 HTMLPluginsCollection_iface_tids
186 static HRESULT create_plugins_collection(OmNavigator *navigator, HTMLPluginsCollection **ret)
188 HTMLPluginsCollection *col;
190 col = heap_alloc_zero(sizeof(*col));
191 if(!col)
192 return E_OUTOFMEMORY;
194 col->IHTMLPluginsCollection_iface.lpVtbl = &HTMLPluginsCollectionVtbl;
195 col->ref = 1;
196 col->navigator = navigator;
198 init_dispex(&col->dispex, (IUnknown*)&col->IHTMLPluginsCollection_iface,
199 &HTMLPluginsCollection_dispex);
201 *ret = col;
202 return S_OK;
205 struct HTMLMimeTypesCollection {
206 DispatchEx dispex;
207 IHTMLMimeTypesCollection IHTMLMimeTypesCollection_iface;
209 LONG ref;
211 OmNavigator *navigator;
214 static inline HTMLMimeTypesCollection *impl_from_IHTMLMimeTypesCollection(IHTMLMimeTypesCollection *iface)
216 return CONTAINING_RECORD(iface, HTMLMimeTypesCollection, IHTMLMimeTypesCollection_iface);
219 static HRESULT WINAPI HTMLMimeTypesCollection_QueryInterface(IHTMLMimeTypesCollection *iface, REFIID riid, void **ppv)
221 HTMLMimeTypesCollection *This = impl_from_IHTMLMimeTypesCollection(iface);
223 if(IsEqualGUID(&IID_IUnknown, riid)) {
224 TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
225 *ppv = &This->IHTMLMimeTypesCollection_iface;
226 }else if(IsEqualGUID(&IID_IHTMLMimeTypesCollection, riid)) {
227 TRACE("(%p)->(IID_IHTMLMimeTypesCollection %p)\n", This, ppv);
228 *ppv = &This->IHTMLMimeTypesCollection_iface;
229 }else if(dispex_query_interface(&This->dispex, riid, ppv)) {
230 return *ppv ? S_OK : E_NOINTERFACE;
231 }else {
232 *ppv = NULL;
233 WARN("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
234 return E_NOINTERFACE;
237 IUnknown_AddRef((IUnknown*)*ppv);
238 return S_OK;
241 static ULONG WINAPI HTMLMimeTypesCollection_AddRef(IHTMLMimeTypesCollection *iface)
243 HTMLMimeTypesCollection *This = impl_from_IHTMLMimeTypesCollection(iface);
244 LONG ref = InterlockedIncrement(&This->ref);
246 TRACE("(%p) ref=%d\n", This, ref);
248 return ref;
251 static ULONG WINAPI HTMLMimeTypesCollection_Release(IHTMLMimeTypesCollection *iface)
253 HTMLMimeTypesCollection *This = impl_from_IHTMLMimeTypesCollection(iface);
254 LONG ref = InterlockedDecrement(&This->ref);
256 TRACE("(%p) ref=%d\n", This, ref);
258 if(!ref) {
259 if(This->navigator)
260 This->navigator->mime_types = NULL;
261 release_dispex(&This->dispex);
262 heap_free(This);
265 return ref;
268 static HRESULT WINAPI HTMLMimeTypesCollection_GetTypeInfoCount(IHTMLMimeTypesCollection *iface, UINT *pctinfo)
270 HTMLMimeTypesCollection *This = impl_from_IHTMLMimeTypesCollection(iface);
271 return IDispatchEx_GetTypeInfoCount(&This->dispex.IDispatchEx_iface, pctinfo);
274 static HRESULT WINAPI HTMLMimeTypesCollection_GetTypeInfo(IHTMLMimeTypesCollection *iface, UINT iTInfo,
275 LCID lcid, ITypeInfo **ppTInfo)
277 HTMLMimeTypesCollection *This = impl_from_IHTMLMimeTypesCollection(iface);
278 return IDispatchEx_GetTypeInfo(&This->dispex.IDispatchEx_iface, iTInfo, lcid, ppTInfo);
281 static HRESULT WINAPI HTMLMimeTypesCollection_GetIDsOfNames(IHTMLMimeTypesCollection *iface, REFIID riid,
282 LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
284 HTMLMimeTypesCollection *This = impl_from_IHTMLMimeTypesCollection(iface);
285 return IDispatchEx_GetIDsOfNames(&This->dispex.IDispatchEx_iface, riid, rgszNames, cNames,
286 lcid, rgDispId);
289 static HRESULT WINAPI HTMLMimeTypesCollection_Invoke(IHTMLMimeTypesCollection *iface, DISPID dispIdMember,
290 REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult,
291 EXCEPINFO *pExcepInfo, UINT *puArgErr)
293 HTMLMimeTypesCollection *This = impl_from_IHTMLMimeTypesCollection(iface);
294 return IDispatchEx_Invoke(&This->dispex.IDispatchEx_iface, dispIdMember, riid, lcid,
295 wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
298 static HRESULT WINAPI HTMLMimeTypesCollection_get_length(IHTMLMimeTypesCollection *iface, LONG *p)
300 HTMLMimeTypesCollection *This = impl_from_IHTMLMimeTypesCollection(iface);
302 TRACE("(%p)->(%p)\n", This, p);
304 /* This is just a stub for compatibility with other browser in IE */
305 *p = 0;
306 return S_OK;
309 static const IHTMLMimeTypesCollectionVtbl HTMLMimeTypesCollectionVtbl = {
310 HTMLMimeTypesCollection_QueryInterface,
311 HTMLMimeTypesCollection_AddRef,
312 HTMLMimeTypesCollection_Release,
313 HTMLMimeTypesCollection_GetTypeInfoCount,
314 HTMLMimeTypesCollection_GetTypeInfo,
315 HTMLMimeTypesCollection_GetIDsOfNames,
316 HTMLMimeTypesCollection_Invoke,
317 HTMLMimeTypesCollection_get_length
320 static const tid_t HTMLMimeTypesCollection_iface_tids[] = {
321 IHTMLMimeTypesCollection_tid,
324 static dispex_static_data_t HTMLMimeTypesCollection_dispex = {
325 NULL,
326 IHTMLMimeTypesCollection_tid,
327 NULL,
328 HTMLMimeTypesCollection_iface_tids
331 static HRESULT create_mime_types_collection(OmNavigator *navigator, HTMLMimeTypesCollection **ret)
333 HTMLMimeTypesCollection *col;
335 col = heap_alloc_zero(sizeof(*col));
336 if(!col)
337 return E_OUTOFMEMORY;
339 col->IHTMLMimeTypesCollection_iface.lpVtbl = &HTMLMimeTypesCollectionVtbl;
340 col->ref = 1;
341 col->navigator = navigator;
343 init_dispex(&col->dispex, (IUnknown*)&col->IHTMLMimeTypesCollection_iface,
344 &HTMLMimeTypesCollection_dispex);
346 *ret = col;
347 return S_OK;
350 static HRESULT WINAPI OmNavigator_QueryInterface(IOmNavigator *iface, REFIID riid, void **ppv)
352 OmNavigator *This = impl_from_IOmNavigator(iface);
354 *ppv = NULL;
356 if(IsEqualGUID(&IID_IUnknown, riid)) {
357 TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
358 *ppv = &This->IOmNavigator_iface;
359 }else if(IsEqualGUID(&IID_IOmNavigator, riid)) {
360 TRACE("(%p)->(IID_IOmNavigator %p)\n", This, ppv);
361 *ppv = &This->IOmNavigator_iface;
362 }else if(dispex_query_interface(&This->dispex, riid, ppv)) {
363 return *ppv ? S_OK : E_NOINTERFACE;
366 if(*ppv) {
367 IUnknown_AddRef((IUnknown*)*ppv);
368 return S_OK;
371 WARN("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
372 return E_NOINTERFACE;
375 static ULONG WINAPI OmNavigator_AddRef(IOmNavigator *iface)
377 OmNavigator *This = impl_from_IOmNavigator(iface);
378 LONG ref = InterlockedIncrement(&This->ref);
380 TRACE("(%p) ref=%d\n", This, ref);
382 return ref;
385 static ULONG WINAPI OmNavigator_Release(IOmNavigator *iface)
387 OmNavigator *This = impl_from_IOmNavigator(iface);
388 LONG ref = InterlockedDecrement(&This->ref);
390 TRACE("(%p) ref=%d\n", This, ref);
392 if(!ref) {
393 if(This->plugins)
394 This->plugins->navigator = NULL;
395 if(This->mime_types)
396 This->mime_types->navigator = NULL;
397 release_dispex(&This->dispex);
398 heap_free(This);
401 return ref;
404 static HRESULT WINAPI OmNavigator_GetTypeInfoCount(IOmNavigator *iface, UINT *pctinfo)
406 OmNavigator *This = impl_from_IOmNavigator(iface);
407 FIXME("(%p)->(%p)\n", This, pctinfo);
408 return E_NOTIMPL;
411 static HRESULT WINAPI OmNavigator_GetTypeInfo(IOmNavigator *iface, UINT iTInfo,
412 LCID lcid, ITypeInfo **ppTInfo)
414 OmNavigator *This = impl_from_IOmNavigator(iface);
416 return IDispatchEx_GetTypeInfo(&This->dispex.IDispatchEx_iface, iTInfo, lcid, ppTInfo);
419 static HRESULT WINAPI OmNavigator_GetIDsOfNames(IOmNavigator *iface, REFIID riid,
420 LPOLESTR *rgszNames, UINT cNames,
421 LCID lcid, DISPID *rgDispId)
423 OmNavigator *This = impl_from_IOmNavigator(iface);
425 return IDispatchEx_GetIDsOfNames(&This->dispex.IDispatchEx_iface, riid, rgszNames, cNames,
426 lcid, rgDispId);
429 static HRESULT WINAPI OmNavigator_Invoke(IOmNavigator *iface, DISPID dispIdMember,
430 REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
431 VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
433 OmNavigator *This = impl_from_IOmNavigator(iface);
435 return IDispatchEx_Invoke(&This->dispex.IDispatchEx_iface, dispIdMember, riid, lcid, wFlags,
436 pDispParams, pVarResult, pExcepInfo, puArgErr);
439 static HRESULT WINAPI OmNavigator_get_appCodeName(IOmNavigator *iface, BSTR *p)
441 OmNavigator *This = impl_from_IOmNavigator(iface);
443 static const WCHAR mozillaW[] = {'M','o','z','i','l','l','a',0};
445 TRACE("(%p)->(%p)\n", This, p);
447 *p = SysAllocString(mozillaW);
448 return S_OK;
451 static HRESULT WINAPI OmNavigator_get_appName(IOmNavigator *iface, BSTR *p)
453 OmNavigator *This = impl_from_IOmNavigator(iface);
455 static const WCHAR app_nameW[] =
456 {'M','i','c','r','o','s','o','f','t',' ',
457 'I','n','t','e','r','n','e','t',' ',
458 'E','x','p','l','o','r','e','r',0};
460 TRACE("(%p)->(%p)\n", This, p);
462 *p = SysAllocString(app_nameW);
463 if(!*p)
464 return E_OUTOFMEMORY;
466 return S_OK;
469 static HRESULT WINAPI OmNavigator_get_appVersion(IOmNavigator *iface, BSTR *p)
471 OmNavigator *This = impl_from_IOmNavigator(iface);
473 char user_agent[512];
474 DWORD size;
475 HRESULT hres;
477 TRACE("(%p)->(%p)\n", This, p);
479 size = sizeof(user_agent);
480 hres = ObtainUserAgentString(0, user_agent, &size);
481 if(FAILED(hres))
482 return hres;
484 if(strncmp(user_agent, "Mozilla/", 8)) {
485 FIXME("Unsupported user agent\n");
486 return E_FAIL;
489 size = MultiByteToWideChar(CP_ACP, 0, user_agent+8, -1, NULL, 0);
490 *p = SysAllocStringLen(NULL, size-1);
491 if(!*p)
492 return E_OUTOFMEMORY;
494 MultiByteToWideChar(CP_ACP, 0, user_agent+8, -1, *p, size);
495 return S_OK;
498 static HRESULT WINAPI OmNavigator_get_userAgent(IOmNavigator *iface, BSTR *p)
500 OmNavigator *This = impl_from_IOmNavigator(iface);
501 char user_agent[512];
502 DWORD size;
503 HRESULT hres;
505 TRACE("(%p)->(%p)\n", This, p);
507 size = sizeof(user_agent);
508 hres = ObtainUserAgentString(0, user_agent, &size);
509 if(FAILED(hres))
510 return hres;
512 size = MultiByteToWideChar(CP_ACP, 0, user_agent, -1, NULL, 0);
513 *p = SysAllocStringLen(NULL, size-1);
514 if(!*p)
515 return E_OUTOFMEMORY;
517 MultiByteToWideChar(CP_ACP, 0, user_agent, -1, *p, size);
518 return S_OK;
521 static HRESULT WINAPI OmNavigator_javaEnabled(IOmNavigator *iface, VARIANT_BOOL *enabled)
523 OmNavigator *This = impl_from_IOmNavigator(iface);
525 FIXME("(%p)->(%p) semi-stub\n", This, enabled);
527 *enabled = VARIANT_FALSE;
528 return S_OK;
531 static HRESULT WINAPI OmNavigator_taintEnabled(IOmNavigator *iface, VARIANT_BOOL *enabled)
533 OmNavigator *This = impl_from_IOmNavigator(iface);
534 FIXME("(%p)->(%p)\n", This, enabled);
535 return E_NOTIMPL;
538 static HRESULT WINAPI OmNavigator_get_mimeTypes(IOmNavigator *iface, IHTMLMimeTypesCollection **p)
540 OmNavigator *This = impl_from_IOmNavigator(iface);
542 TRACE("(%p)->(%p)\n", This, p);
544 if(!This->mime_types) {
545 HRESULT hres;
547 hres = create_mime_types_collection(This, &This->mime_types);
548 if(FAILED(hres))
549 return hres;
550 }else {
551 IHTMLMimeTypesCollection_AddRef(&This->mime_types->IHTMLMimeTypesCollection_iface);
554 *p = &This->mime_types->IHTMLMimeTypesCollection_iface;
555 return S_OK;
558 static HRESULT WINAPI OmNavigator_get_plugins(IOmNavigator *iface, IHTMLPluginsCollection **p)
560 OmNavigator *This = impl_from_IOmNavigator(iface);
562 TRACE("(%p)->(%p)\n", This, p);
564 if(!This->plugins) {
565 HRESULT hres;
567 hres = create_plugins_collection(This, &This->plugins);
568 if(FAILED(hres))
569 return hres;
570 }else {
571 IHTMLPluginsCollection_AddRef(&This->plugins->IHTMLPluginsCollection_iface);
574 *p = &This->plugins->IHTMLPluginsCollection_iface;
575 return S_OK;
578 static HRESULT WINAPI OmNavigator_get_cookieEnabled(IOmNavigator *iface, VARIANT_BOOL *p)
580 OmNavigator *This = impl_from_IOmNavigator(iface);
581 FIXME("(%p)->(%p)\n", This, p);
582 return E_NOTIMPL;
585 static HRESULT WINAPI OmNavigator_get_opsProfile(IOmNavigator *iface, IHTMLOpsProfile **p)
587 OmNavigator *This = impl_from_IOmNavigator(iface);
588 FIXME("(%p)->(%p)\n", This, p);
589 return E_NOTIMPL;
592 static HRESULT WINAPI OmNavigator_toString(IOmNavigator *iface, BSTR *String)
594 OmNavigator *This = impl_from_IOmNavigator(iface);
596 static const WCHAR objectW[] = {'[','o','b','j','e','c','t',']',0};
598 TRACE("(%p)->(%p)\n", This, String);
600 if(!String)
601 return E_INVALIDARG;
603 *String = SysAllocString(objectW);
604 return *String ? S_OK : E_OUTOFMEMORY;
607 static HRESULT WINAPI OmNavigator_get_cpuClass(IOmNavigator *iface, BSTR *p)
609 OmNavigator *This = impl_from_IOmNavigator(iface);
611 static const WCHAR cpu_classW[] =
612 #ifdef _WIN64
613 {'x','6','4',0};
614 #else
615 {'x','8','6',0};
616 #endif
618 TRACE("(%p)->(%p)\n", This, p);
620 *p = SysAllocString(cpu_classW);
621 return *p ? S_OK : E_OUTOFMEMORY;
624 static HRESULT get_language_string(LCID lcid, BSTR *p)
626 BSTR ret;
627 int len;
629 len = LCIDToLocaleName(lcid, NULL, 0, 0);
630 if(!len) {
631 WARN("LCIDToLocaleName failed: %u\n", GetLastError());
632 return E_FAIL;
635 ret = SysAllocStringLen(NULL, len-1);
636 if(!ret)
637 return E_OUTOFMEMORY;
639 len = LCIDToLocaleName(lcid, ret, len, 0);
640 if(!len) {
641 WARN("LCIDToLocaleName failed: %u\n", GetLastError());
642 SysFreeString(ret);
643 return E_FAIL;
646 *p = ret;
647 return S_OK;
650 static HRESULT WINAPI OmNavigator_get_systemLanguage(IOmNavigator *iface, BSTR *p)
652 OmNavigator *This = impl_from_IOmNavigator(iface);
654 TRACE("(%p)->(%p)\n", This, p);
656 return get_language_string(LOCALE_SYSTEM_DEFAULT, p);
659 static HRESULT WINAPI OmNavigator_get_browserLanguage(IOmNavigator *iface, BSTR *p)
661 OmNavigator *This = impl_from_IOmNavigator(iface);
663 TRACE("(%p)->(%p)\n", This, p);
665 return get_language_string(GetUserDefaultUILanguage(), p);
668 static HRESULT WINAPI OmNavigator_get_userLanguage(IOmNavigator *iface, BSTR *p)
670 OmNavigator *This = impl_from_IOmNavigator(iface);
672 TRACE("(%p)->(%p)\n", This, p);
674 return get_language_string(LOCALE_USER_DEFAULT, p);
677 static HRESULT WINAPI OmNavigator_get_platform(IOmNavigator *iface, BSTR *p)
679 OmNavigator *This = impl_from_IOmNavigator(iface);
681 #ifdef _WIN64
682 static const WCHAR platformW[] = {'W','i','n','6','4',0};
683 #else
684 static const WCHAR platformW[] = {'W','i','n','3','2',0};
685 #endif
687 TRACE("(%p)->(%p)\n", This, p);
689 *p = SysAllocString(platformW);
690 return S_OK;
693 static HRESULT WINAPI OmNavigator_get_appMinorVersion(IOmNavigator *iface, BSTR *p)
695 OmNavigator *This = impl_from_IOmNavigator(iface);
697 static const WCHAR zeroW[] = {'0',0};
699 TRACE("(%p)->(%p)\n", This, p);
701 /* NOTE: MSIE returns "0" or values like ";SP2;". Returning "0" should be enough. */
702 *p = SysAllocString(zeroW);
703 return S_OK;
706 static HRESULT WINAPI OmNavigator_get_connectionSpeed(IOmNavigator *iface, LONG *p)
708 OmNavigator *This = impl_from_IOmNavigator(iface);
709 FIXME("(%p)->(%p)\n", This, p);
710 return E_NOTIMPL;
713 static HRESULT WINAPI OmNavigator_get_onLine(IOmNavigator *iface, VARIANT_BOOL *p)
715 OmNavigator *This = impl_from_IOmNavigator(iface);
716 FIXME("(%p)->(%p)\n", This, p);
717 return E_NOTIMPL;
720 static HRESULT WINAPI OmNavigator_get_userProfile(IOmNavigator *iface, IHTMLOpsProfile **p)
722 OmNavigator *This = impl_from_IOmNavigator(iface);
723 FIXME("(%p)->(%p)\n", This, p);
724 return E_NOTIMPL;
727 static const IOmNavigatorVtbl OmNavigatorVtbl = {
728 OmNavigator_QueryInterface,
729 OmNavigator_AddRef,
730 OmNavigator_Release,
731 OmNavigator_GetTypeInfoCount,
732 OmNavigator_GetTypeInfo,
733 OmNavigator_GetIDsOfNames,
734 OmNavigator_Invoke,
735 OmNavigator_get_appCodeName,
736 OmNavigator_get_appName,
737 OmNavigator_get_appVersion,
738 OmNavigator_get_userAgent,
739 OmNavigator_javaEnabled,
740 OmNavigator_taintEnabled,
741 OmNavigator_get_mimeTypes,
742 OmNavigator_get_plugins,
743 OmNavigator_get_cookieEnabled,
744 OmNavigator_get_opsProfile,
745 OmNavigator_toString,
746 OmNavigator_get_cpuClass,
747 OmNavigator_get_systemLanguage,
748 OmNavigator_get_browserLanguage,
749 OmNavigator_get_userLanguage,
750 OmNavigator_get_platform,
751 OmNavigator_get_appMinorVersion,
752 OmNavigator_get_connectionSpeed,
753 OmNavigator_get_onLine,
754 OmNavigator_get_userProfile
757 static const tid_t OmNavigator_iface_tids[] = {
758 IOmNavigator_tid,
761 static dispex_static_data_t OmNavigator_dispex = {
762 NULL,
763 DispHTMLNavigator_tid,
764 NULL,
765 OmNavigator_iface_tids
768 IOmNavigator *OmNavigator_Create(void)
770 OmNavigator *ret;
772 ret = heap_alloc_zero(sizeof(*ret));
773 ret->IOmNavigator_iface.lpVtbl = &OmNavigatorVtbl;
774 ret->ref = 1;
776 init_dispex(&ret->dispex, (IUnknown*)&ret->IOmNavigator_iface, &OmNavigator_dispex);
778 return &ret->IOmNavigator_iface;