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