diff --git a/reactos/dll/win32/kernel32/client/utils.c b/reactos/dll/win32/kernel32/client/utils.c index e88a7f5b2f2..a96d129d09d 100644 --- a/reactos/dll/win32/kernel32/client/utils.c +++ b/reactos/dll/win32/kernel32/client/utils.c @@ -827,6 +827,51 @@ AreFileApisANSI(VOID) return Basep8BitStringToUnicodeString == RtlAnsiStringToUnicodeString; } +/* + * @implemented + */ +VOID +WINAPI +BaseMarkFileForDelete(IN HANDLE FileHandle, + IN ULONG FileAttributes) +{ + IO_STATUS_BLOCK IoStatusBlock; + FILE_BASIC_INFORMATION FileBasicInfo; + FILE_DISPOSITION_INFORMATION FileDispositionInfo; + + /* If no attributes were given, get them */ + if (!FileAttributes) + { + FileBasicInfo.FileAttributes = 0; + NtQueryInformationFile(FileHandle, + &IoStatusBlock, + &FileBasicInfo, + sizeof(FileBasicInfo), + FileBasicInformation); + FileAttributes = FileBasicInfo.FileAttributes; + } + + /* If file is marked as RO, reset its attributes */ + if (FileAttributes & FILE_ATTRIBUTE_READONLY) + { + RtlZeroMemory(&FileBasicInfo, sizeof(FileBasicInfo)); + FileBasicInfo.FileAttributes = FILE_ATTRIBUTE_NORMAL; + NtSetInformationFile(FileHandle, + &IoStatusBlock, + &FileBasicInfo, + sizeof(FileBasicInfo), + FileBasicInformation); + } + + /* Finally, mark the file for deletion */ + FileDispositionInfo.DeleteFile = TRUE; + NtSetInformationFile(FileHandle, + &IoStatusBlock, + &FileDispositionInfo, + sizeof(FileDispositionInfo), + FileDispositionInformation); +} + /* * @unimplemented */ diff --git a/reactos/dll/win32/kernel32/include/kernel32.h b/reactos/dll/win32/kernel32/include/kernel32.h index 227966b0d2e..d6a211d8884 100644 --- a/reactos/dll/win32/kernel32/include/kernel32.h +++ b/reactos/dll/win32/kernel32/include/kernel32.h @@ -323,3 +323,7 @@ BasepLocateExeLdrEntry(IN PLDR_DATA_TABLE_ENTRY Entry, IN PVOID Context, OUT BOOLEAN *StopEnumeration); +VOID +WINAPI +BaseMarkFileForDelete(IN HANDLE FileHandle, + IN ULONG FileAttributes);