ReactOS 0.4.16-dev-980-g00983aa
recyclebin_v5.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: Deals with recycle bins of Windows 2000/XP/2003
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 "sddl.h"
13
15
17{
19
20public:
23 CZZWStr(const CZZWStr&) = delete;
24 CZZWStr& operator=(const CZZWStr&) = delete;
25
27 {
28 SIZE_T cch = wcslen(Str) + 1;
29 m_sz = (LPWSTR)SHAlloc((cch + 1) * sizeof(*Str));
30 if (!m_sz)
31 return false;
32 CopyMemory(m_sz, Str, cch * sizeof(*Str));
33 m_sz[cch] = UNICODE_NULL; // Double-null terminate
34 return true;
35 }
36 inline LPWSTR c_str() { return m_sz; }
37};
38
40{
41 CZZWStr szzFrom, szzTo;
42 if (!szzFrom.Initialize(pszFrom) || !szzTo.Initialize(pszTo))
43 return ERROR_OUTOFMEMORY; // Note: Not one of the DE errors but also not in the DE range
44 SHFILEOPSTRUCTW fos = { hWnd, Op, szzFrom.c_str(), szzTo.c_str(), Flags };
45 return SHFileOperationW(&fos);
46}
47
48static BOOL
51{
52 DWORD RemovableAttributes = FILE_ATTRIBUTE_READONLY;
53 WIN32_FIND_DATAW FindData;
55 LPWSTR FullPath = NULL, pFilePart;
58 BOOL ret = FALSE;
59
62 {
64 ret = TRUE;
65 goto cleanup;
66 }
67 if (FileAttributes & RemovableAttributes)
68 {
69 if (!SetFileAttributesW(FullName, FileAttributes & ~RemovableAttributes))
70 goto cleanup;
71 }
73 {
74 /* Prepare file specification */
76 FullPath = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, (dwLength + 1 + MAX_PATH + 1) * sizeof(WCHAR));
77 if (!FullPath)
78 {
80 goto cleanup;
81 }
82 wcscpy(FullPath, FullName);
83 if (FullPath[dwLength - 1] != '\\')
84 {
85 FullPath[dwLength] = '\\';
86 dwLength++;
87 }
88 pFilePart = &FullPath[dwLength];
89 wcscpy(pFilePart, L"*");
90
91 /* Enumerate contents, and delete it */
92 hSearch = FindFirstFileW(FullPath, &FindData);
93 if (hSearch == INVALID_HANDLE_VALUE)
94 goto cleanup;
95 do
96 {
97 if (!(FindData.cFileName[0] == '.' &&
98 (FindData.cFileName[1] == '\0' || (FindData.cFileName[1] == '.' && FindData.cFileName[2] == '\0'))))
99 {
100 wcscpy(pFilePart, FindData.cFileName);
101 if (!IntDeleteRecursive(FullPath))
102 {
103 FindClose(hSearch);
104 goto cleanup;
105 }
106 }
107 }
108 while (FindNextFileW(hSearch, &FindData));
109 FindClose(hSearch);
111 goto cleanup;
112
113 /* Remove (now empty) directory */
115 goto cleanup;
116 }
117 else
118 {
119 if (!DeleteFileW(FullName))
120 goto cleanup;
121 }
122 ret = TRUE;
123
124cleanup:
125 HeapFree(GetProcessHeap(), 0, FullPath);
126 return ret;
127}
128
130{
131public:
132 RecycleBin5();
133 virtual ~RecycleBin5();
134
135 HRESULT Init(_In_ LPCWSTR VolumePath);
136
137 /* IUnknown interface */
141
142 /* IRecycleBin interface */
143 STDMETHODIMP DeleteFile(_In_ LPCWSTR szFileName) override;
144 STDMETHODIMP EmptyRecycleBin() override;
145 STDMETHODIMP EnumObjects(_Out_ IRecycleBinEnumList **ppEnumList) override;
147 {
148 if (!m_Folder[0])
149 return E_UNEXPECTED;
151 return S_OK;
152 }
153
154 /* IRecycleBin5 interface */
156 _In_ LPCWSTR pDeletedFileName,
157 _In_ DELETED_FILE_RECORD *pDeletedFile) override;
159 _In_ LPCWSTR pDeletedFileName,
160 _In_ DELETED_FILE_RECORD *pDeletedFile) override;
162 _In_ LPCWSTR pDeletedFileName,
163 _In_ DELETED_FILE_RECORD *pDeletedFile) override;
164 STDMETHODIMP OnClosing(_In_ IRecycleBinEnumList *prbel) override;
165
166protected:
172 CStringW m_Folder; /* [drive]:\[RECYCLE_BIN_DIRECTORY]\{SID} */
173};
174
176{
177 TRACE("(%p, %s, %p)\n", this, debugstr_guid(&riid), ppvObject);
178
179 if (!ppvObject)
180 return E_POINTER;
181
183 *ppvObject = static_cast<IRecycleBin5 *>(this);
185 *ppvObject = static_cast<IRecycleBin5 *>(this);
186 else
187 {
188 *ppvObject = NULL;
189 return E_NOINTERFACE;
190 }
191
192 AddRef();
193 return S_OK;
194}
195
196STDMETHODIMP_(ULONG) RecycleBin5::AddRef()
197{
198 TRACE("(%p)\n", this);
200}
201
203{
204 TRACE("(%p)\n", this);
205
208 if (m_hInfoMapped)
210}
211
212STDMETHODIMP_(ULONG) RecycleBin5::Release()
213{
214 TRACE("(%p)\n", this);
215
216 ULONG refCount = InterlockedDecrement(&m_ref);
217 if (refCount == 0)
218 delete this;
219 return refCount;
220}
221
223{
224 LPWSTR szFullName = NULL;
225 DWORD dwBufferLength = 0;
228 CStringW DeletedFileName;
229 WCHAR szUniqueId[64];
230 DWORD len;
233 PDELETED_FILE_RECORD pDeletedFile;
235 DWORD dwAttributes, dwEntries;
236 SYSTEMTIME SystemTime;
237 DWORD ClusterSize, BytesPerSector, SectorsPerCluster;
238 HRESULT hr;
239 WIN32_FIND_DATAW wfd = {};
240
241 TRACE("(%p, %s)\n", this, debugstr_w(szFileName));
242
243 if (m_EnumeratorCount != 0)
245
246 /* Get full file name */
247 while (TRUE)
248 {
249 len = GetFullPathNameW(szFileName, dwBufferLength, szFullName, &lpFilePart);
250 if (len == 0)
251 {
252 if (szFullName)
253 CoTaskMemFree(szFullName);
255 }
256 else if (len < dwBufferLength)
257 break;
258 if (szFullName)
259 CoTaskMemFree(szFullName);
260 dwBufferLength = len;
261 szFullName = (LPWSTR)CoTaskMemAlloc(dwBufferLength * sizeof(WCHAR));
262 if (!szFullName)
264 }
265
266 /* Check if file exists */
267 dwAttributes = GetFileAttributesW(szFullName);
269 {
270 CoTaskMemFree(szFullName);
272 }
273
274 if (dwBufferLength < 2 || szFullName[1] != ':')
275 {
276 /* Not a local file */
277 CoTaskMemFree(szFullName);
279 }
280
283 {
285 goto cleanup;
286 }
287
288 /* Increase INFO2 file size */
293 if (!m_hInfoMapped)
294 {
296 goto cleanup;
297 }
298
299 /* Open INFO2 file */
301 if (!pHeader)
302 {
304 goto cleanup;
305 }
306
307 /* Get number of entries */
308 FileSize.u.LowPart = GetFileSize(m_hInfo, &FileSize.u.HighPart);
309 if (FileSize.u.LowPart < sizeof(INFO2_HEADER))
310 {
312 goto cleanup;
313 }
314 dwEntries = (DWORD)((FileSize.QuadPart - sizeof(INFO2_HEADER)) / sizeof(DELETED_FILE_RECORD)) - 1;
315 pDeletedFile = ((PDELETED_FILE_RECORD)(pHeader + 1)) + dwEntries;
316
317 /* Get file size */
318#if 0
320 {
322 goto cleanup;
323 }
324#else
325 FileSize.u.LowPart = GetFileSize(hFile, &FileSize.u.HighPart);
326 if (FileSize.u.LowPart == INVALID_FILE_SIZE && GetLastError() != NO_ERROR)
327 {
329 goto cleanup;
330 }
331#endif
332 /* Check if file size is > 4Gb */
333 if (FileSize.u.HighPart != 0)
334 {
335 /* Yes, this recyclebin can't support this file */
337 goto cleanup;
338 }
339 pHeader->dwTotalLogicalSize += FileSize.u.LowPart;
340
341 /* Generate new name */
342 Extension = PathFindExtensionW(szFullName);
343 ZeroMemory(pDeletedFile, sizeof(DELETED_FILE_RECORD));
344 if (dwEntries == 0)
345 pDeletedFile->dwRecordUniqueId = 0;
346 else
347 {
348 PDELETED_FILE_RECORD pLastDeleted = ((PDELETED_FILE_RECORD)(pHeader + 1)) + dwEntries - 1;
349 pDeletedFile->dwRecordUniqueId = pLastDeleted->dwRecordUniqueId + 1;
350 }
351
352 pDeletedFile->dwDriveNumber = tolower(szFullName[0]) - 'a';
353 _ultow(pDeletedFile->dwRecordUniqueId, szUniqueId, 10);
354
355 DeletedFileName = m_Folder;
356 DeletedFileName += L"\\D";
357 DeletedFileName += (WCHAR)(L'a' + pDeletedFile->dwDriveNumber);
358 DeletedFileName += szUniqueId;
359 DeletedFileName += Extension;
360
361 /* Get cluster size */
362 if (!GetDiskFreeSpaceW(m_VolumePath, &SectorsPerCluster, &BytesPerSector, NULL, NULL))
363 {
365 goto cleanup;
366 }
367 ClusterSize = BytesPerSector * SectorsPerCluster;
368
369 /* Get current time */
370 GetSystemTime(&SystemTime);
371 if (!SystemTimeToFileTime(&SystemTime, &pDeletedFile->DeletionTime))
372 {
374 goto cleanup;
375 }
376 pDeletedFile->dwPhysicalFileSize = ROUND_UP(FileSize.u.LowPart, ClusterSize);
377
378 /* Set name */
379 wcscpy(pDeletedFile->FileNameW, szFullName);
380 if (WideCharToMultiByte(CP_ACP, 0, pDeletedFile->FileNameW, -1, pDeletedFile->FileNameA, MAX_PATH, NULL, NULL) == 0)
381 {
384 goto cleanup;
385 }
386
387 wfd.dwFileAttributes = dwAttributes;
388 wfd.nFileSizeLow = FileSize.u.LowPart;
389 GetFileTime(hFile, &wfd.ftCreationTime, &wfd.ftLastAccessTime, &wfd.ftLastWriteTime);
390
391 /* Move file */
392 if (MoveFileW(szFullName, DeletedFileName))
393 hr = S_OK;
394 else
396
397 if (SUCCEEDED(hr))
398 {
399 RECYCLEBINFILEIDENTITY ident = { pDeletedFile->DeletionTime, DeletedFileName };
400 CRecycleBin_NotifyRecycled(szFullName, &wfd, &ident);
401 }
402
403cleanup:
404 if (pHeader)
408 CoTaskMemFree(szFullName);
409 return hr;
410}
411
413{
414 TRACE("(%p)\n", this);
415
416 while (TRUE)
417 {
418 IRecycleBinEnumList *prbel;
419 HRESULT hr = EnumObjects(&prbel);
420 if (!SUCCEEDED(hr))
421 return hr;
422
423 IRecycleBinFile *prbf;
424 hr = prbel->Next(1, &prbf, NULL);
425 prbel->Release();
426 if (hr == S_FALSE)
427 return S_OK;
428 hr = prbf->Delete();
429 prbf->Release();
430 if (!SUCCEEDED(hr))
431 return hr;
432 }
433}
434
435STDMETHODIMP RecycleBin5::EnumObjects(_Out_ IRecycleBinEnumList **ppEnumList)
436{
437 TRACE("(%p, %p)\n", this, ppEnumList);
438
439 IUnknown *pUnk;
441 if (!SUCCEEDED(hr))
442 return hr;
443
444 IRecycleBinEnumList *prbel;
445 hr = pUnk->QueryInterface(IID_IRecycleBinEnumList, (void **)&prbel);
446 if (SUCCEEDED(hr))
447 {
449 *ppEnumList = prbel;
450 }
451
452 pUnk->Release();
453 return hr;
454}
455
457 _In_ LPCWSTR pDeletedFileName,
458 _In_ DELETED_FILE_RECORD *pDeletedFile)
459{
460
461 TRACE("(%p, %s, %p)\n", this, debugstr_w(pDeletedFileName), pDeletedFile);
462
463 int res = IntDeleteRecursive(pDeletedFileName);
464 if (!res)
466 res = RemoveFromDatabase(pDeletedFileName, pDeletedFile);
467 if (res == 0)
468 SHUpdateRecycleBinIcon(); // Full --> Empty
469 return res;
470}
471
473 _In_ LPCWSTR pDeletedFileName,
474 _In_ DELETED_FILE_RECORD *pDeletedFile)
475{
476
477 TRACE("(%p, %s, %p)\n", this, debugstr_w(pDeletedFileName), pDeletedFile);
478
479 int res = SHELL_SingleFileOperation(NULL, FO_MOVE, pDeletedFileName, pDeletedFile->FileNameW, 0);
480 if (res)
481 {
482 ERR("SHFileOperationW failed with 0x%x\n", res);
483 return E_FAIL;
484 }
485 res = RemoveFromDatabase(pDeletedFileName, pDeletedFile);
486 if (res == 0)
487 SHUpdateRecycleBinIcon(); // Full --> Empty
488 return res;
489}
490
492 _In_ LPCWSTR pDeletedFileName,
493 _In_ DELETED_FILE_RECORD *pDeletedFile)
494{
497 DELETED_FILE_RECORD *pRecord, *pLast;
498 DWORD dwEntries, i;
499
500 TRACE("(%p, %s, %p)\n", this, debugstr_w(pDeletedFileName), pDeletedFile);
501
502 if (m_EnumeratorCount != 0)
504
506 if (!pHeader)
508
509 FileSize.u.LowPart = GetFileSize(m_hInfo, &FileSize.u.HighPart);
510 if (FileSize.u.LowPart == 0)
511 {
514 }
515 dwEntries = (DWORD)((FileSize.QuadPart - sizeof(INFO2_HEADER)) / sizeof(DELETED_FILE_RECORD));
516
517 pRecord = (DELETED_FILE_RECORD *)(pHeader + 1);
518 for (i = 0; i < dwEntries; i++)
519 {
520 if (pRecord->dwRecordUniqueId == pDeletedFile->dwRecordUniqueId)
521 {
522 /* Clear last entry in the file */
523 MoveMemory(pRecord, pRecord + 1, (dwEntries - i - 1) * sizeof(DELETED_FILE_RECORD));
524 pLast = pRecord + (dwEntries - i - 1);
525 ZeroMemory(pLast, sizeof(DELETED_FILE_RECORD));
527
528 /* Resize file */
533 if (!m_hInfoMapped)
535 dwEntries--;
536 return FAILED((int)dwEntries) ? INT_MAX : dwEntries;
537 }
538 pRecord++;
539 }
540
543}
544
545STDMETHODIMP RecycleBin5::OnClosing(_In_ IRecycleBinEnumList *prbel)
546{
547 TRACE("(%p, %p)\n", this, prbel);
549 return S_OK;
550}
551
552static HRESULT
554 _In_ LPCWSTR Folder,
555 _In_ PSID OwnerSid OPTIONAL)
556{
557 LPWSTR BufferName = NULL;
558 LPWSTR Separator; /* Pointer into BufferName buffer */
559 LPWSTR FileName; /* Pointer into BufferName buffer */
560 LPCSTR DesktopIniContents = "[.ShellClassInfo]\r\nCLSID={645FF040-5081-101B-9F08-00AA002F954E}\r\n";
561 INFO2_HEADER Info2Contents[] = { { 5, 0, 0, 0x320, 0 } };
562 DWORD BytesToWrite, BytesWritten;
563 SIZE_T Needed;
565 HRESULT hr;
566
567 Needed = (wcslen(Folder) + 1 + max(wcslen(RECYCLE_BIN_FILE_NAME), wcslen(L"desktop.ini")) + 1) * sizeof(WCHAR);
568 BufferName = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, Needed);
569 if (!BufferName)
570 {
572 goto cleanup;
573 }
574
575 wcscpy(BufferName, Folder);
576 Separator = wcsstr(&BufferName[3], L"\\");
577 if (Separator)
578 *Separator = UNICODE_NULL;
579 if (!CreateDirectoryW(BufferName, NULL) && GetLastError() != ERROR_ALREADY_EXISTS)
580 {
582 goto cleanup;
583 }
585 if (Separator)
586 {
587 *Separator = L'\\';
588 if (!CreateDirectoryW(BufferName, NULL) && GetLastError() != ERROR_ALREADY_EXISTS)
589 {
591 goto cleanup;
592 }
593 }
594
595 if (OwnerSid)
596 {
597 //DWORD rc;
598
599 /* Add ACL to allow only user/SYSTEM to open it */
600 /* FIXME: rc = SetNamedSecurityInfo(
601 BufferName,
602 SE_FILE_OBJECT,
603 ???,
604 OwnerSid,
605 NULL,
606 ???,
607 ???);
608 if (rc != ERROR_SUCCESS)
609 {
610 hr = HRESULT_FROM_WIN32(rc);
611 goto cleanup;
612 }
613 */
614 }
615
616 wcscat(BufferName, L"\\");
617 FileName = &BufferName[wcslen(BufferName)];
618
619 /* Create desktop.ini */
620 wcscpy(FileName, L"desktop.ini");
623 {
625 goto cleanup;
626 }
627 BytesToWrite = (UINT)strlen(DesktopIniContents);
628 if (!WriteFile(hFile, DesktopIniContents, (DWORD)BytesToWrite, &BytesWritten, NULL))
629 {
631 goto cleanup;
632 }
633 if (BytesWritten != BytesToWrite)
634 {
635 hr = E_FAIL;
636 goto cleanup;
637 }
640
641 /* Create empty INFO2 file */
645 {
647 goto cleanup;
648 }
649 BytesToWrite = sizeof(Info2Contents);
650 if (!WriteFile(hFile, Info2Contents, (DWORD)BytesToWrite, &BytesWritten, NULL))
651 {
653 goto cleanup;
654 }
655 if (BytesWritten == BytesToWrite)
656 hr = S_OK;
657 else
658 hr = E_FAIL;
659
660cleanup:
661 HeapFree(GetProcessHeap(), 0, BufferName);
664 return hr;
665}
666
668 : m_ref(1)
669 , m_hInfo(NULL)
670 , m_hInfoMapped(NULL)
671 , m_EnumeratorCount(0)
672{
673}
674
676{
677 DWORD FileSystemFlags;
678 LPCWSTR RecycleBinDirectory;
679 HANDLE tokenHandle = INVALID_HANDLE_VALUE;
680 PTOKEN_USER TokenUserInfo = NULL;
681 LPWSTR StringSid = NULL;
682 DWORD Needed;
683 INT len;
684 HRESULT hr;
685
686 m_VolumePath = VolumePath;
687
688 /* Get information about file system */
689 if (!GetVolumeInformationW(VolumePath, NULL, 0, NULL, NULL, &FileSystemFlags, NULL, 0))
690 {
692 goto cleanup;
693 }
694
695 if (!(FileSystemFlags & FILE_PERSISTENT_ACLS))
696 {
697 RecycleBinDirectory = RECYCLE_BIN_DIRECTORY_WITHOUT_ACL;
698 }
699 else
700 {
701 RecycleBinDirectory = RECYCLE_BIN_DIRECTORY_WITH_ACL;
702
703 /* Get user SID */
704 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &tokenHandle))
705 {
707 goto cleanup;
708 }
709 if (GetTokenInformation(tokenHandle, TokenUser, NULL, 0, &Needed))
710 {
711 hr = E_FAIL;
712 goto cleanup;
713 }
715 {
717 goto cleanup;
718 }
719 TokenUserInfo = (PTOKEN_USER)HeapAlloc(GetProcessHeap(), 0, Needed);
720 if (!TokenUserInfo)
721 {
723 goto cleanup;
724 }
725 if (!GetTokenInformation(tokenHandle, TokenUser, TokenUserInfo, (DWORD)Needed, &Needed))
726 {
728 goto cleanup;
729 }
730 if (!ConvertSidToStringSidW(TokenUserInfo->User.Sid, &StringSid))
731 {
733 goto cleanup;
734 }
735 }
736
737 m_Folder = VolumePath;
738 m_Folder += RecycleBinDirectory;
739 if (StringSid)
740 {
741 m_Folder += L'\\';
742 m_Folder += StringSid;
743 }
746
750 {
752 hr = RecycleBin5_Create(m_Folder, TokenUserInfo ? TokenUserInfo->User.Sid : NULL);
754 if (!SUCCEEDED(hr))
755 goto cleanup;
757 }
758
760 {
762 goto cleanup;
763 }
764
766 if (!m_hInfoMapped)
767 {
769 goto cleanup;
770 }
771
773 hr = S_OK;
774
775cleanup:
776 if (tokenHandle != INVALID_HANDLE_VALUE)
777 CloseHandle(tokenHandle);
778 HeapFree(GetProcessHeap(), 0, TokenUserInfo);
779 if (StringSid)
780 LocalFree(StringSid);
781 return hr;
782}
783
786{
787 if (!ppUnknown)
788 return E_POINTER;
789
790 *ppUnknown = NULL;
791
792 RecycleBin5 *pThis = new RecycleBin5();
793 if (!pThis)
794 return E_OUTOFMEMORY;
795
796 HRESULT hr = pThis->Init(VolumePath);
797 if (FAILED(hr))
798 {
799 delete pThis;
800 return hr;
801 }
802
803 *ppUnknown = static_cast<IRecycleBin5 *>(pThis);
804 return S_OK;
805}
EXTERN_C void CRecycleBin_NotifyRecycled(LPCWSTR OrigPath, const WIN32_FIND_DATAW *pFind, const RECYCLEBINFILEIDENTITY *pFI)
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
int tolower(int c)
Definition: utclib.c:902
#define InterlockedIncrement
Definition: armddk.h:53
#define InterlockedDecrement
Definition: armddk.h:52
HWND hWnd
Definition: settings.c:17
#define ERR(fmt,...)
Definition: precomp.h:57
DWORD ClusterSize
Definition: format.c:67
#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
int GetLength() const noexcept
Definition: atlsimpstr.h:362
CStringT Left(int nCount) const
Definition: cstringt.h:776
bool Initialize(LPCWSTR Str)
LPWSTR m_sz
CZZWStr & operator=(const CZZWStr &)=delete
LPWSTR c_str()
CZZWStr(const CZZWStr &)=delete
STDMETHODIMP RemoveFromDatabase(_In_ LPCWSTR pDeletedFileName, _In_ DELETED_FILE_RECORD *pDeletedFile) override
STDMETHODIMP Restore(_In_ LPCWSTR pDeletedFileName, _In_ DELETED_FILE_RECORD *pDeletedFile) override
STDMETHODIMP Delete(_In_ LPCWSTR pDeletedFileName, _In_ DELETED_FILE_RECORD *pDeletedFile) override
STDMETHODIMP_(ULONG) Release() override
STDMETHODIMP EmptyRecycleBin() override
STDMETHODIMP OnClosing(_In_ IRecycleBinEnumList *prbel) override
HANDLE m_hInfoMapped
STDMETHODIMP GetDirectory(LPWSTR szPath) override
STDMETHODIMP QueryInterface(_In_ REFIID riid, _Out_ void **ppvObject) override
STDMETHODIMP DeleteFile(_In_ LPCWSTR szFileName) override
CStringW m_Folder
virtual ~RecycleBin5()
STDMETHODIMP_(ULONG) AddRef() override
DWORD m_EnumeratorCount
HRESULT Init(_In_ LPCWSTR VolumePath)
CStringW m_VolumePath
STDMETHODIMP EnumObjects(_Out_ IRecycleBinEnumList **ppEnumList) override
wcscat
wcscpy
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
#define NO_ERROR
Definition: dderror.h:5
#define ERROR_INSUFFICIENT_BUFFER
Definition: dderror.h:10
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define E_FAIL
Definition: ddrawi.h:102
#define ERROR_OUTOFMEMORY
Definition: deptool.c:13
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
BOOL WINAPI GetTokenInformation(HANDLE TokenHandle, TOKEN_INFORMATION_CLASS TokenInformationClass, LPVOID TokenInformation, DWORD TokenInformationLength, PDWORD ReturnLength)
Definition: security.c:411
BOOL WINAPI OpenProcessToken(HANDLE ProcessHandle, DWORD DesiredAccess, PHANDLE TokenHandle)
Definition: security.c:294
BOOL WINAPI ConvertSidToStringSidW(PSID Sid, LPWSTR *StringSid)
Definition: security.c:3583
#define CloseHandle
Definition: compat.h:739
#define GetProcessHeap()
Definition: compat.h:736
#define UnmapViewOfFile
Definition: compat.h:746
#define CP_ACP
Definition: compat.h:109
#define OPEN_EXISTING
Definition: compat.h:775
#define SetFilePointer
Definition: compat.h:743
#define SetLastError(x)
Definition: compat.h:752
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define HeapAlloc
Definition: compat.h:733
#define CreateFileMappingW(a, b, c, d, e, f)
Definition: compat.h:744
#define GetCurrentProcess()
Definition: compat.h:759
#define GENERIC_READ
Definition: compat.h:135
#define ERROR_NOT_SUPPORTED
Definition: compat.h:100
#define MAX_PATH
Definition: compat.h:34
#define HeapFree(x, y, z)
Definition: compat.h:735
#define CreateFileW
Definition: compat.h:741
#define GetFileSizeEx
Definition: compat.h:757
#define WideCharToMultiByte
Definition: compat.h:111
#define MapViewOfFile
Definition: compat.h:745
#define ERROR_INVALID_NAME
Definition: compat.h:103
#define lstrcpynW
Definition: compat.h:738
static DWORD DWORD * dwLength
Definition: fusion.c:86
static void cleanup(void)
Definition: main.c:1335
BOOL WINAPI DeleteFileW(IN LPCWSTR lpFileName)
Definition: delete.c:39
BOOL WINAPI CreateDirectoryW(IN LPCWSTR lpPathName, IN LPSECURITY_ATTRIBUTES lpSecurityAttributes)
Definition: dir.c:90
BOOL WINAPI RemoveDirectoryW(IN LPCWSTR lpPathName)
Definition: dir.c:732
BOOL WINAPI GetDiskFreeSpaceW(IN LPCWSTR lpRootPathName, OUT LPDWORD lpSectorsPerCluster, OUT LPDWORD lpBytesPerSector, OUT LPDWORD lpNumberOfFreeClusters, OUT LPDWORD lpTotalNumberOfClusters)
Definition: disk.c:173
DWORD WINAPI GetFileAttributesW(LPCWSTR lpFileName)
Definition: fileinfo.c:652
BOOL WINAPI SetFileAttributesW(LPCWSTR lpFileName, DWORD dwFileAttributes)
Definition: fileinfo.c:794
BOOL WINAPI SetEndOfFile(HANDLE hFile)
Definition: fileinfo.c:1004
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
HANDLE WINAPI FindFirstFileW(IN LPCWSTR lpFileName, OUT LPWIN32_FIND_DATAW lpFindFileData)
Definition: find.c:320
BOOL WINAPI FindClose(HANDLE hFindFile)
Definition: find.c:502
BOOL WINAPI FindNextFileW(IN HANDLE hFindFile, OUT LPWIN32_FIND_DATAW lpFindFileData)
Definition: find.c:382
BOOL WINAPI MoveFileW(IN LPCWSTR lpExistingFileName, IN LPCWSTR lpNewFileName)
Definition: move.c:1104
BOOL WINAPI WriteFile(IN HANDLE hFile, IN LPCVOID lpBuffer, IN DWORD nNumberOfBytesToWrite OPTIONAL, OUT LPDWORD lpNumberOfBytesWritten, IN LPOVERLAPPED lpOverlapped OPTIONAL)
Definition: rw.c:24
BOOL WINAPI GetVolumeInformationW(IN LPCWSTR lpRootPathName, IN LPWSTR lpVolumeNameBuffer, IN DWORD nVolumeNameSize, OUT LPDWORD lpVolumeSerialNumber OPTIONAL, OUT LPDWORD lpMaximumComponentLength OPTIONAL, OUT LPDWORD lpFileSystemFlags OPTIONAL, OUT LPWSTR lpFileSystemNameBuffer OPTIONAL, IN DWORD nFileSystemNameSize)
Definition: volume.c:226
DWORD WINAPI GetFullPathNameW(IN LPCWSTR lpFileName, IN DWORD nBufferLength, OUT LPWSTR lpBuffer, OUT LPWSTR *lpFilePart)
Definition: path.c:1106
BOOL WINAPI SystemTimeToFileTime(IN CONST SYSTEMTIME *lpSystemTime, OUT LPFILETIME lpFileTime)
Definition: time.c:158
VOID WINAPI GetSystemTime(OUT LPSYSTEMTIME lpSystemTime)
Definition: time.c:327
void WINAPI SHFree(LPVOID pv)
Definition: shellole.c:326
LPVOID WINAPI SHAlloc(SIZE_T len)
Definition: shellole.c:304
LPWSTR WINAPI PathFindExtensionW(LPCWSTR lpszPath)
Definition: path.c:447
static void *static void *static LPDIRECTPLAY IUnknown * pUnk
Definition: dplayx.c:30
#define ROUND_UP(n, align)
Definition: eventvwr.h:34
struct _FileName FileName
Definition: fatprocs.h:897
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
_Must_inspect_result_ _In_opt_ PFLT_INSTANCE _Out_ PHANDLE _In_ ACCESS_MASK _In_ POBJECT_ATTRIBUTES _Out_ PIO_STATUS_BLOCK _In_opt_ PLARGE_INTEGER _In_ ULONG FileAttributes
Definition: fltkernel.h:1236
_Inout_opt_ PUNICODE_STRING Extension
Definition: fltkernel.h:1092
#define FILE_PERSISTENT_ACLS
Definition: from_kernel.h:236
_Must_inspect_result_ _Out_ PLARGE_INTEGER FileSize
Definition: fsrtlfuncs.h:108
GLuint res
Definition: glext.h:9613
GLenum GLsizei len
Definition: glext.h:6722
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
FxContextHeader * pHeader
Definition: handleapi.cpp:604
HLOCAL NTAPI LocalFree(HLOCAL hMem)
Definition: heapmem.c:1594
VOID WINAPI CoTaskMemFree(LPVOID ptr)
Definition: ifs.c:442
LPVOID WINAPI CoTaskMemAlloc(SIZE_T size)
Definition: ifs.c:426
_CRTIMP wchar_t *__cdecl _ultow(_In_ unsigned long _Value, _Pre_notnull_ _Post_z_ wchar_t *_Dest, _In_ int _Radix)
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
_CONST_RETURN wchar_t *__cdecl wcsstr(_In_z_ const wchar_t *_Str, _In_z_ const wchar_t *_SubStr)
REFIID riid
Definition: atlbase.h:39
ULONG Release()
nsresult QueryInterface(nsIIDRef riid, void **result)
nsrefcnt Release()
#define S_OK
Definition: intsafe.h:52
#define SUCCEEDED(hr)
Definition: intsafe.h:50
#define INT_MAX
Definition: intsafe.h:150
#define FAILED(hr)
Definition: intsafe.h:51
#define debugstr_guid
Definition: kernel32.h:35
#define debugstr_w
Definition: kernel32.h:32
#define HResultFromWin32
Definition: loader.cpp:14
#define CREATE_ALWAYS
Definition: disk.h:72
#define ERROR_ALREADY_EXISTS
Definition: disk.h:80
#define FILE_FLAG_BACKUP_SEMANTICS
Definition: disk.h:41
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
LPCWSTR szPath
Definition: env.c:37
static DWORD DWORD void LPSTR DWORD cch
Definition: str.c:202
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 SEC_COMMIT
Definition: mmtypes.h:100
#define _Out_
Definition: no_sal2.h:160
#define _In_
Definition: no_sal2.h:158
#define FILE_ATTRIBUTE_READONLY
Definition: nt_native.h:702
#define PAGE_READWRITE
Definition: nt_native.h:1304
#define FILE_ATTRIBUTE_HIDDEN
Definition: nt_native.h:703
#define FILE_ATTRIBUTE_SYSTEM
Definition: nt_native.h:704
#define FILE_ATTRIBUTE_DIRECTORY
Definition: nt_native.h:705
#define DWORD
Definition: nt_native.h:44
#define GENERIC_WRITE
Definition: nt_native.h:90
#define UNICODE_NULL
#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
EXTERN_C const IID IID_IRecycleBin
Definition: recyclebin.h:241
EXTERN_C const IID IID_IRecycleBinEnumList
Definition: recyclebin.h:240
#define RECYCLE_BIN_DIRECTORY_WITH_ACL
#define RECYCLE_BIN_FILE_NAME
struct _INFO2_HEADER * PINFO2_HEADER
#define RECYCLE_BIN_DIRECTORY_WITHOUT_ACL
EXTERN_C HRESULT WINAPI SHUpdateRecycleBinIcon(void)
static int SHELL_SingleFileOperation(HWND hWnd, UINT Op, LPCWSTR pszFrom, LPCWSTR pszTo, FILEOP_FLAGS Flags)
static HRESULT RecycleBin5_Create(_In_ LPCWSTR Folder, _In_ PSID OwnerSid OPTIONAL)
EXTERN_C HRESULT RecycleBin5_Constructor(_In_ LPCWSTR VolumePath, _Out_ IUnknown **ppUnknown)
static BOOL IntDeleteRecursive(IN LPCWSTR FullName)
EXTERN_C const IID IID_IRecycleBin5
Definition: recyclebin_v5.h:28
struct _DELETED_FILE_RECORD * PDELETED_FILE_RECORD
EXTERN_C HRESULT RecycleBin5Enum_Constructor(_In_ IRecycleBin5 *prb, _In_ HANDLE hInfo, _In_ HANDLE hInfoMapped, _In_ LPCWSTR szPrefix, _Out_ IUnknown **ppUnknown)
interface IRecycleBin5 IRecycleBin5
Definition: recyclebin_v5.h:27
struct _DELETED_FILE_RECORD DELETED_FILE_RECORD
WORD FILEOP_FLAGS
Definition: shellapi.h:214
#define FO_MOVE
Definition: shellapi.h:137
int WINAPI SHFileOperationW(LPSHFILEOPSTRUCTW lpFileOp)
Definition: shlfileop.cpp:2200
HRESULT hr
Definition: shlfolder.c:183
#define TRACE(s)
Definition: solgame.cpp:4
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68
CHAR FileNameA[MAX_PATH]
Definition: recyclebin_v5.h:15
WCHAR FileNameW[MAX_PATH]
Definition: recyclebin_v5.h:20
SID_AND_ATTRIBUTES User
Definition: setypes.h:1010
#define max(a, b)
Definition: svc.c:63
ULONG_PTR SIZE_T
Definition: typedefs.h:80
int32_t INT
Definition: typedefs.h:58
#define IN
Definition: typedefs.h:39
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
int ret
_Must_inspect_result_ _In_ WDFIOTARGET _In_opt_ WDFREQUEST _In_opt_ PWDF_MEMORY_DESCRIPTOR _In_opt_ PLONGLONG _In_opt_ PWDF_REQUEST_SEND_OPTIONS _Out_opt_ PULONG_PTR BytesWritten
Definition: wdfiotarget.h:960
#define ZeroMemory
Definition: winbase.h:1743
#define FILE_END
Definition: winbase.h:115
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define FILE_MAP_WRITE
Definition: winbase.h:155
#define CopyMemory
Definition: winbase.h:1741
#define INVALID_FILE_SIZE
Definition: winbase.h:574
#define MoveMemory
Definition: winbase.h:1740
#define DeleteFile
Definition: winbase.h:3795
_In_ LPCSTR _In_opt_ LPCSTR _In_ DWORD _Out_opt_ LPSTR * lpFilePart
Definition: winbase.h:3106
_In_ void _In_ PCCERT_CONTEXT _In_opt_ LPFILETIME _In_ DWORD _In_ DWORD _Outptr_opt_ void ** ppvObject
Definition: wincrypt.h:6082
_In_ ULONG _In_ ULONG_PTR ident
Definition: winddi.h:3994
#define WINAPI
Definition: msvc.h:6
#define S_FALSE
Definition: winerror.h:2357
#define ERROR_SHARING_VIOLATION
Definition: winerror.h:135
#define E_NOINTERFACE
Definition: winerror.h:2364
#define ERROR_PATH_NOT_FOUND
Definition: winerror.h:106
#define E_UNEXPECTED
Definition: winerror.h:2456
#define ERROR_NO_MORE_FILES
Definition: winerror.h:121
#define HRESULT_FROM_WIN32(x)
Definition: winerror.h:92
#define E_POINTER
Definition: winerror.h:2365
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
_In_ PSTRING FullName
Definition: rtlfuncs.h:1665
struct _TOKEN_USER * PTOKEN_USER
#define TOKEN_QUERY
Definition: setypes.h:928
@ TokenUser
Definition: setypes.h:966
const char * LPCSTR
Definition: xmlstorage.h:183
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185