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
< ARRAY_SIZE(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
);
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
= heap_alloc(sizeof(*This
));
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
);
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
= heap_alloc(sizeof(*This
));
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
;
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 heap_free(This
->path
);
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
= heap_alloc_zero(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 heap_free(This
->item_names
);
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 var
, FolderItem
**item
)
1134 FolderItemsImpl
*This
= impl_from_FolderItems(iface
);
1135 BSTR display_name
= NULL
;
1139 TRACE("(%p,%s,%p)\n", iface
, debugstr_variant(&var
), item
);
1143 if (!shellfolder_exists(This
->folder
->path
))
1146 VariantInit(&index
);
1147 if (FAILED(hr
= VariantCopyInd(&index
, &var
)))
1150 switch (V_VT(&index
))
1153 VariantChangeType(&index
, &index
, 0, VT_I4
);
1157 if (V_I4(&index
) >= This
->item_count
|| V_I4(&index
) < 0)
1160 display_name
= SysAllocString(This
->item_names
[V_I4(&index
)]);
1168 if (!V_BSTR(&index
))
1171 hr
= IShellFolder2_ParseDisplayName(This
->folder
->folder
, NULL
, NULL
, V_BSTR(&index
), NULL
, &pidl
, NULL
);
1172 VariantClear(&index
);
1176 if (IShellFolder2_GetDisplayNameOf(This
->folder
->folder
, pidl
, SHGDN_FORPARSING
, &strret
) == S_OK
)
1177 StrRetToBSTR(&strret
, pidl
, &display_name
);
1185 FIXME("Index type %#x not handled.\n", V_VT(&index
));
1186 VariantClear(&index
);
1192 hr
= FolderItem_Constructor(This
->folder
, display_name
, item
);
1193 SysFreeString(display_name
);
1197 static HRESULT WINAPI
FolderItemsImpl__NewEnum(FolderItems3
*iface
, IUnknown
**ppunk
)
1199 FIXME("(%p,%p)\n", iface
, ppunk
);
1202 return E_INVALIDARG
;
1208 static HRESULT WINAPI
FolderItemsImpl_InvokeVerbEx(FolderItems3
*iface
, VARIANT verb
, VARIANT args
)
1210 FIXME("(%p,%s,%s)\n", iface
, debugstr_variant(&verb
), debugstr_variant(&args
));
1215 static HRESULT WINAPI
FolderItemsImpl_Filter(FolderItems3
*iface
, LONG flags
, BSTR spec
)
1217 FIXME("(%p,%d,%s)\n", iface
, flags
, wine_dbgstr_w(spec
));
1222 static HRESULT WINAPI
FolderItemsImpl_get_Verbs(FolderItems3
*iface
, FolderItemVerbs
**ppfic
)
1224 FIXME("(%p,%p)\n", iface
, ppfic
);
1227 return E_INVALIDARG
;
1233 static const FolderItems3Vtbl FolderItemsImpl_Vtbl
= {
1234 FolderItemsImpl_QueryInterface
,
1235 FolderItemsImpl_AddRef
,
1236 FolderItemsImpl_Release
,
1237 FolderItemsImpl_GetTypeInfoCount
,
1238 FolderItemsImpl_GetTypeInfo
,
1239 FolderItemsImpl_GetIDsOfNames
,
1240 FolderItemsImpl_Invoke
,
1241 FolderItemsImpl_get_Count
,
1242 FolderItemsImpl_get_Application
,
1243 FolderItemsImpl_get_Parent
,
1244 FolderItemsImpl_Item
,
1245 FolderItemsImpl__NewEnum
,
1246 FolderItemsImpl_InvokeVerbEx
,
1247 FolderItemsImpl_Filter
,
1248 FolderItemsImpl_get_Verbs
1251 static void idlist_sort(LPITEMIDLIST
*idlist
, unsigned int l
, unsigned int r
, IShellFolder2
*folder
)
1260 idlist_sort(idlist
, r
, l
, folder
);
1265 idlist_sort(idlist
, l
, m
, folder
);
1266 idlist_sort(idlist
, m
+ 1, r
, folder
);
1268 /* join the two sides */
1269 while (l
<= m
&& m
< r
)
1271 if ((short)IShellFolder2_CompareIDs(folder
, 0, idlist
[l
], idlist
[m
+ 1]) > 0)
1273 LPITEMIDLIST t
= idlist
[m
+ 1];
1274 memmove(&idlist
[l
+ 1], &idlist
[l
], (m
- l
+ 1) * sizeof(idlist
[l
]));
1283 static HRESULT
FolderItems_Constructor(FolderImpl
*folder
, FolderItems
**ret
)
1285 IEnumIDList
*enumidlist
;
1286 FolderItemsImpl
*This
;
1291 TRACE("(%s,%p)\n", debugstr_w(folder
->path
), ret
);
1295 This
= heap_alloc_zero(sizeof(*This
));
1297 return E_OUTOFMEMORY
;
1299 This
->FolderItems3_iface
.lpVtbl
= &FolderItemsImpl_Vtbl
;
1301 This
->folder
= folder
;
1302 Folder3_AddRef(&folder
->Folder3_iface
);
1305 if (FAILED(hr
= IShellFolder2_EnumObjects(folder
->folder
, NULL
, SHCONTF_FOLDERS
| SHCONTF_NONFOLDERS
,
1311 while (IEnumIDList_Next(enumidlist
, 1, &pidl
, NULL
) == S_OK
)
1317 if (This
->item_count
)
1319 LPITEMIDLIST
*pidls
;
1322 pidls
= heap_alloc(This
->item_count
* sizeof(*pidls
));
1323 This
->item_names
= heap_alloc_zero(This
->item_count
* sizeof(*This
->item_names
));
1325 if (!pidls
|| !This
->item_names
)
1328 heap_free(This
->item_names
);
1333 IEnumIDList_Reset(enumidlist
);
1334 if (IEnumIDList_Next(enumidlist
, This
->item_count
, pidls
, &fetched
) == S_OK
)
1335 idlist_sort(pidls
, 0, This
->item_count
- 1, folder
->folder
);
1337 for (i
= 0; i
< This
->item_count
; i
++)
1341 if (IShellFolder2_GetDisplayNameOf(folder
->folder
, pidls
[i
], SHGDN_FORPARSING
, &strret
) == S_OK
)
1342 StrRetToBSTR(&strret
, pidls
[i
], &This
->item_names
[i
]);
1348 IEnumIDList_Release(enumidlist
);
1350 *ret
= (FolderItems
*)&This
->FolderItems3_iface
;
1355 IEnumIDList_Release(enumidlist
);
1359 static HRESULT WINAPI
FolderImpl_QueryInterface(Folder3
*iface
, REFIID riid
,
1362 FolderImpl
*This
= impl_from_Folder(iface
);
1364 TRACE("(%p,%s,%p)\n", iface
, debugstr_guid(riid
), ppv
);
1366 if (!ppv
) return E_INVALIDARG
;
1368 if (IsEqualIID(&IID_IUnknown
, riid
) ||
1369 IsEqualIID(&IID_IDispatch
, riid
) ||
1370 IsEqualIID(&IID_Folder
, riid
) ||
1371 IsEqualIID(&IID_Folder2
, riid
) ||
1372 IsEqualIID(&IID_Folder3
, riid
))
1373 *ppv
= &This
->Folder3_iface
;
1376 WARN("not implemented for %s\n", debugstr_guid(riid
));
1378 return E_NOINTERFACE
;
1380 IUnknown_AddRef((IUnknown
*)*ppv
);
1384 static ULONG WINAPI
FolderImpl_AddRef(Folder3
*iface
)
1386 FolderImpl
*This
= impl_from_Folder(iface
);
1387 ULONG ref
= InterlockedIncrement(&This
->ref
);
1389 TRACE("(%p), new refcount=%i\n", iface
, ref
);
1394 static ULONG WINAPI
FolderImpl_Release(Folder3
*iface
)
1396 FolderImpl
*This
= impl_from_Folder(iface
);
1397 ULONG ref
= InterlockedDecrement(&This
->ref
);
1399 TRACE("(%p), new refcount=%i\n", iface
, ref
);
1404 SysFreeString(This
->path
);
1405 IShellFolder2_Release(This
->folder
);
1406 IDispatch_Release(This
->application
);
1412 static HRESULT WINAPI
FolderImpl_GetTypeInfoCount(Folder3
*iface
, UINT
*pctinfo
)
1414 TRACE("(%p,%p)\n", iface
, pctinfo
);
1420 static HRESULT WINAPI
FolderImpl_GetTypeInfo(Folder3
*iface
, UINT iTInfo
,
1421 LCID lcid
, ITypeInfo
**ppTInfo
)
1425 TRACE("(%p,%u,%d,%p)\n", iface
, iTInfo
, lcid
, ppTInfo
);
1427 hr
= get_typeinfo(Folder3_tid
, ppTInfo
);
1429 ITypeInfo_AddRef(*ppTInfo
);
1434 static HRESULT WINAPI
FolderImpl_GetIDsOfNames(Folder3
*iface
, REFIID riid
,
1435 LPOLESTR
*rgszNames
, UINT cNames
, LCID lcid
, DISPID
*rgDispId
)
1440 TRACE("(%p,%s,%p,%u,%d,%p)\n", iface
, shdebugstr_guid(riid
), rgszNames
, cNames
, lcid
,
1443 hr
= get_typeinfo(Folder3_tid
, &ti
);
1445 hr
= ITypeInfo_GetIDsOfNames(ti
, rgszNames
, cNames
, rgDispId
);
1449 static HRESULT WINAPI
FolderImpl_Invoke(Folder3
*iface
, DISPID dispIdMember
,
1450 REFIID riid
, LCID lcid
, WORD wFlags
, DISPPARAMS
*pDispParams
,
1451 VARIANT
*pVarResult
, EXCEPINFO
*pExcepInfo
, UINT
*puArgErr
)
1453 FolderImpl
*This
= impl_from_Folder(iface
);
1457 TRACE("(%p,%d,%s,%d,%u,%p,%p,%p,%p)\n", iface
, dispIdMember
, shdebugstr_guid(riid
), lcid
,
1458 wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
1460 hr
= get_typeinfo(Folder3_tid
, &ti
);
1462 hr
= ITypeInfo_Invoke(ti
, This
, dispIdMember
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
1466 static HRESULT WINAPI
FolderImpl_get_Title(Folder3
*iface
, BSTR
*title
)
1468 FolderImpl
*This
= impl_from_Folder(iface
);
1469 PCUITEMID_CHILD last_part
;
1470 IShellFolder2
*parent
;
1474 TRACE("(%p,%p)\n", iface
, title
);
1478 if (FAILED(hr
= SHBindToParent(This
->pidl
, &IID_IShellFolder2
, (void **)&parent
, &last_part
)))
1481 hr
= IShellFolder2_GetDetailsOf(parent
, last_part
, 0, &sd
);
1482 IShellFolder2_Release(parent
);
1486 return StrRetToBSTR(&sd
.str
, last_part
, title
);
1489 static HRESULT WINAPI
FolderImpl_get_Application(Folder3
*iface
, IDispatch
**disp
)
1491 FolderImpl
*This
= impl_from_Folder(iface
);
1493 TRACE("(%p,%p)\n", iface
, disp
);
1496 return E_INVALIDARG
;
1498 *disp
= This
->application
;
1499 IDispatch_AddRef(*disp
);
1504 static HRESULT WINAPI
FolderImpl_get_Parent(Folder3
*iface
, IDispatch
**disp
)
1506 TRACE("(%p,%p)\n", iface
, disp
);
1513 static HRESULT WINAPI
FolderImpl_get_ParentFolder(Folder3
*iface
, Folder
**ppsf
)
1515 FIXME("(%p,%p)\n", iface
, ppsf
);
1521 static HRESULT WINAPI
FolderImpl_Items(Folder3
*iface
, FolderItems
**ppid
)
1523 FolderImpl
*This
= impl_from_Folder(iface
);
1525 TRACE("(%p,%p)\n", iface
, ppid
);
1527 return FolderItems_Constructor(This
, ppid
);
1530 static HRESULT WINAPI
FolderImpl_ParseName(Folder3
*iface
, BSTR name
, FolderItem
**item
)
1532 FolderImpl
*This
= impl_from_Folder(iface
);
1538 TRACE("(%p,%s,%p)\n", iface
, debugstr_w(name
), item
);
1542 if (FAILED(IShellFolder2_ParseDisplayName(This
->folder
, NULL
, NULL
, name
, NULL
, &pidl
, NULL
)))
1545 if ((hr
= IShellFolder2_GetDisplayNameOf(This
->folder
, pidl
, SHGDN_FORPARSING
, &strret
)) == S_OK
)
1546 hr
= StrRetToBSTR(&strret
, pidl
, &path
);
1552 hr
= FolderItem_Constructor(This
, path
, item
);
1553 SysFreeString(path
);
1557 static HRESULT WINAPI
FolderImpl_NewFolder(Folder3
*iface
, BSTR name
, VARIANT options
)
1559 FIXME("(%p,%s,%s)\n", iface
, debugstr_w(name
), debugstr_variant(&options
));
1564 static HRESULT WINAPI
FolderImpl_MoveHere(Folder3
*iface
, VARIANT item
, VARIANT options
)
1566 FIXME("(%p,%s,%s)\n", iface
, debugstr_variant(&item
), debugstr_variant(&options
));
1571 static HRESULT WINAPI
FolderImpl_CopyHere(Folder3
*iface
, VARIANT item
, VARIANT options
)
1573 FIXME("(%p,%s,%s)\n", iface
, debugstr_variant(&item
), debugstr_variant(&options
));
1578 static HRESULT WINAPI
FolderImpl_GetDetailsOf(Folder3
*iface
, VARIANT item
, int column
, BSTR
*str
)
1580 FIXME("(%p,%s,%d,%p)\n", iface
, debugstr_variant(&item
), column
, str
);
1586 static HRESULT WINAPI
FolderImpl_get_Self(Folder3
*iface
, FolderItem
**item
)
1588 FolderImpl
*This
= impl_from_Folder(iface
);
1590 TRACE("(%p,%p)\n", iface
, item
);
1592 return FolderItem_Constructor(This
, NULL
, item
);
1595 static HRESULT WINAPI
FolderImpl_get_OfflineStatus(Folder3
*iface
, LONG
*pul
)
1597 FIXME("(%p,%p)\n", iface
, pul
);
1602 static HRESULT WINAPI
FolderImpl_Synchronize(Folder3
*iface
)
1604 FIXME("(%p)\n", iface
);
1609 static HRESULT WINAPI
FolderImpl_get_HaveToShowWebViewBarricade(Folder3
*iface
,
1610 VARIANT_BOOL
*pbHaveToShowWebViewBarricade
)
1612 FIXME("(%p,%p)\n", iface
, pbHaveToShowWebViewBarricade
);
1617 static HRESULT WINAPI
FolderImpl_DismissedWebViewBarricade(Folder3
*iface
)
1619 FIXME("(%p)\n", iface
);
1624 static HRESULT WINAPI
FolderImpl_get_ShowWebViewBarricade(Folder3
*iface
,
1625 VARIANT_BOOL
*pbShowWebViewBarricade
)
1627 FIXME("(%p,%p)\n", iface
, pbShowWebViewBarricade
);
1632 static HRESULT WINAPI
FolderImpl_put_ShowWebViewBarricade(Folder3
*iface
,
1633 VARIANT_BOOL bShowWebViewBarricade
)
1635 FIXME("(%p,%d)\n", iface
, bShowWebViewBarricade
);
1640 static const Folder3Vtbl FolderImpl_Vtbl
= {
1641 FolderImpl_QueryInterface
,
1644 FolderImpl_GetTypeInfoCount
,
1645 FolderImpl_GetTypeInfo
,
1646 FolderImpl_GetIDsOfNames
,
1648 FolderImpl_get_Title
,
1649 FolderImpl_get_Application
,
1650 FolderImpl_get_Parent
,
1651 FolderImpl_get_ParentFolder
,
1653 FolderImpl_ParseName
,
1654 FolderImpl_NewFolder
,
1655 FolderImpl_MoveHere
,
1656 FolderImpl_CopyHere
,
1657 FolderImpl_GetDetailsOf
,
1658 FolderImpl_get_Self
,
1659 FolderImpl_get_OfflineStatus
,
1660 FolderImpl_Synchronize
,
1661 FolderImpl_get_HaveToShowWebViewBarricade
,
1662 FolderImpl_DismissedWebViewBarricade
,
1663 FolderImpl_get_ShowWebViewBarricade
,
1664 FolderImpl_put_ShowWebViewBarricade
1667 static HRESULT
Folder_Constructor(IShellFolder2
*folder
, LPITEMIDLIST pidl
, Folder
**ret
)
1669 PCUITEMID_CHILD last_part
;
1670 IShellFolder2
*parent
;
1677 This
= heap_alloc(sizeof(*This
));
1679 return E_OUTOFMEMORY
;
1681 This
->Folder3_iface
.lpVtbl
= &FolderImpl_Vtbl
;
1683 This
->folder
= folder
;
1684 This
->pidl
= ILClone(pidl
);
1686 hr
= SHBindToParent(pidl
, &IID_IShellFolder2
, (void **)&parent
, &last_part
);
1687 IShellFolder2_GetDisplayNameOf(parent
, last_part
, SHGDN_FORPARSING
, &strret
);
1688 StrRetToBSTR(&strret
, last_part
, &This
->path
);
1689 IShellFolder2_Release(parent
);
1691 IShellDispatch_Constructor(NULL
, &IID_IDispatch
, (void **)&This
->application
);
1693 *ret
= (Folder
*)&This
->Folder3_iface
;
1697 static HRESULT WINAPI
ShellDispatch_QueryInterface(IShellDispatch6
*iface
,
1698 REFIID riid
, LPVOID
*ppv
)
1700 ShellDispatch
*This
= impl_from_IShellDispatch6(iface
);
1702 TRACE("(%p,%s,%p)\n", iface
, debugstr_guid(riid
), ppv
);
1704 if (!ppv
) return E_INVALIDARG
;
1706 if (IsEqualIID(&IID_IUnknown
, riid
) ||
1707 IsEqualIID(&IID_IDispatch
, riid
) ||
1708 IsEqualIID(&IID_IShellDispatch
, riid
) ||
1709 IsEqualIID(&IID_IShellDispatch2
, riid
) ||
1710 IsEqualIID(&IID_IShellDispatch3
, riid
) ||
1711 IsEqualIID(&IID_IShellDispatch4
, riid
) ||
1712 IsEqualIID(&IID_IShellDispatch5
, riid
) ||
1713 IsEqualIID(&IID_IShellDispatch6
, riid
))
1714 *ppv
= &This
->IShellDispatch6_iface
;
1717 WARN("not implemented for %s\n", debugstr_guid(riid
));
1719 return E_NOINTERFACE
;
1722 IShellDispatch6_AddRef(iface
);
1726 static ULONG WINAPI
ShellDispatch_AddRef(IShellDispatch6
*iface
)
1728 ShellDispatch
*This
= impl_from_IShellDispatch6(iface
);
1729 ULONG ref
= InterlockedIncrement(&This
->ref
);
1731 TRACE("(%p), new refcount=%i\n", iface
, ref
);
1736 static ULONG WINAPI
ShellDispatch_Release(IShellDispatch6
*iface
)
1738 ShellDispatch
*This
= impl_from_IShellDispatch6(iface
);
1739 ULONG ref
= InterlockedDecrement(&This
->ref
);
1741 TRACE("(%p), new refcount=%i\n", iface
, ref
);
1749 static HRESULT WINAPI
ShellDispatch_GetTypeInfoCount(IShellDispatch6
*iface
,
1752 TRACE("(%p,%p)\n", iface
, pctinfo
);
1758 static HRESULT WINAPI
ShellDispatch_GetTypeInfo(IShellDispatch6
*iface
,
1759 UINT iTInfo
, LCID lcid
, ITypeInfo
**ppTInfo
)
1763 TRACE("(%p,%u,%d,%p)\n", iface
, iTInfo
, lcid
, ppTInfo
);
1765 hr
= get_typeinfo(IShellDispatch6_tid
, ppTInfo
);
1767 ITypeInfo_AddRef(*ppTInfo
);
1771 static HRESULT WINAPI
ShellDispatch_GetIDsOfNames(IShellDispatch6
*iface
,
1772 REFIID riid
, LPOLESTR
*rgszNames
, UINT cNames
, LCID lcid
, DISPID
*rgDispId
)
1777 TRACE("(%p,%s,%p,%u,%d,%p)\n", iface
, shdebugstr_guid(riid
), rgszNames
, cNames
, lcid
,
1780 hr
= get_typeinfo(IShellDispatch6_tid
, &ti
);
1782 hr
= ITypeInfo_GetIDsOfNames(ti
, rgszNames
, cNames
, rgDispId
);
1786 static HRESULT WINAPI
ShellDispatch_Invoke(IShellDispatch6
*iface
,
1787 DISPID dispIdMember
, REFIID riid
, LCID lcid
, WORD wFlags
,
1788 DISPPARAMS
*pDispParams
, VARIANT
*pVarResult
, EXCEPINFO
*pExcepInfo
,
1791 ShellDispatch
*This
= impl_from_IShellDispatch6(iface
);
1795 TRACE("(%p,%d,%s,%d,%u,%p,%p,%p,%p)\n", iface
, dispIdMember
, shdebugstr_guid(riid
), lcid
,
1796 wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
1798 hr
= get_typeinfo(IShellDispatch6_tid
, &ti
);
1800 hr
= ITypeInfo_Invoke(ti
, &This
->IShellDispatch6_iface
, dispIdMember
, wFlags
, pDispParams
,
1801 pVarResult
, pExcepInfo
, puArgErr
);
1805 static HRESULT WINAPI
ShellDispatch_get_Application(IShellDispatch6
*iface
, IDispatch
**disp
)
1807 TRACE("(%p,%p)\n", iface
, disp
);
1810 return E_INVALIDARG
;
1812 *disp
= (IDispatch
*)iface
;
1813 IDispatch_AddRef(*disp
);
1817 static HRESULT WINAPI
ShellDispatch_get_Parent(IShellDispatch6
*iface
, IDispatch
**disp
)
1819 TRACE("(%p,%p)\n", iface
, disp
);
1823 *disp
= (IDispatch
*)iface
;
1824 IDispatch_AddRef(*disp
);
1830 static HRESULT
create_folder_for_pidl(LPITEMIDLIST pidl
, Folder
**ret
)
1832 IShellFolder2
*folder
;
1833 IShellFolder
*desktop
;
1838 if (FAILED(hr
= SHGetDesktopFolder(&desktop
)))
1841 if (_ILIsDesktop(pidl
))
1842 hr
= IShellFolder_QueryInterface(desktop
, &IID_IShellFolder2
, (void **)&folder
);
1844 hr
= IShellFolder_BindToObject(desktop
, pidl
, NULL
, &IID_IShellFolder2
, (void **)&folder
);
1846 IShellFolder_Release(desktop
);
1851 return Folder_Constructor(folder
, pidl
, ret
);
1854 static HRESULT WINAPI
ShellDispatch_NameSpace(IShellDispatch6
*iface
,
1855 VARIANT dir
, Folder
**ret
)
1860 TRACE("(%p,%s,%p)\n", iface
, debugstr_variant(&dir
), ret
);
1867 if (FAILED(hr
= VariantChangeType(&dir
, &dir
, 0, VT_I4
)))
1872 if (FAILED(hr
= SHGetFolderLocation(NULL
, V_I4(&dir
), NULL
, 0, &pidl
)))
1877 if (FAILED(hr
= SHParseDisplayName(V_BSTR(&dir
), NULL
, &pidl
, 0, NULL
)))
1882 WARN("Ignoring directory value %s\n", debugstr_variant(&dir
));
1886 hr
= create_folder_for_pidl(pidl
, ret
);
1892 static BOOL
is_optional_argument(const VARIANT
*arg
)
1894 return V_VT(arg
) == VT_ERROR
&& V_ERROR(arg
) == DISP_E_PARAMNOTFOUND
;
1897 static HRESULT WINAPI
ShellDispatch_BrowseForFolder(IShellDispatch6
*iface
,
1898 LONG hwnd
, BSTR title
, LONG options
, VARIANT rootfolder
, Folder
**folder
)
1900 PIDLIST_ABSOLUTE selection
;
1901 BROWSEINFOW bi
= { 0 };
1904 TRACE("(%p,%x,%s,%x,%s,%p)\n", iface
, hwnd
, debugstr_w(title
), options
, debugstr_variant(&rootfolder
), folder
);
1908 if (!is_optional_argument(&rootfolder
))
1909 FIXME("root folder is ignored\n");
1911 bi
.hwndOwner
= LongToHandle(hwnd
);
1912 bi
.lpszTitle
= title
;
1913 bi
.ulFlags
= options
;
1915 selection
= SHBrowseForFolderW(&bi
);
1918 hr
= create_folder_for_pidl(selection
, folder
);
1927 static HRESULT WINAPI
ShellDispatch_Windows(IShellDispatch6
*iface
,
1930 FIXME("(%p,%p)\n", iface
, ppid
);
1936 static HRESULT WINAPI
ShellDispatch_Open(IShellDispatch6
*iface
, VARIANT dir
)
1938 FIXME("(%p,%s)\n", iface
, debugstr_variant(&dir
));
1943 static HRESULT WINAPI
ShellDispatch_Explore(IShellDispatch6
*iface
, VARIANT dir
)
1945 FIXME("(%p,%s)\n", iface
, debugstr_variant(&dir
));
1950 static HRESULT WINAPI
ShellDispatch_MinimizeAll(IShellDispatch6
*iface
)
1952 FIXME("(%p)\n", iface
);
1957 static HRESULT WINAPI
ShellDispatch_UndoMinimizeALL(IShellDispatch6
*iface
)
1959 FIXME("(%p)\n", iface
);
1964 static HRESULT WINAPI
ShellDispatch_FileRun(IShellDispatch6
*iface
)
1966 FIXME("(%p)\n", iface
);
1971 static HRESULT WINAPI
ShellDispatch_CascadeWindows(IShellDispatch6
*iface
)
1973 FIXME("(%p)\n", iface
);
1978 static HRESULT WINAPI
ShellDispatch_TileVertically(IShellDispatch6
*iface
)
1980 FIXME("(%p)\n", iface
);
1985 static HRESULT WINAPI
ShellDispatch_TileHorizontally(IShellDispatch6
*iface
)
1987 FIXME("(%p)\n", iface
);
1992 static HRESULT WINAPI
ShellDispatch_ShutdownWindows(IShellDispatch6
*iface
)
1994 FIXME("(%p)\n", iface
);
1999 static HRESULT WINAPI
ShellDispatch_Suspend(IShellDispatch6
*iface
)
2001 FIXME("(%p)\n", iface
);
2006 static HRESULT WINAPI
ShellDispatch_EjectPC(IShellDispatch6
*iface
)
2008 FIXME("(%p)\n", iface
);
2013 static HRESULT WINAPI
ShellDispatch_SetTime(IShellDispatch6
*iface
)
2015 FIXME("(%p)\n", iface
);
2020 static HRESULT WINAPI
ShellDispatch_TrayProperties(IShellDispatch6
*iface
)
2022 FIXME("(%p)\n", iface
);
2027 static HRESULT WINAPI
ShellDispatch_Help(IShellDispatch6
*iface
)
2029 FIXME("(%p)\n", iface
);
2034 static HRESULT WINAPI
ShellDispatch_FindFiles(IShellDispatch6
*iface
)
2036 FIXME("(%p)\n", iface
);
2041 static HRESULT WINAPI
ShellDispatch_FindComputer(IShellDispatch6
*iface
)
2043 FIXME("(%p)\n", iface
);
2048 static HRESULT WINAPI
ShellDispatch_RefreshMenu(IShellDispatch6
*iface
)
2050 FIXME("(%p)\n", iface
);
2055 static HRESULT WINAPI
ShellDispatch_ControlPanelItem(IShellDispatch6
*iface
,
2058 FIXME("(%p,%s)\n", iface
, debugstr_w(szDir
));
2063 static HRESULT WINAPI
ShellDispatch_IsRestricted(IShellDispatch6
*iface
, BSTR group
, BSTR restriction
, LONG
*value
)
2065 FIXME("(%s, %s, %p): stub\n", debugstr_w(group
), debugstr_w(restriction
), value
);
2069 static HRESULT WINAPI
ShellDispatch_ShellExecute(IShellDispatch6
*iface
,
2070 BSTR file
, VARIANT v_args
, VARIANT v_dir
, VARIANT v_op
, VARIANT v_show
)
2072 VARIANT args_str
, dir_str
, op_str
, show_int
;
2073 WCHAR
*args
= NULL
, *dir
= NULL
, *op
= NULL
;
2077 TRACE("(%s, %s, %s, %s, %s)\n", debugstr_w(file
), debugstr_variant(&v_args
),
2078 debugstr_variant(&v_dir
), debugstr_variant(&v_op
), debugstr_variant(&v_show
));
2080 VariantInit(&args_str
);
2081 VariantChangeType(&args_str
, &v_args
, 0, VT_BSTR
);
2082 if (V_VT(&args_str
) == VT_BSTR
)
2083 args
= V_BSTR(&args_str
);
2085 VariantInit(&dir_str
);
2086 VariantChangeType(&dir_str
, &v_dir
, 0, VT_BSTR
);
2087 if (V_VT(&dir_str
) == VT_BSTR
)
2088 dir
= V_BSTR(&dir_str
);
2090 VariantInit(&op_str
);
2091 VariantChangeType(&op_str
, &v_op
, 0, VT_BSTR
);
2092 if (V_VT(&op_str
) == VT_BSTR
)
2093 op
= V_BSTR(&op_str
);
2095 VariantInit(&show_int
);
2096 VariantChangeType(&show_int
, &v_show
, 0, VT_I4
);
2097 if (V_VT(&show_int
) == VT_I4
)
2098 show
= V_I4(&show_int
);
2100 ret
= ShellExecuteW(NULL
, op
, file
, args
, dir
, show
);
2102 VariantClear(&args_str
);
2103 VariantClear(&dir_str
);
2104 VariantClear(&op_str
);
2105 VariantClear(&show_int
);
2107 return (ULONG_PTR
)ret
> 32 ? S_OK
: S_FALSE
;
2110 static HRESULT WINAPI
ShellDispatch_FindPrinter(IShellDispatch6
*iface
, BSTR name
, BSTR location
, BSTR model
)
2112 FIXME("(%s, %s, %s): stub\n", debugstr_w(name
), debugstr_w(location
), debugstr_w(model
));
2116 static HRESULT WINAPI
ShellDispatch_GetSystemInformation(IShellDispatch6
*iface
, BSTR name
, VARIANT
*ret
)
2118 FIXME("(%s, %p): stub\n", debugstr_w(name
), ret
);
2122 static HRESULT WINAPI
ShellDispatch_ServiceStart(IShellDispatch6
*iface
, BSTR service
, VARIANT persistent
, VARIANT
*ret
)
2124 FIXME("(%s, %s, %p): stub\n", debugstr_w(service
), debugstr_variant(&persistent
), ret
);
2128 static HRESULT WINAPI
ShellDispatch_ServiceStop(IShellDispatch6
*iface
, BSTR service
, VARIANT persistent
, VARIANT
*ret
)
2130 FIXME("(%s, %s, %p): stub\n", debugstr_w(service
), debugstr_variant(&persistent
), ret
);
2134 static HRESULT WINAPI
ShellDispatch_IsServiceRunning(IShellDispatch6
*iface
, BSTR name
, VARIANT
*running
)
2136 SERVICE_STATUS_PROCESS status
;
2137 SC_HANDLE scm
, service
;
2140 TRACE("(%s, %p)\n", debugstr_w(name
), running
);
2142 V_VT(running
) = VT_BOOL
;
2143 V_BOOL(running
) = VARIANT_FALSE
;
2145 scm
= OpenSCManagerW(NULL
, NULL
, SC_MANAGER_CONNECT
);
2148 ERR("failed to connect to service manager\n");
2152 service
= OpenServiceW(scm
, name
, SERVICE_QUERY_STATUS
);
2155 ERR("Failed to open service %s (%u)\n", debugstr_w(name
), GetLastError());
2156 CloseServiceHandle(scm
);
2160 if (!QueryServiceStatusEx(service
, SC_STATUS_PROCESS_INFO
, (BYTE
*)&status
,
2161 sizeof(SERVICE_STATUS_PROCESS
), &dummy
))
2163 TRACE("failed to query service status (%u)\n", GetLastError());
2164 CloseServiceHandle(service
);
2165 CloseServiceHandle(scm
);
2169 if (status
.dwCurrentState
== SERVICE_RUNNING
)
2170 V_BOOL(running
) = VARIANT_TRUE
;
2172 CloseServiceHandle(service
);
2173 CloseServiceHandle(scm
);
2178 static HRESULT WINAPI
ShellDispatch_CanStartStopService(IShellDispatch6
*iface
, BSTR service
, VARIANT
*ret
)
2180 FIXME("(%s, %p): stub\n", debugstr_w(service
), ret
);
2184 static HRESULT WINAPI
ShellDispatch_ShowBrowserBar(IShellDispatch6
*iface
, BSTR clsid
, VARIANT show
, VARIANT
*ret
)
2186 FIXME("(%s, %s, %p): stub\n", debugstr_w(clsid
), debugstr_variant(&show
), ret
);
2190 static HRESULT WINAPI
ShellDispatch_AddToRecent(IShellDispatch6
*iface
, VARIANT file
, BSTR category
)
2192 FIXME("(%s, %s): stub\n", debugstr_variant(&file
), debugstr_w(category
));
2196 static HRESULT WINAPI
ShellDispatch_WindowsSecurity(IShellDispatch6
*iface
)
2202 static HRESULT WINAPI
ShellDispatch_ToggleDesktop(IShellDispatch6
*iface
)
2208 static HRESULT WINAPI
ShellDispatch_ExplorerPolicy(IShellDispatch6
*iface
, BSTR policy
, VARIANT
*value
)
2210 FIXME("(%s, %p): stub\n", debugstr_w(policy
), value
);
2214 static HRESULT WINAPI
ShellDispatch_GetSetting(IShellDispatch6
*iface
, LONG setting
, VARIANT_BOOL
*result
)
2216 FIXME("(%d %p): stub\n", setting
, result
);
2220 static HRESULT WINAPI
ShellDispatch_WindowSwitcher(IShellDispatch6
*iface
)
2226 static HRESULT WINAPI
ShellDispatch_SearchCommand(IShellDispatch6
*iface
)
2232 static const IShellDispatch6Vtbl ShellDispatchVtbl
= {
2233 ShellDispatch_QueryInterface
,
2234 ShellDispatch_AddRef
,
2235 ShellDispatch_Release
,
2236 ShellDispatch_GetTypeInfoCount
,
2237 ShellDispatch_GetTypeInfo
,
2238 ShellDispatch_GetIDsOfNames
,
2239 ShellDispatch_Invoke
,
2240 ShellDispatch_get_Application
,
2241 ShellDispatch_get_Parent
,
2242 ShellDispatch_NameSpace
,
2243 ShellDispatch_BrowseForFolder
,
2244 ShellDispatch_Windows
,
2246 ShellDispatch_Explore
,
2247 ShellDispatch_MinimizeAll
,
2248 ShellDispatch_UndoMinimizeALL
,
2249 ShellDispatch_FileRun
,
2250 ShellDispatch_CascadeWindows
,
2251 ShellDispatch_TileVertically
,
2252 ShellDispatch_TileHorizontally
,
2253 ShellDispatch_ShutdownWindows
,
2254 ShellDispatch_Suspend
,
2255 ShellDispatch_EjectPC
,
2256 ShellDispatch_SetTime
,
2257 ShellDispatch_TrayProperties
,
2259 ShellDispatch_FindFiles
,
2260 ShellDispatch_FindComputer
,
2261 ShellDispatch_RefreshMenu
,
2262 ShellDispatch_ControlPanelItem
,
2263 ShellDispatch_IsRestricted
,
2264 ShellDispatch_ShellExecute
,
2265 ShellDispatch_FindPrinter
,
2266 ShellDispatch_GetSystemInformation
,
2267 ShellDispatch_ServiceStart
,
2268 ShellDispatch_ServiceStop
,
2269 ShellDispatch_IsServiceRunning
,
2270 ShellDispatch_CanStartStopService
,
2271 ShellDispatch_ShowBrowserBar
,
2272 ShellDispatch_AddToRecent
,
2273 ShellDispatch_WindowsSecurity
,
2274 ShellDispatch_ToggleDesktop
,
2275 ShellDispatch_ExplorerPolicy
,
2276 ShellDispatch_GetSetting
,
2277 ShellDispatch_WindowSwitcher
,
2278 ShellDispatch_SearchCommand
2281 HRESULT WINAPI
IShellDispatch_Constructor(IUnknown
*outer
, REFIID riid
, void **ppv
)
2283 ShellDispatch
*This
;
2286 TRACE("(%p, %s)\n", outer
, debugstr_guid(riid
));
2290 if (outer
) return CLASS_E_NOAGGREGATION
;
2292 This
= heap_alloc(sizeof(*This
));
2293 if (!This
) return E_OUTOFMEMORY
;
2294 This
->IShellDispatch6_iface
.lpVtbl
= &ShellDispatchVtbl
;
2297 ret
= IShellDispatch6_QueryInterface(&This
->IShellDispatch6_iface
, riid
, ppv
);
2298 IShellDispatch6_Release(&This
->IShellDispatch6_iface
);