sys: FspFsvolSetDispositionInformation: ignore FILE_DISPOSITION_FORCE_IMAGE_SECTION_CHECK flag

This commit is contained in:
Bill Zissimopoulos 2021-11-19 17:16:36 +00:00
parent e09042c028
commit d72fe2ee33
No known key found for this signature in database
GPG Key ID: 3D4F95D52C7B3EA3
3 changed files with 43 additions and 8 deletions

View File

@ -1513,15 +1513,25 @@ retry:
if (!NT_SUCCESS(Result))
goto unlock_exit;
if (FlagOn(DispositionFlags, FILE_DISPOSITION_FORCE_IMAGE_SECTION_CHECK))
/*
* Make sure no process is mapping the file as an image.
*
* NOTE:
* Turns out that NTFS always does this test, even when
* FILE_DISPOSITION_FORCE_IMAGE_SECTION_CHECK has been specified.
* If MmFlushImageSection fails (e.g. an actively running EXE) then
* it only allows the deletion to go through when a secondary hard
* link is being deleted.
*
* Since WinFsp does not support hard links, we will go ahead and
* ignore the FILE_DISPOSITION_FORCE_IMAGE_SECTION_CHECK flag and
* always respect the result of MmFlushImageSection.
*/
Success = MmFlushImageSection(FileObject->SectionObjectPointer, MmFlushForDelete);
if (!Success)
{
/* make sure no process is mapping the file as an image */
Success = MmFlushImageSection(FileObject->SectionObjectPointer, MmFlushForDelete);
if (!Success)
{
Result = STATUS_CANNOT_DELETE;
goto unlock_exit;
}
Result = STATUS_CANNOT_DELETE;
goto unlock_exit;
}
if (FlagOn(DispositionFlags, FILE_DISPOSITION_IGNORE_READONLY_ATTRIBUTE))

View File

@ -200,6 +200,27 @@ static void exec_delete_dotest(ULONG Flags, PWSTR Prefix, ULONG FileInfoTimeout)
ASSERT(!DeleteFileW(FilePath));
ASSERT(ERROR_ACCESS_DENIED == GetLastError());
{
MY_FILE_DISPOSITION_INFO_EX DispositionInfo;
HANDLE Handle;
BOOLEAN Success;
Handle = CreateFileW(FilePath,
DELETE, FILE_SHARE_DELETE, 0,
OPEN_EXISTING, 0, 0);
if (INVALID_HANDLE_VALUE != Handle)
{
DispositionInfo.Disposition = FILE_DISPOSITION_DELETE | FILE_DISPOSITION_POSIX_SEMANTICS;
Success = SetFileInformationByHandle(Handle,
21/*FileDispositionInfoEx*/, &DispositionInfo, sizeof DispositionInfo);
ASSERT(!Success);
ASSERT(
ERROR_INVALID_PARAMETER == GetLastError() ||
ERROR_ACCESS_DENIED == GetLastError());
Success = CloseHandle(Handle);
ASSERT(Success);
}
}
WaitHelper(Process, 1000);
ASSERT(DeleteFileW(FilePath));

View File

@ -154,6 +154,10 @@ typedef struct
{
BOOLEAN Disposition;
} MY_FILE_DISPOSITION_INFO;
typedef struct
{
UINT32 Disposition;
} MY_FILE_DISPOSITION_INFO_EX;
void *memfs_start_ex(ULONG Flags, ULONG FileInfoTimeout);
void *memfs_start(ULONG Flags);