diff --git a/inc/winfsp/fsctl.h b/inc/winfsp/fsctl.h index a08ada78..69926f9e 100644 --- a/inc/winfsp/fsctl.h +++ b/inc/winfsp/fsctl.h @@ -166,7 +166,8 @@ enum UINT32 UmFileContextIsFullContext:1; /* user mode: FileContext parameter is FullContext */\ UINT32 UmReservedFlags:6;\ /* additional kernel-mode flags */\ - UINT32 KmReservedFlags:8;\ + UINT32 AllowOpenInKernelMode:1; /* allow kernel mode to open files when possible */\ + UINT32 KmReservedFlags:7;\ WCHAR Prefix[FSP_FSCTL_VOLUME_PREFIX_SIZE / sizeof(WCHAR)]; /* UNC prefix (\Server\Share) */\ WCHAR FileSystemName[FSP_FSCTL_VOLUME_FSNAME_SIZE / sizeof(WCHAR)]; #define FSP_FSCTL_VOLUME_PARAMS_V1_FIELD_DEFN\ diff --git a/src/dotnet/FileSystemHost.cs b/src/dotnet/FileSystemHost.cs index cbbca4e5..1bfd3d22 100644 --- a/src/dotnet/FileSystemHost.cs +++ b/src/dotnet/FileSystemHost.cs @@ -208,6 +208,11 @@ namespace Fsp get { return 0 != (_VolumeParams.Flags & VolumeParams.DeviceControl); } set { _VolumeParams.Flags |= (value ? VolumeParams.DeviceControl : 0); } } + public Boolean AllowOpenInKernelMode + { + get { return 0 != (_VolumeParams.Flags & VolumeParams.AllowOpenInKernelMode); } + set { _VolumeParams.Flags |= (value ? VolumeParams.AllowOpenInKernelMode : 0); } + } /// /// Gets or sets the prefix for a network file system. /// diff --git a/src/dotnet/Interop.cs b/src/dotnet/Interop.cs index 097ccb42..4e4d4829 100644 --- a/src/dotnet/Interop.cs +++ b/src/dotnet/Interop.cs @@ -51,6 +51,7 @@ namespace Fsp.Interop internal const UInt32 DeviceControl = 0x00008000; internal const UInt32 UmFileContextIsUserContext2 = 0x00010000; internal const UInt32 UmFileContextIsFullContext = 0x00020000; + internal const UInt32 AllowOpenInKernelMode = 0x01000000; internal const int PrefixSize = 192; internal const int FileSystemNameSize = 16; diff --git a/src/sys/fileinfo.c b/src/sys/fileinfo.c index aaaa2fb8..9835755a 100644 --- a/src/sys/fileinfo.c +++ b/src/sys/fileinfo.c @@ -1897,11 +1897,20 @@ BOOLEAN FspFastIoQueryOpen( PFILE_OBJECT FileObject = IrpSp->FileObject; FSP_FSCTL_FILE_INFO FileInfoBuf; - if (0 != FileObject->RelatedFileObject) - /* sorry, no can do relative opens in here */ + DeviceObject = IrpSp->DeviceObject; + + if (FspFsvolDeviceExtensionKind != FspDeviceExtension(DeviceObject)->Kind) FSP_RETURN(Result = FALSE); - Result = FspFileNodeTryGetFileInfoByName(IrpSp->DeviceObject, &FileObject->FileName, &FileInfoBuf); + /* do we allow kernel mode opens? */ + if (!FspFsvolDeviceExtension(DeviceObject)->VolumeParams.AllowOpenInKernelMode) + FSP_RETURN(Result = FALSE); + + /* is this a relative file open? */ + if (0 != FileObject->RelatedFileObject) + FSP_RETURN(Result = FALSE); + + Result = FspFileNodeTryGetFileInfoByName(DeviceObject, &FileObject->FileName, &FileInfoBuf); if (Result) { PVOID Buffer = Info;