ReactOS 0.4.15-dev-7931-gfd331f1
recyclebin_v5.c File Reference
#include "recyclebin_private.h"
#include "sddl.h"
Include dependency graph for recyclebin_v5.c:

Go to the source code of this file.

Classes

struct  RecycleBin5
 

Functions

static BOOL IntDeleteRecursive (IN LPCWSTR FullName)
 
static HRESULT STDMETHODCALLTYPE RecycleBin5_RecycleBin5_QueryInterface (IRecycleBin5 *This, REFIID riid, void **ppvObject)
 
static ULONG STDMETHODCALLTYPE RecycleBin5_RecycleBin5_AddRef (IRecycleBin5 *This)
 
static VOID RecycleBin5_Destructor (struct RecycleBin5 *s)
 
static ULONG STDMETHODCALLTYPE RecycleBin5_RecycleBin5_Release (IRecycleBin5 *This)
 
static HRESULT STDMETHODCALLTYPE RecycleBin5_RecycleBin5_DeleteFile (IN IRecycleBin5 *This, IN LPCWSTR szFileName)
 
static HRESULT STDMETHODCALLTYPE RecycleBin5_RecycleBin5_EmptyRecycleBin (IN IRecycleBin5 *This)
 
static HRESULT STDMETHODCALLTYPE RecycleBin5_RecycleBin5_EnumObjects (IN IRecycleBin5 *This, OUT IRecycleBinEnumList **ppEnumList)
 
static HRESULT STDMETHODCALLTYPE RecycleBin5_RecycleBin5_Delete (IN IRecycleBin5 *This, IN LPCWSTR pDeletedFileName, IN DELETED_FILE_RECORD *pDeletedFile)
 
static HRESULT STDMETHODCALLTYPE RecycleBin5_RecycleBin5_Restore (IN IRecycleBin5 *This, IN LPCWSTR pDeletedFileName, IN DELETED_FILE_RECORD *pDeletedFile)
 
static HRESULT STDMETHODCALLTYPE RecycleBin5_RecycleBin5_OnClosing (IN IRecycleBin5 *This, IN IRecycleBinEnumList *prbel)
 
static HRESULT RecycleBin5_Create (IN LPCWSTR Folder, IN PSID OwnerSid OPTIONAL)
 
HRESULT RecycleBin5_Constructor (IN LPCWSTR VolumePath, OUT IUnknown **ppUnknown)
 

Variables

CONST_VTBL struct IRecycleBin5Vtbl RecycleBin5Vtbl
 

Function Documentation

◆ IntDeleteRecursive()

static BOOL IntDeleteRecursive ( IN LPCWSTR  FullName)
static

Definition at line 14 of file recyclebin_v5.c.

16{
17 DWORD RemovableAttributes = FILE_ATTRIBUTE_READONLY;
18 WIN32_FIND_DATAW FindData;
20 LPWSTR FullPath = NULL, pFilePart;
23 BOOL ret = FALSE;
24
27 {
29 ret = TRUE;
30 goto cleanup;
31 }
32 if (FileAttributes & RemovableAttributes)
33 {
34 if (!SetFileAttributesW(FullName, FileAttributes & ~RemovableAttributes))
35 goto cleanup;
36 }
38 {
39 /* Prepare file specification */
41 FullPath = HeapAlloc(GetProcessHeap(), 0, (dwLength + 1 + MAX_PATH + 1) * sizeof(WCHAR));
42 if (!FullPath)
43 {
45 goto cleanup;
46 }
47 wcscpy(FullPath, FullName);
48 if (FullPath[dwLength - 1] != '\\')
49 {
50 FullPath[dwLength] = '\\';
51 dwLength++;
52 }
53 pFilePart = &FullPath[dwLength];
54 wcscpy(pFilePart, L"*");
55
56 /* Enumerate contents, and delete it */
57 hSearch = FindFirstFileW(FullPath, &FindData);
58 if (hSearch == INVALID_HANDLE_VALUE)
59 goto cleanup;
60 do
61 {
62 if (!(FindData.cFileName[0] == '.' &&
63 (FindData.cFileName[1] == '\0' || (FindData.cFileName[1] == '.' && FindData.cFileName[2] == '\0'))))
64 {
65 wcscpy(pFilePart, FindData.cFileName);
66 if (!IntDeleteRecursive(FullPath))
67 {
68 FindClose(hSearch);
69 goto cleanup;
70 }
71 }
72 }
73 while (FindNextFileW(hSearch, &FindData));
74 FindClose(hSearch);
76 goto cleanup;
77
78 /* Remove (now empty) directory */
80 goto cleanup;
81 }
82 else
83 {
85 goto cleanup;
86 }
87 ret = TRUE;
88
90 HeapFree(GetProcessHeap(), 0, FullPath);
91 return ret;
92}
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define GetProcessHeap()
Definition: compat.h:736
#define SetLastError(x)
Definition: compat.h:752
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define HeapAlloc
Definition: compat.h:733
#define MAX_PATH
Definition: compat.h:34
#define HeapFree(x, y, z)
Definition: compat.h:735
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 RemoveDirectoryW(IN LPCWSTR lpPathName)
Definition: dir.c:732
DWORD WINAPI GetFileAttributesW(LPCWSTR lpFileName)
Definition: fileinfo.c:652
BOOL WINAPI SetFileAttributesW(LPCWSTR lpFileName, DWORD dwFileAttributes)
Definition: fileinfo.c:794
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
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
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
#define FILE_ATTRIBUTE_READONLY
Definition: nt_native.h:702
#define FILE_ATTRIBUTE_DIRECTORY
Definition: nt_native.h:705
#define L(x)
Definition: ntvdm.h:50
static BOOL IntDeleteRecursive(IN LPCWSTR FullName)
Definition: recyclebin_v5.c:14
_CRTIMP wchar_t *__cdecl wcscpy(_Out_writes_z_(_String_length_(_Source)+1) wchar_t *_Dest, _In_z_ const wchar_t *_Source)
ULONG_PTR SIZE_T
Definition: typedefs.h:80
#define INVALID_FILE_ATTRIBUTES
Definition: vfdcmd.c:23
int ret
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define ERROR_NO_MORE_FILES
Definition: winerror.h:121
_In_ PSTRING FullName
Definition: rtlfuncs.h:1648
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184

