shell32: Added missing arguments to trace messages.
[wine.git] / dlls / shell32 / shelldispatch.c
blob0baab6b27f5f176d5c018b91bfd1947aedcbdd59
1 /*
2 * IShellDispatch implementation
4 * Copyright 2010 Alexander Morozov for Etersoft
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.
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.
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
21 #include "config.h"
22 #include "wine/port.h"
24 #include <stdarg.h>
26 #define COBJMACROS
28 #include "windef.h"
29 #include "winbase.h"
30 #include "winreg.h"
31 #include "winsvc.h"
32 #include "shlwapi.h"
33 #include "shlobj.h"
34 #include "shldisp.h"
35 #include "debughlp.h"
37 #include "shell32_main.h"
38 #include "pidl.h"
40 #include "wine/debug.h"
42 WINE_DEFAULT_DEBUG_CHANNEL(shell);
44 static ITypeLib *typelib;
45 static const IID * const tid_ids[] =
47 &IID_NULL,
48 &IID_IShellDispatch6,
49 &IID_IShellFolderViewDual3,
50 &IID_Folder3,
51 &IID_FolderItem2,
52 &IID_FolderItems3,
53 &IID_FolderItemVerb,
54 &IID_FolderItemVerbs
56 static ITypeInfo *typeinfos[LAST_tid];
58 typedef struct {
59 IShellDispatch6 IShellDispatch6_iface;
60 LONG ref;
61 } ShellDispatch;
63 typedef struct {
64 Folder3 Folder3_iface;
65 LONG ref;
66 IDispatch *application;
67 IShellFolder2 *folder;
68 PIDLIST_ABSOLUTE pidl;
69 BSTR path;
70 } FolderImpl;
72 typedef struct {
73 FolderItems3 FolderItems3_iface;
74 LONG ref;
75 FolderImpl *folder;
76 BSTR *item_names;
77 LONG item_count;
78 } FolderItemsImpl;
80 typedef struct {
81 FolderItem2 FolderItem2_iface;
82 LONG ref;
83 FolderImpl *folder;
84 WCHAR *path; /* if NULL, folder path is used */
85 DWORD attributes;
86 } FolderItemImpl;
88 typedef struct {
89 FolderItemVerbs FolderItemVerbs_iface;
90 LONG ref;
92 IContextMenu *contextmenu;
93 HMENU hMenu;
94 LONG count;
95 } FolderItemVerbsImpl;
97 typedef struct {
98 FolderItemVerb FolderItemVerb_iface;
99 LONG ref;
101 IContextMenu *contextmenu;
102 BSTR name;
103 } FolderItemVerbImpl;
105 static inline ShellDispatch *impl_from_IShellDispatch6(IShellDispatch6 *iface)
107 return CONTAINING_RECORD(iface, ShellDispatch, IShellDispatch6_iface);
110 static inline FolderImpl *impl_from_Folder(Folder3 *iface)
112 return CONTAINING_RECORD(iface, FolderImpl, Folder3_iface);
115 static inline FolderItemsImpl *impl_from_FolderItems(FolderItems3 *iface)
117 return CONTAINING_RECORD(iface, FolderItemsImpl, FolderItems3_iface);
120 static inline FolderItemImpl *impl_from_FolderItem(FolderItem2 *iface)
122 return CONTAINING_RECORD(iface, FolderItemImpl, FolderItem2_iface);
125 static inline FolderItemVerbsImpl *impl_from_FolderItemVerbs(FolderItemVerbs *iface)
127 return CONTAINING_RECORD(iface, FolderItemVerbsImpl, FolderItemVerbs_iface);
130 static inline FolderItemVerbImpl *impl_from_FolderItemVerb(FolderItemVerb *iface)
132 return CONTAINING_RECORD(iface, FolderItemVerbImpl, FolderItemVerb_iface);
135 static HRESULT load_typelib(void)
137 ITypeLib *tl;
138 HRESULT hr;
140 hr = LoadRegTypeLib(&LIBID_Shell32, 1, 0, LOCALE_SYSTEM_DEFAULT, &tl);
141 if (FAILED(hr)) {
142 ERR("LoadRegTypeLib failed: %08x\n", hr);
143 return hr;
146 if (InterlockedCompareExchangePointer((void**)&typelib, tl, NULL))
147 ITypeLib_Release(tl);
148 return hr;
151 void release_typelib(void)
153 unsigned i;
155 if (!typelib)
156 return;
158 for (i = 0; i < sizeof(typeinfos)/sizeof(*typeinfos); i++)
159 if (typeinfos[i])
160 ITypeInfo_Release(typeinfos[i]);
162 ITypeLib_Release(typelib);
165 HRESULT get_typeinfo(enum tid_t tid, ITypeInfo **typeinfo)
167 HRESULT hr;
169 if (!typelib)
170 hr = load_typelib();
171 if (!typelib)
172 return hr;
174 if (!typeinfos[tid])
176 ITypeInfo *ti;
178 hr = ITypeLib_GetTypeInfoOfGuid(typelib, tid_ids[tid], &ti);
179 if (FAILED(hr))
181 ERR("GetTypeInfoOfGuid(%s) failed: %08x\n", debugstr_guid(tid_ids[tid]), hr);
182 return hr;
185 if (InterlockedCompareExchangePointer((void**)(typeinfos+tid), ti, NULL))
186 ITypeInfo_Release(ti);
189 *typeinfo = typeinfos[tid];
190 return S_OK;
193 /* FolderItemVerb */
194 static HRESULT WINAPI FolderItemVerbImpl_QueryInterface(FolderItemVerb *iface,
195 REFIID riid, void **ppv)
197 FolderItemVerbImpl *This = impl_from_FolderItemVerb(iface);
199 TRACE("(%p,%s,%p)\n", iface, debugstr_guid(riid), ppv);
201 if (IsEqualIID(&IID_IUnknown, riid) ||
202 IsEqualIID(&IID_IDispatch, riid) ||
203 IsEqualIID(&IID_FolderItemVerb, riid))
204 *ppv = &This->FolderItemVerb_iface;
205 else
207 WARN("not implemented for %s\n", debugstr_guid(riid));
208 *ppv = NULL;
209 return E_NOINTERFACE;
212 IUnknown_AddRef((IUnknown*)*ppv);
213 return S_OK;
216 static ULONG WINAPI FolderItemVerbImpl_AddRef(FolderItemVerb *iface)
218 FolderItemVerbImpl *This = impl_from_FolderItemVerb(iface);
219 ULONG ref = InterlockedIncrement(&This->ref);
221 TRACE("(%p), new refcount=%i\n", iface, ref);
223 return ref;
226 static ULONG WINAPI FolderItemVerbImpl_Release(FolderItemVerb *iface)
228 FolderItemVerbImpl *This = impl_from_FolderItemVerb(iface);
229 ULONG ref = InterlockedDecrement(&This->ref);
231 TRACE("(%p), new refcount=%i\n", iface, ref);
233 if (!ref)
235 IContextMenu_Release(This->contextmenu);
236 SysFreeString(This->name);
237 HeapFree(GetProcessHeap(), 0, This);
240 return ref;
243 static HRESULT WINAPI FolderItemVerbImpl_GetTypeInfoCount(FolderItemVerb *iface, UINT *pctinfo)
245 TRACE("(%p,%p)\n", iface, pctinfo);
246 *pctinfo = 1;
247 return S_OK;
250 static HRESULT WINAPI FolderItemVerbImpl_GetTypeInfo(FolderItemVerb *iface, UINT iTInfo,
251 LCID lcid, ITypeInfo **ppTInfo)
253 HRESULT hr;
255 TRACE("(%p,%u,%d,%p)\n", iface, iTInfo, lcid, ppTInfo);
257 hr = get_typeinfo(FolderItemVerb_tid, ppTInfo);
258 if (SUCCEEDED(hr))
259 ITypeInfo_AddRef(*ppTInfo);
260 return hr;
263 static HRESULT WINAPI FolderItemVerbImpl_GetIDsOfNames(FolderItemVerb *iface,
264 REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
266 ITypeInfo *ti;
267 HRESULT hr;
269 TRACE("(%p,%s,%p,%u,%d,%p)\n", iface, shdebugstr_guid(riid), rgszNames, cNames, lcid,
270 rgDispId);
272 hr = get_typeinfo(FolderItemVerb_tid, &ti);
273 if (SUCCEEDED(hr))
274 hr = ITypeInfo_GetIDsOfNames(ti, rgszNames, cNames, rgDispId);
275 return hr;
278 static HRESULT WINAPI FolderItemVerbImpl_Invoke(FolderItemVerb *iface,
279 DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags,
280 DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo,
281 UINT *puArgErr)
283 ITypeInfo *ti;
284 HRESULT hr;
286 TRACE("(%p,%d,%s,%d,%u,%p,%p,%p,%p)\n", iface, dispIdMember, shdebugstr_guid(riid), lcid,
287 wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
289 hr = get_typeinfo(FolderItemVerb_tid, &ti);
290 if (SUCCEEDED(hr))
291 hr = ITypeInfo_Invoke(ti, iface, dispIdMember, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
292 return hr;
295 static HRESULT WINAPI FolderItemVerbImpl_get_Application(FolderItemVerb *iface, IDispatch **disp)
297 TRACE("(%p, %p)\n", iface, disp);
299 if (disp)
300 *disp = NULL;
301 return E_NOTIMPL;
304 static HRESULT WINAPI FolderItemVerbImpl_get_Parent(FolderItemVerb *iface, IDispatch **disp)
306 TRACE("(%p, %p)\n", iface, disp);
308 if (disp)
309 *disp = NULL;
310 return E_NOTIMPL;
313 static HRESULT WINAPI FolderItemVerbImpl_get_Name(FolderItemVerb *iface, BSTR *name)
315 FolderItemVerbImpl *This = impl_from_FolderItemVerb(iface);
317 TRACE("(%p, %p)\n", iface, name);
319 *name = SysAllocString(This->name);
320 return *name ? S_OK : E_OUTOFMEMORY;
323 static HRESULT WINAPI FolderItemVerbImpl_DoIt(FolderItemVerb *iface)
325 FIXME("(%p)\n", iface);
326 return E_NOTIMPL;
329 static FolderItemVerbVtbl folderitemverbvtbl = {
330 FolderItemVerbImpl_QueryInterface,
331 FolderItemVerbImpl_AddRef,
332 FolderItemVerbImpl_Release,
333 FolderItemVerbImpl_GetTypeInfoCount,
334 FolderItemVerbImpl_GetTypeInfo,
335 FolderItemVerbImpl_GetIDsOfNames,
336 FolderItemVerbImpl_Invoke,
337 FolderItemVerbImpl_get_Application,
338 FolderItemVerbImpl_get_Parent,
339 FolderItemVerbImpl_get_Name,
340 FolderItemVerbImpl_DoIt
343 static HRESULT FolderItemVerb_Constructor(IContextMenu *contextmenu, BSTR name, FolderItemVerb **verb)
345 FolderItemVerbImpl *This;
347 TRACE("%p, %s\n", contextmenu, debugstr_w(name));
349 This = HeapAlloc(GetProcessHeap(), 0, sizeof(FolderItemVerbImpl));
350 if (!This)
351 return E_OUTOFMEMORY;
353 This->FolderItemVerb_iface.lpVtbl = &folderitemverbvtbl;
354 This->ref = 1;
355 This->contextmenu = contextmenu;
356 IContextMenu_AddRef(contextmenu);
357 This->name = name;
359 *verb = &This->FolderItemVerb_iface;
360 return S_OK;
363 /* FolderItemVerbs */
364 static HRESULT WINAPI FolderItemVerbsImpl_QueryInterface(FolderItemVerbs *iface,
365 REFIID riid, void **ppv)
367 FolderItemVerbsImpl *This = impl_from_FolderItemVerbs(iface);
369 TRACE("(%p,%s,%p)\n", iface, debugstr_guid(riid), ppv);
371 if (IsEqualIID(&IID_IUnknown, riid) ||
372 IsEqualIID(&IID_IDispatch, riid) ||
373 IsEqualIID(&IID_FolderItemVerbs, riid))
374 *ppv = &This->FolderItemVerbs_iface;
375 else
377 WARN("not implemented for %s\n", debugstr_guid(riid));
378 *ppv = NULL;
379 return E_NOINTERFACE;
382 IUnknown_AddRef((IUnknown*)*ppv);
383 return S_OK;
386 static ULONG WINAPI FolderItemVerbsImpl_AddRef(FolderItemVerbs *iface)
388 FolderItemVerbsImpl *This = impl_from_FolderItemVerbs(iface);
389 ULONG ref = InterlockedIncrement(&This->ref);
391 TRACE("(%p), new refcount=%i\n", iface, ref);
393 return ref;
396 static ULONG WINAPI FolderItemVerbsImpl_Release(FolderItemVerbs *iface)
398 FolderItemVerbsImpl *This = impl_from_FolderItemVerbs(iface);
399 ULONG ref = InterlockedDecrement(&This->ref);
401 TRACE("(%p), new refcount=%i\n", iface, ref);
403 if (!ref)
405 IContextMenu_Release(This->contextmenu);
406 DestroyMenu(This->hMenu);
407 HeapFree(GetProcessHeap(), 0, This);
410 return ref;
413 static HRESULT WINAPI FolderItemVerbsImpl_GetTypeInfoCount(FolderItemVerbs *iface, UINT *pctinfo)
415 TRACE("(%p,%p)\n", iface, pctinfo);
416 *pctinfo = 1;
417 return S_OK;
420 static HRESULT WINAPI FolderItemVerbsImpl_GetTypeInfo(FolderItemVerbs *iface, UINT iTInfo,
421 LCID lcid, ITypeInfo **ppTInfo)
423 HRESULT hr;
425 TRACE("(%p,%u,%d,%p)\n", iface, iTInfo, lcid, ppTInfo);
427 hr = get_typeinfo(FolderItemVerbs_tid, ppTInfo);
428 if (SUCCEEDED(hr))
429 ITypeInfo_AddRef(*ppTInfo);
430 return hr;
433 static HRESULT WINAPI FolderItemVerbsImpl_GetIDsOfNames(FolderItemVerbs *iface,
434 REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
436 ITypeInfo *ti;
437 HRESULT hr;
439 TRACE("(%p,%s,%p,%u,%d,%p)\n", iface, shdebugstr_guid(riid), rgszNames, cNames, lcid,
440 rgDispId);
442 hr = get_typeinfo(FolderItemVerbs_tid, &ti);
443 if (SUCCEEDED(hr))
444 hr = ITypeInfo_GetIDsOfNames(ti, rgszNames, cNames, rgDispId);
445 return hr;
448 static HRESULT WINAPI FolderItemVerbsImpl_Invoke(FolderItemVerbs *iface,
449 DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags,
450 DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo,
451 UINT *puArgErr)
453 ITypeInfo *ti;
454 HRESULT hr;
456 TRACE("(%p,%d,%s,%d,%u,%p,%p,%p,%p)\n", iface, dispIdMember, shdebugstr_guid(riid), lcid,
457 wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
459 hr = get_typeinfo(FolderItemVerbs_tid, &ti);
460 if (SUCCEEDED(hr))
461 hr = ITypeInfo_Invoke(ti, iface, dispIdMember, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
462 return hr;
465 static HRESULT WINAPI FolderItemVerbsImpl_get_Count(FolderItemVerbs *iface, LONG *count)
467 FolderItemVerbsImpl *This = impl_from_FolderItemVerbs(iface);
469 TRACE("(%p, %p)\n", iface, count);
471 if (!count)
472 return E_INVALIDARG;
474 *count = This->count;
475 return S_OK;
478 static HRESULT WINAPI FolderItemVerbsImpl_get_Application(FolderItemVerbs *iface, IDispatch **disp)
480 TRACE("(%p, %p)\n", iface, disp);
482 if (disp)
483 *disp = NULL;
484 return E_NOTIMPL;
487 static HRESULT WINAPI FolderItemVerbsImpl_get_Parent(FolderItemVerbs *iface, IDispatch **disp)
489 TRACE("(%p, %p)\n", iface, disp);
491 if (disp)
492 *disp = NULL;
493 return E_NOTIMPL;
496 static HRESULT WINAPI FolderItemVerbsImpl_Item(FolderItemVerbs *iface, VARIANT index, FolderItemVerb **verb)
498 FolderItemVerbsImpl *This = impl_from_FolderItemVerbs(iface);
499 MENUITEMINFOW info;
500 HRESULT hr;
501 VARIANT v;
502 BSTR name;
504 TRACE("(%p, %s, %p)\n", iface, debugstr_variant(&index), verb);
506 if (!verb)
507 return E_INVALIDARG;
509 *verb = NULL;
511 VariantInit(&v);
512 VariantCopyInd(&v, &index);
514 hr = VariantChangeType(&v, &v, 0, VT_I4);
515 if (FAILED(hr))
517 FIXME("failed to coerce to VT_I4, %s\n", debugstr_variant(&v));
518 return hr;
521 if (V_I4(&v) > This->count)
522 return S_OK;
524 if (V_I4(&v) == This->count)
525 name = SysAllocStringLen(NULL, 0);
526 else
528 /* get item name */
529 memset(&info, 0, sizeof(info));
530 info.cbSize = sizeof(info);
531 info.fMask = MIIM_STRING;
532 if (!GetMenuItemInfoW(This->hMenu, V_I4(&v), TRUE, &info))
533 return E_FAIL;
535 name = SysAllocStringLen(NULL, info.cch);
536 if (name)
538 info.dwTypeData = name;
539 info.cch++;
540 GetMenuItemInfoW(This->hMenu, V_I4(&v), TRUE, &info);
544 if (!name)
545 return E_OUTOFMEMORY;
547 return FolderItemVerb_Constructor(This->contextmenu, name, verb);
550 static HRESULT WINAPI FolderItemVerbsImpl__NewEnum(FolderItemVerbs *iface, IUnknown **ret)
552 FIXME("(%p, %p)\n", iface, ret);
553 return E_NOTIMPL;
556 static FolderItemVerbsVtbl folderitemverbsvtbl = {
557 FolderItemVerbsImpl_QueryInterface,
558 FolderItemVerbsImpl_AddRef,
559 FolderItemVerbsImpl_Release,
560 FolderItemVerbsImpl_GetTypeInfoCount,
561 FolderItemVerbsImpl_GetTypeInfo,
562 FolderItemVerbsImpl_GetIDsOfNames,
563 FolderItemVerbsImpl_Invoke,
564 FolderItemVerbsImpl_get_Count,
565 FolderItemVerbsImpl_get_Application,
566 FolderItemVerbsImpl_get_Parent,
567 FolderItemVerbsImpl_Item,
568 FolderItemVerbsImpl__NewEnum
571 static HRESULT FolderItemVerbs_Constructor(BSTR path, FolderItemVerbs **verbs)
573 FolderItemVerbsImpl *This;
574 IShellFolder *folder;
575 LPCITEMIDLIST child;
576 LPITEMIDLIST pidl;
577 HRESULT hr;
579 *verbs = NULL;
581 This = HeapAlloc(GetProcessHeap(), 0, sizeof(FolderItemVerbsImpl));
582 if (!This)
583 return E_OUTOFMEMORY;
585 This->FolderItemVerbs_iface.lpVtbl = &folderitemverbsvtbl;
586 This->ref = 1;
588 /* build context menu for this path */
589 hr = SHParseDisplayName(path, NULL, &pidl, 0, NULL);
590 if (FAILED(hr))
591 goto failed;
593 hr = SHBindToParent(pidl, &IID_IShellFolder, (void**)&folder, &child);
594 CoTaskMemFree(pidl);
595 if (FAILED(hr))
596 goto failed;
598 hr = IShellFolder_GetUIObjectOf(folder, NULL, 1, &child, &IID_IContextMenu, NULL, (void**)&This->contextmenu);
599 IShellFolder_Release(folder);
600 if (FAILED(hr))
601 goto failed;
603 This->hMenu = CreatePopupMenu();
604 hr = IContextMenu_QueryContextMenu(This->contextmenu, This->hMenu, 0, FCIDM_SHVIEWFIRST, FCIDM_SHVIEWLAST, CMF_NORMAL);
605 if (FAILED(hr))
607 FolderItemVerbs_Release(&This->FolderItemVerbs_iface);
608 return hr;
611 This->count = GetMenuItemCount(This->hMenu);
612 *verbs = &This->FolderItemVerbs_iface;
613 return S_OK;
615 failed:
616 HeapFree(GetProcessHeap(), 0, This);
617 return hr;
620 static HRESULT WINAPI FolderItemImpl_QueryInterface(FolderItem2 *iface,
621 REFIID riid, LPVOID *ppv)
623 FolderItemImpl *This = impl_from_FolderItem(iface);
625 TRACE("(%p,%s,%p)\n", iface, debugstr_guid(riid), ppv);
627 if (!ppv) return E_INVALIDARG;
629 if (IsEqualIID(&IID_IUnknown, riid) ||
630 IsEqualIID(&IID_IDispatch, riid) ||
631 IsEqualIID(&IID_FolderItem, riid) ||
632 IsEqualIID(&IID_FolderItem2, riid))
633 *ppv = &This->FolderItem2_iface;
634 else
636 WARN("not implemented for %s\n", debugstr_guid(riid));
637 *ppv = NULL;
638 return E_NOINTERFACE;
640 IUnknown_AddRef((IUnknown*)*ppv);
641 return S_OK;
644 static ULONG WINAPI FolderItemImpl_AddRef(FolderItem2 *iface)
646 FolderItemImpl *This = impl_from_FolderItem(iface);
647 ULONG ref = InterlockedIncrement(&This->ref);
649 TRACE("(%p), new refcount=%i\n", iface, ref);
651 return ref;
654 static ULONG WINAPI FolderItemImpl_Release(FolderItem2 *iface)
656 FolderItemImpl *This = impl_from_FolderItem(iface);
657 ULONG ref = InterlockedDecrement(&This->ref);
659 TRACE("(%p), new refcount=%i\n", iface, ref);
661 if (!ref)
663 Folder3_Release(&This->folder->Folder3_iface);
664 HeapFree(GetProcessHeap(), 0, This->path);
665 HeapFree(GetProcessHeap(), 0, This);
667 return ref;
670 static HRESULT WINAPI FolderItemImpl_GetTypeInfoCount(FolderItem2 *iface,
671 UINT *pctinfo)
673 TRACE("(%p,%p)\n", iface, pctinfo);
675 *pctinfo = 1;
676 return S_OK;
679 static HRESULT WINAPI FolderItemImpl_GetTypeInfo(FolderItem2 *iface, UINT iTInfo,
680 LCID lcid, ITypeInfo **ppTInfo)
682 HRESULT hr;
684 TRACE("(%p,%u,%d,%p)\n", iface, iTInfo, lcid, ppTInfo);
686 hr = get_typeinfo(FolderItem2_tid, ppTInfo);
687 if (SUCCEEDED(hr))
688 ITypeInfo_AddRef(*ppTInfo);
689 return hr;
692 static HRESULT WINAPI FolderItemImpl_GetIDsOfNames(FolderItem2 *iface,
693 REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid,
694 DISPID *rgDispId)
696 ITypeInfo *ti;
697 HRESULT hr;
699 TRACE("(%p,%s,%p,%u,%d,%p)\n", iface, shdebugstr_guid(riid), rgszNames, cNames, lcid,
700 rgDispId);
702 hr = get_typeinfo(FolderItem2_tid, &ti);
703 if (SUCCEEDED(hr))
704 hr = ITypeInfo_GetIDsOfNames(ti, rgszNames, cNames, rgDispId);
705 return hr;
708 static HRESULT WINAPI FolderItemImpl_Invoke(FolderItem2 *iface,
709 DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags,
710 DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo,
711 UINT *puArgErr)
713 FolderItemImpl *This = impl_from_FolderItem(iface);
714 ITypeInfo *ti;
715 HRESULT hr;
717 TRACE("(%p,%d,%s,%d,%u,%p,%p,%p,%p)\n", iface, dispIdMember, shdebugstr_guid(riid), lcid,
718 wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
720 hr = get_typeinfo(FolderItem2_tid, &ti);
721 if (SUCCEEDED(hr))
722 hr = ITypeInfo_Invoke(ti, This, dispIdMember, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
723 return hr;
726 static HRESULT WINAPI FolderItemImpl_get_Application(FolderItem2 *iface, IDispatch **disp)
728 FolderItemImpl *This = impl_from_FolderItem(iface);
730 TRACE("(%p,%p)\n", iface, disp);
732 return Folder3_get_Application(&This->folder->Folder3_iface, disp);
735 static HRESULT WINAPI FolderItemImpl_get_Parent(FolderItem2 *iface, IDispatch **disp)
737 FolderItemImpl *This = impl_from_FolderItem(iface);
739 TRACE("(%p,%p)\n", iface, disp);
741 if (disp)
743 *disp = (IDispatch *)&This->folder->Folder3_iface;
744 IDispatch_AddRef(*disp);
747 return S_OK;
750 static HRESULT WINAPI FolderItemImpl_get_Name(FolderItem2 *iface, BSTR *name)
752 FolderItemImpl *This = impl_from_FolderItem(iface);
753 LPCITEMIDLIST last_part;
754 IShellFolder2 *parent;
755 HRESULT hr = S_OK;
756 LPITEMIDLIST pidl;
757 STRRET strret;
759 TRACE("(%p,%p)\n", iface, name);
761 *name = NULL;
763 if (This->path)
764 hr = SHParseDisplayName(This->path, NULL, &pidl, 0, NULL);
765 else
766 pidl = This->folder->pidl;
768 if (FAILED(hr))
769 return S_FALSE;
771 hr = SHBindToParent(pidl, &IID_IShellFolder2, (void **)&parent, &last_part);
772 if (hr == S_OK)
773 hr = IShellFolder2_GetDisplayNameOf(parent, last_part, SHGDN_INFOLDER, &strret);
775 IShellFolder2_Release(parent);
777 if (hr == S_OK)
778 hr = StrRetToBSTR(&strret, last_part, name);
780 if (This->path)
781 ILFree(pidl);
783 return hr;
786 static HRESULT WINAPI FolderItemImpl_put_Name(FolderItem2 *iface, BSTR bs)
788 FIXME("(%p,%s)\n", iface, debugstr_w(bs));
790 return E_NOTIMPL;
793 static HRESULT WINAPI FolderItemImpl_get_Path(FolderItem2 *iface, BSTR *path)
795 FolderItemImpl *This = impl_from_FolderItem(iface);
797 TRACE("(%p,%p)\n", iface, path);
799 *path = SysAllocString(This->path ? This->path : This->folder->path);
800 return *path ? S_OK : E_OUTOFMEMORY;
803 static HRESULT WINAPI FolderItemImpl_get_GetLink(FolderItem2 *iface,
804 IDispatch **ppid)
806 FIXME("(%p,%p)\n", iface, ppid);
808 *ppid = NULL;
809 return E_NOTIMPL;
812 static HRESULT WINAPI FolderItemImpl_get_GetFolder(FolderItem2 *iface,
813 IDispatch **ppid)
815 FIXME("(%p,%p)\n", iface, ppid);
817 *ppid = NULL;
818 return E_NOTIMPL;
821 static HRESULT WINAPI FolderItemImpl_get_IsLink(FolderItem2 *iface, VARIANT_BOOL *b)
823 FolderItemImpl *This = impl_from_FolderItem(iface);
825 TRACE("(%p,%p)\n", iface, b);
827 *b = This->attributes & SFGAO_LINK ? VARIANT_TRUE : VARIANT_FALSE;
829 return S_OK;
832 static HRESULT WINAPI FolderItemImpl_get_IsFolder(FolderItem2 *iface, VARIANT_BOOL *b)
834 FolderItemImpl *This = impl_from_FolderItem(iface);
836 TRACE("(%p,%p)\n", iface, b);
838 *b = This->attributes & SFGAO_FOLDER ? VARIANT_TRUE : VARIANT_FALSE;
840 return S_OK;
843 static HRESULT WINAPI FolderItemImpl_get_IsFileSystem(FolderItem2 *iface, VARIANT_BOOL *b)
845 FolderItemImpl *This = impl_from_FolderItem(iface);
847 TRACE("(%p,%p)\n", iface, b);
849 *b = This->attributes & SFGAO_FILESYSTEM ? VARIANT_TRUE : VARIANT_FALSE;
851 return S_OK;
854 static HRESULT WINAPI FolderItemImpl_get_IsBrowsable(FolderItem2 *iface, VARIANT_BOOL *b)
856 FolderItemImpl *This = impl_from_FolderItem(iface);
858 TRACE("(%p,%p)\n", iface, b);
860 *b = This->attributes & SFGAO_BROWSABLE ? VARIANT_TRUE : VARIANT_FALSE;
862 return S_OK;
865 static HRESULT WINAPI FolderItemImpl_get_ModifyDate(FolderItem2 *iface,
866 DATE *pdt)
868 FIXME("(%p,%p)\n", iface, pdt);
870 return E_NOTIMPL;
873 static HRESULT WINAPI FolderItemImpl_put_ModifyDate(FolderItem2 *iface, DATE dt)
875 FIXME("(%p,%f)\n", iface, dt);
877 return E_NOTIMPL;
880 static HRESULT WINAPI FolderItemImpl_get_Size(FolderItem2 *iface, LONG *pul)
882 FIXME("(%p,%p)\n", iface, pul);
884 return E_NOTIMPL;
887 static HRESULT WINAPI FolderItemImpl_get_Type(FolderItem2 *iface, BSTR *pbs)
889 FIXME("(%p,%p)\n", iface, pbs);
891 *pbs = NULL;
892 return E_NOTIMPL;
895 static HRESULT WINAPI FolderItemImpl_Verbs(FolderItem2 *iface, FolderItemVerbs **verbs)
897 FolderItemImpl *This = impl_from_FolderItem(iface);
899 TRACE("(%p, %p)\n", iface, verbs);
901 if (!verbs)
902 return E_INVALIDARG;
904 return FolderItemVerbs_Constructor(This->path ? This->path : This->folder->path, verbs);
907 static HRESULT WINAPI FolderItemImpl_InvokeVerb(FolderItem2 *iface,
908 VARIANT vVerb)
910 FIXME("(%p)\n", iface);
912 return E_NOTIMPL;
915 static HRESULT WINAPI FolderItemImpl_InvokeVerbEx(FolderItem2 *iface, VARIANT verb, VARIANT args)
917 FIXME("(%p): stub\n", iface);
919 return E_NOTIMPL;
922 static HRESULT WINAPI FolderItemImpl_ExtendedProperty(FolderItem2 *iface, BSTR propname, VARIANT *ret)
924 FIXME("(%p)->(%s %p): stub\n", iface, debugstr_w(propname), ret);
926 return E_NOTIMPL;
929 static const FolderItem2Vtbl FolderItemImpl_Vtbl = {
930 FolderItemImpl_QueryInterface,
931 FolderItemImpl_AddRef,
932 FolderItemImpl_Release,
933 FolderItemImpl_GetTypeInfoCount,
934 FolderItemImpl_GetTypeInfo,
935 FolderItemImpl_GetIDsOfNames,
936 FolderItemImpl_Invoke,
937 FolderItemImpl_get_Application,
938 FolderItemImpl_get_Parent,
939 FolderItemImpl_get_Name,
940 FolderItemImpl_put_Name,
941 FolderItemImpl_get_Path,
942 FolderItemImpl_get_GetLink,
943 FolderItemImpl_get_GetFolder,
944 FolderItemImpl_get_IsLink,
945 FolderItemImpl_get_IsFolder,
946 FolderItemImpl_get_IsFileSystem,
947 FolderItemImpl_get_IsBrowsable,
948 FolderItemImpl_get_ModifyDate,
949 FolderItemImpl_put_ModifyDate,
950 FolderItemImpl_get_Size,
951 FolderItemImpl_get_Type,
952 FolderItemImpl_Verbs,
953 FolderItemImpl_InvokeVerb,
954 FolderItemImpl_InvokeVerbEx,
955 FolderItemImpl_ExtendedProperty
958 static HRESULT FolderItem_Constructor(FolderImpl *folder, const WCHAR *path, FolderItem **item)
960 PIDLIST_ABSOLUTE pidl;
961 FolderItemImpl *This;
963 TRACE("%s\n", debugstr_w(path));
965 *item = NULL;
967 This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*This));
968 if (!This)
969 return E_OUTOFMEMORY;
971 This->FolderItem2_iface.lpVtbl = &FolderItemImpl_Vtbl;
972 This->ref = 1;
973 if (path)
974 This->path = strdupW(path);
976 This->folder = folder;
977 Folder3_AddRef(&folder->Folder3_iface);
979 if (SHParseDisplayName(This->path, NULL, &pidl, ~0u, &This->attributes) == S_OK)
980 ILFree(pidl);
982 *item = (FolderItem *)&This->FolderItem2_iface;
983 return S_OK;
986 static HRESULT WINAPI FolderItemsImpl_QueryInterface(FolderItems3 *iface,
987 REFIID riid, LPVOID *ppv)
989 FolderItemsImpl *This = impl_from_FolderItems(iface);
991 TRACE("(%p,%s,%p)\n", iface, debugstr_guid(riid), ppv);
993 if (!ppv) return E_INVALIDARG;
995 if (IsEqualIID(&IID_IUnknown, riid) ||
996 IsEqualIID(&IID_IDispatch, riid) ||
997 IsEqualIID(&IID_FolderItems, riid) ||
998 IsEqualIID(&IID_FolderItems2, riid) ||
999 IsEqualIID(&IID_FolderItems3, riid))
1000 *ppv = &This->FolderItems3_iface;
1001 else
1003 WARN("not implemented for %s\n", debugstr_guid(riid));
1004 *ppv = NULL;
1005 return E_NOINTERFACE;
1007 IUnknown_AddRef((IUnknown*)*ppv);
1008 return S_OK;
1011 static ULONG WINAPI FolderItemsImpl_AddRef(FolderItems3 *iface)
1013 FolderItemsImpl *This = impl_from_FolderItems(iface);
1014 ULONG ref = InterlockedIncrement(&This->ref);
1016 TRACE("(%p), new refcount=%i\n", iface, ref);
1018 return ref;
1021 static ULONG WINAPI FolderItemsImpl_Release(FolderItems3 *iface)
1023 FolderItemsImpl *This = impl_from_FolderItems(iface);
1024 ULONG ref = InterlockedDecrement(&This->ref);
1025 LONG i;
1027 TRACE("(%p), new refcount=%i\n", iface, ref);
1029 if (!ref)
1031 Folder3_Release(&This->folder->Folder3_iface);
1032 for (i = 0; i < This->item_count; i++)
1033 SysFreeString(This->item_names[i]);
1034 HeapFree(GetProcessHeap(), 0, This->item_names);
1035 HeapFree(GetProcessHeap(), 0, This);
1037 return ref;
1040 static HRESULT WINAPI FolderItemsImpl_GetTypeInfoCount(FolderItems3 *iface,
1041 UINT *count)
1043 TRACE("(%p,%p)\n", iface, count);
1045 *count = 1;
1046 return S_OK;
1049 static HRESULT WINAPI FolderItemsImpl_GetTypeInfo(FolderItems3 *iface,
1050 UINT type, LCID lcid, ITypeInfo **ppti)
1052 HRESULT hr;
1054 TRACE("(%p,%u,%d,%p)\n", iface, type, lcid, ppti);
1056 hr = get_typeinfo(FolderItems3_tid, ppti);
1057 if (SUCCEEDED(hr))
1058 ITypeInfo_AddRef(*ppti);
1059 return hr;
1062 static HRESULT WINAPI FolderItemsImpl_GetIDsOfNames(FolderItems3 *iface,
1063 REFIID riid, LPOLESTR *names, UINT count, LCID lcid, DISPID *dispid)
1065 ITypeInfo *ti;
1066 HRESULT hr;
1068 TRACE("(%p,%s,%p,%u,%d,%p)\n", iface, shdebugstr_guid(riid), names, count, lcid, dispid);
1070 hr = get_typeinfo(FolderItems3_tid, &ti);
1071 if (SUCCEEDED(hr))
1072 hr = ITypeInfo_GetIDsOfNames(ti, names, count, dispid);
1073 return hr;
1076 static HRESULT WINAPI FolderItemsImpl_Invoke(FolderItems3 *iface,
1077 DISPID dispid, REFIID riid, LCID lcid, WORD flags, DISPPARAMS *params,
1078 VARIANT *result, EXCEPINFO *ei, UINT *err)
1080 FolderItemsImpl *This = impl_from_FolderItems(iface);
1081 ITypeInfo *ti;
1082 HRESULT hr;
1084 TRACE("(%p,%d,%s,%d,%u,%p,%p,%p,%p)\n", iface, dispid, shdebugstr_guid(riid), lcid, flags, params, result, ei, err);
1086 hr = get_typeinfo(FolderItems3_tid, &ti);
1087 if (SUCCEEDED(hr))
1088 hr = ITypeInfo_Invoke(ti, This, dispid, flags, params, result, ei, err);
1089 return hr;
1092 static BOOL shellfolder_exists(const WCHAR *path)
1094 PIDLIST_ABSOLUTE pidl = NULL;
1095 HRESULT hr;
1097 hr = SHParseDisplayName(path, NULL, &pidl, 0, NULL);
1098 ILFree(pidl);
1100 return SUCCEEDED(hr);
1103 static HRESULT WINAPI FolderItemsImpl_get_Count(FolderItems3 *iface, LONG *count)
1105 FolderItemsImpl *This = impl_from_FolderItems(iface);
1107 TRACE("(%p,%p)\n", iface, count);
1109 *count = shellfolder_exists(This->folder->path) ? This->item_count : 0;
1110 return S_OK;
1113 static HRESULT WINAPI FolderItemsImpl_get_Application(FolderItems3 *iface, IDispatch **disp)
1115 FolderItemsImpl *This = impl_from_FolderItems(iface);
1117 TRACE("(%p,%p)\n", iface, disp);
1119 return Folder3_get_Application(&This->folder->Folder3_iface, disp);
1122 static HRESULT WINAPI FolderItemsImpl_get_Parent(FolderItems3 *iface, IDispatch **ppid)
1124 TRACE("(%p,%p)\n", iface, ppid);
1126 if (ppid)
1127 *ppid = NULL;
1129 return E_NOTIMPL;
1132 static HRESULT WINAPI FolderItemsImpl_Item(FolderItems3 *iface, VARIANT index, FolderItem **item)
1134 FolderItemsImpl *This = impl_from_FolderItems(iface);
1135 BSTR display_name = NULL;
1136 HRESULT hr;
1138 TRACE("(%p,%s,%p)\n", iface, debugstr_variant(&index), item);
1140 *item = NULL;
1142 if (!shellfolder_exists(This->folder->path))
1143 return S_FALSE;
1145 switch (V_VT(&index))
1147 case VT_I2:
1148 VariantChangeType(&index, &index, 0, VT_I4);
1149 /* fall through */
1151 case VT_I4:
1152 if (V_I4(&index) >= This->item_count || V_I4(&index) < 0)
1153 return S_FALSE;
1155 display_name = SysAllocString(This->item_names[V_I4(&index)]);
1156 break;
1158 case VT_BSTR:
1160 LPITEMIDLIST pidl;
1161 STRRET strret;
1163 if (!V_BSTR(&index))
1164 return S_FALSE;
1166 if (FAILED(hr = IShellFolder2_ParseDisplayName(This->folder->folder, NULL, NULL, V_BSTR(&index),
1167 NULL, &pidl, NULL)))
1168 return S_FALSE;
1170 if (IShellFolder2_GetDisplayNameOf(This->folder->folder, pidl, SHGDN_FORPARSING, &strret) == S_OK)
1171 StrRetToBSTR(&strret, pidl, &display_name);
1172 ILFree(pidl);
1173 break;
1175 case VT_ERROR:
1176 break;
1178 default:
1179 FIXME("Index type %d not handled.\n", V_VT(&index));
1180 /* fall through */
1181 case VT_EMPTY:
1182 return E_NOTIMPL;
1185 hr = FolderItem_Constructor(This->folder, display_name, item);
1186 SysFreeString(display_name);
1187 return hr;
1190 static HRESULT WINAPI FolderItemsImpl__NewEnum(FolderItems3 *iface, IUnknown **ppunk)
1192 FIXME("(%p,%p)\n", iface, ppunk);
1194 if (!ppunk)
1195 return E_INVALIDARG;
1197 *ppunk = NULL;
1198 return E_NOTIMPL;
1201 static HRESULT WINAPI FolderItemsImpl_InvokeVerbEx(FolderItems3 *iface, VARIANT verb, VARIANT args)
1203 FIXME("(%p,%s,%s)\n", iface, debugstr_variant(&verb), debugstr_variant(&args));
1205 return E_NOTIMPL;
1208 static HRESULT WINAPI FolderItemsImpl_Filter(FolderItems3 *iface, LONG flags, BSTR spec)
1210 FIXME("(%p,%d,%s)\n", iface, flags, wine_dbgstr_w(spec));
1212 return E_NOTIMPL;
1215 static HRESULT WINAPI FolderItemsImpl_get_Verbs(FolderItems3 *iface, FolderItemVerbs **ppfic)
1217 FIXME("(%p,%p)\n", iface, ppfic);
1219 if (!ppfic)
1220 return E_INVALIDARG;
1222 *ppfic = NULL;
1223 return E_NOTIMPL;
1226 static const FolderItems3Vtbl FolderItemsImpl_Vtbl = {
1227 FolderItemsImpl_QueryInterface,
1228 FolderItemsImpl_AddRef,
1229 FolderItemsImpl_Release,
1230 FolderItemsImpl_GetTypeInfoCount,
1231 FolderItemsImpl_GetTypeInfo,
1232 FolderItemsImpl_GetIDsOfNames,
1233 FolderItemsImpl_Invoke,
1234 FolderItemsImpl_get_Count,
1235 FolderItemsImpl_get_Application,
1236 FolderItemsImpl_get_Parent,
1237 FolderItemsImpl_Item,
1238 FolderItemsImpl__NewEnum,
1239 FolderItemsImpl_InvokeVerbEx,
1240 FolderItemsImpl_Filter,
1241 FolderItemsImpl_get_Verbs
1244 static void idlist_sort(LPITEMIDLIST *idlist, unsigned int l, unsigned int r, IShellFolder2 *folder)
1246 unsigned int m;
1248 if (l == r)
1249 return;
1251 if (r < l)
1253 idlist_sort(idlist, r, l, folder);
1254 return;
1257 m = (l + r) / 2;
1258 idlist_sort(idlist, l, m, folder);
1259 idlist_sort(idlist, m + 1, r, folder);
1261 /* join the two sides */
1262 while (l <= m && m < r)
1264 if ((short)IShellFolder2_CompareIDs(folder, 0, idlist[l], idlist[m + 1]) > 0)
1266 LPITEMIDLIST t = idlist[m + 1];
1267 memmove(&idlist[l + 1], &idlist[l], (m - l + 1) * sizeof(idlist[l]));
1268 idlist[l] = t;
1270 m++;
1272 l++;
1276 static HRESULT FolderItems_Constructor(FolderImpl *folder, FolderItems **ret)
1278 IEnumIDList *enumidlist;
1279 FolderItemsImpl *This;
1280 LPITEMIDLIST pidl;
1281 unsigned int i;
1282 HRESULT hr;
1284 TRACE("(%s,%p)\n", debugstr_w(folder->path), ret);
1286 *ret = NULL;
1288 This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*This));
1289 if (!This)
1290 return E_OUTOFMEMORY;
1292 This->FolderItems3_iface.lpVtbl = &FolderItemsImpl_Vtbl;
1293 This->ref = 1;
1294 This->folder = folder;
1295 Folder3_AddRef(&folder->Folder3_iface);
1297 enumidlist = NULL;
1298 if (FAILED(hr = IShellFolder2_EnumObjects(folder->folder, NULL, SHCONTF_FOLDERS | SHCONTF_NONFOLDERS,
1299 &enumidlist)))
1301 goto failed;
1304 while (IEnumIDList_Next(enumidlist, 1, &pidl, NULL) == S_OK)
1306 This->item_count++;
1307 ILFree(pidl);
1310 if (This->item_count)
1312 LPITEMIDLIST *pidls;
1313 ULONG fetched;
1315 pidls = HeapAlloc(GetProcessHeap(), 0, This->item_count * sizeof(*pidls));
1316 This->item_names = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, This->item_count * sizeof(*This->item_names));
1318 if (!pidls || !This->item_names)
1320 HeapFree(GetProcessHeap(), 0, pidls);
1321 HeapFree(GetProcessHeap(), 0, This->item_names);
1322 hr = E_OUTOFMEMORY;
1323 goto failed;
1326 IEnumIDList_Reset(enumidlist);
1327 if (IEnumIDList_Next(enumidlist, This->item_count, pidls, &fetched) == S_OK)
1328 idlist_sort(pidls, 0, This->item_count - 1, folder->folder);
1330 for (i = 0; i < This->item_count; i++)
1332 STRRET strret;
1334 if (IShellFolder2_GetDisplayNameOf(folder->folder, pidls[i], SHGDN_FORPARSING, &strret) == S_OK)
1335 StrRetToBSTR(&strret, pidls[i], &This->item_names[i]);
1337 ILFree(pidls[i]);
1339 HeapFree(GetProcessHeap(), 0, pidls);
1341 IEnumIDList_Release(enumidlist);
1343 *ret = (FolderItems *)&This->FolderItems3_iface;
1344 return S_OK;
1346 failed:
1347 if (enumidlist)
1348 IEnumIDList_Release(enumidlist);
1349 return hr;
1352 static HRESULT WINAPI FolderImpl_QueryInterface(Folder3 *iface, REFIID riid,
1353 LPVOID *ppv)
1355 FolderImpl *This = impl_from_Folder(iface);
1357 TRACE("(%p,%s,%p)\n", iface, debugstr_guid(riid), ppv);
1359 if (!ppv) return E_INVALIDARG;
1361 if (IsEqualIID(&IID_IUnknown, riid) ||
1362 IsEqualIID(&IID_IDispatch, riid) ||
1363 IsEqualIID(&IID_Folder, riid) ||
1364 IsEqualIID(&IID_Folder2, riid) ||
1365 IsEqualIID(&IID_Folder3, riid))
1366 *ppv = &This->Folder3_iface;
1367 else
1369 WARN("not implemented for %s\n", debugstr_guid(riid));
1370 *ppv = NULL;
1371 return E_NOINTERFACE;
1373 IUnknown_AddRef((IUnknown*)*ppv);
1374 return S_OK;
1377 static ULONG WINAPI FolderImpl_AddRef(Folder3 *iface)
1379 FolderImpl *This = impl_from_Folder(iface);
1380 ULONG ref = InterlockedIncrement(&This->ref);
1382 TRACE("(%p), new refcount=%i\n", iface, ref);
1384 return ref;
1387 static ULONG WINAPI FolderImpl_Release(Folder3 *iface)
1389 FolderImpl *This = impl_from_Folder(iface);
1390 ULONG ref = InterlockedDecrement(&This->ref);
1392 TRACE("(%p), new refcount=%i\n", iface, ref);
1394 if (!ref)
1396 ILFree(This->pidl);
1397 SysFreeString(This->path);
1398 IShellFolder2_Release(This->folder);
1399 IDispatch_Release(This->application);
1400 HeapFree(GetProcessHeap(), 0, This);
1402 return ref;
1405 static HRESULT WINAPI FolderImpl_GetTypeInfoCount(Folder3 *iface, UINT *pctinfo)
1407 TRACE("(%p,%p)\n", iface, pctinfo);
1409 *pctinfo = 1;
1410 return S_OK;
1413 static HRESULT WINAPI FolderImpl_GetTypeInfo(Folder3 *iface, UINT iTInfo,
1414 LCID lcid, ITypeInfo **ppTInfo)
1416 HRESULT hr;
1418 TRACE("(%p,%u,%d,%p)\n", iface, iTInfo, lcid, ppTInfo);
1420 hr = get_typeinfo(Folder3_tid, ppTInfo);
1421 if (SUCCEEDED(hr))
1422 ITypeInfo_AddRef(*ppTInfo);
1424 return hr;
1427 static HRESULT WINAPI FolderImpl_GetIDsOfNames(Folder3 *iface, REFIID riid,
1428 LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
1430 ITypeInfo *ti;
1431 HRESULT hr;
1433 TRACE("(%p,%s,%p,%u,%d,%p)\n", iface, shdebugstr_guid(riid), rgszNames, cNames, lcid,
1434 rgDispId);
1436 hr = get_typeinfo(Folder3_tid, &ti);
1437 if (SUCCEEDED(hr))
1438 hr = ITypeInfo_GetIDsOfNames(ti, rgszNames, cNames, rgDispId);
1439 return hr;
1442 static HRESULT WINAPI FolderImpl_Invoke(Folder3 *iface, DISPID dispIdMember,
1443 REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
1444 VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
1446 FolderImpl *This = impl_from_Folder(iface);
1447 ITypeInfo *ti;
1448 HRESULT hr;
1450 TRACE("(%p,%d,%s,%d,%u,%p,%p,%p,%p)\n", iface, dispIdMember, shdebugstr_guid(riid), lcid,
1451 wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
1453 hr = get_typeinfo(Folder3_tid, &ti);
1454 if (SUCCEEDED(hr))
1455 hr = ITypeInfo_Invoke(ti, This, dispIdMember, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
1456 return hr;
1459 static HRESULT WINAPI FolderImpl_get_Title(Folder3 *iface, BSTR *title)
1461 FolderImpl *This = impl_from_Folder(iface);
1462 PCUITEMID_CHILD last_part;
1463 IShellFolder2 *parent;
1464 SHELLDETAILS sd;
1465 HRESULT hr;
1467 TRACE("(%p,%p)\n", iface, title);
1469 *title = NULL;
1471 if (FAILED(hr = SHBindToParent(This->pidl, &IID_IShellFolder2, (void **)&parent, &last_part)))
1472 return hr;
1474 hr = IShellFolder2_GetDetailsOf(parent, last_part, 0, &sd);
1475 IShellFolder2_Release(parent);
1476 if (FAILED(hr))
1477 return hr;
1479 return StrRetToBSTR(&sd.str, last_part, title);
1482 static HRESULT WINAPI FolderImpl_get_Application(Folder3 *iface, IDispatch **disp)
1484 FolderImpl *This = impl_from_Folder(iface);
1486 TRACE("(%p,%p)\n", iface, disp);
1488 if (!disp)
1489 return E_INVALIDARG;
1491 *disp = This->application;
1492 IDispatch_AddRef(*disp);
1494 return S_OK;
1497 static HRESULT WINAPI FolderImpl_get_Parent(Folder3 *iface, IDispatch **disp)
1499 TRACE("(%p,%p)\n", iface, disp);
1501 if (disp)
1502 *disp = NULL;
1503 return E_NOTIMPL;
1506 static HRESULT WINAPI FolderImpl_get_ParentFolder(Folder3 *iface, Folder **ppsf)
1508 FIXME("(%p,%p)\n", iface, ppsf);
1510 *ppsf = NULL;
1511 return E_NOTIMPL;
1514 static HRESULT WINAPI FolderImpl_Items(Folder3 *iface, FolderItems **ppid)
1516 FolderImpl *This = impl_from_Folder(iface);
1518 TRACE("(%p,%p)\n", iface, ppid);
1520 return FolderItems_Constructor(This, ppid);
1523 static HRESULT WINAPI FolderImpl_ParseName(Folder3 *iface, BSTR name, FolderItem **item)
1525 FolderImpl *This = impl_from_Folder(iface);
1526 LPITEMIDLIST pidl;
1527 STRRET strret;
1528 HRESULT hr;
1529 BSTR path;
1531 TRACE("(%p,%s,%p)\n", iface, debugstr_w(name), item);
1533 *item = NULL;
1535 if (FAILED(IShellFolder2_ParseDisplayName(This->folder, NULL, NULL, name, NULL, &pidl, NULL)))
1536 return S_FALSE;
1538 if ((hr = IShellFolder2_GetDisplayNameOf(This->folder, pidl, SHGDN_FORPARSING, &strret)) == S_OK)
1539 StrRetToBSTR(&strret, pidl, &path);
1541 ILFree(pidl);
1542 if (FAILED(hr))
1543 return S_FALSE;
1545 hr = FolderItem_Constructor(This, path, item);
1546 SysFreeString(path);
1547 return hr;
1550 static HRESULT WINAPI FolderImpl_NewFolder(Folder3 *iface, BSTR name, VARIANT options)
1552 FIXME("(%p,%s,%s)\n", iface, debugstr_w(name), debugstr_variant(&options));
1554 return E_NOTIMPL;
1557 static HRESULT WINAPI FolderImpl_MoveHere(Folder3 *iface, VARIANT item, VARIANT options)
1559 FIXME("(%p,%s,%s)\n", iface, debugstr_variant(&item), debugstr_variant(&options));
1561 return E_NOTIMPL;
1564 static HRESULT WINAPI FolderImpl_CopyHere(Folder3 *iface, VARIANT item, VARIANT options)
1566 FIXME("(%p,%s,%s)\n", iface, debugstr_variant(&item), debugstr_variant(&options));
1568 return E_NOTIMPL;
1571 static HRESULT WINAPI FolderImpl_GetDetailsOf(Folder3 *iface, VARIANT item, int column, BSTR *str)
1573 FIXME("(%p,%s,%d,%p)\n", iface, debugstr_variant(&item), column, str);
1575 *str = NULL;
1576 return E_NOTIMPL;
1579 static HRESULT WINAPI FolderImpl_get_Self(Folder3 *iface, FolderItem **item)
1581 FolderImpl *This = impl_from_Folder(iface);
1583 TRACE("(%p,%p)\n", iface, item);
1585 return FolderItem_Constructor(This, NULL, item);
1588 static HRESULT WINAPI FolderImpl_get_OfflineStatus(Folder3 *iface, LONG *pul)
1590 FIXME("(%p,%p)\n", iface, pul);
1592 return E_NOTIMPL;
1595 static HRESULT WINAPI FolderImpl_Synchronize(Folder3 *iface)
1597 FIXME("(%p)\n", iface);
1599 return E_NOTIMPL;
1602 static HRESULT WINAPI FolderImpl_get_HaveToShowWebViewBarricade(Folder3 *iface,
1603 VARIANT_BOOL *pbHaveToShowWebViewBarricade)
1605 FIXME("(%p,%p)\n", iface, pbHaveToShowWebViewBarricade);
1607 return E_NOTIMPL;
1610 static HRESULT WINAPI FolderImpl_DismissedWebViewBarricade(Folder3 *iface)
1612 FIXME("(%p)\n", iface);
1614 return E_NOTIMPL;
1617 static HRESULT WINAPI FolderImpl_get_ShowWebViewBarricade(Folder3 *iface,
1618 VARIANT_BOOL *pbShowWebViewBarricade)
1620 FIXME("(%p,%p)\n", iface, pbShowWebViewBarricade);
1622 return E_NOTIMPL;
1625 static HRESULT WINAPI FolderImpl_put_ShowWebViewBarricade(Folder3 *iface,
1626 VARIANT_BOOL bShowWebViewBarricade)
1628 FIXME("(%p,%d)\n", iface, bShowWebViewBarricade);
1630 return E_NOTIMPL;
1633 static const Folder3Vtbl FolderImpl_Vtbl = {
1634 FolderImpl_QueryInterface,
1635 FolderImpl_AddRef,
1636 FolderImpl_Release,
1637 FolderImpl_GetTypeInfoCount,
1638 FolderImpl_GetTypeInfo,
1639 FolderImpl_GetIDsOfNames,
1640 FolderImpl_Invoke,
1641 FolderImpl_get_Title,
1642 FolderImpl_get_Application,
1643 FolderImpl_get_Parent,
1644 FolderImpl_get_ParentFolder,
1645 FolderImpl_Items,
1646 FolderImpl_ParseName,
1647 FolderImpl_NewFolder,
1648 FolderImpl_MoveHere,
1649 FolderImpl_CopyHere,
1650 FolderImpl_GetDetailsOf,
1651 FolderImpl_get_Self,
1652 FolderImpl_get_OfflineStatus,
1653 FolderImpl_Synchronize,
1654 FolderImpl_get_HaveToShowWebViewBarricade,
1655 FolderImpl_DismissedWebViewBarricade,
1656 FolderImpl_get_ShowWebViewBarricade,
1657 FolderImpl_put_ShowWebViewBarricade
1660 static HRESULT Folder_Constructor(IShellFolder2 *folder, LPITEMIDLIST pidl, Folder **ret)
1662 PCUITEMID_CHILD last_part;
1663 IShellFolder2 *parent;
1664 FolderImpl *This;
1665 STRRET strret;
1666 HRESULT hr;
1668 *ret = NULL;
1670 This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This));
1671 if (!This)
1672 return E_OUTOFMEMORY;
1674 This->Folder3_iface.lpVtbl = &FolderImpl_Vtbl;
1675 This->ref = 1;
1676 This->folder = folder;
1677 This->pidl = pidl;
1679 hr = SHBindToParent(pidl, &IID_IShellFolder2, (void **)&parent, &last_part);
1680 IShellFolder2_GetDisplayNameOf(parent, last_part, SHGDN_FORPARSING, &strret);
1681 StrRetToBSTR(&strret, last_part, &This->path);
1682 IShellFolder2_Release(parent);
1684 IShellDispatch_Constructor(NULL, &IID_IDispatch, (void **)&This->application);
1686 *ret = (Folder *)&This->Folder3_iface;
1687 return hr;
1690 static HRESULT WINAPI ShellDispatch_QueryInterface(IShellDispatch6 *iface,
1691 REFIID riid, LPVOID *ppv)
1693 ShellDispatch *This = impl_from_IShellDispatch6(iface);
1695 TRACE("(%p,%s,%p)\n", iface, debugstr_guid(riid), ppv);
1697 if (!ppv) return E_INVALIDARG;
1699 if (IsEqualIID(&IID_IUnknown, riid) ||
1700 IsEqualIID(&IID_IDispatch, riid) ||
1701 IsEqualIID(&IID_IShellDispatch, riid) ||
1702 IsEqualIID(&IID_IShellDispatch2, riid) ||
1703 IsEqualIID(&IID_IShellDispatch3, riid) ||
1704 IsEqualIID(&IID_IShellDispatch4, riid) ||
1705 IsEqualIID(&IID_IShellDispatch5, riid) ||
1706 IsEqualIID(&IID_IShellDispatch6, riid))
1707 *ppv = &This->IShellDispatch6_iface;
1708 else
1710 WARN("not implemented for %s\n", debugstr_guid(riid));
1711 *ppv = NULL;
1712 return E_NOINTERFACE;
1715 IShellDispatch6_AddRef(iface);
1716 return S_OK;
1719 static ULONG WINAPI ShellDispatch_AddRef(IShellDispatch6 *iface)
1721 ShellDispatch *This = impl_from_IShellDispatch6(iface);
1722 ULONG ref = InterlockedIncrement(&This->ref);
1724 TRACE("(%p), new refcount=%i\n", iface, ref);
1726 return ref;
1729 static ULONG WINAPI ShellDispatch_Release(IShellDispatch6 *iface)
1731 ShellDispatch *This = impl_from_IShellDispatch6(iface);
1732 ULONG ref = InterlockedDecrement(&This->ref);
1734 TRACE("(%p), new refcount=%i\n", iface, ref);
1736 if (!ref)
1737 HeapFree(GetProcessHeap(), 0, This);
1739 return ref;
1742 static HRESULT WINAPI ShellDispatch_GetTypeInfoCount(IShellDispatch6 *iface,
1743 UINT *pctinfo)
1745 TRACE("(%p,%p)\n", iface, pctinfo);
1747 *pctinfo = 1;
1748 return S_OK;
1751 static HRESULT WINAPI ShellDispatch_GetTypeInfo(IShellDispatch6 *iface,
1752 UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo)
1754 HRESULT hr;
1756 TRACE("(%p,%u,%d,%p)\n", iface, iTInfo, lcid, ppTInfo);
1758 hr = get_typeinfo(IShellDispatch6_tid, ppTInfo);
1759 if (SUCCEEDED(hr))
1760 ITypeInfo_AddRef(*ppTInfo);
1761 return hr;
1764 static HRESULT WINAPI ShellDispatch_GetIDsOfNames(IShellDispatch6 *iface,
1765 REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
1767 ITypeInfo *ti;
1768 HRESULT hr;
1770 TRACE("(%p,%s,%p,%u,%d,%p)\n", iface, shdebugstr_guid(riid), rgszNames, cNames, lcid,
1771 rgDispId);
1773 hr = get_typeinfo(IShellDispatch6_tid, &ti);
1774 if (SUCCEEDED(hr))
1775 hr = ITypeInfo_GetIDsOfNames(ti, rgszNames, cNames, rgDispId);
1776 return hr;
1779 static HRESULT WINAPI ShellDispatch_Invoke(IShellDispatch6 *iface,
1780 DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags,
1781 DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo,
1782 UINT *puArgErr)
1784 ShellDispatch *This = impl_from_IShellDispatch6(iface);
1785 ITypeInfo *ti;
1786 HRESULT hr;
1788 TRACE("(%p,%d,%s,%d,%u,%p,%p,%p,%p)\n", iface, dispIdMember, shdebugstr_guid(riid), lcid,
1789 wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
1791 hr = get_typeinfo(IShellDispatch6_tid, &ti);
1792 if (SUCCEEDED(hr))
1793 hr = ITypeInfo_Invoke(ti, &This->IShellDispatch6_iface, dispIdMember, wFlags, pDispParams,
1794 pVarResult, pExcepInfo, puArgErr);
1795 return hr;
1798 static HRESULT WINAPI ShellDispatch_get_Application(IShellDispatch6 *iface, IDispatch **disp)
1800 TRACE("(%p,%p)\n", iface, disp);
1802 if (!disp)
1803 return E_INVALIDARG;
1805 *disp = (IDispatch *)iface;
1806 IDispatch_AddRef(*disp);
1807 return S_OK;
1810 static HRESULT WINAPI ShellDispatch_get_Parent(IShellDispatch6 *iface, IDispatch **disp)
1812 TRACE("(%p,%p)\n", iface, disp);
1814 if (disp)
1816 *disp = (IDispatch *)iface;
1817 IDispatch_AddRef(*disp);
1820 return S_OK;
1823 static HRESULT WINAPI ShellDispatch_NameSpace(IShellDispatch6 *iface,
1824 VARIANT dir, Folder **ret)
1826 IShellFolder2 *folder;
1827 IShellFolder *desktop;
1828 LPITEMIDLIST pidl;
1829 HRESULT hr;
1831 TRACE("(%p,%s,%p)\n", iface, debugstr_variant(&dir), ret);
1833 *ret = NULL;
1835 switch (V_VT(&dir))
1837 case VT_I2:
1838 if (FAILED(hr = VariantChangeType(&dir, &dir, 0, VT_I4)))
1839 return hr;
1841 /* fallthrough */
1842 case VT_I4:
1843 if (FAILED(hr = SHGetFolderLocation(NULL, V_I4(&dir), NULL, 0, &pidl)))
1844 return S_FALSE;
1846 break;
1847 case VT_BSTR:
1848 if (FAILED(hr = SHParseDisplayName(V_BSTR(&dir), NULL, &pidl, 0, NULL)))
1849 return S_FALSE;
1851 break;
1852 default:
1853 WARN("Ignoring directory value %s\n", debugstr_variant(&dir));
1854 return S_FALSE;
1857 if (FAILED(hr = SHGetDesktopFolder(&desktop)))
1858 return hr;
1860 if (_ILIsDesktop(pidl))
1861 hr = IShellFolder_QueryInterface(desktop, &IID_IShellFolder2, (void **)&folder);
1862 else
1863 hr = IShellFolder_BindToObject(desktop, pidl, NULL, &IID_IShellFolder2, (void **)&folder);
1865 IShellFolder_Release(desktop);
1867 if (FAILED(hr))
1868 return S_FALSE;
1870 return Folder_Constructor(folder, pidl, ret);
1873 static HRESULT WINAPI ShellDispatch_BrowseForFolder(IShellDispatch6 *iface,
1874 LONG Hwnd, BSTR Title, LONG Options, VARIANT RootFolder, Folder **ppsdf)
1876 FIXME("(%p,%x,%s,%x,%s,%p)\n", iface, Hwnd, debugstr_w(Title), Options, debugstr_variant(&RootFolder), ppsdf);
1878 *ppsdf = NULL;
1879 return E_NOTIMPL;
1882 static HRESULT WINAPI ShellDispatch_Windows(IShellDispatch6 *iface,
1883 IDispatch **ppid)
1885 FIXME("(%p,%p)\n", iface, ppid);
1887 *ppid = NULL;
1888 return E_NOTIMPL;
1891 static HRESULT WINAPI ShellDispatch_Open(IShellDispatch6 *iface, VARIANT dir)
1893 FIXME("(%p,%s)\n", iface, debugstr_variant(&dir));
1895 return E_NOTIMPL;
1898 static HRESULT WINAPI ShellDispatch_Explore(IShellDispatch6 *iface, VARIANT dir)
1900 FIXME("(%p,%s)\n", iface, debugstr_variant(&dir));
1902 return E_NOTIMPL;
1905 static HRESULT WINAPI ShellDispatch_MinimizeAll(IShellDispatch6 *iface)
1907 FIXME("(%p)\n", iface);
1909 return E_NOTIMPL;
1912 static HRESULT WINAPI ShellDispatch_UndoMinimizeALL(IShellDispatch6 *iface)
1914 FIXME("(%p)\n", iface);
1916 return E_NOTIMPL;
1919 static HRESULT WINAPI ShellDispatch_FileRun(IShellDispatch6 *iface)
1921 FIXME("(%p)\n", iface);
1923 return E_NOTIMPL;
1926 static HRESULT WINAPI ShellDispatch_CascadeWindows(IShellDispatch6 *iface)
1928 FIXME("(%p)\n", iface);
1930 return E_NOTIMPL;
1933 static HRESULT WINAPI ShellDispatch_TileVertically(IShellDispatch6 *iface)
1935 FIXME("(%p)\n", iface);
1937 return E_NOTIMPL;
1940 static HRESULT WINAPI ShellDispatch_TileHorizontally(IShellDispatch6 *iface)
1942 FIXME("(%p)\n", iface);
1944 return E_NOTIMPL;
1947 static HRESULT WINAPI ShellDispatch_ShutdownWindows(IShellDispatch6 *iface)
1949 FIXME("(%p)\n", iface);
1951 return E_NOTIMPL;
1954 static HRESULT WINAPI ShellDispatch_Suspend(IShellDispatch6 *iface)
1956 FIXME("(%p)\n", iface);
1958 return E_NOTIMPL;
1961 static HRESULT WINAPI ShellDispatch_EjectPC(IShellDispatch6 *iface)
1963 FIXME("(%p)\n", iface);
1965 return E_NOTIMPL;
1968 static HRESULT WINAPI ShellDispatch_SetTime(IShellDispatch6 *iface)
1970 FIXME("(%p)\n", iface);
1972 return E_NOTIMPL;
1975 static HRESULT WINAPI ShellDispatch_TrayProperties(IShellDispatch6 *iface)
1977 FIXME("(%p)\n", iface);
1979 return E_NOTIMPL;
1982 static HRESULT WINAPI ShellDispatch_Help(IShellDispatch6 *iface)
1984 FIXME("(%p)\n", iface);
1986 return E_NOTIMPL;
1989 static HRESULT WINAPI ShellDispatch_FindFiles(IShellDispatch6 *iface)
1991 FIXME("(%p)\n", iface);
1993 return E_NOTIMPL;
1996 static HRESULT WINAPI ShellDispatch_FindComputer(IShellDispatch6 *iface)
1998 FIXME("(%p)\n", iface);
2000 return E_NOTIMPL;
2003 static HRESULT WINAPI ShellDispatch_RefreshMenu(IShellDispatch6 *iface)
2005 FIXME("(%p)\n", iface);
2007 return E_NOTIMPL;
2010 static HRESULT WINAPI ShellDispatch_ControlPanelItem(IShellDispatch6 *iface,
2011 BSTR szDir)
2013 FIXME("(%p,%s)\n", iface, debugstr_w(szDir));
2015 return E_NOTIMPL;
2018 static HRESULT WINAPI ShellDispatch_IsRestricted(IShellDispatch6 *iface, BSTR group, BSTR restriction, LONG *value)
2020 FIXME("(%s, %s, %p): stub\n", debugstr_w(group), debugstr_w(restriction), value);
2021 return E_NOTIMPL;
2024 static HRESULT WINAPI ShellDispatch_ShellExecute(IShellDispatch6 *iface,
2025 BSTR file, VARIANT v_args, VARIANT v_dir, VARIANT v_op, VARIANT v_show)
2027 VARIANT args_str, dir_str, op_str, show_int;
2028 WCHAR *args = NULL, *dir = NULL, *op = NULL;
2029 INT show = 0;
2030 HINSTANCE ret;
2032 TRACE("(%s, %s, %s, %s, %s)\n", debugstr_w(file), debugstr_variant(&v_args),
2033 debugstr_variant(&v_dir), debugstr_variant(&v_op), debugstr_variant(&v_show));
2035 VariantInit(&args_str);
2036 VariantChangeType(&args_str, &v_args, 0, VT_BSTR);
2037 if (V_VT(&args_str) == VT_BSTR)
2038 args = V_BSTR(&args_str);
2040 VariantInit(&dir_str);
2041 VariantChangeType(&dir_str, &v_dir, 0, VT_BSTR);
2042 if (V_VT(&dir_str) == VT_BSTR)
2043 dir = V_BSTR(&dir_str);
2045 VariantInit(&op_str);
2046 VariantChangeType(&op_str, &v_op, 0, VT_BSTR);
2047 if (V_VT(&op_str) == VT_BSTR)
2048 op = V_BSTR(&op_str);
2050 VariantInit(&show_int);
2051 VariantChangeType(&show_int, &v_show, 0, VT_I4);
2052 if (V_VT(&show_int) == VT_I4)
2053 show = V_I4(&show_int);
2055 ret = ShellExecuteW(NULL, op, file, args, dir, show);
2057 VariantClear(&args_str);
2058 VariantClear(&dir_str);
2059 VariantClear(&op_str);
2060 VariantClear(&show_int);
2062 return (ULONG_PTR)ret > 32 ? S_OK : S_FALSE;
2065 static HRESULT WINAPI ShellDispatch_FindPrinter(IShellDispatch6 *iface, BSTR name, BSTR location, BSTR model)
2067 FIXME("(%s, %s, %s): stub\n", debugstr_w(name), debugstr_w(location), debugstr_w(model));
2068 return E_NOTIMPL;
2071 static HRESULT WINAPI ShellDispatch_GetSystemInformation(IShellDispatch6 *iface, BSTR name, VARIANT *ret)
2073 FIXME("(%s, %p): stub\n", debugstr_w(name), ret);
2074 return E_NOTIMPL;
2077 static HRESULT WINAPI ShellDispatch_ServiceStart(IShellDispatch6 *iface, BSTR service, VARIANT persistent, VARIANT *ret)
2079 FIXME("(%s, %s, %p): stub\n", debugstr_w(service), debugstr_variant(&persistent), ret);
2080 return E_NOTIMPL;
2083 static HRESULT WINAPI ShellDispatch_ServiceStop(IShellDispatch6 *iface, BSTR service, VARIANT persistent, VARIANT *ret)
2085 FIXME("(%s, %s, %p): stub\n", debugstr_w(service), debugstr_variant(&persistent), ret);
2086 return E_NOTIMPL;
2089 static HRESULT WINAPI ShellDispatch_IsServiceRunning(IShellDispatch6 *iface, BSTR name, VARIANT *running)
2091 SERVICE_STATUS_PROCESS status;
2092 SC_HANDLE scm, service;
2093 DWORD dummy;
2095 TRACE("(%s, %p)\n", debugstr_w(name), running);
2097 V_VT(running) = VT_BOOL;
2098 V_BOOL(running) = VARIANT_FALSE;
2100 scm = OpenSCManagerW(NULL, NULL, SC_MANAGER_CONNECT);
2101 if (!scm)
2103 ERR("failed to connect to service manager\n");
2104 return S_OK;
2107 service = OpenServiceW(scm, name, SERVICE_QUERY_STATUS);
2108 if (!service)
2110 ERR("Failed to open service %s (%u)\n", debugstr_w(name), GetLastError());
2111 CloseServiceHandle(scm);
2112 return S_OK;
2115 if (!QueryServiceStatusEx(service, SC_STATUS_PROCESS_INFO, (BYTE *)&status,
2116 sizeof(SERVICE_STATUS_PROCESS), &dummy))
2118 TRACE("failed to query service status (%u)\n", GetLastError());
2119 CloseServiceHandle(service);
2120 CloseServiceHandle(scm);
2121 return S_OK;
2124 if (status.dwCurrentState == SERVICE_RUNNING)
2125 V_BOOL(running) = VARIANT_TRUE;
2127 CloseServiceHandle(service);
2128 CloseServiceHandle(scm);
2130 return S_OK;
2133 static HRESULT WINAPI ShellDispatch_CanStartStopService(IShellDispatch6 *iface, BSTR service, VARIANT *ret)
2135 FIXME("(%s, %p): stub\n", debugstr_w(service), ret);
2136 return E_NOTIMPL;
2139 static HRESULT WINAPI ShellDispatch_ShowBrowserBar(IShellDispatch6 *iface, BSTR clsid, VARIANT show, VARIANT *ret)
2141 FIXME("(%s, %s, %p): stub\n", debugstr_w(clsid), debugstr_variant(&show), ret);
2142 return E_NOTIMPL;
2145 static HRESULT WINAPI ShellDispatch_AddToRecent(IShellDispatch6 *iface, VARIANT file, BSTR category)
2147 FIXME("(%s, %s): stub\n", debugstr_variant(&file), debugstr_w(category));
2148 return E_NOTIMPL;
2151 static HRESULT WINAPI ShellDispatch_WindowsSecurity(IShellDispatch6 *iface)
2153 FIXME("stub\n");
2154 return E_NOTIMPL;
2157 static HRESULT WINAPI ShellDispatch_ToggleDesktop(IShellDispatch6 *iface)
2159 FIXME("stub\n");
2160 return E_NOTIMPL;
2163 static HRESULT WINAPI ShellDispatch_ExplorerPolicy(IShellDispatch6 *iface, BSTR policy, VARIANT *value)
2165 FIXME("(%s, %p): stub\n", debugstr_w(policy), value);
2166 return E_NOTIMPL;
2169 static HRESULT WINAPI ShellDispatch_GetSetting(IShellDispatch6 *iface, LONG setting, VARIANT_BOOL *result)
2171 FIXME("(%d %p): stub\n", setting, result);
2172 return E_NOTIMPL;
2175 static HRESULT WINAPI ShellDispatch_WindowSwitcher(IShellDispatch6 *iface)
2177 FIXME("stub\n");
2178 return E_NOTIMPL;
2181 static HRESULT WINAPI ShellDispatch_SearchCommand(IShellDispatch6 *iface)
2183 FIXME("stub\n");
2184 return E_NOTIMPL;
2187 static const IShellDispatch6Vtbl ShellDispatchVtbl = {
2188 ShellDispatch_QueryInterface,
2189 ShellDispatch_AddRef,
2190 ShellDispatch_Release,
2191 ShellDispatch_GetTypeInfoCount,
2192 ShellDispatch_GetTypeInfo,
2193 ShellDispatch_GetIDsOfNames,
2194 ShellDispatch_Invoke,
2195 ShellDispatch_get_Application,
2196 ShellDispatch_get_Parent,
2197 ShellDispatch_NameSpace,
2198 ShellDispatch_BrowseForFolder,
2199 ShellDispatch_Windows,
2200 ShellDispatch_Open,
2201 ShellDispatch_Explore,
2202 ShellDispatch_MinimizeAll,
2203 ShellDispatch_UndoMinimizeALL,
2204 ShellDispatch_FileRun,
2205 ShellDispatch_CascadeWindows,
2206 ShellDispatch_TileVertically,
2207 ShellDispatch_TileHorizontally,
2208 ShellDispatch_ShutdownWindows,
2209 ShellDispatch_Suspend,
2210 ShellDispatch_EjectPC,
2211 ShellDispatch_SetTime,
2212 ShellDispatch_TrayProperties,
2213 ShellDispatch_Help,
2214 ShellDispatch_FindFiles,
2215 ShellDispatch_FindComputer,
2216 ShellDispatch_RefreshMenu,
2217 ShellDispatch_ControlPanelItem,
2218 ShellDispatch_IsRestricted,
2219 ShellDispatch_ShellExecute,
2220 ShellDispatch_FindPrinter,
2221 ShellDispatch_GetSystemInformation,
2222 ShellDispatch_ServiceStart,
2223 ShellDispatch_ServiceStop,
2224 ShellDispatch_IsServiceRunning,
2225 ShellDispatch_CanStartStopService,
2226 ShellDispatch_ShowBrowserBar,
2227 ShellDispatch_AddToRecent,
2228 ShellDispatch_WindowsSecurity,
2229 ShellDispatch_ToggleDesktop,
2230 ShellDispatch_ExplorerPolicy,
2231 ShellDispatch_GetSetting,
2232 ShellDispatch_WindowSwitcher,
2233 ShellDispatch_SearchCommand
2236 HRESULT WINAPI IShellDispatch_Constructor(IUnknown *outer, REFIID riid, void **ppv)
2238 ShellDispatch *This;
2239 HRESULT ret;
2241 TRACE("(%p, %s)\n", outer, debugstr_guid(riid));
2243 *ppv = NULL;
2245 if (outer) return CLASS_E_NOAGGREGATION;
2247 This = HeapAlloc(GetProcessHeap(), 0, sizeof(ShellDispatch));
2248 if (!This) return E_OUTOFMEMORY;
2249 This->IShellDispatch6_iface.lpVtbl = &ShellDispatchVtbl;
2250 This->ref = 1;
2252 ret = IShellDispatch6_QueryInterface(&This->IShellDispatch6_iface, riid, ppv);
2253 IShellDispatch6_Release(&This->IShellDispatch6_iface);
2254 return ret;