diff --git a/src/sys/dirctl.c b/src/sys/dirctl.c index 9a113b10..fed067ff 100644 --- a/src/sys/dirctl.c +++ b/src/sys/dirctl.c @@ -729,7 +729,7 @@ NTSTATUS FspFsvolDirectoryControlPrepare( MmBuildMdlForNonPagedPool(Mdl); /* map the MDL into user-mode */ - Result = FspMapLockedPagesInUserMode(Mdl, &Address); + Result = FspMapLockedPagesInUserMode(Mdl, &Address, 0); if (!NT_SUCCESS(Result)) { if (0 != Mdl) diff --git a/src/sys/driver.c b/src/sys/driver.c index 6793228e..762759c5 100644 --- a/src/sys/driver.c +++ b/src/sys/driver.c @@ -165,14 +165,17 @@ NTSTATUS DriverEntry( static VOID FspDriverMultiVersionInitialize(VOID) { - UNICODE_STRING Name; - if (RtlIsNtDdiVersionAvailable(NTDDI_WIN7)) { + UNICODE_STRING Name; + RtlInitUnicodeString(&Name, L"CcCoherencyFlushAndPurgeCache"); FspMvCcCoherencyFlushAndPurgeCache = (FSP_MV_CcCoherencyFlushAndPurgeCache *)(UINT_PTR)MmGetSystemRoutineAddress(&Name); } + + if (RtlIsNtDdiVersionAvailable(NTDDI_WIN8)) + FspMvMdlMappingNoWrite = MdlMappingNoWrite; } #if defined(FSP_UNLOAD) @@ -201,3 +204,4 @@ FAST_IO_DISPATCH FspFastIoDispatch; CACHE_MANAGER_CALLBACKS FspCacheManagerCallbacks; FSP_MV_CcCoherencyFlushAndPurgeCache *FspMvCcCoherencyFlushAndPurgeCache; +ULONG FspMvMdlMappingNoWrite = 0; diff --git a/src/sys/driver.h b/src/sys/driver.h index 6fa026b9..cf98b8fa 100644 --- a/src/sys/driver.h +++ b/src/sys/driver.h @@ -419,7 +419,7 @@ NTSTATUS FspSendSetInformationIrp(PDEVICE_OBJECT DeviceObject, PFILE_OBJECT File FILE_INFORMATION_CLASS FileInformationClass, PVOID FileInformation, ULONG Length); NTSTATUS FspBufferUserBuffer(PIRP Irp, ULONG Length, LOCK_OPERATION Operation); NTSTATUS FspLockUserBuffer(PIRP Irp, ULONG Length, LOCK_OPERATION Operation); -NTSTATUS FspMapLockedPagesInUserMode(PMDL Mdl, PVOID *PAddress); +NTSTATUS FspMapLockedPagesInUserMode(PMDL Mdl, PVOID *PAddress, ULONG ExtraPriorityFlags); NTSTATUS FspCcInitializeCacheMap(PFILE_OBJECT FileObject, PCC_FILE_SIZES FileSizes, BOOLEAN PinAccess, PCACHE_MANAGER_CALLBACKS Callbacks, PVOID CallbackContext); NTSTATUS FspCcSetFileSizes(PFILE_OBJECT FileObject, PCC_FILE_SIZES FileSizes); @@ -1037,5 +1037,6 @@ extern FSP_IOCMPL_DISPATCH *FspIopCompleteFunction[]; extern ERESOURCE FspDeviceGlobalResource; extern WCHAR FspFileDescDirectoryPatternMatchAll[]; extern FSP_MV_CcCoherencyFlushAndPurgeCache *FspMvCcCoherencyFlushAndPurgeCache; +extern ULONG FspMvMdlMappingNoWrite; #endif diff --git a/src/sys/read.c b/src/sys/read.c index d8c2459e..4681e192 100644 --- a/src/sys/read.c +++ b/src/sys/read.c @@ -300,7 +300,8 @@ NTSTATUS FspFsvolReadPrepare( } /* map the MDL into user-mode */ - Result = FspMapLockedPagesInUserMode(0 != SafeMdl ? SafeMdl->Mdl : Irp->MdlAddress, &Address); + Result = FspMapLockedPagesInUserMode( + 0 != SafeMdl ? SafeMdl->Mdl : Irp->MdlAddress, &Address, 0); if (!NT_SUCCESS(Result)) { if (0 != SafeMdl) diff --git a/src/sys/util.c b/src/sys/util.c index e8218641..5a1d8fd4 100644 --- a/src/sys/util.c +++ b/src/sys/util.c @@ -15,7 +15,7 @@ static NTSTATUS FspSendSetInformationIrpCompletion( PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context0); NTSTATUS FspBufferUserBuffer(PIRP Irp, ULONG Length, LOCK_OPERATION Operation); NTSTATUS FspLockUserBuffer(PIRP Irp, ULONG Length, LOCK_OPERATION Operation); -NTSTATUS FspMapLockedPagesInUserMode(PMDL Mdl, PVOID *PAddress); +NTSTATUS FspMapLockedPagesInUserMode(PMDL Mdl, PVOID *PAddress, ULONG ExtraPriorityFlags); NTSTATUS FspCcInitializeCacheMap(PFILE_OBJECT FileObject, PCC_FILE_SIZES FileSizes, BOOLEAN PinAccess, PCACHE_MANAGER_CALLBACKS Callbacks, PVOID CallbackContext); NTSTATUS FspCcSetFileSizes(PFILE_OBJECT FileObject, PCC_FILE_SIZES FileSizes); @@ -355,13 +355,14 @@ NTSTATUS FspLockUserBuffer(PIRP Irp, ULONG Length, LOCK_OPERATION Operation) return STATUS_SUCCESS; } -NTSTATUS FspMapLockedPagesInUserMode(PMDL Mdl, PVOID *PAddress) +NTSTATUS FspMapLockedPagesInUserMode(PMDL Mdl, PVOID *PAddress, ULONG ExtraPriorityFlags) { PAGED_CODE(); try { - *PAddress = MmMapLockedPagesSpecifyCache(Mdl, UserMode, MmCached, 0, FALSE, NormalPagePriority); + *PAddress = MmMapLockedPagesSpecifyCache(Mdl, UserMode, MmCached, 0, FALSE, + NormalPagePriority | ExtraPriorityFlags); return 0 != *PAddress ? STATUS_SUCCESS : STATUS_INSUFFICIENT_RESOURCES; } except (EXCEPTION_EXECUTE_HANDLER) diff --git a/src/sys/write.c b/src/sys/write.c index f28539b6..7c9cae87 100644 --- a/src/sys/write.c +++ b/src/sys/write.c @@ -357,7 +357,8 @@ NTSTATUS FspFsvolWritePrepare( } /* map the MDL into user-mode */ - Result = FspMapLockedPagesInUserMode(0 != SafeMdl ? SafeMdl->Mdl : Irp->MdlAddress, &Address); + Result = FspMapLockedPagesInUserMode( + 0 != SafeMdl ? SafeMdl->Mdl : Irp->MdlAddress, &Address, FspMvMdlMappingNoWrite); if (!NT_SUCCESS(Result)) { if (0 != SafeMdl) diff --git a/tst/memfs/memfs.cpp b/tst/memfs/memfs.cpp index 7ae5adfc..a1513ffa 100644 --- a/tst/memfs/memfs.cpp +++ b/tst/memfs/memfs.cpp @@ -10,6 +10,14 @@ #include #include +/* + * Define the DEBUG_BUFFER_CHECK macro on Windows 8 or above. This includes + * a check for the Write buffer to ensure that it is read-only. + */ +#if !defined(NDEBUG) +#define DEBUG_BUFFER_CHECK +#endif + #define MEMFS_SECTOR_SIZE 512 #define MEMFS_SECTORS_PER_ALLOCATION_UNIT 1 @@ -501,6 +509,21 @@ static NTSTATUS Write(FSP_FILE_SYSTEM *FileSystem, BOOLEAN WriteToEndOfFile, BOOLEAN ConstrainedIo, PULONG PBytesTransferred, FSP_FSCTL_FILE_INFO *FileInfo) { +#if defined(DEBUG_BUFFER_CHECK) + SYSTEM_INFO SystemInfo; + GetSystemInfo(&SystemInfo); + for (PUINT8 P = (PUINT8)Buffer, EndP = P + Length; EndP > P; P += SystemInfo.dwPageSize) + __try + { + *P = *P | 0; + assert(0); + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + /* ignore! */ + } +#endif + MEMFS_FILE_NODE *FileNode = (MEMFS_FILE_NODE *)FileNode0; UINT64 EndOffset;