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);