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
22 #include "wine/port.h"
28 #define NONAMELESSUNION
29 #define NONAMELESSSTRUCT
33 #include "wine/debug.h"
36 #include "shell32_main.h"
39 WINE_DEFAULT_DEBUG_CHANNEL(shell);
41 typedef struct _ShellItem {
42 const IShellItemVtbl *lpIShellItemVtbl;
45 const IPersistIDListVtbl *lpIPersistIDListVtbl;
49 static inline ShellItem *impl_from_IPersistIDList( IPersistIDList *iface )
51 return (ShellItem*)((char*)iface - FIELD_OFFSET(ShellItem, lpIPersistIDListVtbl));
55 static HRESULT WINAPI ShellItem_QueryInterface(IShellItem *iface, REFIID riid,
58 ShellItem *This = (ShellItem*)iface;
60 TRACE("(%p,%p,%p)\n", iface, riid, ppv);
62 if (!ppv) return E_INVALIDARG;
64 if (IsEqualIID(&IID_IUnknown, riid) || IsEqualIID(&IID_IShellItem, riid))
68 else if (IsEqualIID(&IID_IPersist, riid) || IsEqualIID(&IID_IPersistIDList, riid))
70 *ppv = &(This->lpIPersistIDListVtbl);
73 FIXME("not implemented for %s\n", shdebugstr_guid(riid));
78 IUnknown_AddRef((IUnknown*)*ppv);
82 static ULONG WINAPI ShellItem_AddRef(IShellItem *iface)
84 ShellItem *This = (ShellItem*)iface;
85 ULONG ref = InterlockedIncrement(&This->ref);
87 TRACE("(%p), new refcount=%i\n", iface, ref);
92 static ULONG WINAPI ShellItem_Release(IShellItem *iface)
94 ShellItem *This = (ShellItem*)iface;
95 ULONG ref = InterlockedDecrement(&This->ref);
97 TRACE("(%p), new refcount=%i\n", iface, ref);
102 HeapFree(GetProcessHeap(), 0, This);
108 static HRESULT ShellItem_get_parent_pidl(ShellItem *This, LPITEMIDLIST *parent_pidl)
110 *parent_pidl = ILClone(This->pidl);
113 if (ILRemoveLastID(*parent_pidl))
117 ILFree(*parent_pidl);
125 return E_OUTOFMEMORY;
129 static HRESULT ShellItem_get_parent_shellfolder(ShellItem *This, IShellFolder **ppsf)
131 LPITEMIDLIST parent_pidl;
132 IShellFolder *desktop;
135 ret = ShellItem_get_parent_pidl(This, &parent_pidl);
138 ret = SHGetDesktopFolder(&desktop);
141 ret = IShellFolder_BindToObject(desktop, parent_pidl, NULL, &IID_IShellFolder, (void**)ppsf);
142 IShellFolder_Release(desktop);
150 static HRESULT ShellItem_get_shellfolder(ShellItem *This, IBindCtx *pbc, IShellFolder **ppsf)
152 IShellFolder *desktop;
155 ret = SHGetDesktopFolder(&desktop);
158 if (_ILIsDesktop(This->pidl))
161 IShellFolder_AddRef(*ppsf);
165 ret = IShellFolder_BindToObject(desktop, This->pidl, pbc, &IID_IShellFolder, (void**)ppsf);
168 IShellFolder_Release(desktop);
174 static HRESULT WINAPI ShellItem_BindToHandler(IShellItem *iface, IBindCtx *pbc,
175 REFGUID rbhid, REFIID riid, void **ppvOut)
177 ShellItem *This = (ShellItem*)iface;
179 TRACE("(%p,%p,%s,%p,%p)\n", iface, pbc, shdebugstr_guid(rbhid), riid, ppvOut);
182 if (IsEqualGUID(rbhid, &BHID_SFObject))
185 ret = ShellItem_get_shellfolder(This, pbc, &psf);
188 ret = IShellFolder_QueryInterface(psf, riid, ppvOut);
189 IShellFolder_Release(psf);
193 else if (IsEqualGUID(rbhid, &BHID_SFUIObject))
195 IShellFolder *psf_parent;
196 if (_ILIsDesktop(This->pidl))
197 ret = SHGetDesktopFolder(&psf_parent);
199 ret = ShellItem_get_parent_shellfolder(This, &psf_parent);
203 LPCITEMIDLIST pidl = ILFindLastID(This->pidl);
204 ret = IShellFolder_GetUIObjectOf(psf_parent, NULL, 1, &pidl, riid, NULL, ppvOut);
205 IShellFolder_Release(psf_parent);
209 else if (IsEqualGUID(rbhid, &BHID_DataObject))
211 return ShellItem_BindToHandler((IShellItem*)This, pbc, &BHID_SFUIObject, &IID_IDataObject, ppvOut);
214 FIXME("Unsupported BHID %s.\n", debugstr_guid(rbhid));
216 return MK_E_NOOBJECT;
219 static HRESULT WINAPI ShellItem_GetParent(IShellItem *iface, IShellItem **ppsi)
221 ShellItem *This = (ShellItem*)iface;
222 LPITEMIDLIST parent_pidl;
225 TRACE("(%p,%p)\n", iface, ppsi);
227 ret = ShellItem_get_parent_pidl(This, &parent_pidl);
230 ret = SHCreateShellItem(NULL, NULL, parent_pidl, ppsi);
237 static HRESULT WINAPI ShellItem_GetDisplayName(IShellItem *iface, SIGDN sigdnName,
240 ShellItem *This = (ShellItem*)iface;
241 TRACE("(%p,%x,%p)\n", iface, sigdnName, ppszName);
243 return SHGetNameFromIDList(This->pidl, sigdnName, ppszName);
246 static HRESULT WINAPI ShellItem_GetAttributes(IShellItem *iface, SFGAOF sfgaoMask,
247 SFGAOF *psfgaoAttribs)
249 ShellItem *This = (ShellItem*)iface;
250 IShellFolder *parent_folder;
251 LPITEMIDLIST child_pidl;
254 TRACE("(%p,%x,%p)\n", iface, sfgaoMask, psfgaoAttribs);
256 ret = ShellItem_get_parent_shellfolder(This, &parent_folder);
259 child_pidl = ILFindLastID(This->pidl);
260 *psfgaoAttribs = sfgaoMask;
261 ret = IShellFolder_GetAttributesOf(parent_folder, 1, (LPCITEMIDLIST*)&child_pidl, psfgaoAttribs);
262 IShellFolder_Release(parent_folder);
268 static HRESULT WINAPI ShellItem_Compare(IShellItem *iface, IShellItem *oth,
269 SICHINTF hint, int *piOrder)
271 LPWSTR dispname, dispname_oth;
273 TRACE("(%p,%p,%x,%p)\n", iface, oth, hint, piOrder);
275 if(hint & (SICHINT_CANONICAL | SICHINT_ALLFIELDS))
276 FIXME("Unsupported flags 0x%08x\n", hint);
278 ret = IShellItem_GetDisplayName(iface, SIGDN_DESKTOPABSOLUTEEDITING, &dispname);
281 ret = IShellItem_GetDisplayName(oth, SIGDN_DESKTOPABSOLUTEEDITING, &dispname_oth);
284 *piOrder = lstrcmpiW(dispname, dispname_oth);
285 CoTaskMemFree(dispname_oth);
287 CoTaskMemFree(dispname);
290 if(SUCCEEDED(ret) && *piOrder &&
291 (hint & SICHINT_TEST_FILESYSPATH_IF_NOT_EQUAL))
293 LPWSTR dispname, dispname_oth;
295 TRACE("Testing filesystem path.\n");
296 ret = IShellItem_GetDisplayName(iface, SIGDN_FILESYSPATH, &dispname);
299 ret = IShellItem_GetDisplayName(oth, SIGDN_FILESYSPATH, &dispname_oth);
302 *piOrder = lstrcmpiW(dispname, dispname_oth);
303 CoTaskMemFree(dispname_oth);
305 CoTaskMemFree(dispname);
318 static const IShellItemVtbl ShellItem_Vtbl = {
319 ShellItem_QueryInterface,
322 ShellItem_BindToHandler,
324 ShellItem_GetDisplayName,
325 ShellItem_GetAttributes,
330 static HRESULT ShellItem_GetClassID(ShellItem* This, CLSID *pClassID)
332 TRACE("(%p,%p)\n", This, pClassID);
334 *pClassID = CLSID_ShellItem;
339 static HRESULT WINAPI ShellItem_IPersistIDList_QueryInterface(IPersistIDList *iface,
340 REFIID riid, void **ppv)
342 ShellItem *This = impl_from_IPersistIDList(iface);
343 return ShellItem_QueryInterface((IShellItem*)This, riid, ppv);
346 static ULONG WINAPI ShellItem_IPersistIDList_AddRef(IPersistIDList *iface)
348 ShellItem *This = impl_from_IPersistIDList(iface);
349 return ShellItem_AddRef((IShellItem*)This);
352 static ULONG WINAPI ShellItem_IPersistIDList_Release(IPersistIDList *iface)
354 ShellItem *This = impl_from_IPersistIDList(iface);
355 return ShellItem_Release((IShellItem*)This);
358 static HRESULT WINAPI ShellItem_IPersistIDList_GetClassID(IPersistIDList* iface,
361 ShellItem *This = impl_from_IPersistIDList(iface);
363 return ShellItem_GetClassID(This, pClassID);
366 static HRESULT WINAPI ShellItem_IPersistIDList_SetIDList(IPersistIDList* iface,
369 ShellItem *This = impl_from_IPersistIDList(iface);
370 LPITEMIDLIST new_pidl;
372 TRACE("(%p,%p)\n", This, pidl);
374 new_pidl = ILClone(pidl);
379 This->pidl = new_pidl;
383 return E_OUTOFMEMORY;
386 static HRESULT WINAPI ShellItem_IPersistIDList_GetIDList(IPersistIDList* iface,
389 ShellItem *This = impl_from_IPersistIDList(iface);
391 TRACE("(%p,%p)\n", This, ppidl);
393 *ppidl = ILClone(This->pidl);
397 return E_OUTOFMEMORY;
400 static const IPersistIDListVtbl ShellItem_IPersistIDList_Vtbl = {
401 ShellItem_IPersistIDList_QueryInterface,
402 ShellItem_IPersistIDList_AddRef,
403 ShellItem_IPersistIDList_Release,
404 ShellItem_IPersistIDList_GetClassID,
405 ShellItem_IPersistIDList_SetIDList,
406 ShellItem_IPersistIDList_GetIDList
410 HRESULT WINAPI IShellItem_Constructor(IUnknown *pUnkOuter, REFIID riid, void **ppv)
415 TRACE("(%p,%s)\n",pUnkOuter, debugstr_guid(riid));
419 if (pUnkOuter) return CLASS_E_NOAGGREGATION;
421 This = HeapAlloc(GetProcessHeap(), 0, sizeof(ShellItem));
422 This->lpIShellItemVtbl = &ShellItem_Vtbl;
425 This->lpIPersistIDListVtbl = &ShellItem_IPersistIDList_Vtbl;
427 ret = ShellItem_QueryInterface((IShellItem*)This, riid, ppv);
428 ShellItem_Release((IShellItem*)This);
433 HRESULT WINAPI SHCreateShellItem(LPCITEMIDLIST pidlParent,
434 IShellFolder *psfParent, LPCITEMIDLIST pidl, IShellItem **ppsi)
437 LPITEMIDLIST new_pidl;
440 TRACE("(%p,%p,%p,%p)\n", pidlParent, psfParent, pidl, ppsi);
446 else if (pidlParent || psfParent)
448 LPITEMIDLIST temp_parent=NULL;
451 IPersistFolder2* ppf2Parent;
453 if (FAILED(IPersistFolder2_QueryInterface(psfParent, &IID_IPersistFolder2, (void**)&ppf2Parent)))
455 FIXME("couldn't get IPersistFolder2 interface of parent\n");
456 return E_NOINTERFACE;
459 if (FAILED(IPersistFolder2_GetCurFolder(ppf2Parent, &temp_parent)))
461 FIXME("couldn't get parent PIDL\n");
462 IPersistFolder2_Release(ppf2Parent);
463 return E_NOINTERFACE;
466 pidlParent = temp_parent;
467 IPersistFolder2_Release(ppf2Parent);
470 new_pidl = ILCombine(pidlParent, pidl);
474 return E_OUTOFMEMORY;
478 new_pidl = ILClone(pidl);
480 return E_OUTOFMEMORY;
483 ret = IShellItem_Constructor(NULL, &IID_IShellItem, (void**)&This);
486 *ppsi = (IShellItem*)This;
487 This->pidl = new_pidl;
497 HRESULT WINAPI SHCreateItemFromParsingName(PCWSTR pszPath,
498 IBindCtx *pbc, REFIID riid, void **ppv)
505 ret = SHParseDisplayName(pszPath, pbc, &pidl, 0, NULL);
509 ret = IShellItem_Constructor(NULL, riid, (void**)&This);
524 HRESULT WINAPI SHCreateItemFromIDList(PCIDLIST_ABSOLUTE pidl, REFIID riid, void **ppv)
532 ret = IShellItem_Constructor(NULL, riid, ppv);
535 psiimpl = (ShellItem*)*ppv;
536 psiimpl->pidl = ILClone(pidl);
542 HRESULT WINAPI SHGetItemFromDataObject(IDataObject *pdtobj,
543 DATAOBJ_GET_ITEM_FLAGS dwFlags, REFIID riid, void **ppv)
549 TRACE("%p, %x, %s, %p\n", pdtobj, dwFlags, debugstr_guid(riid), ppv);
554 fmt.cfFormat = RegisterClipboardFormatW(CFSTR_SHELLIDLISTW);
556 fmt.dwAspect = DVASPECT_CONTENT;
558 fmt.tymed = TYMED_HGLOBAL;
560 ret = IDataObject_GetData(pdtobj, &fmt, &medium);
563 LPIDA pida = GlobalLock(medium.u.hGlobal);
565 if((pida->cidl > 1 && !(dwFlags & DOGIF_ONLY_IF_ONE)) ||
570 /* Get the first pidl (parent + child1) */
571 pidl = ILCombine((LPCITEMIDLIST) ((LPBYTE)pida+pida->aoffset[0]),
572 (LPCITEMIDLIST) ((LPBYTE)pida+pida->aoffset[1]));
574 ret = SHCreateItemFromIDList(pidl, riid, ppv);
582 GlobalUnlock(medium.u.hGlobal);
583 GlobalFree(medium.u.hGlobal);
586 if(FAILED(ret) && !(dwFlags & DOGIF_NO_HDROP))
588 TRACE("Attempting to fall back on CF_HDROP.\n");
590 fmt.cfFormat = CF_HDROP;
592 fmt.dwAspect = DVASPECT_CONTENT;
594 fmt.tymed = TYMED_HGLOBAL;
596 ret = IDataObject_GetData(pdtobj, &fmt, &medium);
599 DROPFILES *df = GlobalLock(medium.u.hGlobal);
600 LPBYTE files = (LPBYTE)df + df->pFiles;
601 BOOL multiple_files = FALSE;
606 WCHAR filename[MAX_PATH];
607 PCSTR first_file = (PCSTR)files;
608 if(*(files + lstrlenA(first_file) + 1) != 0)
609 multiple_files = TRUE;
611 if( !(multiple_files && (dwFlags & DOGIF_ONLY_IF_ONE)) )
613 MultiByteToWideChar(CP_ACP, 0, first_file, -1, filename, MAX_PATH);
614 ret = SHCreateItemFromParsingName(filename, NULL, riid, ppv);
619 PCWSTR first_file = (PCWSTR)files;
620 if(*((PCWSTR)files + lstrlenW(first_file) + 1) != 0)
621 multiple_files = TRUE;
623 if( !(multiple_files && (dwFlags & DOGIF_ONLY_IF_ONE)) )
624 ret = SHCreateItemFromParsingName(first_file, NULL, riid, ppv);
627 GlobalUnlock(medium.u.hGlobal);
628 GlobalFree(medium.u.hGlobal);
632 if(FAILED(ret) && !(dwFlags & DOGIF_NO_URL))
634 FIXME("Failed to create item, should try CF_URL.\n");
640 HRESULT WINAPI SHGetItemFromObject(IUnknown *punk, REFIID riid, void **ppv)
645 ret = SHGetIDListFromObject(punk, &pidl);
648 ret = SHCreateItemFromIDList(pidl, riid, ppv);
655 /*************************************************************************
656 * IShellItemArray implementation
659 IShellItemArray IShellItemArray_iface;
664 } IShellItemArrayImpl;
666 static inline IShellItemArrayImpl *impl_from_IShellItemArray(IShellItemArray *iface)
668 return CONTAINING_RECORD(iface, IShellItemArrayImpl, IShellItemArray_iface);
671 static HRESULT WINAPI IShellItemArray_fnQueryInterface(IShellItemArray *iface,
675 IShellItemArrayImpl *This = impl_from_IShellItemArray(iface);
676 TRACE("%p (%s, %p)\n", This, shdebugstr_guid(riid), ppvObject);
679 if(IsEqualIID(riid, &IID_IShellItemArray) ||
680 IsEqualIID(riid, &IID_IUnknown))
687 IUnknown_AddRef((IUnknown*)*ppvObject);
691 return E_NOINTERFACE;
694 static ULONG WINAPI IShellItemArray_fnAddRef(IShellItemArray *iface)
696 IShellItemArrayImpl *This = impl_from_IShellItemArray(iface);
697 LONG ref = InterlockedIncrement(&This->ref);
698 TRACE("%p - ref %d\n", This, ref);
703 static ULONG WINAPI IShellItemArray_fnRelease(IShellItemArray *iface)
705 IShellItemArrayImpl *This = impl_from_IShellItemArray(iface);
706 LONG ref = InterlockedDecrement(&This->ref);
707 TRACE("%p - ref %d\n", This, ref);
714 for(i = 0; i < This->item_count; i++)
715 IShellItem_Release(This->array[i]);
717 HeapFree(GetProcessHeap(), 0, This->array);
718 HeapFree(GetProcessHeap(), 0, This);
725 static HRESULT WINAPI IShellItemArray_fnBindToHandler(IShellItemArray *iface,
731 IShellItemArrayImpl *This = impl_from_IShellItemArray(iface);
732 FIXME("Stub: %p (%p, %s, %s, %p)\n",
733 This, pbc, shdebugstr_guid(bhid), shdebugstr_guid(riid), ppvOut);
738 static HRESULT WINAPI IShellItemArray_fnGetPropertyStore(IShellItemArray *iface,
739 GETPROPERTYSTOREFLAGS flags,
743 IShellItemArrayImpl *This = impl_from_IShellItemArray(iface);
744 FIXME("Stub: %p (%x, %s, %p)\n", This, flags, shdebugstr_guid(riid), ppv);
749 static HRESULT WINAPI IShellItemArray_fnGetPropertyDescriptionList(IShellItemArray *iface,
750 REFPROPERTYKEY keyType,
754 IShellItemArrayImpl *This = impl_from_IShellItemArray(iface);
755 FIXME("Stub: %p (%p, %s, %p)\n",
756 This, keyType, shdebugstr_guid(riid), ppv);
761 static HRESULT WINAPI IShellItemArray_fnGetAttributes(IShellItemArray *iface,
762 SIATTRIBFLAGS AttribFlags,
764 SFGAOF *psfgaoAttribs)
766 IShellItemArrayImpl *This = impl_from_IShellItemArray(iface);
767 FIXME("Stub: %p (%x, %x, %p)\n", This, AttribFlags, sfgaoMask, psfgaoAttribs);
772 static HRESULT WINAPI IShellItemArray_fnGetCount(IShellItemArray *iface,
775 IShellItemArrayImpl *This = impl_from_IShellItemArray(iface);
776 TRACE("%p (%p)\n", This, pdwNumItems);
778 *pdwNumItems = This->item_count;
783 static HRESULT WINAPI IShellItemArray_fnGetItemAt(IShellItemArray *iface,
787 IShellItemArrayImpl *This = impl_from_IShellItemArray(iface);
788 TRACE("%p (%x, %p)\n", This, dwIndex, ppsi);
791 if(dwIndex + 1 > This->item_count)
794 *ppsi = This->array[dwIndex];
795 IShellItem_AddRef(*ppsi);
800 static HRESULT WINAPI IShellItemArray_fnEnumItems(IShellItemArray *iface,
801 IEnumShellItems **ppenumShellItems)
803 IShellItemArrayImpl *This = impl_from_IShellItemArray(iface);
804 FIXME("Stub: %p (%p)\n", This, ppenumShellItems);
809 static const IShellItemArrayVtbl vt_IShellItemArray = {
810 IShellItemArray_fnQueryInterface,
811 IShellItemArray_fnAddRef,
812 IShellItemArray_fnRelease,
813 IShellItemArray_fnBindToHandler,
814 IShellItemArray_fnGetPropertyStore,
815 IShellItemArray_fnGetPropertyDescriptionList,
816 IShellItemArray_fnGetAttributes,
817 IShellItemArray_fnGetCount,
818 IShellItemArray_fnGetItemAt,
819 IShellItemArray_fnEnumItems
822 static HRESULT IShellItemArray_Constructor(IUnknown *pUnkOuter, REFIID riid, void **ppv)
824 IShellItemArrayImpl *This;
827 TRACE("(%p, %s, %p)\n",pUnkOuter, debugstr_guid(riid), ppv);
830 return CLASS_E_NOAGGREGATION;
832 This = HeapAlloc(GetProcessHeap(), 0, sizeof(IShellItemArrayImpl));
834 return E_OUTOFMEMORY;
837 This->IShellItemArray_iface.lpVtbl = &vt_IShellItemArray;
839 This->item_count = 0;
841 ret = IShellItemArray_QueryInterface(&This->IShellItemArray_iface, riid, ppv);
842 IShellItemArray_Release(&This->IShellItemArray_iface);
847 HRESULT WINAPI SHCreateShellItemArray(PCIDLIST_ABSOLUTE pidlParent,
850 PCUITEMID_CHILD_ARRAY ppidl,
851 IShellItemArray **ppsiItemArray)
853 IShellItemArrayImpl *This;
855 HRESULT ret = E_FAIL;
858 TRACE("%p, %p, %d, %p, %p\n", pidlParent, psf, cidl, ppidl, ppsiItemArray);
860 if(!pidlParent && !psf)
866 array = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, cidl*sizeof(IShellItem*));
868 return E_OUTOFMEMORY;
870 for(i = 0; i < cidl; i++)
872 ret = SHCreateShellItem(pidlParent, psf, ppidl[i], &array[i]);
873 if(FAILED(ret)) break;
878 ret = IShellItemArray_Constructor(NULL, &IID_IShellItemArray, (void**)&This);
882 This->item_count = cidl;
883 *ppsiItemArray = &This->IShellItemArray_iface;
889 /* Something failed, clean up. */
890 for(i = 0; i < cidl; i++)
891 if(array[i]) IShellItem_Release(array[i]);
892 HeapFree(GetProcessHeap(), 0, array);
893 *ppsiItemArray = NULL;
897 HRESULT WINAPI SHCreateShellItemArrayFromShellItem(IShellItem *psi, REFIID riid, void **ppv)
899 IShellItemArrayImpl *This;
903 TRACE("%p, %s, %p\n", psi, shdebugstr_guid(riid), ppv);
905 array = HeapAlloc(GetProcessHeap(), 0, sizeof(IShellItem*));
907 return E_OUTOFMEMORY;
909 ret = IShellItemArray_Constructor(NULL, riid, (void**)&This);
913 IShellItem_AddRef(psi);
915 This->item_count = 1;
920 HeapFree(GetProcessHeap(), 0, array);
927 HRESULT WINAPI SHCreateShellItemArrayFromDataObject(IDataObject *pdo, REFIID riid, void **ppv)
929 IShellItemArray *psia;
934 TRACE("%p, %s, %p\n", pdo, shdebugstr_guid(riid), ppv);
941 fmt.cfFormat = RegisterClipboardFormatW(CFSTR_SHELLIDLISTW);
943 fmt.dwAspect = DVASPECT_CONTENT;
945 fmt.tymed = TYMED_HGLOBAL;
947 ret = IDataObject_GetData(pdo, &fmt, &medium);
950 LPIDA pida = GlobalLock(medium.u.hGlobal);
951 LPCITEMIDLIST parent_pidl;
952 LPCITEMIDLIST *children;
954 TRACE("Converting %d objects.\n", pida->cidl);
956 parent_pidl = (LPCITEMIDLIST) ((LPBYTE)pida+pida->aoffset[0]);
958 children = HeapAlloc(GetProcessHeap(), 0, sizeof(LPCITEMIDLIST)*pida->cidl);
959 for(i = 0; i < pida->cidl; i++)
960 children[i] = (LPCITEMIDLIST) ((LPBYTE)pida+pida->aoffset[i+1]);
962 ret = SHCreateShellItemArray(parent_pidl, NULL, pida->cidl, children, (IShellItemArray**)&psia);
964 HeapFree(GetProcessHeap(), 0, children);
966 GlobalUnlock(medium.u.hGlobal);
967 GlobalFree(medium.u.hGlobal);
972 ret = IShellItemArray_QueryInterface(psia, riid, ppv);
973 IShellItemArray_Release(psia);