sys: fileinfo: call MmCanFileBeTruncated only when truncating (allows file mappings to be created)

sys: util.c: FspGetMdlAddress()
This commit is contained in:
Bill Zissimopoulos 2016-03-16 16:17:22 -07:00
parent fc7c709e5f
commit 26d2d51117
3 changed files with 52 additions and 12 deletions

View File

@ -472,6 +472,10 @@ VOID FspFileNodeCleanupComplete(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject
} }
else if (FileNode->TruncateOnClose && FlagOn(FileObject->Flags, FO_CACHE_SUPPORTED)) else if (FileNode->TruncateOnClose && FlagOn(FileObject->Flags, FO_CACHE_SUPPORTED))
{ {
/*
* Even when the FileInfo is expired, this is the best guess for a file size
* without asking the user-mode file system.
*/
TruncateSize = FileNode->Header.FileSize; TruncateSize = FileNode->Header.FileSize;
PTruncateSize = &TruncateSize; PTruncateSize = &TruncateSize;
} }

View File

@ -573,21 +573,34 @@ static NTSTATUS FspFsvolSetAllocationInformation(PFILE_OBJECT FileObject,
{ {
PFILE_ALLOCATION_INFORMATION Info = (PFILE_ALLOCATION_INFORMATION)Buffer; PFILE_ALLOCATION_INFORMATION Info = (PFILE_ALLOCATION_INFORMATION)Buffer;
FSP_FILE_NODE *FileNode = FileObject->FsContext; FSP_FILE_NODE *FileNode = FileObject->FsContext;
FSP_FSCTL_FILE_INFO FileInfo;
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension =
FspFsvolDeviceExtension(FileNode->FsvolDeviceObject); FspFsvolDeviceExtension(FileNode->FsvolDeviceObject);
UINT64 AllocationSize = Info->AllocationSize.QuadPart; LARGE_INTEGER AllocationSize = Info->AllocationSize;
UINT64 AllocationUnit; UINT64 AllocationUnit;
BOOLEAN Success; BOOLEAN Success;
AllocationUnit = FsvolDeviceExtension->VolumeParams.SectorSize * AllocationUnit = FsvolDeviceExtension->VolumeParams.SectorSize *
FsvolDeviceExtension->VolumeParams.SectorsPerAllocationUnit; FsvolDeviceExtension->VolumeParams.SectorsPerAllocationUnit;
AllocationSize = (AllocationSize + AllocationUnit - 1) / AllocationUnit * AllocationUnit; AllocationSize.QuadPart = (AllocationSize.QuadPart + AllocationUnit - 1) /
Request->Req.SetInformation.Info.Allocation.AllocationSize = AllocationSize; AllocationUnit * AllocationUnit;
Request->Req.SetInformation.Info.Allocation.AllocationSize = AllocationSize.QuadPart;
Success = MmCanFileBeTruncated(FileObject->SectionObjectPointer, &Info->AllocationSize); /*
* Even when the FileInfo is expired, this is the best guess for a file size
* without asking the user-mode file system.
*/
FspFileNodeGetFileInfo(FileNode, &FileInfo);
/* are we truncating? */
if ((UINT64)AllocationSize.QuadPart < FileInfo.FileSize)
{
/* see what the MM thinks about all this */
Success = MmCanFileBeTruncated(FileObject->SectionObjectPointer, &AllocationSize);
if (!Success) if (!Success)
return STATUS_USER_MAPPED_FILE; return STATUS_USER_MAPPED_FILE;
} }
}
else else
{ {
FSP_FILE_NODE *FileNode = FileObject->FsContext; FSP_FILE_NODE *FileNode = FileObject->FsContext;
@ -654,14 +667,27 @@ static NTSTATUS FspFsvolSetEndOfFileInformation(PFILE_OBJECT FileObject,
else if (0 == Response) else if (0 == Response)
{ {
PFILE_END_OF_FILE_INFORMATION Info = (PFILE_END_OF_FILE_INFORMATION)Buffer; PFILE_END_OF_FILE_INFORMATION Info = (PFILE_END_OF_FILE_INFORMATION)Buffer;
FSP_FILE_NODE *FileNode = FileObject->FsContext;
FSP_FSCTL_FILE_INFO FileInfo;
BOOLEAN Success; BOOLEAN Success;
Request->Req.SetInformation.Info.EndOfFile.FileSize = Info->EndOfFile.QuadPart; Request->Req.SetInformation.Info.EndOfFile.FileSize = Info->EndOfFile.QuadPart;
/*
* Even when the FileInfo is expired, this is the best guess for a file size
* without asking the user-mode file system.
*/
FspFileNodeGetFileInfo(FileNode, &FileInfo);
/* are we truncating? */
if ((UINT64)Info->EndOfFile.QuadPart < FileInfo.FileSize)
{
/* see what the MM thinks about all this */
Success = MmCanFileBeTruncated(FileObject->SectionObjectPointer, &Info->EndOfFile); Success = MmCanFileBeTruncated(FileObject->SectionObjectPointer, &Info->EndOfFile);
if (!Success) if (!Success)
return STATUS_USER_MAPPED_FILE; return STATUS_USER_MAPPED_FILE;
} }
}
else else
{ {
FSP_FILE_NODE *FileNode = FileObject->FsContext; FSP_FILE_NODE *FileNode = FileObject->FsContext;

View File

@ -539,11 +539,21 @@ static VOID FspQueueDelayedWorkItemDPC(PKDPC Dpc,
ExQueueWorkItem(&DelayedWorkItem->WorkQueueItem, DelayedWorkQueue); ExQueueWorkItem(&DelayedWorkItem->WorkQueueItem, DelayedWorkQueue);
} }
static inline PVOID FspGetMdlAddress(PMDL Mdl)
{
PVOID VirtualAddress = MmGetMdlVirtualAddress(Mdl);
if (0 == VirtualAddress)
VirtualAddress = MmGetSystemAddressForMdlSafe(Mdl, NormalPagePriority);
return VirtualAddress;
}
BOOLEAN FspSafeMdlCheck(PMDL Mdl) BOOLEAN FspSafeMdlCheck(PMDL Mdl)
{ {
PAGED_CODE(); PAGED_CODE();
PVOID VirtualAddress = MmGetMdlVirtualAddress(Mdl); PVOID VirtualAddress = FspGetMdlAddress(Mdl);
ULONG ByteCount = MmGetMdlByteCount(Mdl); ULONG ByteCount = MmGetMdlByteCount(Mdl);
return 0 == BYTE_OFFSET(VirtualAddress) && 0 == BYTE_OFFSET(ByteCount); return 0 == BYTE_OFFSET(VirtualAddress) && 0 == BYTE_OFFSET(ByteCount);
@ -554,7 +564,7 @@ NTSTATUS FspSafeMdlCreate(PMDL UserMdl, LOCK_OPERATION Operation, FSP_SAFE_MDL *
PAGED_CODE(); PAGED_CODE();
NTSTATUS Result; NTSTATUS Result;
PVOID VirtualAddress = MmGetMdlVirtualAddress(UserMdl); PVOID VirtualAddress = FspGetMdlAddress(UserMdl);
ULONG ByteCount = MmGetMdlByteCount(UserMdl); ULONG ByteCount = MmGetMdlByteCount(UserMdl);
ULONG PageCount = ADDRESS_AND_SIZE_TO_SPAN_PAGES(VirtualAddress, ByteCount); ULONG PageCount = ADDRESS_AND_SIZE_TO_SPAN_PAGES(VirtualAddress, ByteCount);
FSP_SAFE_MDL *SafeMdl; FSP_SAFE_MDL *SafeMdl;
@ -696,7 +706,7 @@ VOID FspSafeMdlCopyBack(FSP_SAFE_MDL *SafeMdl)
if (IoReadAccess == SafeMdl->Operation) if (IoReadAccess == SafeMdl->Operation)
return; return;
PVOID VirtualAddress = MmGetMdlVirtualAddress(SafeMdl->UserMdl); PVOID VirtualAddress = FspGetMdlAddress(SafeMdl->UserMdl);
ULONG ByteCount = MmGetMdlByteCount(SafeMdl->UserMdl); ULONG ByteCount = MmGetMdlByteCount(SafeMdl->UserMdl);
ULONG PageCount = ADDRESS_AND_SIZE_TO_SPAN_PAGES(VirtualAddress, ByteCount); ULONG PageCount = ADDRESS_AND_SIZE_TO_SPAN_PAGES(VirtualAddress, ByteCount);
ULONG ByteOffsetBgn0, ByteOffsetEnd0, ByteOffsetEnd1; ULONG ByteOffsetBgn0, ByteOffsetEnd0, ByteOffsetEnd1;