ReactOS 0.4.16-dev-981-g80eb313
recyclebin_v5_enumerator.cpp
Go to the documentation of this file.
1/*
2 * PROJECT: Recycle bin management
3 * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
4 * PURPOSE: Enumerates contents of a MS Windows 2000/XP/2003 recyclebin
5 * COPYRIGHT: Copyright 2006-2007 Hervé Poussineau (hpoussin@reactos.org)
6 * Copyright 2024 Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com)
7 */
8
10#include <atlstr.h>
11#include <shlwapi.h>
12#include <strsafe.h>
13
14class RecycleBin5File : public IRecycleBinFile
15{
16public:
18 virtual ~RecycleBin5File();
19
21 _In_ IRecycleBin5 *prb,
22 _In_ LPCWSTR Folder,
23 _In_ PDELETED_FILE_RECORD pDeletedFile);
24
25 /* IUnknown methods */
29
30 /* IRecycleBinFile methods */
32 {
35 }
37 STDMETHODIMP GetLastModificationTime(FILETIME *pLastModificationTime) override;
38 STDMETHODIMP GetDeletionTime(FILETIME *pDeletionTime) override;
39 STDMETHODIMP GetFileSize(ULARGE_INTEGER *pFileSize) override;
40 STDMETHODIMP GetPhysicalFileSize(ULARGE_INTEGER *pPhysicalFileSize) override;
41 STDMETHODIMP GetAttributes(DWORD *pAttributes) override;
43 STDMETHODIMP Delete() override;
44 STDMETHODIMP Restore() override;
46
47protected:
52};
53
55{
56 TRACE("(%p, %s, %p)\n", this, debugstr_guid(&riid), ppvObject);
57
58 if (!ppvObject)
59 return E_POINTER;
60
62 {
63 *ppvObject = static_cast<IRecycleBinFile *>(this);
64 }
65 else
66 {
67 *ppvObject = NULL;
68 return E_NOINTERFACE;
69 }
70
71 AddRef();
72 return S_OK;
73}
74
75STDMETHODIMP_(ULONG) RecycleBin5File::AddRef()
76{
77 TRACE("(%p)\n", this);
79}
80
82{
83 TRACE("(%p)\n", this);
84 m_recycleBin->Release();
86}
87
88STDMETHODIMP_(ULONG) RecycleBin5File::Release()
89{
90 TRACE("(%p)\n", this);
91 ULONG refCount = InterlockedDecrement(&m_ref);
92 if (refCount == 0)
93 delete this;
94 return refCount;
95}
96
98{
99 HRESULT hr = S_OK;
100 ULARGE_INTEGER uli;
102 ZeroMemory(&pInfo->LastModification, sizeof(pInfo->LastModification));
104 C_ASSERT(sizeof(pInfo->FileSize) <= sizeof(UINT));
105 pInfo->FileSize = FAILED(GetFileSize(&uli)) ? INVALID_FILE_SIZE : uli.LowPart;
106 if (FAILED(hr = GetAttributes(&pInfo->Attributes)))
107 pInfo->Attributes = 0;
110 return hr;
111}
112
114{
115 TRACE("(%p, %p)\n", this, pLastModificationTime);
116
120
126 NULL,
129 NULL);
132
133 HRESULT hr;
134 if (GetFileTime(hFile, NULL, NULL, pLastModificationTime))
135 hr = S_OK;
136 else
139 return hr;
140}
141
143{
144 TRACE("(%p, %p)\n", this, pDeletionTime);
145 *pDeletionTime = m_deletedFile.DeletionTime;
146 return S_OK;
147}
148
150{
151 TRACE("(%p, %p)\n", this, pFileSize);
152
157 {
158 pFileSize->QuadPart = 0;
159 return S_OK;
160 }
161
165 pFileSize->u.LowPart = ::GetFileSize(hFile, &pFileSize->u.HighPart);
166
167 HRESULT hr;
168 if (pFileSize->u.LowPart != INVALID_FILE_SIZE)
169 hr = S_OK;
170 else
172
174 return hr;
175}
176
178{
179 TRACE("(%p, %p)\n", this, pPhysicalFileSize);
180 pPhysicalFileSize->u.HighPart = 0;
181 pPhysicalFileSize->u.LowPart = m_deletedFile.dwPhysicalFileSize;
182 return S_OK;
183}
184
186{
188
189 TRACE("(%p, %p)\n", this, pAttributes);
190
194
195 *pAttributes = dwAttributes;
196 return S_OK;
197}
198
200{
201 DWORD dwRequired;
202
203 TRACE("(%p, %u, %p, %p)\n", this, BufferSize, Buffer, RequiredSize);
204
205 dwRequired = (DWORD)(wcslen(m_deletedFile.FileNameW) + 1) * sizeof(WCHAR);
206 if (RequiredSize)
207 *RequiredSize = dwRequired;
208
209 if (BufferSize == 0 && !Buffer)
210 return S_OK;
211
212 if (BufferSize < dwRequired)
213 return E_OUTOFMEMORY;
215 return S_OK;
216}
217
219{
220 TRACE("(%p)\n", this);
221 return m_recycleBin->Delete(m_FullName, &m_deletedFile);
222}
223
225{
226 TRACE("(%p)\n", this);
227 return m_recycleBin->Restore(m_FullName, &m_deletedFile);
228}
229
231{
232 TRACE("(%p)\n", this);
233 return m_recycleBin->RemoveFromDatabase(m_FullName, &m_deletedFile);
234}
235
237 : m_ref(1)
238 , m_recycleBin(NULL)
239 , m_FullName(NULL)
240{
242}
243
246 _In_ IRecycleBin5 *prb,
247 _In_ LPCWSTR Folder,
248 _In_ PDELETED_FILE_RECORD pDeletedFile)
249{
250 m_recycleBin = prb;
251 m_recycleBin->AddRef();
252 m_deletedFile = *pDeletedFile;
253
254 WCHAR szUniqueId[32];
255 StringCchPrintfW(szUniqueId, _countof(szUniqueId), L"%lu", pDeletedFile->dwRecordUniqueId);
256
257 CStringW strFullName(Folder);
258 strFullName += L"\\D";
259 strFullName += (WCHAR)(L'a' + pDeletedFile->dwDriveNumber);
260 strFullName += szUniqueId;
261 strFullName += PathFindExtensionW(pDeletedFile->FileNameW);
263 return E_FAIL;
264
265 return SHStrDup(strFullName, &m_FullName);
266}
267
268static HRESULT
270 _In_ IRecycleBin5 *prb,
271 _In_ LPCWSTR Folder,
272 _In_ PDELETED_FILE_RECORD pDeletedFile,
273 _Out_ IRecycleBinFile **ppFile)
274{
275 if (!ppFile)
276 return E_POINTER;
277
278 *ppFile = NULL;
279
280 RecycleBin5File *pThis = new RecycleBin5File();
281 if (!pThis)
282 return E_OUTOFMEMORY;
283
284 HRESULT hr = pThis->Init(prb, Folder, pDeletedFile);
285 if (FAILED(hr))
286 {
287 delete pThis;
288 return hr;
289 }
290
291 *ppFile = static_cast<IRecycleBinFile *>(pThis);
292 return S_OK;
293}
294
295class RecycleBin5Enum : public IRecycleBinEnumList
296{
297public:
299 virtual ~RecycleBin5Enum();
300
302 _In_ IRecycleBin5 *prb,
303 _In_ HANDLE hInfo,
304 _In_ HANDLE hInfoMapped,
305 _In_ LPCWSTR pszPrefix);
306
307 /* IUnknown methods */
311
312 /* IRecycleBinEnumList methods */
313 STDMETHODIMP Next(DWORD celt, IRecycleBinFile **rgelt, DWORD *pceltFetched) override;
314 STDMETHODIMP Skip(DWORD celt) override;
315 STDMETHODIMP Reset() override;
316
317protected:
324};
325
327{
328 TRACE("(%p, %s, %p)\n", this, debugstr_guid(&riid), ppvObject);
329
330 if (!ppvObject)
331 return E_POINTER;
332
334 *ppvObject = static_cast<IRecycleBinEnumList *>(this);
335 else
336 {
337 *ppvObject = NULL;
338 return E_NOINTERFACE;
339 }
340
341 AddRef();
342 return S_OK;
343}
344
345STDMETHODIMP_(ULONG) RecycleBin5Enum::AddRef()
346{
347 TRACE("(%p)\n", this);
349}
350
352{
353 TRACE("(%p)\n", this);
354
355 m_recycleBin->OnClosing(this);
357 m_recycleBin->Release();
359}
360
361STDMETHODIMP_(ULONG) RecycleBin5Enum::Release()
362{
363 TRACE("(%p)\n", this);
364
365 ULONG refCount = InterlockedDecrement(&m_ref);
366 if (refCount == 0)
367 delete this;
368 return refCount;
369}
370
371STDMETHODIMP RecycleBin5Enum::Next(DWORD celt, IRecycleBinFile **rgelt, DWORD *pceltFetched)
372{
373 HRESULT hr;
374
375 TRACE("(%p, %u, %p, %p)\n", this, celt, rgelt, pceltFetched);
376
377 if (!rgelt)
378 return E_POINTER;
379 if (!pceltFetched && celt > 1)
380 return E_INVALIDARG;
381
383 FileSize.u.LowPart = GetFileSize(m_hInfo, &FileSize.u.HighPart);
384 if (FileSize.u.LowPart == 0)
386
387 DWORD dwEntries =
388 (DWORD)((FileSize.QuadPart - sizeof(INFO2_HEADER)) / sizeof(DELETED_FILE_RECORD));
389
390 DWORD iEntry = m_dwCurrent, fetched = 0;
391 PDELETED_FILE_RECORD pDeletedFile = (PDELETED_FILE_RECORD)(m_pInfo + 1) + iEntry;
392 for (; iEntry < dwEntries && fetched < celt; ++iEntry)
393 {
394 hr = RecycleBin5File_Constructor(m_recycleBin, m_pszPrefix, pDeletedFile, &rgelt[fetched]);
395 if (SUCCEEDED(hr))
396 fetched++;
397 pDeletedFile++;
398 }
399
400 m_dwCurrent = iEntry;
401 if (pceltFetched)
402 *pceltFetched = fetched;
403 if (fetched == celt)
404 return S_OK;
405 else
406 return S_FALSE;
407}
408
410{
411 TRACE("(%p, %u)\n", this, celt);
412 m_dwCurrent += celt;
413 return S_OK;
414}
415
417{
418 TRACE("(%p)\n", this);
419 m_dwCurrent = 0;
420 return S_OK;
421}
422
424 : m_ref(1)
425 , m_recycleBin(NULL)
426 , m_hInfo(NULL)
427 , m_pInfo(NULL)
428 , m_dwCurrent(0)
429 , m_pszPrefix(NULL)
430{
431}
432
435 _In_ IRecycleBin5 *prb,
436 _In_ HANDLE hInfo,
437 _In_ HANDLE hInfoMapped,
438 _In_ LPCWSTR pszPrefix)
439{
440 m_recycleBin = prb;
441 m_recycleBin->AddRef();
442
443 HRESULT hr = SHStrDup(pszPrefix, &m_pszPrefix);
444 if (FAILED(hr))
445 return hr;
446
447 m_hInfo = hInfo;
448 m_pInfo = (PINFO2_HEADER)MapViewOfFile(hInfoMapped, FILE_MAP_READ, 0, 0, 0);
449 if (!m_pInfo)
451
453 return E_FAIL;
454
455 return S_OK;
456}
457
461 _In_ IRecycleBin5 *prb,
462 _In_ HANDLE hInfo,
463 _In_ HANDLE hInfoMapped,
464 _In_ LPCWSTR szPrefix,
465 _Out_ IUnknown **ppUnknown)
466{
467 if (!ppUnknown)
468 return E_POINTER;
469
470 *ppUnknown = NULL;
471
472 RecycleBin5Enum *pThis = new RecycleBin5Enum();
473 if (!pThis)
474 return E_OUTOFMEMORY;
475
476 HRESULT hr = pThis->Init(prb, hInfo, hInfoMapped, szPrefix);
477 if (FAILED(hr))
478 {
479 delete pThis;
480 return hr;
481 }
482
483 *ppUnknown = static_cast<IRecycleBinEnumList *>(pThis);
484 return S_OK;
485}
#define InterlockedIncrement
Definition: armddk.h:53
#define InterlockedDecrement
Definition: armddk.h:52
#define EXTERN_C
Definition: basetyps.h:12
#define STDMETHODIMP
Definition: basetyps.h:43
#define STDMETHODIMP_(t)
Definition: basetyps.h:44
const GUID IID_IUnknown
_In_ BOOLEAN Release
Definition: cdrom.h:920
Definition: bufpool.h:45
STDMETHODIMP Reset() override
STDMETHODIMP Next(DWORD celt, IRecycleBinFile **rgelt, DWORD *pceltFetched) override
STDMETHODIMP Skip(DWORD celt) override
STDMETHODIMP QueryInterface(REFIID riid, void **ppvObject) override
HRESULT Init(_In_ IRecycleBin5 *prb, _In_ HANDLE hInfo, _In_ HANDLE hInfoMapped, _In_ LPCWSTR pszPrefix)
STDMETHODIMP_(ULONG) AddRef() override
STDMETHODIMP_(ULONG) Release() override
STDMETHODIMP IsEqualIdentity(const RECYCLEBINFILEIDENTITY *pFI) override
STDMETHODIMP GetFileSize(ULARGE_INTEGER *pFileSize) override
STDMETHODIMP GetPhysicalFileSize(ULARGE_INTEGER *pPhysicalFileSize) override
HRESULT Init(_In_ IRecycleBin5 *prb, _In_ LPCWSTR Folder, _In_ PDELETED_FILE_RECORD pDeletedFile)
STDMETHODIMP_(ULONG) Release() override
STDMETHODIMP RemoveFromDatabase() override
STDMETHODIMP GetAttributes(DWORD *pAttributes) override
STDMETHODIMP QueryInterface(REFIID riid, void **ppvObject) override
DELETED_FILE_RECORD m_deletedFile
STDMETHODIMP Restore() override
STDMETHODIMP GetInfo(PDELETED_FILE_INFO pInfo) override
STDMETHODIMP Delete() override
STDMETHODIMP GetDeletionTime(FILETIME *pDeletionTime) override
STDMETHODIMP GetFileName(SIZE_T BufferSize, LPWSTR Buffer, SIZE_T *RequiredSize) override
STDMETHODIMP_(ULONG) AddRef() override
STDMETHODIMP GetLastModificationTime(FILETIME *pLastModificationTime) override
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define E_INVALIDARG
Definition: ddrawi.h:101
#define E_FAIL
Definition: ddrawi.h:102
#define NULL
Definition: types.h:112
#define CloseHandle
Definition: compat.h:739
#define UnmapViewOfFile
Definition: compat.h:746
#define OPEN_EXISTING
Definition: compat.h:775
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define GENERIC_READ
Definition: compat.h:135
#define CreateFileW
Definition: compat.h:741
#define FILE_MAP_READ
Definition: compat.h:776
#define MapViewOfFile
Definition: compat.h:745
#define FILE_SHARE_READ
Definition: compat.h:136
DWORD WINAPI GetFileAttributesW(LPCWSTR lpFileName)
Definition: fileinfo.c:652
DWORD WINAPI GetFileSize(HANDLE hFile, LPDWORD lpFileSizeHigh)
Definition: fileinfo.c:331
BOOL WINAPI GetFileTime(IN HANDLE hFile, OUT LPFILETIME lpCreationTime OPTIONAL, OUT LPFILETIME lpLastAccessTime OPTIONAL, OUT LPFILETIME lpLastWriteTime OPTIONAL)
Definition: fileinfo.c:896
void WINAPI SHFree(LPVOID pv)
Definition: shellole.c:326
LPWSTR WINAPI PathFindExtensionW(LPCWSTR lpszPath)
Definition: path.c:447
unsigned long DWORD
Definition: ntddk_ex.h:95
_Must_inspect_result_ _Out_ PLARGE_INTEGER FileSize
Definition: fsrtlfuncs.h:108
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
REFIID riid
Definition: atlbase.h:39
#define S_OK
Definition: intsafe.h:52
#define SUCCEEDED(hr)
Definition: intsafe.h:50
#define FAILED(hr)
Definition: intsafe.h:51
#define C_ASSERT(e)
Definition: intsafe.h:73
#define debugstr_guid
Definition: kernel32.h:35
#define HResultFromWin32
Definition: loader.cpp:14
#define FILE_FLAG_BACKUP_SEMANTICS
Definition: disk.h:41
static ULONG WINAPI AddRef(IStream *iface)
Definition: clist.c:90
_In_ HANDLE hFile
Definition: mswsock.h:90
unsigned int UINT
Definition: ndis.h:50
#define _Out_
Definition: no_sal2.h:160
#define _In_
Definition: no_sal2.h:158
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
#define FILE_SHARE_DELETE
Definition: nt_native.h:682
#define FILE_ATTRIBUTE_DIRECTORY
Definition: nt_native.h:705
#define DWORD
Definition: nt_native.h:44
#define L(x)
Definition: ntvdm.h:50
long LONG
Definition: pedump.c:60
#define IsEqualIID(riid1, riid2)
Definition: guiddef.h:95
#define REFIID
Definition: guiddef.h:118
static void InitializeRecycleBinStringRef(PRECYCLEBINSTRING pRBS, LPCWSTR String)
Definition: recyclebin.h:62
EXTERN_C const IID IID_IRecycleBinFile
Definition: recyclebin.h:239
EXTERN_C const IID IID_IRecycleBinEnumList
Definition: recyclebin.h:240
EXTERN_C BOOL RecycleBinGeneric_IsEqualFileIdentity(const RECYCLEBINFILEIDENTITY *p1, const RECYCLEBINFILEIDENTITY *p2)
struct _INFO2_HEADER * PINFO2_HEADER
struct _DELETED_FILE_RECORD * PDELETED_FILE_RECORD
interface IRecycleBin5 IRecycleBin5
Definition: recyclebin_v5.h:27
struct _DELETED_FILE_RECORD DELETED_FILE_RECORD
static HRESULT RecycleBin5File_Constructor(_In_ IRecycleBin5 *prb, _In_ LPCWSTR Folder, _In_ PDELETED_FILE_RECORD pDeletedFile, _Out_ IRecycleBinFile **ppFile)
EXTERN_C HRESULT RecycleBin5Enum_Constructor(_In_ IRecycleBin5 *prb, _In_ HANDLE hInfo, _In_ HANDLE hInfoMapped, _In_ LPCWSTR szPrefix, _Out_ IUnknown **ppUnknown)
HRESULT hr
Definition: shlfolder.c:183
#define SHStrDup
Definition: shlwapi.h:1572
#define _countof(array)
Definition: sndvol32.h:70
#define TRACE(s)
Definition: solgame.cpp:4
STRSAFEAPI StringCchPrintfW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszFormat,...)
Definition: strsafe.h:530
RECYCLEBINFILESIZETYPE FileSize
Definition: recyclebin.h:42
RECYCLEBINSTRING RecycledFullPath
Definition: recyclebin.h:45
FILETIME DeletionTime
Definition: recyclebin.h:41
RECYCLEBINSTRING OriginalFullPath
Definition: recyclebin.h:44
FILETIME LastModification
Definition: recyclebin.h:40
WCHAR FileNameW[MAX_PATH]
Definition: recyclebin_v5.h:20
struct _ULARGE_INTEGER::@4266 u
$ULONG LowPart
Definition: ntbasedef.h:577
ULONGLONG QuadPart
Definition: ms-dtyp.idl:185
ULONG_PTR SIZE_T
Definition: typedefs.h:80
uint32_t ULONG
Definition: typedefs.h:59
LONGLONG QuadPart
Definition: typedefs.h:114
struct _LARGE_INTEGER::@2379 u
DWORD dwAttributes
Definition: vdmdbg.h:34
#define INVALID_FILE_ATTRIBUTES
Definition: vfdcmd.c:23
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ ULONG _Out_ PVOID _Out_ PULONG RequiredSize
Definition: wdfdevice.h:4439
_In_ WDFMEMORY _Out_opt_ size_t * BufferSize
Definition: wdfmemory.h:254
#define ZeroMemory
Definition: winbase.h:1743
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define CopyMemory
Definition: winbase.h:1741
#define INVALID_FILE_SIZE
Definition: winbase.h:574
_In_ void _In_ PCCERT_CONTEXT _In_opt_ LPFILETIME _In_ DWORD _In_ DWORD _Outptr_opt_ void ** ppvObject
Definition: wincrypt.h:6082
#define S_FALSE
Definition: winerror.h:2357
#define E_NOINTERFACE
Definition: winerror.h:2364
#define HRESULT_FROM_WIN32(x)
Definition: winerror.h:92
#define E_POINTER
Definition: winerror.h:2365
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185