[BOOTDATA][SHELL32] Add some recognized file extensions (.db, .efi, .nls, .ocx, ...
[reactos.git] / dll / win32 / shell32 / CFolderItems.cpp
1 /*
2 * PROJECT: shell32
3 * LICENSE: LGPL-2.1+ (https://spdx.org/licenses/LGPL-2.1+)
4 * PURPOSE: FolderItem(s) implementation
5 * COPYRIGHT: Copyright 2015-2018 Mark Jansen (mark.jansen@reactos.org)
6 */
7
8 #include "precomp.h"
9
10 WINE_DEFAULT_DEBUG_CHANNEL(shell);
11
12
13 CFolderItem::CFolderItem()
14 {
15 }
16
17 CFolderItem::~CFolderItem()
18 {
19 }
20
21 HRESULT CFolderItem::Initialize(Folder* folder, LPITEMIDLIST idlist)
22 {
23 m_idlist.Attach(ILClone(idlist));
24 m_Folder = folder;
25 return S_OK;
26 }
27
28 // *** FolderItem methods ***
29 HRESULT STDMETHODCALLTYPE CFolderItem::get_Application(IDispatch **ppid)
30 {
31 TRACE("(%p, %p)\n", this, ppid);
32 return m_Folder->get_Application(ppid);
33 }
34
35 HRESULT STDMETHODCALLTYPE CFolderItem::get_Parent(IDispatch **ppid)
36 {
37 TRACE("(%p, %p)\n", this, ppid);
38 if (ppid)
39 {
40 *ppid = m_Folder;
41 m_Folder->AddRef();
42 }
43 return E_NOTIMPL;
44 }
45
46 HRESULT STDMETHODCALLTYPE CFolderItem::get_Name(BSTR *pbs)
47 {
48 TRACE("(%p, %p)\n", this, pbs);
49
50 *pbs = NULL;
51
52 CComPtr<IShellFolder2> Parent;
53 LPCITEMIDLIST last_part;
54 HRESULT hr = SHBindToParent(m_idlist, IID_PPV_ARG(IShellFolder2, &Parent), &last_part);
55 if (FAILED_UNEXPECTEDLY(hr))
56 return hr;
57
58 STRRET strret;
59 hr = Parent->GetDisplayNameOf(last_part, SHGDN_INFOLDER, &strret);
60 if (!FAILED_UNEXPECTEDLY(hr))
61 hr = StrRetToBSTR(&strret, last_part, pbs);
62
63 return hr;
64 }
65
66 HRESULT STDMETHODCALLTYPE CFolderItem::put_Name(BSTR bs)
67 {
68 TRACE("(%p, %s)\n", this, wine_dbgstr_w(bs));
69 return E_NOTIMPL;
70 }
71
72 HRESULT STDMETHODCALLTYPE CFolderItem::get_Path(BSTR *pbs)
73 {
74 CComPtr<IShellFolder> psfDesktop;
75
76 HRESULT hr = SHGetDesktopFolder(&psfDesktop);
77 if (!SUCCEEDED(hr))
78 return hr;
79
80 STRRET strret;
81 hr = psfDesktop->GetDisplayNameOf(m_idlist, SHGDN_FORPARSING, &strret);
82 if (FAILED_UNEXPECTEDLY(hr))
83 return hr;
84
85 return StrRetToBSTR(&strret, NULL, pbs);
86 }
87
88 HRESULT STDMETHODCALLTYPE CFolderItem::get_GetLink(IDispatch **ppid)
89 {
90 TRACE("(%p, %p)\n", this, ppid);
91 return E_NOTIMPL;
92 }
93
94 HRESULT STDMETHODCALLTYPE CFolderItem::get_GetFolder(IDispatch **ppid)
95 {
96 TRACE("(%p, %p)\n", this, ppid);
97 return E_NOTIMPL;
98 }
99
100 HRESULT STDMETHODCALLTYPE CFolderItem::get_IsLink(VARIANT_BOOL *pb)
101 {
102 TRACE("(%p, %p)\n", this, pb);
103 return E_NOTIMPL;
104 }
105
106 HRESULT STDMETHODCALLTYPE CFolderItem::get_IsFolder(VARIANT_BOOL *pb)
107 {
108 TRACE("(%p, %p)\n", this, pb);
109 return E_NOTIMPL;
110 }
111
112 HRESULT STDMETHODCALLTYPE CFolderItem::get_IsFileSystem(VARIANT_BOOL *pb)
113 {
114 TRACE("(%p, %p)\n", this, pb);
115 return E_NOTIMPL;
116 }
117
118 HRESULT STDMETHODCALLTYPE CFolderItem::get_IsBrowsable(VARIANT_BOOL *pb)
119 {
120 TRACE("(%p, %p)\n", this, pb);
121 return E_NOTIMPL;
122 }
123
124 HRESULT STDMETHODCALLTYPE CFolderItem::get_ModifyDate(DATE *pdt)
125 {
126 TRACE("(%p, %p)\n", this, pdt);
127 return E_NOTIMPL;
128 }
129
130 HRESULT STDMETHODCALLTYPE CFolderItem::put_ModifyDate(DATE dt)
131 {
132 TRACE("(%p, %f)\n", this, dt);
133 return E_NOTIMPL;
134 }
135
136 HRESULT STDMETHODCALLTYPE CFolderItem::get_Size(LONG *pul)
137 {
138 TRACE("(%p, %p)\n", this, pul);
139 return E_NOTIMPL;
140 }
141
142 HRESULT STDMETHODCALLTYPE CFolderItem::get_Type(BSTR *pbs)
143 {
144 TRACE("(%p, %p)\n", this, pbs);
145 return E_NOTIMPL;
146 }
147
148 HRESULT STDMETHODCALLTYPE CFolderItem::Verbs(FolderItemVerbs **ppfic)
149 {
150 if (!ppfic)
151 return E_POINTER;
152 CFolderItemVerbs* verbs = new CComObject<CFolderItemVerbs>();
153 HRESULT hr = verbs->Init(m_idlist);
154 if (FAILED_UNEXPECTEDLY(hr))
155 {
156 delete verbs;
157 return hr;
158 }
159 verbs->AddRef();
160 *ppfic = verbs;
161 return S_OK;
162 }
163
164 HRESULT STDMETHODCALLTYPE CFolderItem::InvokeVerb(VARIANT vVerb)
165 {
166 TRACE("(%p, %s)\n", this, wine_dbgstr_variant(&vVerb));
167 return E_NOTIMPL;
168 }
169
170
171
172 CFolderItems::CFolderItems()
173 :m_Count(-1)
174 {
175 }
176
177 CFolderItems::~CFolderItems()
178 {
179 }
180
181 HRESULT CFolderItems::Initialize(LPITEMIDLIST idlist, Folder* parent)
182 {
183 CComPtr<IShellFolder> psfDesktop, psfTarget;
184
185 m_idlist.Attach(ILClone(idlist));
186
187 HRESULT hr = SHGetDesktopFolder(&psfDesktop);
188 if (FAILED_UNEXPECTEDLY(hr))
189 return hr;
190
191 hr = psfDesktop->BindToObject(m_idlist, NULL, IID_PPV_ARG(IShellFolder, &psfTarget));
192 if (FAILED_UNEXPECTEDLY(hr))
193 return hr;
194
195 hr = psfTarget->EnumObjects(NULL, SHCONTF_FOLDERS | SHCONTF_NONFOLDERS, &m_EnumIDList);
196
197 if (FAILED_UNEXPECTEDLY(hr))
198 return hr;
199
200 m_Folder = parent;
201 return S_OK;
202 }
203
204 // *** FolderItems methods ***
205 HRESULT STDMETHODCALLTYPE CFolderItems::get_Count(long *plCount)
206 {
207 if (!m_EnumIDList)
208 return E_FAIL;
209
210 if (!plCount)
211 return E_POINTER;
212
213 if (m_Count == -1)
214 {
215 long count = 0;
216
217 HRESULT hr = m_EnumIDList->Reset();
218 if (FAILED_UNEXPECTEDLY(hr))
219 return hr;
220
221 CComHeapPtr<ITEMIDLIST> Pidl;
222 while ((hr = m_EnumIDList->Next(1, &Pidl, 0)) != S_FALSE)
223 {
224 count++;
225 Pidl.Free();
226 }
227 m_Count = count;
228 }
229 *plCount = m_Count;
230
231 return S_OK;
232 }
233
234 HRESULT STDMETHODCALLTYPE CFolderItems::get_Application(IDispatch **ppid)
235 {
236 TRACE("(%p, %p)\n", this, ppid);
237 return m_Folder->get_Application(ppid);
238 }
239
240 HRESULT STDMETHODCALLTYPE CFolderItems::get_Parent(IDispatch **ppid)
241 {
242 TRACE("(%p, %p)\n", this, ppid);
243
244 if (ppid)
245 *ppid = NULL;
246
247 return E_NOTIMPL;
248 }
249
250 HRESULT STDMETHODCALLTYPE CFolderItems::Item(VARIANT index, FolderItem **ppid)
251 {
252 if (!m_EnumIDList)
253 return E_FAIL;
254
255 if (V_VT(&index) == VT_I2)
256 VariantChangeType(&index, &index, 0, VT_I4);
257
258 if (V_VT(&index) == VT_I4)
259 {
260 ULONG count = V_UI4(&index);
261
262 HRESULT hr = m_EnumIDList->Reset();
263 if (FAILED_UNEXPECTEDLY(hr))
264 return hr;
265
266 hr = m_EnumIDList->Skip(count);
267
268 if (FAILED_UNEXPECTEDLY(hr))
269 return hr;
270
271 CComHeapPtr<ITEMIDLIST> spPidl;
272 hr = m_EnumIDList->Next(1, &spPidl, 0);
273 if (FAILED_UNEXPECTEDLY(hr))
274 return hr;
275 hr = ShellObjectCreatorInit<CFolderItem>(m_Folder, static_cast<LPITEMIDLIST>(spPidl), IID_PPV_ARG(FolderItem, ppid));
276 if (FAILED_UNEXPECTEDLY(hr))
277 return hr;
278 return hr;
279 }
280 else if (V_VT(&index) == VT_BSTR)
281 {
282 if (!V_BSTR(&index))
283 return S_FALSE;
284
285 HRESULT hr = m_Folder->ParseName(V_BSTR(&index), ppid);
286 if (FAILED_UNEXPECTEDLY(hr))
287 return hr;
288 return hr;
289 }
290
291 FIXME("Index type %d not handled.\n", V_VT(&index));
292 return E_NOTIMPL;
293 }
294
295 HRESULT STDMETHODCALLTYPE CFolderItems::_NewEnum(IUnknown **ppunk)
296 {
297 return ShellObjectCreatorInit<CFolderItems>(static_cast<LPITEMIDLIST>(m_idlist), m_Folder, IID_FolderItems, reinterpret_cast<void**>(ppunk));
298 }
299