gdi32: Reimplement Ellipse in paths to avoid calling imprecise arc helper functions.
[wine.git] / dlls / shell32 / shelldispatch.c
blob6dece6da4858d972922a209a31841b921b2158fa
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"
39 #include "wine/debug.h"
41 WINE_DEFAULT_DEBUG_CHANNEL(shell);
43 static ITypeLib *typelib;
44 static const IID * const tid_ids[] =
46 &IID_NULL,
47 &IID_IShellDispatch6,
48 &IID_IShellFolderViewDual3,
49 &IID_Folder3,
50 &IID_FolderItem2,
51 &IID_FolderItemVerb,
52 &IID_FolderItemVerbs
54 static ITypeInfo *typeinfos[LAST_tid];
56 typedef struct {
57 IShellDispatch6 IShellDispatch6_iface;
58 LONG ref;
59 } ShellDispatch;
61 typedef struct {
62 Folder3 Folder3_iface;
63 LONG ref;
64 VARIANT dir;
65 } FolderImpl;
67 typedef struct {
68 FolderItem2 FolderItem2_iface;
69 LONG ref;
70 VARIANT dir;
71 } FolderItemImpl;
73 typedef struct {
74 FolderItemVerbs FolderItemVerbs_iface;
75 LONG ref;
77 IContextMenu *contextmenu;
78 HMENU hMenu;
79 LONG count;
80 } FolderItemVerbsImpl;
82 typedef struct {
83 FolderItemVerb FolderItemVerb_iface;
84 LONG ref;
86 IContextMenu *contextmenu;
87 BSTR name;
88 } FolderItemVerbImpl;
90 static inline ShellDispatch *impl_from_IShellDispatch6(IShellDispatch6 *iface)
92 return CONTAINING_RECORD(iface, ShellDispatch, IShellDispatch6_iface);
95 static inline FolderImpl *impl_from_Folder(Folder3 *iface)
97 return CONTAINING_RECORD(iface, FolderImpl, Folder3_iface);
100 static inline FolderItemImpl *impl_from_FolderItem(FolderItem2 *iface)
102 return CONTAINING_RECORD(iface, FolderItemImpl, FolderItem2_iface);
105 static inline FolderItemVerbsImpl *impl_from_FolderItemVerbs(FolderItemVerbs *iface)
107 return CONTAINING_RECORD(iface, FolderItemVerbsImpl, FolderItemVerbs_iface);
110 static inline FolderItemVerbImpl *impl_from_FolderItemVerb(FolderItemVerb *iface)
112 return CONTAINING_RECORD(iface, FolderItemVerbImpl, FolderItemVerb_iface);
115 static HRESULT load_typelib(void)
117 ITypeLib *tl;
118 HRESULT hr;
120 hr = LoadRegTypeLib(&LIBID_Shell32, 1, 0, LOCALE_SYSTEM_DEFAULT, &tl);
121 if (FAILED(hr)) {
122 ERR("LoadRegTypeLib failed: %08x\n", hr);
123 return hr;
126 if (InterlockedCompareExchangePointer((void**)&typelib, tl, NULL))
127 ITypeLib_Release(tl);
128 return hr;
131 void release_typelib(void)
133 unsigned i;
135 if (!typelib)
136 return;
138 for (i = 0; i < sizeof(typeinfos)/sizeof(*typeinfos); i++)
139 if (typeinfos[i])
140 ITypeInfo_Release(typeinfos[i]);
142 ITypeLib_Release(typelib);
145 HRESULT get_typeinfo(enum tid_t tid, ITypeInfo **typeinfo)
147 HRESULT hr;
149 if (!typelib)
150 hr = load_typelib();
151 if (!typelib)
152 return hr;
154 if (!typeinfos[tid])
156 ITypeInfo *ti;
158 hr = ITypeLib_GetTypeInfoOfGuid(typelib, tid_ids[tid], &ti);
159 if (FAILED(hr))
161 ERR("GetTypeInfoOfGuid(%s) failed: %08x\n", debugstr_guid(tid_ids[tid]), hr);
162 return hr;
165 if (InterlockedCompareExchangePointer((void**)(typeinfos+tid), ti, NULL))
166 ITypeInfo_Release(ti);
169 *typeinfo = typeinfos[tid];
170 return S_OK;
173 /* FolderItemVerb */
174 static HRESULT WINAPI FolderItemVerbImpl_QueryInterface(FolderItemVerb *iface,
175 REFIID riid, void **ppv)
177 FolderItemVerbImpl *This = impl_from_FolderItemVerb(iface);
179 TRACE("(%p,%p,%p)\n", iface, riid, ppv);
181 *ppv = NULL;
183 if (IsEqualIID(&IID_IUnknown, riid) ||
184 IsEqualIID(&IID_IDispatch, riid) ||
185 IsEqualIID(&IID_FolderItemVerb, riid))
186 *ppv = &This->FolderItemVerb_iface;
187 else
189 FIXME("not implemented for %s\n", shdebugstr_guid(riid));
190 *ppv = NULL;
191 return E_NOINTERFACE;
194 IUnknown_AddRef((IUnknown*)*ppv);
195 return S_OK;
198 static ULONG WINAPI FolderItemVerbImpl_AddRef(FolderItemVerb *iface)
200 FolderItemVerbImpl *This = impl_from_FolderItemVerb(iface);
201 ULONG ref = InterlockedIncrement(&This->ref);
203 TRACE("(%p), new refcount=%i\n", iface, ref);
205 return ref;
208 static ULONG WINAPI FolderItemVerbImpl_Release(FolderItemVerb *iface)
210 FolderItemVerbImpl *This = impl_from_FolderItemVerb(iface);
211 ULONG ref = InterlockedDecrement(&This->ref);
213 TRACE("(%p), new refcount=%i\n", iface, ref);
215 if (!ref)
217 IContextMenu_Release(This->contextmenu);
218 SysFreeString(This->name);
219 HeapFree(GetProcessHeap(), 0, This);
222 return ref;
225 static HRESULT WINAPI FolderItemVerbImpl_GetTypeInfoCount(FolderItemVerb *iface, UINT *pctinfo)
227 TRACE("(%p,%p)\n", iface, pctinfo);
228 *pctinfo = 1;
229 return S_OK;
232 static HRESULT WINAPI FolderItemVerbImpl_GetTypeInfo(FolderItemVerb *iface, UINT iTInfo,
233 LCID lcid, ITypeInfo **ppTInfo)
235 HRESULT hr;
237 TRACE("(%p,%u,%d,%p)\n", iface, iTInfo, lcid, ppTInfo);
239 hr = get_typeinfo(FolderItemVerb_tid, ppTInfo);
240 if (SUCCEEDED(hr))
241 ITypeInfo_AddRef(*ppTInfo);
242 return hr;
245 static HRESULT WINAPI FolderItemVerbImpl_GetIDsOfNames(FolderItemVerb *iface,
246 REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
248 ITypeInfo *ti;
249 HRESULT hr;
251 TRACE("(%p,%p,%p,%u,%d,%p)\n", iface, riid, rgszNames, cNames, lcid,
252 rgDispId);
254 hr = get_typeinfo(FolderItemVerb_tid, &ti);
255 if (SUCCEEDED(hr))
256 hr = ITypeInfo_GetIDsOfNames(ti, rgszNames, cNames, rgDispId);
257 return hr;
260 static HRESULT WINAPI FolderItemVerbImpl_Invoke(FolderItemVerb *iface,
261 DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags,
262 DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo,
263 UINT *puArgErr)
265 ITypeInfo *ti;
266 HRESULT hr;
268 TRACE("(%p,%d,%p,%d,%u,%p,%p,%p,%p)\n", iface, dispIdMember, riid, lcid,
269 wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
271 hr = get_typeinfo(FolderItemVerb_tid, &ti);
272 if (SUCCEEDED(hr))
273 hr = ITypeInfo_Invoke(ti, iface, dispIdMember, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
274 return hr;
277 static HRESULT WINAPI FolderItemVerbImpl_get_Application(FolderItemVerb *iface, IDispatch **disp)
279 FIXME("(%p, %p)\n", iface, disp);
280 return E_NOTIMPL;
283 static HRESULT WINAPI FolderItemVerbImpl_get_Parent(FolderItemVerb *iface, IDispatch **disp)
285 FIXME("(%p, %p)\n", iface, disp);
286 return E_NOTIMPL;
289 static HRESULT WINAPI FolderItemVerbImpl_get_Name(FolderItemVerb *iface, BSTR *name)
291 FolderItemVerbImpl *This = impl_from_FolderItemVerb(iface);
293 TRACE("(%p, %p)\n", iface, name);
295 *name = SysAllocString(This->name);
296 return *name ? S_OK : E_OUTOFMEMORY;
299 static HRESULT WINAPI FolderItemVerbImpl_DoIt(FolderItemVerb *iface)
301 FIXME("(%p)\n", iface);
302 return E_NOTIMPL;
305 static FolderItemVerbVtbl folderitemverbvtbl = {
306 FolderItemVerbImpl_QueryInterface,
307 FolderItemVerbImpl_AddRef,
308 FolderItemVerbImpl_Release,
309 FolderItemVerbImpl_GetTypeInfoCount,
310 FolderItemVerbImpl_GetTypeInfo,
311 FolderItemVerbImpl_GetIDsOfNames,
312 FolderItemVerbImpl_Invoke,
313 FolderItemVerbImpl_get_Application,
314 FolderItemVerbImpl_get_Parent,
315 FolderItemVerbImpl_get_Name,
316 FolderItemVerbImpl_DoIt
319 static HRESULT FolderItemVerb_Constructor(IContextMenu *contextmenu, BSTR name, FolderItemVerb **verb)
321 FolderItemVerbImpl *This;
323 TRACE("%p, %s\n", contextmenu, debugstr_w(name));
325 This = HeapAlloc(GetProcessHeap(), 0, sizeof(FolderItemVerbImpl));
326 if (!This)
327 return E_OUTOFMEMORY;
329 This->FolderItemVerb_iface.lpVtbl = &folderitemverbvtbl;
330 This->ref = 1;
331 This->contextmenu = contextmenu;
332 IContextMenu_AddRef(contextmenu);
333 This->name = name;
335 *verb = &This->FolderItemVerb_iface;
336 return S_OK;
339 /* FolderItemVerbs */
340 static HRESULT WINAPI FolderItemVerbsImpl_QueryInterface(FolderItemVerbs *iface,
341 REFIID riid, void **ppv)
343 FolderItemVerbsImpl *This = impl_from_FolderItemVerbs(iface);
345 TRACE("(%p,%p,%p)\n", iface, riid, ppv);
347 *ppv = NULL;
349 if (IsEqualIID(&IID_IUnknown, riid) ||
350 IsEqualIID(&IID_IDispatch, riid) ||
351 IsEqualIID(&IID_FolderItemVerbs, riid))
352 *ppv = &This->FolderItemVerbs_iface;
353 else
355 FIXME("not implemented for %s\n", shdebugstr_guid(riid));
356 *ppv = NULL;
357 return E_NOINTERFACE;
360 IUnknown_AddRef((IUnknown*)*ppv);
361 return S_OK;
364 static ULONG WINAPI FolderItemVerbsImpl_AddRef(FolderItemVerbs *iface)
366 FolderItemVerbsImpl *This = impl_from_FolderItemVerbs(iface);
367 ULONG ref = InterlockedIncrement(&This->ref);
369 TRACE("(%p), new refcount=%i\n", iface, ref);
371 return ref;
374 static ULONG WINAPI FolderItemVerbsImpl_Release(FolderItemVerbs *iface)
376 FolderItemVerbsImpl *This = impl_from_FolderItemVerbs(iface);
377 ULONG ref = InterlockedDecrement(&This->ref);
379 TRACE("(%p), new refcount=%i\n", iface, ref);
381 if (!ref)
383 IContextMenu_Release(This->contextmenu);
384 DestroyMenu(This->hMenu);
385 HeapFree(GetProcessHeap(), 0, This);
388 return ref;
391 static HRESULT WINAPI FolderItemVerbsImpl_GetTypeInfoCount(FolderItemVerbs *iface, UINT *pctinfo)
393 TRACE("(%p,%p)\n", iface, pctinfo);
394 *pctinfo = 1;
395 return S_OK;
398 static HRESULT WINAPI FolderItemVerbsImpl_GetTypeInfo(FolderItemVerbs *iface, UINT iTInfo,
399 LCID lcid, ITypeInfo **ppTInfo)
401 HRESULT hr;
403 TRACE("(%p,%u,%d,%p)\n", iface, iTInfo, lcid, ppTInfo);
405 hr = get_typeinfo(FolderItemVerbs_tid, ppTInfo);
406 if (SUCCEEDED(hr))
407 ITypeInfo_AddRef(*ppTInfo);
408 return hr;
411 static HRESULT WINAPI FolderItemVerbsImpl_GetIDsOfNames(FolderItemVerbs *iface,
412 REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
414 ITypeInfo *ti;
415 HRESULT hr;
417 TRACE("(%p,%p,%p,%u,%d,%p)\n", iface, riid, rgszNames, cNames, lcid,
418 rgDispId);
420 hr = get_typeinfo(FolderItemVerbs_tid, &ti);
421 if (SUCCEEDED(hr))
422 hr = ITypeInfo_GetIDsOfNames(ti, rgszNames, cNames, rgDispId);
423 return hr;
426 static HRESULT WINAPI FolderItemVerbsImpl_Invoke(FolderItemVerbs *iface,
427 DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags,
428 DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo,
429 UINT *puArgErr)
431 ITypeInfo *ti;
432 HRESULT hr;
434 TRACE("(%p,%d,%p,%d,%u,%p,%p,%p,%p)\n", iface, dispIdMember, riid, lcid,
435 wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
437 hr = get_typeinfo(FolderItemVerbs_tid, &ti);
438 if (SUCCEEDED(hr))
439 hr = ITypeInfo_Invoke(ti, iface, dispIdMember, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
440 return hr;
443 static HRESULT WINAPI FolderItemVerbsImpl_get_Count(FolderItemVerbs *iface, LONG *count)
445 FolderItemVerbsImpl *This = impl_from_FolderItemVerbs(iface);
447 TRACE("(%p, %p)\n", iface, count);
449 if (!count)
450 return E_INVALIDARG;
452 *count = This->count;
453 return S_OK;
456 static HRESULT WINAPI FolderItemVerbsImpl_get_Application(FolderItemVerbs *iface, IDispatch **disp)
458 FIXME("(%p, %p)\n", iface, disp);
459 return E_NOTIMPL;
462 static HRESULT WINAPI FolderItemVerbsImpl_get_Parent(FolderItemVerbs *iface, IDispatch **disp)
464 FIXME("(%p, %p)\n", iface, disp);
465 return E_NOTIMPL;
468 static HRESULT WINAPI FolderItemVerbsImpl_Item(FolderItemVerbs *iface, VARIANT index, FolderItemVerb **verb)
470 FolderItemVerbsImpl *This = impl_from_FolderItemVerbs(iface);
471 MENUITEMINFOW info;
472 HRESULT hr;
473 VARIANT v;
474 BSTR name;
476 TRACE("(%p, %s, %p)\n", iface, debugstr_variant(&index), verb);
478 if (!verb)
479 return E_INVALIDARG;
481 *verb = NULL;
483 VariantInit(&v);
484 VariantCopyInd(&v, &index);
486 hr = VariantChangeType(&v, &v, 0, VT_I4);
487 if (FAILED(hr))
489 FIXME("failed to coerce to VT_I4, %s\n", debugstr_variant(&v));
490 return hr;
493 if (V_I4(&v) > This->count)
494 return S_OK;
496 if (V_I4(&v) == This->count)
497 name = SysAllocStringLen(NULL, 0);
498 else
500 /* get item name */
501 memset(&info, 0, sizeof(info));
502 info.cbSize = sizeof(info);
503 info.fMask = MIIM_STRING;
504 if (!GetMenuItemInfoW(This->hMenu, V_I4(&v), TRUE, &info))
505 return E_FAIL;
507 name = SysAllocStringLen(NULL, info.cch);
508 if (name)
510 info.dwTypeData = name;
511 info.cch++;
512 GetMenuItemInfoW(This->hMenu, V_I4(&v), TRUE, &info);
516 if (!name)
517 return E_OUTOFMEMORY;
519 return FolderItemVerb_Constructor(This->contextmenu, name, verb);
522 static HRESULT WINAPI FolderItemVerbsImpl__NewEnum(FolderItemVerbs *iface, IUnknown **ret)
524 FIXME("(%p, %p)\n", iface, ret);
525 return E_NOTIMPL;
528 static FolderItemVerbsVtbl folderitemverbsvtbl = {
529 FolderItemVerbsImpl_QueryInterface,
530 FolderItemVerbsImpl_AddRef,
531 FolderItemVerbsImpl_Release,
532 FolderItemVerbsImpl_GetTypeInfoCount,
533 FolderItemVerbsImpl_GetTypeInfo,
534 FolderItemVerbsImpl_GetIDsOfNames,
535 FolderItemVerbsImpl_Invoke,
536 FolderItemVerbsImpl_get_Count,
537 FolderItemVerbsImpl_get_Application,
538 FolderItemVerbsImpl_get_Parent,
539 FolderItemVerbsImpl_Item,
540 FolderItemVerbsImpl__NewEnum
543 static HRESULT FolderItemVerbs_Constructor(BSTR path, FolderItemVerbs **verbs)
545 FolderItemVerbsImpl *This;
546 IShellFolder *folder;
547 LPCITEMIDLIST child;
548 LPITEMIDLIST pidl;
549 HRESULT hr;
551 This = HeapAlloc(GetProcessHeap(), 0, sizeof(FolderItemVerbsImpl));
552 if (!This)
553 return E_OUTOFMEMORY;
555 This->FolderItemVerbs_iface.lpVtbl = &folderitemverbsvtbl;
556 This->ref = 1;
558 /* build context menu for this path */
559 hr = SHParseDisplayName(path, NULL, &pidl, 0, NULL);
560 if (FAILED(hr))
561 goto failed;
563 hr = SHBindToParent(pidl, &IID_IShellFolder, (void**)&folder, &child);
564 CoTaskMemFree(pidl);
565 if (FAILED(hr))
566 goto failed;
568 hr = IShellFolder_GetUIObjectOf(folder, NULL, 1, &child, &IID_IContextMenu, NULL, (void**)&This->contextmenu);
569 IShellFolder_Release(folder);
570 if (FAILED(hr))
571 goto failed;
573 This->hMenu = CreatePopupMenu();
574 hr = IContextMenu_QueryContextMenu(This->contextmenu, This->hMenu, 0, FCIDM_SHVIEWFIRST, FCIDM_SHVIEWLAST, CMF_NORMAL);
575 if (FAILED(hr))
577 FolderItemVerbs_Release(&This->FolderItemVerbs_iface);
578 return hr;
581 This->count = GetMenuItemCount(This->hMenu);
582 *verbs = &This->FolderItemVerbs_iface;
583 return S_OK;
585 failed:
586 HeapFree(GetProcessHeap(), 0, This);
587 return hr;
590 static HRESULT WINAPI FolderItemImpl_QueryInterface(FolderItem2 *iface,
591 REFIID riid, LPVOID *ppv)
593 FolderItemImpl *This = impl_from_FolderItem(iface);
595 TRACE("(%p,%p,%p)\n", iface, riid, ppv);
597 if (!ppv) return E_INVALIDARG;
599 if (IsEqualIID(&IID_IUnknown, riid) ||
600 IsEqualIID(&IID_IDispatch, riid) ||
601 IsEqualIID(&IID_FolderItem, riid) ||
602 IsEqualIID(&IID_FolderItem2, riid))
603 *ppv = &This->FolderItem2_iface;
604 else
606 FIXME("not implemented for %s\n", shdebugstr_guid(riid));
607 *ppv = NULL;
608 return E_NOINTERFACE;
610 IUnknown_AddRef((IUnknown*)*ppv);
611 return S_OK;
614 static ULONG WINAPI FolderItemImpl_AddRef(FolderItem2 *iface)
616 FolderItemImpl *This = impl_from_FolderItem(iface);
617 ULONG ref = InterlockedIncrement(&This->ref);
619 TRACE("(%p), new refcount=%i\n", iface, ref);
621 return ref;
624 static ULONG WINAPI FolderItemImpl_Release(FolderItem2 *iface)
626 FolderItemImpl *This = impl_from_FolderItem(iface);
627 ULONG ref = InterlockedDecrement(&This->ref);
629 TRACE("(%p), new refcount=%i\n", iface, ref);
631 if (!ref)
633 VariantClear(&This->dir);
634 HeapFree(GetProcessHeap(), 0, This);
636 return ref;
639 static HRESULT WINAPI FolderItemImpl_GetTypeInfoCount(FolderItem2 *iface,
640 UINT *pctinfo)
642 TRACE("(%p,%p)\n", iface, pctinfo);
644 *pctinfo = 1;
645 return S_OK;
648 static HRESULT WINAPI FolderItemImpl_GetTypeInfo(FolderItem2 *iface, UINT iTInfo,
649 LCID lcid, ITypeInfo **ppTInfo)
651 HRESULT hr;
653 TRACE("(%p,%u,%d,%p)\n", iface, iTInfo, lcid, ppTInfo);
655 hr = get_typeinfo(FolderItem2_tid, ppTInfo);
656 if (SUCCEEDED(hr))
657 ITypeInfo_AddRef(*ppTInfo);
658 return hr;
661 static HRESULT WINAPI FolderItemImpl_GetIDsOfNames(FolderItem2 *iface,
662 REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid,
663 DISPID *rgDispId)
665 ITypeInfo *ti;
666 HRESULT hr;
668 TRACE("(%p,%p,%p,%u,%d,%p)\n", iface, riid, rgszNames, cNames, lcid,
669 rgDispId);
671 hr = get_typeinfo(FolderItem2_tid, &ti);
672 if (SUCCEEDED(hr))
673 hr = ITypeInfo_GetIDsOfNames(ti, rgszNames, cNames, rgDispId);
674 return hr;
677 static HRESULT WINAPI FolderItemImpl_Invoke(FolderItem2 *iface,
678 DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags,
679 DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo,
680 UINT *puArgErr)
682 FolderItemImpl *This = impl_from_FolderItem(iface);
683 ITypeInfo *ti;
684 HRESULT hr;
686 TRACE("(%p,%d,%p,%d,%u,%p,%p,%p,%p)\n", iface, dispIdMember, riid, lcid,
687 wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
689 hr = get_typeinfo(FolderItem2_tid, &ti);
690 if (SUCCEEDED(hr))
691 hr = ITypeInfo_Invoke(ti, This, dispIdMember, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
692 return hr;
695 static HRESULT WINAPI FolderItemImpl_get_Application(FolderItem2 *iface,
696 IDispatch **ppid)
698 FIXME("(%p,%p)\n", iface, ppid);
700 *ppid = NULL;
701 return E_NOTIMPL;
704 static HRESULT WINAPI FolderItemImpl_get_Parent(FolderItem2 *iface,
705 IDispatch **ppid)
707 FIXME("(%p,%p)\n", iface, ppid);
709 *ppid = NULL;
710 return E_NOTIMPL;
713 static HRESULT WINAPI FolderItemImpl_get_Name(FolderItem2 *iface, BSTR *pbs)
715 FIXME("(%p,%p)\n", iface, pbs);
717 *pbs = NULL;
718 return E_NOTIMPL;
721 static HRESULT WINAPI FolderItemImpl_put_Name(FolderItem2 *iface, BSTR bs)
723 FIXME("(%p,%s)\n", iface, debugstr_w(bs));
725 return E_NOTIMPL;
728 static HRESULT WINAPI FolderItemImpl_get_Path(FolderItem2 *iface, BSTR *pbs)
730 FolderItemImpl *This = impl_from_FolderItem(iface);
731 HRESULT ret = S_OK;
732 WCHAR *pathW;
733 int len;
735 TRACE("(%p,%p)\n", iface, pbs);
737 *pbs = NULL;
738 if (V_VT(&This->dir) == VT_I4)
740 pathW = HeapAlloc(GetProcessHeap(), 0, MAX_PATH * sizeof(WCHAR));
741 if (!pathW) return E_OUTOFMEMORY;
742 ret = SHGetFolderPathW(NULL, V_I4(&This->dir), NULL, SHGFP_TYPE_CURRENT,
743 pathW);
744 if (ret == S_OK)
745 *pbs = SysAllocString(pathW);
746 else if (ret == E_INVALIDARG)
748 FIXME("not implemented for %#x\n", V_I4(&This->dir));
749 ret = E_NOTIMPL;
751 HeapFree(GetProcessHeap(), 0, pathW);
753 else /* VT_BSTR */
755 pathW = V_BSTR(&This->dir);
756 len = lstrlenW(pathW);
757 *pbs = SysAllocStringLen(pathW, pathW[len - 1] == '\\' ? len - 1 : len);
759 if (ret == S_OK && !*pbs)
760 ret = E_OUTOFMEMORY;
761 return ret;
764 static HRESULT WINAPI FolderItemImpl_get_GetLink(FolderItem2 *iface,
765 IDispatch **ppid)
767 FIXME("(%p,%p)\n", iface, ppid);
769 *ppid = NULL;
770 return E_NOTIMPL;
773 static HRESULT WINAPI FolderItemImpl_get_GetFolder(FolderItem2 *iface,
774 IDispatch **ppid)
776 FIXME("(%p,%p)\n", iface, ppid);
778 *ppid = NULL;
779 return E_NOTIMPL;
782 static HRESULT WINAPI FolderItemImpl_get_IsLink(FolderItem2 *iface,
783 VARIANT_BOOL *pb)
785 FIXME("(%p,%p)\n", iface, pb);
787 return E_NOTIMPL;
790 static HRESULT WINAPI FolderItemImpl_get_IsFolder(FolderItem2 *iface,
791 VARIANT_BOOL *pb)
793 FIXME("(%p,%p)\n", iface, pb);
795 return E_NOTIMPL;
798 static HRESULT WINAPI FolderItemImpl_get_IsFileSystem(FolderItem2 *iface,
799 VARIANT_BOOL *pb)
801 FIXME("(%p,%p)\n", iface, pb);
803 return E_NOTIMPL;
806 static HRESULT WINAPI FolderItemImpl_get_IsBrowsable(FolderItem2 *iface,
807 VARIANT_BOOL *pb)
809 FIXME("(%p,%p)\n", iface, pb);
811 return E_NOTIMPL;
814 static HRESULT WINAPI FolderItemImpl_get_ModifyDate(FolderItem2 *iface,
815 DATE *pdt)
817 FIXME("(%p,%p)\n", iface, pdt);
819 return E_NOTIMPL;
822 static HRESULT WINAPI FolderItemImpl_put_ModifyDate(FolderItem2 *iface, DATE dt)
824 FIXME("(%p,%f)\n", iface, dt);
826 return E_NOTIMPL;
829 static HRESULT WINAPI FolderItemImpl_get_Size(FolderItem2 *iface, LONG *pul)
831 FIXME("(%p,%p)\n", iface, pul);
833 return E_NOTIMPL;
836 static HRESULT WINAPI FolderItemImpl_get_Type(FolderItem2 *iface, BSTR *pbs)
838 FIXME("(%p,%p)\n", iface, pbs);
840 *pbs = NULL;
841 return E_NOTIMPL;
844 static HRESULT WINAPI FolderItemImpl_Verbs(FolderItem2 *iface, FolderItemVerbs **verbs)
846 HRESULT hr;
847 BSTR path;
849 TRACE("(%p, %p)\n", iface, verbs);
851 if (!verbs)
852 return E_INVALIDARG;
854 *verbs = NULL;
856 hr = FolderItem2_get_Path(iface, &path);
857 if (FAILED(hr))
858 return hr;
860 hr = FolderItemVerbs_Constructor(path, verbs);
861 SysFreeString(path);
862 return hr;
865 static HRESULT WINAPI FolderItemImpl_InvokeVerb(FolderItem2 *iface,
866 VARIANT vVerb)
868 FIXME("(%p)\n", iface);
870 return E_NOTIMPL;
873 static HRESULT WINAPI FolderItemImpl_InvokeVerbEx(FolderItem2 *iface, VARIANT verb, VARIANT args)
875 FIXME("(%p): stub\n", iface);
877 return E_NOTIMPL;
880 static HRESULT WINAPI FolderItemImpl_ExtendedProperty(FolderItem2 *iface, BSTR propname, VARIANT *ret)
882 FIXME("(%p)->(%s %p): stub\n", iface, debugstr_w(propname), ret);
884 return E_NOTIMPL;
887 static const FolderItem2Vtbl FolderItemImpl_Vtbl = {
888 FolderItemImpl_QueryInterface,
889 FolderItemImpl_AddRef,
890 FolderItemImpl_Release,
891 FolderItemImpl_GetTypeInfoCount,
892 FolderItemImpl_GetTypeInfo,
893 FolderItemImpl_GetIDsOfNames,
894 FolderItemImpl_Invoke,
895 FolderItemImpl_get_Application,
896 FolderItemImpl_get_Parent,
897 FolderItemImpl_get_Name,
898 FolderItemImpl_put_Name,
899 FolderItemImpl_get_Path,
900 FolderItemImpl_get_GetLink,
901 FolderItemImpl_get_GetFolder,
902 FolderItemImpl_get_IsLink,
903 FolderItemImpl_get_IsFolder,
904 FolderItemImpl_get_IsFileSystem,
905 FolderItemImpl_get_IsBrowsable,
906 FolderItemImpl_get_ModifyDate,
907 FolderItemImpl_put_ModifyDate,
908 FolderItemImpl_get_Size,
909 FolderItemImpl_get_Type,
910 FolderItemImpl_Verbs,
911 FolderItemImpl_InvokeVerb,
912 FolderItemImpl_InvokeVerbEx,
913 FolderItemImpl_ExtendedProperty
916 static HRESULT FolderItem_Constructor(VARIANT *dir, FolderItem **ppfi)
918 FolderItemImpl *This;
919 HRESULT ret;
921 TRACE("%s\n", debugstr_variant(dir));
923 *ppfi = NULL;
925 This = HeapAlloc(GetProcessHeap(), 0, sizeof(FolderItemImpl));
926 if (!This) return E_OUTOFMEMORY;
927 This->FolderItem2_iface.lpVtbl = &FolderItemImpl_Vtbl;
928 This->ref = 1;
930 VariantInit(&This->dir);
931 ret = VariantCopy(&This->dir, dir);
932 if (FAILED(ret))
934 HeapFree(GetProcessHeap(), 0, This);
935 return E_OUTOFMEMORY;
938 *ppfi = (FolderItem*)&This->FolderItem2_iface;
939 return ret;
942 static HRESULT WINAPI FolderImpl_QueryInterface(Folder3 *iface, REFIID riid,
943 LPVOID *ppv)
945 FolderImpl *This = impl_from_Folder(iface);
947 TRACE("(%p,%p,%p)\n", iface, riid, ppv);
949 if (!ppv) return E_INVALIDARG;
951 if (IsEqualIID(&IID_IUnknown, riid) ||
952 IsEqualIID(&IID_IDispatch, riid) ||
953 IsEqualIID(&IID_Folder, riid) ||
954 IsEqualIID(&IID_Folder2, riid) ||
955 IsEqualIID(&IID_Folder3, riid))
956 *ppv = &This->Folder3_iface;
957 else
959 FIXME("not implemented for %s\n", shdebugstr_guid(riid));
960 *ppv = NULL;
961 return E_NOINTERFACE;
963 IUnknown_AddRef((IUnknown*)*ppv);
964 return S_OK;
967 static ULONG WINAPI FolderImpl_AddRef(Folder3 *iface)
969 FolderImpl *This = impl_from_Folder(iface);
970 ULONG ref = InterlockedIncrement(&This->ref);
972 TRACE("(%p), new refcount=%i\n", iface, ref);
974 return ref;
977 static ULONG WINAPI FolderImpl_Release(Folder3 *iface)
979 FolderImpl *This = impl_from_Folder(iface);
980 ULONG ref = InterlockedDecrement(&This->ref);
982 TRACE("(%p), new refcount=%i\n", iface, ref);
984 if (!ref)
986 VariantClear(&This->dir);
987 HeapFree(GetProcessHeap(), 0, This);
989 return ref;
992 static HRESULT WINAPI FolderImpl_GetTypeInfoCount(Folder3 *iface, UINT *pctinfo)
994 TRACE("(%p,%p)\n", iface, pctinfo);
996 *pctinfo = 1;
997 return S_OK;
1000 static HRESULT WINAPI FolderImpl_GetTypeInfo(Folder3 *iface, UINT iTInfo,
1001 LCID lcid, ITypeInfo **ppTInfo)
1003 HRESULT hr;
1005 TRACE("(%p,%u,%d,%p)\n", iface, iTInfo, lcid, ppTInfo);
1007 hr = get_typeinfo(Folder3_tid, ppTInfo);
1008 if (SUCCEEDED(hr))
1009 ITypeInfo_AddRef(*ppTInfo);
1011 return hr;
1014 static HRESULT WINAPI FolderImpl_GetIDsOfNames(Folder3 *iface, REFIID riid,
1015 LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
1017 ITypeInfo *ti;
1018 HRESULT hr;
1020 TRACE("(%p,%p,%p,%u,%d,%p)\n", iface, riid, rgszNames, cNames, lcid,
1021 rgDispId);
1023 hr = get_typeinfo(Folder3_tid, &ti);
1024 if (SUCCEEDED(hr))
1025 hr = ITypeInfo_GetIDsOfNames(ti, rgszNames, cNames, rgDispId);
1026 return hr;
1029 static HRESULT WINAPI FolderImpl_Invoke(Folder3 *iface, DISPID dispIdMember,
1030 REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
1031 VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
1033 FolderImpl *This = impl_from_Folder(iface);
1034 ITypeInfo *ti;
1035 HRESULT hr;
1037 TRACE("(%p,%d,%p,%d,%u,%p,%p,%p,%p)\n", iface, dispIdMember, riid, lcid,
1038 wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
1040 hr = get_typeinfo(Folder3_tid, &ti);
1041 if (SUCCEEDED(hr))
1042 hr = ITypeInfo_Invoke(ti, This, dispIdMember, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
1043 return hr;
1046 static HRESULT WINAPI FolderImpl_get_Title(Folder3 *iface, BSTR *pbs)
1048 FolderImpl *This = impl_from_Folder(iface);
1049 WCHAR *p;
1050 int len;
1052 TRACE("(%p,%p)\n", iface, pbs);
1054 *pbs = NULL;
1056 if (V_VT(&This->dir) == VT_I4)
1058 FIXME("special folder constants are not supported\n");
1059 return E_NOTIMPL;
1061 p = PathFindFileNameW(V_BSTR(&This->dir));
1062 len = lstrlenW(p);
1063 *pbs = SysAllocStringLen(p, p[len - 1] == '\\' ? len - 1 : len);
1064 return *pbs ? S_OK : E_OUTOFMEMORY;
1067 static HRESULT WINAPI FolderImpl_get_Application(Folder3 *iface,
1068 IDispatch **ppid)
1070 FIXME("(%p,%p)\n", iface, ppid);
1072 *ppid = NULL;
1073 return E_NOTIMPL;
1076 static HRESULT WINAPI FolderImpl_get_Parent(Folder3 *iface, IDispatch **ppid)
1078 FIXME("(%p,%p)\n", iface, ppid);
1080 *ppid = NULL;
1081 return E_NOTIMPL;
1084 static HRESULT WINAPI FolderImpl_get_ParentFolder(Folder3 *iface, Folder **ppsf)
1086 FIXME("(%p,%p)\n", iface, ppsf);
1088 *ppsf = NULL;
1089 return E_NOTIMPL;
1092 static HRESULT WINAPI FolderImpl_Items(Folder3 *iface, FolderItems **ppid)
1094 FIXME("(%p,%p)\n", iface, ppid);
1096 *ppid = NULL;
1097 return E_NOTIMPL;
1100 static HRESULT WINAPI FolderImpl_ParseName(Folder3 *iface, BSTR name, FolderItem **item)
1102 FolderItem *self;
1103 BSTR str;
1104 WCHAR pathW[MAX_PATH];
1105 VARIANT v;
1106 HRESULT hr;
1108 TRACE("(%p,%s,%p)\n", iface, debugstr_w(name), item);
1110 *item = NULL;
1112 if (!name || !name[0])
1113 return S_FALSE;
1115 hr = Folder3_get_Self(iface, &self);
1116 if (FAILED(hr))
1117 return hr;
1119 hr = FolderItem_get_Path(self, &str);
1120 FolderItem_Release(self);
1122 PathCombineW(pathW, str, name);
1123 SysFreeString(str);
1125 if (!PathFileExistsW(pathW))
1126 return S_FALSE;
1128 V_VT(&v) = VT_BSTR;
1129 V_BSTR(&v) = SysAllocString(pathW);
1130 hr = FolderItem_Constructor(&v, item);
1131 VariantClear(&v);
1132 return hr;
1135 static HRESULT WINAPI FolderImpl_NewFolder(Folder3 *iface, BSTR bName,
1136 VARIANT vOptions)
1138 FIXME("(%p,%s)\n", iface, debugstr_w(bName));
1140 return E_NOTIMPL;
1143 static HRESULT WINAPI FolderImpl_MoveHere(Folder3 *iface, VARIANT vItem,
1144 VARIANT vOptions)
1146 FIXME("(%p)\n", iface);
1148 return E_NOTIMPL;
1151 static HRESULT WINAPI FolderImpl_CopyHere(Folder3 *iface, VARIANT vItem,
1152 VARIANT vOptions)
1154 FIXME("(%p)\n", iface);
1156 return E_NOTIMPL;
1159 static HRESULT WINAPI FolderImpl_GetDetailsOf(Folder3 *iface, VARIANT vItem,
1160 int iColumn, BSTR *pbs)
1162 FIXME("(%p,%d,%p)\n", iface, iColumn, pbs);
1164 *pbs = NULL;
1165 return E_NOTIMPL;
1168 static HRESULT WINAPI FolderImpl_get_Self(Folder3 *iface, FolderItem **ppfi)
1170 FolderImpl *This = impl_from_Folder(iface);
1172 TRACE("(%p,%p)\n", iface, ppfi);
1174 return FolderItem_Constructor(&This->dir, ppfi);
1177 static HRESULT WINAPI FolderImpl_get_OfflineStatus(Folder3 *iface, LONG *pul)
1179 FIXME("(%p,%p)\n", iface, pul);
1181 return E_NOTIMPL;
1184 static HRESULT WINAPI FolderImpl_Synchronize(Folder3 *iface)
1186 FIXME("(%p)\n", iface);
1188 return E_NOTIMPL;
1191 static HRESULT WINAPI FolderImpl_get_HaveToShowWebViewBarricade(Folder3 *iface,
1192 VARIANT_BOOL *pbHaveToShowWebViewBarricade)
1194 FIXME("(%p,%p)\n", iface, pbHaveToShowWebViewBarricade);
1196 return E_NOTIMPL;
1199 static HRESULT WINAPI FolderImpl_DismissedWebViewBarricade(Folder3 *iface)
1201 FIXME("(%p)\n", iface);
1203 return E_NOTIMPL;
1206 static HRESULT WINAPI FolderImpl_get_ShowWebViewBarricade(Folder3 *iface,
1207 VARIANT_BOOL *pbShowWebViewBarricade)
1209 FIXME("(%p,%p)\n", iface, pbShowWebViewBarricade);
1211 return E_NOTIMPL;
1214 static HRESULT WINAPI FolderImpl_put_ShowWebViewBarricade(Folder3 *iface,
1215 VARIANT_BOOL bShowWebViewBarricade)
1217 FIXME("(%p,%d)\n", iface, bShowWebViewBarricade);
1219 return E_NOTIMPL;
1222 static const Folder3Vtbl FolderImpl_Vtbl = {
1223 FolderImpl_QueryInterface,
1224 FolderImpl_AddRef,
1225 FolderImpl_Release,
1226 FolderImpl_GetTypeInfoCount,
1227 FolderImpl_GetTypeInfo,
1228 FolderImpl_GetIDsOfNames,
1229 FolderImpl_Invoke,
1230 FolderImpl_get_Title,
1231 FolderImpl_get_Application,
1232 FolderImpl_get_Parent,
1233 FolderImpl_get_ParentFolder,
1234 FolderImpl_Items,
1235 FolderImpl_ParseName,
1236 FolderImpl_NewFolder,
1237 FolderImpl_MoveHere,
1238 FolderImpl_CopyHere,
1239 FolderImpl_GetDetailsOf,
1240 FolderImpl_get_Self,
1241 FolderImpl_get_OfflineStatus,
1242 FolderImpl_Synchronize,
1243 FolderImpl_get_HaveToShowWebViewBarricade,
1244 FolderImpl_DismissedWebViewBarricade,
1245 FolderImpl_get_ShowWebViewBarricade,
1246 FolderImpl_put_ShowWebViewBarricade
1249 static HRESULT Folder_Constructor(VARIANT *dir, Folder **ppsdf)
1251 FolderImpl *This;
1252 HRESULT ret;
1254 *ppsdf = NULL;
1256 switch (V_VT(dir))
1258 case VT_I4:
1259 /* FIXME: add some checks */
1260 break;
1261 case VT_BSTR:
1262 if (PathIsDirectoryW(V_BSTR(dir)) &&
1263 !PathIsRelativeW(V_BSTR(dir)) &&
1264 PathFileExistsW(V_BSTR(dir)))
1265 break;
1266 default:
1267 return S_FALSE;
1270 This = HeapAlloc(GetProcessHeap(), 0, sizeof(FolderImpl));
1271 if (!This) return E_OUTOFMEMORY;
1272 This->Folder3_iface.lpVtbl = &FolderImpl_Vtbl;
1273 This->ref = 1;
1275 VariantInit(&This->dir);
1276 ret = VariantCopy(&This->dir, dir);
1277 if (FAILED(ret))
1279 HeapFree(GetProcessHeap(), 0, This);
1280 return E_OUTOFMEMORY;
1283 *ppsdf = (Folder*)&This->Folder3_iface;
1284 return ret;
1287 static HRESULT WINAPI ShellDispatch_QueryInterface(IShellDispatch6 *iface,
1288 REFIID riid, LPVOID *ppv)
1290 ShellDispatch *This = impl_from_IShellDispatch6(iface);
1292 TRACE("(%p,%p,%p)\n", iface, riid, ppv);
1294 if (!ppv) return E_INVALIDARG;
1296 if (IsEqualIID(&IID_IUnknown, riid) ||
1297 IsEqualIID(&IID_IDispatch, riid) ||
1298 IsEqualIID(&IID_IShellDispatch, riid) ||
1299 IsEqualIID(&IID_IShellDispatch2, riid) ||
1300 IsEqualIID(&IID_IShellDispatch3, riid) ||
1301 IsEqualIID(&IID_IShellDispatch4, riid) ||
1302 IsEqualIID(&IID_IShellDispatch5, riid) ||
1303 IsEqualIID(&IID_IShellDispatch6, riid))
1304 *ppv = &This->IShellDispatch6_iface;
1305 else
1307 FIXME("not implemented for %s\n", shdebugstr_guid(riid));
1308 *ppv = NULL;
1309 return E_NOINTERFACE;
1312 IShellDispatch6_AddRef(iface);
1313 return S_OK;
1316 static ULONG WINAPI ShellDispatch_AddRef(IShellDispatch6 *iface)
1318 ShellDispatch *This = impl_from_IShellDispatch6(iface);
1319 ULONG ref = InterlockedIncrement(&This->ref);
1321 TRACE("(%p), new refcount=%i\n", iface, ref);
1323 return ref;
1326 static ULONG WINAPI ShellDispatch_Release(IShellDispatch6 *iface)
1328 ShellDispatch *This = impl_from_IShellDispatch6(iface);
1329 ULONG ref = InterlockedDecrement(&This->ref);
1331 TRACE("(%p), new refcount=%i\n", iface, ref);
1333 if (!ref)
1334 HeapFree(GetProcessHeap(), 0, This);
1336 return ref;
1339 static HRESULT WINAPI ShellDispatch_GetTypeInfoCount(IShellDispatch6 *iface,
1340 UINT *pctinfo)
1342 TRACE("(%p,%p)\n", iface, pctinfo);
1344 *pctinfo = 1;
1345 return S_OK;
1348 static HRESULT WINAPI ShellDispatch_GetTypeInfo(IShellDispatch6 *iface,
1349 UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo)
1351 HRESULT hr;
1353 TRACE("(%p,%u,%d,%p)\n", iface, iTInfo, lcid, ppTInfo);
1355 hr = get_typeinfo(IShellDispatch6_tid, ppTInfo);
1356 if (SUCCEEDED(hr))
1357 ITypeInfo_AddRef(*ppTInfo);
1358 return hr;
1361 static HRESULT WINAPI ShellDispatch_GetIDsOfNames(IShellDispatch6 *iface,
1362 REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
1364 ITypeInfo *ti;
1365 HRESULT hr;
1367 TRACE("(%p,%p,%p,%u,%d,%p)\n", iface, riid, rgszNames, cNames, lcid,
1368 rgDispId);
1370 hr = get_typeinfo(IShellDispatch6_tid, &ti);
1371 if (SUCCEEDED(hr))
1372 hr = ITypeInfo_GetIDsOfNames(ti, rgszNames, cNames, rgDispId);
1373 return hr;
1376 static HRESULT WINAPI ShellDispatch_Invoke(IShellDispatch6 *iface,
1377 DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags,
1378 DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo,
1379 UINT *puArgErr)
1381 ShellDispatch *This = impl_from_IShellDispatch6(iface);
1382 ITypeInfo *ti;
1383 HRESULT hr;
1385 TRACE("(%p,%d,%p,%d,%u,%p,%p,%p,%p)\n", iface, dispIdMember, riid, lcid,
1386 wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
1388 hr = get_typeinfo(IShellDispatch6_tid, &ti);
1389 if (SUCCEEDED(hr))
1390 hr = ITypeInfo_Invoke(ti, &This->IShellDispatch6_iface, dispIdMember, wFlags, pDispParams,
1391 pVarResult, pExcepInfo, puArgErr);
1392 return hr;
1395 static HRESULT WINAPI ShellDispatch_get_Application(IShellDispatch6 *iface,
1396 IDispatch **ppid)
1398 FIXME("(%p,%p)\n", iface, ppid);
1400 *ppid = NULL;
1401 return E_NOTIMPL;
1404 static HRESULT WINAPI ShellDispatch_get_Parent(IShellDispatch6 *iface,
1405 IDispatch **ppid)
1407 FIXME("(%p,%p)\n", iface, ppid);
1409 *ppid = NULL;
1410 return E_NOTIMPL;
1413 static HRESULT WINAPI ShellDispatch_NameSpace(IShellDispatch6 *iface,
1414 VARIANT vDir, Folder **ppsdf)
1416 TRACE("(%p,%p)\n", iface, ppsdf);
1418 return Folder_Constructor(&vDir, ppsdf);
1421 static HRESULT WINAPI ShellDispatch_BrowseForFolder(IShellDispatch6 *iface,
1422 LONG Hwnd, BSTR Title, LONG Options, VARIANT RootFolder, Folder **ppsdf)
1424 FIXME("(%p,%x,%s,%x,%p)\n", iface, Hwnd, debugstr_w(Title), Options, ppsdf);
1426 *ppsdf = NULL;
1427 return E_NOTIMPL;
1430 static HRESULT WINAPI ShellDispatch_Windows(IShellDispatch6 *iface,
1431 IDispatch **ppid)
1433 FIXME("(%p,%p)\n", iface, ppid);
1435 *ppid = NULL;
1436 return E_NOTIMPL;
1439 static HRESULT WINAPI ShellDispatch_Open(IShellDispatch6 *iface, VARIANT vDir)
1441 FIXME("(%p)\n", iface);
1443 return E_NOTIMPL;
1446 static HRESULT WINAPI ShellDispatch_Explore(IShellDispatch6 *iface, VARIANT vDir)
1448 FIXME("(%p)\n", iface);
1450 return E_NOTIMPL;
1453 static HRESULT WINAPI ShellDispatch_MinimizeAll(IShellDispatch6 *iface)
1455 FIXME("(%p)\n", iface);
1457 return E_NOTIMPL;
1460 static HRESULT WINAPI ShellDispatch_UndoMinimizeALL(IShellDispatch6 *iface)
1462 FIXME("(%p)\n", iface);
1464 return E_NOTIMPL;
1467 static HRESULT WINAPI ShellDispatch_FileRun(IShellDispatch6 *iface)
1469 FIXME("(%p)\n", iface);
1471 return E_NOTIMPL;
1474 static HRESULT WINAPI ShellDispatch_CascadeWindows(IShellDispatch6 *iface)
1476 FIXME("(%p)\n", iface);
1478 return E_NOTIMPL;
1481 static HRESULT WINAPI ShellDispatch_TileVertically(IShellDispatch6 *iface)
1483 FIXME("(%p)\n", iface);
1485 return E_NOTIMPL;
1488 static HRESULT WINAPI ShellDispatch_TileHorizontally(IShellDispatch6 *iface)
1490 FIXME("(%p)\n", iface);
1492 return E_NOTIMPL;
1495 static HRESULT WINAPI ShellDispatch_ShutdownWindows(IShellDispatch6 *iface)
1497 FIXME("(%p)\n", iface);
1499 return E_NOTIMPL;
1502 static HRESULT WINAPI ShellDispatch_Suspend(IShellDispatch6 *iface)
1504 FIXME("(%p)\n", iface);
1506 return E_NOTIMPL;
1509 static HRESULT WINAPI ShellDispatch_EjectPC(IShellDispatch6 *iface)
1511 FIXME("(%p)\n", iface);
1513 return E_NOTIMPL;
1516 static HRESULT WINAPI ShellDispatch_SetTime(IShellDispatch6 *iface)
1518 FIXME("(%p)\n", iface);
1520 return E_NOTIMPL;
1523 static HRESULT WINAPI ShellDispatch_TrayProperties(IShellDispatch6 *iface)
1525 FIXME("(%p)\n", iface);
1527 return E_NOTIMPL;
1530 static HRESULT WINAPI ShellDispatch_Help(IShellDispatch6 *iface)
1532 FIXME("(%p)\n", iface);
1534 return E_NOTIMPL;
1537 static HRESULT WINAPI ShellDispatch_FindFiles(IShellDispatch6 *iface)
1539 FIXME("(%p)\n", iface);
1541 return E_NOTIMPL;
1544 static HRESULT WINAPI ShellDispatch_FindComputer(IShellDispatch6 *iface)
1546 FIXME("(%p)\n", iface);
1548 return E_NOTIMPL;
1551 static HRESULT WINAPI ShellDispatch_RefreshMenu(IShellDispatch6 *iface)
1553 FIXME("(%p)\n", iface);
1555 return E_NOTIMPL;
1558 static HRESULT WINAPI ShellDispatch_ControlPanelItem(IShellDispatch6 *iface,
1559 BSTR szDir)
1561 FIXME("(%p,%s)\n", iface, debugstr_w(szDir));
1563 return E_NOTIMPL;
1566 static HRESULT WINAPI ShellDispatch_IsRestricted(IShellDispatch6 *iface, BSTR group, BSTR restriction, LONG *value)
1568 FIXME("(%s, %s, %p): stub\n", debugstr_w(group), debugstr_w(restriction), value);
1569 return E_NOTIMPL;
1572 static HRESULT WINAPI ShellDispatch_ShellExecute(IShellDispatch6 *iface,
1573 BSTR file, VARIANT v_args, VARIANT v_dir, VARIANT v_op, VARIANT v_show)
1575 VARIANT args_str, dir_str, op_str, show_int;
1576 WCHAR *args = NULL, *dir = NULL, *op = NULL;
1577 INT show = 0;
1578 HINSTANCE ret;
1580 TRACE("(%s, %s, %s, %s, %s)\n", debugstr_w(file), debugstr_variant(&v_args),
1581 debugstr_variant(&v_dir), debugstr_variant(&v_op), debugstr_variant(&v_show));
1583 VariantInit(&args_str);
1584 VariantChangeType(&args_str, &v_args, 0, VT_BSTR);
1585 if (V_VT(&args_str) == VT_BSTR)
1586 args = V_BSTR(&args_str);
1588 VariantInit(&dir_str);
1589 VariantChangeType(&dir_str, &v_dir, 0, VT_BSTR);
1590 if (V_VT(&dir_str) == VT_BSTR)
1591 dir = V_BSTR(&dir_str);
1593 VariantInit(&op_str);
1594 VariantChangeType(&op_str, &v_op, 0, VT_BSTR);
1595 if (V_VT(&op_str) == VT_BSTR)
1596 op = V_BSTR(&op_str);
1598 VariantInit(&show_int);
1599 VariantChangeType(&show_int, &v_show, 0, VT_I4);
1600 if (V_VT(&show_int) == VT_I4)
1601 show = V_I4(&show_int);
1603 ret = ShellExecuteW(NULL, op, file, args, dir, show);
1605 VariantClear(&args_str);
1606 VariantClear(&dir_str);
1607 VariantClear(&op_str);
1608 VariantClear(&show_int);
1610 return (ULONG_PTR)ret > 32 ? S_OK : S_FALSE;
1613 static HRESULT WINAPI ShellDispatch_FindPrinter(IShellDispatch6 *iface, BSTR name, BSTR location, BSTR model)
1615 FIXME("(%s, %s, %s): stub\n", debugstr_w(name), debugstr_w(location), debugstr_w(model));
1616 return E_NOTIMPL;
1619 static HRESULT WINAPI ShellDispatch_GetSystemInformation(IShellDispatch6 *iface, BSTR name, VARIANT *ret)
1621 FIXME("(%s, %p): stub\n", debugstr_w(name), ret);
1622 return E_NOTIMPL;
1625 static HRESULT WINAPI ShellDispatch_ServiceStart(IShellDispatch6 *iface, BSTR service, VARIANT persistent, VARIANT *ret)
1627 FIXME("(%s, %p): stub\n", debugstr_w(service), ret);
1628 return E_NOTIMPL;
1631 static HRESULT WINAPI ShellDispatch_ServiceStop(IShellDispatch6 *iface, BSTR service, VARIANT persistent, VARIANT *ret)
1633 FIXME("(%s, %p): stub\n", debugstr_w(service), ret);
1634 return E_NOTIMPL;
1637 static HRESULT WINAPI ShellDispatch_IsServiceRunning(IShellDispatch6 *iface, BSTR name, VARIANT *running)
1639 SERVICE_STATUS_PROCESS status;
1640 SC_HANDLE scm, service;
1641 DWORD dummy;
1643 TRACE("(%s, %p)\n", debugstr_w(name), running);
1645 V_VT(running) = VT_BOOL;
1646 V_BOOL(running) = VARIANT_FALSE;
1648 scm = OpenSCManagerW(NULL, NULL, SC_MANAGER_CONNECT);
1649 if (!scm)
1651 ERR("failed to connect to service manager\n");
1652 return S_OK;
1655 service = OpenServiceW(scm, name, SERVICE_QUERY_STATUS);
1656 if (!service)
1658 ERR("Failed to open service %s (%u)\n", debugstr_w(name), GetLastError());
1659 CloseServiceHandle(scm);
1660 return S_OK;
1663 if (!QueryServiceStatusEx(service, SC_STATUS_PROCESS_INFO, (BYTE *)&status,
1664 sizeof(SERVICE_STATUS_PROCESS), &dummy))
1666 TRACE("failed to query service status (%u)\n", GetLastError());
1667 CloseServiceHandle(service);
1668 CloseServiceHandle(scm);
1669 return S_OK;
1672 if (status.dwCurrentState == SERVICE_RUNNING)
1673 V_BOOL(running) = VARIANT_TRUE;
1675 CloseServiceHandle(service);
1676 CloseServiceHandle(scm);
1678 return S_OK;
1681 static HRESULT WINAPI ShellDispatch_CanStartStopService(IShellDispatch6 *iface, BSTR service, VARIANT *ret)
1683 FIXME("(%s, %p): stub\n", debugstr_w(service), ret);
1684 return E_NOTIMPL;
1687 static HRESULT WINAPI ShellDispatch_ShowBrowserBar(IShellDispatch6 *iface, BSTR clsid, VARIANT show, VARIANT *ret)
1689 FIXME("(%s, %p): stub\n", debugstr_w(clsid), ret);
1690 return E_NOTIMPL;
1693 static HRESULT WINAPI ShellDispatch_AddToRecent(IShellDispatch6 *iface, VARIANT file, BSTR category)
1695 FIXME("(%s): stub\n", debugstr_w(category));
1696 return E_NOTIMPL;
1699 static HRESULT WINAPI ShellDispatch_WindowsSecurity(IShellDispatch6 *iface)
1701 FIXME("stub\n");
1702 return E_NOTIMPL;
1705 static HRESULT WINAPI ShellDispatch_ToggleDesktop(IShellDispatch6 *iface)
1707 FIXME("stub\n");
1708 return E_NOTIMPL;
1711 static HRESULT WINAPI ShellDispatch_ExplorerPolicy(IShellDispatch6 *iface, BSTR policy, VARIANT *value)
1713 FIXME("(%s, %p): stub\n", debugstr_w(policy), value);
1714 return E_NOTIMPL;
1717 static HRESULT WINAPI ShellDispatch_GetSetting(IShellDispatch6 *iface, LONG setting, VARIANT_BOOL *result)
1719 FIXME("(%d %p): stub\n", setting, result);
1720 return E_NOTIMPL;
1723 static HRESULT WINAPI ShellDispatch_WindowSwitcher(IShellDispatch6 *iface)
1725 FIXME("stub\n");
1726 return E_NOTIMPL;
1729 static HRESULT WINAPI ShellDispatch_SearchCommand(IShellDispatch6 *iface)
1731 FIXME("stub\n");
1732 return E_NOTIMPL;
1735 static const IShellDispatch6Vtbl ShellDispatchVtbl = {
1736 ShellDispatch_QueryInterface,
1737 ShellDispatch_AddRef,
1738 ShellDispatch_Release,
1739 ShellDispatch_GetTypeInfoCount,
1740 ShellDispatch_GetTypeInfo,
1741 ShellDispatch_GetIDsOfNames,
1742 ShellDispatch_Invoke,
1743 ShellDispatch_get_Application,
1744 ShellDispatch_get_Parent,
1745 ShellDispatch_NameSpace,
1746 ShellDispatch_BrowseForFolder,
1747 ShellDispatch_Windows,
1748 ShellDispatch_Open,
1749 ShellDispatch_Explore,
1750 ShellDispatch_MinimizeAll,
1751 ShellDispatch_UndoMinimizeALL,
1752 ShellDispatch_FileRun,
1753 ShellDispatch_CascadeWindows,
1754 ShellDispatch_TileVertically,
1755 ShellDispatch_TileHorizontally,
1756 ShellDispatch_ShutdownWindows,
1757 ShellDispatch_Suspend,
1758 ShellDispatch_EjectPC,
1759 ShellDispatch_SetTime,
1760 ShellDispatch_TrayProperties,
1761 ShellDispatch_Help,
1762 ShellDispatch_FindFiles,
1763 ShellDispatch_FindComputer,
1764 ShellDispatch_RefreshMenu,
1765 ShellDispatch_ControlPanelItem,
1766 ShellDispatch_IsRestricted,
1767 ShellDispatch_ShellExecute,
1768 ShellDispatch_FindPrinter,
1769 ShellDispatch_GetSystemInformation,
1770 ShellDispatch_ServiceStart,
1771 ShellDispatch_ServiceStop,
1772 ShellDispatch_IsServiceRunning,
1773 ShellDispatch_CanStartStopService,
1774 ShellDispatch_ShowBrowserBar,
1775 ShellDispatch_AddToRecent,
1776 ShellDispatch_WindowsSecurity,
1777 ShellDispatch_ToggleDesktop,
1778 ShellDispatch_ExplorerPolicy,
1779 ShellDispatch_GetSetting,
1780 ShellDispatch_WindowSwitcher,
1781 ShellDispatch_SearchCommand
1784 HRESULT WINAPI IShellDispatch_Constructor(IUnknown *outer, REFIID riid, void **ppv)
1786 ShellDispatch *This;
1787 HRESULT ret;
1789 TRACE("(%p, %s)\n", outer, debugstr_guid(riid));
1791 *ppv = NULL;
1793 if (outer) return CLASS_E_NOAGGREGATION;
1795 This = HeapAlloc(GetProcessHeap(), 0, sizeof(ShellDispatch));
1796 if (!This) return E_OUTOFMEMORY;
1797 This->IShellDispatch6_iface.lpVtbl = &ShellDispatchVtbl;
1798 This->ref = 1;
1800 ret = IShellDispatch6_QueryInterface(&This->IShellDispatch6_iface, riid, ppv);
1801 IShellDispatch6_Release(&This->IShellDispatch6_iface);
1802 return ret;