shell32: Added a stub for IShellDispatch2.
[wine] / dlls / shell32 / shelldispatch.c
1 /*
2  * IShellDispatch implementation
3  *
4  * Copyright 2010 Alexander Morozov for Etersoft
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20
21 #include "config.h"
22 #include "wine/port.h"
23
24 #include <stdarg.h>
25
26 #define COBJMACROS
27 #define NONAMELESSUNION
28 #define NONAMELESSSTRUCT
29
30 #include "windef.h"
31 #include "winbase.h"
32 #include "winreg.h"
33 #include "shlwapi.h"
34 #include "shlobj.h"
35 #include "shldisp.h"
36 #include "debughlp.h"
37
38 #include "wine/debug.h"
39
40 WINE_DEFAULT_DEBUG_CHANNEL(shell);
41
42 typedef struct {
43     IShellDispatch2 IShellDispatch2_iface;
44     LONG ref;
45     ITypeInfo *typeinfo;
46 } ShellDispatch;
47
48 typedef struct {
49     Folder3 Folder_iface;
50     LONG ref;
51     ITypeInfo *iTypeInfo;
52     VARIANT dir;
53 } FolderImpl;
54
55 typedef struct {
56     FolderItem FolderItem_iface;
57     LONG ref;
58     ITypeInfo *iTypeInfo;
59     VARIANT dir;
60 } FolderItemImpl;
61
62 static inline ShellDispatch *impl_from_IShellDispatch2(IShellDispatch2 *iface)
63 {
64     return CONTAINING_RECORD(iface, ShellDispatch, IShellDispatch2_iface);
65 }
66
67 static inline FolderImpl *impl_from_Folder(Folder3 *iface)
68 {
69     return CONTAINING_RECORD(iface, FolderImpl, Folder_iface);
70 }
71
72 static inline FolderItemImpl *impl_from_FolderItem(FolderItem *iface)
73 {
74     return CONTAINING_RECORD(iface, FolderItemImpl, FolderItem_iface);
75 }
76
77 static HRESULT load_type_info(REFGUID guid, ITypeInfo **pptinfo)
78 {
79     ITypeLib *typelib;
80     HRESULT ret;
81
82     ret = LoadRegTypeLib(&LIBID_Shell32, 1, 0, LOCALE_SYSTEM_DEFAULT, &typelib);
83     if (FAILED(ret))
84     {
85         ERR("LoadRegTypeLib failed: %08x\n", ret);
86         return ret;
87     }
88
89     ret = ITypeLib_GetTypeInfoOfGuid(typelib, guid, pptinfo);
90     ITypeLib_Release(typelib);
91     if (FAILED(ret))
92         ERR("failed to load ITypeInfo\n");
93
94     return ret;
95 }
96
97 static HRESULT WINAPI FolderItemImpl_QueryInterface(FolderItem *iface,
98         REFIID riid, LPVOID *ppv)
99 {
100     FolderItemImpl *This = impl_from_FolderItem(iface);
101
102     TRACE("(%p,%p,%p)\n", iface, riid, ppv);
103
104     if (!ppv) return E_INVALIDARG;
105
106     if (IsEqualIID(&IID_IUnknown, riid) ||
107         IsEqualIID(&IID_IDispatch, riid) ||
108         IsEqualIID(&IID_FolderItem, riid))
109         *ppv = This;
110     else
111     {
112         FIXME("not implemented for %s\n", shdebugstr_guid(riid));
113         *ppv = NULL;
114         return E_NOINTERFACE;
115     }
116     IUnknown_AddRef((IUnknown*)*ppv);
117     return S_OK;
118 }
119
120 static ULONG WINAPI FolderItemImpl_AddRef(FolderItem *iface)
121 {
122     FolderItemImpl *This = impl_from_FolderItem(iface);
123     ULONG ref = InterlockedIncrement(&This->ref);
124
125     TRACE("(%p), new refcount=%i\n", iface, ref);
126
127     return ref;
128 }
129
130 static ULONG WINAPI FolderItemImpl_Release(FolderItem *iface)
131 {
132     FolderItemImpl *This = impl_from_FolderItem(iface);
133     ULONG ref = InterlockedDecrement(&This->ref);
134
135     TRACE("(%p), new refcount=%i\n", iface, ref);
136
137     if (!ref)
138     {
139         VariantClear(&This->dir);
140         ITypeInfo_Release(This->iTypeInfo);
141         HeapFree(GetProcessHeap(), 0, This);
142     }
143     return ref;
144 }
145
146 static HRESULT WINAPI FolderItemImpl_GetTypeInfoCount(FolderItem *iface,
147         UINT *pctinfo)
148 {
149     TRACE("(%p,%p)\n", iface, pctinfo);
150
151     *pctinfo = 1;
152     return S_OK;
153 }
154
155 static HRESULT WINAPI FolderItemImpl_GetTypeInfo(FolderItem *iface, UINT iTInfo,
156         LCID lcid, ITypeInfo **ppTInfo)
157 {
158     FolderItemImpl *This = impl_from_FolderItem(iface);
159
160     TRACE("(%p,%u,%d,%p)\n", iface, iTInfo, lcid, ppTInfo);
161
162     ITypeInfo_AddRef(This->iTypeInfo);
163     *ppTInfo = This->iTypeInfo;
164     return S_OK;
165 }
166
167 static HRESULT WINAPI FolderItemImpl_GetIDsOfNames(FolderItem *iface,
168         REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid,
169         DISPID *rgDispId)
170 {
171     FolderItemImpl *This = impl_from_FolderItem(iface);
172
173     TRACE("(%p,%p,%p,%u,%d,%p)\n", iface, riid, rgszNames, cNames, lcid,
174             rgDispId);
175
176     return ITypeInfo_GetIDsOfNames(This->iTypeInfo, rgszNames, cNames, rgDispId);
177 }
178
179 static HRESULT WINAPI FolderItemImpl_Invoke(FolderItem *iface,
180         DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags,
181         DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo,
182         UINT *puArgErr)
183 {
184     FolderItemImpl *This = impl_from_FolderItem(iface);
185
186     TRACE("(%p,%d,%p,%d,%u,%p,%p,%p,%p)\n", iface, dispIdMember, riid, lcid,
187             wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
188
189     return ITypeInfo_Invoke(This->iTypeInfo, This, dispIdMember, wFlags,
190             pDispParams, pVarResult, pExcepInfo, puArgErr);
191 }
192
193 static HRESULT WINAPI FolderItemImpl_get_Application(FolderItem *iface,
194         IDispatch **ppid)
195 {
196     FIXME("(%p,%p)\n", iface, ppid);
197
198     *ppid = NULL;
199     return E_NOTIMPL;
200 }
201
202 static HRESULT WINAPI FolderItemImpl_get_Parent(FolderItem *iface,
203         IDispatch **ppid)
204 {
205     FIXME("(%p,%p)\n", iface, ppid);
206
207     *ppid = NULL;
208     return E_NOTIMPL;
209 }
210
211 static HRESULT WINAPI FolderItemImpl_get_Name(FolderItem *iface, BSTR *pbs)
212 {
213     FIXME("(%p,%p)\n", iface, pbs);
214
215     *pbs = NULL;
216     return E_NOTIMPL;
217 }
218
219 static HRESULT WINAPI FolderItemImpl_put_Name(FolderItem *iface, BSTR bs)
220 {
221     FIXME("(%p,%s)\n", iface, debugstr_w(bs));
222
223     return E_NOTIMPL;
224 }
225
226 static HRESULT WINAPI FolderItemImpl_get_Path(FolderItem *iface, BSTR *pbs)
227 {
228     FolderItemImpl *This = impl_from_FolderItem(iface);
229     HRESULT ret = S_OK;
230     WCHAR *pathW;
231     int len;
232
233     TRACE("(%p,%p)\n", iface, pbs);
234
235     *pbs = NULL;
236     if (V_VT(&This->dir) == VT_I4)
237     {
238         pathW = HeapAlloc(GetProcessHeap(), 0, MAX_PATH * sizeof(WCHAR));
239         if (!pathW) return E_OUTOFMEMORY;
240         ret = SHGetFolderPathW(NULL, V_I4(&This->dir), NULL, SHGFP_TYPE_CURRENT,
241                 pathW);
242         if (ret == S_OK)
243             *pbs = SysAllocString(pathW);
244         else if (ret == E_INVALIDARG)
245         {
246             FIXME("not implemented for %#x\n", V_I4(&This->dir));
247             ret = E_NOTIMPL;
248         }
249         HeapFree(GetProcessHeap(), 0, pathW);
250     }
251     else /* VT_BSTR */
252     {
253         pathW = V_BSTR(&This->dir);
254         len = lstrlenW(pathW);
255         *pbs = SysAllocStringLen(pathW, pathW[len - 1] == '\\' ? len - 1 : len);
256     }
257     if (ret == S_OK && !*pbs)
258         ret = E_OUTOFMEMORY;
259     return ret;
260 }
261
262 static HRESULT WINAPI FolderItemImpl_get_GetLink(FolderItem *iface,
263         IDispatch **ppid)
264 {
265     FIXME("(%p,%p)\n", iface, ppid);
266
267     *ppid = NULL;
268     return E_NOTIMPL;
269 }
270
271 static HRESULT WINAPI FolderItemImpl_get_GetFolder(FolderItem *iface,
272         IDispatch **ppid)
273 {
274     FIXME("(%p,%p)\n", iface, ppid);
275
276     *ppid = NULL;
277     return E_NOTIMPL;
278 }
279
280 static HRESULT WINAPI FolderItemImpl_get_IsLink(FolderItem *iface,
281         VARIANT_BOOL *pb)
282 {
283     FIXME("(%p,%p)\n", iface, pb);
284
285     return E_NOTIMPL;
286 }
287
288 static HRESULT WINAPI FolderItemImpl_get_IsFolder(FolderItem *iface,
289         VARIANT_BOOL *pb)
290 {
291     FIXME("(%p,%p)\n", iface, pb);
292
293     return E_NOTIMPL;
294 }
295
296 static HRESULT WINAPI FolderItemImpl_get_IsFileSystem(FolderItem *iface,
297         VARIANT_BOOL *pb)
298 {
299     FIXME("(%p,%p)\n", iface, pb);
300
301     return E_NOTIMPL;
302 }
303
304 static HRESULT WINAPI FolderItemImpl_get_IsBrowsable(FolderItem *iface,
305         VARIANT_BOOL *pb)
306 {
307     FIXME("(%p,%p)\n", iface, pb);
308
309     return E_NOTIMPL;
310 }
311
312 static HRESULT WINAPI FolderItemImpl_get_ModifyDate(FolderItem *iface,
313         DATE *pdt)
314 {
315     FIXME("(%p,%p)\n", iface, pdt);
316
317     return E_NOTIMPL;
318 }
319
320 static HRESULT WINAPI FolderItemImpl_put_ModifyDate(FolderItem *iface, DATE dt)
321 {
322     FIXME("(%p,%f)\n", iface, dt);
323
324     return E_NOTIMPL;
325 }
326
327 static HRESULT WINAPI FolderItemImpl_get_Size(FolderItem *iface, LONG *pul)
328 {
329     FIXME("(%p,%p)\n", iface, pul);
330
331     return E_NOTIMPL;
332 }
333
334 static HRESULT WINAPI FolderItemImpl_get_Type(FolderItem *iface, BSTR *pbs)
335 {
336     FIXME("(%p,%p)\n", iface, pbs);
337
338     *pbs = NULL;
339     return E_NOTIMPL;
340 }
341
342 static HRESULT WINAPI FolderItemImpl_Verbs(FolderItem *iface,
343         FolderItemVerbs **ppfic)
344 {
345     FIXME("(%p,%p)\n", iface, ppfic);
346
347     *ppfic = NULL;
348     return E_NOTIMPL;
349 }
350
351 static HRESULT WINAPI FolderItemImpl_InvokeVerb(FolderItem *iface,
352         VARIANT vVerb)
353 {
354     FIXME("(%p)\n", iface);
355
356     return E_NOTIMPL;
357 }
358
359 static const FolderItemVtbl FolderItemImpl_Vtbl = {
360     FolderItemImpl_QueryInterface,
361     FolderItemImpl_AddRef,
362     FolderItemImpl_Release,
363     FolderItemImpl_GetTypeInfoCount,
364     FolderItemImpl_GetTypeInfo,
365     FolderItemImpl_GetIDsOfNames,
366     FolderItemImpl_Invoke,
367     FolderItemImpl_get_Application,
368     FolderItemImpl_get_Parent,
369     FolderItemImpl_get_Name,
370     FolderItemImpl_put_Name,
371     FolderItemImpl_get_Path,
372     FolderItemImpl_get_GetLink,
373     FolderItemImpl_get_GetFolder,
374     FolderItemImpl_get_IsLink,
375     FolderItemImpl_get_IsFolder,
376     FolderItemImpl_get_IsFileSystem,
377     FolderItemImpl_get_IsBrowsable,
378     FolderItemImpl_get_ModifyDate,
379     FolderItemImpl_put_ModifyDate,
380     FolderItemImpl_get_Size,
381     FolderItemImpl_get_Type,
382     FolderItemImpl_Verbs,
383     FolderItemImpl_InvokeVerb
384 };
385
386 static HRESULT FolderItem_Constructor(VARIANT *dir, FolderItem **ppfi)
387 {
388     FolderItemImpl *This;
389     HRESULT ret;
390
391     *ppfi = NULL;
392
393     This = HeapAlloc(GetProcessHeap(), 0, sizeof(FolderItemImpl));
394     if (!This) return E_OUTOFMEMORY;
395     This->FolderItem_iface.lpVtbl = &FolderItemImpl_Vtbl;
396     This->ref = 1;
397
398     ret = load_type_info(&IID_FolderItem, &This->iTypeInfo);
399     if (FAILED(ret))
400     {
401         HeapFree(GetProcessHeap(), 0, This);
402         return ret;
403     }
404
405     VariantInit(&This->dir);
406     ret = VariantCopy(&This->dir, dir);
407     if (FAILED(ret))
408     {
409         ITypeInfo_Release(This->iTypeInfo);
410         HeapFree(GetProcessHeap(), 0, This);
411         return E_OUTOFMEMORY;
412     }
413
414     *ppfi = (FolderItem*)This;
415     return ret;
416 }
417
418 static HRESULT WINAPI FolderImpl_QueryInterface(Folder3 *iface, REFIID riid,
419         LPVOID *ppv)
420 {
421     FolderImpl *This = impl_from_Folder(iface);
422
423     TRACE("(%p,%p,%p)\n", iface, riid, ppv);
424
425     if (!ppv) return E_INVALIDARG;
426
427     if (IsEqualIID(&IID_IUnknown, riid) ||
428         IsEqualIID(&IID_IDispatch, riid) ||
429         IsEqualIID(&IID_Folder, riid) ||
430         IsEqualIID(&IID_Folder2, riid) ||
431         IsEqualIID(&IID_Folder3, riid))
432         *ppv = This;
433     else
434     {
435         FIXME("not implemented for %s\n", shdebugstr_guid(riid));
436         *ppv = NULL;
437         return E_NOINTERFACE;
438     }
439     IUnknown_AddRef((IUnknown*)*ppv);
440     return S_OK;
441 }
442
443 static ULONG WINAPI FolderImpl_AddRef(Folder3 *iface)
444 {
445     FolderImpl *This = impl_from_Folder(iface);
446     ULONG ref = InterlockedIncrement(&This->ref);
447
448     TRACE("(%p), new refcount=%i\n", iface, ref);
449
450     return ref;
451 }
452
453 static ULONG WINAPI FolderImpl_Release(Folder3 *iface)
454 {
455     FolderImpl *This = impl_from_Folder(iface);
456     ULONG ref = InterlockedDecrement(&This->ref);
457
458     TRACE("(%p), new refcount=%i\n", iface, ref);
459
460     if (!ref)
461     {
462         VariantClear(&This->dir);
463         ITypeInfo_Release(This->iTypeInfo);
464         HeapFree(GetProcessHeap(), 0, This);
465     }
466     return ref;
467 }
468
469 static HRESULT WINAPI FolderImpl_GetTypeInfoCount(Folder3 *iface, UINT *pctinfo)
470 {
471     TRACE("(%p,%p)\n", iface, pctinfo);
472
473     *pctinfo = 1;
474     return S_OK;
475 }
476
477 static HRESULT WINAPI FolderImpl_GetTypeInfo(Folder3 *iface, UINT iTInfo,
478         LCID lcid, ITypeInfo **ppTInfo)
479 {
480     FolderImpl *This = impl_from_Folder(iface);
481
482     TRACE("(%p,%u,%d,%p)\n", iface, iTInfo, lcid, ppTInfo);
483
484     ITypeInfo_AddRef(This->iTypeInfo);
485     *ppTInfo = This->iTypeInfo;
486     return S_OK;
487 }
488
489 static HRESULT WINAPI FolderImpl_GetIDsOfNames(Folder3 *iface, REFIID riid,
490         LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
491 {
492     FolderImpl *This = impl_from_Folder(iface);
493
494     TRACE("(%p,%p,%p,%u,%d,%p)\n", iface, riid, rgszNames, cNames, lcid,
495             rgDispId);
496
497     return ITypeInfo_GetIDsOfNames(This->iTypeInfo, rgszNames, cNames,
498             rgDispId);
499 }
500
501 static HRESULT WINAPI FolderImpl_Invoke(Folder3 *iface, DISPID dispIdMember,
502         REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
503         VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
504 {
505     FolderImpl *This = impl_from_Folder(iface);
506
507     TRACE("(%p,%d,%p,%d,%u,%p,%p,%p,%p)\n", iface, dispIdMember, riid, lcid,
508             wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
509
510     return ITypeInfo_Invoke(This->iTypeInfo, This, dispIdMember, wFlags,
511             pDispParams, pVarResult, pExcepInfo, puArgErr);
512 }
513
514 static HRESULT WINAPI FolderImpl_get_Title(Folder3 *iface, BSTR *pbs)
515 {
516     FolderImpl *This = impl_from_Folder(iface);
517     WCHAR *p;
518     int len;
519
520     TRACE("(%p,%p)\n", iface, pbs);
521
522     *pbs = NULL;
523
524     if (V_VT(&This->dir) == VT_I4)
525     {
526         FIXME("special folder constants are not supported\n");
527         return E_NOTIMPL;
528     }
529     p = PathFindFileNameW(V_BSTR(&This->dir));
530     len = lstrlenW(p);
531     *pbs = SysAllocStringLen(p, p[len - 1] == '\\' ? len - 1 : len);
532     return *pbs ? S_OK : E_OUTOFMEMORY;
533 }
534
535 static HRESULT WINAPI FolderImpl_get_Application(Folder3 *iface,
536         IDispatch **ppid)
537 {
538     FIXME("(%p,%p)\n", iface, ppid);
539
540     *ppid = NULL;
541     return E_NOTIMPL;
542 }
543
544 static HRESULT WINAPI FolderImpl_get_Parent(Folder3 *iface, IDispatch **ppid)
545 {
546     FIXME("(%p,%p)\n", iface, ppid);
547
548     *ppid = NULL;
549     return E_NOTIMPL;
550 }
551
552 static HRESULT WINAPI FolderImpl_get_ParentFolder(Folder3 *iface, Folder **ppsf)
553 {
554     FIXME("(%p,%p)\n", iface, ppsf);
555
556     *ppsf = NULL;
557     return E_NOTIMPL;
558 }
559
560 static HRESULT WINAPI FolderImpl_Items(Folder3 *iface, FolderItems **ppid)
561 {
562     FIXME("(%p,%p)\n", iface, ppid);
563
564     *ppid = NULL;
565     return E_NOTIMPL;
566 }
567
568 static HRESULT WINAPI FolderImpl_ParseName(Folder3 *iface, BSTR bName,
569         FolderItem **ppid)
570 {
571     FIXME("(%p,%s,%p)\n", iface, debugstr_w(bName), ppid);
572
573     *ppid = NULL;
574     return E_NOTIMPL;
575 }
576
577 static HRESULT WINAPI FolderImpl_NewFolder(Folder3 *iface, BSTR bName,
578         VARIANT vOptions)
579 {
580     FIXME("(%p,%s)\n", iface, debugstr_w(bName));
581
582     return E_NOTIMPL;
583 }
584
585 static HRESULT WINAPI FolderImpl_MoveHere(Folder3 *iface, VARIANT vItem,
586         VARIANT vOptions)
587 {
588     FIXME("(%p)\n", iface);
589
590     return E_NOTIMPL;
591 }
592
593 static HRESULT WINAPI FolderImpl_CopyHere(Folder3 *iface, VARIANT vItem,
594         VARIANT vOptions)
595 {
596     FIXME("(%p)\n", iface);
597
598     return E_NOTIMPL;
599 }
600
601 static HRESULT WINAPI FolderImpl_GetDetailsOf(Folder3 *iface, VARIANT vItem,
602         int iColumn, BSTR *pbs)
603 {
604     FIXME("(%p,%d,%p)\n", iface, iColumn, pbs);
605
606     *pbs = NULL;
607     return E_NOTIMPL;
608 }
609
610 static HRESULT WINAPI FolderImpl_get_Self(Folder3 *iface, FolderItem **ppfi)
611 {
612     FolderImpl *This = impl_from_Folder(iface);
613
614     TRACE("(%p,%p)\n", iface, ppfi);
615
616     return FolderItem_Constructor(&This->dir, ppfi);
617 }
618
619 static HRESULT WINAPI FolderImpl_get_OfflineStatus(Folder3 *iface, LONG *pul)
620 {
621     FIXME("(%p,%p)\n", iface, pul);
622
623     return E_NOTIMPL;
624 }
625
626 static HRESULT WINAPI FolderImpl_Synchronize(Folder3 *iface)
627 {
628     FIXME("(%p)\n", iface);
629
630     return E_NOTIMPL;
631 }
632
633 static HRESULT WINAPI FolderImpl_get_HaveToShowWebViewBarricade(Folder3 *iface,
634         VARIANT_BOOL *pbHaveToShowWebViewBarricade)
635 {
636     FIXME("(%p,%p)\n", iface, pbHaveToShowWebViewBarricade);
637
638     return E_NOTIMPL;
639 }
640
641 static HRESULT WINAPI FolderImpl_DismissedWebViewBarricade(Folder3 *iface)
642 {
643     FIXME("(%p)\n", iface);
644
645     return E_NOTIMPL;
646 }
647
648 static HRESULT WINAPI FolderImpl_get_ShowWebViewBarricade(Folder3 *iface,
649         VARIANT_BOOL *pbShowWebViewBarricade)
650 {
651     FIXME("(%p,%p)\n", iface, pbShowWebViewBarricade);
652
653     return E_NOTIMPL;
654 }
655
656 static HRESULT WINAPI FolderImpl_put_ShowWebViewBarricade(Folder3 *iface,
657         VARIANT_BOOL bShowWebViewBarricade)
658 {
659     FIXME("(%p,%d)\n", iface, bShowWebViewBarricade);
660
661     return E_NOTIMPL;
662 }
663
664 static const Folder3Vtbl FolderImpl_Vtbl = {
665     FolderImpl_QueryInterface,
666     FolderImpl_AddRef,
667     FolderImpl_Release,
668     FolderImpl_GetTypeInfoCount,
669     FolderImpl_GetTypeInfo,
670     FolderImpl_GetIDsOfNames,
671     FolderImpl_Invoke,
672     FolderImpl_get_Title,
673     FolderImpl_get_Application,
674     FolderImpl_get_Parent,
675     FolderImpl_get_ParentFolder,
676     FolderImpl_Items,
677     FolderImpl_ParseName,
678     FolderImpl_NewFolder,
679     FolderImpl_MoveHere,
680     FolderImpl_CopyHere,
681     FolderImpl_GetDetailsOf,
682     FolderImpl_get_Self,
683     FolderImpl_get_OfflineStatus,
684     FolderImpl_Synchronize,
685     FolderImpl_get_HaveToShowWebViewBarricade,
686     FolderImpl_DismissedWebViewBarricade,
687     FolderImpl_get_ShowWebViewBarricade,
688     FolderImpl_put_ShowWebViewBarricade
689 };
690
691 static HRESULT Folder_Constructor(VARIANT *dir, Folder **ppsdf)
692 {
693     FolderImpl *This;
694     HRESULT ret;
695
696     *ppsdf = NULL;
697
698     switch (V_VT(dir))
699     {
700         case VT_I4:
701             /* FIXME: add some checks */
702             break;
703         case VT_BSTR:
704             if (PathIsDirectoryW(V_BSTR(dir)) &&
705                 !PathIsRelativeW(V_BSTR(dir)) &&
706                 PathFileExistsW(V_BSTR(dir)))
707                 break;
708         default:
709             return S_FALSE;
710     }
711
712     This = HeapAlloc(GetProcessHeap(), 0, sizeof(FolderImpl));
713     if (!This) return E_OUTOFMEMORY;
714     This->Folder_iface.lpVtbl = &FolderImpl_Vtbl;
715     This->ref = 1;
716
717     ret = load_type_info(&IID_Folder3, &This->iTypeInfo);
718     if (FAILED(ret))
719     {
720         HeapFree(GetProcessHeap(), 0, This);
721         return ret;
722     }
723
724     VariantInit(&This->dir);
725     ret = VariantCopy(&This->dir, dir);
726     if (FAILED(ret))
727     {
728         ITypeInfo_Release(This->iTypeInfo);
729         HeapFree(GetProcessHeap(), 0, This);
730         return E_OUTOFMEMORY;
731     }
732
733     *ppsdf = (Folder*)This;
734     return ret;
735 }
736
737 static HRESULT WINAPI ShellDispatch_QueryInterface(IShellDispatch2 *iface,
738         REFIID riid, LPVOID *ppv)
739 {
740     ShellDispatch *This = impl_from_IShellDispatch2(iface);
741
742     TRACE("(%p,%p,%p)\n", iface, riid, ppv);
743
744     if (!ppv) return E_INVALIDARG;
745
746     if (IsEqualIID(&IID_IUnknown, riid) ||
747         IsEqualIID(&IID_IDispatch, riid) ||
748         IsEqualIID(&IID_IShellDispatch, riid) ||
749         IsEqualIID(&IID_IShellDispatch2, riid))
750         *ppv = This;
751     else
752     {
753         FIXME("not implemented for %s\n", shdebugstr_guid(riid));
754         *ppv = NULL;
755         return E_NOINTERFACE;
756     }
757
758     IShellDispatch2_AddRef(iface);
759     return S_OK;
760 }
761
762 static ULONG WINAPI ShellDispatch_AddRef(IShellDispatch2 *iface)
763 {
764     ShellDispatch *This = impl_from_IShellDispatch2(iface);
765     ULONG ref = InterlockedIncrement(&This->ref);
766
767     TRACE("(%p), new refcount=%i\n", iface, ref);
768
769     return ref;
770 }
771
772 static ULONG WINAPI ShellDispatch_Release(IShellDispatch2 *iface)
773 {
774     ShellDispatch *This = impl_from_IShellDispatch2(iface);
775     ULONG ref = InterlockedDecrement(&This->ref);
776
777     TRACE("(%p), new refcount=%i\n", iface, ref);
778
779     if (!ref)
780     {
781         ITypeInfo_Release(This->typeinfo);
782         HeapFree(GetProcessHeap(), 0, This);
783     }
784     return ref;
785 }
786
787 static HRESULT WINAPI ShellDispatch_GetTypeInfoCount(IShellDispatch2 *iface,
788         UINT *pctinfo)
789 {
790     TRACE("(%p,%p)\n", iface, pctinfo);
791
792     *pctinfo = 1;
793     return S_OK;
794 }
795
796 static HRESULT WINAPI ShellDispatch_GetTypeInfo(IShellDispatch2 *iface,
797         UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo)
798 {
799     ShellDispatch *This = impl_from_IShellDispatch2(iface);
800
801     TRACE("(%p,%u,%d,%p)\n", iface, iTInfo, lcid, ppTInfo);
802
803     ITypeInfo_AddRef(This->typeinfo);
804     *ppTInfo = This->typeinfo;
805     return S_OK;
806 }
807
808 static HRESULT WINAPI ShellDispatch_GetIDsOfNames(IShellDispatch2 *iface,
809         REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
810 {
811     ShellDispatch *This = impl_from_IShellDispatch2(iface);
812
813     TRACE("(%p,%p,%p,%u,%d,%p)\n", iface, riid, rgszNames, cNames, lcid,
814             rgDispId);
815
816     return ITypeInfo_GetIDsOfNames(This->typeinfo, rgszNames, cNames, rgDispId);
817 }
818
819 static HRESULT WINAPI ShellDispatch_Invoke(IShellDispatch2 *iface,
820         DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags,
821         DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo,
822         UINT *puArgErr)
823 {
824     ShellDispatch *This = impl_from_IShellDispatch2(iface);
825
826     TRACE("(%p,%d,%p,%d,%u,%p,%p,%p,%p)\n", iface, dispIdMember, riid, lcid,
827             wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
828
829     return ITypeInfo_Invoke(This->typeinfo, This, dispIdMember, wFlags,
830             pDispParams, pVarResult, pExcepInfo, puArgErr);
831 }
832
833 static HRESULT WINAPI ShellDispatch_get_Application(IShellDispatch2 *iface,
834         IDispatch **ppid)
835 {
836     FIXME("(%p,%p)\n", iface, ppid);
837
838     *ppid = NULL;
839     return E_NOTIMPL;
840 }
841
842 static HRESULT WINAPI ShellDispatch_get_Parent(IShellDispatch2 *iface,
843         IDispatch **ppid)
844 {
845     FIXME("(%p,%p)\n", iface, ppid);
846
847     *ppid = NULL;
848     return E_NOTIMPL;
849 }
850
851 static HRESULT WINAPI ShellDispatch_NameSpace(IShellDispatch2 *iface,
852         VARIANT vDir, Folder **ppsdf)
853 {
854     TRACE("(%p,%p)\n", iface, ppsdf);
855
856     return Folder_Constructor(&vDir, ppsdf);
857 }
858
859 static HRESULT WINAPI ShellDispatch_BrowseForFolder(IShellDispatch2 *iface,
860         LONG Hwnd, BSTR Title, LONG Options, VARIANT RootFolder, Folder **ppsdf)
861 {
862     FIXME("(%p,%x,%s,%x,%p)\n", iface, Hwnd, debugstr_w(Title), Options, ppsdf);
863
864     *ppsdf = NULL;
865     return E_NOTIMPL;
866 }
867
868 static HRESULT WINAPI ShellDispatch_Windows(IShellDispatch2 *iface,
869         IDispatch **ppid)
870 {
871     FIXME("(%p,%p)\n", iface, ppid);
872
873     *ppid = NULL;
874     return E_NOTIMPL;
875 }
876
877 static HRESULT WINAPI ShellDispatch_Open(IShellDispatch2 *iface, VARIANT vDir)
878 {
879     FIXME("(%p)\n", iface);
880
881     return E_NOTIMPL;
882 }
883
884 static HRESULT WINAPI ShellDispatch_Explore(IShellDispatch2 *iface, VARIANT vDir)
885 {
886     FIXME("(%p)\n", iface);
887
888     return E_NOTIMPL;
889 }
890
891 static HRESULT WINAPI ShellDispatch_MinimizeAll(IShellDispatch2 *iface)
892 {
893     FIXME("(%p)\n", iface);
894
895     return E_NOTIMPL;
896 }
897
898 static HRESULT WINAPI ShellDispatch_UndoMinimizeALL(IShellDispatch2 *iface)
899 {
900     FIXME("(%p)\n", iface);
901
902     return E_NOTIMPL;
903 }
904
905 static HRESULT WINAPI ShellDispatch_FileRun(IShellDispatch2 *iface)
906 {
907     FIXME("(%p)\n", iface);
908
909     return E_NOTIMPL;
910 }
911
912 static HRESULT WINAPI ShellDispatch_CascadeWindows(IShellDispatch2 *iface)
913 {
914     FIXME("(%p)\n", iface);
915
916     return E_NOTIMPL;
917 }
918
919 static HRESULT WINAPI ShellDispatch_TileVertically(IShellDispatch2 *iface)
920 {
921     FIXME("(%p)\n", iface);
922
923     return E_NOTIMPL;
924 }
925
926 static HRESULT WINAPI ShellDispatch_TileHorizontally(IShellDispatch2 *iface)
927 {
928     FIXME("(%p)\n", iface);
929
930     return E_NOTIMPL;
931 }
932
933 static HRESULT WINAPI ShellDispatch_ShutdownWindows(IShellDispatch2 *iface)
934 {
935     FIXME("(%p)\n", iface);
936
937     return E_NOTIMPL;
938 }
939
940 static HRESULT WINAPI ShellDispatch_Suspend(IShellDispatch2 *iface)
941 {
942     FIXME("(%p)\n", iface);
943
944     return E_NOTIMPL;
945 }
946
947 static HRESULT WINAPI ShellDispatch_EjectPC(IShellDispatch2 *iface)
948 {
949     FIXME("(%p)\n", iface);
950
951     return E_NOTIMPL;
952 }
953
954 static HRESULT WINAPI ShellDispatch_SetTime(IShellDispatch2 *iface)
955 {
956     FIXME("(%p)\n", iface);
957
958     return E_NOTIMPL;
959 }
960
961 static HRESULT WINAPI ShellDispatch_TrayProperties(IShellDispatch2 *iface)
962 {
963     FIXME("(%p)\n", iface);
964
965     return E_NOTIMPL;
966 }
967
968 static HRESULT WINAPI ShellDispatch_Help(IShellDispatch2 *iface)
969 {
970     FIXME("(%p)\n", iface);
971
972     return E_NOTIMPL;
973 }
974
975 static HRESULT WINAPI ShellDispatch_FindFiles(IShellDispatch2 *iface)
976 {
977     FIXME("(%p)\n", iface);
978
979     return E_NOTIMPL;
980 }
981
982 static HRESULT WINAPI ShellDispatch_FindComputer(IShellDispatch2 *iface)
983 {
984     FIXME("(%p)\n", iface);
985
986     return E_NOTIMPL;
987 }
988
989 static HRESULT WINAPI ShellDispatch_RefreshMenu(IShellDispatch2 *iface)
990 {
991     FIXME("(%p)\n", iface);
992
993     return E_NOTIMPL;
994 }
995
996 static HRESULT WINAPI ShellDispatch_ControlPanelItem(IShellDispatch2 *iface,
997         BSTR szDir)
998 {
999     FIXME("(%p,%s)\n", iface, debugstr_w(szDir));
1000
1001     return E_NOTIMPL;
1002 }
1003
1004 static HRESULT WINAPI ShellDispatch_IsRestricted(IShellDispatch2 *iface, BSTR group, BSTR restriction, LONG *value)
1005 {
1006     FIXME("(%s, %s, %p): stub\n", debugstr_w(group), debugstr_w(restriction), value);
1007     return E_NOTIMPL;
1008 }
1009
1010 static HRESULT WINAPI ShellDispatch_ShellExecute(IShellDispatch2 *iface, BSTR file, VARIANT args, VARIANT dir,
1011         VARIANT op, VARIANT show)
1012 {
1013     FIXME("(%s): stub\n", debugstr_w(file));
1014     return E_NOTIMPL;
1015 }
1016
1017 static HRESULT WINAPI ShellDispatch_FindPrinter(IShellDispatch2 *iface, BSTR name, BSTR location, BSTR model)
1018 {
1019     FIXME("(%s, %s, %s): stub\n", debugstr_w(name), debugstr_w(location), debugstr_w(model));
1020     return E_NOTIMPL;
1021 }
1022
1023 static HRESULT WINAPI ShellDispatch_GetSystemInformation(IShellDispatch2 *iface, BSTR name, VARIANT *ret)
1024 {
1025     FIXME("(%s, %p): stub\n", debugstr_w(name), ret);
1026     return E_NOTIMPL;
1027 }
1028
1029 static HRESULT WINAPI ShellDispatch_ServiceStart(IShellDispatch2 *iface, BSTR service, VARIANT persistent, VARIANT *ret)
1030 {
1031     FIXME("(%s, %p): stub\n", debugstr_w(service), ret);
1032     return E_NOTIMPL;
1033 }
1034
1035 static HRESULT WINAPI ShellDispatch_ServiceStop(IShellDispatch2 *iface, BSTR service, VARIANT persistent, VARIANT *ret)
1036 {
1037     FIXME("(%s, %p): stub\n", debugstr_w(service), ret);
1038     return E_NOTIMPL;
1039 }
1040
1041 static HRESULT WINAPI ShellDispatch_IsServiceRunning(IShellDispatch2 *iface, BSTR service, VARIANT *running)
1042 {
1043     FIXME("(%s, %p): stub\n", debugstr_w(service), running);
1044     return E_NOTIMPL;
1045 }
1046
1047 static HRESULT WINAPI ShellDispatch_CanStartStopService(IShellDispatch2 *iface, BSTR service, VARIANT *ret)
1048 {
1049     FIXME("(%s, %p): stub\n", debugstr_w(service), ret);
1050     return E_NOTIMPL;
1051 }
1052
1053 static HRESULT WINAPI ShellDispatch_ShowBrowserBar(IShellDispatch2 *iface, BSTR clsid, VARIANT show, VARIANT *ret)
1054 {
1055     FIXME("(%s, %p): stub\n", debugstr_w(clsid), ret);
1056     return E_NOTIMPL;
1057 }
1058
1059 static const IShellDispatch2Vtbl ShellDispatch2Vtbl = {
1060     ShellDispatch_QueryInterface,
1061     ShellDispatch_AddRef,
1062     ShellDispatch_Release,
1063     ShellDispatch_GetTypeInfoCount,
1064     ShellDispatch_GetTypeInfo,
1065     ShellDispatch_GetIDsOfNames,
1066     ShellDispatch_Invoke,
1067     ShellDispatch_get_Application,
1068     ShellDispatch_get_Parent,
1069     ShellDispatch_NameSpace,
1070     ShellDispatch_BrowseForFolder,
1071     ShellDispatch_Windows,
1072     ShellDispatch_Open,
1073     ShellDispatch_Explore,
1074     ShellDispatch_MinimizeAll,
1075     ShellDispatch_UndoMinimizeALL,
1076     ShellDispatch_FileRun,
1077     ShellDispatch_CascadeWindows,
1078     ShellDispatch_TileVertically,
1079     ShellDispatch_TileHorizontally,
1080     ShellDispatch_ShutdownWindows,
1081     ShellDispatch_Suspend,
1082     ShellDispatch_EjectPC,
1083     ShellDispatch_SetTime,
1084     ShellDispatch_TrayProperties,
1085     ShellDispatch_Help,
1086     ShellDispatch_FindFiles,
1087     ShellDispatch_FindComputer,
1088     ShellDispatch_RefreshMenu,
1089     ShellDispatch_ControlPanelItem,
1090     ShellDispatch_IsRestricted,
1091     ShellDispatch_ShellExecute,
1092     ShellDispatch_FindPrinter,
1093     ShellDispatch_GetSystemInformation,
1094     ShellDispatch_ServiceStart,
1095     ShellDispatch_ServiceStop,
1096     ShellDispatch_IsServiceRunning,
1097     ShellDispatch_CanStartStopService,
1098     ShellDispatch_ShowBrowserBar
1099 };
1100
1101 HRESULT WINAPI IShellDispatch_Constructor(IUnknown *outer, REFIID riid, void **ppv)
1102 {
1103     ShellDispatch *This;
1104     HRESULT ret;
1105
1106     TRACE("(%p, %s)\n", outer, debugstr_guid(riid));
1107
1108     *ppv = NULL;
1109
1110     if (outer) return CLASS_E_NOAGGREGATION;
1111
1112     This = HeapAlloc(GetProcessHeap(), 0, sizeof(ShellDispatch));
1113     if (!This) return E_OUTOFMEMORY;
1114     This->IShellDispatch2_iface.lpVtbl = &ShellDispatch2Vtbl;
1115     This->ref = 1;
1116
1117     ret = load_type_info(&IID_IShellDispatch2, &This->typeinfo);
1118     if (FAILED(ret))
1119     {
1120         HeapFree(GetProcessHeap(), 0, This);
1121         return ret;
1122     }
1123
1124     ret = IShellDispatch2_QueryInterface(&This->IShellDispatch2_iface, riid, ppv);
1125     IShellDispatch2_Release(&This->IShellDispatch2_iface);
1126     return ret;
1127 }