From 290896b01007b326936ecb2e4b3002b5159abe5d Mon Sep 17 00:00:00 2001 From: "Felix A. Croes" Date: Mon, 13 May 2019 09:47:59 +0200 Subject: [PATCH] Add asyncronous support for dotnet. --- src/dotnet/FileSystemHost.cs | 83 ++++++++++++++++++++++++++++++++++++ src/dotnet/Interop.cs | 75 ++++++++++++++++++++++++++++++++ 2 files changed, 158 insertions(+) diff --git a/src/dotnet/FileSystemHost.cs b/src/dotnet/FileSystemHost.cs index ace67292..3f8bd2fb 100644 --- a/src/dotnet/FileSystemHost.cs +++ b/src/dotnet/FileSystemHost.cs @@ -381,6 +381,89 @@ namespace Fsp { return Api.GetVersion(); } + /// + /// Returns a RequestHint to reference the current operation asynchronously. + /// + public UInt64 GetOperationRequestHint() + { + return Api.FspFileSystemGetOperationRequestHint(); + } + /// + /// Asynchronously complete a Write operation. + /// + /// + /// A reference to the operation to complete. + /// + /// + /// STATUS_SUCCESS or error code. + /// + /// + /// The number of bytes written. + /// + /// + /// Updated file information. + /// + public void SendWriteResponse(UInt64 RequestHint, UInt32 Status, UInt32 BytesTransferred, ref FileInfo FileInfo) + { + var Response = new FspFsctlTransactRsp() + { + Size = 128, + Kind = (UInt32) FspFsctlTransact.WriteKind, + Hint = RequestHint + }; + Response.IoStatus.Information = BytesTransferred; + Response.IoStatus.Status = Status; + Response.WriteFileInfo = FileInfo; + Api.FspFileSystemSendResponse(_FileSystemPtr, ref Response); + } + /// + /// Asynchronously complete a Read operation. + /// + /// + /// A reference to the operation to complete. + /// + /// + /// STATUS_SUCCESS or error code. + /// + /// + /// Number of bytes read. + /// + public void SendReadResponse(UInt64 RequestHint, UInt32 Status, UInt32 BytesTransferred) + { + var Response = new FspFsctlTransactRsp() + { + Size = 128, + Kind = (UInt32) FspFsctlTransact.ReadKind, + Hint = RequestHint + }; + Response.IoStatus.Information = BytesTransferred; + Response.IoStatus.Status = Status; + Api.FspFileSystemSendResponse(_FileSystemPtr, ref Response); + } + /// + /// Asynchronously complete a ReadDirectory operation. + /// + /// + /// A reference to the operation to complete. + /// + /// + /// STATUS_SUCCESS or error code. + /// + /// + /// Number of bytes read. + /// + public void SendReadDirectoryResponse(UInt64 RequestHint, UInt32 Status, UInt32 BytesTransferred) + { + var Response = new FspFsctlTransactRsp() + { + Size = 128, + Kind = (UInt32) FspFsctlTransact.QueryDirectoryKind, + Hint = RequestHint + }; + Response.IoStatus.Information = BytesTransferred; + Response.IoStatus.Status = Status; + Api.FspFileSystemSendResponse(_FileSystemPtr, ref Response); + } /* FSP_FILE_SYSTEM_INTERFACE */ private static Byte[] ByteBufferNotNull = new Byte[0]; diff --git a/src/dotnet/Interop.cs b/src/dotnet/Interop.cs index a6b41ddf..08079c92 100644 --- a/src/dotnet/Interop.cs +++ b/src/dotnet/Interop.cs @@ -354,6 +354,65 @@ namespace Fsp.Interop public IntPtr Information; } + [StructLayout(LayoutKind.Sequential)] + internal struct IoStatus + { + internal UInt32 Information; + internal UInt32 Status; + } + + internal enum FspFsctlTransact + { + ReadKind = 5, + WriteKind = 6, + QueryDirectoryKind = 14 + } + + [StructLayout(LayoutKind.Explicit)] + internal struct FspFsctlTransactReq + { + [FieldOffset(0)] + internal UInt16 Version; + [FieldOffset(2)] + internal UInt16 Size; + [FieldOffset(4)] + internal UInt32 Kind; + [FieldOffset(8)] + internal UInt64 Hint; + + [FieldOffset(0)] + internal unsafe fixed Byte Padding[88]; + } + + [StructLayout(LayoutKind.Explicit)] + internal struct FspFsctlTransactRsp + { + [FieldOffset(0)] + internal UInt16 Version; + [FieldOffset(2)] + internal UInt16 Size; + [FieldOffset(4)] + internal UInt32 Kind; + [FieldOffset(8)] + internal UInt64 Hint; + + [FieldOffset(16)] + internal IoStatus IoStatus; + + [FieldOffset(24)] + internal FileInfo WriteFileInfo; + + [FieldOffset(0)] + internal unsafe fixed Byte Padding[128]; + } + + [StructLayout(LayoutKind.Sequential)] + internal unsafe struct FspFileSystemOperationContext + { + internal FspFsctlTransactReq *Request; + internal FspFsctlTransactRsp *Response; + } + [StructLayout(LayoutKind.Sequential)] internal struct FileSystemInterface { @@ -662,6 +721,12 @@ namespace Fsp.Interop internal delegate Int32 FspFileSystemStopDispatcher( IntPtr FileSystem); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate void FspFileSystemSendResponse( + IntPtr FileSystem, + ref FspFsctlTransactRsp Response); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate ref FspFileSystemOperationContext FspFileSystemGetOperationContext(); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate IntPtr FspFileSystemMountPointF( IntPtr FileSystem); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] @@ -846,6 +911,8 @@ namespace Fsp.Interop internal static Proto.FspFileSystemRemoveMountPoint FspFileSystemRemoveMountPoint; internal static Proto.FspFileSystemStartDispatcher FspFileSystemStartDispatcher; internal static Proto.FspFileSystemStopDispatcher FspFileSystemStopDispatcher; + internal static Proto.FspFileSystemSendResponse FspFileSystemSendResponse; + internal static Proto.FspFileSystemGetOperationContext FspFileSystemGetOperationContext; internal static Proto.FspFileSystemMountPointF FspFileSystemMountPoint; internal static Proto.FspFileSystemSetOperationGuardStrategyF FspFileSystemSetOperationGuardStrategy; internal static Proto.FspFileSystemSetDebugLogF FspFileSystemSetDebugLog; @@ -892,6 +959,12 @@ namespace Fsp.Interop else return _FspFileSystemSetMountPointEx(FileSystem, MountPoint, IntPtr.Zero); } + internal static unsafe UInt64 FspFileSystemGetOperationRequestHint() + { + FspFileSystemOperationContext Context = FspFileSystemGetOperationContext(); + FspFsctlTransactReq Request = *Context.Request; + return Request.Hint; + } internal static unsafe Boolean FspFileSystemAddDirInfo( ref DirInfo DirInfo, IntPtr Buffer, @@ -1240,6 +1313,8 @@ namespace Fsp.Interop FspFileSystemRemoveMountPoint = GetEntryPoint(Module); FspFileSystemStartDispatcher = GetEntryPoint(Module); FspFileSystemStopDispatcher = GetEntryPoint(Module); + FspFileSystemSendResponse = GetEntryPoint(Module); + FspFileSystemGetOperationContext = GetEntryPoint(Module); FspFileSystemMountPoint = GetEntryPoint(Module); FspFileSystemSetOperationGuardStrategy = GetEntryPoint(Module); FspFileSystemSetDebugLog = GetEntryPoint(Module);