ReactOS 0.4.16-dev-340-g0540c21
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;
146
147 /* IRecycleBin5 interface */
149 _In_ LPCWSTR pDeletedFileName,
150 _In_ DELETED_FILE_RECORD *pDeletedFile) override;
152 _In_ LPCWSTR pDeletedFileName,
153 _In_ DELETED_FILE_RECORD *pDeletedFile) override;
154 STDMETHODIMP OnClosing(_In_ IRecycleBinEnumList *prbel) override;
155
156protected:
162 CStringW m_Folder; /* [drive]:\[RECYCLE_BIN_DIRECTORY]\{SID} */
163};
164
166{
167 TRACE("(%p, %s, %p)\n", this, debugstr_guid(&riid), ppvObject);
168
169 if (!ppvObject)
170 return E_POINTER;
171
173 *ppvObject = static_cast<IRecycleBin5 *>(this);
175 *ppvObject = static_cast<IRecycleBin5 *>(this);
176 else
177 {
178 *ppvObject = NULL;
179 return E_NOINTERFACE;
180 }
181
182 AddRef();
183 return S_OK;
184}
185
186STDMETHODIMP_(ULONG) RecycleBin5::AddRef()
187{
188 TRACE("(%p)\n", this);
190}
191
193{
194 TRACE("(%p)\n", this);
195
198 if (m_hInfoMapped)
200}
201
202STDMETHODIMP_(ULONG) RecycleBin5::Release()
203{
204 TRACE("(%p)\n", this);
205
206 ULONG refCount = InterlockedDecrement(&m_ref);
207 if (refCount == 0)
208 delete this;
209 return refCount;
210}
211
213{
214 LPWSTR szFullName = NULL;
215 DWORD dwBufferLength = 0;
218 CStringW DeletedFileName;
219 WCHAR szUniqueId[64];
220 DWORD len;
223 PDELETED_FILE_RECORD pDeletedFile;
225 DWORD dwAttributes, dwEntries;
226 SYSTEMTIME SystemTime;
227 DWORD ClusterSize, BytesPerSector, SectorsPerCluster;
228 HRESULT hr;
229
230 TRACE("(%p, %s)\n", this, debugstr_w(szFileName));
231
232 if (m_EnumeratorCount != 0)
234
235 /* Get full file name */
236 while (TRUE)
237 {
238 len = GetFullPathNameW(szFileName, dwBufferLength, szFullName, &lpFilePart);
239 if (len == 0)
240 {
241 if (szFullName)
242 CoTaskMemFree(szFullName);
244 }
245 else if (len < dwBufferLength)
246 break;
247 if (szFullName)
248 CoTaskMemFree(szFullName);
249 dwBufferLength = len;
250 szFullName = (LPWSTR)CoTaskMemAlloc(dwBufferLength * sizeof(WCHAR));
251 if (!szFullName)
253 }
254
255 /* Check if file exists */
256 dwAttributes = GetFileAttributesW(szFullName);
258 {
259 CoTaskMemFree(szFullName);
261 }
262
263 if (dwBufferLength < 2 || szFullName[1] != ':')
264 {
265 /* Not a local file */
266 CoTaskMemFree(szFullName);
268 }
269
272 {
274 goto cleanup;
275 }
276
277 /* Increase INFO2 file size */
282 if (!m_hInfoMapped)
283 {
285 goto cleanup;
286 }
287
288 /* Open INFO2 file */
290 if (!pHeader)
291 {
293 goto cleanup;
294 }
295
296 /* Get number of entries */
297 FileSize.u.LowPart = GetFileSize(m_hInfo, &FileSize.u.HighPart);
298 if (FileSize.u.LowPart < sizeof(INFO2_HEADER))
299 {
301 goto cleanup;
302 }
303 dwEntries = (DWORD)((FileSize.QuadPart - sizeof(INFO2_HEADER)) / sizeof(DELETED_FILE_RECORD)) - 1;
304 pDeletedFile = ((PDELETED_FILE_RECORD)(pHeader + 1)) + dwEntries;
305
306 /* Get file size */
307#if 0
309 {
311 goto cleanup;
312 }
313#else
314 FileSize.u.LowPart = GetFileSize(hFile, &FileSize.u.HighPart);
315 if (FileSize.u.LowPart == INVALID_FILE_SIZE && GetLastError() != NO_ERROR)
316 {
318 goto cleanup;
319 }
320#endif
321 /* Check if file size is > 4Gb */
322 if (FileSize.u.HighPart != 0)
323 {
324 /* Yes, this recyclebin can't support this file */
326 goto cleanup;
327 }
328 pHeader->dwTotalLogicalSize += FileSize.u.LowPart;
329
330 /* Generate new name */
331 Extension = PathFindExtensionW(szFullName);
332 ZeroMemory(pDeletedFile, sizeof(DELETED_FILE_RECORD));
333 if (dwEntries == 0)
334 pDeletedFile->dwRecordUniqueId = 0;
335 else
336 {
337 PDELETED_FILE_RECORD pLastDeleted = ((PDELETED_FILE_RECORD)(pHeader + 1)) + dwEntries - 1;
338 pDeletedFile->dwRecordUniqueId = pLastDeleted->dwRecordUniqueId + 1;
339 }
340
341 pDeletedFile->dwDriveNumber = tolower(szFullName[0]) - 'a';
342 _ultow(pDeletedFile->dwRecordUniqueId, szUniqueId, 10);
343
344 DeletedFileName = m_Folder;
345 DeletedFileName += L"\\D";
346 DeletedFileName += (WCHAR)(L'a' + pDeletedFile->dwDriveNumber);
347 DeletedFileName += szUniqueId;
348 DeletedFileName += Extension;
349
350 /* Get cluster size */
351 if (!GetDiskFreeSpaceW(m_VolumePath, &SectorsPerCluster, &BytesPerSector, NULL, NULL))
352 {
354 goto cleanup;
355 }
356 ClusterSize = BytesPerSector * SectorsPerCluster;
357
358 /* Get current time */
359 GetSystemTime(&SystemTime);
360 if (!SystemTimeToFileTime(&SystemTime, &pDeletedFile->DeletionTime))
361 {
363 goto cleanup;
364 }
365 pDeletedFile->dwPhysicalFileSize = ROUND_UP(FileSize.u.LowPart, ClusterSize);
366
367 /* Set name */
368 wcscpy(pDeletedFile->FileNameW, szFullName);
369 if (WideCharToMultiByte(CP_ACP, 0, pDeletedFile->FileNameW, -1, pDeletedFile->FileNameA, MAX_PATH, NULL, NULL) == 0)
370 {
373 goto cleanup;
374 }
375
376 /* Move file */
377 if (MoveFileW(szFullName, DeletedFileName))
378 hr = S_OK;
379 else
381
382cleanup:
383 if (pHeader)
387 CoTaskMemFree(szFullName);
388 return hr;
389}
390
392{
393 TRACE("(%p)\n", this);
394
395 while (TRUE)
396 {
397 IRecycleBinEnumList *prbel;
398 HRESULT hr = EnumObjects(&prbel);
399 if (!SUCCEEDED(hr))
400 return hr;
401
402 IRecycleBinFile *prbf;
403 hr = prbel->Next(1, &prbf, NULL);
404 prbel->Release();
405 if (hr == S_FALSE)
406 return S_OK;
407 hr = prbf->Delete();
408 prbf->Release();
409 if (!SUCCEEDED(hr))
410 return hr;
411 }
412}
413
414STDMETHODIMP RecycleBin5::EnumObjects(_Out_ IRecycleBinEnumList **ppEnumList)
415{
416 TRACE("(%p, %p)\n", this, ppEnumList);
417
418 IUnknown *pUnk;
420 if (!SUCCEEDED(hr))
421 return hr;
422
423 IRecycleBinEnumList *prbel;
424 hr = pUnk->QueryInterface(IID_IRecycleBinEnumList, (void **)&prbel);
425 if (SUCCEEDED(hr))
426 {
428 *ppEnumList = prbel;
429 }
430
431 pUnk->Release();
432 return hr;
433}
434
436 _In_ LPCWSTR pDeletedFileName,
437 _In_ DELETED_FILE_RECORD *pDeletedFile)
438{
441 DELETED_FILE_RECORD *pRecord, *pLast;
442 DWORD dwEntries, i;
443
444 TRACE("(%p, %s, %p)\n", this, debugstr_w(pDeletedFileName), pDeletedFile);
445
446 if (m_EnumeratorCount != 0)
448
450 if (!pHeader)
452
453 FileSize.u.LowPart = GetFileSize(m_hInfo, &FileSize.u.HighPart);
454 if (FileSize.u.LowPart == 0)
455 {
458 }
459 dwEntries = (DWORD)((FileSize.QuadPart - sizeof(INFO2_HEADER)) / sizeof(DELETED_FILE_RECORD));
460
461 pRecord = (DELETED_FILE_RECORD *)(pHeader + 1);
462 for (i = 0; i < dwEntries; i++)
463 {
464 if (pRecord->dwRecordUniqueId == pDeletedFile->dwRecordUniqueId)
465 {
466 /* Delete file */
467 if (!IntDeleteRecursive(pDeletedFileName))
468 {
471 }
472
473 /* Clear last entry in the file */
474 MoveMemory(pRecord, pRecord + 1, (dwEntries - i - 1) * sizeof(DELETED_FILE_RECORD));
475 pLast = pRecord + (dwEntries - i - 1);
476 ZeroMemory(pLast, sizeof(DELETED_FILE_RECORD));
478
479 /* Resize file */
484 if (!m_hInfoMapped)
486 return S_OK;
487 }
488 pRecord++;
489 }
492}
493
495 _In_ LPCWSTR pDeletedFileName,
496 _In_ DELETED_FILE_RECORD *pDeletedFile)
497{
500 DELETED_FILE_RECORD *pRecord, *pLast;
501 DWORD dwEntries, i;
502 int res;
503
504 TRACE("(%p, %s, %p)\n", this, debugstr_w(pDeletedFileName), pDeletedFile);
505
506 if (m_EnumeratorCount != 0)
508
510 if (!pHeader)
512
513 FileSize.u.LowPart = GetFileSize(m_hInfo, &FileSize.u.HighPart);
514 if (FileSize.u.LowPart == 0)
515 {
518 }
519 dwEntries = (DWORD)((FileSize.QuadPart - sizeof(INFO2_HEADER)) / sizeof(DELETED_FILE_RECORD));
520
521 pRecord = (DELETED_FILE_RECORD *)(pHeader + 1);
522 for (i = 0; i < dwEntries; i++)
523 {
524 if (pRecord->dwRecordUniqueId == pDeletedFile->dwRecordUniqueId)
525 {
526 res = SHELL_SingleFileOperation(NULL, FO_MOVE, pDeletedFileName, pDeletedFile->FileNameW, 0);
527 if (res)
528 {
529 ERR("SHFileOperationW failed with 0x%x\n", res);
531 return E_FAIL;
532 }
533
534 /* Clear last entry in the file */
535 MoveMemory(pRecord, pRecord + 1, (dwEntries - i - 1) * sizeof(DELETED_FILE_RECORD));
536 pLast = pRecord + (dwEntries - i - 1);
537 ZeroMemory(pLast, sizeof(DELETED_FILE_RECORD));
539
540 /* Resize file */
545 if (!m_hInfoMapped)
547 if (dwEntries == 1)
548 SHUpdateRecycleBinIcon(); // Full --> Empty
549 return S_OK;
550 }
551 pRecord++;
552 }
553
556}
557
558STDMETHODIMP RecycleBin5::OnClosing(_In_ IRecycleBinEnumList *prbel)
559{
560 TRACE("(%p, %p)\n", this, prbel);
562 return S_OK;
563}
564
565static HRESULT
567 _In_ LPCWSTR Folder,
568 _In_ PSID OwnerSid OPTIONAL)
569{
570 LPWSTR BufferName = NULL;
571 LPWSTR Separator; /* Pointer into BufferName buffer */
572 LPWSTR FileName; /* Pointer into BufferName buffer */
573 LPCSTR DesktopIniContents = "[.ShellClassInfo]\r\nCLSID={645FF040-5081-101B-9F08-00AA002F954E}\r\n";
574 INFO2_HEADER Info2Contents[] = { { 5, 0, 0, 0x320, 0 } };
575 DWORD BytesToWrite, BytesWritten, Needed;
577 HRESULT hr;
578
579 Needed = (wcslen(Folder) + 1 + max(wcslen(RECYCLE_BIN_FILE_NAME), wcslen(L"desktop.ini")) + 1) * sizeof(WCHAR);
580 BufferName = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, Needed);
581 if (!BufferName)
582 {
584 goto cleanup;
585 }
586
587 wcscpy(BufferName, Folder);
588 Separator = wcsstr(&BufferName[3], L"\\");
589 if (Separator)
590 *Separator = UNICODE_NULL;
591 if (!CreateDirectoryW(BufferName, NULL) && GetLastError() != ERROR_ALREADY_EXISTS)
592 {
594 goto cleanup;
595 }
597 if (Separator)
598 {
599 *Separator = L'\\';
600 if (!CreateDirectoryW(BufferName, NULL) && GetLastError() != ERROR_ALREADY_EXISTS)
601 {
603 goto cleanup;
604 }
605 }
606
607 if (OwnerSid)
608 {
609 //DWORD rc;
610
611 /* Add ACL to allow only user/SYSTEM to open it */
612 /* FIXME: rc = SetNamedSecurityInfo(
613 BufferName,
614 SE_FILE_OBJECT,
615 ???,
616 OwnerSid,
617 NULL,
618 ???,
619 ???);
620 if (rc != ERROR_SUCCESS)
621 {
622 hr = HRESULT_FROM_WIN32(rc);
623 goto cleanup;
624 }
625 */
626 }
627
628 wcscat(BufferName, L"\\");
629 FileName = &BufferName[wcslen(BufferName)];
630
631 /* Create desktop.ini */
632 wcscpy(FileName, L"desktop.ini");
635 {
637 goto cleanup;
638 }
639 BytesToWrite = strlen(DesktopIniContents);
640 if (!WriteFile(hFile, DesktopIniContents, (DWORD)BytesToWrite, &BytesWritten, NULL))
641 {
643 goto cleanup;
644 }
645 if (BytesWritten != BytesToWrite)
646 {
647 hr = E_FAIL;
648 goto cleanup;
649 }
652
653 /* Create empty INFO2 file */
657 {
659 goto cleanup;
660 }
661 BytesToWrite = sizeof(Info2Contents);
662 if (!WriteFile(hFile, Info2Contents, (DWORD)BytesToWrite, &BytesWritten, NULL))
663 {
665 goto cleanup;
666 }
667 if (BytesWritten == BytesToWrite)
668 hr = S_OK;
669 else
670 hr = E_FAIL;
671
672cleanup:
673 HeapFree(GetProcessHeap(), 0, BufferName);
676 return hr;
677}
678
680 : m_ref(1)
681 , m_hInfo(NULL)
682 , m_hInfoMapped(NULL)
683 , m_EnumeratorCount(0)
684{
685}
686
688{
689 DWORD FileSystemFlags;
690 LPCWSTR RecycleBinDirectory;
691 HANDLE tokenHandle = INVALID_HANDLE_VALUE;
692 PTOKEN_USER TokenUserInfo = NULL;
693 LPWSTR StringSid = NULL;
694 DWORD Needed;
695 INT len;
696 HRESULT hr;
697
698 m_VolumePath = VolumePath;
699
700 /* Get information about file system */
701 if (!GetVolumeInformationW(VolumePath, NULL, 0, NULL, NULL, &FileSystemFlags, NULL, 0))
702 {
704 goto cleanup;
705 }
706
707 if (!(FileSystemFlags & FILE_PERSISTENT_ACLS))
708 {
709 RecycleBinDirectory = RECYCLE_BIN_DIRECTORY_WITHOUT_ACL;
710 }
711 else
712 {
713 RecycleBinDirectory = RECYCLE_BIN_DIRECTORY_WITH_ACL;
714
715 /* Get user SID */
716 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &tokenHandle))
717 {
719 goto cleanup;
720 }
721 if (GetTokenInformation(tokenHandle, TokenUser, NULL, 0, &Needed))
722 {
723 hr = E_FAIL;
724 goto cleanup;
725 }
727 {
729 goto cleanup;
730 }
731 TokenUserInfo = (PTOKEN_USER)HeapAlloc(GetProcessHeap(), 0, Needed);
732 if (!TokenUserInfo)
733 {
735 goto cleanup;
736 }
737 if (!GetTokenInformation(tokenHandle, TokenUser, TokenUserInfo, (DWORD)Needed, &Needed))
738 {
740 goto cleanup;
741 }
742 if (!ConvertSidToStringSidW(TokenUserInfo->User.Sid, &StringSid))
743 {
745 goto cleanup;
746 }
747 }
748
749 m_Folder = VolumePath;
750 m_Folder += RecycleBinDirectory;
751 if (StringSid)
752 {
753 m_Folder += L'\\';
754 m_Folder += StringSid;
755 }
758
762 {
764 hr = RecycleBin5_Create(m_Folder, TokenUserInfo ? TokenUserInfo->User.Sid : NULL);
766 if (!SUCCEEDED(hr))
767 goto cleanup;
769 }
770
772 {
774 goto cleanup;
775 }
776
778 if (!m_hInfoMapped)
779 {
781 goto cleanup;
782 }
783
785 hr = S_OK;
786
787cleanup:
788 if (tokenHandle != INVALID_HANDLE_VALUE)
789 CloseHandle(tokenHandle);
790 HeapFree(GetProcessHeap(), 0, TokenUserInfo);
791 if (StringSid)
792 LocalFree(StringSid);
793 return hr;
794}
795
798{
799 if (!ppUnknown)
800 return E_POINTER;
801
802 *ppUnknown = NULL;
803
804 RecycleBin5 *pThis = new RecycleBin5();
805 if (!pThis)
806 return E_OUTOFMEMORY;
807
808 HRESULT hr = pThis->Init(VolumePath);
809 if (FAILED(hr))
810 {
811 delete pThis;
812 return hr;
813 }
814
815 *ppUnknown = static_cast<IRecycleBin5 *>(pThis);
816 return S_OK;
817}
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 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 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
#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
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
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 FAILED(hr)
Definition: intsafe.h:51
#define debugstr_guid
Definition: kernel32.h:35
#define debugstr_w
Definition: kernel32.h:32
#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
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:246
EXTERN_C const IID IID_IRecycleBinEnumList
Definition: recyclebin.h:245
#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
_CRTIMP wchar_t *__cdecl wcscpy(_Out_writes_z_(_String_length_(_Source)+1) wchar_t *_Dest, _In_z_ const wchar_t *_Source)
_CRTIMP wchar_t *__cdecl wcscat(_Inout_updates_z_(_String_length_(_Dest)+_String_length_(_Source)+1) wchar_t *_Dest, _In_z_ const wchar_t *_Source)
WORD FILEOP_FLAGS
Definition: shellapi.h:214
#define FO_MOVE
Definition: shellapi.h:137
int WINAPI SHFileOperationW(LPSHFILEOPSTRUCTW lpFileOp)
Definition: shlfileop.cpp:1990
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::@2304 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:1737
#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:1735
#define INVALID_FILE_SIZE
Definition: winbase.h:574
#define MoveMemory
Definition: winbase.h:1734
#define DeleteFile
Definition: winbase.h:3789
_In_ LPCSTR _In_opt_ LPCSTR _In_ DWORD _Out_opt_ LPSTR * lpFilePart
Definition: winbase.h:3100
_In_ void _In_ PCCERT_CONTEXT _In_opt_ LPFILETIME _In_ DWORD _In_ DWORD _Outptr_opt_ void ** ppvObject
Definition: wincrypt.h:6082
#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 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