2 * IShellItem and IShellItemArray implementations
4 * Copyright 2008 Vincent Povirk for CodeWeavers
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
25 #define NONAMELESSUNION
29 #include "wine/debug.h"
32 #include "shell32_main.h"
35 WINE_DEFAULT_DEBUG_CHANNEL(shell
);
37 typedef struct _ShellItem
{
38 IShellItem2 IShellItem2_iface
;
41 IPersistIDList IPersistIDList_iface
;
42 IShellItemImageFactory IShellItemImageFactory_iface
;
45 typedef struct _CustomDestinationList
{
46 ICustomDestinationList ICustomDestinationList_iface
;
48 } CustomDestinationList
;
50 static inline ShellItem
*impl_from_IShellItem2(IShellItem2
*iface
)
52 return CONTAINING_RECORD(iface
, ShellItem
, IShellItem2_iface
);
55 static inline ShellItem
*impl_from_IPersistIDList( IPersistIDList
*iface
)
57 return CONTAINING_RECORD(iface
, ShellItem
, IPersistIDList_iface
);
60 static inline ShellItem
*impl_from_IShellItemImageFactory( IShellItemImageFactory
*iface
)
62 return CONTAINING_RECORD(iface
, ShellItem
, IShellItemImageFactory_iface
);
65 static inline CustomDestinationList
*impl_from_ICustomDestinationList( ICustomDestinationList
*iface
)
67 return CONTAINING_RECORD(iface
, CustomDestinationList
, ICustomDestinationList_iface
);
70 static HRESULT WINAPI
ShellItem_QueryInterface(IShellItem2
*iface
, REFIID riid
,
73 ShellItem
*This
= impl_from_IShellItem2(iface
);
75 TRACE("(%p, %s, %p)\n", iface
, debugstr_guid(riid
), ppv
);
77 if (!ppv
) return E_INVALIDARG
;
79 if (IsEqualIID(&IID_IUnknown
, riid
) || IsEqualIID(&IID_IShellItem
, riid
) ||
80 IsEqualIID(&IID_IShellItem2
, riid
))
82 *ppv
= &This
->IShellItem2_iface
;
84 else if (IsEqualIID(&IID_IPersist
, riid
) || IsEqualIID(&IID_IPersistIDList
, riid
))
86 *ppv
= &This
->IPersistIDList_iface
;
88 else if (IsEqualIID(&IID_IShellItemImageFactory
, riid
))
90 *ppv
= &This
->IShellItemImageFactory_iface
;
93 FIXME("not implemented for %s\n", shdebugstr_guid(riid
));
98 IUnknown_AddRef((IUnknown
*)*ppv
);
102 static ULONG WINAPI
ShellItem_AddRef(IShellItem2
*iface
)
104 ShellItem
*This
= impl_from_IShellItem2(iface
);
105 ULONG ref
= InterlockedIncrement(&This
->ref
);
107 TRACE("(%p), new refcount=%li\n", iface
, ref
);
112 static ULONG WINAPI
ShellItem_Release(IShellItem2
*iface
)
114 ShellItem
*This
= impl_from_IShellItem2(iface
);
115 ULONG ref
= InterlockedDecrement(&This
->ref
);
117 TRACE("(%p), new refcount=%li\n", iface
, ref
);
128 static HRESULT
ShellItem_get_parent_pidl(ShellItem
*This
, LPITEMIDLIST
*parent_pidl
)
130 *parent_pidl
= ILClone(This
->pidl
);
133 if (ILRemoveLastID(*parent_pidl
))
137 ILFree(*parent_pidl
);
145 return E_OUTOFMEMORY
;
149 static HRESULT
ShellItem_get_parent_shellfolder(ShellItem
*This
, IShellFolder
**ppsf
)
151 LPITEMIDLIST parent_pidl
;
152 IShellFolder
*desktop
;
155 ret
= ShellItem_get_parent_pidl(This
, &parent_pidl
);
158 ret
= SHGetDesktopFolder(&desktop
);
161 if (_ILIsDesktop(parent_pidl
))
167 ret
= IShellFolder_BindToObject(desktop
, parent_pidl
, NULL
, &IID_IShellFolder
, (void**)ppsf
);
168 IShellFolder_Release(desktop
);
177 static HRESULT
ShellItem_get_shellfolder(ShellItem
*This
, IBindCtx
*pbc
, IShellFolder
**ppsf
)
179 IShellFolder
*desktop
;
182 ret
= SHGetDesktopFolder(&desktop
);
185 if (_ILIsDesktop(This
->pidl
))
188 IShellFolder_AddRef(*ppsf
);
192 ret
= IShellFolder_BindToObject(desktop
, This
->pidl
, pbc
, &IID_IShellFolder
, (void**)ppsf
);
195 IShellFolder_Release(desktop
);
201 static HRESULT WINAPI
ShellItem_BindToHandler(IShellItem2
*iface
, IBindCtx
*pbc
,
202 REFGUID rbhid
, REFIID riid
, void **ppvOut
)
204 ShellItem
*This
= impl_from_IShellItem2(iface
);
206 TRACE("(%p,%p,%s,%p,%p)\n", iface
, pbc
, shdebugstr_guid(rbhid
), riid
, ppvOut
);
209 if (IsEqualGUID(rbhid
, &BHID_SFObject
))
212 ret
= ShellItem_get_shellfolder(This
, pbc
, &psf
);
215 ret
= IShellFolder_QueryInterface(psf
, riid
, ppvOut
);
216 IShellFolder_Release(psf
);
220 else if (IsEqualGUID(rbhid
, &BHID_SFUIObject
))
222 IShellFolder
*psf_parent
;
223 if (_ILIsDesktop(This
->pidl
))
224 ret
= SHGetDesktopFolder(&psf_parent
);
226 ret
= ShellItem_get_parent_shellfolder(This
, &psf_parent
);
230 LPCITEMIDLIST pidl
= ILFindLastID(This
->pidl
);
231 ret
= IShellFolder_GetUIObjectOf(psf_parent
, NULL
, 1, &pidl
, riid
, NULL
, ppvOut
);
232 IShellFolder_Release(psf_parent
);
236 else if (IsEqualGUID(rbhid
, &BHID_DataObject
))
238 return ShellItem_BindToHandler(&This
->IShellItem2_iface
, pbc
, &BHID_SFUIObject
,
239 &IID_IDataObject
, ppvOut
);
242 FIXME("Unsupported BHID %s.\n", debugstr_guid(rbhid
));
244 return MK_E_NOOBJECT
;
247 static HRESULT WINAPI
ShellItem_GetParent(IShellItem2
*iface
, IShellItem
**ppsi
)
249 ShellItem
*This
= impl_from_IShellItem2(iface
);
250 LPITEMIDLIST parent_pidl
;
253 TRACE("(%p,%p)\n", iface
, ppsi
);
255 ret
= ShellItem_get_parent_pidl(This
, &parent_pidl
);
258 ret
= SHCreateShellItem(NULL
, NULL
, parent_pidl
, ppsi
);
265 static HRESULT WINAPI
ShellItem_GetDisplayName(IShellItem2
*iface
, SIGDN sigdnName
,
268 ShellItem
*This
= impl_from_IShellItem2(iface
);
269 TRACE("(%p,%x,%p)\n", iface
, sigdnName
, ppszName
);
271 return SHGetNameFromIDList(This
->pidl
, sigdnName
, ppszName
);
274 static HRESULT WINAPI
ShellItem_GetAttributes(IShellItem2
*iface
, SFGAOF sfgaoMask
,
275 SFGAOF
*psfgaoAttribs
)
277 ShellItem
*This
= impl_from_IShellItem2(iface
);
278 IShellFolder
*parent_folder
;
279 LPITEMIDLIST child_pidl
;
282 TRACE("(%p,%lx,%p)\n", iface
, sfgaoMask
, psfgaoAttribs
);
284 if (_ILIsDesktop(This
->pidl
))
285 ret
= SHGetDesktopFolder(&parent_folder
);
287 ret
= ShellItem_get_parent_shellfolder(This
, &parent_folder
);
290 child_pidl
= ILFindLastID(This
->pidl
);
291 *psfgaoAttribs
= sfgaoMask
;
292 ret
= IShellFolder_GetAttributesOf(parent_folder
, 1, (LPCITEMIDLIST
*)&child_pidl
, psfgaoAttribs
);
293 *psfgaoAttribs
&= sfgaoMask
;
294 IShellFolder_Release(parent_folder
);
298 if(sfgaoMask
== *psfgaoAttribs
)
308 static HRESULT WINAPI
ShellItem_Compare(IShellItem2
*iface
, IShellItem
*oth
,
309 SICHINTF hint
, int *piOrder
)
311 LPWSTR dispname
, dispname_oth
;
313 TRACE("(%p,%p,%lx,%p)\n", iface
, oth
, hint
, piOrder
);
315 if(hint
& (SICHINT_CANONICAL
| SICHINT_ALLFIELDS
))
316 FIXME("Unsupported flags 0x%08lx\n", hint
);
318 ret
= IShellItem2_GetDisplayName(iface
, SIGDN_DESKTOPABSOLUTEEDITING
, &dispname
);
321 ret
= IShellItem_GetDisplayName(oth
, SIGDN_DESKTOPABSOLUTEEDITING
, &dispname_oth
);
324 *piOrder
= lstrcmpiW(dispname
, dispname_oth
);
325 CoTaskMemFree(dispname_oth
);
327 CoTaskMemFree(dispname
);
330 if(SUCCEEDED(ret
) && *piOrder
&&
331 (hint
& SICHINT_TEST_FILESYSPATH_IF_NOT_EQUAL
))
333 LPWSTR dispname
, dispname_oth
;
335 TRACE("Testing filesystem path.\n");
336 ret
= IShellItem2_GetDisplayName(iface
, SIGDN_FILESYSPATH
, &dispname
);
339 ret
= IShellItem_GetDisplayName(oth
, SIGDN_FILESYSPATH
, &dispname_oth
);
342 *piOrder
= lstrcmpiW(dispname
, dispname_oth
);
343 CoTaskMemFree(dispname_oth
);
345 CoTaskMemFree(dispname
);
358 static HRESULT WINAPI
ShellItem2_GetPropertyStore(IShellItem2
*iface
, GETPROPERTYSTOREFLAGS flags
,
359 REFIID riid
, void **ppv
)
361 ShellItem
*This
= impl_from_IShellItem2(iface
);
362 FIXME("Stub: %p (%d, %s, %p)\n", This
, flags
, shdebugstr_guid(riid
), ppv
);
366 static HRESULT WINAPI
ShellItem2_GetPropertyStoreWithCreateObject(IShellItem2
*iface
,
367 GETPROPERTYSTOREFLAGS flags
, IUnknown
*punkCreateObject
, REFIID riid
, void **ppv
)
369 ShellItem
*This
= impl_from_IShellItem2(iface
);
370 FIXME("Stub: %p (%08x, %p, %s, %p)\n",
371 This
, flags
, punkCreateObject
, shdebugstr_guid(riid
), ppv
);
375 static HRESULT WINAPI
ShellItem2_GetPropertyStoreForKeys(IShellItem2
*iface
, const PROPERTYKEY
*rgKeys
,
376 UINT cKeys
, GETPROPERTYSTOREFLAGS flags
, REFIID riid
, void **ppv
)
378 ShellItem
*This
= impl_from_IShellItem2(iface
);
379 FIXME("Stub: %p (%p, %d, %08x, %s, %p)\n",
380 This
, rgKeys
, cKeys
, flags
, shdebugstr_guid(riid
), ppv
);
384 static HRESULT WINAPI
ShellItem2_GetPropertyDescriptionList(IShellItem2
*iface
,
385 REFPROPERTYKEY keyType
, REFIID riid
, void **ppv
)
387 ShellItem
*This
= impl_from_IShellItem2(iface
);
388 FIXME("Stub: %p (%p, %s, %p)\n", This
, keyType
, debugstr_guid(riid
), ppv
);
392 static HRESULT WINAPI
ShellItem2_Update(IShellItem2
*iface
, IBindCtx
*pbc
)
394 ShellItem
*This
= impl_from_IShellItem2(iface
);
395 FIXME("Stub: %p (%p)\n", This
, pbc
);
399 static HRESULT WINAPI
ShellItem2_GetProperty(IShellItem2
*iface
, REFPROPERTYKEY key
, PROPVARIANT
*ppropvar
)
401 ShellItem
*This
= impl_from_IShellItem2(iface
);
402 FIXME("Stub: %p (%p, %p)\n", This
, key
, ppropvar
);
406 static HRESULT WINAPI
ShellItem2_GetCLSID(IShellItem2
*iface
, REFPROPERTYKEY key
, CLSID
*pclsid
)
408 ShellItem
*This
= impl_from_IShellItem2(iface
);
409 FIXME("Stub: %p (%p, %p)\n", This
, key
, pclsid
);
413 static HRESULT WINAPI
ShellItem2_GetFileTime(IShellItem2
*iface
, REFPROPERTYKEY key
, FILETIME
*pft
)
415 ShellItem
*This
= impl_from_IShellItem2(iface
);
416 FIXME("Stub: %p (%p, %p)\n", This
, key
, pft
);
420 static HRESULT WINAPI
ShellItem2_GetInt32(IShellItem2
*iface
, REFPROPERTYKEY key
, int *pi
)
422 ShellItem
*This
= impl_from_IShellItem2(iface
);
423 FIXME("Stub: %p (%p, %p)\n", This
, key
, pi
);
427 static HRESULT WINAPI
ShellItem2_GetString(IShellItem2
*iface
, REFPROPERTYKEY key
, LPWSTR
*ppsz
)
429 ShellItem
*This
= impl_from_IShellItem2(iface
);
430 FIXME("Stub: %p (%p, %p)\n", This
, key
, ppsz
);
434 static HRESULT WINAPI
ShellItem2_GetUInt32(IShellItem2
*iface
, REFPROPERTYKEY key
, ULONG
*pui
)
436 ShellItem
*This
= impl_from_IShellItem2(iface
);
437 FIXME("Stub: %p (%p, %p)\n", This
, key
, pui
);
441 static HRESULT WINAPI
ShellItem2_GetUInt64(IShellItem2
*iface
, REFPROPERTYKEY key
, ULONGLONG
*pull
)
443 ShellItem
*This
= impl_from_IShellItem2(iface
);
444 FIXME("Stub: %p (%p, %p)\n", This
, key
, pull
);
448 static HRESULT WINAPI
ShellItem2_GetBool(IShellItem2
*iface
, REFPROPERTYKEY key
, BOOL
*pf
)
450 ShellItem
*This
= impl_from_IShellItem2(iface
);
451 FIXME("Stub: %p (%p, %p)\n", This
, key
, pf
);
456 static const IShellItem2Vtbl ShellItem2_Vtbl
= {
457 ShellItem_QueryInterface
,
460 ShellItem_BindToHandler
,
462 ShellItem_GetDisplayName
,
463 ShellItem_GetAttributes
,
465 ShellItem2_GetPropertyStore
,
466 ShellItem2_GetPropertyStoreWithCreateObject
,
467 ShellItem2_GetPropertyStoreForKeys
,
468 ShellItem2_GetPropertyDescriptionList
,
470 ShellItem2_GetProperty
,
472 ShellItem2_GetFileTime
,
474 ShellItem2_GetString
,
475 ShellItem2_GetUInt32
,
476 ShellItem2_GetUInt64
,
480 static HRESULT WINAPI
ShellItem_IPersistIDList_QueryInterface(IPersistIDList
*iface
,
481 REFIID riid
, void **ppv
)
483 ShellItem
*This
= impl_from_IPersistIDList(iface
);
484 return IShellItem2_QueryInterface(&This
->IShellItem2_iface
, riid
, ppv
);
487 static ULONG WINAPI
ShellItem_IPersistIDList_AddRef(IPersistIDList
*iface
)
489 ShellItem
*This
= impl_from_IPersistIDList(iface
);
490 return IShellItem2_AddRef(&This
->IShellItem2_iface
);
493 static ULONG WINAPI
ShellItem_IPersistIDList_Release(IPersistIDList
*iface
)
495 ShellItem
*This
= impl_from_IPersistIDList(iface
);
496 return IShellItem2_Release(&This
->IShellItem2_iface
);
499 static HRESULT WINAPI
ShellItem_IPersistIDList_GetClassID(IPersistIDList
* iface
,
502 *pClassID
= CLSID_ShellItem
;
506 static HRESULT WINAPI
ShellItem_IPersistIDList_SetIDList(IPersistIDList
* iface
,
509 ShellItem
*This
= impl_from_IPersistIDList(iface
);
510 LPITEMIDLIST new_pidl
;
512 TRACE("(%p,%p)\n", This
, pidl
);
514 new_pidl
= ILClone(pidl
);
519 This
->pidl
= new_pidl
;
523 return E_OUTOFMEMORY
;
526 static HRESULT WINAPI
ShellItem_IPersistIDList_GetIDList(IPersistIDList
* iface
,
529 ShellItem
*This
= impl_from_IPersistIDList(iface
);
531 TRACE("(%p,%p)\n", This
, ppidl
);
533 *ppidl
= ILClone(This
->pidl
);
537 return E_OUTOFMEMORY
;
540 static const IPersistIDListVtbl ShellItem_IPersistIDList_Vtbl
= {
541 ShellItem_IPersistIDList_QueryInterface
,
542 ShellItem_IPersistIDList_AddRef
,
543 ShellItem_IPersistIDList_Release
,
544 ShellItem_IPersistIDList_GetClassID
,
545 ShellItem_IPersistIDList_SetIDList
,
546 ShellItem_IPersistIDList_GetIDList
549 static HRESULT WINAPI
ShellItem_IShellItemImageFactory_QueryInterface(IShellItemImageFactory
*iface
,
550 REFIID riid
, void **ppv
)
552 ShellItem
*This
= impl_from_IShellItemImageFactory(iface
);
553 return IShellItem2_QueryInterface(&This
->IShellItem2_iface
, riid
, ppv
);
556 static ULONG WINAPI
ShellItem_IShellItemImageFactory_AddRef(IShellItemImageFactory
*iface
)
558 ShellItem
*This
= impl_from_IShellItemImageFactory(iface
);
559 return IShellItem2_AddRef(&This
->IShellItem2_iface
);
562 static ULONG WINAPI
ShellItem_IShellItemImageFactory_Release(IShellItemImageFactory
*iface
)
564 ShellItem
*This
= impl_from_IShellItemImageFactory(iface
);
565 return IShellItem2_Release(&This
->IShellItem2_iface
);
568 static HRESULT WINAPI
ShellItem_IShellItemImageFactory_GetImage(IShellItemImageFactory
*iface
,
569 SIZE size
, SIIGBF flags
, HBITMAP
*phbm
)
571 ShellItem
*This
= impl_from_IShellItemImageFactory(iface
);
572 static const BITMAPINFOHEADER dummy_bmi_header
= {
573 .biSize
= sizeof(dummy_bmi_header
),
578 .biCompression
= BI_RGB
583 FIXME("%p ({%lu, %lu} %d %p): stub\n", This
, size
.cx
, size
.cy
, flags
, phbm
);
585 if (!(*phbm
= CreateDIBSection(NULL
, (const BITMAPINFO
*)&dummy_bmi_header
,
586 DIB_RGB_COLORS
, NULL
, NULL
, 0)))
588 return E_OUTOFMEMORY
;
594 static const IShellItemImageFactoryVtbl ShellItem_IShellItemImageFactory_Vtbl
= {
595 ShellItem_IShellItemImageFactory_QueryInterface
,
596 ShellItem_IShellItemImageFactory_AddRef
,
597 ShellItem_IShellItemImageFactory_Release
,
598 ShellItem_IShellItemImageFactory_GetImage
,
602 HRESULT WINAPI
IShellItem_Constructor(IUnknown
*pUnkOuter
, REFIID riid
, void **ppv
)
607 TRACE("(%p,%s)\n",pUnkOuter
, debugstr_guid(riid
));
611 if (pUnkOuter
) return CLASS_E_NOAGGREGATION
;
613 This
= heap_alloc(sizeof(*This
));
614 This
->IShellItem2_iface
.lpVtbl
= &ShellItem2_Vtbl
;
617 This
->IPersistIDList_iface
.lpVtbl
= &ShellItem_IPersistIDList_Vtbl
;
618 This
->IShellItemImageFactory_iface
.lpVtbl
= &ShellItem_IShellItemImageFactory_Vtbl
;
620 ret
= IShellItem2_QueryInterface(&This
->IShellItem2_iface
, riid
, ppv
);
621 IShellItem2_Release(&This
->IShellItem2_iface
);
626 HRESULT WINAPI
SHCreateShellItem(LPCITEMIDLIST pidlParent
,
627 IShellFolder
*psfParent
, LPCITEMIDLIST pidl
, IShellItem
**ppsi
)
629 LPITEMIDLIST new_pidl
;
632 TRACE("(%p,%p,%p,%p)\n", pidlParent
, psfParent
, pidl
, ppsi
);
640 else if (pidlParent
|| psfParent
)
642 LPITEMIDLIST temp_parent
=NULL
;
645 IPersistFolder2
* ppf2Parent
;
647 if (FAILED(IShellFolder_QueryInterface(psfParent
, &IID_IPersistFolder2
, (void**)&ppf2Parent
)))
649 FIXME("couldn't get IPersistFolder2 interface of parent\n");
650 return E_NOINTERFACE
;
653 if (FAILED(IPersistFolder2_GetCurFolder(ppf2Parent
, &temp_parent
)))
655 FIXME("couldn't get parent PIDL\n");
656 IPersistFolder2_Release(ppf2Parent
);
657 return E_NOINTERFACE
;
660 pidlParent
= temp_parent
;
661 IPersistFolder2_Release(ppf2Parent
);
664 new_pidl
= ILCombine(pidlParent
, pidl
);
668 return E_OUTOFMEMORY
;
672 new_pidl
= ILClone(pidl
);
674 return E_OUTOFMEMORY
;
677 ret
= SHCreateItemFromIDList(new_pidl
, &IID_IShellItem
, (void**)ppsi
);
683 HRESULT WINAPI
SHCreateItemFromParsingName(PCWSTR pszPath
,
684 IBindCtx
*pbc
, REFIID riid
, void **ppv
)
691 ret
= SHParseDisplayName(pszPath
, pbc
, &pidl
, 0, NULL
);
694 ret
= SHCreateItemFromIDList(pidl
, riid
, ppv
);
700 HRESULT WINAPI
SHCreateItemFromRelativeName(IShellItem
*parent
, PCWSTR name
, IBindCtx
*pbc
,
701 REFIID riid
, void **ppv
)
703 LPITEMIDLIST pidl_folder
= NULL
, pidl
= NULL
;
704 IShellFolder
*desktop
= NULL
, *folder
= NULL
;
707 TRACE("(%p, %s, %p, %s, %p)\n", parent
, wine_dbgstr_w(name
), pbc
, debugstr_guid(riid
), ppv
);
715 hr
= SHGetIDListFromObject((IUnknown
*)parent
, &pidl_folder
);
719 hr
= SHGetDesktopFolder(&desktop
);
723 if(!_ILIsDesktop(pidl_folder
))
725 hr
= IShellFolder_BindToObject(desktop
, pidl_folder
, NULL
, &IID_IShellFolder
,
731 hr
= IShellFolder_ParseDisplayName(folder
? folder
: desktop
, NULL
, pbc
, (LPWSTR
)name
,
735 hr
= SHCreateItemFromIDList(pidl
, riid
, ppv
);
743 IShellFolder_Release(desktop
);
745 IShellFolder_Release(folder
);
749 HRESULT WINAPI
SHCreateItemFromIDList(PCIDLIST_ABSOLUTE pidl
, REFIID riid
, void **ppv
)
751 IPersistIDList
*persist
;
758 ret
= IShellItem_Constructor(NULL
, &IID_IPersistIDList
, (void**)&persist
);
762 ret
= IPersistIDList_SetIDList(persist
, pidl
);
765 IPersistIDList_Release(persist
);
769 ret
= IPersistIDList_QueryInterface(persist
, riid
, ppv
);
770 IPersistIDList_Release(persist
);
774 HRESULT WINAPI
SHCreateItemInKnownFolder(REFKNOWNFOLDERID rfid
, DWORD flags
,
775 PCWSTR filename
, REFIID riid
, void **ppv
)
778 IShellItem
*parent
= NULL
;
779 LPITEMIDLIST pidl
= NULL
;
781 TRACE("(%p, %lx, %s, %s, %p)\n", rfid
, flags
, wine_dbgstr_w(filename
),
782 debugstr_guid(riid
), ppv
);
788 hr
= SHGetKnownFolderIDList(rfid
, flags
, NULL
, &pidl
);
792 hr
= SHCreateItemFromIDList(pidl
, &IID_IShellItem
, (void**)&parent
);
800 hr
= SHCreateItemFromRelativeName(parent
, filename
, NULL
, riid
, ppv
);
802 hr
= IShellItem_QueryInterface(parent
, riid
, ppv
);
805 IShellItem_Release(parent
);
809 HRESULT WINAPI
SHGetItemFromDataObject(IDataObject
*pdtobj
,
810 DATAOBJ_GET_ITEM_FLAGS dwFlags
, REFIID riid
, void **ppv
)
816 TRACE("%p, %x, %s, %p\n", pdtobj
, dwFlags
, debugstr_guid(riid
), ppv
);
821 fmt
.cfFormat
= RegisterClipboardFormatW(CFSTR_SHELLIDLISTW
);
823 fmt
.dwAspect
= DVASPECT_CONTENT
;
825 fmt
.tymed
= TYMED_HGLOBAL
;
827 ret
= IDataObject_GetData(pdtobj
, &fmt
, &medium
);
830 LPIDA pida
= GlobalLock(medium
.u
.hGlobal
);
832 if((pida
->cidl
> 1 && !(dwFlags
& DOGIF_ONLY_IF_ONE
)) ||
837 /* Get the first pidl (parent + child1) */
838 pidl
= ILCombine((LPCITEMIDLIST
) ((LPBYTE
)pida
+pida
->aoffset
[0]),
839 (LPCITEMIDLIST
) ((LPBYTE
)pida
+pida
->aoffset
[1]));
841 ret
= SHCreateItemFromIDList(pidl
, riid
, ppv
);
849 GlobalUnlock(medium
.u
.hGlobal
);
850 GlobalFree(medium
.u
.hGlobal
);
853 if(FAILED(ret
) && !(dwFlags
& DOGIF_NO_HDROP
))
855 TRACE("Attempting to fall back on CF_HDROP.\n");
857 fmt
.cfFormat
= CF_HDROP
;
859 fmt
.dwAspect
= DVASPECT_CONTENT
;
861 fmt
.tymed
= TYMED_HGLOBAL
;
863 ret
= IDataObject_GetData(pdtobj
, &fmt
, &medium
);
866 DROPFILES
*df
= GlobalLock(medium
.u
.hGlobal
);
867 LPBYTE files
= (LPBYTE
)df
+ df
->pFiles
;
868 BOOL multiple_files
= FALSE
;
873 WCHAR filename
[MAX_PATH
];
874 PCSTR first_file
= (PCSTR
)files
;
875 if(*(files
+ lstrlenA(first_file
) + 1) != 0)
876 multiple_files
= TRUE
;
878 if( !(multiple_files
&& (dwFlags
& DOGIF_ONLY_IF_ONE
)) )
880 MultiByteToWideChar(CP_ACP
, 0, first_file
, -1, filename
, MAX_PATH
);
881 ret
= SHCreateItemFromParsingName(filename
, NULL
, riid
, ppv
);
886 PCWSTR first_file
= (PCWSTR
)files
;
887 if(*((PCWSTR
)files
+ lstrlenW(first_file
) + 1) != 0)
888 multiple_files
= TRUE
;
890 if( !(multiple_files
&& (dwFlags
& DOGIF_ONLY_IF_ONE
)) )
891 ret
= SHCreateItemFromParsingName(first_file
, NULL
, riid
, ppv
);
894 GlobalUnlock(medium
.u
.hGlobal
);
895 GlobalFree(medium
.u
.hGlobal
);
899 if(FAILED(ret
) && !(dwFlags
& DOGIF_NO_URL
))
901 FIXME("Failed to create item, should try CF_URL.\n");
907 HRESULT WINAPI
SHGetItemFromObject(IUnknown
*punk
, REFIID riid
, void **ppv
)
912 ret
= SHGetIDListFromObject(punk
, &pidl
);
915 ret
= SHCreateItemFromIDList(pidl
, riid
, ppv
);
922 /*************************************************************************
923 * IEnumShellItems implementation
926 IEnumShellItems IEnumShellItems_iface
;
929 IShellItemArray
*array
;
932 } IEnumShellItemsImpl
;
934 static inline IEnumShellItemsImpl
*impl_from_IEnumShellItems(IEnumShellItems
*iface
)
936 return CONTAINING_RECORD(iface
, IEnumShellItemsImpl
, IEnumShellItems_iface
);
939 static HRESULT WINAPI
IEnumShellItems_fnQueryInterface(IEnumShellItems
*iface
,
943 IEnumShellItemsImpl
*This
= impl_from_IEnumShellItems(iface
);
944 TRACE("%p (%s, %p)\n", This
, shdebugstr_guid(riid
), ppvObject
);
947 if(IsEqualIID(riid
, &IID_IEnumShellItems
) ||
948 IsEqualIID(riid
, &IID_IUnknown
))
950 *ppvObject
= &This
->IEnumShellItems_iface
;
955 IUnknown_AddRef((IUnknown
*)*ppvObject
);
959 return E_NOINTERFACE
;
962 static ULONG WINAPI
IEnumShellItems_fnAddRef(IEnumShellItems
*iface
)
964 IEnumShellItemsImpl
*This
= impl_from_IEnumShellItems(iface
);
965 LONG ref
= InterlockedIncrement(&This
->ref
);
966 TRACE("%p - ref %ld\n", This
, ref
);
971 static ULONG WINAPI
IEnumShellItems_fnRelease(IEnumShellItems
*iface
)
973 IEnumShellItemsImpl
*This
= impl_from_IEnumShellItems(iface
);
974 LONG ref
= InterlockedDecrement(&This
->ref
);
975 TRACE("%p - ref %ld\n", This
, ref
);
980 IShellItemArray_Release(This
->array
);
988 static HRESULT WINAPI
IEnumShellItems_fnNext(IEnumShellItems
* iface
,
993 IEnumShellItemsImpl
*This
= impl_from_IEnumShellItems(iface
);
994 HRESULT hr
= S_FALSE
;
997 TRACE("%p (%ld %p %p)\n", This
, celt
, rgelt
, pceltFetched
);
999 if(pceltFetched
== NULL
&& celt
!= 1)
1000 return E_INVALIDARG
;
1002 for(i
= This
->position
; fetched
< celt
&& i
< This
->count
; i
++) {
1003 hr
= IShellItemArray_GetItemAt(This
->array
, i
, &rgelt
[fetched
]);
1012 if(pceltFetched
!= NULL
)
1013 *pceltFetched
= fetched
;
1024 static HRESULT WINAPI
IEnumShellItems_fnSkip(IEnumShellItems
* iface
, ULONG celt
)
1026 IEnumShellItemsImpl
*This
= impl_from_IEnumShellItems(iface
);
1027 TRACE("%p (%ld)\n", This
, celt
);
1029 This
->position
= min(This
->position
+ celt
, This
->count
-1);
1034 static HRESULT WINAPI
IEnumShellItems_fnReset(IEnumShellItems
* iface
)
1036 IEnumShellItemsImpl
*This
= impl_from_IEnumShellItems(iface
);
1037 TRACE("%p\n", This
);
1044 static HRESULT WINAPI
IEnumShellItems_fnClone(IEnumShellItems
* iface
, IEnumShellItems
**ppenum
)
1046 IEnumShellItemsImpl
*This
= impl_from_IEnumShellItems(iface
);
1047 TRACE("%p (%p)\n", This
, ppenum
);
1049 /* Not implemented anywhere */
1055 static const IEnumShellItemsVtbl vt_IEnumShellItems
= {
1056 IEnumShellItems_fnQueryInterface
,
1057 IEnumShellItems_fnAddRef
,
1058 IEnumShellItems_fnRelease
,
1059 IEnumShellItems_fnNext
,
1060 IEnumShellItems_fnSkip
,
1061 IEnumShellItems_fnReset
,
1062 IEnumShellItems_fnClone
1065 static HRESULT
IEnumShellItems_Constructor(IShellItemArray
*array
, IEnumShellItems
**ppesi
)
1067 IEnumShellItemsImpl
*This
;
1070 This
= heap_alloc(sizeof(*This
));
1072 return E_OUTOFMEMORY
;
1075 This
->IEnumShellItems_iface
.lpVtbl
= &vt_IEnumShellItems
;
1076 This
->array
= array
;
1079 IShellItemArray_AddRef(This
->array
);
1080 IShellItemArray_GetCount(This
->array
, &This
->count
);
1082 ret
= IEnumShellItems_QueryInterface(&This
->IEnumShellItems_iface
, &IID_IEnumShellItems
, (void**)ppesi
);
1083 IEnumShellItems_Release(&This
->IEnumShellItems_iface
);
1089 /*************************************************************************
1090 * IShellItemArray implementation
1093 IShellItemArray IShellItemArray_iface
;
1098 } IShellItemArrayImpl
;
1100 static inline IShellItemArrayImpl
*impl_from_IShellItemArray(IShellItemArray
*iface
)
1102 return CONTAINING_RECORD(iface
, IShellItemArrayImpl
, IShellItemArray_iface
);
1105 static HRESULT WINAPI
IShellItemArray_fnQueryInterface(IShellItemArray
*iface
,
1109 IShellItemArrayImpl
*This
= impl_from_IShellItemArray(iface
);
1110 TRACE("%p (%s, %p)\n", This
, shdebugstr_guid(riid
), ppvObject
);
1113 if(IsEqualIID(riid
, &IID_IShellItemArray
) ||
1114 IsEqualIID(riid
, &IID_IUnknown
))
1116 *ppvObject
= &This
->IShellItemArray_iface
;
1121 IUnknown_AddRef((IUnknown
*)*ppvObject
);
1125 return E_NOINTERFACE
;
1128 static ULONG WINAPI
IShellItemArray_fnAddRef(IShellItemArray
*iface
)
1130 IShellItemArrayImpl
*This
= impl_from_IShellItemArray(iface
);
1131 LONG ref
= InterlockedIncrement(&This
->ref
);
1132 TRACE("%p - ref %ld\n", This
, ref
);
1137 static ULONG WINAPI
IShellItemArray_fnRelease(IShellItemArray
*iface
)
1139 IShellItemArrayImpl
*This
= impl_from_IShellItemArray(iface
);
1140 LONG ref
= InterlockedDecrement(&This
->ref
);
1141 TRACE("%p - ref %ld\n", This
, ref
);
1146 TRACE("Freeing.\n");
1148 for(i
= 0; i
< This
->item_count
; i
++)
1149 IShellItem_Release(This
->array
[i
]);
1151 heap_free(This
->array
);
1159 static HRESULT WINAPI
IShellItemArray_fnBindToHandler(IShellItemArray
*iface
,
1165 IShellItemArrayImpl
*This
= impl_from_IShellItemArray(iface
);
1166 FIXME("Stub: %p (%p, %s, %s, %p)\n",
1167 This
, pbc
, shdebugstr_guid(bhid
), shdebugstr_guid(riid
), ppvOut
);
1172 static HRESULT WINAPI
IShellItemArray_fnGetPropertyStore(IShellItemArray
*iface
,
1173 GETPROPERTYSTOREFLAGS flags
,
1177 IShellItemArrayImpl
*This
= impl_from_IShellItemArray(iface
);
1178 FIXME("Stub: %p (%x, %s, %p)\n", This
, flags
, shdebugstr_guid(riid
), ppv
);
1183 static HRESULT WINAPI
IShellItemArray_fnGetPropertyDescriptionList(IShellItemArray
*iface
,
1184 REFPROPERTYKEY keyType
,
1188 IShellItemArrayImpl
*This
= impl_from_IShellItemArray(iface
);
1189 FIXME("Stub: %p (%p, %s, %p)\n",
1190 This
, keyType
, shdebugstr_guid(riid
), ppv
);
1195 static HRESULT WINAPI
IShellItemArray_fnGetAttributes(IShellItemArray
*iface
,
1196 SIATTRIBFLAGS AttribFlags
,
1198 SFGAOF
*psfgaoAttribs
)
1200 IShellItemArrayImpl
*This
= impl_from_IShellItemArray(iface
);
1204 TRACE("%p (%x, %lx, %p)\n", This
, AttribFlags
, sfgaoMask
, psfgaoAttribs
);
1206 if(AttribFlags
& ~(SIATTRIBFLAGS_AND
|SIATTRIBFLAGS_OR
))
1207 FIXME("%08x contains unsupported attribution flags\n", AttribFlags
);
1209 for(i
= 0; i
< This
->item_count
; i
++)
1211 hr
= IShellItem_GetAttributes(This
->array
[i
], sfgaoMask
, &attr
);
1217 *psfgaoAttribs
= attr
;
1221 switch(AttribFlags
& SIATTRIBFLAGS_MASK
)
1223 case SIATTRIBFLAGS_AND
:
1224 *psfgaoAttribs
&= attr
;
1226 case SIATTRIBFLAGS_OR
:
1227 *psfgaoAttribs
|= attr
;
1234 if(*psfgaoAttribs
== sfgaoMask
)
1243 static HRESULT WINAPI
IShellItemArray_fnGetCount(IShellItemArray
*iface
,
1246 IShellItemArrayImpl
*This
= impl_from_IShellItemArray(iface
);
1247 TRACE("%p (%p)\n", This
, pdwNumItems
);
1249 *pdwNumItems
= This
->item_count
;
1254 static HRESULT WINAPI
IShellItemArray_fnGetItemAt(IShellItemArray
*iface
,
1258 IShellItemArrayImpl
*This
= impl_from_IShellItemArray(iface
);
1259 TRACE("%p (%lx, %p)\n", This
, dwIndex
, ppsi
);
1262 if(dwIndex
+ 1 > This
->item_count
)
1265 *ppsi
= This
->array
[dwIndex
];
1266 IShellItem_AddRef(*ppsi
);
1271 static HRESULT WINAPI
IShellItemArray_fnEnumItems(IShellItemArray
*iface
,
1272 IEnumShellItems
**ppenumShellItems
)
1274 IShellItemArrayImpl
*This
= impl_from_IShellItemArray(iface
);
1275 TRACE("%p (%p)\n", This
, ppenumShellItems
);
1276 return IEnumShellItems_Constructor(iface
, ppenumShellItems
);
1279 static const IShellItemArrayVtbl vt_IShellItemArray
= {
1280 IShellItemArray_fnQueryInterface
,
1281 IShellItemArray_fnAddRef
,
1282 IShellItemArray_fnRelease
,
1283 IShellItemArray_fnBindToHandler
,
1284 IShellItemArray_fnGetPropertyStore
,
1285 IShellItemArray_fnGetPropertyDescriptionList
,
1286 IShellItemArray_fnGetAttributes
,
1287 IShellItemArray_fnGetCount
,
1288 IShellItemArray_fnGetItemAt
,
1289 IShellItemArray_fnEnumItems
1292 /* Caller is responsible to AddRef all items */
1293 static HRESULT
create_shellitemarray(IShellItem
**items
, DWORD count
, IShellItemArray
**ret
)
1295 IShellItemArrayImpl
*This
;
1297 TRACE("(%p, %ld, %p)\n", items
, count
, ret
);
1299 This
= heap_alloc(sizeof(*This
));
1301 return E_OUTOFMEMORY
;
1303 This
->IShellItemArray_iface
.lpVtbl
= &vt_IShellItemArray
;
1306 This
->array
= heap_alloc(count
*sizeof(IShellItem
*));
1310 return E_OUTOFMEMORY
;
1312 memcpy(This
->array
, items
, count
*sizeof(IShellItem
*));
1313 This
->item_count
= count
;
1315 *ret
= &This
->IShellItemArray_iface
;
1319 HRESULT WINAPI
SHCreateShellItemArray(PCIDLIST_ABSOLUTE pidlParent
,
1322 PCUITEMID_CHILD_ARRAY ppidl
,
1323 IShellItemArray
**ppsiItemArray
)
1326 HRESULT ret
= E_FAIL
;
1329 TRACE("%p, %p, %d, %p, %p\n", pidlParent
, psf
, cidl
, ppidl
, ppsiItemArray
);
1331 *ppsiItemArray
= NULL
;
1333 if(!pidlParent
&& !psf
)
1337 return E_INVALIDARG
;
1339 array
= heap_alloc_zero(cidl
*sizeof(IShellItem
*));
1341 return E_OUTOFMEMORY
;
1343 for(i
= 0; i
< cidl
; i
++)
1345 ret
= SHCreateShellItem(pidlParent
, psf
, ppidl
[i
], &array
[i
]);
1346 if(FAILED(ret
)) break;
1351 ret
= create_shellitemarray(array
, cidl
, ppsiItemArray
);
1356 for(i
= 0; i
< cidl
; i
++)
1357 if(array
[i
]) IShellItem_Release(array
[i
]);
1363 HRESULT WINAPI
SHCreateShellItemArrayFromShellItem(IShellItem
*item
, REFIID riid
, void **ppv
)
1365 IShellItemArray
*array
;
1368 TRACE("%p, %s, %p\n", item
, shdebugstr_guid(riid
), ppv
);
1372 IShellItem_AddRef(item
);
1373 ret
= create_shellitemarray(&item
, 1, &array
);
1376 IShellItem_Release(item
);
1380 ret
= IShellItemArray_QueryInterface(array
, riid
, ppv
);
1381 IShellItemArray_Release(array
);
1385 HRESULT WINAPI
SHCreateShellItemArrayFromDataObject(IDataObject
*pdo
, REFIID riid
, void **ppv
)
1387 IShellItemArray
*psia
;
1392 TRACE("%p, %s, %p\n", pdo
, shdebugstr_guid(riid
), ppv
);
1395 return E_INVALIDARG
;
1399 fmt
.cfFormat
= RegisterClipboardFormatW(CFSTR_SHELLIDLISTW
);
1401 fmt
.dwAspect
= DVASPECT_CONTENT
;
1403 fmt
.tymed
= TYMED_HGLOBAL
;
1405 ret
= IDataObject_GetData(pdo
, &fmt
, &medium
);
1408 LPIDA pida
= GlobalLock(medium
.u
.hGlobal
);
1409 LPCITEMIDLIST parent_pidl
;
1410 LPCITEMIDLIST
*children
;
1412 TRACE("Converting %d objects.\n", pida
->cidl
);
1414 parent_pidl
= (LPCITEMIDLIST
) ((LPBYTE
)pida
+pida
->aoffset
[0]);
1416 children
= heap_alloc(sizeof(LPCITEMIDLIST
)*pida
->cidl
);
1417 for(i
= 0; i
< pida
->cidl
; i
++)
1418 children
[i
] = (LPCITEMIDLIST
) ((LPBYTE
)pida
+pida
->aoffset
[i
+1]);
1420 ret
= SHCreateShellItemArray(parent_pidl
, NULL
, pida
->cidl
, children
, &psia
);
1422 heap_free(children
);
1424 GlobalUnlock(medium
.u
.hGlobal
);
1425 GlobalFree(medium
.u
.hGlobal
);
1430 ret
= IShellItemArray_QueryInterface(psia
, riid
, ppv
);
1431 IShellItemArray_Release(psia
);
1437 HRESULT WINAPI
SHCreateShellItemArrayFromIDLists(UINT cidl
,
1438 PCIDLIST_ABSOLUTE_ARRAY pidl_array
,
1439 IShellItemArray
**psia
)
1444 TRACE("%d, %p, %p\n", cidl
, pidl_array
, psia
);
1449 return E_INVALIDARG
;
1451 array
= heap_alloc_zero(cidl
*sizeof(IShellItem
*));
1453 return E_OUTOFMEMORY
;
1455 for(i
= 0; i
< cidl
; i
++)
1457 ret
= SHCreateShellItem(NULL
, NULL
, pidl_array
[i
], &array
[i
]);
1464 ret
= create_shellitemarray(array
, cidl
, psia
);
1469 for(i
= 0; i
< cidl
; i
++)
1470 if(array
[i
]) IShellItem_Release(array
[i
]);
1477 HRESULT WINAPI
SHGetPropertyStoreFromParsingName(const WCHAR
*path
, IBindCtx
*pbc
, GETPROPERTYSTOREFLAGS flags
,
1478 REFIID riid
, void **ppv
)
1483 TRACE("(%s %p %#x %p %p)\n", debugstr_w(path
), pbc
, flags
, riid
, ppv
);
1485 hr
= SHCreateItemFromParsingName(path
, pbc
, &IID_IShellItem2
, (void **)&item
);
1488 hr
= IShellItem2_GetPropertyStore(item
, flags
, riid
, ppv
);
1489 IShellItem2_Release(item
);
1495 static HRESULT WINAPI
CustomDestinationList_QueryInterface(ICustomDestinationList
*iface
, REFIID riid
, void **obj
)
1497 CustomDestinationList
*This
= impl_from_ICustomDestinationList(iface
);
1499 TRACE("(%p, %s, %p)\n", This
, debugstr_guid(riid
), obj
);
1501 if (IsEqualIID(&IID_ICustomDestinationList
, riid
) || IsEqualIID(&IID_IUnknown
, riid
))
1503 *obj
= &This
->ICustomDestinationList_iface
;
1506 WARN("Unsupported interface %s.\n", shdebugstr_guid(riid
));
1508 return E_NOINTERFACE
;
1511 IUnknown_AddRef((IUnknown
*)*obj
);
1515 static ULONG WINAPI
CustomDestinationList_AddRef(ICustomDestinationList
*iface
)
1517 CustomDestinationList
*This
= impl_from_ICustomDestinationList(iface
);
1518 ULONG ref
= InterlockedIncrement(&This
->ref
);
1520 TRACE("(%p), new refcount=%li\n", This
, ref
);
1525 static ULONG WINAPI
CustomDestinationList_Release(ICustomDestinationList
*iface
)
1527 CustomDestinationList
*This
= impl_from_ICustomDestinationList(iface
);
1528 ULONG ref
= InterlockedDecrement(&This
->ref
);
1530 TRACE("(%p), new refcount=%li\n", This
, ref
);
1538 static HRESULT WINAPI
CustomDestinationList_SetAppID(ICustomDestinationList
*iface
, const WCHAR
*appid
)
1540 CustomDestinationList
*This
= impl_from_ICustomDestinationList(iface
);
1542 FIXME("%p (%s): stub\n", This
, debugstr_w(appid
));
1547 static HRESULT WINAPI
CustomDestinationList_BeginList(ICustomDestinationList
*iface
, UINT
*min_slots
, REFIID riid
, void **obj
)
1549 CustomDestinationList
*This
= impl_from_ICustomDestinationList(iface
);
1551 FIXME("%p (%p %s %p): stub\n", This
, min_slots
, debugstr_guid(riid
), obj
);
1556 static HRESULT WINAPI
CustomDestinationList_AppendCategory(ICustomDestinationList
*iface
, const WCHAR
*category
, IObjectArray
*array
)
1558 CustomDestinationList
*This
= impl_from_ICustomDestinationList(iface
);
1560 FIXME("%p (%s %p): stub\n", This
, debugstr_w(category
), array
);
1565 static HRESULT WINAPI
CustomDestinationList_AppendKnownCategory(ICustomDestinationList
*iface
, KNOWNDESTCATEGORY category
)
1567 CustomDestinationList
*This
= impl_from_ICustomDestinationList(iface
);
1569 FIXME("%p (%d): stub\n", This
, category
);
1574 static HRESULT WINAPI
CustomDestinationList_AddUserTasks(ICustomDestinationList
*iface
, IObjectArray
*tasks
)
1576 CustomDestinationList
*This
= impl_from_ICustomDestinationList(iface
);
1578 FIXME("%p (%p): stub\n", This
, tasks
);
1583 static HRESULT WINAPI
CustomDestinationList_CommitList(ICustomDestinationList
*iface
)
1585 CustomDestinationList
*This
= impl_from_ICustomDestinationList(iface
);
1587 FIXME("%p: stub\n", This
);
1592 static HRESULT WINAPI
CustomDestinationList_GetRemovedDestinations(ICustomDestinationList
*iface
, REFIID riid
, void **obj
)
1594 CustomDestinationList
*This
= impl_from_ICustomDestinationList(iface
);
1596 FIXME("%p (%s %p): stub\n", This
, debugstr_guid(riid
), obj
);
1601 static HRESULT WINAPI
CustomDestinationList_DeleteList(ICustomDestinationList
*iface
, const WCHAR
*appid
)
1603 CustomDestinationList
*This
= impl_from_ICustomDestinationList(iface
);
1605 FIXME("%p (%s): stub\n", This
, debugstr_w(appid
));
1610 static HRESULT WINAPI
CustomDestinationList_AbortList(ICustomDestinationList
*iface
)
1612 CustomDestinationList
*This
= impl_from_ICustomDestinationList(iface
);
1614 FIXME("%p: stub\n", This
);
1619 static const ICustomDestinationListVtbl CustomDestinationListVtbl
=
1621 CustomDestinationList_QueryInterface
,
1622 CustomDestinationList_AddRef
,
1623 CustomDestinationList_Release
,
1624 CustomDestinationList_SetAppID
,
1625 CustomDestinationList_BeginList
,
1626 CustomDestinationList_AppendCategory
,
1627 CustomDestinationList_AppendKnownCategory
,
1628 CustomDestinationList_AddUserTasks
,
1629 CustomDestinationList_CommitList
,
1630 CustomDestinationList_GetRemovedDestinations
,
1631 CustomDestinationList_DeleteList
,
1632 CustomDestinationList_AbortList
1635 HRESULT WINAPI
CustomDestinationList_Constructor(IUnknown
*outer
, REFIID riid
, void **obj
)
1637 CustomDestinationList
*list
;
1640 TRACE("%p %s %p\n", outer
, debugstr_guid(riid
), obj
);
1643 return CLASS_E_NOAGGREGATION
;
1645 if(!(list
= heap_alloc(sizeof(*list
))))
1646 return E_OUTOFMEMORY
;
1648 list
->ICustomDestinationList_iface
.lpVtbl
= &CustomDestinationListVtbl
;
1651 hr
= ICustomDestinationList_QueryInterface(&list
->ICustomDestinationList_iface
, riid
, obj
);
1652 ICustomDestinationList_Release(&list
->ICustomDestinationList_iface
);