dll: FspFileSystemStopServiceIfNecessary

This commit is contained in:
Bill Zissimopoulos
2023-02-01 17:42:11 +00:00
parent da3a8aa229
commit 3aadaee511
10 changed files with 196 additions and 3 deletions

View File

@@ -1188,6 +1188,39 @@ namespace Fsp
{
return STATUS_INVALID_DEVICE_REQUEST;
}
/// <summary>
/// Inform the file system that its dispatcher has been stopped.
/// </summary>
/// <remarks>
/// <para>
/// Prior to WinFsp v2.0 the FSD would never unmount a file system volume unless
/// the user mode file system requested the unmount. Since WinFsp v2.0 it is possible
/// for the FSD to unmount a file system volume without an explicit user mode file system
/// request. For example, this happens when the FSD is being uninstalled.
/// </para><para>
/// A user mode file system can use this operation to determine when its dispatcher
/// has been stopped. The Normally parameter can be used to determine why the dispatcher
/// was stopped: it is TRUE when the file system is being stopped normally (i.e. via the
/// native FspFileSystemStopDispatcher) and FALSE otherwise.
/// </para><para>
/// A file system that uses the Service class infrastructure may use the
/// StopServiceIfNecessary method to correctly handle all cases. The base implementation
/// of this method calls the StopServiceIfNecessary method.
/// </para><para>
/// This operation is the last one that a file system will receive.
/// </para>
/// </remarks>
/// <param name="Normally">
/// TRUE if the file system is being stopped via the native FspFileSystemStopDispatcher.
/// FALSE if the file system is being stopped because of another reason such
/// as driver unload/uninstall.
/// </param>
/// <seealso cref="StopServiceIfNecessary"/>
public virtual void DispatcherStopped(
Boolean Normally)
{
StopServiceIfNecessary(Normally);
}
/* helpers */
/// <summary>
@@ -1483,6 +1516,10 @@ namespace Fsp
{
return FullEaInformation.PackedSize(EaName, EaValue, NeedEa);
}
public void StopServiceIfNecessary(Boolean Normally)
{
Api.FspFileSystemStopServiceIfNecessary(IntPtr.Zero, Normally);
}
}
}

View File

@@ -1426,6 +1426,21 @@ namespace Fsp
}
}
private static void DispatcherStopped(
IntPtr FileSystemPtr,
Boolean Normally)
{
FileSystemBase FileSystem = (FileSystemBase)Api.GetUserContext(FileSystemPtr);
try
{
FileSystem.DispatcherStopped(Normally);
}
catch (Exception ex)
{
ExceptionHandler(FileSystem, ex);
}
}
static FileSystemHost()
{
_FileSystemInterface.GetVolumeInfo = GetVolumeInfo;
@@ -1456,6 +1471,7 @@ namespace Fsp
_FileSystemInterface.SetDelete = SetDelete;
_FileSystemInterface.GetEa = GetEa;
_FileSystemInterface.SetEa = SetEa;
_FileSystemInterface.DispatcherStopped = DispatcherStopped;
_FileSystemInterfacePtr = Marshal.AllocHGlobal(FileSystemInterface.Size);
/* Marshal.AllocHGlobal does not zero memory; we must do it ourselves! */

View File

@@ -745,6 +745,10 @@ namespace Fsp.Interop
out FileInfo FileInfo);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate Int32 Obsolete0();
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate void DispatcherStopped(
IntPtr FileSystem,
[MarshalAs(UnmanagedType.U1)] Boolean Normally);
}
internal static int Size = IntPtr.Size * 64;
@@ -781,6 +785,7 @@ namespace Fsp.Interop
internal Proto.GetEa GetEa;
internal Proto.SetEa SetEa;
internal Proto.Obsolete0 Obsolete0;
internal Proto.DispatcherStopped DispatcherStopped;
/* NTSTATUS (*Reserved[33])(); */
}
@@ -907,6 +912,10 @@ namespace Fsp.Interop
UInt32 Length,
out UInt32 PBytesTransferred);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate void FspFileSystemStopServiceIfNecessary(
IntPtr FileSystem,
[MarshalAs(UnmanagedType.U1)] Boolean Normally);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.U1)]
internal delegate Boolean FspFileSystemAcquireDirectoryBuffer(
ref IntPtr PDirBuffer,
@@ -1048,6 +1057,7 @@ namespace Fsp.Interop
internal static Proto.FspFileSystemAddStreamInfo _FspFileSystemAddStreamInfo;
internal static Proto.FspFileSystemAddEa _FspFileSystemAddEa;
internal static Proto.FspFileSystemAddNotifyInfo _FspFileSystemAddNotifyInfo;
internal static Proto.FspFileSystemStopServiceIfNecessary FspFileSystemStopServiceIfNecessary;
internal static Proto.FspFileSystemAcquireDirectoryBuffer FspFileSystemAcquireDirectoryBuffer;
internal static Proto.FspFileSystemFillDirectoryBuffer FspFileSystemFillDirectoryBuffer;
internal static Proto.FspFileSystemReleaseDirectoryBuffer FspFileSystemReleaseDirectoryBuffer;
@@ -1506,6 +1516,7 @@ namespace Fsp.Interop
_FspFileSystemAddStreamInfo = GetEntryPoint<Proto.FspFileSystemAddStreamInfo>(Module);
_FspFileSystemAddEa = GetEntryPoint<Proto.FspFileSystemAddEa>(Module);
_FspFileSystemAddNotifyInfo = GetEntryPoint<Proto.FspFileSystemAddNotifyInfo>(Module);
FspFileSystemStopServiceIfNecessary = GetEntryPoint<Proto.FspFileSystemStopServiceIfNecessary>(Module);
FspFileSystemAcquireDirectoryBuffer = GetEntryPoint<Proto.FspFileSystemAcquireDirectoryBuffer>(Module);
FspFileSystemFillDirectoryBuffer = GetEntryPoint<Proto.FspFileSystemFillDirectoryBuffer>(Module);
FspFileSystemReleaseDirectoryBuffer = GetEntryPoint<Proto.FspFileSystemReleaseDirectoryBuffer>(Module);