Referenced by IntDeleteRecursive(), and RecycleBin5_RecycleBin5_Delete().

◆ RecycleBin5_Constructor()

HRESULT RecycleBin5_Constructor ( IN LPCWSTR  VolumePath,
OUT IUnknown **  ppUnknown 
)

Definition at line 675 of file recyclebin_v5.c.

676{
677 struct RecycleBin5 *s = NULL;
678 DWORD FileSystemFlags;
679 LPCWSTR RecycleBinDirectory;
680 HANDLE tokenHandle = INVALID_HANDLE_VALUE;
681 PTOKEN_USER TokenUserInfo = NULL;
682 LPWSTR StringSid = NULL, p;
683 DWORD Needed, DirectoryLength;
684 INT len;
685 HRESULT hr;
686
687 if (!ppUnknown)
688 return E_POINTER;
689
690 /* Get information about file system */
693 NULL,
694 0,
695 NULL,
696 NULL,
697 &FileSystemFlags,
698 NULL,
699 0))
700 {
702 goto cleanup;
703 }
704 if (!(FileSystemFlags & FILE_PERSISTENT_ACLS))
705 RecycleBinDirectory = RECYCLE_BIN_DIRECTORY_WITHOUT_ACL;
706 else
707 {
708 RecycleBinDirectory = RECYCLE_BIN_DIRECTORY_WITH_ACL;
709
710 /* Get user SID */
711 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &tokenHandle))
712 {
714 goto cleanup;
715 }
716 if (GetTokenInformation(tokenHandle, TokenUser, NULL, 0, &Needed))
717 {
718 hr = E_FAIL;
719 goto cleanup;
720 }
722 {
724 goto cleanup;
725 }
726 TokenUserInfo = HeapAlloc(GetProcessHeap(), 0, Needed);
727 if (!TokenUserInfo)
728 {
730 goto cleanup;
731 }
732 if (!GetTokenInformation(tokenHandle, TokenUser, TokenUserInfo, (DWORD)Needed, &Needed))
733 {
735 goto cleanup;
736 }
737 if (!ConvertSidToStringSidW(TokenUserInfo->User.Sid, &StringSid))
738 {
740 goto cleanup;
741 }
742 }
743
744 DirectoryLength = wcslen(VolumePath) + wcslen(RecycleBinDirectory) + 1;
745 if (StringSid)
746 DirectoryLength += wcslen(StringSid) + 1;
747 DirectoryLength += 1 + wcslen(RECYCLE_BIN_FILE_NAME);
748 DirectoryLength += wcslen(VolumePath) + 1;
749 Needed = (DirectoryLength + 1) * sizeof(WCHAR);
750
751 s = CoTaskMemAlloc(sizeof(struct RecycleBin5) + Needed);
752 if (!s)
753 {
755 goto cleanup;
756 }
757 ZeroMemory(s, sizeof(struct RecycleBin5));
758 s->recycleBinImpl.lpVtbl = &RecycleBin5Vtbl;
759 s->ref = 1;
760 if (StringSid)
761 len = swprintf(s->Folder, L"%s%s\\%s", VolumePath, RecycleBinDirectory, StringSid);
762 else
763 len = swprintf(s->Folder, L"%s%s", VolumePath, RecycleBinDirectory);
764 p = &s->Folder[len];
766 s->hInfo = CreateFileW(s->Folder, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
768 {
769 *p = UNICODE_NULL;
770 hr = RecycleBin5_Create(s->Folder, TokenUserInfo ? TokenUserInfo->User.Sid : NULL);
771 *p = L'\\';
772 if (!SUCCEEDED(hr))
773 goto cleanup;
774 s->hInfo = CreateFileW(s->Folder, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
775 }
776 if (s->hInfo == INVALID_HANDLE_VALUE)
777 {
779 goto cleanup;
780 }
781 s->hInfoMapped = CreateFileMappingW(s->hInfo, NULL, PAGE_READWRITE | SEC_COMMIT, 0, 0, NULL);
782 if (!s->hInfoMapped)
783 {
785 goto cleanup;
786 }
787 *p = UNICODE_NULL;
788 s->VolumePath = p + 1;
789 wcscpy(s->VolumePath, VolumePath);
790
791 *ppUnknown = (IUnknown *)&s->recycleBinImpl;
792
793 hr = S_OK;
794
795cleanup:
796 if (tokenHandle != INVALID_HANDLE_VALUE)
797 CloseHandle(tokenHandle);
798 HeapFree(GetProcessHeap(), 0, TokenUserInfo);
799 if (StringSid)
800 LocalFree(StringSid);
801 if (!SUCCEEDED(hr))
802 {
803 if (s)
805 }
806 return hr;
807}
#define ERROR_INSUFFICIENT_BUFFER
Definition: dderror.h:10
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define E_FAIL
Definition: ddrawi.h:102
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 OPEN_EXISTING
Definition: compat.h:775
#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 CreateFileW
Definition: compat.h:741
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
#define swprintf
Definition: precomp.h:40
#define FILE_PERSISTENT_ACLS
Definition: from_kernel.h:236
GLdouble s
Definition: gl.h:2039
GLfloat GLfloat p
Definition: glext.h:8902
GLenum GLsizei len
Definition: glext.h:6722
HLOCAL NTAPI LocalFree(HLOCAL hMem)
Definition: heapmem.c:1594
LPVOID WINAPI CoTaskMemAlloc(SIZE_T size)
Definition: ifs.c:426
#define S_OK
Definition: intsafe.h:52
#define SUCCEEDED(hr)
Definition: intsafe.h:50
if(dx< 0)
Definition: linetemp.h:194
#define SEC_COMMIT
Definition: mmtypes.h:100
#define PAGE_READWRITE
Definition: nt_native.h:1304
#define GENERIC_WRITE
Definition: nt_native.h:90
#define UNICODE_NULL
#define RECYCLE_BIN_DIRECTORY_WITH_ACL
#define RECYCLE_BIN_FILE_NAME
#define RECYCLE_BIN_DIRECTORY_WITHOUT_ACL
static VOID RecycleBin5_Destructor(struct RecycleBin5 *s)
CONST_VTBL struct IRecycleBin5Vtbl RecycleBin5Vtbl
static HRESULT RecycleBin5_Create(IN LPCWSTR Folder, IN PSID OwnerSid OPTIONAL)
HRESULT hr
Definition: shlfolder.c:183
LPWSTR VolumePath
SID_AND_ATTRIBUTES User
Definition: setypes.h:1010
int32_t INT
Definition: typedefs.h:58
#define ZeroMemory
Definition: winbase.h:1712
#define ERROR_PATH_NOT_FOUND
Definition: winerror.h:106
#define HRESULT_FROM_WIN32(x)
Definition: winerror.h:92
#define E_POINTER
Definition: winerror.h:2365
#define TOKEN_QUERY
Definition: setypes.h:928
@ TokenUser
Definition: setypes.h:966
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185

Referenced by GetDefaultRecycleBin().

◆ RecycleBin5_Create()

static HRESULT RecycleBin5_Create ( IN LPCWSTR  Folder,
IN PSID OwnerSid  OPTIONAL 
)
static

Definition at line 562 of file recyclebin_v5.c.

565{
566 LPWSTR BufferName = NULL;
567 LPWSTR Separator; /* Pointer into BufferName buffer */
568 LPWSTR FileName; /* Pointer into BufferName buffer */
569 LPCSTR DesktopIniContents = "[.ShellClassInfo]\r\nCLSID={645FF040-5081-101B-9F08-00AA002F954E}\r\n";
570 INFO2_HEADER Info2Contents[] = { { 5, 0, 0, 0x320, 0 } };
571 DWORD BytesToWrite, BytesWritten, Needed;
573 HRESULT hr;
574
575 Needed = (wcslen(Folder) + 1 + max(wcslen(RECYCLE_BIN_FILE_NAME), wcslen(L"desktop.ini")) + 1) * sizeof(WCHAR);
576 BufferName = HeapAlloc(GetProcessHeap(), 0, Needed);
577 if (!BufferName)
578 {
580 goto cleanup;
581 }
582
583 wcscpy(BufferName, Folder);
584 Separator = wcsstr(&BufferName[3], L"\\");
585 if (Separator)
586 *Separator = UNICODE_NULL;
587 if (!CreateDirectoryW(BufferName, NULL) && GetLastError() != ERROR_ALREADY_EXISTS)
588 {
590 goto cleanup;
591 }
593 if (Separator)
594 {
595 *Separator = L'\\';
596 if (!CreateDirectoryW(BufferName, NULL) && GetLastError() != ERROR_ALREADY_EXISTS)
597 {
599 goto cleanup;
600 }
601 }
602
603 if (OwnerSid)
604 {
605 //DWORD rc;
606
607 /* Add ACL to allow only user/SYSTEM to open it */
608 /* FIXME: rc = SetNamedSecurityInfo(
609 BufferName,
610 SE_FILE_OBJECT,
611 ???,
612 OwnerSid,
613 NULL,
614 ???,
615 ???);
616 if (rc != ERROR_SUCCESS)
617 {
618 hr = HRESULT_FROM_WIN32(rc);
619 goto cleanup;
620 }
621 */
622 }
623
624 wcscat(BufferName, L"\\");
625 FileName = &BufferName[wcslen(BufferName)];
626
627 /* Create desktop.ini */
628 wcscpy(FileName, L"desktop.ini");
631 {
633 goto cleanup;
634 }
635 BytesToWrite = strlen(DesktopIniContents);
636 if (!WriteFile(hFile, DesktopIniContents, (DWORD)BytesToWrite, &BytesWritten, NULL))
637 {
639 goto cleanup;
640 }
641 if (BytesWritten != BytesToWrite)
642 {
643 hr = E_FAIL;
644 goto cleanup;
645 }
648
649 /* Create empty INFO2 file */
653 {
655 goto cleanup;
656 }
657 BytesToWrite = sizeof(Info2Contents);
658 if (!WriteFile(hFile, Info2Contents, (DWORD)BytesToWrite, &BytesWritten, NULL))
659 {
661 goto cleanup;
662 }
663 if (BytesWritten == BytesToWrite)
664 hr = S_OK;
665 else
666 hr = E_FAIL;
667
668cleanup:
669 HeapFree(GetProcessHeap(), 0, BufferName);
672 return hr;
673}
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
BOOL WINAPI CreateDirectoryW(IN LPCWSTR lpPathName, IN LPSECURITY_ATTRIBUTES lpSecurityAttributes)
Definition: dir.c:90
BOOL WINAPI WriteFile(IN HANDLE hFile, IN LPCVOID lpBuffer, IN DWORD nNumberOfBytesToWrite OPTIONAL, OUT LPDWORD lpNumberOfBytesWritten, IN LPOVERLAPPED lpOverlapped OPTIONAL)
Definition: rw.c:24
struct _FileName FileName
Definition: fatprocs.h:896
_CONST_RETURN wchar_t *__cdecl wcsstr(_In_z_ const wchar_t *_Str, _In_z_ const wchar_t *_SubStr)
#define CREATE_ALWAYS
Definition: disk.h:72
#define ERROR_ALREADY_EXISTS
Definition: disk.h:80
_In_ HANDLE hFile
Definition: mswsock.h:90
#define FILE_ATTRIBUTE_HIDDEN
Definition: nt_native.h:703
#define FILE_ATTRIBUTE_SYSTEM
Definition: nt_native.h:704
_CRTIMP wchar_t *__cdecl wcscat(_Inout_updates_z_(_String_length_(_Dest)+_String_length_(_Source)+1) wchar_t *_Dest, _In_z_ const wchar_t *_Source)
#define max(a, b)
Definition: svc.c:63
_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
const char * LPCSTR
Definition: xmlstorage.h:183

Referenced by RecycleBin5_Constructor().

◆ RecycleBin5_Destructor()

static VOID RecycleBin5_Destructor ( struct RecycleBin5 s)
static

Definition at line 147 of file recyclebin_v5.c.

149{
150 TRACE("(%p)\n", s);
151
152 if (s->hInfo && s->hInfo != INVALID_HANDLE_VALUE)
153 CloseHandle(s->hInfo);
154 if (s->hInfoMapped)
155 CloseHandle(s->hInfoMapped);
157}
VOID WINAPI CoTaskMemFree(LPVOID ptr)
Definition: ifs.c:442
#define TRACE(s)
Definition: solgame.cpp:4

Referenced by RecycleBin5_Constructor(), and RecycleBin5_RecycleBin5_Release().

◆ RecycleBin5_RecycleBin5_AddRef()

static ULONG STDMETHODCALLTYPE RecycleBin5_RecycleBin5_AddRef ( IRecycleBin5 This)
static

Definition at line 137 of file recyclebin_v5.c.

139{
141 ULONG refCount = InterlockedIncrement((PLONG)&s->ref);
142 TRACE("(%p)\n", This);
143 return refCount;
144}
#define InterlockedIncrement
Definition: armddk.h:53
IRecycleBin5 recycleBinImpl
Definition: recyclebin_v5.c:97
int32_t * PLONG
Definition: typedefs.h:58
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59

◆ RecycleBin5_RecycleBin5_Delete()

static HRESULT STDMETHODCALLTYPE RecycleBin5_RecycleBin5_Delete ( IN IRecycleBin5 This,
IN LPCWSTR  pDeletedFileName,
IN DELETED_FILE_RECORD pDeletedFile 
)
static

Definition at line 404 of file recyclebin_v5.c.

408{
412 DELETED_FILE_RECORD *pRecord, *pLast;
413 DWORD dwEntries, i;
414
415 TRACE("(%p, %s, %p)\n", This, debugstr_w(pDeletedFileName), pDeletedFile);
416
417 if (s->EnumeratorCount != 0)
419
420 pHeader = MapViewOfFile(s->hInfoMapped, FILE_MAP_WRITE, 0, 0, 0);
421 if (!pHeader)
423
424 FileSize.u.LowPart = GetFileSize(s->hInfo, &FileSize.u.HighPart);
425 if (FileSize.u.LowPart == 0)
426 {
429 }
430 dwEntries = (DWORD)((FileSize.QuadPart - sizeof(INFO2_HEADER)) / sizeof(DELETED_FILE_RECORD));
431
432 pRecord = (DELETED_FILE_RECORD *)(pHeader + 1);
433 for (i = 0; i < dwEntries; i++)
434 {
435 if (pRecord->dwRecordUniqueId == pDeletedFile->dwRecordUniqueId)
436 {
437 /* Delete file */
438 if (!IntDeleteRecursive(pDeletedFileName))
439 {
442 }
443
444 /* Clear last entry in the file */
445 MoveMemory(pRecord, pRecord + 1, (dwEntries - i - 1) * sizeof(DELETED_FILE_RECORD));
446 pLast = pRecord + (dwEntries - i - 1);
447 ZeroMemory(pLast, sizeof(DELETED_FILE_RECORD));
449
450 /* Resize file */
451 CloseHandle(s->hInfoMapped);
453 SetEndOfFile(s->hInfo);
454 s->hInfoMapped = CreateFileMappingW(s->hInfo, NULL, PAGE_READWRITE | SEC_COMMIT, 0, 0, NULL);
455 if (!s->hInfoMapped)
457 return S_OK;
458 }
459 pRecord++;
460 }
463}
#define UnmapViewOfFile
Definition: compat.h:746
#define SetFilePointer
Definition: compat.h:743
#define MapViewOfFile
Definition: compat.h:745
BOOL WINAPI SetEndOfFile(HANDLE hFile)
Definition: fileinfo.c:1004
DWORD WINAPI GetFileSize(HANDLE hFile, LPDWORD lpFileSizeHigh)
Definition: fileinfo.c:331
_Must_inspect_result_ _Out_ PLARGE_INTEGER FileSize
Definition: fsrtlfuncs.h:108
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
#define debugstr_w
Definition: kernel32.h:32
#define DWORD
Definition: nt_native.h:44
long LONG
Definition: pedump.c:60
struct _DELETED_FILE_RECORD DELETED_FILE_RECORD
LONGLONG QuadPart
Definition: typedefs.h:114
struct _LARGE_INTEGER::@2295 u
#define FILE_END
Definition: winbase.h:114
#define FILE_MAP_WRITE
Definition: winbase.h:154
#define MoveMemory
Definition: winbase.h:1709
#define ERROR_SHARING_VIOLATION
Definition: winerror.h:135

◆ RecycleBin5_RecycleBin5_DeleteFile()

static HRESULT STDMETHODCALLTYPE RecycleBin5_RecycleBin5_DeleteFile ( IN IRecycleBin5 This,
IN LPCWSTR  szFileName 
)
static

Definition at line 177 of file recyclebin_v5.c.

180{
182 LPWSTR szFullName = NULL;
183 DWORD dwBufferLength = 0;
186 WCHAR DeletedFileName[MAX_PATH];
187 DWORD len;
190 PDELETED_FILE_RECORD pDeletedFile;
192 DWORD dwAttributes, dwEntries;
193 SYSTEMTIME SystemTime;
194 DWORD ClusterSize, BytesPerSector, SectorsPerCluster;
195 HRESULT hr;
196
197 TRACE("(%p, %s)\n", This, debugstr_w(szFileName));
198
199 if (s->EnumeratorCount != 0)
201
202 /* Get full file name */
203 while (TRUE)
204 {
205 len = GetFullPathNameW(szFileName, dwBufferLength, szFullName, &lpFilePart);
206 if (len == 0)
207 {
208 if (szFullName)
209 CoTaskMemFree(szFullName);
211 }
212 else if (len < dwBufferLength)
213 break;
214 if (szFullName)
215 CoTaskMemFree(szFullName);
216 dwBufferLength = len;
217 szFullName = CoTaskMemAlloc(dwBufferLength * sizeof(WCHAR));
218 if (!szFullName)
220 }
221
222 /* Check if file exists */
223 dwAttributes = GetFileAttributesW(szFullName);
225 {
226 CoTaskMemFree(szFullName);
228 }
229
230 if (dwBufferLength < 2 || szFullName[1] != ':')
231 {
232 /* Not a local file */
233 CoTaskMemFree(szFullName);
235 }
236
239 {
241 goto cleanup;
242 }
243
244 /* Increase INFO2 file size */
245 CloseHandle(s->hInfoMapped);
247 SetEndOfFile(s->hInfo);
248 s->hInfoMapped = CreateFileMappingW(s->hInfo, NULL, PAGE_READWRITE | SEC_COMMIT, 0, 0, NULL);
249 if (!s->hInfoMapped)
250 {
252 goto cleanup;
253 }
254
255 /* Open INFO2 file */
256 pHeader = MapViewOfFile(s->hInfoMapped, FILE_MAP_WRITE, 0, 0, 0);
257 if (!pHeader)
258 {
260 goto cleanup;
261 }
262
263 /* Get number of entries */
264 FileSize.u.LowPart = GetFileSize(s->hInfo, &FileSize.u.HighPart);
265 if (FileSize.u.LowPart < sizeof(INFO2_HEADER))
266 {
268 goto cleanup;
269 }
270 dwEntries = (DWORD)((FileSize.QuadPart - sizeof(INFO2_HEADER)) / sizeof(DELETED_FILE_RECORD)) - 1;
271 pDeletedFile = ((PDELETED_FILE_RECORD)(pHeader + 1)) + dwEntries;
272
273 /* Get file size */
274#if 0
276 {
278 goto cleanup;
279 }
280#else
281 FileSize.u.LowPart = GetFileSize(hFile, &FileSize.u.HighPart);
282 if (FileSize.u.LowPart == INVALID_FILE_SIZE && GetLastError() != NO_ERROR)
283 {
285 goto cleanup;
286 }
287#endif
288 /* Check if file size is > 4Gb */
289 if (FileSize.u.HighPart != 0)
290 {
291 /* Yes, this recyclebin can't support this file */
293 goto cleanup;
294 }
295 pHeader->dwTotalLogicalSize += FileSize.u.LowPart;
296
297 /* Generate new name */
298 Extension = wcsrchr(szFullName, '.');
299 ZeroMemory(pDeletedFile, sizeof(DELETED_FILE_RECORD));
300 if (dwEntries == 0)
301 pDeletedFile->dwRecordUniqueId = 0;
302 else
303 {
304 PDELETED_FILE_RECORD pLastDeleted = ((PDELETED_FILE_RECORD)(pHeader + 1)) + dwEntries - 1;
305 pDeletedFile->dwRecordUniqueId = pLastDeleted->dwRecordUniqueId + 1;
306 }
307 pDeletedFile->dwDriveNumber = tolower(szFullName[0]) - 'a';
308 _snwprintf(DeletedFileName, MAX_PATH, L"%s\\D%c%lu%s", s->Folder, pDeletedFile->dwDriveNumber + 'a', pDeletedFile->dwRecordUniqueId, Extension);
309
310 /* Get cluster size */
311 if (!GetDiskFreeSpaceW(s->VolumePath, &SectorsPerCluster, &BytesPerSector, NULL, NULL))
312 {
314 goto cleanup;
315 }
316 ClusterSize = BytesPerSector * SectorsPerCluster;
317
318 /* Get current time */
319 GetSystemTime(&SystemTime);
320 if (!SystemTimeToFileTime(&SystemTime, &pDeletedFile->DeletionTime))
321 {
323 goto cleanup;
324 }
325 pDeletedFile->dwPhysicalFileSize = ROUND_UP(FileSize.u.LowPart, ClusterSize);
326
327 /* Set name */
328 wcscpy(pDeletedFile->FileNameW, szFullName);
329 if (WideCharToMultiByte(CP_ACP, 0, pDeletedFile->FileNameW, -1, pDeletedFile->FileNameA, MAX_PATH, NULL, NULL) == 0)
330 {
333 goto cleanup;
334 }
335
336 /* Move file */
337 if (MoveFileW(szFullName, DeletedFileName))
338 hr = S_OK;
339 else
341
342cleanup:
343 if (pHeader)
347 CoTaskMemFree(szFullName);
348 return hr;
349}
int tolower(int c)
Definition: utclib.c:902
DWORD ClusterSize
Definition: format.c:67
#define NO_ERROR
Definition: dderror.h:5
#define wcsrchr
Definition: compat.h:16
#define CP_ACP
Definition: compat.h:109
#define ERROR_NOT_SUPPORTED
Definition: compat.h:100
#define GetFileSizeEx
Definition: compat.h:757
#define WideCharToMultiByte
Definition: compat.h:111
#define ERROR_INVALID_NAME
Definition: compat.h:103
BOOL WINAPI GetDiskFreeSpaceW(IN LPCWSTR lpRootPathName, OUT LPDWORD lpSectorsPerCluster, OUT LPDWORD lpBytesPerSector, OUT LPDWORD lpNumberOfFreeClusters, OUT LPDWORD lpTotalNumberOfClusters)
Definition: disk.c:173
BOOL WINAPI MoveFileW(IN LPCWSTR lpExistingFileName, IN LPCWSTR lpNewFileName)
Definition: move.c:1104
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
#define ROUND_UP(n, align)
Definition: eventvwr.h:34
_Inout_opt_ PUNICODE_STRING Extension
Definition: fltkernel.h:1092
#define FILE_FLAG_BACKUP_SEMANTICS
Definition: disk.h:41
int _snwprintf(wchar_t *buffer, size_t count, const wchar_t *format,...)
struct _DELETED_FILE_RECORD * PDELETED_FILE_RECORD
CHAR FileNameA[MAX_PATH]
Definition: recyclebin_v5.h:15
WCHAR FileNameW[MAX_PATH]
Definition: recyclebin_v5.h:20
DWORD dwAttributes
Definition: vdmdbg.h:34
#define INVALID_FILE_SIZE
Definition: winbase.h:548
_In_ LPCSTR _In_opt_ LPCSTR _In_ DWORD _Out_opt_ LPSTR * lpFilePart
Definition: winbase.h:3075

◆ RecycleBin5_RecycleBin5_EmptyRecycleBin()

static HRESULT STDMETHODCALLTYPE RecycleBin5_RecycleBin5_EmptyRecycleBin ( IN IRecycleBin5 This)
static

Definition at line 352 of file recyclebin_v5.c.

354{
355 IRecycleBinEnumList *prbel;
356 IRecycleBinFile *prbf;
357 HRESULT hr;
358
359 TRACE("(%p)\n", This);
360
361 while (TRUE)
362 {
363 hr = IRecycleBin5_EnumObjects(This, &prbel);
364 if (!SUCCEEDED(hr))
365 return hr;
366 hr = IRecycleBinEnumList_Next(prbel, 1, &prbf, NULL);
367 IRecycleBinEnumList_Release(prbel);
368 if (hr == S_FALSE)
369 return S_OK;
370 hr = IRecycleBinFile_Delete(prbf);
371 IRecycleBinFile_Release(prbf);
372 if (!SUCCEEDED(hr))
373 return hr;
374 }
375}
#define S_FALSE
Definition: winerror.h:2357

◆ RecycleBin5_RecycleBin5_EnumObjects()

static HRESULT STDMETHODCALLTYPE RecycleBin5_RecycleBin5_EnumObjects ( IN IRecycleBin5 This,
OUT IRecycleBinEnumList **  ppEnumList 
)
static

Definition at line 378 of file recyclebin_v5.c.

381{
383 IRecycleBinEnumList *prbel;
384 HRESULT hr;
385 IUnknown *pUnk;
386
387 TRACE("(%p, %p)\n", This, ppEnumList);
388
389 hr = RecycleBin5Enum_Constructor(This, s->hInfo, s->hInfoMapped, s->Folder, &pUnk);
390 if (!SUCCEEDED(hr))
391 return hr;
392
393 hr = IUnknown_QueryInterface(pUnk, &IID_IRecycleBinEnumList, (void **)&prbel);
394 if (SUCCEEDED(hr))
395 {
396 s->EnumeratorCount++;
397 *ppEnumList = prbel;
398 }
399 IUnknown_Release(pUnk);
400 return hr;
401}
static void *static void *static LPDIRECTPLAY IUnknown * pUnk
Definition: dplayx.c:30
EXTERN_C const IID IID_IRecycleBinEnumList
Definition: recyclebin.h:242
HRESULT RecycleBin5Enum_Constructor(IN IRecycleBin5 *prb, IN HANDLE hInfo, IN HANDLE hInfoMapped, IN LPCWSTR szPrefix, OUT IUnknown **ppUnknown)

◆ RecycleBin5_RecycleBin5_OnClosing()

static HRESULT STDMETHODCALLTYPE RecycleBin5_RecycleBin5_OnClosing ( IN IRecycleBin5 This,
IN IRecycleBinEnumList *  prbel 
)
static

Definition at line 538 of file recyclebin_v5.c.

541{
543 TRACE("(%p, %p)\n", This, prbel);
544 s->EnumeratorCount--;
545 return S_OK;
546}

◆ RecycleBin5_RecycleBin5_QueryInterface()

static HRESULT STDMETHODCALLTYPE RecycleBin5_RecycleBin5_QueryInterface ( IRecycleBin5 This,
REFIID  riid,
void **  ppvObject 
)
static

Definition at line 108 of file recyclebin_v5.c.

112{
114
115 TRACE("(%p, %s, %p)\n", This, debugstr_guid(riid), ppvObject);
116
117 if (!ppvObject)
118 return E_POINTER;
119
121 *ppvObject = &s->recycleBinImpl;
122 else if (IsEqualIID(riid, &IID_IRecycleBin))
123 *ppvObject = &s->recycleBinImpl;
124 else if (IsEqualIID(riid, &IID_IRecycleBin5))
125 *ppvObject = &s->recycleBinImpl;
126 else
127 {
128 *ppvObject = NULL;
129 return E_NOINTERFACE;
130 }
131
132 IUnknown_AddRef(This);
133 return S_OK;
134}
const GUID IID_IUnknown
REFIID riid
Definition: atlbase.h:39
#define debugstr_guid
Definition: kernel32.h:35
#define IsEqualIID(riid1, riid2)
Definition: guiddef.h:95
EXTERN_C const IID IID_IRecycleBin
Definition: recyclebin.h:243
EXTERN_C const IID IID_IRecycleBin5
Definition: recyclebin_v5.h:28
_In_ void _In_ PCCERT_CONTEXT _In_opt_ LPFILETIME _In_ DWORD _In_ DWORD _Outptr_opt_ void ** ppvObject
Definition: wincrypt.h:6082
#define E_NOINTERFACE
Definition: winerror.h:2364

◆ RecycleBin5_RecycleBin5_Release()

static ULONG STDMETHODCALLTYPE RecycleBin5_RecycleBin5_Release ( IRecycleBin5 This)
static

Definition at line 160 of file recyclebin_v5.c.

162{
164 ULONG refCount;
165
166 TRACE("(%p)\n", This);
167
168 refCount = InterlockedDecrement((PLONG)&s->ref);
169
170 if (refCount == 0)
172
173 return refCount;
174}
#define InterlockedDecrement
Definition: armddk.h:52

◆ RecycleBin5_RecycleBin5_Restore()

static HRESULT STDMETHODCALLTYPE RecycleBin5_RecycleBin5_Restore ( IN IRecycleBin5 This,
IN LPCWSTR  pDeletedFileName,
IN DELETED_FILE_RECORD pDeletedFile 
)
static

Definition at line 466 of file recyclebin_v5.c.

470{
474 DELETED_FILE_RECORD *pRecord, *pLast;
475 DWORD dwEntries, i;
477 int res;
478
479 TRACE("(%p, %s, %p)\n", This, debugstr_w(pDeletedFileName), pDeletedFile);
480
481 if (s->EnumeratorCount != 0)
483
484 pHeader = MapViewOfFile(s->hInfoMapped, FILE_MAP_WRITE, 0, 0, 0);
485 if (!pHeader)
487
488 FileSize.u.LowPart = GetFileSize(s->hInfo, &FileSize.u.HighPart);
489 if (FileSize.u.LowPart == 0)
490 {
493 }
494 dwEntries = (DWORD)((FileSize.QuadPart - sizeof(INFO2_HEADER)) / sizeof(DELETED_FILE_RECORD));
495
496 pRecord = (DELETED_FILE_RECORD *)(pHeader + 1);
497 for (i = 0; i < dwEntries; i++)
498 {
499 if (pRecord->dwRecordUniqueId == pDeletedFile->dwRecordUniqueId)
500 {
501 /* Restore file */
502 ZeroMemory(&op, sizeof(op));
503 op.wFunc = FO_MOVE;
504 op.pFrom = pDeletedFileName;
505 op.pTo = pDeletedFile->FileNameW;
506
508 if (res)
509 {
510 ERR("SHFileOperationW failed with 0x%x\n", res);
512 return E_FAIL;
513 }
514
515 /* Clear last entry in the file */
516 MoveMemory(pRecord, pRecord + 1, (dwEntries - i - 1) * sizeof(DELETED_FILE_RECORD));
517 pLast = pRecord + (dwEntries - i - 1);
518 ZeroMemory(pLast, sizeof(DELETED_FILE_RECORD));
520
521 /* Resize file */
522 CloseHandle(s->hInfoMapped);
524 SetEndOfFile(s->hInfo);
525 s->hInfoMapped = CreateFileMappingW(s->hInfo, NULL, PAGE_READWRITE | SEC_COMMIT, 0, 0, NULL);
526 if (!s->hInfoMapped)
528 return S_OK;
529 }
530 pRecord++;
531 }
532
535}
#define ERR(fmt,...)
Definition: debug.h:110
UINT op
Definition: effect.c:236
GLuint res
Definition: glext.h:9613
#define FO_MOVE
Definition: shellapi.h:136
int WINAPI SHFileOperationW(LPSHFILEOPSTRUCTW lpFileOp)
Definition: shlfileop.cpp:1987

Variable Documentation

◆ RecycleBin5Vtbl

Initial value:
=
{
}
static HRESULT STDMETHODCALLTYPE RecycleBin5_RecycleBin5_Restore(IN IRecycleBin5 *This, IN LPCWSTR pDeletedFileName, IN DELETED_FILE_RECORD *pDeletedFile)
static HRESULT STDMETHODCALLTYPE RecycleBin5_RecycleBin5_OnClosing(IN IRecycleBin5 *This, IN IRecycleBinEnumList *prbel)
static ULONG STDMETHODCALLTYPE RecycleBin5_RecycleBin5_AddRef(IRecycleBin5 *This)
static HRESULT STDMETHODCALLTYPE RecycleBin5_RecycleBin5_EmptyRecycleBin(IN IRecycleBin5 *This)
static ULONG STDMETHODCALLTYPE RecycleBin5_RecycleBin5_Release(IRecycleBin5 *This)
static HRESULT STDMETHODCALLTYPE RecycleBin5_RecycleBin5_QueryInterface(IRecycleBin5 *This, REFIID riid, void **ppvObject)
static HRESULT STDMETHODCALLTYPE RecycleBin5_RecycleBin5_DeleteFile(IN IRecycleBin5 *This, IN LPCWSTR szFileName)
static HRESULT STDMETHODCALLTYPE RecycleBin5_RecycleBin5_EnumObjects(IN IRecycleBin5 *This, OUT IRecycleBinEnumList **ppEnumList)
static HRESULT STDMETHODCALLTYPE RecycleBin5_RecycleBin5_Delete(IN IRecycleBin5 *This, IN LPCWSTR pDeletedFileName, IN DELETED_FILE_RECORD *pDeletedFile)

Definition at line 548 of file recyclebin_v5.c.

Referenced by RecycleBin5_Constructor().