d3d9: Implement IDirect3DVertexBuffer9 private data handling on top of wined3d_resource.
[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 typedef struct HTMLMimeTypesCollection HTMLMimeTypesCollection;
36
37 typedef struct {
38     DispatchEx dispex;
39     IOmNavigator IOmNavigator_iface;
40
41     LONG ref;
42
43     HTMLPluginsCollection *plugins;
44     HTMLMimeTypesCollection *mime_types;
45 } OmNavigator;
46
47 static inline OmNavigator *impl_from_IOmNavigator(IOmNavigator *iface)
48 {
49     return CONTAINING_RECORD(iface, OmNavigator, IOmNavigator_iface);
50 }
51
52 struct HTMLPluginsCollection {
53     DispatchEx dispex;
54     IHTMLPluginsCollection IHTMLPluginsCollection_iface;
55
56     LONG ref;
57
58     OmNavigator *navigator;
59 };
60
61 static inline HTMLPluginsCollection *impl_from_IHTMLPluginsCollection(IHTMLPluginsCollection *iface)
62 {
63     return CONTAINING_RECORD(iface, HTMLPluginsCollection, IHTMLPluginsCollection_iface);
64 }
65
66 static HRESULT WINAPI HTMLPluginsCollection_QueryInterface(IHTMLPluginsCollection *iface, REFIID riid, void **ppv)
67 {
68     HTMLPluginsCollection *This = impl_from_IHTMLPluginsCollection(iface);
69
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;
82     }
83
84     IUnknown_AddRef((IUnknown*)*ppv);
85     return S_OK;
86 }
87
88 static ULONG WINAPI HTMLPluginsCollection_AddRef(IHTMLPluginsCollection *iface)
89 {
90     HTMLPluginsCollection *This = impl_from_IHTMLPluginsCollection(iface);
91     LONG ref = InterlockedIncrement(&This->ref);
92
93     TRACE("(%p) ref=%d\n", This, ref);
94
95     return ref;
96 }
97
98 static ULONG WINAPI HTMLPluginsCollection_Release(IHTMLPluginsCollection *iface)
99 {
100     HTMLPluginsCollection *This = impl_from_IHTMLPluginsCollection(iface);
101     LONG ref = InterlockedDecrement(&This->ref);
102
103     TRACE("(%p) ref=%d\n", This, ref);
104
105     if(!ref) {
106         if(This->navigator)
107             This->navigator->plugins = NULL;
108         release_dispex(&This->dispex);
109         heap_free(This);
110     }
111
112     return ref;
113 }
114
115 static HRESULT WINAPI HTMLPluginsCollection_GetTypeInfoCount(IHTMLPluginsCollection *iface, UINT *pctinfo)
116 {
117     HTMLPluginsCollection *This = impl_from_IHTMLPluginsCollection(iface);
118     return IDispatchEx_GetTypeInfoCount(&This->dispex.IDispatchEx_iface, pctinfo);
119 }
120
121 static HRESULT WINAPI HTMLPluginsCollection_GetTypeInfo(IHTMLPluginsCollection *iface, UINT iTInfo,
122                                               LCID lcid, ITypeInfo **ppTInfo)
123 {
124     HTMLPluginsCollection *This = impl_from_IHTMLPluginsCollection(iface);
125     return IDispatchEx_GetTypeInfo(&This->dispex.IDispatchEx_iface, iTInfo, lcid, ppTInfo);
126 }
127
128 static HRESULT WINAPI HTMLPluginsCollection_GetIDsOfNames(IHTMLPluginsCollection *iface, REFIID riid,
129         LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
130 {
131     HTMLPluginsCollection *This = impl_from_IHTMLPluginsCollection(iface);
132     return IDispatchEx_GetIDsOfNames(&This->dispex.IDispatchEx_iface, riid, rgszNames, cNames,
133             lcid, rgDispId);
134 }
135
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)
139 {
140     HTMLPluginsCollection *This = impl_from_IHTMLPluginsCollection(iface);
141     return IDispatchEx_Invoke(&This->dispex.IDispatchEx_iface, dispIdMember, riid, lcid,
142             wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
143 }
144
145 static HRESULT WINAPI HTMLPluginsCollection_get_length(IHTMLPluginsCollection *iface, LONG *p)
146 {
147     HTMLPluginsCollection *This = impl_from_IHTMLPluginsCollection(iface);
148     FIXME("(%p)->(%p)\n", This, p);
149     return E_NOTIMPL;
150 }
151
152 static HRESULT WINAPI HTMLPluginsCollection_refresh(IHTMLPluginsCollection *iface, VARIANT_BOOL reload)
153 {
154     HTMLPluginsCollection *This = impl_from_IHTMLPluginsCollection(iface);
155     FIXME("(%p)->(%x)\n", This, reload);
156     return E_NOTIMPL;
157 }
158
159 static const IHTMLPluginsCollectionVtbl HTMLPluginsCollectionVtbl = {
160     HTMLPluginsCollection_QueryInterface,
161     HTMLPluginsCollection_AddRef,
162     HTMLPluginsCollection_Release,
163     HTMLPluginsCollection_GetTypeInfoCount,
164     HTMLPluginsCollection_GetTypeInfo,
165     HTMLPluginsCollection_GetIDsOfNames,
166     HTMLPluginsCollection_Invoke,
167     HTMLPluginsCollection_get_length,
168     HTMLPluginsCollection_refresh
169 };
170
171 static const tid_t HTMLPluginsCollection_iface_tids[] = {
172     IHTMLPluginsCollection_tid,
173     0
174 };
175 static dispex_static_data_t HTMLPluginsCollection_dispex = {
176     NULL,
177     DispCPlugins_tid,
178     NULL,
179     HTMLPluginsCollection_iface_tids
180 };
181
182 static HRESULT create_plugins_collection(OmNavigator *navigator, HTMLPluginsCollection **ret)
183 {
184     HTMLPluginsCollection *col;
185
186     col = heap_alloc_zero(sizeof(*col));
187     if(!col)
188         return E_OUTOFMEMORY;
189
190     col->IHTMLPluginsCollection_iface.lpVtbl = &HTMLPluginsCollectionVtbl;
191     col->ref = 1;
192     col->navigator = navigator;
193
194     init_dispex(&col->dispex, (IUnknown*)&col->IHTMLPluginsCollection_iface,
195                 &HTMLPluginsCollection_dispex);
196
197     *ret = col;
198     return S_OK;
199 }
200
201 struct HTMLMimeTypesCollection {
202     DispatchEx dispex;
203     IHTMLMimeTypesCollection IHTMLMimeTypesCollection_iface;
204
205     LONG ref;
206
207     OmNavigator *navigator;
208 };
209
210 static inline HTMLMimeTypesCollection *impl_from_IHTMLMimeTypesCollection(IHTMLMimeTypesCollection *iface)
211 {
212     return CONTAINING_RECORD(iface, HTMLMimeTypesCollection, IHTMLMimeTypesCollection_iface);
213 }
214
215 static HRESULT WINAPI HTMLMimeTypesCollection_QueryInterface(IHTMLMimeTypesCollection *iface, REFIID riid, void **ppv)
216 {
217     HTMLMimeTypesCollection *This = impl_from_IHTMLMimeTypesCollection(iface);
218
219     if(IsEqualGUID(&IID_IUnknown, riid)) {
220         TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
221         *ppv = &This->IHTMLMimeTypesCollection_iface;
222     }else if(IsEqualGUID(&IID_IHTMLMimeTypesCollection, riid)) {
223         TRACE("(%p)->(IID_IHTMLMimeTypesCollection %p)\n", This, ppv);
224         *ppv = &This->IHTMLMimeTypesCollection_iface;
225     }else if(dispex_query_interface(&This->dispex, riid, ppv)) {
226         return *ppv ? S_OK : E_NOINTERFACE;
227     }else {
228         *ppv = NULL;
229         WARN("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
230         return E_NOINTERFACE;
231     }
232
233     IUnknown_AddRef((IUnknown*)*ppv);
234     return S_OK;
235 }
236
237 static ULONG WINAPI HTMLMimeTypesCollection_AddRef(IHTMLMimeTypesCollection *iface)
238 {
239     HTMLMimeTypesCollection *This = impl_from_IHTMLMimeTypesCollection(iface);
240     LONG ref = InterlockedIncrement(&This->ref);
241
242     TRACE("(%p) ref=%d\n", This, ref);
243
244     return ref;
245 }
246
247 static ULONG WINAPI HTMLMimeTypesCollection_Release(IHTMLMimeTypesCollection *iface)
248 {
249     HTMLMimeTypesCollection *This = impl_from_IHTMLMimeTypesCollection(iface);
250     LONG ref = InterlockedDecrement(&This->ref);
251
252     TRACE("(%p) ref=%d\n", This, ref);
253
254     if(!ref) {
255         if(This->navigator)
256             This->navigator->mime_types = NULL;
257         release_dispex(&This->dispex);
258         heap_free(This);
259     }
260
261     return ref;
262 }
263
264 static HRESULT WINAPI HTMLMimeTypesCollection_GetTypeInfoCount(IHTMLMimeTypesCollection *iface, UINT *pctinfo)
265 {
266     HTMLMimeTypesCollection *This = impl_from_IHTMLMimeTypesCollection(iface);
267     return IDispatchEx_GetTypeInfoCount(&This->dispex.IDispatchEx_iface, pctinfo);
268 }
269
270 static HRESULT WINAPI HTMLMimeTypesCollection_GetTypeInfo(IHTMLMimeTypesCollection *iface, UINT iTInfo,
271                                               LCID lcid, ITypeInfo **ppTInfo)
272 {
273     HTMLMimeTypesCollection *This = impl_from_IHTMLMimeTypesCollection(iface);
274     return IDispatchEx_GetTypeInfo(&This->dispex.IDispatchEx_iface, iTInfo, lcid, ppTInfo);
275 }
276
277 static HRESULT WINAPI HTMLMimeTypesCollection_GetIDsOfNames(IHTMLMimeTypesCollection *iface, REFIID riid,
278         LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
279 {
280     HTMLMimeTypesCollection *This = impl_from_IHTMLMimeTypesCollection(iface);
281     return IDispatchEx_GetIDsOfNames(&This->dispex.IDispatchEx_iface, riid, rgszNames, cNames,
282             lcid, rgDispId);
283 }
284
285 static HRESULT WINAPI HTMLMimeTypesCollection_Invoke(IHTMLMimeTypesCollection *iface, DISPID dispIdMember,
286         REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult,
287         EXCEPINFO *pExcepInfo, UINT *puArgErr)
288 {
289     HTMLMimeTypesCollection *This = impl_from_IHTMLMimeTypesCollection(iface);
290     return IDispatchEx_Invoke(&This->dispex.IDispatchEx_iface, dispIdMember, riid, lcid,
291             wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
292 }
293
294 static HRESULT WINAPI HTMLMimeTypesCollection_get_length(IHTMLMimeTypesCollection *iface, LONG *p)
295 {
296     HTMLMimeTypesCollection *This = impl_from_IHTMLMimeTypesCollection(iface);
297
298     TRACE("(%p)->(%p)\n", This, p);
299
300     /* This is just a stub for compatibility with other browser in IE */
301     *p = 0;
302     return S_OK;
303 }
304
305 static const IHTMLMimeTypesCollectionVtbl HTMLMimeTypesCollectionVtbl = {
306     HTMLMimeTypesCollection_QueryInterface,
307     HTMLMimeTypesCollection_AddRef,
308     HTMLMimeTypesCollection_Release,
309     HTMLMimeTypesCollection_GetTypeInfoCount,
310     HTMLMimeTypesCollection_GetTypeInfo,
311     HTMLMimeTypesCollection_GetIDsOfNames,
312     HTMLMimeTypesCollection_Invoke,
313     HTMLMimeTypesCollection_get_length
314 };
315
316 static const tid_t HTMLMimeTypesCollection_iface_tids[] = {
317     IHTMLMimeTypesCollection_tid,
318     0
319 };
320 static dispex_static_data_t HTMLMimeTypesCollection_dispex = {
321     NULL,
322     IHTMLMimeTypesCollection_tid,
323     NULL,
324     HTMLMimeTypesCollection_iface_tids
325 };
326
327 static HRESULT create_mime_types_collection(OmNavigator *navigator, HTMLMimeTypesCollection **ret)
328 {
329     HTMLMimeTypesCollection *col;
330
331     col = heap_alloc_zero(sizeof(*col));
332     if(!col)
333         return E_OUTOFMEMORY;
334
335     col->IHTMLMimeTypesCollection_iface.lpVtbl = &HTMLMimeTypesCollectionVtbl;
336     col->ref = 1;
337     col->navigator = navigator;
338
339     init_dispex(&col->dispex, (IUnknown*)&col->IHTMLMimeTypesCollection_iface,
340                 &HTMLMimeTypesCollection_dispex);
341
342     *ret = col;
343     return S_OK;
344 }
345
346 static HRESULT WINAPI OmNavigator_QueryInterface(IOmNavigator *iface, REFIID riid, void **ppv)
347 {
348     OmNavigator *This = impl_from_IOmNavigator(iface);
349
350     *ppv = NULL;
351
352     if(IsEqualGUID(&IID_IUnknown, riid)) {
353         TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
354         *ppv = &This->IOmNavigator_iface;
355     }else if(IsEqualGUID(&IID_IOmNavigator, riid)) {
356         TRACE("(%p)->(IID_IOmNavigator %p)\n", This, ppv);
357         *ppv = &This->IOmNavigator_iface;
358     }else if(dispex_query_interface(&This->dispex, riid, ppv)) {
359         return *ppv ? S_OK : E_NOINTERFACE;
360     }
361
362     if(*ppv) {
363         IUnknown_AddRef((IUnknown*)*ppv);
364         return S_OK;
365     }
366
367     WARN("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
368     return E_NOINTERFACE;
369 }
370
371 static ULONG WINAPI OmNavigator_AddRef(IOmNavigator *iface)
372 {
373     OmNavigator *This = impl_from_IOmNavigator(iface);
374     LONG ref = InterlockedIncrement(&This->ref);
375
376     TRACE("(%p) ref=%d\n", This, ref);
377
378     return ref;
379 }
380
381 static ULONG WINAPI OmNavigator_Release(IOmNavigator *iface)
382 {
383     OmNavigator *This = impl_from_IOmNavigator(iface);
384     LONG ref = InterlockedDecrement(&This->ref);
385
386     TRACE("(%p) ref=%d\n", This, ref);
387
388     if(!ref) {
389         if(This->plugins)
390             This->plugins->navigator = NULL;
391         if(This->mime_types)
392             This->mime_types->navigator = NULL;
393         release_dispex(&This->dispex);
394         heap_free(This);
395     }
396
397     return ref;
398 }
399
400 static HRESULT WINAPI OmNavigator_GetTypeInfoCount(IOmNavigator *iface, UINT *pctinfo)
401 {
402     OmNavigator *This = impl_from_IOmNavigator(iface);
403     FIXME("(%p)->(%p)\n", This, pctinfo);
404     return E_NOTIMPL;
405 }
406
407 static HRESULT WINAPI OmNavigator_GetTypeInfo(IOmNavigator *iface, UINT iTInfo,
408                                               LCID lcid, ITypeInfo **ppTInfo)
409 {
410     OmNavigator *This = impl_from_IOmNavigator(iface);
411
412     return IDispatchEx_GetTypeInfo(&This->dispex.IDispatchEx_iface, iTInfo, lcid, ppTInfo);
413 }
414
415 static HRESULT WINAPI OmNavigator_GetIDsOfNames(IOmNavigator *iface, REFIID riid,
416                                                 LPOLESTR *rgszNames, UINT cNames,
417                                                 LCID lcid, DISPID *rgDispId)
418 {
419     OmNavigator *This = impl_from_IOmNavigator(iface);
420
421     return IDispatchEx_GetIDsOfNames(&This->dispex.IDispatchEx_iface, riid, rgszNames, cNames,
422             lcid, rgDispId);
423 }
424
425 static HRESULT WINAPI OmNavigator_Invoke(IOmNavigator *iface, DISPID dispIdMember,
426                             REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
427                             VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
428 {
429     OmNavigator *This = impl_from_IOmNavigator(iface);
430
431     return IDispatchEx_Invoke(&This->dispex.IDispatchEx_iface, dispIdMember, riid, lcid, wFlags,
432             pDispParams, pVarResult, pExcepInfo, puArgErr);
433 }
434
435 static HRESULT WINAPI OmNavigator_get_appCodeName(IOmNavigator *iface, BSTR *p)
436 {
437     OmNavigator *This = impl_from_IOmNavigator(iface);
438
439     static const WCHAR mozillaW[] = {'M','o','z','i','l','l','a',0};
440
441     TRACE("(%p)->(%p)\n", This, p);
442
443     *p = SysAllocString(mozillaW);
444     return S_OK;
445 }
446
447 static HRESULT WINAPI OmNavigator_get_appName(IOmNavigator *iface, BSTR *p)
448 {
449     OmNavigator *This = impl_from_IOmNavigator(iface);
450
451     static const WCHAR app_nameW[] =
452         {'M','i','c','r','o','s','o','f','t',' ',
453          'I','n','t','e','r','n','e','t',' ',
454          'E','x','p','l','o','r','e','r',0};
455
456     TRACE("(%p)->(%p)\n", This, p);
457
458     *p = SysAllocString(app_nameW);
459     if(!*p)
460         return E_OUTOFMEMORY;
461
462     return S_OK;
463 }
464
465 static HRESULT WINAPI OmNavigator_get_appVersion(IOmNavigator *iface, BSTR *p)
466 {
467     OmNavigator *This = impl_from_IOmNavigator(iface);
468
469     char user_agent[512];
470     DWORD size;
471     HRESULT hres;
472
473     TRACE("(%p)->(%p)\n", This, p);
474
475     size = sizeof(user_agent);
476     hres = ObtainUserAgentString(0, user_agent, &size);
477     if(FAILED(hres))
478         return hres;
479
480     if(strncmp(user_agent, "Mozilla/", 8)) {
481         FIXME("Unsupported user agent\n");
482         return E_FAIL;
483     }
484
485     size = MultiByteToWideChar(CP_ACP, 0, user_agent+8, -1, NULL, 0);
486     *p = SysAllocStringLen(NULL, size-1);
487     if(!*p)
488         return E_OUTOFMEMORY;
489
490     MultiByteToWideChar(CP_ACP, 0, user_agent+8, -1, *p, size);
491     return S_OK;
492 }
493
494 static HRESULT WINAPI OmNavigator_get_userAgent(IOmNavigator *iface, BSTR *p)
495 {
496     OmNavigator *This = impl_from_IOmNavigator(iface);
497     char user_agent[512];
498     DWORD size;
499     HRESULT hres;
500
501     TRACE("(%p)->(%p)\n", This, p);
502
503     size = sizeof(user_agent);
504     hres = ObtainUserAgentString(0, user_agent, &size);
505     if(FAILED(hres))
506         return hres;
507
508     size = MultiByteToWideChar(CP_ACP, 0, user_agent, -1, NULL, 0);
509     *p = SysAllocStringLen(NULL, size-1);
510     if(!*p)
511         return E_OUTOFMEMORY;
512
513     MultiByteToWideChar(CP_ACP, 0, user_agent, -1, *p, size);
514     return S_OK;
515 }
516
517 static HRESULT WINAPI OmNavigator_javaEnabled(IOmNavigator *iface, VARIANT_BOOL *enabled)
518 {
519     OmNavigator *This = impl_from_IOmNavigator(iface);
520
521     FIXME("(%p)->(%p) semi-stub\n", This, enabled);
522
523     *enabled = VARIANT_FALSE;
524     return S_OK;
525 }
526
527 static HRESULT WINAPI OmNavigator_taintEnabled(IOmNavigator *iface, VARIANT_BOOL *enabled)
528 {
529     OmNavigator *This = impl_from_IOmNavigator(iface);
530     FIXME("(%p)->(%p)\n", This, enabled);
531     return E_NOTIMPL;
532 }
533
534 static HRESULT WINAPI OmNavigator_get_mimeTypes(IOmNavigator *iface, IHTMLMimeTypesCollection **p)
535 {
536     OmNavigator *This = impl_from_IOmNavigator(iface);
537
538     TRACE("(%p)->(%p)\n", This, p);
539
540     if(!This->mime_types) {
541         HRESULT hres;
542
543         hres = create_mime_types_collection(This, &This->mime_types);
544         if(FAILED(hres))
545             return hres;
546     }else {
547         IHTMLMimeTypesCollection_AddRef(&This->mime_types->IHTMLMimeTypesCollection_iface);
548     }
549
550     *p = &This->mime_types->IHTMLMimeTypesCollection_iface;
551     return S_OK;
552 }
553
554 static HRESULT WINAPI OmNavigator_get_plugins(IOmNavigator *iface, IHTMLPluginsCollection **p)
555 {
556     OmNavigator *This = impl_from_IOmNavigator(iface);
557
558     TRACE("(%p)->(%p)\n", This, p);
559
560     if(!This->plugins) {
561         HRESULT hres;
562
563         hres = create_plugins_collection(This, &This->plugins);
564         if(FAILED(hres))
565             return hres;
566     }else {
567         IHTMLPluginsCollection_AddRef(&This->plugins->IHTMLPluginsCollection_iface);
568     }
569
570     *p = &This->plugins->IHTMLPluginsCollection_iface;
571     return S_OK;
572 }
573
574 static HRESULT WINAPI OmNavigator_get_cookieEnabled(IOmNavigator *iface, VARIANT_BOOL *p)
575 {
576     OmNavigator *This = impl_from_IOmNavigator(iface);
577     FIXME("(%p)->(%p)\n", This, p);
578     return E_NOTIMPL;
579 }
580
581 static HRESULT WINAPI OmNavigator_get_opsProfile(IOmNavigator *iface, IHTMLOpsProfile **p)
582 {
583     OmNavigator *This = impl_from_IOmNavigator(iface);
584     FIXME("(%p)->(%p)\n", This, p);
585     return E_NOTIMPL;
586 }
587
588 static HRESULT WINAPI OmNavigator_toString(IOmNavigator *iface, BSTR *String)
589 {
590     OmNavigator *This = impl_from_IOmNavigator(iface);
591
592     static const WCHAR objectW[] = {'[','o','b','j','e','c','t',']',0};
593
594     TRACE("(%p)->(%p)\n", This, String);
595
596     if(!String)
597         return E_INVALIDARG;
598
599     *String = SysAllocString(objectW);
600     return *String ? S_OK : E_OUTOFMEMORY;
601 }
602
603 static HRESULT WINAPI OmNavigator_get_cpuClass(IOmNavigator *iface, BSTR *p)
604 {
605     OmNavigator *This = impl_from_IOmNavigator(iface);
606
607     static const WCHAR cpu_classW[] =
608 #ifdef _WIN64
609         {'x','6','4',0};
610 #else
611         {'x','8','6',0};
612 #endif
613
614     TRACE("(%p)->(%p)\n", This, p);
615
616     *p = SysAllocString(cpu_classW);
617     return *p ? S_OK : E_OUTOFMEMORY;
618 }
619
620 static HRESULT WINAPI OmNavigator_get_systemLanguage(IOmNavigator *iface, BSTR *p)
621 {
622     OmNavigator *This = impl_from_IOmNavigator(iface);
623     FIXME("(%p)->(%p)\n", This, p);
624     return E_NOTIMPL;
625 }
626
627 static HRESULT WINAPI OmNavigator_get_browserLanguage(IOmNavigator *iface, BSTR *p)
628 {
629     OmNavigator *This = impl_from_IOmNavigator(iface);
630     FIXME("(%p)->(%p)\n", This, p);
631     return E_NOTIMPL;
632 }
633
634 static HRESULT WINAPI OmNavigator_get_userLanguage(IOmNavigator *iface, BSTR *p)
635 {
636     OmNavigator *This = impl_from_IOmNavigator(iface);
637     FIXME("(%p)->(%p)\n", This, p);
638     return E_NOTIMPL;
639 }
640
641 static HRESULT WINAPI OmNavigator_get_platform(IOmNavigator *iface, BSTR *p)
642 {
643     OmNavigator *This = impl_from_IOmNavigator(iface);
644
645 #ifdef _WIN64
646     static const WCHAR platformW[] = {'W','i','n','6','4',0};
647 #else
648     static const WCHAR platformW[] = {'W','i','n','3','2',0};
649 #endif
650
651     TRACE("(%p)->(%p)\n", This, p);
652
653     *p = SysAllocString(platformW);
654     return S_OK;
655 }
656
657 static HRESULT WINAPI OmNavigator_get_appMinorVersion(IOmNavigator *iface, BSTR *p)
658 {
659     OmNavigator *This = impl_from_IOmNavigator(iface);
660     FIXME("(%p)->(%p)\n", This, p);
661     return E_NOTIMPL;
662 }
663
664 static HRESULT WINAPI OmNavigator_get_connectionSpeed(IOmNavigator *iface, LONG *p)
665 {
666     OmNavigator *This = impl_from_IOmNavigator(iface);
667     FIXME("(%p)->(%p)\n", This, p);
668     return E_NOTIMPL;
669 }
670
671 static HRESULT WINAPI OmNavigator_get_onLine(IOmNavigator *iface, VARIANT_BOOL *p)
672 {
673     OmNavigator *This = impl_from_IOmNavigator(iface);
674     FIXME("(%p)->(%p)\n", This, p);
675     return E_NOTIMPL;
676 }
677
678 static HRESULT WINAPI OmNavigator_get_userProfile(IOmNavigator *iface, IHTMLOpsProfile **p)
679 {
680     OmNavigator *This = impl_from_IOmNavigator(iface);
681     FIXME("(%p)->(%p)\n", This, p);
682     return E_NOTIMPL;
683 }
684
685 static const IOmNavigatorVtbl OmNavigatorVtbl = {
686     OmNavigator_QueryInterface,
687     OmNavigator_AddRef,
688     OmNavigator_Release,
689     OmNavigator_GetTypeInfoCount,
690     OmNavigator_GetTypeInfo,
691     OmNavigator_GetIDsOfNames,
692     OmNavigator_Invoke,
693     OmNavigator_get_appCodeName,
694     OmNavigator_get_appName,
695     OmNavigator_get_appVersion,
696     OmNavigator_get_userAgent,
697     OmNavigator_javaEnabled,
698     OmNavigator_taintEnabled,
699     OmNavigator_get_mimeTypes,
700     OmNavigator_get_plugins,
701     OmNavigator_get_cookieEnabled,
702     OmNavigator_get_opsProfile,
703     OmNavigator_toString,
704     OmNavigator_get_cpuClass,
705     OmNavigator_get_systemLanguage,
706     OmNavigator_get_browserLanguage,
707     OmNavigator_get_userLanguage,
708     OmNavigator_get_platform,
709     OmNavigator_get_appMinorVersion,
710     OmNavigator_get_connectionSpeed,
711     OmNavigator_get_onLine,
712     OmNavigator_get_userProfile
713 };
714
715 static const tid_t OmNavigator_iface_tids[] = {
716     IOmNavigator_tid,
717     0
718 };
719 static dispex_static_data_t OmNavigator_dispex = {
720     NULL,
721     DispHTMLNavigator_tid,
722     NULL,
723     OmNavigator_iface_tids
724 };
725
726 IOmNavigator *OmNavigator_Create(void)
727 {
728     OmNavigator *ret;
729
730     ret = heap_alloc_zero(sizeof(*ret));
731     ret->IOmNavigator_iface.lpVtbl = &OmNavigatorVtbl;
732     ret->ref = 1;
733
734     init_dispex(&ret->dispex, (IUnknown*)&ret->IOmNavigator_iface, &OmNavigator_dispex);
735
736     return &ret->IOmNavigator_iface;
737 }