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 const IShellItemArrayVtbl *lpVtbl;
664 } IShellItemArrayImpl;
666 static HRESULT WINAPI IShellItemArray_fnQueryInterface(IShellItemArray *iface,
670 IShellItemArrayImpl *This = (IShellItemArrayImpl *)iface;
671 TRACE("%p (%s, %p)\n", This, shdebugstr_guid(riid), ppvObject);
674 if(IsEqualIID(riid, &IID_IShellItemArray) ||
675 IsEqualIID(riid, &IID_IUnknown))
682 IUnknown_AddRef((IUnknown*)*ppvObject);
686 return E_NOINTERFACE;
689 static ULONG WINAPI IShellItemArray_fnAddRef(IShellItemArray *iface)
691 IShellItemArrayImpl *This = (IShellItemArrayImpl *)iface;
692 LONG ref = InterlockedIncrement(&This->ref);
693 TRACE("%p - ref %d\n", This, ref);
698 static ULONG WINAPI IShellItemArray_fnRelease(IShellItemArray *iface)
700 IShellItemArrayImpl *This = (IShellItemArrayImpl *)iface;
701 LONG ref = InterlockedDecrement(&This->ref);
702 TRACE("%p - ref %d\n", This, ref);
709 for(i = 0; i < This->item_count; i++)
710 IShellItem_Release(This->array[i]);
712 HeapFree(GetProcessHeap(), 0, This->array);
713 HeapFree(GetProcessHeap(), 0, This);
720 static HRESULT WINAPI IShellItemArray_fnBindToHandler(IShellItemArray *iface,
726 IShellItemArrayImpl *This = (IShellItemArrayImpl *)iface;
727 FIXME("Stub: %p (%p, %s, %s, %p)\n",
728 This, pbc, shdebugstr_guid(bhid), shdebugstr_guid(riid), ppvOut);
733 static HRESULT WINAPI IShellItemArray_fnGetPropertyStore(IShellItemArray *iface,
734 GETPROPERTYSTOREFLAGS flags,
738 IShellItemArrayImpl *This = (IShellItemArrayImpl *)iface;
739 FIXME("Stub: %p (%x, %s, %p)\n", This, flags, shdebugstr_guid(riid), ppv);
744 static HRESULT WINAPI IShellItemArray_fnGetPropertyDescriptionList(IShellItemArray *iface,
745 REFPROPERTYKEY keyType,
749 IShellItemArrayImpl *This = (IShellItemArrayImpl *)iface;
750 FIXME("Stub: %p (%p, %s, %p)\n",
751 This, keyType, shdebugstr_guid(riid), ppv);
756 static HRESULT WINAPI IShellItemArray_fnGetAttributes(IShellItemArray *iface,
757 SIATTRIBFLAGS AttribFlags,
759 SFGAOF *psfgaoAttribs)
761 IShellItemArrayImpl *This = (IShellItemArrayImpl *)iface;
762 FIXME("Stub: %p (%x, %x, %p)\n", This, AttribFlags, sfgaoMask, psfgaoAttribs);
767 static HRESULT WINAPI IShellItemArray_fnGetCount(IShellItemArray *iface,
770 IShellItemArrayImpl *This = (IShellItemArrayImpl *)iface;
771 TRACE("%p (%p)\n", This, pdwNumItems);
773 *pdwNumItems = This->item_count;
778 static HRESULT WINAPI IShellItemArray_fnGetItemAt(IShellItemArray *iface,
782 IShellItemArrayImpl *This = (IShellItemArrayImpl *)iface;
783 TRACE("%p (%x, %p)\n", This, dwIndex, ppsi);
786 if(dwIndex + 1 > This->item_count)
789 *ppsi = This->array[dwIndex];
790 IShellItem_AddRef(*ppsi);
795 static HRESULT WINAPI IShellItemArray_fnEnumItems(IShellItemArray *iface,
796 IEnumShellItems **ppenumShellItems)
798 IShellItemArrayImpl *This = (IShellItemArrayImpl *)iface;
799 FIXME("Stub: %p (%p)\n", This, ppenumShellItems);
804 static const IShellItemArrayVtbl vt_IShellItemArray = {
805 IShellItemArray_fnQueryInterface,
806 IShellItemArray_fnAddRef,
807 IShellItemArray_fnRelease,
808 IShellItemArray_fnBindToHandler,
809 IShellItemArray_fnGetPropertyStore,
810 IShellItemArray_fnGetPropertyDescriptionList,
811 IShellItemArray_fnGetAttributes,
812 IShellItemArray_fnGetCount,
813 IShellItemArray_fnGetItemAt,
814 IShellItemArray_fnEnumItems
817 static HRESULT IShellItemArray_Constructor(IUnknown *pUnkOuter, REFIID riid, void **ppv)
819 IShellItemArrayImpl *This;
822 TRACE("(%p, %s, %p)\n",pUnkOuter, debugstr_guid(riid), ppv);
825 return CLASS_E_NOAGGREGATION;
827 This = HeapAlloc(GetProcessHeap(), 0, sizeof(IShellItemArrayImpl));
829 return E_OUTOFMEMORY;
832 This->lpVtbl = &vt_IShellItemArray;
834 This->item_count = 0;
836 ret = IShellItemArray_QueryInterface((IShellItemArray*)This, riid, ppv);
837 IShellItemArray_Release((IShellItemArray*)This);
842 HRESULT WINAPI SHCreateShellItemArray(PCIDLIST_ABSOLUTE pidlParent,
845 PCUITEMID_CHILD_ARRAY ppidl,
846 IShellItemArray **ppsiItemArray)
848 IShellItemArrayImpl *This;
850 HRESULT ret = E_FAIL;
853 TRACE("%p, %p, %d, %p, %p\n", pidlParent, psf, cidl, ppidl, ppsiItemArray);
855 if(!pidlParent && !psf)
861 array = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, cidl*sizeof(IShellItem*));
863 return E_OUTOFMEMORY;
865 for(i = 0; i < cidl; i++)
867 ret = SHCreateShellItem(pidlParent, psf, ppidl[i], &array[i]);
868 if(FAILED(ret)) break;
873 ret = IShellItemArray_Constructor(NULL, &IID_IShellItemArray, (void**)&This);
877 This->item_count = cidl;
878 *ppsiItemArray = (IShellItemArray*)This;
884 /* Something failed, clean up. */
885 for(i = 0; i < cidl; i++)
886 if(array[i]) IShellItem_Release(array[i]);
887 HeapFree(GetProcessHeap(), 0, array);
888 *ppsiItemArray = NULL;
892 HRESULT WINAPI SHCreateShellItemArrayFromShellItem(IShellItem *psi, REFIID riid, void **ppv)
894 IShellItemArrayImpl *This;
898 TRACE("%p, %s, %p\n", psi, shdebugstr_guid(riid), ppv);
900 array = HeapAlloc(GetProcessHeap(), 0, sizeof(IShellItem*));
902 return E_OUTOFMEMORY;
904 ret = IShellItemArray_Constructor(NULL, riid, (void**)&This);
908 IShellItem_AddRef(psi);
910 This->item_count = 1;
915 HeapFree(GetProcessHeap(), 0, array);
922 HRESULT WINAPI SHCreateShellItemArrayFromDataObject(IDataObject *pdo, REFIID riid, void **ppv)
924 IShellItemArray *psia;
929 TRACE("%p, %s, %p\n", pdo, shdebugstr_guid(riid), ppv);
936 fmt.cfFormat = RegisterClipboardFormatW(CFSTR_SHELLIDLISTW);
938 fmt.dwAspect = DVASPECT_CONTENT;
940 fmt.tymed = TYMED_HGLOBAL;
942 ret = IDataObject_GetData(pdo, &fmt, &medium);
945 LPIDA pida = GlobalLock(medium.u.hGlobal);
946 LPCITEMIDLIST parent_pidl;
947 LPCITEMIDLIST *children;
949 TRACE("Converting %d objects.\n", pida->cidl);
951 parent_pidl = (LPCITEMIDLIST) ((LPBYTE)pida+pida->aoffset[0]);
953 children = HeapAlloc(GetProcessHeap(), 0, sizeof(LPCITEMIDLIST)*pida->cidl);
954 for(i = 0; i < pida->cidl; i++)
955 children[i] = (LPCITEMIDLIST) ((LPBYTE)pida+pida->aoffset[i+1]);
957 ret = SHCreateShellItemArray(parent_pidl, NULL, pida->cidl, children, (IShellItemArray**)&psia);
959 HeapFree(GetProcessHeap(), 0, children);
961 GlobalUnlock(medium.u.hGlobal);
962 GlobalFree(medium.u.hGlobal);
967 ret = IShellItemArray_QueryInterface(psia, riid, ppv);
968 IShellItemArray_Release(psia);