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 var, FolderItem **ppid) 251 { 252 CComVariant index; 253 HRESULT hr; 254 255 if (!m_EnumIDList) 256 return E_FAIL; 257 258 hr = VariantCopyInd(&index, &var); 259 if (FAILED(hr)) 260 return hr; 261 262 if (V_VT(&index) == VT_I2) 263 VariantChangeType(&index, &index, 0, VT_I4); 264 265 if (V_VT(&index) == VT_I4) 266 { 267 ULONG count = V_UI4(&index); 268 269 hr = m_EnumIDList->Reset(); 270 if (FAILED_UNEXPECTEDLY(hr)) 271 return hr; 272 273 hr = m_EnumIDList->Skip(count); 274 275 if (FAILED_UNEXPECTEDLY(hr)) 276 return hr; 277 278 CComHeapPtr<ITEMIDLIST> spPidl; 279 hr = m_EnumIDList->Next(1, &spPidl, 0); 280 if (FAILED_UNEXPECTEDLY(hr)) 281 return hr; 282 hr = ShellObjectCreatorInit<CFolderItem>(m_Folder, static_cast<LPITEMIDLIST>(spPidl), IID_PPV_ARG(FolderItem, ppid)); 283 if (FAILED_UNEXPECTEDLY(hr)) 284 return hr; 285 return hr; 286 } 287 else if (V_VT(&index) == VT_BSTR) 288 { 289 if (!V_BSTR(&index)) 290 return S_FALSE; 291 292 hr = m_Folder->ParseName(V_BSTR(&index), ppid); 293 if (FAILED_UNEXPECTEDLY(hr)) 294 return hr; 295 return hr; 296 } 297 298 FIXME("Index type %d not handled.\n", V_VT(&index)); 299 return E_NOTIMPL; 300 } 301 302 HRESULT STDMETHODCALLTYPE CFolderItems::_NewEnum(IUnknown **ppunk) 303 { 304 return ShellObjectCreatorInit<CFolderItems>(static_cast<LPITEMIDLIST>(m_idlist), m_Folder, IID_FolderItems, reinterpret_cast<void**>(ppunk)); 305 } 306 307