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
22 #include "wine/port.h"
37 #include "shell32_main.h"
40 #include "wine/debug.h"
42 WINE_DEFAULT_DEBUG_CHANNEL(shell
);
44 static ITypeLib
*typelib
;
45 static const IID
* const tid_ids
[] =
49 &IID_IShellFolderViewDual3
,
56 static ITypeInfo
*typeinfos
[LAST_tid
];
59 IShellDispatch6 IShellDispatch6_iface
;
64 Folder3 Folder3_iface
;
66 IDispatch
*application
;
67 IShellFolder2
*folder
;
68 PIDLIST_ABSOLUTE pidl
;
73 FolderItems3 FolderItems3_iface
;
81 FolderItem2 FolderItem2_iface
;
84 WCHAR
*path
; /* if NULL, folder path is used */
89 FolderItemVerbs FolderItemVerbs_iface
;
92 IContextMenu
*contextmenu
;
95 } FolderItemVerbsImpl
;
98 FolderItemVerb FolderItemVerb_iface
;
101 IContextMenu
*contextmenu
;
103 } FolderItemVerbImpl
;
105 static inline ShellDispatch
*impl_from_IShellDispatch6(IShellDispatch6
*iface
)
107 return CONTAINING_RECORD(iface
, ShellDispatch
, IShellDispatch6_iface
);
110 static inline FolderImpl
*impl_from_Folder(Folder3
*iface
)
112 return CONTAINING_RECORD(iface
, FolderImpl
, Folder3_iface
);
115 static inline FolderItemsImpl
*impl_from_FolderItems(FolderItems3
*iface
)
117 return CONTAINING_RECORD(iface
, FolderItemsImpl
, FolderItems3_iface
);
120 static inline FolderItemImpl
*impl_from_FolderItem(FolderItem2
*iface
)
122 return CONTAINING_RECORD(iface
, FolderItemImpl
, FolderItem2_iface
);
125 static inline FolderItemVerbsImpl
*impl_from_FolderItemVerbs(FolderItemVerbs
*iface
)
127 return CONTAINING_RECORD(iface
, FolderItemVerbsImpl
, FolderItemVerbs_iface
);
130 static inline FolderItemVerbImpl
*impl_from_FolderItemVerb(FolderItemVerb
*iface
)
132 return CONTAINING_RECORD(iface
, FolderItemVerbImpl
, FolderItemVerb_iface
);
135 static HRESULT
load_typelib(void)
140 hr
= LoadRegTypeLib(&LIBID_Shell32
, 1, 0, LOCALE_SYSTEM_DEFAULT
, &tl
);
142 ERR("LoadRegTypeLib failed: %08x\n", hr
);
146 if (InterlockedCompareExchangePointer((void**)&typelib
, tl
, NULL
))
147 ITypeLib_Release(tl
);
151 void release_typelib(void)
158 for (i
= 0; i
< sizeof(typeinfos
)/sizeof(*typeinfos
); i
++)
160 ITypeInfo_Release(typeinfos
[i
]);
162 ITypeLib_Release(typelib
);
165 HRESULT
get_typeinfo(enum tid_t tid
, ITypeInfo
**typeinfo
)
178 hr
= ITypeLib_GetTypeInfoOfGuid(typelib
, tid_ids
[tid
], &ti
);
181 ERR("GetTypeInfoOfGuid(%s) failed: %08x\n", debugstr_guid(tid_ids
[tid
]), hr
);
185 if (InterlockedCompareExchangePointer((void**)(typeinfos
+tid
), ti
, NULL
))
186 ITypeInfo_Release(ti
);
189 *typeinfo
= typeinfos
[tid
];
194 static HRESULT WINAPI
FolderItemVerbImpl_QueryInterface(FolderItemVerb
*iface
,
195 REFIID riid
, void **ppv
)
197 FolderItemVerbImpl
*This
= impl_from_FolderItemVerb(iface
);
199 TRACE("(%p,%s,%p)\n", iface
, debugstr_guid(riid
), ppv
);
201 if (IsEqualIID(&IID_IUnknown
, riid
) ||
202 IsEqualIID(&IID_IDispatch
, riid
) ||
203 IsEqualIID(&IID_FolderItemVerb
, riid
))
204 *ppv
= &This
->FolderItemVerb_iface
;
207 WARN("not implemented for %s\n", debugstr_guid(riid
));
209 return E_NOINTERFACE
;
212 IUnknown_AddRef((IUnknown
*)*ppv
);
216 static ULONG WINAPI
FolderItemVerbImpl_AddRef(FolderItemVerb
*iface
)
218 FolderItemVerbImpl
*This
= impl_from_FolderItemVerb(iface
);
219 ULONG ref
= InterlockedIncrement(&This
->ref
);
221 TRACE("(%p), new refcount=%i\n", iface
, ref
);
226 static ULONG WINAPI
FolderItemVerbImpl_Release(FolderItemVerb
*iface
)
228 FolderItemVerbImpl
*This
= impl_from_FolderItemVerb(iface
);
229 ULONG ref
= InterlockedDecrement(&This
->ref
);
231 TRACE("(%p), new refcount=%i\n", iface
, ref
);
235 IContextMenu_Release(This
->contextmenu
);
236 SysFreeString(This
->name
);
237 HeapFree(GetProcessHeap(), 0, This
);
243 static HRESULT WINAPI
FolderItemVerbImpl_GetTypeInfoCount(FolderItemVerb
*iface
, UINT
*pctinfo
)
245 TRACE("(%p,%p)\n", iface
, pctinfo
);
250 static HRESULT WINAPI
FolderItemVerbImpl_GetTypeInfo(FolderItemVerb
*iface
, UINT iTInfo
,
251 LCID lcid
, ITypeInfo
**ppTInfo
)
255 TRACE("(%p,%u,%d,%p)\n", iface
, iTInfo
, lcid
, ppTInfo
);
257 hr
= get_typeinfo(FolderItemVerb_tid
, ppTInfo
);
259 ITypeInfo_AddRef(*ppTInfo
);
263 static HRESULT WINAPI
FolderItemVerbImpl_GetIDsOfNames(FolderItemVerb
*iface
,
264 REFIID riid
, LPOLESTR
*rgszNames
, UINT cNames
, LCID lcid
, DISPID
*rgDispId
)
269 TRACE("(%p,%s,%p,%u,%d,%p)\n", iface
, shdebugstr_guid(riid
), rgszNames
, cNames
, lcid
,
272 hr
= get_typeinfo(FolderItemVerb_tid
, &ti
);
274 hr
= ITypeInfo_GetIDsOfNames(ti
, rgszNames
, cNames
, rgDispId
);
278 static HRESULT WINAPI
FolderItemVerbImpl_Invoke(FolderItemVerb
*iface
,
279 DISPID dispIdMember
, REFIID riid
, LCID lcid
, WORD wFlags
,
280 DISPPARAMS
*pDispParams
, VARIANT
*pVarResult
, EXCEPINFO
*pExcepInfo
,
286 TRACE("(%p,%d,%s,%d,%u,%p,%p,%p,%p)\n", iface
, dispIdMember
, shdebugstr_guid(riid
), lcid
,
287 wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
289 hr
= get_typeinfo(FolderItemVerb_tid
, &ti
);
291 hr
= ITypeInfo_Invoke(ti
, iface
, dispIdMember
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
295 static HRESULT WINAPI
FolderItemVerbImpl_get_Application(FolderItemVerb
*iface
, IDispatch
**disp
)
297 TRACE("(%p, %p)\n", iface
, disp
);
304 static HRESULT WINAPI
FolderItemVerbImpl_get_Parent(FolderItemVerb
*iface
, IDispatch
**disp
)
306 TRACE("(%p, %p)\n", iface
, disp
);
313 static HRESULT WINAPI
FolderItemVerbImpl_get_Name(FolderItemVerb
*iface
, BSTR
*name
)
315 FolderItemVerbImpl
*This
= impl_from_FolderItemVerb(iface
);
317 TRACE("(%p, %p)\n", iface
, name
);
319 *name
= SysAllocString(This
->name
);
320 return *name
? S_OK
: E_OUTOFMEMORY
;
323 static HRESULT WINAPI
FolderItemVerbImpl_DoIt(FolderItemVerb
*iface
)
325 FIXME("(%p)\n", iface
);
329 static FolderItemVerbVtbl folderitemverbvtbl
= {
330 FolderItemVerbImpl_QueryInterface
,
331 FolderItemVerbImpl_AddRef
,
332 FolderItemVerbImpl_Release
,
333 FolderItemVerbImpl_GetTypeInfoCount
,
334 FolderItemVerbImpl_GetTypeInfo
,
335 FolderItemVerbImpl_GetIDsOfNames
,
336 FolderItemVerbImpl_Invoke
,
337 FolderItemVerbImpl_get_Application
,
338 FolderItemVerbImpl_get_Parent
,
339 FolderItemVerbImpl_get_Name
,
340 FolderItemVerbImpl_DoIt
343 static HRESULT
FolderItemVerb_Constructor(IContextMenu
*contextmenu
, BSTR name
, FolderItemVerb
**verb
)
345 FolderItemVerbImpl
*This
;
347 TRACE("%p, %s\n", contextmenu
, debugstr_w(name
));
349 This
= HeapAlloc(GetProcessHeap(), 0, sizeof(FolderItemVerbImpl
));
351 return E_OUTOFMEMORY
;
353 This
->FolderItemVerb_iface
.lpVtbl
= &folderitemverbvtbl
;
355 This
->contextmenu
= contextmenu
;
356 IContextMenu_AddRef(contextmenu
);
359 *verb
= &This
->FolderItemVerb_iface
;
363 /* FolderItemVerbs */
364 static HRESULT WINAPI
FolderItemVerbsImpl_QueryInterface(FolderItemVerbs
*iface
,
365 REFIID riid
, void **ppv
)
367 FolderItemVerbsImpl
*This
= impl_from_FolderItemVerbs(iface
);
369 TRACE("(%p,%s,%p)\n", iface
, debugstr_guid(riid
), ppv
);
371 if (IsEqualIID(&IID_IUnknown
, riid
) ||
372 IsEqualIID(&IID_IDispatch
, riid
) ||
373 IsEqualIID(&IID_FolderItemVerbs
, riid
))
374 *ppv
= &This
->FolderItemVerbs_iface
;
377 WARN("not implemented for %s\n", debugstr_guid(riid
));
379 return E_NOINTERFACE
;
382 IUnknown_AddRef((IUnknown
*)*ppv
);
386 static ULONG WINAPI
FolderItemVerbsImpl_AddRef(FolderItemVerbs
*iface
)
388 FolderItemVerbsImpl
*This
= impl_from_FolderItemVerbs(iface
);
389 ULONG ref
= InterlockedIncrement(&This
->ref
);
391 TRACE("(%p), new refcount=%i\n", iface
, ref
);
396 static ULONG WINAPI
FolderItemVerbsImpl_Release(FolderItemVerbs
*iface
)
398 FolderItemVerbsImpl
*This
= impl_from_FolderItemVerbs(iface
);
399 ULONG ref
= InterlockedDecrement(&This
->ref
);
401 TRACE("(%p), new refcount=%i\n", iface
, ref
);
405 IContextMenu_Release(This
->contextmenu
);
406 DestroyMenu(This
->hMenu
);
407 HeapFree(GetProcessHeap(), 0, This
);
413 static HRESULT WINAPI
FolderItemVerbsImpl_GetTypeInfoCount(FolderItemVerbs
*iface
, UINT
*pctinfo
)
415 TRACE("(%p,%p)\n", iface
, pctinfo
);
420 static HRESULT WINAPI
FolderItemVerbsImpl_GetTypeInfo(FolderItemVerbs
*iface
, UINT iTInfo
,
421 LCID lcid
, ITypeInfo
**ppTInfo
)
425 TRACE("(%p,%u,%d,%p)\n", iface
, iTInfo
, lcid
, ppTInfo
);
427 hr
= get_typeinfo(FolderItemVerbs_tid
, ppTInfo
);
429 ITypeInfo_AddRef(*ppTInfo
);
433 static HRESULT WINAPI
FolderItemVerbsImpl_GetIDsOfNames(FolderItemVerbs
*iface
,
434 REFIID riid
, LPOLESTR
*rgszNames
, UINT cNames
, LCID lcid
, DISPID
*rgDispId
)
439 TRACE("(%p,%s,%p,%u,%d,%p)\n", iface
, shdebugstr_guid(riid
), rgszNames
, cNames
, lcid
,
442 hr
= get_typeinfo(FolderItemVerbs_tid
, &ti
);
444 hr
= ITypeInfo_GetIDsOfNames(ti
, rgszNames
, cNames
, rgDispId
);
448 static HRESULT WINAPI
FolderItemVerbsImpl_Invoke(FolderItemVerbs
*iface
,
449 DISPID dispIdMember
, REFIID riid
, LCID lcid
, WORD wFlags
,
450 DISPPARAMS
*pDispParams
, VARIANT
*pVarResult
, EXCEPINFO
*pExcepInfo
,
456 TRACE("(%p,%d,%s,%d,%u,%p,%p,%p,%p)\n", iface
, dispIdMember
, shdebugstr_guid(riid
), lcid
,
457 wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
459 hr
= get_typeinfo(FolderItemVerbs_tid
, &ti
);
461 hr
= ITypeInfo_Invoke(ti
, iface
, dispIdMember
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
465 static HRESULT WINAPI
FolderItemVerbsImpl_get_Count(FolderItemVerbs
*iface
, LONG
*count
)
467 FolderItemVerbsImpl
*This
= impl_from_FolderItemVerbs(iface
);
469 TRACE("(%p, %p)\n", iface
, count
);
474 *count
= This
->count
;
478 static HRESULT WINAPI
FolderItemVerbsImpl_get_Application(FolderItemVerbs
*iface
, IDispatch
**disp
)
480 TRACE("(%p, %p)\n", iface
, disp
);
487 static HRESULT WINAPI
FolderItemVerbsImpl_get_Parent(FolderItemVerbs
*iface
, IDispatch
**disp
)
489 TRACE("(%p, %p)\n", iface
, disp
);
496 static HRESULT WINAPI
FolderItemVerbsImpl_Item(FolderItemVerbs
*iface
, VARIANT index
, FolderItemVerb
**verb
)
498 FolderItemVerbsImpl
*This
= impl_from_FolderItemVerbs(iface
);
504 TRACE("(%p, %s, %p)\n", iface
, debugstr_variant(&index
), verb
);
512 VariantCopyInd(&v
, &index
);
514 hr
= VariantChangeType(&v
, &v
, 0, VT_I4
);
517 FIXME("failed to coerce to VT_I4, %s\n", debugstr_variant(&v
));
521 if (V_I4(&v
) > This
->count
)
524 if (V_I4(&v
) == This
->count
)
525 name
= SysAllocStringLen(NULL
, 0);
529 memset(&info
, 0, sizeof(info
));
530 info
.cbSize
= sizeof(info
);
531 info
.fMask
= MIIM_STRING
;
532 if (!GetMenuItemInfoW(This
->hMenu
, V_I4(&v
), TRUE
, &info
))
535 name
= SysAllocStringLen(NULL
, info
.cch
);
538 info
.dwTypeData
= name
;
540 GetMenuItemInfoW(This
->hMenu
, V_I4(&v
), TRUE
, &info
);
545 return E_OUTOFMEMORY
;
547 return FolderItemVerb_Constructor(This
->contextmenu
, name
, verb
);
550 static HRESULT WINAPI
FolderItemVerbsImpl__NewEnum(FolderItemVerbs
*iface
, IUnknown
**ret
)
552 FIXME("(%p, %p)\n", iface
, ret
);
556 static FolderItemVerbsVtbl folderitemverbsvtbl
= {
557 FolderItemVerbsImpl_QueryInterface
,
558 FolderItemVerbsImpl_AddRef
,
559 FolderItemVerbsImpl_Release
,
560 FolderItemVerbsImpl_GetTypeInfoCount
,
561 FolderItemVerbsImpl_GetTypeInfo
,
562 FolderItemVerbsImpl_GetIDsOfNames
,
563 FolderItemVerbsImpl_Invoke
,
564 FolderItemVerbsImpl_get_Count
,
565 FolderItemVerbsImpl_get_Application
,
566 FolderItemVerbsImpl_get_Parent
,
567 FolderItemVerbsImpl_Item
,
568 FolderItemVerbsImpl__NewEnum
571 static HRESULT
FolderItemVerbs_Constructor(BSTR path
, FolderItemVerbs
**verbs
)
573 FolderItemVerbsImpl
*This
;
574 IShellFolder
*folder
;
581 This
= HeapAlloc(GetProcessHeap(), 0, sizeof(FolderItemVerbsImpl
));
583 return E_OUTOFMEMORY
;
585 This
->FolderItemVerbs_iface
.lpVtbl
= &folderitemverbsvtbl
;
588 /* build context menu for this path */
589 hr
= SHParseDisplayName(path
, NULL
, &pidl
, 0, NULL
);
593 hr
= SHBindToParent(pidl
, &IID_IShellFolder
, (void**)&folder
, &child
);
598 hr
= IShellFolder_GetUIObjectOf(folder
, NULL
, 1, &child
, &IID_IContextMenu
, NULL
, (void**)&This
->contextmenu
);
599 IShellFolder_Release(folder
);
603 This
->hMenu
= CreatePopupMenu();
604 hr
= IContextMenu_QueryContextMenu(This
->contextmenu
, This
->hMenu
, 0, FCIDM_SHVIEWFIRST
, FCIDM_SHVIEWLAST
, CMF_NORMAL
);
607 FolderItemVerbs_Release(&This
->FolderItemVerbs_iface
);
611 This
->count
= GetMenuItemCount(This
->hMenu
);
612 *verbs
= &This
->FolderItemVerbs_iface
;
616 HeapFree(GetProcessHeap(), 0, This
);
620 static HRESULT WINAPI
FolderItemImpl_QueryInterface(FolderItem2
*iface
,
621 REFIID riid
, LPVOID
*ppv
)
623 FolderItemImpl
*This
= impl_from_FolderItem(iface
);
625 TRACE("(%p,%s,%p)\n", iface
, debugstr_guid(riid
), ppv
);
627 if (!ppv
) return E_INVALIDARG
;
629 if (IsEqualIID(&IID_IUnknown
, riid
) ||
630 IsEqualIID(&IID_IDispatch
, riid
) ||
631 IsEqualIID(&IID_FolderItem
, riid
) ||
632 IsEqualIID(&IID_FolderItem2
, riid
))
633 *ppv
= &This
->FolderItem2_iface
;
636 WARN("not implemented for %s\n", debugstr_guid(riid
));
638 return E_NOINTERFACE
;
640 IUnknown_AddRef((IUnknown
*)*ppv
);
644 static ULONG WINAPI
FolderItemImpl_AddRef(FolderItem2
*iface
)
646 FolderItemImpl
*This
= impl_from_FolderItem(iface
);
647 ULONG ref
= InterlockedIncrement(&This
->ref
);
649 TRACE("(%p), new refcount=%i\n", iface
, ref
);
654 static ULONG WINAPI
FolderItemImpl_Release(FolderItem2
*iface
)
656 FolderItemImpl
*This
= impl_from_FolderItem(iface
);
657 ULONG ref
= InterlockedDecrement(&This
->ref
);
659 TRACE("(%p), new refcount=%i\n", iface
, ref
);
663 Folder3_Release(&This
->folder
->Folder3_iface
);
664 HeapFree(GetProcessHeap(), 0, This
->path
);
665 HeapFree(GetProcessHeap(), 0, This
);
670 static HRESULT WINAPI
FolderItemImpl_GetTypeInfoCount(FolderItem2
*iface
,
673 TRACE("(%p,%p)\n", iface
, pctinfo
);
679 static HRESULT WINAPI
FolderItemImpl_GetTypeInfo(FolderItem2
*iface
, UINT iTInfo
,
680 LCID lcid
, ITypeInfo
**ppTInfo
)
684 TRACE("(%p,%u,%d,%p)\n", iface
, iTInfo
, lcid
, ppTInfo
);
686 hr
= get_typeinfo(FolderItem2_tid
, ppTInfo
);
688 ITypeInfo_AddRef(*ppTInfo
);
692 static HRESULT WINAPI
FolderItemImpl_GetIDsOfNames(FolderItem2
*iface
,
693 REFIID riid
, LPOLESTR
*rgszNames
, UINT cNames
, LCID lcid
,
699 TRACE("(%p,%s,%p,%u,%d,%p)\n", iface
, shdebugstr_guid(riid
), rgszNames
, cNames
, lcid
,
702 hr
= get_typeinfo(FolderItem2_tid
, &ti
);
704 hr
= ITypeInfo_GetIDsOfNames(ti
, rgszNames
, cNames
, rgDispId
);
708 static HRESULT WINAPI
FolderItemImpl_Invoke(FolderItem2
*iface
,
709 DISPID dispIdMember
, REFIID riid
, LCID lcid
, WORD wFlags
,
710 DISPPARAMS
*pDispParams
, VARIANT
*pVarResult
, EXCEPINFO
*pExcepInfo
,
713 FolderItemImpl
*This
= impl_from_FolderItem(iface
);
717 TRACE("(%p,%d,%s,%d,%u,%p,%p,%p,%p)\n", iface
, dispIdMember
, shdebugstr_guid(riid
), lcid
,
718 wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
720 hr
= get_typeinfo(FolderItem2_tid
, &ti
);
722 hr
= ITypeInfo_Invoke(ti
, This
, dispIdMember
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
726 static HRESULT WINAPI
FolderItemImpl_get_Application(FolderItem2
*iface
, IDispatch
**disp
)
728 FolderItemImpl
*This
= impl_from_FolderItem(iface
);
730 TRACE("(%p,%p)\n", iface
, disp
);
732 return Folder3_get_Application(&This
->folder
->Folder3_iface
, disp
);
735 static HRESULT WINAPI
FolderItemImpl_get_Parent(FolderItem2
*iface
, IDispatch
**disp
)
737 FolderItemImpl
*This
= impl_from_FolderItem(iface
);
739 TRACE("(%p,%p)\n", iface
, disp
);
743 *disp
= (IDispatch
*)&This
->folder
->Folder3_iface
;
744 IDispatch_AddRef(*disp
);
750 static HRESULT WINAPI
FolderItemImpl_get_Name(FolderItem2
*iface
, BSTR
*name
)
752 FolderItemImpl
*This
= impl_from_FolderItem(iface
);
753 LPCITEMIDLIST last_part
;
754 IShellFolder2
*parent
;
759 TRACE("(%p,%p)\n", iface
, name
);
764 hr
= SHParseDisplayName(This
->path
, NULL
, &pidl
, 0, NULL
);
766 pidl
= This
->folder
->pidl
;
771 hr
= SHBindToParent(pidl
, &IID_IShellFolder2
, (void **)&parent
, &last_part
);
773 hr
= IShellFolder2_GetDisplayNameOf(parent
, last_part
, SHGDN_INFOLDER
, &strret
);
775 IShellFolder2_Release(parent
);
778 hr
= StrRetToBSTR(&strret
, last_part
, name
);
786 static HRESULT WINAPI
FolderItemImpl_put_Name(FolderItem2
*iface
, BSTR bs
)
788 FIXME("(%p,%s)\n", iface
, debugstr_w(bs
));
793 static HRESULT WINAPI
FolderItemImpl_get_Path(FolderItem2
*iface
, BSTR
*path
)
795 FolderItemImpl
*This
= impl_from_FolderItem(iface
);
797 TRACE("(%p,%p)\n", iface
, path
);
799 *path
= SysAllocString(This
->path
? This
->path
: This
->folder
->path
);
800 return *path
? S_OK
: E_OUTOFMEMORY
;
803 static HRESULT WINAPI
FolderItemImpl_get_GetLink(FolderItem2
*iface
,
806 FIXME("(%p,%p)\n", iface
, ppid
);
812 static HRESULT WINAPI
FolderItemImpl_get_GetFolder(FolderItem2
*iface
,
815 FIXME("(%p,%p)\n", iface
, ppid
);
821 static HRESULT WINAPI
FolderItemImpl_get_IsLink(FolderItem2
*iface
, VARIANT_BOOL
*b
)
823 FolderItemImpl
*This
= impl_from_FolderItem(iface
);
825 TRACE("(%p,%p)\n", iface
, b
);
827 *b
= This
->attributes
& SFGAO_LINK
? VARIANT_TRUE
: VARIANT_FALSE
;
832 static HRESULT WINAPI
FolderItemImpl_get_IsFolder(FolderItem2
*iface
, VARIANT_BOOL
*b
)
834 FolderItemImpl
*This
= impl_from_FolderItem(iface
);
836 TRACE("(%p,%p)\n", iface
, b
);
838 *b
= This
->attributes
& SFGAO_FOLDER
? VARIANT_TRUE
: VARIANT_FALSE
;
843 static HRESULT WINAPI
FolderItemImpl_get_IsFileSystem(FolderItem2
*iface
, VARIANT_BOOL
*b
)
845 FolderItemImpl
*This
= impl_from_FolderItem(iface
);
847 TRACE("(%p,%p)\n", iface
, b
);
849 *b
= This
->attributes
& SFGAO_FILESYSTEM
? VARIANT_TRUE
: VARIANT_FALSE
;
854 static HRESULT WINAPI
FolderItemImpl_get_IsBrowsable(FolderItem2
*iface
, VARIANT_BOOL
*b
)
856 FolderItemImpl
*This
= impl_from_FolderItem(iface
);
858 TRACE("(%p,%p)\n", iface
, b
);
860 *b
= This
->attributes
& SFGAO_BROWSABLE
? VARIANT_TRUE
: VARIANT_FALSE
;
865 static HRESULT WINAPI
FolderItemImpl_get_ModifyDate(FolderItem2
*iface
,
868 FIXME("(%p,%p)\n", iface
, pdt
);
873 static HRESULT WINAPI
FolderItemImpl_put_ModifyDate(FolderItem2
*iface
, DATE dt
)
875 FIXME("(%p,%f)\n", iface
, dt
);
880 static HRESULT WINAPI
FolderItemImpl_get_Size(FolderItem2
*iface
, LONG
*pul
)
882 FIXME("(%p,%p)\n", iface
, pul
);
887 static HRESULT WINAPI
FolderItemImpl_get_Type(FolderItem2
*iface
, BSTR
*pbs
)
889 FIXME("(%p,%p)\n", iface
, pbs
);
895 static HRESULT WINAPI
FolderItemImpl_Verbs(FolderItem2
*iface
, FolderItemVerbs
**verbs
)
897 FolderItemImpl
*This
= impl_from_FolderItem(iface
);
899 TRACE("(%p, %p)\n", iface
, verbs
);
904 return FolderItemVerbs_Constructor(This
->path
? This
->path
: This
->folder
->path
, verbs
);
907 static HRESULT WINAPI
FolderItemImpl_InvokeVerb(FolderItem2
*iface
,
910 FIXME("(%p)\n", iface
);
915 static HRESULT WINAPI
FolderItemImpl_InvokeVerbEx(FolderItem2
*iface
, VARIANT verb
, VARIANT args
)
917 FIXME("(%p): stub\n", iface
);
922 static HRESULT WINAPI
FolderItemImpl_ExtendedProperty(FolderItem2
*iface
, BSTR propname
, VARIANT
*ret
)
924 FIXME("(%p)->(%s %p): stub\n", iface
, debugstr_w(propname
), ret
);
929 static const FolderItem2Vtbl FolderItemImpl_Vtbl
= {
930 FolderItemImpl_QueryInterface
,
931 FolderItemImpl_AddRef
,
932 FolderItemImpl_Release
,
933 FolderItemImpl_GetTypeInfoCount
,
934 FolderItemImpl_GetTypeInfo
,
935 FolderItemImpl_GetIDsOfNames
,
936 FolderItemImpl_Invoke
,
937 FolderItemImpl_get_Application
,
938 FolderItemImpl_get_Parent
,
939 FolderItemImpl_get_Name
,
940 FolderItemImpl_put_Name
,
941 FolderItemImpl_get_Path
,
942 FolderItemImpl_get_GetLink
,
943 FolderItemImpl_get_GetFolder
,
944 FolderItemImpl_get_IsLink
,
945 FolderItemImpl_get_IsFolder
,
946 FolderItemImpl_get_IsFileSystem
,
947 FolderItemImpl_get_IsBrowsable
,
948 FolderItemImpl_get_ModifyDate
,
949 FolderItemImpl_put_ModifyDate
,
950 FolderItemImpl_get_Size
,
951 FolderItemImpl_get_Type
,
952 FolderItemImpl_Verbs
,
953 FolderItemImpl_InvokeVerb
,
954 FolderItemImpl_InvokeVerbEx
,
955 FolderItemImpl_ExtendedProperty
958 static HRESULT
FolderItem_Constructor(FolderImpl
*folder
, const WCHAR
*path
, FolderItem
**item
)
960 PIDLIST_ABSOLUTE pidl
;
961 FolderItemImpl
*This
;
963 TRACE("%s\n", debugstr_w(path
));
967 This
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*This
));
969 return E_OUTOFMEMORY
;
971 This
->FolderItem2_iface
.lpVtbl
= &FolderItemImpl_Vtbl
;
974 This
->path
= strdupW(path
);
976 This
->folder
= folder
;
977 Folder3_AddRef(&folder
->Folder3_iface
);
979 if (SHParseDisplayName(This
->path
, NULL
, &pidl
, ~0u, &This
->attributes
) == S_OK
)
982 *item
= (FolderItem
*)&This
->FolderItem2_iface
;
986 static HRESULT WINAPI
FolderItemsImpl_QueryInterface(FolderItems3
*iface
,
987 REFIID riid
, LPVOID
*ppv
)
989 FolderItemsImpl
*This
= impl_from_FolderItems(iface
);
991 TRACE("(%p,%s,%p)\n", iface
, debugstr_guid(riid
), ppv
);
993 if (!ppv
) return E_INVALIDARG
;
995 if (IsEqualIID(&IID_IUnknown
, riid
) ||
996 IsEqualIID(&IID_IDispatch
, riid
) ||
997 IsEqualIID(&IID_FolderItems
, riid
) ||
998 IsEqualIID(&IID_FolderItems2
, riid
) ||
999 IsEqualIID(&IID_FolderItems3
, riid
))
1000 *ppv
= &This
->FolderItems3_iface
;
1003 WARN("not implemented for %s\n", debugstr_guid(riid
));
1005 return E_NOINTERFACE
;
1007 IUnknown_AddRef((IUnknown
*)*ppv
);
1011 static ULONG WINAPI
FolderItemsImpl_AddRef(FolderItems3
*iface
)
1013 FolderItemsImpl
*This
= impl_from_FolderItems(iface
);
1014 ULONG ref
= InterlockedIncrement(&This
->ref
);
1016 TRACE("(%p), new refcount=%i\n", iface
, ref
);
1021 static ULONG WINAPI
FolderItemsImpl_Release(FolderItems3
*iface
)
1023 FolderItemsImpl
*This
= impl_from_FolderItems(iface
);
1024 ULONG ref
= InterlockedDecrement(&This
->ref
);
1027 TRACE("(%p), new refcount=%i\n", iface
, ref
);
1031 Folder3_Release(&This
->folder
->Folder3_iface
);
1032 for (i
= 0; i
< This
->item_count
; i
++)
1033 SysFreeString(This
->item_names
[i
]);
1034 HeapFree(GetProcessHeap(), 0, This
->item_names
);
1035 HeapFree(GetProcessHeap(), 0, This
);
1040 static HRESULT WINAPI
FolderItemsImpl_GetTypeInfoCount(FolderItems3
*iface
,
1043 TRACE("(%p,%p)\n", iface
, count
);
1049 static HRESULT WINAPI
FolderItemsImpl_GetTypeInfo(FolderItems3
*iface
,
1050 UINT type
, LCID lcid
, ITypeInfo
**ppti
)
1054 TRACE("(%p,%u,%d,%p)\n", iface
, type
, lcid
, ppti
);
1056 hr
= get_typeinfo(FolderItems3_tid
, ppti
);
1058 ITypeInfo_AddRef(*ppti
);
1062 static HRESULT WINAPI
FolderItemsImpl_GetIDsOfNames(FolderItems3
*iface
,
1063 REFIID riid
, LPOLESTR
*names
, UINT count
, LCID lcid
, DISPID
*dispid
)
1068 TRACE("(%p,%s,%p,%u,%d,%p)\n", iface
, shdebugstr_guid(riid
), names
, count
, lcid
, dispid
);
1070 hr
= get_typeinfo(FolderItems3_tid
, &ti
);
1072 hr
= ITypeInfo_GetIDsOfNames(ti
, names
, count
, dispid
);
1076 static HRESULT WINAPI
FolderItemsImpl_Invoke(FolderItems3
*iface
,
1077 DISPID dispid
, REFIID riid
, LCID lcid
, WORD flags
, DISPPARAMS
*params
,
1078 VARIANT
*result
, EXCEPINFO
*ei
, UINT
*err
)
1080 FolderItemsImpl
*This
= impl_from_FolderItems(iface
);
1084 TRACE("(%p,%d,%s,%d,%u,%p,%p,%p,%p)\n", iface
, dispid
, shdebugstr_guid(riid
), lcid
, flags
, params
, result
, ei
, err
);
1086 hr
= get_typeinfo(FolderItems3_tid
, &ti
);
1088 hr
= ITypeInfo_Invoke(ti
, This
, dispid
, flags
, params
, result
, ei
, err
);
1092 static BOOL
shellfolder_exists(const WCHAR
*path
)
1094 PIDLIST_ABSOLUTE pidl
= NULL
;
1097 hr
= SHParseDisplayName(path
, NULL
, &pidl
, 0, NULL
);
1100 return SUCCEEDED(hr
);
1103 static HRESULT WINAPI
FolderItemsImpl_get_Count(FolderItems3
*iface
, LONG
*count
)
1105 FolderItemsImpl
*This
= impl_from_FolderItems(iface
);
1107 TRACE("(%p,%p)\n", iface
, count
);
1109 *count
= shellfolder_exists(This
->folder
->path
) ? This
->item_count
: 0;
1113 static HRESULT WINAPI
FolderItemsImpl_get_Application(FolderItems3
*iface
, IDispatch
**disp
)
1115 FolderItemsImpl
*This
= impl_from_FolderItems(iface
);
1117 TRACE("(%p,%p)\n", iface
, disp
);
1119 return Folder3_get_Application(&This
->folder
->Folder3_iface
, disp
);
1122 static HRESULT WINAPI
FolderItemsImpl_get_Parent(FolderItems3
*iface
, IDispatch
**ppid
)
1124 TRACE("(%p,%p)\n", iface
, ppid
);
1132 static HRESULT WINAPI
FolderItemsImpl_Item(FolderItems3
*iface
, VARIANT index
, FolderItem
**item
)
1134 FolderItemsImpl
*This
= impl_from_FolderItems(iface
);
1135 BSTR display_name
= NULL
;
1138 TRACE("(%p,%s,%p)\n", iface
, debugstr_variant(&index
), item
);
1142 if (!shellfolder_exists(This
->folder
->path
))
1145 switch (V_VT(&index
))
1148 VariantChangeType(&index
, &index
, 0, VT_I4
);
1152 if (V_I4(&index
) >= This
->item_count
|| V_I4(&index
) < 0)
1155 display_name
= SysAllocString(This
->item_names
[V_I4(&index
)]);
1163 if (!V_BSTR(&index
))
1166 if (FAILED(hr
= IShellFolder2_ParseDisplayName(This
->folder
->folder
, NULL
, NULL
, V_BSTR(&index
),
1167 NULL
, &pidl
, NULL
)))
1170 if (IShellFolder2_GetDisplayNameOf(This
->folder
->folder
, pidl
, SHGDN_FORPARSING
, &strret
) == S_OK
)
1171 StrRetToBSTR(&strret
, pidl
, &display_name
);
1179 FIXME("Index type %d not handled.\n", V_VT(&index
));
1185 hr
= FolderItem_Constructor(This
->folder
, display_name
, item
);
1186 SysFreeString(display_name
);
1190 static HRESULT WINAPI
FolderItemsImpl__NewEnum(FolderItems3
*iface
, IUnknown
**ppunk
)
1192 FIXME("(%p,%p)\n", iface
, ppunk
);
1195 return E_INVALIDARG
;
1201 static HRESULT WINAPI
FolderItemsImpl_InvokeVerbEx(FolderItems3
*iface
, VARIANT verb
, VARIANT args
)
1203 FIXME("(%p,%s,%s)\n", iface
, debugstr_variant(&verb
), debugstr_variant(&args
));
1208 static HRESULT WINAPI
FolderItemsImpl_Filter(FolderItems3
*iface
, LONG flags
, BSTR spec
)
1210 FIXME("(%p,%d,%s)\n", iface
, flags
, wine_dbgstr_w(spec
));
1215 static HRESULT WINAPI
FolderItemsImpl_get_Verbs(FolderItems3
*iface
, FolderItemVerbs
**ppfic
)
1217 FIXME("(%p,%p)\n", iface
, ppfic
);
1220 return E_INVALIDARG
;
1226 static const FolderItems3Vtbl FolderItemsImpl_Vtbl
= {
1227 FolderItemsImpl_QueryInterface
,
1228 FolderItemsImpl_AddRef
,
1229 FolderItemsImpl_Release
,
1230 FolderItemsImpl_GetTypeInfoCount
,
1231 FolderItemsImpl_GetTypeInfo
,
1232 FolderItemsImpl_GetIDsOfNames
,
1233 FolderItemsImpl_Invoke
,
1234 FolderItemsImpl_get_Count
,
1235 FolderItemsImpl_get_Application
,
1236 FolderItemsImpl_get_Parent
,
1237 FolderItemsImpl_Item
,
1238 FolderItemsImpl__NewEnum
,
1239 FolderItemsImpl_InvokeVerbEx
,
1240 FolderItemsImpl_Filter
,
1241 FolderItemsImpl_get_Verbs
1244 static void idlist_sort(LPITEMIDLIST
*idlist
, unsigned int l
, unsigned int r
, IShellFolder2
*folder
)
1253 idlist_sort(idlist
, r
, l
, folder
);
1258 idlist_sort(idlist
, l
, m
, folder
);
1259 idlist_sort(idlist
, m
+ 1, r
, folder
);
1261 /* join the two sides */
1262 while (l
<= m
&& m
< r
)
1264 if ((short)IShellFolder2_CompareIDs(folder
, 0, idlist
[l
], idlist
[m
+ 1]) > 0)
1266 LPITEMIDLIST t
= idlist
[m
+ 1];
1267 memmove(&idlist
[l
+ 1], &idlist
[l
], (m
- l
+ 1) * sizeof(idlist
[l
]));
1276 static HRESULT
FolderItems_Constructor(FolderImpl
*folder
, FolderItems
**ret
)
1278 IEnumIDList
*enumidlist
;
1279 FolderItemsImpl
*This
;
1284 TRACE("(%s,%p)\n", debugstr_w(folder
->path
), ret
);
1288 This
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*This
));
1290 return E_OUTOFMEMORY
;
1292 This
->FolderItems3_iface
.lpVtbl
= &FolderItemsImpl_Vtbl
;
1294 This
->folder
= folder
;
1295 Folder3_AddRef(&folder
->Folder3_iface
);
1298 if (FAILED(hr
= IShellFolder2_EnumObjects(folder
->folder
, NULL
, SHCONTF_FOLDERS
| SHCONTF_NONFOLDERS
,
1304 while (IEnumIDList_Next(enumidlist
, 1, &pidl
, NULL
) == S_OK
)
1310 if (This
->item_count
)
1312 LPITEMIDLIST
*pidls
;
1315 pidls
= HeapAlloc(GetProcessHeap(), 0, This
->item_count
* sizeof(*pidls
));
1316 This
->item_names
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, This
->item_count
* sizeof(*This
->item_names
));
1318 if (!pidls
|| !This
->item_names
)
1320 HeapFree(GetProcessHeap(), 0, pidls
);
1321 HeapFree(GetProcessHeap(), 0, This
->item_names
);
1326 IEnumIDList_Reset(enumidlist
);
1327 if (IEnumIDList_Next(enumidlist
, This
->item_count
, pidls
, &fetched
) == S_OK
)
1328 idlist_sort(pidls
, 0, This
->item_count
- 1, folder
->folder
);
1330 for (i
= 0; i
< This
->item_count
; i
++)
1334 if (IShellFolder2_GetDisplayNameOf(folder
->folder
, pidls
[i
], SHGDN_FORPARSING
, &strret
) == S_OK
)
1335 StrRetToBSTR(&strret
, pidls
[i
], &This
->item_names
[i
]);
1339 HeapFree(GetProcessHeap(), 0, pidls
);
1341 IEnumIDList_Release(enumidlist
);
1343 *ret
= (FolderItems
*)&This
->FolderItems3_iface
;
1348 IEnumIDList_Release(enumidlist
);
1352 static HRESULT WINAPI
FolderImpl_QueryInterface(Folder3
*iface
, REFIID riid
,
1355 FolderImpl
*This
= impl_from_Folder(iface
);
1357 TRACE("(%p,%s,%p)\n", iface
, debugstr_guid(riid
), ppv
);
1359 if (!ppv
) return E_INVALIDARG
;
1361 if (IsEqualIID(&IID_IUnknown
, riid
) ||
1362 IsEqualIID(&IID_IDispatch
, riid
) ||
1363 IsEqualIID(&IID_Folder
, riid
) ||
1364 IsEqualIID(&IID_Folder2
, riid
) ||
1365 IsEqualIID(&IID_Folder3
, riid
))
1366 *ppv
= &This
->Folder3_iface
;
1369 WARN("not implemented for %s\n", debugstr_guid(riid
));
1371 return E_NOINTERFACE
;
1373 IUnknown_AddRef((IUnknown
*)*ppv
);
1377 static ULONG WINAPI
FolderImpl_AddRef(Folder3
*iface
)
1379 FolderImpl
*This
= impl_from_Folder(iface
);
1380 ULONG ref
= InterlockedIncrement(&This
->ref
);
1382 TRACE("(%p), new refcount=%i\n", iface
, ref
);
1387 static ULONG WINAPI
FolderImpl_Release(Folder3
*iface
)
1389 FolderImpl
*This
= impl_from_Folder(iface
);
1390 ULONG ref
= InterlockedDecrement(&This
->ref
);
1392 TRACE("(%p), new refcount=%i\n", iface
, ref
);
1397 SysFreeString(This
->path
);
1398 IShellFolder2_Release(This
->folder
);
1399 IDispatch_Release(This
->application
);
1400 HeapFree(GetProcessHeap(), 0, This
);
1405 static HRESULT WINAPI
FolderImpl_GetTypeInfoCount(Folder3
*iface
, UINT
*pctinfo
)
1407 TRACE("(%p,%p)\n", iface
, pctinfo
);
1413 static HRESULT WINAPI
FolderImpl_GetTypeInfo(Folder3
*iface
, UINT iTInfo
,
1414 LCID lcid
, ITypeInfo
**ppTInfo
)
1418 TRACE("(%p,%u,%d,%p)\n", iface
, iTInfo
, lcid
, ppTInfo
);
1420 hr
= get_typeinfo(Folder3_tid
, ppTInfo
);
1422 ITypeInfo_AddRef(*ppTInfo
);
1427 static HRESULT WINAPI
FolderImpl_GetIDsOfNames(Folder3
*iface
, REFIID riid
,
1428 LPOLESTR
*rgszNames
, UINT cNames
, LCID lcid
, DISPID
*rgDispId
)
1433 TRACE("(%p,%s,%p,%u,%d,%p)\n", iface
, shdebugstr_guid(riid
), rgszNames
, cNames
, lcid
,
1436 hr
= get_typeinfo(Folder3_tid
, &ti
);
1438 hr
= ITypeInfo_GetIDsOfNames(ti
, rgszNames
, cNames
, rgDispId
);
1442 static HRESULT WINAPI
FolderImpl_Invoke(Folder3
*iface
, DISPID dispIdMember
,
1443 REFIID riid
, LCID lcid
, WORD wFlags
, DISPPARAMS
*pDispParams
,
1444 VARIANT
*pVarResult
, EXCEPINFO
*pExcepInfo
, UINT
*puArgErr
)
1446 FolderImpl
*This
= impl_from_Folder(iface
);
1450 TRACE("(%p,%d,%s,%d,%u,%p,%p,%p,%p)\n", iface
, dispIdMember
, shdebugstr_guid(riid
), lcid
,
1451 wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
1453 hr
= get_typeinfo(Folder3_tid
, &ti
);
1455 hr
= ITypeInfo_Invoke(ti
, This
, dispIdMember
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
1459 static HRESULT WINAPI
FolderImpl_get_Title(Folder3
*iface
, BSTR
*title
)
1461 FolderImpl
*This
= impl_from_Folder(iface
);
1462 PCUITEMID_CHILD last_part
;
1463 IShellFolder2
*parent
;
1467 TRACE("(%p,%p)\n", iface
, title
);
1471 if (FAILED(hr
= SHBindToParent(This
->pidl
, &IID_IShellFolder2
, (void **)&parent
, &last_part
)))
1474 hr
= IShellFolder2_GetDetailsOf(parent
, last_part
, 0, &sd
);
1475 IShellFolder2_Release(parent
);
1479 return StrRetToBSTR(&sd
.str
, last_part
, title
);
1482 static HRESULT WINAPI
FolderImpl_get_Application(Folder3
*iface
, IDispatch
**disp
)
1484 FolderImpl
*This
= impl_from_Folder(iface
);
1486 TRACE("(%p,%p)\n", iface
, disp
);
1489 return E_INVALIDARG
;
1491 *disp
= This
->application
;
1492 IDispatch_AddRef(*disp
);
1497 static HRESULT WINAPI
FolderImpl_get_Parent(Folder3
*iface
, IDispatch
**disp
)
1499 TRACE("(%p,%p)\n", iface
, disp
);
1506 static HRESULT WINAPI
FolderImpl_get_ParentFolder(Folder3
*iface
, Folder
**ppsf
)
1508 FIXME("(%p,%p)\n", iface
, ppsf
);
1514 static HRESULT WINAPI
FolderImpl_Items(Folder3
*iface
, FolderItems
**ppid
)
1516 FolderImpl
*This
= impl_from_Folder(iface
);
1518 TRACE("(%p,%p)\n", iface
, ppid
);
1520 return FolderItems_Constructor(This
, ppid
);
1523 static HRESULT WINAPI
FolderImpl_ParseName(Folder3
*iface
, BSTR name
, FolderItem
**item
)
1525 FolderImpl
*This
= impl_from_Folder(iface
);
1531 TRACE("(%p,%s,%p)\n", iface
, debugstr_w(name
), item
);
1535 if (FAILED(IShellFolder2_ParseDisplayName(This
->folder
, NULL
, NULL
, name
, NULL
, &pidl
, NULL
)))
1538 if ((hr
= IShellFolder2_GetDisplayNameOf(This
->folder
, pidl
, SHGDN_FORPARSING
, &strret
)) == S_OK
)
1539 hr
= StrRetToBSTR(&strret
, pidl
, &path
);
1545 hr
= FolderItem_Constructor(This
, path
, item
);
1546 SysFreeString(path
);
1550 static HRESULT WINAPI
FolderImpl_NewFolder(Folder3
*iface
, BSTR name
, VARIANT options
)
1552 FIXME("(%p,%s,%s)\n", iface
, debugstr_w(name
), debugstr_variant(&options
));
1557 static HRESULT WINAPI
FolderImpl_MoveHere(Folder3
*iface
, VARIANT item
, VARIANT options
)
1559 FIXME("(%p,%s,%s)\n", iface
, debugstr_variant(&item
), debugstr_variant(&options
));
1564 static HRESULT WINAPI
FolderImpl_CopyHere(Folder3
*iface
, VARIANT item
, VARIANT options
)
1566 FIXME("(%p,%s,%s)\n", iface
, debugstr_variant(&item
), debugstr_variant(&options
));
1571 static HRESULT WINAPI
FolderImpl_GetDetailsOf(Folder3
*iface
, VARIANT item
, int column
, BSTR
*str
)
1573 FIXME("(%p,%s,%d,%p)\n", iface
, debugstr_variant(&item
), column
, str
);
1579 static HRESULT WINAPI
FolderImpl_get_Self(Folder3
*iface
, FolderItem
**item
)
1581 FolderImpl
*This
= impl_from_Folder(iface
);
1583 TRACE("(%p,%p)\n", iface
, item
);
1585 return FolderItem_Constructor(This
, NULL
, item
);
1588 static HRESULT WINAPI
FolderImpl_get_OfflineStatus(Folder3
*iface
, LONG
*pul
)
1590 FIXME("(%p,%p)\n", iface
, pul
);
1595 static HRESULT WINAPI
FolderImpl_Synchronize(Folder3
*iface
)
1597 FIXME("(%p)\n", iface
);
1602 static HRESULT WINAPI
FolderImpl_get_HaveToShowWebViewBarricade(Folder3
*iface
,
1603 VARIANT_BOOL
*pbHaveToShowWebViewBarricade
)
1605 FIXME("(%p,%p)\n", iface
, pbHaveToShowWebViewBarricade
);
1610 static HRESULT WINAPI
FolderImpl_DismissedWebViewBarricade(Folder3
*iface
)
1612 FIXME("(%p)\n", iface
);
1617 static HRESULT WINAPI
FolderImpl_get_ShowWebViewBarricade(Folder3
*iface
,
1618 VARIANT_BOOL
*pbShowWebViewBarricade
)
1620 FIXME("(%p,%p)\n", iface
, pbShowWebViewBarricade
);
1625 static HRESULT WINAPI
FolderImpl_put_ShowWebViewBarricade(Folder3
*iface
,
1626 VARIANT_BOOL bShowWebViewBarricade
)
1628 FIXME("(%p,%d)\n", iface
, bShowWebViewBarricade
);
1633 static const Folder3Vtbl FolderImpl_Vtbl
= {
1634 FolderImpl_QueryInterface
,
1637 FolderImpl_GetTypeInfoCount
,
1638 FolderImpl_GetTypeInfo
,
1639 FolderImpl_GetIDsOfNames
,
1641 FolderImpl_get_Title
,
1642 FolderImpl_get_Application
,
1643 FolderImpl_get_Parent
,
1644 FolderImpl_get_ParentFolder
,
1646 FolderImpl_ParseName
,
1647 FolderImpl_NewFolder
,
1648 FolderImpl_MoveHere
,
1649 FolderImpl_CopyHere
,
1650 FolderImpl_GetDetailsOf
,
1651 FolderImpl_get_Self
,
1652 FolderImpl_get_OfflineStatus
,
1653 FolderImpl_Synchronize
,
1654 FolderImpl_get_HaveToShowWebViewBarricade
,
1655 FolderImpl_DismissedWebViewBarricade
,
1656 FolderImpl_get_ShowWebViewBarricade
,
1657 FolderImpl_put_ShowWebViewBarricade
1660 static HRESULT
Folder_Constructor(IShellFolder2
*folder
, LPITEMIDLIST pidl
, Folder
**ret
)
1662 PCUITEMID_CHILD last_part
;
1663 IShellFolder2
*parent
;
1670 This
= HeapAlloc(GetProcessHeap(), 0, sizeof(*This
));
1672 return E_OUTOFMEMORY
;
1674 This
->Folder3_iface
.lpVtbl
= &FolderImpl_Vtbl
;
1676 This
->folder
= folder
;
1679 hr
= SHBindToParent(pidl
, &IID_IShellFolder2
, (void **)&parent
, &last_part
);
1680 IShellFolder2_GetDisplayNameOf(parent
, last_part
, SHGDN_FORPARSING
, &strret
);
1681 StrRetToBSTR(&strret
, last_part
, &This
->path
);
1682 IShellFolder2_Release(parent
);
1684 IShellDispatch_Constructor(NULL
, &IID_IDispatch
, (void **)&This
->application
);
1686 *ret
= (Folder
*)&This
->Folder3_iface
;
1690 static HRESULT WINAPI
ShellDispatch_QueryInterface(IShellDispatch6
*iface
,
1691 REFIID riid
, LPVOID
*ppv
)
1693 ShellDispatch
*This
= impl_from_IShellDispatch6(iface
);
1695 TRACE("(%p,%s,%p)\n", iface
, debugstr_guid(riid
), ppv
);
1697 if (!ppv
) return E_INVALIDARG
;
1699 if (IsEqualIID(&IID_IUnknown
, riid
) ||
1700 IsEqualIID(&IID_IDispatch
, riid
) ||
1701 IsEqualIID(&IID_IShellDispatch
, riid
) ||
1702 IsEqualIID(&IID_IShellDispatch2
, riid
) ||
1703 IsEqualIID(&IID_IShellDispatch3
, riid
) ||
1704 IsEqualIID(&IID_IShellDispatch4
, riid
) ||
1705 IsEqualIID(&IID_IShellDispatch5
, riid
) ||
1706 IsEqualIID(&IID_IShellDispatch6
, riid
))
1707 *ppv
= &This
->IShellDispatch6_iface
;
1710 WARN("not implemented for %s\n", debugstr_guid(riid
));
1712 return E_NOINTERFACE
;
1715 IShellDispatch6_AddRef(iface
);
1719 static ULONG WINAPI
ShellDispatch_AddRef(IShellDispatch6
*iface
)
1721 ShellDispatch
*This
= impl_from_IShellDispatch6(iface
);
1722 ULONG ref
= InterlockedIncrement(&This
->ref
);
1724 TRACE("(%p), new refcount=%i\n", iface
, ref
);
1729 static ULONG WINAPI
ShellDispatch_Release(IShellDispatch6
*iface
)
1731 ShellDispatch
*This
= impl_from_IShellDispatch6(iface
);
1732 ULONG ref
= InterlockedDecrement(&This
->ref
);
1734 TRACE("(%p), new refcount=%i\n", iface
, ref
);
1737 HeapFree(GetProcessHeap(), 0, This
);
1742 static HRESULT WINAPI
ShellDispatch_GetTypeInfoCount(IShellDispatch6
*iface
,
1745 TRACE("(%p,%p)\n", iface
, pctinfo
);
1751 static HRESULT WINAPI
ShellDispatch_GetTypeInfo(IShellDispatch6
*iface
,
1752 UINT iTInfo
, LCID lcid
, ITypeInfo
**ppTInfo
)
1756 TRACE("(%p,%u,%d,%p)\n", iface
, iTInfo
, lcid
, ppTInfo
);
1758 hr
= get_typeinfo(IShellDispatch6_tid
, ppTInfo
);
1760 ITypeInfo_AddRef(*ppTInfo
);
1764 static HRESULT WINAPI
ShellDispatch_GetIDsOfNames(IShellDispatch6
*iface
,
1765 REFIID riid
, LPOLESTR
*rgszNames
, UINT cNames
, LCID lcid
, DISPID
*rgDispId
)
1770 TRACE("(%p,%s,%p,%u,%d,%p)\n", iface
, shdebugstr_guid(riid
), rgszNames
, cNames
, lcid
,
1773 hr
= get_typeinfo(IShellDispatch6_tid
, &ti
);
1775 hr
= ITypeInfo_GetIDsOfNames(ti
, rgszNames
, cNames
, rgDispId
);
1779 static HRESULT WINAPI
ShellDispatch_Invoke(IShellDispatch6
*iface
,
1780 DISPID dispIdMember
, REFIID riid
, LCID lcid
, WORD wFlags
,
1781 DISPPARAMS
*pDispParams
, VARIANT
*pVarResult
, EXCEPINFO
*pExcepInfo
,
1784 ShellDispatch
*This
= impl_from_IShellDispatch6(iface
);
1788 TRACE("(%p,%d,%s,%d,%u,%p,%p,%p,%p)\n", iface
, dispIdMember
, shdebugstr_guid(riid
), lcid
,
1789 wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
1791 hr
= get_typeinfo(IShellDispatch6_tid
, &ti
);
1793 hr
= ITypeInfo_Invoke(ti
, &This
->IShellDispatch6_iface
, dispIdMember
, wFlags
, pDispParams
,
1794 pVarResult
, pExcepInfo
, puArgErr
);
1798 static HRESULT WINAPI
ShellDispatch_get_Application(IShellDispatch6
*iface
, IDispatch
**disp
)
1800 TRACE("(%p,%p)\n", iface
, disp
);
1803 return E_INVALIDARG
;
1805 *disp
= (IDispatch
*)iface
;
1806 IDispatch_AddRef(*disp
);
1810 static HRESULT WINAPI
ShellDispatch_get_Parent(IShellDispatch6
*iface
, IDispatch
**disp
)
1812 TRACE("(%p,%p)\n", iface
, disp
);
1816 *disp
= (IDispatch
*)iface
;
1817 IDispatch_AddRef(*disp
);
1823 static HRESULT WINAPI
ShellDispatch_NameSpace(IShellDispatch6
*iface
,
1824 VARIANT dir
, Folder
**ret
)
1826 IShellFolder2
*folder
;
1827 IShellFolder
*desktop
;
1831 TRACE("(%p,%s,%p)\n", iface
, debugstr_variant(&dir
), ret
);
1838 if (FAILED(hr
= VariantChangeType(&dir
, &dir
, 0, VT_I4
)))
1843 if (FAILED(hr
= SHGetFolderLocation(NULL
, V_I4(&dir
), NULL
, 0, &pidl
)))
1848 if (FAILED(hr
= SHParseDisplayName(V_BSTR(&dir
), NULL
, &pidl
, 0, NULL
)))
1853 WARN("Ignoring directory value %s\n", debugstr_variant(&dir
));
1857 if (FAILED(hr
= SHGetDesktopFolder(&desktop
)))
1860 if (_ILIsDesktop(pidl
))
1861 hr
= IShellFolder_QueryInterface(desktop
, &IID_IShellFolder2
, (void **)&folder
);
1863 hr
= IShellFolder_BindToObject(desktop
, pidl
, NULL
, &IID_IShellFolder2
, (void **)&folder
);
1865 IShellFolder_Release(desktop
);
1870 return Folder_Constructor(folder
, pidl
, ret
);
1873 static HRESULT WINAPI
ShellDispatch_BrowseForFolder(IShellDispatch6
*iface
,
1874 LONG Hwnd
, BSTR Title
, LONG Options
, VARIANT RootFolder
, Folder
**ppsdf
)
1876 FIXME("(%p,%x,%s,%x,%s,%p)\n", iface
, Hwnd
, debugstr_w(Title
), Options
, debugstr_variant(&RootFolder
), ppsdf
);
1882 static HRESULT WINAPI
ShellDispatch_Windows(IShellDispatch6
*iface
,
1885 FIXME("(%p,%p)\n", iface
, ppid
);
1891 static HRESULT WINAPI
ShellDispatch_Open(IShellDispatch6
*iface
, VARIANT dir
)
1893 FIXME("(%p,%s)\n", iface
, debugstr_variant(&dir
));
1898 static HRESULT WINAPI
ShellDispatch_Explore(IShellDispatch6
*iface
, VARIANT dir
)
1900 FIXME("(%p,%s)\n", iface
, debugstr_variant(&dir
));
1905 static HRESULT WINAPI
ShellDispatch_MinimizeAll(IShellDispatch6
*iface
)
1907 FIXME("(%p)\n", iface
);
1912 static HRESULT WINAPI
ShellDispatch_UndoMinimizeALL(IShellDispatch6
*iface
)
1914 FIXME("(%p)\n", iface
);
1919 static HRESULT WINAPI
ShellDispatch_FileRun(IShellDispatch6
*iface
)
1921 FIXME("(%p)\n", iface
);
1926 static HRESULT WINAPI
ShellDispatch_CascadeWindows(IShellDispatch6
*iface
)
1928 FIXME("(%p)\n", iface
);
1933 static HRESULT WINAPI
ShellDispatch_TileVertically(IShellDispatch6
*iface
)
1935 FIXME("(%p)\n", iface
);
1940 static HRESULT WINAPI
ShellDispatch_TileHorizontally(IShellDispatch6
*iface
)
1942 FIXME("(%p)\n", iface
);
1947 static HRESULT WINAPI
ShellDispatch_ShutdownWindows(IShellDispatch6
*iface
)
1949 FIXME("(%p)\n", iface
);
1954 static HRESULT WINAPI
ShellDispatch_Suspend(IShellDispatch6
*iface
)
1956 FIXME("(%p)\n", iface
);
1961 static HRESULT WINAPI
ShellDispatch_EjectPC(IShellDispatch6
*iface
)
1963 FIXME("(%p)\n", iface
);
1968 static HRESULT WINAPI
ShellDispatch_SetTime(IShellDispatch6
*iface
)
1970 FIXME("(%p)\n", iface
);
1975 static HRESULT WINAPI
ShellDispatch_TrayProperties(IShellDispatch6
*iface
)
1977 FIXME("(%p)\n", iface
);
1982 static HRESULT WINAPI
ShellDispatch_Help(IShellDispatch6
*iface
)
1984 FIXME("(%p)\n", iface
);
1989 static HRESULT WINAPI
ShellDispatch_FindFiles(IShellDispatch6
*iface
)
1991 FIXME("(%p)\n", iface
);
1996 static HRESULT WINAPI
ShellDispatch_FindComputer(IShellDispatch6
*iface
)
1998 FIXME("(%p)\n", iface
);
2003 static HRESULT WINAPI
ShellDispatch_RefreshMenu(IShellDispatch6
*iface
)
2005 FIXME("(%p)\n", iface
);
2010 static HRESULT WINAPI
ShellDispatch_ControlPanelItem(IShellDispatch6
*iface
,
2013 FIXME("(%p,%s)\n", iface
, debugstr_w(szDir
));
2018 static HRESULT WINAPI
ShellDispatch_IsRestricted(IShellDispatch6
*iface
, BSTR group
, BSTR restriction
, LONG
*value
)
2020 FIXME("(%s, %s, %p): stub\n", debugstr_w(group
), debugstr_w(restriction
), value
);
2024 static HRESULT WINAPI
ShellDispatch_ShellExecute(IShellDispatch6
*iface
,
2025 BSTR file
, VARIANT v_args
, VARIANT v_dir
, VARIANT v_op
, VARIANT v_show
)
2027 VARIANT args_str
, dir_str
, op_str
, show_int
;
2028 WCHAR
*args
= NULL
, *dir
= NULL
, *op
= NULL
;
2032 TRACE("(%s, %s, %s, %s, %s)\n", debugstr_w(file
), debugstr_variant(&v_args
),
2033 debugstr_variant(&v_dir
), debugstr_variant(&v_op
), debugstr_variant(&v_show
));
2035 VariantInit(&args_str
);
2036 VariantChangeType(&args_str
, &v_args
, 0, VT_BSTR
);
2037 if (V_VT(&args_str
) == VT_BSTR
)
2038 args
= V_BSTR(&args_str
);
2040 VariantInit(&dir_str
);
2041 VariantChangeType(&dir_str
, &v_dir
, 0, VT_BSTR
);
2042 if (V_VT(&dir_str
) == VT_BSTR
)
2043 dir
= V_BSTR(&dir_str
);
2045 VariantInit(&op_str
);
2046 VariantChangeType(&op_str
, &v_op
, 0, VT_BSTR
);
2047 if (V_VT(&op_str
) == VT_BSTR
)
2048 op
= V_BSTR(&op_str
);
2050 VariantInit(&show_int
);
2051 VariantChangeType(&show_int
, &v_show
, 0, VT_I4
);
2052 if (V_VT(&show_int
) == VT_I4
)
2053 show
= V_I4(&show_int
);
2055 ret
= ShellExecuteW(NULL
, op
, file
, args
, dir
, show
);
2057 VariantClear(&args_str
);
2058 VariantClear(&dir_str
);
2059 VariantClear(&op_str
);
2060 VariantClear(&show_int
);
2062 return (ULONG_PTR
)ret
> 32 ? S_OK
: S_FALSE
;
2065 static HRESULT WINAPI
ShellDispatch_FindPrinter(IShellDispatch6
*iface
, BSTR name
, BSTR location
, BSTR model
)
2067 FIXME("(%s, %s, %s): stub\n", debugstr_w(name
), debugstr_w(location
), debugstr_w(model
));
2071 static HRESULT WINAPI
ShellDispatch_GetSystemInformation(IShellDispatch6
*iface
, BSTR name
, VARIANT
*ret
)
2073 FIXME("(%s, %p): stub\n", debugstr_w(name
), ret
);
2077 static HRESULT WINAPI
ShellDispatch_ServiceStart(IShellDispatch6
*iface
, BSTR service
, VARIANT persistent
, VARIANT
*ret
)
2079 FIXME("(%s, %s, %p): stub\n", debugstr_w(service
), debugstr_variant(&persistent
), ret
);
2083 static HRESULT WINAPI
ShellDispatch_ServiceStop(IShellDispatch6
*iface
, BSTR service
, VARIANT persistent
, VARIANT
*ret
)
2085 FIXME("(%s, %s, %p): stub\n", debugstr_w(service
), debugstr_variant(&persistent
), ret
);
2089 static HRESULT WINAPI
ShellDispatch_IsServiceRunning(IShellDispatch6
*iface
, BSTR name
, VARIANT
*running
)
2091 SERVICE_STATUS_PROCESS status
;
2092 SC_HANDLE scm
, service
;
2095 TRACE("(%s, %p)\n", debugstr_w(name
), running
);
2097 V_VT(running
) = VT_BOOL
;
2098 V_BOOL(running
) = VARIANT_FALSE
;
2100 scm
= OpenSCManagerW(NULL
, NULL
, SC_MANAGER_CONNECT
);
2103 ERR("failed to connect to service manager\n");
2107 service
= OpenServiceW(scm
, name
, SERVICE_QUERY_STATUS
);
2110 ERR("Failed to open service %s (%u)\n", debugstr_w(name
), GetLastError());
2111 CloseServiceHandle(scm
);
2115 if (!QueryServiceStatusEx(service
, SC_STATUS_PROCESS_INFO
, (BYTE
*)&status
,
2116 sizeof(SERVICE_STATUS_PROCESS
), &dummy
))
2118 TRACE("failed to query service status (%u)\n", GetLastError());
2119 CloseServiceHandle(service
);
2120 CloseServiceHandle(scm
);
2124 if (status
.dwCurrentState
== SERVICE_RUNNING
)
2125 V_BOOL(running
) = VARIANT_TRUE
;
2127 CloseServiceHandle(service
);
2128 CloseServiceHandle(scm
);
2133 static HRESULT WINAPI
ShellDispatch_CanStartStopService(IShellDispatch6
*iface
, BSTR service
, VARIANT
*ret
)
2135 FIXME("(%s, %p): stub\n", debugstr_w(service
), ret
);
2139 static HRESULT WINAPI
ShellDispatch_ShowBrowserBar(IShellDispatch6
*iface
, BSTR clsid
, VARIANT show
, VARIANT
*ret
)
2141 FIXME("(%s, %s, %p): stub\n", debugstr_w(clsid
), debugstr_variant(&show
), ret
);
2145 static HRESULT WINAPI
ShellDispatch_AddToRecent(IShellDispatch6
*iface
, VARIANT file
, BSTR category
)
2147 FIXME("(%s, %s): stub\n", debugstr_variant(&file
), debugstr_w(category
));
2151 static HRESULT WINAPI
ShellDispatch_WindowsSecurity(IShellDispatch6
*iface
)
2157 static HRESULT WINAPI
ShellDispatch_ToggleDesktop(IShellDispatch6
*iface
)
2163 static HRESULT WINAPI
ShellDispatch_ExplorerPolicy(IShellDispatch6
*iface
, BSTR policy
, VARIANT
*value
)
2165 FIXME("(%s, %p): stub\n", debugstr_w(policy
), value
);
2169 static HRESULT WINAPI
ShellDispatch_GetSetting(IShellDispatch6
*iface
, LONG setting
, VARIANT_BOOL
*result
)
2171 FIXME("(%d %p): stub\n", setting
, result
);
2175 static HRESULT WINAPI
ShellDispatch_WindowSwitcher(IShellDispatch6
*iface
)
2181 static HRESULT WINAPI
ShellDispatch_SearchCommand(IShellDispatch6
*iface
)
2187 static const IShellDispatch6Vtbl ShellDispatchVtbl
= {
2188 ShellDispatch_QueryInterface
,
2189 ShellDispatch_AddRef
,
2190 ShellDispatch_Release
,
2191 ShellDispatch_GetTypeInfoCount
,
2192 ShellDispatch_GetTypeInfo
,
2193 ShellDispatch_GetIDsOfNames
,
2194 ShellDispatch_Invoke
,
2195 ShellDispatch_get_Application
,
2196 ShellDispatch_get_Parent
,
2197 ShellDispatch_NameSpace
,
2198 ShellDispatch_BrowseForFolder
,
2199 ShellDispatch_Windows
,
2201 ShellDispatch_Explore
,
2202 ShellDispatch_MinimizeAll
,
2203 ShellDispatch_UndoMinimizeALL
,
2204 ShellDispatch_FileRun
,
2205 ShellDispatch_CascadeWindows
,
2206 ShellDispatch_TileVertically
,
2207 ShellDispatch_TileHorizontally
,
2208 ShellDispatch_ShutdownWindows
,
2209 ShellDispatch_Suspend
,
2210 ShellDispatch_EjectPC
,
2211 ShellDispatch_SetTime
,
2212 ShellDispatch_TrayProperties
,
2214 ShellDispatch_FindFiles
,
2215 ShellDispatch_FindComputer
,
2216 ShellDispatch_RefreshMenu
,
2217 ShellDispatch_ControlPanelItem
,
2218 ShellDispatch_IsRestricted
,
2219 ShellDispatch_ShellExecute
,
2220 ShellDispatch_FindPrinter
,
2221 ShellDispatch_GetSystemInformation
,
2222 ShellDispatch_ServiceStart
,
2223 ShellDispatch_ServiceStop
,
2224 ShellDispatch_IsServiceRunning
,
2225 ShellDispatch_CanStartStopService
,
2226 ShellDispatch_ShowBrowserBar
,
2227 ShellDispatch_AddToRecent
,
2228 ShellDispatch_WindowsSecurity
,
2229 ShellDispatch_ToggleDesktop
,
2230 ShellDispatch_ExplorerPolicy
,
2231 ShellDispatch_GetSetting
,
2232 ShellDispatch_WindowSwitcher
,
2233 ShellDispatch_SearchCommand
2236 HRESULT WINAPI
IShellDispatch_Constructor(IUnknown
*outer
, REFIID riid
, void **ppv
)
2238 ShellDispatch
*This
;
2241 TRACE("(%p, %s)\n", outer
, debugstr_guid(riid
));
2245 if (outer
) return CLASS_E_NOAGGREGATION
;
2247 This
= HeapAlloc(GetProcessHeap(), 0, sizeof(ShellDispatch
));
2248 if (!This
) return E_OUTOFMEMORY
;
2249 This
->IShellDispatch6_iface
.lpVtbl
= &ShellDispatchVtbl
;
2252 ret
= IShellDispatch6_QueryInterface(&This
->IShellDispatch6_iface
, riid
, ppv
);
2253 IShellDispatch6_Release(&This
->IShellDispatch6_iface
);