webservices: Add a stub implementation of WS_TYPE_ATTRIBUTE_FIELD_MAPPING in the...
[wine.git] / dlls / shell32 / shelldispatch.c
blobac79302c9334ad7e66b6d94b67399eaa429ef986
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_FolderItems3,
52 &IID_FolderItemVerb,
53 &IID_FolderItemVerbs
55 static ITypeInfo *typeinfos[LAST_tid];
57 typedef struct {
58 IShellDispatch6 IShellDispatch6_iface;
59 LONG ref;
60 } ShellDispatch;
62 typedef struct {
63 Folder3 Folder3_iface;
64 LONG ref;
65 VARIANT dir;
66 } FolderImpl;
68 typedef struct {
69 FolderItems3 FolderItems3_iface;
70 LONG ref;
71 } FolderItemsImpl;
73 typedef struct {
74 FolderItem2 FolderItem2_iface;
75 LONG ref;
76 VARIANT dir;
77 } FolderItemImpl;
79 typedef struct {
80 FolderItemVerbs FolderItemVerbs_iface;
81 LONG ref;
83 IContextMenu *contextmenu;
84 HMENU hMenu;
85 LONG count;
86 } FolderItemVerbsImpl;
88 typedef struct {
89 FolderItemVerb FolderItemVerb_iface;
90 LONG ref;
92 IContextMenu *contextmenu;
93 BSTR name;
94 } FolderItemVerbImpl;
96 static inline ShellDispatch *impl_from_IShellDispatch6(IShellDispatch6 *iface)
98 return CONTAINING_RECORD(iface, ShellDispatch, IShellDispatch6_iface);
101 static inline FolderImpl *impl_from_Folder(Folder3 *iface)
103 return CONTAINING_RECORD(iface, FolderImpl, Folder3_iface);
106 static inline FolderItemsImpl *impl_from_FolderItems(FolderItems3 *iface)
108 return CONTAINING_RECORD(iface, FolderItemsImpl, FolderItems3_iface);
111 static inline FolderItemImpl *impl_from_FolderItem(FolderItem2 *iface)
113 return CONTAINING_RECORD(iface, FolderItemImpl, FolderItem2_iface);
116 static inline FolderItemVerbsImpl *impl_from_FolderItemVerbs(FolderItemVerbs *iface)
118 return CONTAINING_RECORD(iface, FolderItemVerbsImpl, FolderItemVerbs_iface);
121 static inline FolderItemVerbImpl *impl_from_FolderItemVerb(FolderItemVerb *iface)
123 return CONTAINING_RECORD(iface, FolderItemVerbImpl, FolderItemVerb_iface);
126 static HRESULT load_typelib(void)
128 ITypeLib *tl;
129 HRESULT hr;
131 hr = LoadRegTypeLib(&LIBID_Shell32, 1, 0, LOCALE_SYSTEM_DEFAULT, &tl);
132 if (FAILED(hr)) {
133 ERR("LoadRegTypeLib failed: %08x\n", hr);
134 return hr;
137 if (InterlockedCompareExchangePointer((void**)&typelib, tl, NULL))
138 ITypeLib_Release(tl);
139 return hr;
142 void release_typelib(void)
144 unsigned i;
146 if (!typelib)
147 return;
149 for (i = 0; i < sizeof(typeinfos)/sizeof(*typeinfos); i++)
150 if (typeinfos[i])
151 ITypeInfo_Release(typeinfos[i]);
153 ITypeLib_Release(typelib);
156 HRESULT get_typeinfo(enum tid_t tid, ITypeInfo **typeinfo)
158 HRESULT hr;
160 if (!typelib)
161 hr = load_typelib();
162 if (!typelib)
163 return hr;
165 if (!typeinfos[tid])
167 ITypeInfo *ti;
169 hr = ITypeLib_GetTypeInfoOfGuid(typelib, tid_ids[tid], &ti);
170 if (FAILED(hr))
172 ERR("GetTypeInfoOfGuid(%s) failed: %08x\n", debugstr_guid(tid_ids[tid]), hr);
173 return hr;
176 if (InterlockedCompareExchangePointer((void**)(typeinfos+tid), ti, NULL))
177 ITypeInfo_Release(ti);
180 *typeinfo = typeinfos[tid];
181 return S_OK;
184 /* FolderItemVerb */
185 static HRESULT WINAPI FolderItemVerbImpl_QueryInterface(FolderItemVerb *iface,
186 REFIID riid, void **ppv)
188 FolderItemVerbImpl *This = impl_from_FolderItemVerb(iface);
190 TRACE("(%p,%s,%p)\n", iface, shdebugstr_guid(riid), ppv);
192 *ppv = NULL;
194 if (IsEqualIID(&IID_IUnknown, riid) ||
195 IsEqualIID(&IID_IDispatch, riid) ||
196 IsEqualIID(&IID_FolderItemVerb, riid))
197 *ppv = &This->FolderItemVerb_iface;
198 else
200 FIXME("not implemented for %s\n", shdebugstr_guid(riid));
201 *ppv = NULL;
202 return E_NOINTERFACE;
205 IUnknown_AddRef((IUnknown*)*ppv);
206 return S_OK;
209 static ULONG WINAPI FolderItemVerbImpl_AddRef(FolderItemVerb *iface)
211 FolderItemVerbImpl *This = impl_from_FolderItemVerb(iface);
212 ULONG ref = InterlockedIncrement(&This->ref);
214 TRACE("(%p), new refcount=%i\n", iface, ref);
216 return ref;
219 static ULONG WINAPI FolderItemVerbImpl_Release(FolderItemVerb *iface)
221 FolderItemVerbImpl *This = impl_from_FolderItemVerb(iface);
222 ULONG ref = InterlockedDecrement(&This->ref);
224 TRACE("(%p), new refcount=%i\n", iface, ref);
226 if (!ref)
228 IContextMenu_Release(This->contextmenu);
229 SysFreeString(This->name);
230 HeapFree(GetProcessHeap(), 0, This);
233 return ref;
236 static HRESULT WINAPI FolderItemVerbImpl_GetTypeInfoCount(FolderItemVerb *iface, UINT *pctinfo)
238 TRACE("(%p,%p)\n", iface, pctinfo);
239 *pctinfo = 1;
240 return S_OK;
243 static HRESULT WINAPI FolderItemVerbImpl_GetTypeInfo(FolderItemVerb *iface, UINT iTInfo,
244 LCID lcid, ITypeInfo **ppTInfo)
246 HRESULT hr;
248 TRACE("(%p,%u,%d,%p)\n", iface, iTInfo, lcid, ppTInfo);
250 hr = get_typeinfo(FolderItemVerb_tid, ppTInfo);
251 if (SUCCEEDED(hr))
252 ITypeInfo_AddRef(*ppTInfo);
253 return hr;
256 static HRESULT WINAPI FolderItemVerbImpl_GetIDsOfNames(FolderItemVerb *iface,
257 REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
259 ITypeInfo *ti;
260 HRESULT hr;
262 TRACE("(%p,%s,%p,%u,%d,%p)\n", iface, shdebugstr_guid(riid), rgszNames, cNames, lcid,
263 rgDispId);
265 hr = get_typeinfo(FolderItemVerb_tid, &ti);
266 if (SUCCEEDED(hr))
267 hr = ITypeInfo_GetIDsOfNames(ti, rgszNames, cNames, rgDispId);
268 return hr;
271 static HRESULT WINAPI FolderItemVerbImpl_Invoke(FolderItemVerb *iface,
272 DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags,
273 DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo,
274 UINT *puArgErr)
276 ITypeInfo *ti;
277 HRESULT hr;
279 TRACE("(%p,%d,%s,%d,%u,%p,%p,%p,%p)\n", iface, dispIdMember, shdebugstr_guid(riid), lcid,
280 wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
282 hr = get_typeinfo(FolderItemVerb_tid, &ti);
283 if (SUCCEEDED(hr))
284 hr = ITypeInfo_Invoke(ti, iface, dispIdMember, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
285 return hr;
288 static HRESULT WINAPI FolderItemVerbImpl_get_Application(FolderItemVerb *iface, IDispatch **disp)
290 FIXME("(%p, %p)\n", iface, disp);
291 return E_NOTIMPL;
294 static HRESULT WINAPI FolderItemVerbImpl_get_Parent(FolderItemVerb *iface, IDispatch **disp)
296 FIXME("(%p, %p)\n", iface, disp);
297 return E_NOTIMPL;
300 static HRESULT WINAPI FolderItemVerbImpl_get_Name(FolderItemVerb *iface, BSTR *name)
302 FolderItemVerbImpl *This = impl_from_FolderItemVerb(iface);
304 TRACE("(%p, %p)\n", iface, name);
306 *name = SysAllocString(This->name);
307 return *name ? S_OK : E_OUTOFMEMORY;
310 static HRESULT WINAPI FolderItemVerbImpl_DoIt(FolderItemVerb *iface)
312 FIXME("(%p)\n", iface);
313 return E_NOTIMPL;
316 static FolderItemVerbVtbl folderitemverbvtbl = {
317 FolderItemVerbImpl_QueryInterface,
318 FolderItemVerbImpl_AddRef,
319 FolderItemVerbImpl_Release,
320 FolderItemVerbImpl_GetTypeInfoCount,
321 FolderItemVerbImpl_GetTypeInfo,
322 FolderItemVerbImpl_GetIDsOfNames,
323 FolderItemVerbImpl_Invoke,
324 FolderItemVerbImpl_get_Application,
325 FolderItemVerbImpl_get_Parent,
326 FolderItemVerbImpl_get_Name,
327 FolderItemVerbImpl_DoIt
330 static HRESULT FolderItemVerb_Constructor(IContextMenu *contextmenu, BSTR name, FolderItemVerb **verb)
332 FolderItemVerbImpl *This;
334 TRACE("%p, %s\n", contextmenu, debugstr_w(name));
336 This = HeapAlloc(GetProcessHeap(), 0, sizeof(FolderItemVerbImpl));
337 if (!This)
338 return E_OUTOFMEMORY;
340 This->FolderItemVerb_iface.lpVtbl = &folderitemverbvtbl;
341 This->ref = 1;
342 This->contextmenu = contextmenu;
343 IContextMenu_AddRef(contextmenu);
344 This->name = name;
346 *verb = &This->FolderItemVerb_iface;
347 return S_OK;
350 /* FolderItemVerbs */
351 static HRESULT WINAPI FolderItemVerbsImpl_QueryInterface(FolderItemVerbs *iface,
352 REFIID riid, void **ppv)
354 FolderItemVerbsImpl *This = impl_from_FolderItemVerbs(iface);
356 TRACE("(%p,%s,%p)\n", iface, shdebugstr_guid(riid), ppv);
358 *ppv = NULL;
360 if (IsEqualIID(&IID_IUnknown, riid) ||
361 IsEqualIID(&IID_IDispatch, riid) ||
362 IsEqualIID(&IID_FolderItemVerbs, riid))
363 *ppv = &This->FolderItemVerbs_iface;
364 else
366 FIXME("not implemented for %s\n", shdebugstr_guid(riid));
367 *ppv = NULL;
368 return E_NOINTERFACE;
371 IUnknown_AddRef((IUnknown*)*ppv);
372 return S_OK;
375 static ULONG WINAPI FolderItemVerbsImpl_AddRef(FolderItemVerbs *iface)
377 FolderItemVerbsImpl *This = impl_from_FolderItemVerbs(iface);
378 ULONG ref = InterlockedIncrement(&This->ref);
380 TRACE("(%p), new refcount=%i\n", iface, ref);
382 return ref;
385 static ULONG WINAPI FolderItemVerbsImpl_Release(FolderItemVerbs *iface)
387 FolderItemVerbsImpl *This = impl_from_FolderItemVerbs(iface);
388 ULONG ref = InterlockedDecrement(&This->ref);
390 TRACE("(%p), new refcount=%i\n", iface, ref);
392 if (!ref)
394 IContextMenu_Release(This->contextmenu);
395 DestroyMenu(This->hMenu);
396 HeapFree(GetProcessHeap(), 0, This);
399 return ref;
402 static HRESULT WINAPI FolderItemVerbsImpl_GetTypeInfoCount(FolderItemVerbs *iface, UINT *pctinfo)
404 TRACE("(%p,%p)\n", iface, pctinfo);
405 *pctinfo = 1;
406 return S_OK;
409 static HRESULT WINAPI FolderItemVerbsImpl_GetTypeInfo(FolderItemVerbs *iface, UINT iTInfo,
410 LCID lcid, ITypeInfo **ppTInfo)
412 HRESULT hr;
414 TRACE("(%p,%u,%d,%p)\n", iface, iTInfo, lcid, ppTInfo);
416 hr = get_typeinfo(FolderItemVerbs_tid, ppTInfo);
417 if (SUCCEEDED(hr))
418 ITypeInfo_AddRef(*ppTInfo);
419 return hr;
422 static HRESULT WINAPI FolderItemVerbsImpl_GetIDsOfNames(FolderItemVerbs *iface,
423 REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
425 ITypeInfo *ti;
426 HRESULT hr;
428 TRACE("(%p,%s,%p,%u,%d,%p)\n", iface, shdebugstr_guid(riid), rgszNames, cNames, lcid,
429 rgDispId);
431 hr = get_typeinfo(FolderItemVerbs_tid, &ti);
432 if (SUCCEEDED(hr))
433 hr = ITypeInfo_GetIDsOfNames(ti, rgszNames, cNames, rgDispId);
434 return hr;
437 static HRESULT WINAPI FolderItemVerbsImpl_Invoke(FolderItemVerbs *iface,
438 DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags,
439 DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo,
440 UINT *puArgErr)
442 ITypeInfo *ti;
443 HRESULT hr;
445 TRACE("(%p,%d,%s,%d,%u,%p,%p,%p,%p)\n", iface, dispIdMember, shdebugstr_guid(riid), lcid,
446 wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
448 hr = get_typeinfo(FolderItemVerbs_tid, &ti);
449 if (SUCCEEDED(hr))
450 hr = ITypeInfo_Invoke(ti, iface, dispIdMember, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
451 return hr;
454 static HRESULT WINAPI FolderItemVerbsImpl_get_Count(FolderItemVerbs *iface, LONG *count)
456 FolderItemVerbsImpl *This = impl_from_FolderItemVerbs(iface);
458 TRACE("(%p, %p)\n", iface, count);
460 if (!count)
461 return E_INVALIDARG;
463 *count = This->count;
464 return S_OK;
467 static HRESULT WINAPI FolderItemVerbsImpl_get_Application(FolderItemVerbs *iface, IDispatch **disp)
469 FIXME("(%p, %p)\n", iface, disp);
470 return E_NOTIMPL;
473 static HRESULT WINAPI FolderItemVerbsImpl_get_Parent(FolderItemVerbs *iface, IDispatch **disp)
475 FIXME("(%p, %p)\n", iface, disp);
476 return E_NOTIMPL;
479 static HRESULT WINAPI FolderItemVerbsImpl_Item(FolderItemVerbs *iface, VARIANT index, FolderItemVerb **verb)
481 FolderItemVerbsImpl *This = impl_from_FolderItemVerbs(iface);
482 MENUITEMINFOW info;
483 HRESULT hr;
484 VARIANT v;
485 BSTR name;
487 TRACE("(%p, %s, %p)\n", iface, debugstr_variant(&index), verb);
489 if (!verb)
490 return E_INVALIDARG;
492 *verb = NULL;
494 VariantInit(&v);
495 VariantCopyInd(&v, &index);
497 hr = VariantChangeType(&v, &v, 0, VT_I4);
498 if (FAILED(hr))
500 FIXME("failed to coerce to VT_I4, %s\n", debugstr_variant(&v));
501 return hr;
504 if (V_I4(&v) > This->count)
505 return S_OK;
507 if (V_I4(&v) == This->count)
508 name = SysAllocStringLen(NULL, 0);
509 else
511 /* get item name */
512 memset(&info, 0, sizeof(info));
513 info.cbSize = sizeof(info);
514 info.fMask = MIIM_STRING;
515 if (!GetMenuItemInfoW(This->hMenu, V_I4(&v), TRUE, &info))
516 return E_FAIL;
518 name = SysAllocStringLen(NULL, info.cch);
519 if (name)
521 info.dwTypeData = name;
522 info.cch++;
523 GetMenuItemInfoW(This->hMenu, V_I4(&v), TRUE, &info);
527 if (!name)
528 return E_OUTOFMEMORY;
530 return FolderItemVerb_Constructor(This->contextmenu, name, verb);
533 static HRESULT WINAPI FolderItemVerbsImpl__NewEnum(FolderItemVerbs *iface, IUnknown **ret)
535 FIXME("(%p, %p)\n", iface, ret);
536 return E_NOTIMPL;
539 static FolderItemVerbsVtbl folderitemverbsvtbl = {
540 FolderItemVerbsImpl_QueryInterface,
541 FolderItemVerbsImpl_AddRef,
542 FolderItemVerbsImpl_Release,
543 FolderItemVerbsImpl_GetTypeInfoCount,
544 FolderItemVerbsImpl_GetTypeInfo,
545 FolderItemVerbsImpl_GetIDsOfNames,
546 FolderItemVerbsImpl_Invoke,
547 FolderItemVerbsImpl_get_Count,
548 FolderItemVerbsImpl_get_Application,
549 FolderItemVerbsImpl_get_Parent,
550 FolderItemVerbsImpl_Item,
551 FolderItemVerbsImpl__NewEnum
554 static HRESULT FolderItemVerbs_Constructor(BSTR path, FolderItemVerbs **verbs)
556 FolderItemVerbsImpl *This;
557 IShellFolder *folder;
558 LPCITEMIDLIST child;
559 LPITEMIDLIST pidl;
560 HRESULT hr;
562 This = HeapAlloc(GetProcessHeap(), 0, sizeof(FolderItemVerbsImpl));
563 if (!This)
564 return E_OUTOFMEMORY;
566 This->FolderItemVerbs_iface.lpVtbl = &folderitemverbsvtbl;
567 This->ref = 1;
569 /* build context menu for this path */
570 hr = SHParseDisplayName(path, NULL, &pidl, 0, NULL);
571 if (FAILED(hr))
572 goto failed;
574 hr = SHBindToParent(pidl, &IID_IShellFolder, (void**)&folder, &child);
575 CoTaskMemFree(pidl);
576 if (FAILED(hr))
577 goto failed;
579 hr = IShellFolder_GetUIObjectOf(folder, NULL, 1, &child, &IID_IContextMenu, NULL, (void**)&This->contextmenu);
580 IShellFolder_Release(folder);
581 if (FAILED(hr))
582 goto failed;
584 This->hMenu = CreatePopupMenu();
585 hr = IContextMenu_QueryContextMenu(This->contextmenu, This->hMenu, 0, FCIDM_SHVIEWFIRST, FCIDM_SHVIEWLAST, CMF_NORMAL);
586 if (FAILED(hr))
588 FolderItemVerbs_Release(&This->FolderItemVerbs_iface);
589 return hr;
592 This->count = GetMenuItemCount(This->hMenu);
593 *verbs = &This->FolderItemVerbs_iface;
594 return S_OK;
596 failed:
597 HeapFree(GetProcessHeap(), 0, This);
598 return hr;
601 static HRESULT WINAPI FolderItemImpl_QueryInterface(FolderItem2 *iface,
602 REFIID riid, LPVOID *ppv)
604 FolderItemImpl *This = impl_from_FolderItem(iface);
606 TRACE("(%p,%s,%p)\n", iface, shdebugstr_guid(riid), ppv);
608 if (!ppv) return E_INVALIDARG;
610 if (IsEqualIID(&IID_IUnknown, riid) ||
611 IsEqualIID(&IID_IDispatch, riid) ||
612 IsEqualIID(&IID_FolderItem, riid) ||
613 IsEqualIID(&IID_FolderItem2, riid))
614 *ppv = &This->FolderItem2_iface;
615 else
617 FIXME("not implemented for %s\n", shdebugstr_guid(riid));
618 *ppv = NULL;
619 return E_NOINTERFACE;
621 IUnknown_AddRef((IUnknown*)*ppv);
622 return S_OK;
625 static ULONG WINAPI FolderItemImpl_AddRef(FolderItem2 *iface)
627 FolderItemImpl *This = impl_from_FolderItem(iface);
628 ULONG ref = InterlockedIncrement(&This->ref);
630 TRACE("(%p), new refcount=%i\n", iface, ref);
632 return ref;
635 static ULONG WINAPI FolderItemImpl_Release(FolderItem2 *iface)
637 FolderItemImpl *This = impl_from_FolderItem(iface);
638 ULONG ref = InterlockedDecrement(&This->ref);
640 TRACE("(%p), new refcount=%i\n", iface, ref);
642 if (!ref)
644 VariantClear(&This->dir);
645 HeapFree(GetProcessHeap(), 0, This);
647 return ref;
650 static HRESULT WINAPI FolderItemImpl_GetTypeInfoCount(FolderItem2 *iface,
651 UINT *pctinfo)
653 TRACE("(%p,%p)\n", iface, pctinfo);
655 *pctinfo = 1;
656 return S_OK;
659 static HRESULT WINAPI FolderItemImpl_GetTypeInfo(FolderItem2 *iface, UINT iTInfo,
660 LCID lcid, ITypeInfo **ppTInfo)
662 HRESULT hr;
664 TRACE("(%p,%u,%d,%p)\n", iface, iTInfo, lcid, ppTInfo);
666 hr = get_typeinfo(FolderItem2_tid, ppTInfo);
667 if (SUCCEEDED(hr))
668 ITypeInfo_AddRef(*ppTInfo);
669 return hr;
672 static HRESULT WINAPI FolderItemImpl_GetIDsOfNames(FolderItem2 *iface,
673 REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid,
674 DISPID *rgDispId)
676 ITypeInfo *ti;
677 HRESULT hr;
679 TRACE("(%p,%s,%p,%u,%d,%p)\n", iface, shdebugstr_guid(riid), rgszNames, cNames, lcid,
680 rgDispId);
682 hr = get_typeinfo(FolderItem2_tid, &ti);
683 if (SUCCEEDED(hr))
684 hr = ITypeInfo_GetIDsOfNames(ti, rgszNames, cNames, rgDispId);
685 return hr;
688 static HRESULT WINAPI FolderItemImpl_Invoke(FolderItem2 *iface,
689 DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags,
690 DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo,
691 UINT *puArgErr)
693 FolderItemImpl *This = impl_from_FolderItem(iface);
694 ITypeInfo *ti;
695 HRESULT hr;
697 TRACE("(%p,%d,%s,%d,%u,%p,%p,%p,%p)\n", iface, dispIdMember, shdebugstr_guid(riid), lcid,
698 wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
700 hr = get_typeinfo(FolderItem2_tid, &ti);
701 if (SUCCEEDED(hr))
702 hr = ITypeInfo_Invoke(ti, This, dispIdMember, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
703 return hr;
706 static HRESULT WINAPI FolderItemImpl_get_Application(FolderItem2 *iface,
707 IDispatch **ppid)
709 FIXME("(%p,%p)\n", iface, ppid);
711 *ppid = NULL;
712 return E_NOTIMPL;
715 static HRESULT WINAPI FolderItemImpl_get_Parent(FolderItem2 *iface,
716 IDispatch **ppid)
718 FIXME("(%p,%p)\n", iface, ppid);
720 *ppid = NULL;
721 return E_NOTIMPL;
724 static HRESULT WINAPI FolderItemImpl_get_Name(FolderItem2 *iface, BSTR *pbs)
726 FIXME("(%p,%p)\n", iface, pbs);
728 *pbs = NULL;
729 return E_NOTIMPL;
732 static HRESULT WINAPI FolderItemImpl_put_Name(FolderItem2 *iface, BSTR bs)
734 FIXME("(%p,%s)\n", iface, debugstr_w(bs));
736 return E_NOTIMPL;
739 static HRESULT WINAPI FolderItemImpl_get_Path(FolderItem2 *iface, BSTR *pbs)
741 FolderItemImpl *This = impl_from_FolderItem(iface);
742 HRESULT ret = S_OK;
743 WCHAR *pathW;
744 int len;
746 TRACE("(%p,%p)\n", iface, pbs);
748 *pbs = NULL;
749 if (V_VT(&This->dir) == VT_I4)
751 pathW = HeapAlloc(GetProcessHeap(), 0, MAX_PATH * sizeof(WCHAR));
752 if (!pathW) return E_OUTOFMEMORY;
753 ret = SHGetFolderPathW(NULL, V_I4(&This->dir), NULL, SHGFP_TYPE_CURRENT,
754 pathW);
755 if (ret == S_OK)
756 *pbs = SysAllocString(pathW);
757 else if (ret == E_INVALIDARG)
759 FIXME("not implemented for %#x\n", V_I4(&This->dir));
760 ret = E_NOTIMPL;
762 HeapFree(GetProcessHeap(), 0, pathW);
764 else /* VT_BSTR */
766 pathW = V_BSTR(&This->dir);
767 len = lstrlenW(pathW);
768 *pbs = SysAllocStringLen(pathW, pathW[len - 1] == '\\' ? len - 1 : len);
770 if (ret == S_OK && !*pbs)
771 ret = E_OUTOFMEMORY;
772 return ret;
775 static HRESULT WINAPI FolderItemImpl_get_GetLink(FolderItem2 *iface,
776 IDispatch **ppid)
778 FIXME("(%p,%p)\n", iface, ppid);
780 *ppid = NULL;
781 return E_NOTIMPL;
784 static HRESULT WINAPI FolderItemImpl_get_GetFolder(FolderItem2 *iface,
785 IDispatch **ppid)
787 FIXME("(%p,%p)\n", iface, ppid);
789 *ppid = NULL;
790 return E_NOTIMPL;
793 static HRESULT WINAPI FolderItemImpl_get_IsLink(FolderItem2 *iface,
794 VARIANT_BOOL *pb)
796 FIXME("(%p,%p)\n", iface, pb);
798 return E_NOTIMPL;
801 static HRESULT WINAPI FolderItemImpl_get_IsFolder(FolderItem2 *iface,
802 VARIANT_BOOL *pb)
804 FIXME("(%p,%p)\n", iface, pb);
806 return E_NOTIMPL;
809 static HRESULT WINAPI FolderItemImpl_get_IsFileSystem(FolderItem2 *iface,
810 VARIANT_BOOL *pb)
812 FIXME("(%p,%p)\n", iface, pb);
814 return E_NOTIMPL;
817 static HRESULT WINAPI FolderItemImpl_get_IsBrowsable(FolderItem2 *iface,
818 VARIANT_BOOL *pb)
820 FIXME("(%p,%p)\n", iface, pb);
822 return E_NOTIMPL;
825 static HRESULT WINAPI FolderItemImpl_get_ModifyDate(FolderItem2 *iface,
826 DATE *pdt)
828 FIXME("(%p,%p)\n", iface, pdt);
830 return E_NOTIMPL;
833 static HRESULT WINAPI FolderItemImpl_put_ModifyDate(FolderItem2 *iface, DATE dt)
835 FIXME("(%p,%f)\n", iface, dt);
837 return E_NOTIMPL;
840 static HRESULT WINAPI FolderItemImpl_get_Size(FolderItem2 *iface, LONG *pul)
842 FIXME("(%p,%p)\n", iface, pul);
844 return E_NOTIMPL;
847 static HRESULT WINAPI FolderItemImpl_get_Type(FolderItem2 *iface, BSTR *pbs)
849 FIXME("(%p,%p)\n", iface, pbs);
851 *pbs = NULL;
852 return E_NOTIMPL;
855 static HRESULT WINAPI FolderItemImpl_Verbs(FolderItem2 *iface, FolderItemVerbs **verbs)
857 HRESULT hr;
858 BSTR path;
860 TRACE("(%p, %p)\n", iface, verbs);
862 if (!verbs)
863 return E_INVALIDARG;
865 *verbs = NULL;
867 hr = FolderItem2_get_Path(iface, &path);
868 if (FAILED(hr))
869 return hr;
871 hr = FolderItemVerbs_Constructor(path, verbs);
872 SysFreeString(path);
873 return hr;
876 static HRESULT WINAPI FolderItemImpl_InvokeVerb(FolderItem2 *iface,
877 VARIANT vVerb)
879 FIXME("(%p)\n", iface);
881 return E_NOTIMPL;
884 static HRESULT WINAPI FolderItemImpl_InvokeVerbEx(FolderItem2 *iface, VARIANT verb, VARIANT args)
886 FIXME("(%p): stub\n", iface);
888 return E_NOTIMPL;
891 static HRESULT WINAPI FolderItemImpl_ExtendedProperty(FolderItem2 *iface, BSTR propname, VARIANT *ret)
893 FIXME("(%p)->(%s %p): stub\n", iface, debugstr_w(propname), ret);
895 return E_NOTIMPL;
898 static const FolderItem2Vtbl FolderItemImpl_Vtbl = {
899 FolderItemImpl_QueryInterface,
900 FolderItemImpl_AddRef,
901 FolderItemImpl_Release,
902 FolderItemImpl_GetTypeInfoCount,
903 FolderItemImpl_GetTypeInfo,
904 FolderItemImpl_GetIDsOfNames,
905 FolderItemImpl_Invoke,
906 FolderItemImpl_get_Application,
907 FolderItemImpl_get_Parent,
908 FolderItemImpl_get_Name,
909 FolderItemImpl_put_Name,
910 FolderItemImpl_get_Path,
911 FolderItemImpl_get_GetLink,
912 FolderItemImpl_get_GetFolder,
913 FolderItemImpl_get_IsLink,
914 FolderItemImpl_get_IsFolder,
915 FolderItemImpl_get_IsFileSystem,
916 FolderItemImpl_get_IsBrowsable,
917 FolderItemImpl_get_ModifyDate,
918 FolderItemImpl_put_ModifyDate,
919 FolderItemImpl_get_Size,
920 FolderItemImpl_get_Type,
921 FolderItemImpl_Verbs,
922 FolderItemImpl_InvokeVerb,
923 FolderItemImpl_InvokeVerbEx,
924 FolderItemImpl_ExtendedProperty
927 static HRESULT FolderItem_Constructor(VARIANT *dir, FolderItem **ppfi)
929 FolderItemImpl *This;
930 HRESULT ret;
932 TRACE("%s\n", debugstr_variant(dir));
934 *ppfi = NULL;
936 This = HeapAlloc(GetProcessHeap(), 0, sizeof(FolderItemImpl));
937 if (!This) return E_OUTOFMEMORY;
938 This->FolderItem2_iface.lpVtbl = &FolderItemImpl_Vtbl;
939 This->ref = 1;
941 VariantInit(&This->dir);
942 ret = VariantCopy(&This->dir, dir);
943 if (FAILED(ret))
945 HeapFree(GetProcessHeap(), 0, This);
946 return E_OUTOFMEMORY;
949 *ppfi = (FolderItem*)&This->FolderItem2_iface;
950 return ret;
953 static HRESULT WINAPI FolderItemsImpl_QueryInterface(FolderItems3 *iface,
954 REFIID riid, LPVOID *ppv)
956 FolderItemsImpl *This = impl_from_FolderItems(iface);
958 TRACE("(%p,%s,%p)\n", iface, shdebugstr_guid(riid), ppv);
960 if (!ppv) return E_INVALIDARG;
962 if (IsEqualIID(&IID_IUnknown, riid) ||
963 IsEqualIID(&IID_IDispatch, riid) ||
964 IsEqualIID(&IID_FolderItems, riid) ||
965 IsEqualIID(&IID_FolderItems2, riid) ||
966 IsEqualIID(&IID_FolderItems3, riid))
967 *ppv = &This->FolderItems3_iface;
968 else
970 FIXME("not implemented for %s\n", shdebugstr_guid(riid));
971 *ppv = NULL;
972 return E_NOINTERFACE;
974 IUnknown_AddRef((IUnknown*)*ppv);
975 return S_OK;
978 static ULONG WINAPI FolderItemsImpl_AddRef(FolderItems3 *iface)
980 FolderItemsImpl *This = impl_from_FolderItems(iface);
981 ULONG ref = InterlockedIncrement(&This->ref);
983 TRACE("(%p), new refcount=%i\n", iface, ref);
985 return ref;
988 static ULONG WINAPI FolderItemsImpl_Release(FolderItems3 *iface)
990 FolderItemsImpl *This = impl_from_FolderItems(iface);
991 ULONG ref = InterlockedDecrement(&This->ref);
993 TRACE("(%p), new refcount=%i\n", iface, ref);
995 if (!ref)
996 HeapFree(GetProcessHeap(), 0, This);
997 return ref;
1000 static HRESULT WINAPI FolderItemsImpl_GetTypeInfoCount(FolderItems3 *iface,
1001 UINT *count)
1003 TRACE("(%p,%p)\n", iface, count);
1005 *count = 1;
1006 return S_OK;
1009 static HRESULT WINAPI FolderItemsImpl_GetTypeInfo(FolderItems3 *iface,
1010 UINT type, LCID lcid, ITypeInfo **ppti)
1012 HRESULT hr;
1014 TRACE("(%p,%u,%d,%p)\n", iface, type, lcid, ppti);
1016 hr = get_typeinfo(FolderItems3_tid, ppti);
1017 if (SUCCEEDED(hr))
1018 ITypeInfo_AddRef(*ppti);
1019 return hr;
1022 static HRESULT WINAPI FolderItemsImpl_GetIDsOfNames(FolderItems3 *iface,
1023 REFIID riid, LPOLESTR *names, UINT count, LCID lcid, DISPID *dispid)
1025 ITypeInfo *ti;
1026 HRESULT hr;
1028 TRACE("(%p,%s,%p,%u,%d,%p)\n", iface, shdebugstr_guid(riid), names, count, lcid, dispid);
1030 hr = get_typeinfo(FolderItems3_tid, &ti);
1031 if (SUCCEEDED(hr))
1032 hr = ITypeInfo_GetIDsOfNames(ti, names, count, dispid);
1033 return hr;
1036 static HRESULT WINAPI FolderItemsImpl_Invoke(FolderItems3 *iface,
1037 DISPID dispid, REFIID riid, LCID lcid, WORD flags, DISPPARAMS *params,
1038 VARIANT *result, EXCEPINFO *ei, UINT *err)
1040 FolderItemsImpl *This = impl_from_FolderItems(iface);
1041 ITypeInfo *ti;
1042 HRESULT hr;
1044 TRACE("(%p,%d,%s,%d,%u,%p,%p,%p,%p)\n", iface, dispid, shdebugstr_guid(riid), lcid, flags, params, result, ei, err);
1046 hr = get_typeinfo(FolderItems3_tid, &ti);
1047 if (SUCCEEDED(hr))
1048 hr = ITypeInfo_Invoke(ti, This, dispid, flags, params, result, ei, err);
1049 return hr;
1052 static HRESULT WINAPI FolderItemsImpl_get_Count(FolderItems3 *iface, LONG *count)
1054 FIXME("(%p,%p)\n", iface, count);
1056 return E_NOTIMPL;
1059 static HRESULT WINAPI FolderItemsImpl_get_Application(FolderItems3 *iface, IDispatch **ppid)
1061 FIXME("(%p,%p)\n", iface, ppid);
1063 if (!ppid)
1064 return E_INVALIDARG;
1066 *ppid = NULL;
1067 return E_NOTIMPL;
1070 static HRESULT WINAPI FolderItemsImpl_get_Parent(FolderItems3 *iface, IDispatch **ppid)
1072 TRACE("(%p,%p)\n", iface, ppid);
1074 if (ppid)
1075 *ppid = NULL;
1077 return E_NOTIMPL;
1080 static HRESULT WINAPI FolderItemsImpl_Item(FolderItems3 *iface, VARIANT index, FolderItem **ppid)
1082 FIXME("(%p,%s,%p)\n", iface, debugstr_variant(&index), ppid);
1084 *ppid = NULL;
1085 return E_NOTIMPL;
1088 static HRESULT WINAPI FolderItemsImpl__NewEnum(FolderItems3 *iface, IUnknown **ppunk)
1090 FIXME("(%p,%p)\n", iface, ppunk);
1092 if (!ppunk)
1093 return E_INVALIDARG;
1095 *ppunk = NULL;
1096 return E_NOTIMPL;
1099 static HRESULT WINAPI FolderItemsImpl_InvokeVerbEx(FolderItems3 *iface, VARIANT verb, VARIANT args)
1101 FIXME("(%p,%s,%s)\n", iface, debugstr_variant(&verb), debugstr_variant(&args));
1103 return E_NOTIMPL;
1106 static HRESULT WINAPI FolderItemsImpl_Filter(FolderItems3 *iface, LONG flags, BSTR spec)
1108 FIXME("(%p,%d,%s)\n", iface, flags, wine_dbgstr_w(spec));
1110 return E_NOTIMPL;
1113 static HRESULT WINAPI FolderItemsImpl_get_Verbs(FolderItems3 *iface, FolderItemVerbs **ppfic)
1115 FIXME("(%p,%p)\n", iface, ppfic);
1117 if (!ppfic)
1118 return E_INVALIDARG;
1120 *ppfic = NULL;
1121 return E_NOTIMPL;
1124 static const FolderItems3Vtbl FolderItemsImpl_Vtbl = {
1125 FolderItemsImpl_QueryInterface,
1126 FolderItemsImpl_AddRef,
1127 FolderItemsImpl_Release,
1128 FolderItemsImpl_GetTypeInfoCount,
1129 FolderItemsImpl_GetTypeInfo,
1130 FolderItemsImpl_GetIDsOfNames,
1131 FolderItemsImpl_Invoke,
1132 FolderItemsImpl_get_Count,
1133 FolderItemsImpl_get_Application,
1134 FolderItemsImpl_get_Parent,
1135 FolderItemsImpl_Item,
1136 FolderItemsImpl__NewEnum,
1137 FolderItemsImpl_InvokeVerbEx,
1138 FolderItemsImpl_Filter,
1139 FolderItemsImpl_get_Verbs
1142 static HRESULT FolderItems_Constructor(FolderItems **ppfi)
1144 FolderItemsImpl *This;
1146 TRACE("\n");
1148 *ppfi = NULL;
1150 This = HeapAlloc(GetProcessHeap(), 0, sizeof(FolderItemsImpl));
1151 if (!This) return E_OUTOFMEMORY;
1152 This->FolderItems3_iface.lpVtbl = &FolderItemsImpl_Vtbl;
1153 This->ref = 1;
1155 *ppfi = (FolderItems*)&This->FolderItems3_iface;
1156 return S_OK;
1159 static HRESULT WINAPI FolderImpl_QueryInterface(Folder3 *iface, REFIID riid,
1160 LPVOID *ppv)
1162 FolderImpl *This = impl_from_Folder(iface);
1164 TRACE("(%p,%s,%p)\n", iface, shdebugstr_guid(riid), ppv);
1166 if (!ppv) return E_INVALIDARG;
1168 if (IsEqualIID(&IID_IUnknown, riid) ||
1169 IsEqualIID(&IID_IDispatch, riid) ||
1170 IsEqualIID(&IID_Folder, riid) ||
1171 IsEqualIID(&IID_Folder2, riid) ||
1172 IsEqualIID(&IID_Folder3, riid))
1173 *ppv = &This->Folder3_iface;
1174 else
1176 FIXME("not implemented for %s\n", shdebugstr_guid(riid));
1177 *ppv = NULL;
1178 return E_NOINTERFACE;
1180 IUnknown_AddRef((IUnknown*)*ppv);
1181 return S_OK;
1184 static ULONG WINAPI FolderImpl_AddRef(Folder3 *iface)
1186 FolderImpl *This = impl_from_Folder(iface);
1187 ULONG ref = InterlockedIncrement(&This->ref);
1189 TRACE("(%p), new refcount=%i\n", iface, ref);
1191 return ref;
1194 static ULONG WINAPI FolderImpl_Release(Folder3 *iface)
1196 FolderImpl *This = impl_from_Folder(iface);
1197 ULONG ref = InterlockedDecrement(&This->ref);
1199 TRACE("(%p), new refcount=%i\n", iface, ref);
1201 if (!ref)
1203 VariantClear(&This->dir);
1204 HeapFree(GetProcessHeap(), 0, This);
1206 return ref;
1209 static HRESULT WINAPI FolderImpl_GetTypeInfoCount(Folder3 *iface, UINT *pctinfo)
1211 TRACE("(%p,%p)\n", iface, pctinfo);
1213 *pctinfo = 1;
1214 return S_OK;
1217 static HRESULT WINAPI FolderImpl_GetTypeInfo(Folder3 *iface, UINT iTInfo,
1218 LCID lcid, ITypeInfo **ppTInfo)
1220 HRESULT hr;
1222 TRACE("(%p,%u,%d,%p)\n", iface, iTInfo, lcid, ppTInfo);
1224 hr = get_typeinfo(Folder3_tid, ppTInfo);
1225 if (SUCCEEDED(hr))
1226 ITypeInfo_AddRef(*ppTInfo);
1228 return hr;
1231 static HRESULT WINAPI FolderImpl_GetIDsOfNames(Folder3 *iface, REFIID riid,
1232 LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
1234 ITypeInfo *ti;
1235 HRESULT hr;
1237 TRACE("(%p,%s,%p,%u,%d,%p)\n", iface, shdebugstr_guid(riid), rgszNames, cNames, lcid,
1238 rgDispId);
1240 hr = get_typeinfo(Folder3_tid, &ti);
1241 if (SUCCEEDED(hr))
1242 hr = ITypeInfo_GetIDsOfNames(ti, rgszNames, cNames, rgDispId);
1243 return hr;
1246 static HRESULT WINAPI FolderImpl_Invoke(Folder3 *iface, DISPID dispIdMember,
1247 REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
1248 VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
1250 FolderImpl *This = impl_from_Folder(iface);
1251 ITypeInfo *ti;
1252 HRESULT hr;
1254 TRACE("(%p,%d,%s,%d,%u,%p,%p,%p,%p)\n", iface, dispIdMember, shdebugstr_guid(riid), lcid,
1255 wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
1257 hr = get_typeinfo(Folder3_tid, &ti);
1258 if (SUCCEEDED(hr))
1259 hr = ITypeInfo_Invoke(ti, This, dispIdMember, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
1260 return hr;
1263 static HRESULT WINAPI FolderImpl_get_Title(Folder3 *iface, BSTR *pbs)
1265 FolderImpl *This = impl_from_Folder(iface);
1266 WCHAR *p;
1267 int len;
1269 TRACE("(%p,%p)\n", iface, pbs);
1271 *pbs = NULL;
1273 if (V_VT(&This->dir) == VT_I4)
1275 FIXME("special folder constants are not supported\n");
1276 return E_NOTIMPL;
1278 p = PathFindFileNameW(V_BSTR(&This->dir));
1279 len = lstrlenW(p);
1280 *pbs = SysAllocStringLen(p, p[len - 1] == '\\' ? len - 1 : len);
1281 return *pbs ? S_OK : E_OUTOFMEMORY;
1284 static HRESULT WINAPI FolderImpl_get_Application(Folder3 *iface,
1285 IDispatch **ppid)
1287 FIXME("(%p,%p)\n", iface, ppid);
1289 *ppid = NULL;
1290 return E_NOTIMPL;
1293 static HRESULT WINAPI FolderImpl_get_Parent(Folder3 *iface, IDispatch **ppid)
1295 FIXME("(%p,%p)\n", iface, ppid);
1297 *ppid = NULL;
1298 return E_NOTIMPL;
1301 static HRESULT WINAPI FolderImpl_get_ParentFolder(Folder3 *iface, Folder **ppsf)
1303 FIXME("(%p,%p)\n", iface, ppsf);
1305 *ppsf = NULL;
1306 return E_NOTIMPL;
1309 static HRESULT WINAPI FolderImpl_Items(Folder3 *iface, FolderItems **ppid)
1311 FIXME("(%p,%p)\n", iface, ppid);
1313 return FolderItems_Constructor(ppid);
1316 static HRESULT WINAPI FolderImpl_ParseName(Folder3 *iface, BSTR name, FolderItem **item)
1318 FolderItem *self;
1319 BSTR str;
1320 WCHAR pathW[MAX_PATH];
1321 VARIANT v;
1322 HRESULT hr;
1324 TRACE("(%p,%s,%p)\n", iface, debugstr_w(name), item);
1326 *item = NULL;
1328 if (!name || !name[0])
1329 return S_FALSE;
1331 hr = Folder3_get_Self(iface, &self);
1332 if (FAILED(hr))
1333 return hr;
1335 hr = FolderItem_get_Path(self, &str);
1336 FolderItem_Release(self);
1338 PathCombineW(pathW, str, name);
1339 SysFreeString(str);
1341 if (!PathFileExistsW(pathW))
1342 return S_FALSE;
1344 V_VT(&v) = VT_BSTR;
1345 V_BSTR(&v) = SysAllocString(pathW);
1346 hr = FolderItem_Constructor(&v, item);
1347 VariantClear(&v);
1348 return hr;
1351 static HRESULT WINAPI FolderImpl_NewFolder(Folder3 *iface, BSTR bName,
1352 VARIANT vOptions)
1354 FIXME("(%p,%s)\n", iface, debugstr_w(bName));
1356 return E_NOTIMPL;
1359 static HRESULT WINAPI FolderImpl_MoveHere(Folder3 *iface, VARIANT vItem,
1360 VARIANT vOptions)
1362 FIXME("(%p)\n", iface);
1364 return E_NOTIMPL;
1367 static HRESULT WINAPI FolderImpl_CopyHere(Folder3 *iface, VARIANT vItem,
1368 VARIANT vOptions)
1370 FIXME("(%p)\n", iface);
1372 return E_NOTIMPL;
1375 static HRESULT WINAPI FolderImpl_GetDetailsOf(Folder3 *iface, VARIANT vItem,
1376 int iColumn, BSTR *pbs)
1378 FIXME("(%p,%d,%p)\n", iface, iColumn, pbs);
1380 *pbs = NULL;
1381 return E_NOTIMPL;
1384 static HRESULT WINAPI FolderImpl_get_Self(Folder3 *iface, FolderItem **ppfi)
1386 FolderImpl *This = impl_from_Folder(iface);
1388 TRACE("(%p,%p)\n", iface, ppfi);
1390 return FolderItem_Constructor(&This->dir, ppfi);
1393 static HRESULT WINAPI FolderImpl_get_OfflineStatus(Folder3 *iface, LONG *pul)
1395 FIXME("(%p,%p)\n", iface, pul);
1397 return E_NOTIMPL;
1400 static HRESULT WINAPI FolderImpl_Synchronize(Folder3 *iface)
1402 FIXME("(%p)\n", iface);
1404 return E_NOTIMPL;
1407 static HRESULT WINAPI FolderImpl_get_HaveToShowWebViewBarricade(Folder3 *iface,
1408 VARIANT_BOOL *pbHaveToShowWebViewBarricade)
1410 FIXME("(%p,%p)\n", iface, pbHaveToShowWebViewBarricade);
1412 return E_NOTIMPL;
1415 static HRESULT WINAPI FolderImpl_DismissedWebViewBarricade(Folder3 *iface)
1417 FIXME("(%p)\n", iface);
1419 return E_NOTIMPL;
1422 static HRESULT WINAPI FolderImpl_get_ShowWebViewBarricade(Folder3 *iface,
1423 VARIANT_BOOL *pbShowWebViewBarricade)
1425 FIXME("(%p,%p)\n", iface, pbShowWebViewBarricade);
1427 return E_NOTIMPL;
1430 static HRESULT WINAPI FolderImpl_put_ShowWebViewBarricade(Folder3 *iface,
1431 VARIANT_BOOL bShowWebViewBarricade)
1433 FIXME("(%p,%d)\n", iface, bShowWebViewBarricade);
1435 return E_NOTIMPL;
1438 static const Folder3Vtbl FolderImpl_Vtbl = {
1439 FolderImpl_QueryInterface,
1440 FolderImpl_AddRef,
1441 FolderImpl_Release,
1442 FolderImpl_GetTypeInfoCount,
1443 FolderImpl_GetTypeInfo,
1444 FolderImpl_GetIDsOfNames,
1445 FolderImpl_Invoke,
1446 FolderImpl_get_Title,
1447 FolderImpl_get_Application,
1448 FolderImpl_get_Parent,
1449 FolderImpl_get_ParentFolder,
1450 FolderImpl_Items,
1451 FolderImpl_ParseName,
1452 FolderImpl_NewFolder,
1453 FolderImpl_MoveHere,
1454 FolderImpl_CopyHere,
1455 FolderImpl_GetDetailsOf,
1456 FolderImpl_get_Self,
1457 FolderImpl_get_OfflineStatus,
1458 FolderImpl_Synchronize,
1459 FolderImpl_get_HaveToShowWebViewBarricade,
1460 FolderImpl_DismissedWebViewBarricade,
1461 FolderImpl_get_ShowWebViewBarricade,
1462 FolderImpl_put_ShowWebViewBarricade
1465 static HRESULT Folder_Constructor(VARIANT *dir, Folder **ppsdf)
1467 FolderImpl *This;
1468 HRESULT ret;
1470 *ppsdf = NULL;
1472 switch (V_VT(dir))
1474 case VT_I4:
1475 /* FIXME: add some checks */
1476 break;
1477 case VT_BSTR:
1478 if (PathIsDirectoryW(V_BSTR(dir)) &&
1479 !PathIsRelativeW(V_BSTR(dir)) &&
1480 PathFileExistsW(V_BSTR(dir)))
1481 break;
1482 default:
1483 return S_FALSE;
1486 This = HeapAlloc(GetProcessHeap(), 0, sizeof(FolderImpl));
1487 if (!This) return E_OUTOFMEMORY;
1488 This->Folder3_iface.lpVtbl = &FolderImpl_Vtbl;
1489 This->ref = 1;
1491 VariantInit(&This->dir);
1492 ret = VariantCopy(&This->dir, dir);
1493 if (FAILED(ret))
1495 HeapFree(GetProcessHeap(), 0, This);
1496 return E_OUTOFMEMORY;
1499 *ppsdf = (Folder*)&This->Folder3_iface;
1500 return ret;
1503 static HRESULT WINAPI ShellDispatch_QueryInterface(IShellDispatch6 *iface,
1504 REFIID riid, LPVOID *ppv)
1506 ShellDispatch *This = impl_from_IShellDispatch6(iface);
1508 TRACE("(%p,%s,%p)\n", iface, shdebugstr_guid(riid), ppv);
1510 if (!ppv) return E_INVALIDARG;
1512 if (IsEqualIID(&IID_IUnknown, riid) ||
1513 IsEqualIID(&IID_IDispatch, riid) ||
1514 IsEqualIID(&IID_IShellDispatch, riid) ||
1515 IsEqualIID(&IID_IShellDispatch2, riid) ||
1516 IsEqualIID(&IID_IShellDispatch3, riid) ||
1517 IsEqualIID(&IID_IShellDispatch4, riid) ||
1518 IsEqualIID(&IID_IShellDispatch5, riid) ||
1519 IsEqualIID(&IID_IShellDispatch6, riid))
1520 *ppv = &This->IShellDispatch6_iface;
1521 else
1523 FIXME("not implemented for %s\n", shdebugstr_guid(riid));
1524 *ppv = NULL;
1525 return E_NOINTERFACE;
1528 IShellDispatch6_AddRef(iface);
1529 return S_OK;
1532 static ULONG WINAPI ShellDispatch_AddRef(IShellDispatch6 *iface)
1534 ShellDispatch *This = impl_from_IShellDispatch6(iface);
1535 ULONG ref = InterlockedIncrement(&This->ref);
1537 TRACE("(%p), new refcount=%i\n", iface, ref);
1539 return ref;
1542 static ULONG WINAPI ShellDispatch_Release(IShellDispatch6 *iface)
1544 ShellDispatch *This = impl_from_IShellDispatch6(iface);
1545 ULONG ref = InterlockedDecrement(&This->ref);
1547 TRACE("(%p), new refcount=%i\n", iface, ref);
1549 if (!ref)
1550 HeapFree(GetProcessHeap(), 0, This);
1552 return ref;
1555 static HRESULT WINAPI ShellDispatch_GetTypeInfoCount(IShellDispatch6 *iface,
1556 UINT *pctinfo)
1558 TRACE("(%p,%p)\n", iface, pctinfo);
1560 *pctinfo = 1;
1561 return S_OK;
1564 static HRESULT WINAPI ShellDispatch_GetTypeInfo(IShellDispatch6 *iface,
1565 UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo)
1567 HRESULT hr;
1569 TRACE("(%p,%u,%d,%p)\n", iface, iTInfo, lcid, ppTInfo);
1571 hr = get_typeinfo(IShellDispatch6_tid, ppTInfo);
1572 if (SUCCEEDED(hr))
1573 ITypeInfo_AddRef(*ppTInfo);
1574 return hr;
1577 static HRESULT WINAPI ShellDispatch_GetIDsOfNames(IShellDispatch6 *iface,
1578 REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
1580 ITypeInfo *ti;
1581 HRESULT hr;
1583 TRACE("(%p,%s,%p,%u,%d,%p)\n", iface, shdebugstr_guid(riid), rgszNames, cNames, lcid,
1584 rgDispId);
1586 hr = get_typeinfo(IShellDispatch6_tid, &ti);
1587 if (SUCCEEDED(hr))
1588 hr = ITypeInfo_GetIDsOfNames(ti, rgszNames, cNames, rgDispId);
1589 return hr;
1592 static HRESULT WINAPI ShellDispatch_Invoke(IShellDispatch6 *iface,
1593 DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags,
1594 DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo,
1595 UINT *puArgErr)
1597 ShellDispatch *This = impl_from_IShellDispatch6(iface);
1598 ITypeInfo *ti;
1599 HRESULT hr;
1601 TRACE("(%p,%d,%s,%d,%u,%p,%p,%p,%p)\n", iface, dispIdMember, shdebugstr_guid(riid), lcid,
1602 wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
1604 hr = get_typeinfo(IShellDispatch6_tid, &ti);
1605 if (SUCCEEDED(hr))
1606 hr = ITypeInfo_Invoke(ti, &This->IShellDispatch6_iface, dispIdMember, wFlags, pDispParams,
1607 pVarResult, pExcepInfo, puArgErr);
1608 return hr;
1611 static HRESULT WINAPI ShellDispatch_get_Application(IShellDispatch6 *iface,
1612 IDispatch **ppid)
1614 FIXME("(%p,%p)\n", iface, ppid);
1616 *ppid = NULL;
1617 return E_NOTIMPL;
1620 static HRESULT WINAPI ShellDispatch_get_Parent(IShellDispatch6 *iface,
1621 IDispatch **ppid)
1623 FIXME("(%p,%p)\n", iface, ppid);
1625 *ppid = NULL;
1626 return E_NOTIMPL;
1629 static HRESULT WINAPI ShellDispatch_NameSpace(IShellDispatch6 *iface,
1630 VARIANT vDir, Folder **ppsdf)
1632 TRACE("(%p,%p)\n", iface, ppsdf);
1634 return Folder_Constructor(&vDir, ppsdf);
1637 static HRESULT WINAPI ShellDispatch_BrowseForFolder(IShellDispatch6 *iface,
1638 LONG Hwnd, BSTR Title, LONG Options, VARIANT RootFolder, Folder **ppsdf)
1640 FIXME("(%p,%x,%s,%x,%p)\n", iface, Hwnd, debugstr_w(Title), Options, ppsdf);
1642 *ppsdf = NULL;
1643 return E_NOTIMPL;
1646 static HRESULT WINAPI ShellDispatch_Windows(IShellDispatch6 *iface,
1647 IDispatch **ppid)
1649 FIXME("(%p,%p)\n", iface, ppid);
1651 *ppid = NULL;
1652 return E_NOTIMPL;
1655 static HRESULT WINAPI ShellDispatch_Open(IShellDispatch6 *iface, VARIANT vDir)
1657 FIXME("(%p)\n", iface);
1659 return E_NOTIMPL;
1662 static HRESULT WINAPI ShellDispatch_Explore(IShellDispatch6 *iface, VARIANT vDir)
1664 FIXME("(%p)\n", iface);
1666 return E_NOTIMPL;
1669 static HRESULT WINAPI ShellDispatch_MinimizeAll(IShellDispatch6 *iface)
1671 FIXME("(%p)\n", iface);
1673 return E_NOTIMPL;
1676 static HRESULT WINAPI ShellDispatch_UndoMinimizeALL(IShellDispatch6 *iface)
1678 FIXME("(%p)\n", iface);
1680 return E_NOTIMPL;
1683 static HRESULT WINAPI ShellDispatch_FileRun(IShellDispatch6 *iface)
1685 FIXME("(%p)\n", iface);
1687 return E_NOTIMPL;
1690 static HRESULT WINAPI ShellDispatch_CascadeWindows(IShellDispatch6 *iface)
1692 FIXME("(%p)\n", iface);
1694 return E_NOTIMPL;
1697 static HRESULT WINAPI ShellDispatch_TileVertically(IShellDispatch6 *iface)
1699 FIXME("(%p)\n", iface);
1701 return E_NOTIMPL;
1704 static HRESULT WINAPI ShellDispatch_TileHorizontally(IShellDispatch6 *iface)
1706 FIXME("(%p)\n", iface);
1708 return E_NOTIMPL;
1711 static HRESULT WINAPI ShellDispatch_ShutdownWindows(IShellDispatch6 *iface)
1713 FIXME("(%p)\n", iface);
1715 return E_NOTIMPL;
1718 static HRESULT WINAPI ShellDispatch_Suspend(IShellDispatch6 *iface)
1720 FIXME("(%p)\n", iface);
1722 return E_NOTIMPL;
1725 static HRESULT WINAPI ShellDispatch_EjectPC(IShellDispatch6 *iface)
1727 FIXME("(%p)\n", iface);
1729 return E_NOTIMPL;
1732 static HRESULT WINAPI ShellDispatch_SetTime(IShellDispatch6 *iface)
1734 FIXME("(%p)\n", iface);
1736 return E_NOTIMPL;
1739 static HRESULT WINAPI ShellDispatch_TrayProperties(IShellDispatch6 *iface)
1741 FIXME("(%p)\n", iface);
1743 return E_NOTIMPL;
1746 static HRESULT WINAPI ShellDispatch_Help(IShellDispatch6 *iface)
1748 FIXME("(%p)\n", iface);
1750 return E_NOTIMPL;
1753 static HRESULT WINAPI ShellDispatch_FindFiles(IShellDispatch6 *iface)
1755 FIXME("(%p)\n", iface);
1757 return E_NOTIMPL;
1760 static HRESULT WINAPI ShellDispatch_FindComputer(IShellDispatch6 *iface)
1762 FIXME("(%p)\n", iface);
1764 return E_NOTIMPL;
1767 static HRESULT WINAPI ShellDispatch_RefreshMenu(IShellDispatch6 *iface)
1769 FIXME("(%p)\n", iface);
1771 return E_NOTIMPL;
1774 static HRESULT WINAPI ShellDispatch_ControlPanelItem(IShellDispatch6 *iface,
1775 BSTR szDir)
1777 FIXME("(%p,%s)\n", iface, debugstr_w(szDir));
1779 return E_NOTIMPL;
1782 static HRESULT WINAPI ShellDispatch_IsRestricted(IShellDispatch6 *iface, BSTR group, BSTR restriction, LONG *value)
1784 FIXME("(%s, %s, %p): stub\n", debugstr_w(group), debugstr_w(restriction), value);
1785 return E_NOTIMPL;
1788 static HRESULT WINAPI ShellDispatch_ShellExecute(IShellDispatch6 *iface,
1789 BSTR file, VARIANT v_args, VARIANT v_dir, VARIANT v_op, VARIANT v_show)
1791 VARIANT args_str, dir_str, op_str, show_int;
1792 WCHAR *args = NULL, *dir = NULL, *op = NULL;
1793 INT show = 0;
1794 HINSTANCE ret;
1796 TRACE("(%s, %s, %s, %s, %s)\n", debugstr_w(file), debugstr_variant(&v_args),
1797 debugstr_variant(&v_dir), debugstr_variant(&v_op), debugstr_variant(&v_show));
1799 VariantInit(&args_str);
1800 VariantChangeType(&args_str, &v_args, 0, VT_BSTR);
1801 if (V_VT(&args_str) == VT_BSTR)
1802 args = V_BSTR(&args_str);
1804 VariantInit(&dir_str);
1805 VariantChangeType(&dir_str, &v_dir, 0, VT_BSTR);
1806 if (V_VT(&dir_str) == VT_BSTR)
1807 dir = V_BSTR(&dir_str);
1809 VariantInit(&op_str);
1810 VariantChangeType(&op_str, &v_op, 0, VT_BSTR);
1811 if (V_VT(&op_str) == VT_BSTR)
1812 op = V_BSTR(&op_str);
1814 VariantInit(&show_int);
1815 VariantChangeType(&show_int, &v_show, 0, VT_I4);
1816 if (V_VT(&show_int) == VT_I4)
1817 show = V_I4(&show_int);
1819 ret = ShellExecuteW(NULL, op, file, args, dir, show);
1821 VariantClear(&args_str);
1822 VariantClear(&dir_str);
1823 VariantClear(&op_str);
1824 VariantClear(&show_int);
1826 return (ULONG_PTR)ret > 32 ? S_OK : S_FALSE;
1829 static HRESULT WINAPI ShellDispatch_FindPrinter(IShellDispatch6 *iface, BSTR name, BSTR location, BSTR model)
1831 FIXME("(%s, %s, %s): stub\n", debugstr_w(name), debugstr_w(location), debugstr_w(model));
1832 return E_NOTIMPL;
1835 static HRESULT WINAPI ShellDispatch_GetSystemInformation(IShellDispatch6 *iface, BSTR name, VARIANT *ret)
1837 FIXME("(%s, %p): stub\n", debugstr_w(name), ret);
1838 return E_NOTIMPL;
1841 static HRESULT WINAPI ShellDispatch_ServiceStart(IShellDispatch6 *iface, BSTR service, VARIANT persistent, VARIANT *ret)
1843 FIXME("(%s, %p): stub\n", debugstr_w(service), ret);
1844 return E_NOTIMPL;
1847 static HRESULT WINAPI ShellDispatch_ServiceStop(IShellDispatch6 *iface, BSTR service, VARIANT persistent, VARIANT *ret)
1849 FIXME("(%s, %p): stub\n", debugstr_w(service), ret);
1850 return E_NOTIMPL;
1853 static HRESULT WINAPI ShellDispatch_IsServiceRunning(IShellDispatch6 *iface, BSTR name, VARIANT *running)
1855 SERVICE_STATUS_PROCESS status;
1856 SC_HANDLE scm, service;
1857 DWORD dummy;
1859 TRACE("(%s, %p)\n", debugstr_w(name), running);
1861 V_VT(running) = VT_BOOL;
1862 V_BOOL(running) = VARIANT_FALSE;
1864 scm = OpenSCManagerW(NULL, NULL, SC_MANAGER_CONNECT);
1865 if (!scm)
1867 ERR("failed to connect to service manager\n");
1868 return S_OK;
1871 service = OpenServiceW(scm, name, SERVICE_QUERY_STATUS);
1872 if (!service)
1874 ERR("Failed to open service %s (%u)\n", debugstr_w(name), GetLastError());
1875 CloseServiceHandle(scm);
1876 return S_OK;
1879 if (!QueryServiceStatusEx(service, SC_STATUS_PROCESS_INFO, (BYTE *)&status,
1880 sizeof(SERVICE_STATUS_PROCESS), &dummy))
1882 TRACE("failed to query service status (%u)\n", GetLastError());
1883 CloseServiceHandle(service);
1884 CloseServiceHandle(scm);
1885 return S_OK;
1888 if (status.dwCurrentState == SERVICE_RUNNING)
1889 V_BOOL(running) = VARIANT_TRUE;
1891 CloseServiceHandle(service);
1892 CloseServiceHandle(scm);
1894 return S_OK;
1897 static HRESULT WINAPI ShellDispatch_CanStartStopService(IShellDispatch6 *iface, BSTR service, VARIANT *ret)
1899 FIXME("(%s, %p): stub\n", debugstr_w(service), ret);
1900 return E_NOTIMPL;
1903 static HRESULT WINAPI ShellDispatch_ShowBrowserBar(IShellDispatch6 *iface, BSTR clsid, VARIANT show, VARIANT *ret)
1905 FIXME("(%s, %p): stub\n", debugstr_w(clsid), ret);
1906 return E_NOTIMPL;
1909 static HRESULT WINAPI ShellDispatch_AddToRecent(IShellDispatch6 *iface, VARIANT file, BSTR category)
1911 FIXME("(%s): stub\n", debugstr_w(category));
1912 return E_NOTIMPL;
1915 static HRESULT WINAPI ShellDispatch_WindowsSecurity(IShellDispatch6 *iface)
1917 FIXME("stub\n");
1918 return E_NOTIMPL;
1921 static HRESULT WINAPI ShellDispatch_ToggleDesktop(IShellDispatch6 *iface)
1923 FIXME("stub\n");
1924 return E_NOTIMPL;
1927 static HRESULT WINAPI ShellDispatch_ExplorerPolicy(IShellDispatch6 *iface, BSTR policy, VARIANT *value)
1929 FIXME("(%s, %p): stub\n", debugstr_w(policy), value);
1930 return E_NOTIMPL;
1933 static HRESULT WINAPI ShellDispatch_GetSetting(IShellDispatch6 *iface, LONG setting, VARIANT_BOOL *result)
1935 FIXME("(%d %p): stub\n", setting, result);
1936 return E_NOTIMPL;
1939 static HRESULT WINAPI ShellDispatch_WindowSwitcher(IShellDispatch6 *iface)
1941 FIXME("stub\n");
1942 return E_NOTIMPL;
1945 static HRESULT WINAPI ShellDispatch_SearchCommand(IShellDispatch6 *iface)
1947 FIXME("stub\n");
1948 return E_NOTIMPL;
1951 static const IShellDispatch6Vtbl ShellDispatchVtbl = {
1952 ShellDispatch_QueryInterface,
1953 ShellDispatch_AddRef,
1954 ShellDispatch_Release,
1955 ShellDispatch_GetTypeInfoCount,
1956 ShellDispatch_GetTypeInfo,
1957 ShellDispatch_GetIDsOfNames,
1958 ShellDispatch_Invoke,
1959 ShellDispatch_get_Application,
1960 ShellDispatch_get_Parent,
1961 ShellDispatch_NameSpace,
1962 ShellDispatch_BrowseForFolder,
1963 ShellDispatch_Windows,
1964 ShellDispatch_Open,
1965 ShellDispatch_Explore,
1966 ShellDispatch_MinimizeAll,
1967 ShellDispatch_UndoMinimizeALL,
1968 ShellDispatch_FileRun,
1969 ShellDispatch_CascadeWindows,
1970 ShellDispatch_TileVertically,
1971 ShellDispatch_TileHorizontally,
1972 ShellDispatch_ShutdownWindows,
1973 ShellDispatch_Suspend,
1974 ShellDispatch_EjectPC,
1975 ShellDispatch_SetTime,
1976 ShellDispatch_TrayProperties,
1977 ShellDispatch_Help,
1978 ShellDispatch_FindFiles,
1979 ShellDispatch_FindComputer,
1980 ShellDispatch_RefreshMenu,
1981 ShellDispatch_ControlPanelItem,
1982 ShellDispatch_IsRestricted,
1983 ShellDispatch_ShellExecute,
1984 ShellDispatch_FindPrinter,
1985 ShellDispatch_GetSystemInformation,
1986 ShellDispatch_ServiceStart,
1987 ShellDispatch_ServiceStop,
1988 ShellDispatch_IsServiceRunning,
1989 ShellDispatch_CanStartStopService,
1990 ShellDispatch_ShowBrowserBar,
1991 ShellDispatch_AddToRecent,
1992 ShellDispatch_WindowsSecurity,
1993 ShellDispatch_ToggleDesktop,
1994 ShellDispatch_ExplorerPolicy,
1995 ShellDispatch_GetSetting,
1996 ShellDispatch_WindowSwitcher,
1997 ShellDispatch_SearchCommand
2000 HRESULT WINAPI IShellDispatch_Constructor(IUnknown *outer, REFIID riid, void **ppv)
2002 ShellDispatch *This;
2003 HRESULT ret;
2005 TRACE("(%p, %s)\n", outer, debugstr_guid(riid));
2007 *ppv = NULL;
2009 if (outer) return CLASS_E_NOAGGREGATION;
2011 This = HeapAlloc(GetProcessHeap(), 0, sizeof(ShellDispatch));
2012 if (!This) return E_OUTOFMEMORY;
2013 This->IShellDispatch6_iface.lpVtbl = &ShellDispatchVtbl;
2014 This->ref = 1;
2016 ret = IShellDispatch6_QueryInterface(&This->IShellDispatch6_iface, riid, ppv);
2017 IShellDispatch6_Release(&This->IShellDispatch6_iface);
2018 return ret;