2 * IShellItem implementation
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
23 WINE_DEFAULT_DEBUG_CHANNEL(shell
);
25 typedef struct _ShellItem
{
26 const IShellItemVtbl
*lpIShellItemVtbl
;
29 const IPersistIDListVtbl
*lpIPersistIDListVtbl
;
32 HRESULT WINAPI
SHCreateShellItem(LPCITEMIDLIST pidlParent
,
33 IShellFolder
*psfParent
, LPCITEMIDLIST pidl
, IShellItem
**ppsi
);
36 static inline ShellItem
*impl_from_IPersistIDList( IPersistIDList
*iface
)
38 return (ShellItem
*)((char*)iface
- FIELD_OFFSET(ShellItem
, lpIPersistIDListVtbl
));
42 static HRESULT WINAPI
ShellItem_QueryInterface(IShellItem
*iface
, REFIID riid
,
45 ShellItem
*This
= (ShellItem
*)iface
;
47 TRACE("(%p,%p,%p)\n", iface
, riid
, ppv
);
49 if (!ppv
) return E_INVALIDARG
;
51 if (IsEqualIID(&IID_IUnknown
, riid
) || IsEqualIID(&IID_IShellItem
, riid
))
55 else if (IsEqualIID(&IID_IPersist
, riid
) || IsEqualIID(&IID_IPersistIDList
, riid
))
57 *ppv
= (IPersistIDListVtbl
*)&(This
->lpIPersistIDListVtbl
);
60 FIXME("not implemented for %s\n", shdebugstr_guid(riid
));
65 IUnknown_AddRef((IUnknown
*)*ppv
);
69 static ULONG WINAPI
ShellItem_AddRef(IShellItem
*iface
)
71 ShellItem
*This
= (ShellItem
*)iface
;
72 ULONG ref
= InterlockedIncrement(&This
->ref
);
74 TRACE("(%p), new refcount=%i\n", iface
, ref
);
79 static ULONG WINAPI
ShellItem_Release(IShellItem
*iface
)
81 ShellItem
*This
= (ShellItem
*)iface
;
82 ULONG ref
= InterlockedDecrement(&This
->ref
);
84 TRACE("(%p), new refcount=%i\n", iface
, ref
);
89 HeapFree(GetProcessHeap(), 0, This
);
95 static HRESULT
ShellItem_get_parent_pidl(ShellItem
*This
, LPITEMIDLIST
*parent_pidl
)
97 *parent_pidl
= ILClone(This
->pidl
);
100 if (ILRemoveLastID(*parent_pidl
))
104 ILFree(*parent_pidl
);
112 return E_OUTOFMEMORY
;
116 static HRESULT
ShellItem_get_parent_shellfolder(ShellItem
*This
, IShellFolder
**ppsf
)
118 LPITEMIDLIST parent_pidl
;
119 IShellFolder
*desktop
;
122 ret
= ShellItem_get_parent_pidl(This
, &parent_pidl
);
125 ret
= SHGetDesktopFolder(&desktop
);
128 ret
= IShellFolder_BindToObject(desktop
, parent_pidl
, NULL
, &IID_IShellFolder
, (void**)ppsf
);
129 IShellFolder_Release(desktop
);
137 static HRESULT WINAPI
ShellItem_BindToHandler(IShellItem
*iface
, IBindCtx
*pbc
,
138 REFGUID rbhid
, REFIID riid
, void **ppvOut
)
140 FIXME("(%p,%p,%s,%p,%p)\n", iface
, pbc
, shdebugstr_guid(rbhid
), riid
, ppvOut
);
147 static HRESULT WINAPI
ShellItem_GetParent(IShellItem
*iface
, IShellItem
**ppsi
)
149 ShellItem
*This
= (ShellItem
*)iface
;
150 LPITEMIDLIST parent_pidl
;
153 TRACE("(%p,%p)\n", iface
, ppsi
);
155 ret
= ShellItem_get_parent_pidl(This
, &parent_pidl
);
158 ret
= SHCreateShellItem(NULL
, NULL
, parent_pidl
, ppsi
);
165 static HRESULT WINAPI
ShellItem_GetDisplayName(IShellItem
*iface
, SIGDN sigdnName
,
168 FIXME("(%p,%x,%p)\n", iface
, sigdnName
, ppszName
);
175 static HRESULT WINAPI
ShellItem_GetAttributes(IShellItem
*iface
, SFGAOF sfgaoMask
,
176 SFGAOF
*psfgaoAttribs
)
178 ShellItem
*This
= (ShellItem
*)iface
;
179 IShellFolder
*parent_folder
;
180 LPITEMIDLIST child_pidl
;
183 TRACE("(%p,%x,%p)\n", iface
, sfgaoMask
, psfgaoAttribs
);
185 ret
= ShellItem_get_parent_shellfolder(This
, &parent_folder
);
188 child_pidl
= ILFindLastID(This
->pidl
);
189 *psfgaoAttribs
= sfgaoMask
;
190 ret
= IShellFolder_GetAttributesOf(parent_folder
, 1, (LPCITEMIDLIST
*)&child_pidl
, psfgaoAttribs
);
191 IShellFolder_Release(parent_folder
);
197 static HRESULT WINAPI
ShellItem_Compare(IShellItem
*iface
, IShellItem
*oth
,
198 SICHINTF hint
, int *piOrder
)
200 FIXME("(%p,%p,%x,%p)\n", iface
, oth
, hint
, piOrder
);
205 static const IShellItemVtbl ShellItem_Vtbl
= {
206 ShellItem_QueryInterface
,
209 ShellItem_BindToHandler
,
211 ShellItem_GetDisplayName
,
212 ShellItem_GetAttributes
,
217 static HRESULT
ShellItem_GetClassID(ShellItem
* This
, CLSID
*pClassID
)
219 TRACE("(%p,%p)\n", This
, pClassID
);
221 *pClassID
= CLSID_ShellItem
;
226 static HRESULT WINAPI
ShellItem_IPersistIDList_QueryInterface(IPersistIDList
*iface
,
227 REFIID riid
, void **ppv
)
229 ShellItem
*This
= impl_from_IPersistIDList(iface
);
230 return ShellItem_QueryInterface((IShellItem
*)This
, riid
, ppv
);
233 static ULONG WINAPI
ShellItem_IPersistIDList_AddRef(IPersistIDList
*iface
)
235 ShellItem
*This
= impl_from_IPersistIDList(iface
);
236 return ShellItem_AddRef((IShellItem
*)This
);
239 static ULONG WINAPI
ShellItem_IPersistIDList_Release(IPersistIDList
*iface
)
241 ShellItem
*This
= impl_from_IPersistIDList(iface
);
242 return ShellItem_Release((IShellItem
*)This
);
245 static HRESULT WINAPI
ShellItem_IPersistIDList_GetClassID(IPersistIDList
* iface
,
248 ShellItem
*This
= impl_from_IPersistIDList(iface
);
250 return ShellItem_GetClassID(This
, pClassID
);
253 static HRESULT WINAPI
ShellItem_IPersistIDList_SetIDList(IPersistIDList
* iface
,
256 ShellItem
*This
= impl_from_IPersistIDList(iface
);
257 LPITEMIDLIST new_pidl
;
259 TRACE("(%p,%p)\n", This
, pidl
);
261 new_pidl
= ILClone(pidl
);
266 This
->pidl
= new_pidl
;
270 return E_OUTOFMEMORY
;
273 static HRESULT WINAPI
ShellItem_IPersistIDList_GetIDList(IPersistIDList
* iface
,
276 ShellItem
*This
= impl_from_IPersistIDList(iface
);
278 TRACE("(%p,%p)\n", This
, ppidl
);
280 *ppidl
= ILClone(This
->pidl
);
284 return E_OUTOFMEMORY
;
287 static const IPersistIDListVtbl ShellItem_IPersistIDList_Vtbl
= {
288 ShellItem_IPersistIDList_QueryInterface
,
289 ShellItem_IPersistIDList_AddRef
,
290 ShellItem_IPersistIDList_Release
,
291 ShellItem_IPersistIDList_GetClassID
,
292 ShellItem_IPersistIDList_SetIDList
,
293 ShellItem_IPersistIDList_GetIDList
297 HRESULT WINAPI
IShellItem_Constructor(IUnknown
*pUnkOuter
, REFIID riid
, void **ppv
)
302 TRACE("(%p,%s)\n",pUnkOuter
, debugstr_guid(riid
));
306 if (pUnkOuter
) return CLASS_E_NOAGGREGATION
;
308 This
= HeapAlloc(GetProcessHeap(), 0, sizeof(ShellItem
));
309 This
->lpIShellItemVtbl
= &ShellItem_Vtbl
;
312 This
->lpIPersistIDListVtbl
= &ShellItem_IPersistIDList_Vtbl
;
314 ret
= ShellItem_QueryInterface((IShellItem
*)This
, riid
, ppv
);
315 ShellItem_Release((IShellItem
*)This
);
320 HRESULT WINAPI
SHCreateShellItem(LPCITEMIDLIST pidlParent
,
321 IShellFolder
*psfParent
, LPCITEMIDLIST pidl
, IShellItem
**ppsi
)
324 LPITEMIDLIST new_pidl
;
327 TRACE("(%p,%p,%p,%p)\n", pidlParent
, psfParent
, pidl
, ppsi
);
333 else if (pidlParent
|| psfParent
)
335 LPITEMIDLIST temp_parent
=NULL
;
338 IPersistFolder2
* ppf2Parent
;
340 if (FAILED(IPersistFolder2_QueryInterface(psfParent
, &IID_IPersistFolder2
, (void**)&ppf2Parent
)))
342 FIXME("couldn't get IPersistFolder2 interface of parent\n");
343 return E_NOINTERFACE
;
346 if (FAILED(IPersistFolder2_GetCurFolder(ppf2Parent
, &temp_parent
)))
348 FIXME("couldn't get parent PIDL\n");
349 IPersistFolder2_Release(ppf2Parent
);
350 return E_NOINTERFACE
;
353 pidlParent
= temp_parent
;
354 IPersistFolder2_Release(ppf2Parent
);
357 new_pidl
= ILCombine(pidlParent
, pidl
);
361 return E_OUTOFMEMORY
;
365 new_pidl
= ILClone(pidl
);
367 return E_OUTOFMEMORY
;
370 ret
= IShellItem_Constructor(NULL
, &IID_IShellItem
, (void**)&This
);
373 *ppsi
= (IShellItem
*)This
;
374 This
->pidl
= new_pidl
;