ReactOS  0.4.13-dev-247-g0f29b3f
CShellItem.cpp
Go to the documentation of this file.
1 /*
2  * IShellItem implementation
3  *
4  * Copyright 2008 Vincent Povirk for CodeWeavers
5  * Copyright 2009 Andrew Hill
6  * Copyright 2013 Katayama Hirofumi MZ
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21  */
22 
23 #include "precomp.h"
24 
26 
28  IShellFolder *psfParent, LPCITEMIDLIST pidl, IShellItem **ppsi);
29 
31  m_pidl(NULL)
32 {
33 }
34 
36 {
37  ILFree(m_pidl);
38 }
39 
41 {
42  *parent_pidl = ILClone(m_pidl);
43  if (*parent_pidl)
44  {
45  if (ILRemoveLastID(*parent_pidl))
46  return S_OK;
47  else
48  {
49  ILFree(*parent_pidl);
50  *parent_pidl = NULL;
51  return E_INVALIDARG;
52  }
53  }
54  else
55  {
56  *parent_pidl = NULL;
57  return E_OUTOFMEMORY;
58  }
59 }
60 
62 {
63  HRESULT hr;
64  LPITEMIDLIST parent_pidl;
65  CComPtr<IShellFolder> desktop;
66 
67  hr = get_parent_pidl(&parent_pidl);
68  if (SUCCEEDED(hr))
69  {
70  hr = SHGetDesktopFolder(&desktop);
71  if (SUCCEEDED(hr))
72  hr = desktop->BindToObject(parent_pidl, NULL, IID_PPV_ARG(IShellFolder, ppsf));
73  ILFree(parent_pidl);
74  }
75 
76  return hr;
77 }
78 
80 {
82  CComPtr<IShellFolder> psfDesktop;
83  HRESULT ret;
84 
85  ret = SHGetDesktopFolder(&psfDesktop);
87  return ret;
88 
89  if (_ILIsDesktop(m_pidl))
90  psf = psfDesktop;
91  else
92  {
93  ret = psfDesktop->BindToObject(m_pidl, pbc, IID_PPV_ARG(IShellFolder, &psf));
95  return ret;
96  }
97 
98  return psf->QueryInterface(riid, ppvOut);
99 }
100 
102 {
103  HRESULT ret;
104  TRACE("(%p, %p,%s,%p,%p)\n", this, pbc, shdebugstr_guid(&rbhid), riid, ppvOut);
105 
106  *ppvOut = NULL;
107  if (IsEqualGUID(rbhid, BHID_SFObject))
108  {
109  return get_shellfolder(pbc, riid, ppvOut);
110  }
111  else if (IsEqualGUID(rbhid, BHID_SFUIObject))
112  {
113  CComPtr<IShellFolder> psf_parent;
114  if (_ILIsDesktop(m_pidl))
115  ret = SHGetDesktopFolder(&psf_parent);
116  else
117  ret = get_parent_shellfolder(&psf_parent);
119  return ret;
120 
122  return psf_parent->GetUIObjectOf(NULL, 1, &pidl, riid, NULL, ppvOut);
123  }
124  else if (IsEqualGUID(rbhid, BHID_DataObject))
125  {
126  return BindToHandler(pbc, BHID_SFUIObject, IID_IDataObject, ppvOut);
127  }
128  else if (IsEqualGUID(rbhid, BHID_SFViewObject))
129  {
133  return ret;
134 
135  return psf->CreateViewObject(NULL, riid, ppvOut);
136  }
137 
138  FIXME("Unsupported BHID %s.\n", debugstr_guid(&rbhid));
139 
140  return MK_E_NOOBJECT;
141 }
142 
144 {
145  HRESULT hr;
146  LPITEMIDLIST parent_pidl;
147 
148  TRACE("(%p,%p)\n", this, ppsi);
149 
150  hr = get_parent_pidl(&parent_pidl);
151  if (SUCCEEDED(hr))
152  {
153  hr = SHCreateShellItem(NULL, NULL, parent_pidl, ppsi);
154  ILFree(parent_pidl);
155  }
156 
157  return hr;
158 }
159 
161 {
163 }
164 
166 {
167  CComPtr<IShellFolder> parent_folder;
168  LPCITEMIDLIST child_pidl;
169  HRESULT hr;
170 
171  TRACE("(%p,%x,%p)\n", this, sfgaoMask, psfgaoAttribs);
172 
173  if (_ILIsDesktop(m_pidl))
174  hr = SHGetDesktopFolder(&parent_folder);
175  else
176  hr = get_parent_shellfolder(&parent_folder);
177  if (FAILED_UNEXPECTEDLY(hr))
178  return hr;
179 
180  child_pidl = ILFindLastID(m_pidl);
181  *psfgaoAttribs = sfgaoMask;
182  hr = parent_folder->GetAttributesOf(1, &child_pidl, psfgaoAttribs);
183  *psfgaoAttribs &= sfgaoMask;
184 
185  if (FAILED_UNEXPECTEDLY(hr))
186  return hr;
187 
188  return (sfgaoMask == *psfgaoAttribs) ? S_OK : S_FALSE;
189 }
190 
192 {
193  HRESULT hr;
194  CComPtr<IPersistIDList> pIDList;
195  CComPtr<IShellFolder> psfDesktop;
196  LPITEMIDLIST pidl;
197 
198  TRACE("(%p,%p,%x,%p)\n", this, oth, hint, piOrder);
199 
200  if (piOrder == NULL || oth == NULL)
201  return E_POINTER;
202 
203  hr = oth->QueryInterface(IID_PPV_ARG(IPersistIDList, &pIDList));
204  if (SUCCEEDED(hr))
205  {
206  hr = pIDList->GetIDList(&pidl);
207  if (SUCCEEDED(hr))
208  {
209  hr = SHGetDesktopFolder(&psfDesktop);
210  if (SUCCEEDED(hr))
211  {
212  hr = psfDesktop->CompareIDs(hint, m_pidl, pidl);
213  *piOrder = (int)(short)SCODE_CODE(hr);
214  }
215  ILFree(pidl);
216  }
217  }
218 
219  if(FAILED(hr))
220  return hr;
221 
222  if(*piOrder)
223  return S_FALSE;
224  else
225  return S_OK;
226 }
227 
229 {
230  TRACE("(%p,%p)\n", this, pClassID);
231 
232  *pClassID = CLSID_ShellItem;
233  return S_OK;
234 }
235 
237 {
238  LPITEMIDLIST new_pidl;
239 
240  TRACE("(%p,%p)\n", this, pidlx);
241 
242  new_pidl = ILClone(pidlx);
243  if (new_pidl)
244  {
245  ILFree(m_pidl);
246  m_pidl = new_pidl;
247  return S_OK;
248  }
249  else
250  return E_OUTOFMEMORY;
251 }
252 
254 {
255  TRACE("(%p,%p)\n", this, ppidl);
256 
257  *ppidl = ILClone(m_pidl);
258  if (*ppidl)
259  return S_OK;
260  else
261  return E_OUTOFMEMORY;
262 }
263 
265  IShellFolder *psfParent, LPCITEMIDLIST pidl, IShellItem **ppsi)
266 {
267  HRESULT hr;
268  CComPtr<IShellItem> newShellItem;
269  LPITEMIDLIST new_pidl;
270  CComPtr<IPersistIDList> newPersistIDList;
271 
272  TRACE("(%p,%p,%p,%p)\n", pidlParent, psfParent, pidl, ppsi);
273 
274  *ppsi = NULL;
275 
276  if (!pidl)
277  return E_INVALIDARG;
278 
279  if (pidlParent || psfParent)
280  {
281  LPITEMIDLIST temp_parent = NULL;
282  if (!pidlParent)
283  {
284  CComPtr<IPersistFolder2> ppf2Parent;
285 
286  if (FAILED(psfParent->QueryInterface(IID_PPV_ARG(IPersistFolder2, &ppf2Parent))))
287  {
288  FIXME("couldn't get IPersistFolder2 interface of parent\n");
289  return E_NOINTERFACE;
290  }
291 
292  if (FAILED(ppf2Parent->GetCurFolder(&temp_parent)))
293  {
294  FIXME("couldn't get parent PIDL\n");
295  return E_NOINTERFACE;
296  }
297 
298  pidlParent = temp_parent;
299  }
300 
301  new_pidl = ILCombine(pidlParent, pidl);
302  ILFree(temp_parent);
303 
304  if (!new_pidl)
305  return E_OUTOFMEMORY;
306  }
307  else
308  {
309  new_pidl = ILClone(pidl);
310  if (!new_pidl)
311  return E_OUTOFMEMORY;
312  }
313 
314  hr = CShellItem::_CreatorClass::CreateInstance(NULL, IID_PPV_ARG(IShellItem, &newShellItem));
315  if (FAILED(hr))
316  {
317  ILFree(new_pidl);
318  return hr;
319  }
320  hr = newShellItem->QueryInterface(IID_PPV_ARG(IPersistIDList, &newPersistIDList));
321  if (FAILED(hr))
322  {
323  ILFree(new_pidl);
324  return hr;
325  }
326  hr = newPersistIDList->SetIDList(new_pidl);
327  if (FAILED(hr))
328  {
329  ILFree(new_pidl);
330  return hr;
331  }
332  ILFree(new_pidl);
333 
334  *ppsi = newShellItem.Detach();
335 
336  return hr;
337 }
#define REFIID
Definition: guiddef.h:113
void WINAPI ILFree(LPITEMIDLIST pidl)
Definition: pidl.c:925
#define E_NOINTERFACE
Definition: winerror.h:2364
HRESULT hr
Definition: shlfolder.c:183
Definition: scsiwmi.h:51
REFIID riid
Definition: precomp.h:44
LPITEMIDLIST WINAPI ILCombine(LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2)
Definition: pidl.c:699
const ITEMIDLIST UNALIGNED * LPCITEMIDLIST
Definition: shtypes.idl:42
virtual HRESULT WINAPI SetIDList(LPCITEMIDLIST pidl)
Definition: CShellItem.cpp:236
const char * shdebugstr_guid(const struct _GUID *id)
Definition: debughlp.cpp:414
const GUID IID_IDataObject
BOOL WINAPI ILRemoveLastID(LPITEMIDLIST pidl)
Definition: pidl.c:212
#define IID_PPV_ARG(Itype, ppType)
virtual HRESULT WINAPI BindToHandler(IBindCtx *pbc, REFGUID rbhid, REFIID riid, void **ppvOut)
Definition: CShellItem.cpp:101
virtual HRESULT WINAPI GetIDList(LPITEMIDLIST *ppidl)
Definition: CShellItem.cpp:253
virtual HRESULT WINAPI GetAttributes(SFGAOF sfgaoMask, SFGAOF *psfgaoAttribs)
Definition: CShellItem.cpp:165
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define FIXME(fmt,...)
Definition: debug.h:110
HRESULT WINAPI SHGetNameFromIDList(PCIDLIST_ABSOLUTE pidl, SIGDN sigdnName, PWSTR *ppszName)
Definition: pidl.c:1409
HRESULT get_parent_pidl(LPITEMIDLIST *parent_pidl)
Definition: CShellItem.cpp:40
HRESULT get_shellfolder(IBindCtx *pbc, REFIID riid, void **ppvOut)
Definition: CShellItem.cpp:79
#define S_FALSE
Definition: winerror.h:2357
#define E_INVALIDARG
Definition: ddrawi.h:101
virtual HRESULT WINAPI GetParent(IShellItem **ppsi)
Definition: CShellItem.cpp:143
SIGDN sigdnName
Definition: shobjidl.idl:588
virtual HRESULT WINAPI Compare(IShellItem *oth, SICHINTF hint, int *piOrder)
Definition: CShellItem.cpp:191
smooth NULL
Definition: ftsmooth.c:416
LPITEMIDLIST WINAPI ILFindLastID(LPCITEMIDLIST pidl)
Definition: pidl.c:189
#define debugstr_guid
Definition: kernel32.h:35
BOOL _ILIsDesktop(LPCITEMIDLIST pidl)
Definition: CBandSite.h:24
SIGDN PWSTR * ppszName
Definition: shobjidl.idl:588
#define TRACE(s)
Definition: solgame.cpp:4
HRESULT WINAPI SHGetDesktopFolder(IShellFolder **psf)
LPITEMIDLIST m_pidl
Definition: CShellItem.h:32
LONG HRESULT
Definition: typedefs.h:77
#define FAILED_UNEXPECTEDLY(hr)
Definition: shellutils.h:35
#define WINAPI
Definition: msvc.h:8
int ret
EXTERN_C HRESULT WINAPI SHCreateShellItem(LPCITEMIDLIST pidlParent, IShellFolder *psfParent, LPCITEMIDLIST pidl, IShellItem **ppsi)
Definition: CShellItem.cpp:264
virtual HRESULT WINAPI GetDisplayName(SIGDN sigdnName, LPWSTR *ppszName)
Definition: CShellItem.cpp:160
DWORD SICHINTF
Definition: shobjidl.idl:373
#define S_OK
Definition: intsafe.h:59
DWORD hint
Definition: vfdcmd.c:88
virtual HRESULT WINAPI GetClassID(CLSID *pClassID)
Definition: CShellItem.cpp:228
void shell(int argc, const char *argv[])
Definition: cmds.c:1231
LPITEMIDLIST WINAPI ILClone(LPCITEMIDLIST pidl)
Definition: pidl.c:228
BOOL WINAPI IsEqualGUID(REFGUID rguid1, REFGUID rguid2)
Definition: compobj.c:4021
#define SCODE_CODE(sc)
Definition: winerror.h:77
WINE_DEFAULT_DEBUG_CHANNEL(shell)
HRESULT QueryInterface([in] REFIID riid, [out, iid_is(riid)] void **ppvObject)
T * Detach()
Definition: atlcomcli.h:156
WCHAR * LPWSTR
Definition: xmlstorage.h:184
#define E_POINTER
Definition: winerror.h:2365
#define EXTERN_C
Definition: basetyps.h:12
ITEMIDLIST UNALIGNED * LPITEMIDLIST
Definition: shtypes.idl:41
HRESULT get_parent_shellfolder(IShellFolder **ppsf)
Definition: CShellItem.cpp:61
static IShellFolder IShellItem **static IBindCtx LPITEMIDLIST SFGAOF
Definition: ebrowser.c:83
#define MK_E_NOOBJECT
Definition: winerror.h:2786
#define SUCCEEDED(hr)
Definition: intsafe.h:57
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31