From 637a1dac7ec32a2aba81d6221a78af238c1c9e5e Mon Sep 17 00:00:00 2001 From: Bill Zissimopoulos Date: Fri, 4 May 2018 14:51:48 -0700 Subject: [PATCH] dotnet: implement Control operation --- src/dotnet/FileSystemBase.cs | 43 ++++++++++++++++++++++++++++++++++++ src/dotnet/FileSystemHost.cs | 30 +++++++++++++++++++++++++ src/dotnet/Interop.cs | 11 ++++++++- 3 files changed, 83 insertions(+), 1 deletion(-) diff --git a/src/dotnet/FileSystemBase.cs b/src/dotnet/FileSystemBase.cs index e66da75a..e208abd9 100644 --- a/src/dotnet/FileSystemBase.cs +++ b/src/dotnet/FileSystemBase.cs @@ -966,6 +966,49 @@ namespace Fsp FileInfo = default(FileInfo); return STATUS_INVALID_DEVICE_REQUEST; } + /// + /// Processes a control code. + /// + /// + /// This function is called when a program uses the DeviceIoControl API. + /// + /// + /// The file node of the file or directory to be controled. + /// + /// + /// The file descriptor of the file or directory to be controled. + /// + /// + /// The control code for the operation. This code must have a DeviceType with bit + /// 0x8000 set and must have a TransferType of METHOD_BUFFERED. + /// + /// + /// Pointer to a buffer that contains the input data. + /// + /// + /// Input data length. + /// + /// + /// Pointer to a buffer that will receive the output data. + /// + /// + /// Output data length. + /// + /// + /// Receives the actual number of bytes transferred. + /// + /// STATUS_SUCCESS or error code. + public virtual Int32 Control( + Object FileNode, + Object FileDesc, + UInt32 ControlCode, + IntPtr InputBuffer, UInt32 InputBufferLength, + IntPtr OutputBuffer, UInt32 OutputBufferLength, + out UInt32 BytesTransferred) + { + BytesTransferred = default(UInt32); + return STATUS_INVALID_DEVICE_REQUEST; + } /* helpers */ /// diff --git a/src/dotnet/FileSystemHost.cs b/src/dotnet/FileSystemHost.cs index d98ad582..55a14c2c 100644 --- a/src/dotnet/FileSystemHost.cs +++ b/src/dotnet/FileSystemHost.cs @@ -1020,6 +1020,35 @@ namespace Fsp return ExceptionHandler(FileSystem, ex); } } + private static Int32 Control( + IntPtr FileSystemPtr, + ref FullContext FullContext, + UInt32 ControlCode, + IntPtr InputBuffer, UInt32 InputBufferLength, + IntPtr OutputBuffer, UInt32 OutputBufferLength, + out UInt32 PBytesTransferred) + { + FileSystemBase FileSystem = (FileSystemBase)Api.GetUserContext(FileSystemPtr); + try + { + Object FileNode, FileDesc; + Api.GetFullContext(ref FullContext, out FileNode, out FileDesc); + return FileSystem.Control( + FileNode, + FileDesc, + ControlCode, + InputBuffer, + InputBufferLength, + OutputBuffer, + OutputBufferLength, + out PBytesTransferred); + } + catch (Exception ex) + { + PBytesTransferred = default(UInt32); + return ExceptionHandler(FileSystem, ex); + } + } static FileSystemHost() { @@ -1048,6 +1077,7 @@ namespace Fsp _FileSystemInterface.DeleteReparsePoint = DeleteReparsePoint; _FileSystemInterface.GetStreamInfo = GetStreamInfo; _FileSystemInterface.GetDirInfoByName = GetDirInfoByName; + _FileSystemInterface.Control = Control; _FileSystemInterfacePtr = Marshal.AllocHGlobal(FileSystemInterface.Size); Marshal.StructureToPtr(_FileSystemInterface, _FileSystemInterfacePtr, false); diff --git a/src/dotnet/Interop.cs b/src/dotnet/Interop.cs index c9a7c95b..c81e9b67 100644 --- a/src/dotnet/Interop.cs +++ b/src/dotnet/Interop.cs @@ -457,6 +457,14 @@ namespace Fsp.Interop ref FullContext FullContext, [MarshalAs(UnmanagedType.LPWStr)] String FileName, out DirInfo DirInfo); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate Int32 Control( + IntPtr FileSystem, + ref FullContext FullContext, + UInt32 ControlCode, + IntPtr InputBuffer, UInt32 InputBufferLength, + IntPtr OutputBuffer, UInt32 OutputBufferLength, + out UInt32 PBytesTransferred); } internal static int Size = IntPtr.Size * 64; @@ -486,7 +494,8 @@ namespace Fsp.Interop internal Proto.DeleteReparsePoint DeleteReparsePoint; internal Proto.GetStreamInfo GetStreamInfo; internal Proto.GetDirInfoByName GetDirInfoByName; - /* NTSTATUS (*Reserved[39])(); */ + internal Proto.Control Control; + /* NTSTATUS (*Reserved[38])(); */ } [SuppressUnmanagedCodeSecurity]