[shell32.dll]
[reactos.git] / dll / win32 / shell32 / shellitem.cpp
1 /*
2 * IShellItem implementation
3 *
4 * Copyright 2008 Vincent Povirk for CodeWeavers
5 * Copyright 2009 Andrew Hill
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 */
21
22 #include "precomp.h"
23
24 WINE_DEFAULT_DEBUG_CHANNEL(shell);
25
26 EXTERN_C HRESULT WINAPI SHCreateShellItem(LPCITEMIDLIST pidlParent,
27 IShellFolder *psfParent, LPCITEMIDLIST pidl, IShellItem **ppsi);
28
29 ShellItem::ShellItem()
30 {
31 pidl = NULL;
32 }
33
34 ShellItem::~ShellItem()
35 {
36 ILFree(pidl);
37 }
38
39 HRESULT ShellItem::get_parent_pidl(LPITEMIDLIST *parent_pidl)
40 {
41 *parent_pidl = ILClone(pidl);
42 if (*parent_pidl)
43 {
44 if (ILRemoveLastID(*parent_pidl))
45 return S_OK;
46 else
47 {
48 ILFree(*parent_pidl);
49 *parent_pidl = NULL;
50 return E_INVALIDARG;
51 }
52 }
53 else
54 {
55 *parent_pidl = NULL;
56 return E_OUTOFMEMORY;
57 }
58 }
59
60 HRESULT ShellItem::get_parent_shellfolder(IShellFolder **ppsf)
61 {
62 LPITEMIDLIST parent_pidl;
63 CComPtr<IShellFolder> desktop;
64 HRESULT ret;
65
66 ret = get_parent_pidl(&parent_pidl);
67 if (SUCCEEDED(ret))
68 {
69 ret = SHGetDesktopFolder(&desktop);
70 if (SUCCEEDED(ret))
71 ret = desktop->BindToObject(parent_pidl, NULL, IID_IShellFolder, (void**)ppsf);
72 ILFree(parent_pidl);
73 }
74
75 return ret;
76 }
77
78 HRESULT WINAPI ShellItem::BindToHandler(IBindCtx *pbc, REFGUID rbhid, REFIID riid, void **ppvOut)
79 {
80 FIXME("(%p,%p,%s,%p,%p)\n", this, pbc, shdebugstr_guid(&rbhid), riid, ppvOut);
81
82 *ppvOut = NULL;
83
84 return E_NOTIMPL;
85 }
86
87 HRESULT WINAPI ShellItem::GetParent(IShellItem **ppsi)
88 {
89 LPITEMIDLIST parent_pidl;
90 HRESULT ret;
91
92 TRACE("(%p,%p)\n", this, ppsi);
93
94 ret = get_parent_pidl(&parent_pidl);
95 if (SUCCEEDED(ret))
96 {
97 ret = SHCreateShellItem(NULL, NULL, parent_pidl, ppsi);
98 ILFree(parent_pidl);
99 }
100
101 return ret;
102 }
103
104 HRESULT WINAPI ShellItem::GetDisplayName(SIGDN sigdnName, LPWSTR *ppszName)
105 {
106 FIXME("(%p,%x,%p)\n", this, sigdnName, ppszName);
107
108 *ppszName = NULL;
109
110 return E_NOTIMPL;
111 }
112
113 HRESULT WINAPI ShellItem::GetAttributes(SFGAOF sfgaoMask, SFGAOF *psfgaoAttribs)
114 {
115 CComPtr<IShellFolder> parent_folder;
116 LPITEMIDLIST child_pidl;
117 HRESULT ret;
118
119 TRACE("(%p,%x,%p)\n", this, sfgaoMask, psfgaoAttribs);
120
121 ret = get_parent_shellfolder(&parent_folder);
122 if (SUCCEEDED(ret))
123 {
124 child_pidl = ILFindLastID(pidl);
125 *psfgaoAttribs = sfgaoMask;
126 ret = parent_folder->GetAttributesOf(1, (LPCITEMIDLIST*)&child_pidl, psfgaoAttribs);
127 }
128
129 return ret;
130 }
131
132 HRESULT WINAPI ShellItem::Compare(IShellItem *oth, SICHINTF hint, int *piOrder)
133 {
134 FIXME("(%p,%p,%x,%p)\n", this, oth, hint, piOrder);
135
136 return E_NOTIMPL;
137 }
138
139 HRESULT WINAPI ShellItem::GetClassID(CLSID *pClassID)
140 {
141 TRACE("(%p,%p)\n", this, pClassID);
142
143 *pClassID = CLSID_ShellItem;
144 return S_OK;
145 }
146
147
148 HRESULT WINAPI ShellItem::SetIDList(LPCITEMIDLIST pidlx)
149 {
150 LPITEMIDLIST new_pidl;
151
152 TRACE("(%p,%p)\n", this, pidlx);
153
154 new_pidl = ILClone(pidlx);
155
156 if (new_pidl)
157 {
158 ILFree(pidl);
159 pidl = new_pidl;
160 return S_OK;
161 }
162 else
163 return E_OUTOFMEMORY;
164 }
165
166 HRESULT WINAPI ShellItem::GetIDList(LPITEMIDLIST *ppidl)
167 {
168 TRACE("(%p,%p)\n", this, ppidl);
169
170 *ppidl = ILClone(pidl);
171 if (*ppidl)
172 return S_OK;
173 else
174 return E_OUTOFMEMORY;
175 }
176
177 HRESULT WINAPI SHCreateShellItem(LPCITEMIDLIST pidlParent,
178 IShellFolder *psfParent, LPCITEMIDLIST pidl, IShellItem **ppsi)
179 {
180 IShellItem *newShellItem;
181 LPITEMIDLIST new_pidl;
182 CComPtr<IPersistIDList> newPersistIDList;
183 HRESULT ret;
184
185 TRACE("(%p,%p,%p,%p)\n", pidlParent, psfParent, pidl, ppsi);
186
187 if (!pidl)
188 {
189 return E_INVALIDARG;
190 }
191 else if (pidlParent || psfParent)
192 {
193 LPITEMIDLIST temp_parent=NULL;
194 if (!pidlParent)
195 {
196 CComPtr<IPersistFolder2> ppf2Parent;
197
198 if (FAILED(psfParent->QueryInterface(IID_IPersistFolder2, (void**)&ppf2Parent)))
199 {
200 FIXME("couldn't get IPersistFolder2 interface of parent\n");
201 return E_NOINTERFACE;
202 }
203
204 if (FAILED(ppf2Parent->GetCurFolder(&temp_parent)))
205 {
206 FIXME("couldn't get parent PIDL\n");
207 return E_NOINTERFACE;
208 }
209
210 pidlParent = temp_parent;
211 }
212
213 new_pidl = ILCombine(pidlParent, pidl);
214 ILFree(temp_parent);
215
216 if (!new_pidl)
217 return E_OUTOFMEMORY;
218 }
219 else
220 {
221 new_pidl = ILClone(pidl);
222 if (!new_pidl)
223 return E_OUTOFMEMORY;
224 }
225
226 ret = ShellItem::_CreatorClass::CreateInstance(NULL, IID_IShellItem, (void**)&newShellItem);
227 if (FAILED(ret))
228 {
229 *ppsi = NULL;
230 ILFree(new_pidl);
231 return ret;
232 }
233 ret = newShellItem->QueryInterface(IID_IPersistIDList, (void **)&newPersistIDList);
234 if (FAILED(ret))
235 {
236 ILFree(new_pidl);
237 return ret;
238 }
239 ret = newPersistIDList->SetIDList(new_pidl);
240 if (FAILED(ret))
241 {
242 ILFree(new_pidl);
243 return ret;
244 }
245 ILFree(new_pidl);
246 *ppsi = newShellItem;
247 return ret;
248 }