shell32: Implement FolderItems_get_Count.
[wine.git] / dlls / shell32 / shelldispatch.c
blobec52c6d613d3b8fd4dbf0d140e8bb1701febc50e
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 VARIANT dir;
72 WCHAR **item_filenames;
73 LONG item_count;
74 } FolderItemsImpl;
76 typedef struct {
77 FolderItem2 FolderItem2_iface;
78 LONG ref;
79 VARIANT dir;
80 } FolderItemImpl;
82 typedef struct {
83 FolderItemVerbs FolderItemVerbs_iface;
84 LONG ref;
86 IContextMenu *contextmenu;
87 HMENU hMenu;
88 LONG count;
89 } FolderItemVerbsImpl;
91 typedef struct {
92 FolderItemVerb FolderItemVerb_iface;
93 LONG ref;
95 IContextMenu *contextmenu;
96 BSTR name;
97 } FolderItemVerbImpl;
99 static inline ShellDispatch *impl_from_IShellDispatch6(IShellDispatch6 *iface)
101 return CONTAINING_RECORD(iface, ShellDispatch, IShellDispatch6_iface);
104 static inline FolderImpl *impl_from_Folder(Folder3 *iface)
106 return CONTAINING_RECORD(iface, FolderImpl, Folder3_iface);
109 static inline FolderItemsImpl *impl_from_FolderItems(FolderItems3 *iface)
111 return CONTAINING_RECORD(iface, FolderItemsImpl, FolderItems3_iface);
114 static inline FolderItemImpl *impl_from_FolderItem(FolderItem2 *iface)
116 return CONTAINING_RECORD(iface, FolderItemImpl, FolderItem2_iface);
119 static inline FolderItemVerbsImpl *impl_from_FolderItemVerbs(FolderItemVerbs *iface)
121 return CONTAINING_RECORD(iface, FolderItemVerbsImpl, FolderItemVerbs_iface);
124 static inline FolderItemVerbImpl *impl_from_FolderItemVerb(FolderItemVerb *iface)
126 return CONTAINING_RECORD(iface, FolderItemVerbImpl, FolderItemVerb_iface);
129 static HRESULT load_typelib(void)
131 ITypeLib *tl;
132 HRESULT hr;
134 hr = LoadRegTypeLib(&LIBID_Shell32, 1, 0, LOCALE_SYSTEM_DEFAULT, &tl);
135 if (FAILED(hr)) {
136 ERR("LoadRegTypeLib failed: %08x\n", hr);
137 return hr;
140 if (InterlockedCompareExchangePointer((void**)&typelib, tl, NULL))
141 ITypeLib_Release(tl);
142 return hr;
145 void release_typelib(void)
147 unsigned i;
149 if (!typelib)
150 return;
152 for (i = 0; i < sizeof(typeinfos)/sizeof(*typeinfos); i++)
153 if (typeinfos[i])
154 ITypeInfo_Release(typeinfos[i]);
156 ITypeLib_Release(typelib);
159 HRESULT get_typeinfo(enum tid_t tid, ITypeInfo **typeinfo)
161 HRESULT hr;
163 if (!typelib)
164 hr = load_typelib();
165 if (!typelib)
166 return hr;
168 if (!typeinfos[tid])
170 ITypeInfo *ti;
172 hr = ITypeLib_GetTypeInfoOfGuid(typelib, tid_ids[tid], &ti);
173 if (FAILED(hr))
175 ERR("GetTypeInfoOfGuid(%s) failed: %08x\n", debugstr_guid(tid_ids[tid]), hr);
176 return hr;
179 if (InterlockedCompareExchangePointer((void**)(typeinfos+tid), ti, NULL))
180 ITypeInfo_Release(ti);
183 *typeinfo = typeinfos[tid];
184 return S_OK;
187 /* FolderItemVerb */
188 static HRESULT WINAPI FolderItemVerbImpl_QueryInterface(FolderItemVerb *iface,
189 REFIID riid, void **ppv)
191 FolderItemVerbImpl *This = impl_from_FolderItemVerb(iface);
193 TRACE("(%p,%s,%p)\n", iface, shdebugstr_guid(riid), ppv);
195 *ppv = NULL;
197 if (IsEqualIID(&IID_IUnknown, riid) ||
198 IsEqualIID(&IID_IDispatch, riid) ||
199 IsEqualIID(&IID_FolderItemVerb, riid))
200 *ppv = &This->FolderItemVerb_iface;
201 else
203 FIXME("not implemented for %s\n", shdebugstr_guid(riid));
204 *ppv = NULL;
205 return E_NOINTERFACE;
208 IUnknown_AddRef((IUnknown*)*ppv);
209 return S_OK;
212 static ULONG WINAPI FolderItemVerbImpl_AddRef(FolderItemVerb *iface)
214 FolderItemVerbImpl *This = impl_from_FolderItemVerb(iface);
215 ULONG ref = InterlockedIncrement(&This->ref);
217 TRACE("(%p), new refcount=%i\n", iface, ref);
219 return ref;
222 static ULONG WINAPI FolderItemVerbImpl_Release(FolderItemVerb *iface)
224 FolderItemVerbImpl *This = impl_from_FolderItemVerb(iface);
225 ULONG ref = InterlockedDecrement(&This->ref);
227 TRACE("(%p), new refcount=%i\n", iface, ref);
229 if (!ref)
231 IContextMenu_Release(This->contextmenu);
232 SysFreeString(This->name);
233 HeapFree(GetProcessHeap(), 0, This);
236 return ref;
239 static HRESULT WINAPI FolderItemVerbImpl_GetTypeInfoCount(FolderItemVerb *iface, UINT *pctinfo)
241 TRACE("(%p,%p)\n", iface, pctinfo);
242 *pctinfo = 1;
243 return S_OK;
246 static HRESULT WINAPI FolderItemVerbImpl_GetTypeInfo(FolderItemVerb *iface, UINT iTInfo,
247 LCID lcid, ITypeInfo **ppTInfo)
249 HRESULT hr;
251 TRACE("(%p,%u,%d,%p)\n", iface, iTInfo, lcid, ppTInfo);
253 hr = get_typeinfo(FolderItemVerb_tid, ppTInfo);
254 if (SUCCEEDED(hr))
255 ITypeInfo_AddRef(*ppTInfo);
256 return hr;
259 static HRESULT WINAPI FolderItemVerbImpl_GetIDsOfNames(FolderItemVerb *iface,
260 REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
262 ITypeInfo *ti;
263 HRESULT hr;
265 TRACE("(%p,%s,%p,%u,%d,%p)\n", iface, shdebugstr_guid(riid), rgszNames, cNames, lcid,
266 rgDispId);
268 hr = get_typeinfo(FolderItemVerb_tid, &ti);
269 if (SUCCEEDED(hr))
270 hr = ITypeInfo_GetIDsOfNames(ti, rgszNames, cNames, rgDispId);
271 return hr;
274 static HRESULT WINAPI FolderItemVerbImpl_Invoke(FolderItemVerb *iface,
275 DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags,
276 DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo,
277 UINT *puArgErr)
279 ITypeInfo *ti;
280 HRESULT hr;
282 TRACE("(%p,%d,%s,%d,%u,%p,%p,%p,%p)\n", iface, dispIdMember, shdebugstr_guid(riid), lcid,
283 wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
285 hr = get_typeinfo(FolderItemVerb_tid, &ti);
286 if (SUCCEEDED(hr))
287 hr = ITypeInfo_Invoke(ti, iface, dispIdMember, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
288 return hr;
291 static HRESULT WINAPI FolderItemVerbImpl_get_Application(FolderItemVerb *iface, IDispatch **disp)
293 FIXME("(%p, %p)\n", iface, disp);
294 return E_NOTIMPL;
297 static HRESULT WINAPI FolderItemVerbImpl_get_Parent(FolderItemVerb *iface, IDispatch **disp)
299 FIXME("(%p, %p)\n", iface, disp);
300 return E_NOTIMPL;
303 static HRESULT WINAPI FolderItemVerbImpl_get_Name(FolderItemVerb *iface, BSTR *name)
305 FolderItemVerbImpl *This = impl_from_FolderItemVerb(iface);
307 TRACE("(%p, %p)\n", iface, name);
309 *name = SysAllocString(This->name);
310 return *name ? S_OK : E_OUTOFMEMORY;
313 static HRESULT WINAPI FolderItemVerbImpl_DoIt(FolderItemVerb *iface)
315 FIXME("(%p)\n", iface);
316 return E_NOTIMPL;
319 static FolderItemVerbVtbl folderitemverbvtbl = {
320 FolderItemVerbImpl_QueryInterface,
321 FolderItemVerbImpl_AddRef,
322 FolderItemVerbImpl_Release,
323 FolderItemVerbImpl_GetTypeInfoCount,
324 FolderItemVerbImpl_GetTypeInfo,
325 FolderItemVerbImpl_GetIDsOfNames,
326 FolderItemVerbImpl_Invoke,
327 FolderItemVerbImpl_get_Application,
328 FolderItemVerbImpl_get_Parent,
329 FolderItemVerbImpl_get_Name,
330 FolderItemVerbImpl_DoIt
333 static HRESULT FolderItemVerb_Constructor(IContextMenu *contextmenu, BSTR name, FolderItemVerb **verb)
335 FolderItemVerbImpl *This;
337 TRACE("%p, %s\n", contextmenu, debugstr_w(name));
339 This = HeapAlloc(GetProcessHeap(), 0, sizeof(FolderItemVerbImpl));
340 if (!This)
341 return E_OUTOFMEMORY;
343 This->FolderItemVerb_iface.lpVtbl = &folderitemverbvtbl;
344 This->ref = 1;
345 This->contextmenu = contextmenu;
346 IContextMenu_AddRef(contextmenu);
347 This->name = name;
349 *verb = &This->FolderItemVerb_iface;
350 return S_OK;
353 /* FolderItemVerbs */
354 static HRESULT WINAPI FolderItemVerbsImpl_QueryInterface(FolderItemVerbs *iface,
355 REFIID riid, void **ppv)
357 FolderItemVerbsImpl *This = impl_from_FolderItemVerbs(iface);
359 TRACE("(%p,%s,%p)\n", iface, shdebugstr_guid(riid), ppv);
361 *ppv = NULL;
363 if (IsEqualIID(&IID_IUnknown, riid) ||
364 IsEqualIID(&IID_IDispatch, riid) ||
365 IsEqualIID(&IID_FolderItemVerbs, riid))
366 *ppv = &This->FolderItemVerbs_iface;
367 else
369 FIXME("not implemented for %s\n", shdebugstr_guid(riid));
370 *ppv = NULL;
371 return E_NOINTERFACE;
374 IUnknown_AddRef((IUnknown*)*ppv);
375 return S_OK;
378 static ULONG WINAPI FolderItemVerbsImpl_AddRef(FolderItemVerbs *iface)
380 FolderItemVerbsImpl *This = impl_from_FolderItemVerbs(iface);
381 ULONG ref = InterlockedIncrement(&This->ref);
383 TRACE("(%p), new refcount=%i\n", iface, ref);
385 return ref;
388 static ULONG WINAPI FolderItemVerbsImpl_Release(FolderItemVerbs *iface)
390 FolderItemVerbsImpl *This = impl_from_FolderItemVerbs(iface);
391 ULONG ref = InterlockedDecrement(&This->ref);
393 TRACE("(%p), new refcount=%i\n", iface, ref);
395 if (!ref)
397 IContextMenu_Release(This->contextmenu);
398 DestroyMenu(This->hMenu);
399 HeapFree(GetProcessHeap(), 0, This);
402 return ref;
405 static HRESULT WINAPI FolderItemVerbsImpl_GetTypeInfoCount(FolderItemVerbs *iface, UINT *pctinfo)
407 TRACE("(%p,%p)\n", iface, pctinfo);
408 *pctinfo = 1;
409 return S_OK;
412 static HRESULT WINAPI FolderItemVerbsImpl_GetTypeInfo(FolderItemVerbs *iface, UINT iTInfo,
413 LCID lcid, ITypeInfo **ppTInfo)
415 HRESULT hr;
417 TRACE("(%p,%u,%d,%p)\n", iface, iTInfo, lcid, ppTInfo);
419 hr = get_typeinfo(FolderItemVerbs_tid, ppTInfo);
420 if (SUCCEEDED(hr))
421 ITypeInfo_AddRef(*ppTInfo);
422 return hr;
425 static HRESULT WINAPI FolderItemVerbsImpl_GetIDsOfNames(FolderItemVerbs *iface,
426 REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
428 ITypeInfo *ti;
429 HRESULT hr;
431 TRACE("(%p,%s,%p,%u,%d,%p)\n", iface, shdebugstr_guid(riid), rgszNames, cNames, lcid,
432 rgDispId);
434 hr = get_typeinfo(FolderItemVerbs_tid, &ti);
435 if (SUCCEEDED(hr))
436 hr = ITypeInfo_GetIDsOfNames(ti, rgszNames, cNames, rgDispId);
437 return hr;
440 static HRESULT WINAPI FolderItemVerbsImpl_Invoke(FolderItemVerbs *iface,
441 DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags,
442 DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo,
443 UINT *puArgErr)
445 ITypeInfo *ti;
446 HRESULT hr;
448 TRACE("(%p,%d,%s,%d,%u,%p,%p,%p,%p)\n", iface, dispIdMember, shdebugstr_guid(riid), lcid,
449 wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
451 hr = get_typeinfo(FolderItemVerbs_tid, &ti);
452 if (SUCCEEDED(hr))
453 hr = ITypeInfo_Invoke(ti, iface, dispIdMember, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
454 return hr;
457 static HRESULT WINAPI FolderItemVerbsImpl_get_Count(FolderItemVerbs *iface, LONG *count)
459 FolderItemVerbsImpl *This = impl_from_FolderItemVerbs(iface);
461 TRACE("(%p, %p)\n", iface, count);
463 if (!count)
464 return E_INVALIDARG;
466 *count = This->count;
467 return S_OK;
470 static HRESULT WINAPI FolderItemVerbsImpl_get_Application(FolderItemVerbs *iface, IDispatch **disp)
472 FIXME("(%p, %p)\n", iface, disp);
473 return E_NOTIMPL;
476 static HRESULT WINAPI FolderItemVerbsImpl_get_Parent(FolderItemVerbs *iface, IDispatch **disp)
478 FIXME("(%p, %p)\n", iface, disp);
479 return E_NOTIMPL;
482 static HRESULT WINAPI FolderItemVerbsImpl_Item(FolderItemVerbs *iface, VARIANT index, FolderItemVerb **verb)
484 FolderItemVerbsImpl *This = impl_from_FolderItemVerbs(iface);
485 MENUITEMINFOW info;
486 HRESULT hr;
487 VARIANT v;
488 BSTR name;
490 TRACE("(%p, %s, %p)\n", iface, debugstr_variant(&index), verb);
492 if (!verb)
493 return E_INVALIDARG;
495 *verb = NULL;
497 VariantInit(&v);
498 VariantCopyInd(&v, &index);
500 hr = VariantChangeType(&v, &v, 0, VT_I4);
501 if (FAILED(hr))
503 FIXME("failed to coerce to VT_I4, %s\n", debugstr_variant(&v));
504 return hr;
507 if (V_I4(&v) > This->count)
508 return S_OK;
510 if (V_I4(&v) == This->count)
511 name = SysAllocStringLen(NULL, 0);
512 else
514 /* get item name */
515 memset(&info, 0, sizeof(info));
516 info.cbSize = sizeof(info);
517 info.fMask = MIIM_STRING;
518 if (!GetMenuItemInfoW(This->hMenu, V_I4(&v), TRUE, &info))
519 return E_FAIL;
521 name = SysAllocStringLen(NULL, info.cch);
522 if (name)
524 info.dwTypeData = name;
525 info.cch++;
526 GetMenuItemInfoW(This->hMenu, V_I4(&v), TRUE, &info);
530 if (!name)
531 return E_OUTOFMEMORY;
533 return FolderItemVerb_Constructor(This->contextmenu, name, verb);
536 static HRESULT WINAPI FolderItemVerbsImpl__NewEnum(FolderItemVerbs *iface, IUnknown **ret)
538 FIXME("(%p, %p)\n", iface, ret);
539 return E_NOTIMPL;
542 static FolderItemVerbsVtbl folderitemverbsvtbl = {
543 FolderItemVerbsImpl_QueryInterface,
544 FolderItemVerbsImpl_AddRef,
545 FolderItemVerbsImpl_Release,
546 FolderItemVerbsImpl_GetTypeInfoCount,
547 FolderItemVerbsImpl_GetTypeInfo,
548 FolderItemVerbsImpl_GetIDsOfNames,
549 FolderItemVerbsImpl_Invoke,
550 FolderItemVerbsImpl_get_Count,
551 FolderItemVerbsImpl_get_Application,
552 FolderItemVerbsImpl_get_Parent,
553 FolderItemVerbsImpl_Item,
554 FolderItemVerbsImpl__NewEnum
557 static HRESULT FolderItemVerbs_Constructor(BSTR path, FolderItemVerbs **verbs)
559 FolderItemVerbsImpl *This;
560 IShellFolder *folder;
561 LPCITEMIDLIST child;
562 LPITEMIDLIST pidl;
563 HRESULT hr;
565 This = HeapAlloc(GetProcessHeap(), 0, sizeof(FolderItemVerbsImpl));
566 if (!This)
567 return E_OUTOFMEMORY;
569 This->FolderItemVerbs_iface.lpVtbl = &folderitemverbsvtbl;
570 This->ref = 1;
572 /* build context menu for this path */
573 hr = SHParseDisplayName(path, NULL, &pidl, 0, NULL);
574 if (FAILED(hr))
575 goto failed;
577 hr = SHBindToParent(pidl, &IID_IShellFolder, (void**)&folder, &child);
578 CoTaskMemFree(pidl);
579 if (FAILED(hr))
580 goto failed;
582 hr = IShellFolder_GetUIObjectOf(folder, NULL, 1, &child, &IID_IContextMenu, NULL, (void**)&This->contextmenu);
583 IShellFolder_Release(folder);
584 if (FAILED(hr))
585 goto failed;
587 This->hMenu = CreatePopupMenu();
588 hr = IContextMenu_QueryContextMenu(This->contextmenu, This->hMenu, 0, FCIDM_SHVIEWFIRST, FCIDM_SHVIEWLAST, CMF_NORMAL);
589 if (FAILED(hr))
591 FolderItemVerbs_Release(&This->FolderItemVerbs_iface);
592 return hr;
595 This->count = GetMenuItemCount(This->hMenu);
596 *verbs = &This->FolderItemVerbs_iface;
597 return S_OK;
599 failed:
600 HeapFree(GetProcessHeap(), 0, This);
601 return hr;
604 static HRESULT WINAPI FolderItemImpl_QueryInterface(FolderItem2 *iface,
605 REFIID riid, LPVOID *ppv)
607 FolderItemImpl *This = impl_from_FolderItem(iface);
609 TRACE("(%p,%s,%p)\n", iface, shdebugstr_guid(riid), ppv);
611 if (!ppv) return E_INVALIDARG;
613 if (IsEqualIID(&IID_IUnknown, riid) ||
614 IsEqualIID(&IID_IDispatch, riid) ||
615 IsEqualIID(&IID_FolderItem, riid) ||
616 IsEqualIID(&IID_FolderItem2, riid))
617 *ppv = &This->FolderItem2_iface;
618 else
620 FIXME("not implemented for %s\n", shdebugstr_guid(riid));
621 *ppv = NULL;
622 return E_NOINTERFACE;
624 IUnknown_AddRef((IUnknown*)*ppv);
625 return S_OK;
628 static ULONG WINAPI FolderItemImpl_AddRef(FolderItem2 *iface)
630 FolderItemImpl *This = impl_from_FolderItem(iface);
631 ULONG ref = InterlockedIncrement(&This->ref);
633 TRACE("(%p), new refcount=%i\n", iface, ref);
635 return ref;
638 static ULONG WINAPI FolderItemImpl_Release(FolderItem2 *iface)
640 FolderItemImpl *This = impl_from_FolderItem(iface);
641 ULONG ref = InterlockedDecrement(&This->ref);
643 TRACE("(%p), new refcount=%i\n", iface, ref);
645 if (!ref)
647 VariantClear(&This->dir);
648 HeapFree(GetProcessHeap(), 0, This);
650 return ref;
653 static HRESULT WINAPI FolderItemImpl_GetTypeInfoCount(FolderItem2 *iface,
654 UINT *pctinfo)
656 TRACE("(%p,%p)\n", iface, pctinfo);
658 *pctinfo = 1;
659 return S_OK;
662 static HRESULT WINAPI FolderItemImpl_GetTypeInfo(FolderItem2 *iface, UINT iTInfo,
663 LCID lcid, ITypeInfo **ppTInfo)
665 HRESULT hr;
667 TRACE("(%p,%u,%d,%p)\n", iface, iTInfo, lcid, ppTInfo);
669 hr = get_typeinfo(FolderItem2_tid, ppTInfo);
670 if (SUCCEEDED(hr))
671 ITypeInfo_AddRef(*ppTInfo);
672 return hr;
675 static HRESULT WINAPI FolderItemImpl_GetIDsOfNames(FolderItem2 *iface,
676 REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid,
677 DISPID *rgDispId)
679 ITypeInfo *ti;
680 HRESULT hr;
682 TRACE("(%p,%s,%p,%u,%d,%p)\n", iface, shdebugstr_guid(riid), rgszNames, cNames, lcid,
683 rgDispId);
685 hr = get_typeinfo(FolderItem2_tid, &ti);
686 if (SUCCEEDED(hr))
687 hr = ITypeInfo_GetIDsOfNames(ti, rgszNames, cNames, rgDispId);
688 return hr;
691 static HRESULT WINAPI FolderItemImpl_Invoke(FolderItem2 *iface,
692 DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags,
693 DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo,
694 UINT *puArgErr)
696 FolderItemImpl *This = impl_from_FolderItem(iface);
697 ITypeInfo *ti;
698 HRESULT hr;
700 TRACE("(%p,%d,%s,%d,%u,%p,%p,%p,%p)\n", iface, dispIdMember, shdebugstr_guid(riid), lcid,
701 wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
703 hr = get_typeinfo(FolderItem2_tid, &ti);
704 if (SUCCEEDED(hr))
705 hr = ITypeInfo_Invoke(ti, This, dispIdMember, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
706 return hr;
709 static HRESULT WINAPI FolderItemImpl_get_Application(FolderItem2 *iface,
710 IDispatch **ppid)
712 FIXME("(%p,%p)\n", iface, ppid);
714 *ppid = NULL;
715 return E_NOTIMPL;
718 static HRESULT WINAPI FolderItemImpl_get_Parent(FolderItem2 *iface,
719 IDispatch **ppid)
721 FIXME("(%p,%p)\n", iface, ppid);
723 *ppid = NULL;
724 return E_NOTIMPL;
727 static HRESULT WINAPI FolderItemImpl_get_Name(FolderItem2 *iface, BSTR *pbs)
729 FIXME("(%p,%p)\n", iface, pbs);
731 *pbs = NULL;
732 return E_NOTIMPL;
735 static HRESULT WINAPI FolderItemImpl_put_Name(FolderItem2 *iface, BSTR bs)
737 FIXME("(%p,%s)\n", iface, debugstr_w(bs));
739 return E_NOTIMPL;
742 static HRESULT WINAPI FolderItemImpl_get_Path(FolderItem2 *iface, BSTR *pbs)
744 FolderItemImpl *This = impl_from_FolderItem(iface);
745 HRESULT ret = S_OK;
746 WCHAR *pathW;
747 int len;
749 TRACE("(%p,%p)\n", iface, pbs);
751 *pbs = NULL;
752 if (V_VT(&This->dir) == VT_I4)
754 pathW = HeapAlloc(GetProcessHeap(), 0, MAX_PATH * sizeof(WCHAR));
755 if (!pathW) return E_OUTOFMEMORY;
756 ret = SHGetFolderPathW(NULL, V_I4(&This->dir), NULL, SHGFP_TYPE_CURRENT,
757 pathW);
758 if (ret == S_OK)
759 *pbs = SysAllocString(pathW);
760 else if (ret == E_INVALIDARG)
762 FIXME("not implemented for %#x\n", V_I4(&This->dir));
763 ret = E_NOTIMPL;
765 HeapFree(GetProcessHeap(), 0, pathW);
767 else /* VT_BSTR */
769 pathW = V_BSTR(&This->dir);
770 len = lstrlenW(pathW);
771 *pbs = SysAllocStringLen(pathW, pathW[len - 1] == '\\' ? len - 1 : len);
773 if (ret == S_OK && !*pbs)
774 ret = E_OUTOFMEMORY;
775 return ret;
778 static HRESULT WINAPI FolderItemImpl_get_GetLink(FolderItem2 *iface,
779 IDispatch **ppid)
781 FIXME("(%p,%p)\n", iface, ppid);
783 *ppid = NULL;
784 return E_NOTIMPL;
787 static HRESULT WINAPI FolderItemImpl_get_GetFolder(FolderItem2 *iface,
788 IDispatch **ppid)
790 FIXME("(%p,%p)\n", iface, ppid);
792 *ppid = NULL;
793 return E_NOTIMPL;
796 static HRESULT WINAPI FolderItemImpl_get_IsLink(FolderItem2 *iface,
797 VARIANT_BOOL *pb)
799 FIXME("(%p,%p)\n", iface, pb);
801 return E_NOTIMPL;
804 static HRESULT WINAPI FolderItemImpl_get_IsFolder(FolderItem2 *iface,
805 VARIANT_BOOL *pb)
807 FIXME("(%p,%p)\n", iface, pb);
809 return E_NOTIMPL;
812 static HRESULT WINAPI FolderItemImpl_get_IsFileSystem(FolderItem2 *iface,
813 VARIANT_BOOL *pb)
815 FIXME("(%p,%p)\n", iface, pb);
817 return E_NOTIMPL;
820 static HRESULT WINAPI FolderItemImpl_get_IsBrowsable(FolderItem2 *iface,
821 VARIANT_BOOL *pb)
823 FIXME("(%p,%p)\n", iface, pb);
825 return E_NOTIMPL;
828 static HRESULT WINAPI FolderItemImpl_get_ModifyDate(FolderItem2 *iface,
829 DATE *pdt)
831 FIXME("(%p,%p)\n", iface, pdt);
833 return E_NOTIMPL;
836 static HRESULT WINAPI FolderItemImpl_put_ModifyDate(FolderItem2 *iface, DATE dt)
838 FIXME("(%p,%f)\n", iface, dt);
840 return E_NOTIMPL;
843 static HRESULT WINAPI FolderItemImpl_get_Size(FolderItem2 *iface, LONG *pul)
845 FIXME("(%p,%p)\n", iface, pul);
847 return E_NOTIMPL;
850 static HRESULT WINAPI FolderItemImpl_get_Type(FolderItem2 *iface, BSTR *pbs)
852 FIXME("(%p,%p)\n", iface, pbs);
854 *pbs = NULL;
855 return E_NOTIMPL;
858 static HRESULT WINAPI FolderItemImpl_Verbs(FolderItem2 *iface, FolderItemVerbs **verbs)
860 HRESULT hr;
861 BSTR path;
863 TRACE("(%p, %p)\n", iface, verbs);
865 if (!verbs)
866 return E_INVALIDARG;
868 *verbs = NULL;
870 hr = FolderItem2_get_Path(iface, &path);
871 if (FAILED(hr))
872 return hr;
874 hr = FolderItemVerbs_Constructor(path, verbs);
875 SysFreeString(path);
876 return hr;
879 static HRESULT WINAPI FolderItemImpl_InvokeVerb(FolderItem2 *iface,
880 VARIANT vVerb)
882 FIXME("(%p)\n", iface);
884 return E_NOTIMPL;
887 static HRESULT WINAPI FolderItemImpl_InvokeVerbEx(FolderItem2 *iface, VARIANT verb, VARIANT args)
889 FIXME("(%p): stub\n", iface);
891 return E_NOTIMPL;
894 static HRESULT WINAPI FolderItemImpl_ExtendedProperty(FolderItem2 *iface, BSTR propname, VARIANT *ret)
896 FIXME("(%p)->(%s %p): stub\n", iface, debugstr_w(propname), ret);
898 return E_NOTIMPL;
901 static const FolderItem2Vtbl FolderItemImpl_Vtbl = {
902 FolderItemImpl_QueryInterface,
903 FolderItemImpl_AddRef,
904 FolderItemImpl_Release,
905 FolderItemImpl_GetTypeInfoCount,
906 FolderItemImpl_GetTypeInfo,
907 FolderItemImpl_GetIDsOfNames,
908 FolderItemImpl_Invoke,
909 FolderItemImpl_get_Application,
910 FolderItemImpl_get_Parent,
911 FolderItemImpl_get_Name,
912 FolderItemImpl_put_Name,
913 FolderItemImpl_get_Path,
914 FolderItemImpl_get_GetLink,
915 FolderItemImpl_get_GetFolder,
916 FolderItemImpl_get_IsLink,
917 FolderItemImpl_get_IsFolder,
918 FolderItemImpl_get_IsFileSystem,
919 FolderItemImpl_get_IsBrowsable,
920 FolderItemImpl_get_ModifyDate,
921 FolderItemImpl_put_ModifyDate,
922 FolderItemImpl_get_Size,
923 FolderItemImpl_get_Type,
924 FolderItemImpl_Verbs,
925 FolderItemImpl_InvokeVerb,
926 FolderItemImpl_InvokeVerbEx,
927 FolderItemImpl_ExtendedProperty
930 static HRESULT FolderItem_Constructor(VARIANT *dir, FolderItem **ppfi)
932 FolderItemImpl *This;
933 HRESULT ret;
935 TRACE("%s\n", debugstr_variant(dir));
937 *ppfi = NULL;
939 This = HeapAlloc(GetProcessHeap(), 0, sizeof(FolderItemImpl));
940 if (!This) return E_OUTOFMEMORY;
941 This->FolderItem2_iface.lpVtbl = &FolderItemImpl_Vtbl;
942 This->ref = 1;
944 VariantInit(&This->dir);
945 ret = VariantCopy(&This->dir, dir);
946 if (FAILED(ret))
948 HeapFree(GetProcessHeap(), 0, This);
949 return E_OUTOFMEMORY;
952 *ppfi = (FolderItem*)&This->FolderItem2_iface;
953 return ret;
956 static HRESULT WINAPI FolderItemsImpl_QueryInterface(FolderItems3 *iface,
957 REFIID riid, LPVOID *ppv)
959 FolderItemsImpl *This = impl_from_FolderItems(iface);
961 TRACE("(%p,%s,%p)\n", iface, shdebugstr_guid(riid), ppv);
963 if (!ppv) return E_INVALIDARG;
965 if (IsEqualIID(&IID_IUnknown, riid) ||
966 IsEqualIID(&IID_IDispatch, riid) ||
967 IsEqualIID(&IID_FolderItems, riid) ||
968 IsEqualIID(&IID_FolderItems2, riid) ||
969 IsEqualIID(&IID_FolderItems3, riid))
970 *ppv = &This->FolderItems3_iface;
971 else
973 FIXME("not implemented for %s\n", shdebugstr_guid(riid));
974 *ppv = NULL;
975 return E_NOINTERFACE;
977 IUnknown_AddRef((IUnknown*)*ppv);
978 return S_OK;
981 static ULONG WINAPI FolderItemsImpl_AddRef(FolderItems3 *iface)
983 FolderItemsImpl *This = impl_from_FolderItems(iface);
984 ULONG ref = InterlockedIncrement(&This->ref);
986 TRACE("(%p), new refcount=%i\n", iface, ref);
988 return ref;
991 static ULONG WINAPI FolderItemsImpl_Release(FolderItems3 *iface)
993 FolderItemsImpl *This = impl_from_FolderItems(iface);
994 ULONG ref = InterlockedDecrement(&This->ref);
995 LONG i;
997 TRACE("(%p), new refcount=%i\n", iface, ref);
999 if (!ref)
1001 VariantClear(&This->dir);
1002 for (i = 0; i < This->item_count; i++)
1003 HeapFree(GetProcessHeap(), 0, This->item_filenames[i]);
1004 HeapFree(GetProcessHeap(), 0, This->item_filenames);
1005 HeapFree(GetProcessHeap(), 0, This);
1007 return ref;
1010 static HRESULT WINAPI FolderItemsImpl_GetTypeInfoCount(FolderItems3 *iface,
1011 UINT *count)
1013 TRACE("(%p,%p)\n", iface, count);
1015 *count = 1;
1016 return S_OK;
1019 static HRESULT WINAPI FolderItemsImpl_GetTypeInfo(FolderItems3 *iface,
1020 UINT type, LCID lcid, ITypeInfo **ppti)
1022 HRESULT hr;
1024 TRACE("(%p,%u,%d,%p)\n", iface, type, lcid, ppti);
1026 hr = get_typeinfo(FolderItems3_tid, ppti);
1027 if (SUCCEEDED(hr))
1028 ITypeInfo_AddRef(*ppti);
1029 return hr;
1032 static HRESULT WINAPI FolderItemsImpl_GetIDsOfNames(FolderItems3 *iface,
1033 REFIID riid, LPOLESTR *names, UINT count, LCID lcid, DISPID *dispid)
1035 ITypeInfo *ti;
1036 HRESULT hr;
1038 TRACE("(%p,%s,%p,%u,%d,%p)\n", iface, shdebugstr_guid(riid), names, count, lcid, dispid);
1040 hr = get_typeinfo(FolderItems3_tid, &ti);
1041 if (SUCCEEDED(hr))
1042 hr = ITypeInfo_GetIDsOfNames(ti, names, count, dispid);
1043 return hr;
1046 static HRESULT WINAPI FolderItemsImpl_Invoke(FolderItems3 *iface,
1047 DISPID dispid, REFIID riid, LCID lcid, WORD flags, DISPPARAMS *params,
1048 VARIANT *result, EXCEPINFO *ei, UINT *err)
1050 FolderItemsImpl *This = impl_from_FolderItems(iface);
1051 ITypeInfo *ti;
1052 HRESULT hr;
1054 TRACE("(%p,%d,%s,%d,%u,%p,%p,%p,%p)\n", iface, dispid, shdebugstr_guid(riid), lcid, flags, params, result, ei, err);
1056 hr = get_typeinfo(FolderItems3_tid, &ti);
1057 if (SUCCEEDED(hr))
1058 hr = ITypeInfo_Invoke(ti, This, dispid, flags, params, result, ei, err);
1059 return hr;
1062 static HRESULT WINAPI FolderItemsImpl_get_Count(FolderItems3 *iface, LONG *count)
1064 FolderItemsImpl *This = impl_from_FolderItems(iface);
1066 TRACE("(%p,%p)\n", iface, count);
1068 *count = PathIsDirectoryW(V_BSTR(&This->dir)) ? This->item_count : 0;
1069 return S_OK;
1072 static HRESULT WINAPI FolderItemsImpl_get_Application(FolderItems3 *iface, IDispatch **ppid)
1074 FIXME("(%p,%p)\n", iface, ppid);
1076 if (!ppid)
1077 return E_INVALIDARG;
1079 *ppid = NULL;
1080 return E_NOTIMPL;
1083 static HRESULT WINAPI FolderItemsImpl_get_Parent(FolderItems3 *iface, IDispatch **ppid)
1085 TRACE("(%p,%p)\n", iface, ppid);
1087 if (ppid)
1088 *ppid = NULL;
1090 return E_NOTIMPL;
1093 static HRESULT WINAPI FolderItemsImpl_Item(FolderItems3 *iface, VARIANT index, FolderItem **ppid)
1095 FolderItemsImpl *This = impl_from_FolderItems(iface);
1096 WCHAR canonicalized_index[MAX_PATH], path_str[MAX_PATH];
1097 VARIANT path_var;
1098 HRESULT ret;
1100 TRACE("(%p,%s,%p)\n", iface, debugstr_variant(&index), ppid);
1102 *ppid = NULL;
1104 if (!PathIsDirectoryW(V_BSTR(&This->dir)))
1105 return S_FALSE;
1107 switch (V_VT(&index))
1109 case VT_I2:
1110 VariantChangeType(&index, &index, 0, VT_I4);
1111 /* fall through */
1113 case VT_I4:
1114 if (V_I4(&index) >= This->item_count || V_I4(&index) < 0)
1115 return S_FALSE;
1117 if (!PathCombineW(path_str, V_BSTR(&This->dir), This->item_filenames[V_I4(&index)]))
1118 return S_FALSE;
1120 break;
1122 case VT_BSTR:
1123 if (!V_BSTR(&index))
1124 return S_FALSE;
1126 if (!PathCanonicalizeW(canonicalized_index, V_BSTR(&index)))
1127 return S_FALSE;
1129 if (strcmpW(V_BSTR(&index), canonicalized_index) != 0)
1130 return S_FALSE;
1132 if (!PathCombineW(path_str, V_BSTR(&This->dir), V_BSTR(&index)))
1133 return S_FALSE;
1135 if (!PathFileExistsW(path_str))
1136 return S_FALSE;
1138 break;
1140 case VT_ERROR:
1141 return FolderItem_Constructor(&This->dir, ppid);
1143 default:
1144 return E_NOTIMPL;
1147 V_VT(&path_var) = VT_BSTR;
1148 V_BSTR(&path_var) = SysAllocString(path_str);
1149 ret = FolderItem_Constructor(&path_var, ppid);
1150 VariantClear(&path_var);
1151 return ret;
1154 static HRESULT WINAPI FolderItemsImpl__NewEnum(FolderItems3 *iface, IUnknown **ppunk)
1156 FIXME("(%p,%p)\n", iface, ppunk);
1158 if (!ppunk)
1159 return E_INVALIDARG;
1161 *ppunk = NULL;
1162 return E_NOTIMPL;
1165 static HRESULT WINAPI FolderItemsImpl_InvokeVerbEx(FolderItems3 *iface, VARIANT verb, VARIANT args)
1167 FIXME("(%p,%s,%s)\n", iface, debugstr_variant(&verb), debugstr_variant(&args));
1169 return E_NOTIMPL;
1172 static HRESULT WINAPI FolderItemsImpl_Filter(FolderItems3 *iface, LONG flags, BSTR spec)
1174 FIXME("(%p,%d,%s)\n", iface, flags, wine_dbgstr_w(spec));
1176 return E_NOTIMPL;
1179 static HRESULT WINAPI FolderItemsImpl_get_Verbs(FolderItems3 *iface, FolderItemVerbs **ppfic)
1181 FIXME("(%p,%p)\n", iface, ppfic);
1183 if (!ppfic)
1184 return E_INVALIDARG;
1186 *ppfic = NULL;
1187 return E_NOTIMPL;
1190 static const FolderItems3Vtbl FolderItemsImpl_Vtbl = {
1191 FolderItemsImpl_QueryInterface,
1192 FolderItemsImpl_AddRef,
1193 FolderItemsImpl_Release,
1194 FolderItemsImpl_GetTypeInfoCount,
1195 FolderItemsImpl_GetTypeInfo,
1196 FolderItemsImpl_GetIDsOfNames,
1197 FolderItemsImpl_Invoke,
1198 FolderItemsImpl_get_Count,
1199 FolderItemsImpl_get_Application,
1200 FolderItemsImpl_get_Parent,
1201 FolderItemsImpl_Item,
1202 FolderItemsImpl__NewEnum,
1203 FolderItemsImpl_InvokeVerbEx,
1204 FolderItemsImpl_Filter,
1205 FolderItemsImpl_get_Verbs
1208 static HRESULT FolderItems_Constructor(VARIANT *dir, FolderItems **ppfi)
1210 static const WCHAR backslash_star[] = {'\\','*',0};
1211 static const WCHAR dot[] = {'.',0};
1212 static const WCHAR dot_dot[] = {'.','.',0};
1213 FolderItemsImpl *This;
1214 LONG item_size;
1215 WCHAR glob[MAX_PATH + 2];
1216 HANDLE first_file;
1217 WIN32_FIND_DATAW file_info;
1218 WCHAR **filenames;
1219 HRESULT ret;
1221 TRACE("(%s,%p)\n", debugstr_variant(dir), ppfi);
1223 *ppfi = NULL;
1225 if (V_VT(dir) == VT_I4)
1227 FIXME("special folder constants are not supported\n");
1228 return E_NOTIMPL;
1231 This = HeapAlloc(GetProcessHeap(), 0, sizeof(FolderItemsImpl));
1232 if (!This) return E_OUTOFMEMORY;
1233 This->FolderItems3_iface.lpVtbl = &FolderItemsImpl_Vtbl;
1234 This->ref = 1;
1236 VariantInit(&This->dir);
1237 ret = VariantCopy(&This->dir, dir);
1238 if (FAILED(ret))
1240 HeapFree(GetProcessHeap(), 0, This);
1241 return ret;
1244 This->item_count = 0;
1245 lstrcpyW(glob, V_BSTR(dir));
1246 lstrcatW(glob, backslash_star);
1247 first_file = FindFirstFileW(glob, &file_info);
1248 if (first_file != INVALID_HANDLE_VALUE)
1250 item_size = 128;
1251 This->item_filenames = HeapAlloc(GetProcessHeap(), 0, item_size * sizeof(WCHAR*));
1252 if (!This->item_filenames)
1253 goto fail;
1257 if (!strcmpW(file_info.cFileName, dot) || !strcmpW(file_info.cFileName, dot_dot))
1258 continue;
1260 if (This->item_count >= item_size)
1262 item_size *= 2;
1263 filenames = HeapReAlloc(GetProcessHeap(), 0, This->item_filenames, item_size * sizeof(WCHAR*));
1264 if (!filenames)
1265 goto fail;
1266 This->item_filenames = filenames;
1269 This->item_filenames[This->item_count] = strdupW(file_info.cFileName);
1270 if (!This->item_filenames[This->item_count])
1271 goto fail;
1272 This->item_count++;
1274 while (FindNextFileW(first_file, &file_info));
1276 FindClose(first_file);
1277 HeapReAlloc(GetProcessHeap(), HEAP_REALLOC_IN_PLACE_ONLY,
1278 This->item_filenames, This->item_count * sizeof(WCHAR*));
1280 else
1282 This->item_filenames = NULL;
1285 *ppfi = (FolderItems*)&This->FolderItems3_iface;
1286 return S_OK;
1288 fail:
1289 FindClose(first_file);
1290 FolderItems3_Release(&This->FolderItems3_iface);
1291 return E_OUTOFMEMORY;
1294 static HRESULT WINAPI FolderImpl_QueryInterface(Folder3 *iface, REFIID riid,
1295 LPVOID *ppv)
1297 FolderImpl *This = impl_from_Folder(iface);
1299 TRACE("(%p,%s,%p)\n", iface, shdebugstr_guid(riid), ppv);
1301 if (!ppv) return E_INVALIDARG;
1303 if (IsEqualIID(&IID_IUnknown, riid) ||
1304 IsEqualIID(&IID_IDispatch, riid) ||
1305 IsEqualIID(&IID_Folder, riid) ||
1306 IsEqualIID(&IID_Folder2, riid) ||
1307 IsEqualIID(&IID_Folder3, riid))
1308 *ppv = &This->Folder3_iface;
1309 else
1311 FIXME("not implemented for %s\n", shdebugstr_guid(riid));
1312 *ppv = NULL;
1313 return E_NOINTERFACE;
1315 IUnknown_AddRef((IUnknown*)*ppv);
1316 return S_OK;
1319 static ULONG WINAPI FolderImpl_AddRef(Folder3 *iface)
1321 FolderImpl *This = impl_from_Folder(iface);
1322 ULONG ref = InterlockedIncrement(&This->ref);
1324 TRACE("(%p), new refcount=%i\n", iface, ref);
1326 return ref;
1329 static ULONG WINAPI FolderImpl_Release(Folder3 *iface)
1331 FolderImpl *This = impl_from_Folder(iface);
1332 ULONG ref = InterlockedDecrement(&This->ref);
1334 TRACE("(%p), new refcount=%i\n", iface, ref);
1336 if (!ref)
1338 VariantClear(&This->dir);
1339 HeapFree(GetProcessHeap(), 0, This);
1341 return ref;
1344 static HRESULT WINAPI FolderImpl_GetTypeInfoCount(Folder3 *iface, UINT *pctinfo)
1346 TRACE("(%p,%p)\n", iface, pctinfo);
1348 *pctinfo = 1;
1349 return S_OK;
1352 static HRESULT WINAPI FolderImpl_GetTypeInfo(Folder3 *iface, UINT iTInfo,
1353 LCID lcid, ITypeInfo **ppTInfo)
1355 HRESULT hr;
1357 TRACE("(%p,%u,%d,%p)\n", iface, iTInfo, lcid, ppTInfo);
1359 hr = get_typeinfo(Folder3_tid, ppTInfo);
1360 if (SUCCEEDED(hr))
1361 ITypeInfo_AddRef(*ppTInfo);
1363 return hr;
1366 static HRESULT WINAPI FolderImpl_GetIDsOfNames(Folder3 *iface, REFIID riid,
1367 LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
1369 ITypeInfo *ti;
1370 HRESULT hr;
1372 TRACE("(%p,%s,%p,%u,%d,%p)\n", iface, shdebugstr_guid(riid), rgszNames, cNames, lcid,
1373 rgDispId);
1375 hr = get_typeinfo(Folder3_tid, &ti);
1376 if (SUCCEEDED(hr))
1377 hr = ITypeInfo_GetIDsOfNames(ti, rgszNames, cNames, rgDispId);
1378 return hr;
1381 static HRESULT WINAPI FolderImpl_Invoke(Folder3 *iface, DISPID dispIdMember,
1382 REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
1383 VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
1385 FolderImpl *This = impl_from_Folder(iface);
1386 ITypeInfo *ti;
1387 HRESULT hr;
1389 TRACE("(%p,%d,%s,%d,%u,%p,%p,%p,%p)\n", iface, dispIdMember, shdebugstr_guid(riid), lcid,
1390 wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
1392 hr = get_typeinfo(Folder3_tid, &ti);
1393 if (SUCCEEDED(hr))
1394 hr = ITypeInfo_Invoke(ti, This, dispIdMember, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
1395 return hr;
1398 static HRESULT WINAPI FolderImpl_get_Title(Folder3 *iface, BSTR *pbs)
1400 FolderImpl *This = impl_from_Folder(iface);
1401 WCHAR *p;
1402 int len;
1404 TRACE("(%p,%p)\n", iface, pbs);
1406 *pbs = NULL;
1408 if (V_VT(&This->dir) == VT_I4)
1410 FIXME("special folder constants are not supported\n");
1411 return E_NOTIMPL;
1413 p = PathFindFileNameW(V_BSTR(&This->dir));
1414 len = lstrlenW(p);
1415 *pbs = SysAllocStringLen(p, p[len - 1] == '\\' ? len - 1 : len);
1416 return *pbs ? S_OK : E_OUTOFMEMORY;
1419 static HRESULT WINAPI FolderImpl_get_Application(Folder3 *iface,
1420 IDispatch **ppid)
1422 FIXME("(%p,%p)\n", iface, ppid);
1424 *ppid = NULL;
1425 return E_NOTIMPL;
1428 static HRESULT WINAPI FolderImpl_get_Parent(Folder3 *iface, IDispatch **ppid)
1430 FIXME("(%p,%p)\n", iface, ppid);
1432 *ppid = NULL;
1433 return E_NOTIMPL;
1436 static HRESULT WINAPI FolderImpl_get_ParentFolder(Folder3 *iface, Folder **ppsf)
1438 FIXME("(%p,%p)\n", iface, ppsf);
1440 *ppsf = NULL;
1441 return E_NOTIMPL;
1444 static HRESULT WINAPI FolderImpl_Items(Folder3 *iface, FolderItems **ppid)
1446 FolderImpl *This = impl_from_Folder(iface);
1448 TRACE("(%p,%p)\n", iface, ppid);
1450 return FolderItems_Constructor(&This->dir, ppid);
1453 static HRESULT WINAPI FolderImpl_ParseName(Folder3 *iface, BSTR name, FolderItem **item)
1455 FolderItem *self;
1456 BSTR str;
1457 WCHAR pathW[MAX_PATH];
1458 VARIANT v;
1459 HRESULT hr;
1461 TRACE("(%p,%s,%p)\n", iface, debugstr_w(name), item);
1463 *item = NULL;
1465 if (!name || !name[0])
1466 return S_FALSE;
1468 hr = Folder3_get_Self(iface, &self);
1469 if (FAILED(hr))
1470 return hr;
1472 hr = FolderItem_get_Path(self, &str);
1473 FolderItem_Release(self);
1475 PathCombineW(pathW, str, name);
1476 SysFreeString(str);
1478 if (!PathFileExistsW(pathW))
1479 return S_FALSE;
1481 V_VT(&v) = VT_BSTR;
1482 V_BSTR(&v) = SysAllocString(pathW);
1483 hr = FolderItem_Constructor(&v, item);
1484 VariantClear(&v);
1485 return hr;
1488 static HRESULT WINAPI FolderImpl_NewFolder(Folder3 *iface, BSTR bName,
1489 VARIANT vOptions)
1491 FIXME("(%p,%s)\n", iface, debugstr_w(bName));
1493 return E_NOTIMPL;
1496 static HRESULT WINAPI FolderImpl_MoveHere(Folder3 *iface, VARIANT vItem,
1497 VARIANT vOptions)
1499 FIXME("(%p)\n", iface);
1501 return E_NOTIMPL;
1504 static HRESULT WINAPI FolderImpl_CopyHere(Folder3 *iface, VARIANT vItem,
1505 VARIANT vOptions)
1507 FIXME("(%p)\n", iface);
1509 return E_NOTIMPL;
1512 static HRESULT WINAPI FolderImpl_GetDetailsOf(Folder3 *iface, VARIANT vItem,
1513 int iColumn, BSTR *pbs)
1515 FIXME("(%p,%d,%p)\n", iface, iColumn, pbs);
1517 *pbs = NULL;
1518 return E_NOTIMPL;
1521 static HRESULT WINAPI FolderImpl_get_Self(Folder3 *iface, FolderItem **ppfi)
1523 FolderImpl *This = impl_from_Folder(iface);
1525 TRACE("(%p,%p)\n", iface, ppfi);
1527 return FolderItem_Constructor(&This->dir, ppfi);
1530 static HRESULT WINAPI FolderImpl_get_OfflineStatus(Folder3 *iface, LONG *pul)
1532 FIXME("(%p,%p)\n", iface, pul);
1534 return E_NOTIMPL;
1537 static HRESULT WINAPI FolderImpl_Synchronize(Folder3 *iface)
1539 FIXME("(%p)\n", iface);
1541 return E_NOTIMPL;
1544 static HRESULT WINAPI FolderImpl_get_HaveToShowWebViewBarricade(Folder3 *iface,
1545 VARIANT_BOOL *pbHaveToShowWebViewBarricade)
1547 FIXME("(%p,%p)\n", iface, pbHaveToShowWebViewBarricade);
1549 return E_NOTIMPL;
1552 static HRESULT WINAPI FolderImpl_DismissedWebViewBarricade(Folder3 *iface)
1554 FIXME("(%p)\n", iface);
1556 return E_NOTIMPL;
1559 static HRESULT WINAPI FolderImpl_get_ShowWebViewBarricade(Folder3 *iface,
1560 VARIANT_BOOL *pbShowWebViewBarricade)
1562 FIXME("(%p,%p)\n", iface, pbShowWebViewBarricade);
1564 return E_NOTIMPL;
1567 static HRESULT WINAPI FolderImpl_put_ShowWebViewBarricade(Folder3 *iface,
1568 VARIANT_BOOL bShowWebViewBarricade)
1570 FIXME("(%p,%d)\n", iface, bShowWebViewBarricade);
1572 return E_NOTIMPL;
1575 static const Folder3Vtbl FolderImpl_Vtbl = {
1576 FolderImpl_QueryInterface,
1577 FolderImpl_AddRef,
1578 FolderImpl_Release,
1579 FolderImpl_GetTypeInfoCount,
1580 FolderImpl_GetTypeInfo,
1581 FolderImpl_GetIDsOfNames,
1582 FolderImpl_Invoke,
1583 FolderImpl_get_Title,
1584 FolderImpl_get_Application,
1585 FolderImpl_get_Parent,
1586 FolderImpl_get_ParentFolder,
1587 FolderImpl_Items,
1588 FolderImpl_ParseName,
1589 FolderImpl_NewFolder,
1590 FolderImpl_MoveHere,
1591 FolderImpl_CopyHere,
1592 FolderImpl_GetDetailsOf,
1593 FolderImpl_get_Self,
1594 FolderImpl_get_OfflineStatus,
1595 FolderImpl_Synchronize,
1596 FolderImpl_get_HaveToShowWebViewBarricade,
1597 FolderImpl_DismissedWebViewBarricade,
1598 FolderImpl_get_ShowWebViewBarricade,
1599 FolderImpl_put_ShowWebViewBarricade
1602 static HRESULT Folder_Constructor(VARIANT *dir, Folder **ppsdf)
1604 FolderImpl *This;
1605 HRESULT ret;
1607 *ppsdf = NULL;
1609 switch (V_VT(dir))
1611 case VT_I4:
1612 /* FIXME: add some checks */
1613 break;
1614 case VT_BSTR:
1615 if (PathIsDirectoryW(V_BSTR(dir)) &&
1616 !PathIsRelativeW(V_BSTR(dir)) &&
1617 PathFileExistsW(V_BSTR(dir)))
1618 break;
1619 default:
1620 return S_FALSE;
1623 This = HeapAlloc(GetProcessHeap(), 0, sizeof(FolderImpl));
1624 if (!This) return E_OUTOFMEMORY;
1625 This->Folder3_iface.lpVtbl = &FolderImpl_Vtbl;
1626 This->ref = 1;
1628 VariantInit(&This->dir);
1629 ret = VariantCopy(&This->dir, dir);
1630 if (FAILED(ret))
1632 HeapFree(GetProcessHeap(), 0, This);
1633 return E_OUTOFMEMORY;
1636 *ppsdf = (Folder*)&This->Folder3_iface;
1637 return ret;
1640 static HRESULT WINAPI ShellDispatch_QueryInterface(IShellDispatch6 *iface,
1641 REFIID riid, LPVOID *ppv)
1643 ShellDispatch *This = impl_from_IShellDispatch6(iface);
1645 TRACE("(%p,%s,%p)\n", iface, shdebugstr_guid(riid), ppv);
1647 if (!ppv) return E_INVALIDARG;
1649 if (IsEqualIID(&IID_IUnknown, riid) ||
1650 IsEqualIID(&IID_IDispatch, riid) ||
1651 IsEqualIID(&IID_IShellDispatch, riid) ||
1652 IsEqualIID(&IID_IShellDispatch2, riid) ||
1653 IsEqualIID(&IID_IShellDispatch3, riid) ||
1654 IsEqualIID(&IID_IShellDispatch4, riid) ||
1655 IsEqualIID(&IID_IShellDispatch5, riid) ||
1656 IsEqualIID(&IID_IShellDispatch6, riid))
1657 *ppv = &This->IShellDispatch6_iface;
1658 else
1660 FIXME("not implemented for %s\n", shdebugstr_guid(riid));
1661 *ppv = NULL;
1662 return E_NOINTERFACE;
1665 IShellDispatch6_AddRef(iface);
1666 return S_OK;
1669 static ULONG WINAPI ShellDispatch_AddRef(IShellDispatch6 *iface)
1671 ShellDispatch *This = impl_from_IShellDispatch6(iface);
1672 ULONG ref = InterlockedIncrement(&This->ref);
1674 TRACE("(%p), new refcount=%i\n", iface, ref);
1676 return ref;
1679 static ULONG WINAPI ShellDispatch_Release(IShellDispatch6 *iface)
1681 ShellDispatch *This = impl_from_IShellDispatch6(iface);
1682 ULONG ref = InterlockedDecrement(&This->ref);
1684 TRACE("(%p), new refcount=%i\n", iface, ref);
1686 if (!ref)
1687 HeapFree(GetProcessHeap(), 0, This);
1689 return ref;
1692 static HRESULT WINAPI ShellDispatch_GetTypeInfoCount(IShellDispatch6 *iface,
1693 UINT *pctinfo)
1695 TRACE("(%p,%p)\n", iface, pctinfo);
1697 *pctinfo = 1;
1698 return S_OK;
1701 static HRESULT WINAPI ShellDispatch_GetTypeInfo(IShellDispatch6 *iface,
1702 UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo)
1704 HRESULT hr;
1706 TRACE("(%p,%u,%d,%p)\n", iface, iTInfo, lcid, ppTInfo);
1708 hr = get_typeinfo(IShellDispatch6_tid, ppTInfo);
1709 if (SUCCEEDED(hr))
1710 ITypeInfo_AddRef(*ppTInfo);
1711 return hr;
1714 static HRESULT WINAPI ShellDispatch_GetIDsOfNames(IShellDispatch6 *iface,
1715 REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
1717 ITypeInfo *ti;
1718 HRESULT hr;
1720 TRACE("(%p,%s,%p,%u,%d,%p)\n", iface, shdebugstr_guid(riid), rgszNames, cNames, lcid,
1721 rgDispId);
1723 hr = get_typeinfo(IShellDispatch6_tid, &ti);
1724 if (SUCCEEDED(hr))
1725 hr = ITypeInfo_GetIDsOfNames(ti, rgszNames, cNames, rgDispId);
1726 return hr;
1729 static HRESULT WINAPI ShellDispatch_Invoke(IShellDispatch6 *iface,
1730 DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags,
1731 DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo,
1732 UINT *puArgErr)
1734 ShellDispatch *This = impl_from_IShellDispatch6(iface);
1735 ITypeInfo *ti;
1736 HRESULT hr;
1738 TRACE("(%p,%d,%s,%d,%u,%p,%p,%p,%p)\n", iface, dispIdMember, shdebugstr_guid(riid), lcid,
1739 wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
1741 hr = get_typeinfo(IShellDispatch6_tid, &ti);
1742 if (SUCCEEDED(hr))
1743 hr = ITypeInfo_Invoke(ti, &This->IShellDispatch6_iface, dispIdMember, wFlags, pDispParams,
1744 pVarResult, pExcepInfo, puArgErr);
1745 return hr;
1748 static HRESULT WINAPI ShellDispatch_get_Application(IShellDispatch6 *iface,
1749 IDispatch **ppid)
1751 FIXME("(%p,%p)\n", iface, ppid);
1753 *ppid = NULL;
1754 return E_NOTIMPL;
1757 static HRESULT WINAPI ShellDispatch_get_Parent(IShellDispatch6 *iface,
1758 IDispatch **ppid)
1760 FIXME("(%p,%p)\n", iface, ppid);
1762 *ppid = NULL;
1763 return E_NOTIMPL;
1766 static HRESULT WINAPI ShellDispatch_NameSpace(IShellDispatch6 *iface,
1767 VARIANT vDir, Folder **ppsdf)
1769 TRACE("(%p,%p)\n", iface, ppsdf);
1771 return Folder_Constructor(&vDir, ppsdf);
1774 static HRESULT WINAPI ShellDispatch_BrowseForFolder(IShellDispatch6 *iface,
1775 LONG Hwnd, BSTR Title, LONG Options, VARIANT RootFolder, Folder **ppsdf)
1777 FIXME("(%p,%x,%s,%x,%p)\n", iface, Hwnd, debugstr_w(Title), Options, ppsdf);
1779 *ppsdf = NULL;
1780 return E_NOTIMPL;
1783 static HRESULT WINAPI ShellDispatch_Windows(IShellDispatch6 *iface,
1784 IDispatch **ppid)
1786 FIXME("(%p,%p)\n", iface, ppid);
1788 *ppid = NULL;
1789 return E_NOTIMPL;
1792 static HRESULT WINAPI ShellDispatch_Open(IShellDispatch6 *iface, VARIANT vDir)
1794 FIXME("(%p)\n", iface);
1796 return E_NOTIMPL;
1799 static HRESULT WINAPI ShellDispatch_Explore(IShellDispatch6 *iface, VARIANT vDir)
1801 FIXME("(%p)\n", iface);
1803 return E_NOTIMPL;
1806 static HRESULT WINAPI ShellDispatch_MinimizeAll(IShellDispatch6 *iface)
1808 FIXME("(%p)\n", iface);
1810 return E_NOTIMPL;
1813 static HRESULT WINAPI ShellDispatch_UndoMinimizeALL(IShellDispatch6 *iface)
1815 FIXME("(%p)\n", iface);
1817 return E_NOTIMPL;
1820 static HRESULT WINAPI ShellDispatch_FileRun(IShellDispatch6 *iface)
1822 FIXME("(%p)\n", iface);
1824 return E_NOTIMPL;
1827 static HRESULT WINAPI ShellDispatch_CascadeWindows(IShellDispatch6 *iface)
1829 FIXME("(%p)\n", iface);
1831 return E_NOTIMPL;
1834 static HRESULT WINAPI ShellDispatch_TileVertically(IShellDispatch6 *iface)
1836 FIXME("(%p)\n", iface);
1838 return E_NOTIMPL;
1841 static HRESULT WINAPI ShellDispatch_TileHorizontally(IShellDispatch6 *iface)
1843 FIXME("(%p)\n", iface);
1845 return E_NOTIMPL;
1848 static HRESULT WINAPI ShellDispatch_ShutdownWindows(IShellDispatch6 *iface)
1850 FIXME("(%p)\n", iface);
1852 return E_NOTIMPL;
1855 static HRESULT WINAPI ShellDispatch_Suspend(IShellDispatch6 *iface)
1857 FIXME("(%p)\n", iface);
1859 return E_NOTIMPL;
1862 static HRESULT WINAPI ShellDispatch_EjectPC(IShellDispatch6 *iface)
1864 FIXME("(%p)\n", iface);
1866 return E_NOTIMPL;
1869 static HRESULT WINAPI ShellDispatch_SetTime(IShellDispatch6 *iface)
1871 FIXME("(%p)\n", iface);
1873 return E_NOTIMPL;
1876 static HRESULT WINAPI ShellDispatch_TrayProperties(IShellDispatch6 *iface)
1878 FIXME("(%p)\n", iface);
1880 return E_NOTIMPL;
1883 static HRESULT WINAPI ShellDispatch_Help(IShellDispatch6 *iface)
1885 FIXME("(%p)\n", iface);
1887 return E_NOTIMPL;
1890 static HRESULT WINAPI ShellDispatch_FindFiles(IShellDispatch6 *iface)
1892 FIXME("(%p)\n", iface);
1894 return E_NOTIMPL;
1897 static HRESULT WINAPI ShellDispatch_FindComputer(IShellDispatch6 *iface)
1899 FIXME("(%p)\n", iface);
1901 return E_NOTIMPL;
1904 static HRESULT WINAPI ShellDispatch_RefreshMenu(IShellDispatch6 *iface)
1906 FIXME("(%p)\n", iface);
1908 return E_NOTIMPL;
1911 static HRESULT WINAPI ShellDispatch_ControlPanelItem(IShellDispatch6 *iface,
1912 BSTR szDir)
1914 FIXME("(%p,%s)\n", iface, debugstr_w(szDir));
1916 return E_NOTIMPL;
1919 static HRESULT WINAPI ShellDispatch_IsRestricted(IShellDispatch6 *iface, BSTR group, BSTR restriction, LONG *value)
1921 FIXME("(%s, %s, %p): stub\n", debugstr_w(group), debugstr_w(restriction), value);
1922 return E_NOTIMPL;
1925 static HRESULT WINAPI ShellDispatch_ShellExecute(IShellDispatch6 *iface,
1926 BSTR file, VARIANT v_args, VARIANT v_dir, VARIANT v_op, VARIANT v_show)
1928 VARIANT args_str, dir_str, op_str, show_int;
1929 WCHAR *args = NULL, *dir = NULL, *op = NULL;
1930 INT show = 0;
1931 HINSTANCE ret;
1933 TRACE("(%s, %s, %s, %s, %s)\n", debugstr_w(file), debugstr_variant(&v_args),
1934 debugstr_variant(&v_dir), debugstr_variant(&v_op), debugstr_variant(&v_show));
1936 VariantInit(&args_str);
1937 VariantChangeType(&args_str, &v_args, 0, VT_BSTR);
1938 if (V_VT(&args_str) == VT_BSTR)
1939 args = V_BSTR(&args_str);
1941 VariantInit(&dir_str);
1942 VariantChangeType(&dir_str, &v_dir, 0, VT_BSTR);
1943 if (V_VT(&dir_str) == VT_BSTR)
1944 dir = V_BSTR(&dir_str);
1946 VariantInit(&op_str);
1947 VariantChangeType(&op_str, &v_op, 0, VT_BSTR);
1948 if (V_VT(&op_str) == VT_BSTR)
1949 op = V_BSTR(&op_str);
1951 VariantInit(&show_int);
1952 VariantChangeType(&show_int, &v_show, 0, VT_I4);
1953 if (V_VT(&show_int) == VT_I4)
1954 show = V_I4(&show_int);
1956 ret = ShellExecuteW(NULL, op, file, args, dir, show);
1958 VariantClear(&args_str);
1959 VariantClear(&dir_str);
1960 VariantClear(&op_str);
1961 VariantClear(&show_int);
1963 return (ULONG_PTR)ret > 32 ? S_OK : S_FALSE;
1966 static HRESULT WINAPI ShellDispatch_FindPrinter(IShellDispatch6 *iface, BSTR name, BSTR location, BSTR model)
1968 FIXME("(%s, %s, %s): stub\n", debugstr_w(name), debugstr_w(location), debugstr_w(model));
1969 return E_NOTIMPL;
1972 static HRESULT WINAPI ShellDispatch_GetSystemInformation(IShellDispatch6 *iface, BSTR name, VARIANT *ret)
1974 FIXME("(%s, %p): stub\n", debugstr_w(name), ret);
1975 return E_NOTIMPL;
1978 static HRESULT WINAPI ShellDispatch_ServiceStart(IShellDispatch6 *iface, BSTR service, VARIANT persistent, VARIANT *ret)
1980 FIXME("(%s, %p): stub\n", debugstr_w(service), ret);
1981 return E_NOTIMPL;
1984 static HRESULT WINAPI ShellDispatch_ServiceStop(IShellDispatch6 *iface, BSTR service, VARIANT persistent, VARIANT *ret)
1986 FIXME("(%s, %p): stub\n", debugstr_w(service), ret);
1987 return E_NOTIMPL;
1990 static HRESULT WINAPI ShellDispatch_IsServiceRunning(IShellDispatch6 *iface, BSTR name, VARIANT *running)
1992 SERVICE_STATUS_PROCESS status;
1993 SC_HANDLE scm, service;
1994 DWORD dummy;
1996 TRACE("(%s, %p)\n", debugstr_w(name), running);
1998 V_VT(running) = VT_BOOL;
1999 V_BOOL(running) = VARIANT_FALSE;
2001 scm = OpenSCManagerW(NULL, NULL, SC_MANAGER_CONNECT);
2002 if (!scm)
2004 ERR("failed to connect to service manager\n");
2005 return S_OK;
2008 service = OpenServiceW(scm, name, SERVICE_QUERY_STATUS);
2009 if (!service)
2011 ERR("Failed to open service %s (%u)\n", debugstr_w(name), GetLastError());
2012 CloseServiceHandle(scm);
2013 return S_OK;
2016 if (!QueryServiceStatusEx(service, SC_STATUS_PROCESS_INFO, (BYTE *)&status,
2017 sizeof(SERVICE_STATUS_PROCESS), &dummy))
2019 TRACE("failed to query service status (%u)\n", GetLastError());
2020 CloseServiceHandle(service);
2021 CloseServiceHandle(scm);
2022 return S_OK;
2025 if (status.dwCurrentState == SERVICE_RUNNING)
2026 V_BOOL(running) = VARIANT_TRUE;
2028 CloseServiceHandle(service);
2029 CloseServiceHandle(scm);
2031 return S_OK;
2034 static HRESULT WINAPI ShellDispatch_CanStartStopService(IShellDispatch6 *iface, BSTR service, VARIANT *ret)
2036 FIXME("(%s, %p): stub\n", debugstr_w(service), ret);
2037 return E_NOTIMPL;
2040 static HRESULT WINAPI ShellDispatch_ShowBrowserBar(IShellDispatch6 *iface, BSTR clsid, VARIANT show, VARIANT *ret)
2042 FIXME("(%s, %p): stub\n", debugstr_w(clsid), ret);
2043 return E_NOTIMPL;
2046 static HRESULT WINAPI ShellDispatch_AddToRecent(IShellDispatch6 *iface, VARIANT file, BSTR category)
2048 FIXME("(%s): stub\n", debugstr_w(category));
2049 return E_NOTIMPL;
2052 static HRESULT WINAPI ShellDispatch_WindowsSecurity(IShellDispatch6 *iface)
2054 FIXME("stub\n");
2055 return E_NOTIMPL;
2058 static HRESULT WINAPI ShellDispatch_ToggleDesktop(IShellDispatch6 *iface)
2060 FIXME("stub\n");
2061 return E_NOTIMPL;
2064 static HRESULT WINAPI ShellDispatch_ExplorerPolicy(IShellDispatch6 *iface, BSTR policy, VARIANT *value)
2066 FIXME("(%s, %p): stub\n", debugstr_w(policy), value);
2067 return E_NOTIMPL;
2070 static HRESULT WINAPI ShellDispatch_GetSetting(IShellDispatch6 *iface, LONG setting, VARIANT_BOOL *result)
2072 FIXME("(%d %p): stub\n", setting, result);
2073 return E_NOTIMPL;
2076 static HRESULT WINAPI ShellDispatch_WindowSwitcher(IShellDispatch6 *iface)
2078 FIXME("stub\n");
2079 return E_NOTIMPL;
2082 static HRESULT WINAPI ShellDispatch_SearchCommand(IShellDispatch6 *iface)
2084 FIXME("stub\n");
2085 return E_NOTIMPL;
2088 static const IShellDispatch6Vtbl ShellDispatchVtbl = {
2089 ShellDispatch_QueryInterface,
2090 ShellDispatch_AddRef,
2091 ShellDispatch_Release,
2092 ShellDispatch_GetTypeInfoCount,
2093 ShellDispatch_GetTypeInfo,
2094 ShellDispatch_GetIDsOfNames,
2095 ShellDispatch_Invoke,
2096 ShellDispatch_get_Application,
2097 ShellDispatch_get_Parent,
2098 ShellDispatch_NameSpace,
2099 ShellDispatch_BrowseForFolder,
2100 ShellDispatch_Windows,
2101 ShellDispatch_Open,
2102 ShellDispatch_Explore,
2103 ShellDispatch_MinimizeAll,
2104 ShellDispatch_UndoMinimizeALL,
2105 ShellDispatch_FileRun,
2106 ShellDispatch_CascadeWindows,
2107 ShellDispatch_TileVertically,
2108 ShellDispatch_TileHorizontally,
2109 ShellDispatch_ShutdownWindows,
2110 ShellDispatch_Suspend,
2111 ShellDispatch_EjectPC,
2112 ShellDispatch_SetTime,
2113 ShellDispatch_TrayProperties,
2114 ShellDispatch_Help,
2115 ShellDispatch_FindFiles,
2116 ShellDispatch_FindComputer,
2117 ShellDispatch_RefreshMenu,
2118 ShellDispatch_ControlPanelItem,
2119 ShellDispatch_IsRestricted,
2120 ShellDispatch_ShellExecute,
2121 ShellDispatch_FindPrinter,
2122 ShellDispatch_GetSystemInformation,
2123 ShellDispatch_ServiceStart,
2124 ShellDispatch_ServiceStop,
2125 ShellDispatch_IsServiceRunning,
2126 ShellDispatch_CanStartStopService,
2127 ShellDispatch_ShowBrowserBar,
2128 ShellDispatch_AddToRecent,
2129 ShellDispatch_WindowsSecurity,
2130 ShellDispatch_ToggleDesktop,
2131 ShellDispatch_ExplorerPolicy,
2132 ShellDispatch_GetSetting,
2133 ShellDispatch_WindowSwitcher,
2134 ShellDispatch_SearchCommand
2137 HRESULT WINAPI IShellDispatch_Constructor(IUnknown *outer, REFIID riid, void **ppv)
2139 ShellDispatch *This;
2140 HRESULT ret;
2142 TRACE("(%p, %s)\n", outer, debugstr_guid(riid));
2144 *ppv = NULL;
2146 if (outer) return CLASS_E_NOAGGREGATION;
2148 This = HeapAlloc(GetProcessHeap(), 0, sizeof(ShellDispatch));
2149 if (!This) return E_OUTOFMEMORY;
2150 This->IShellDispatch6_iface.lpVtbl = &ShellDispatchVtbl;
2151 This->ref = 1;
2153 ret = IShellDispatch6_QueryInterface(&This->IShellDispatch6_iface, riid, ppv);
2154 IShellDispatch6_Release(&This->IShellDispatch6_iface);
2155 return ret;