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