mirror of
https://github.com/winfsp/winfsp.git
synced 2025-06-08 04:52:10 -05:00
dotnet: file change notification support
This commit is contained in:
parent
1b7a78edff
commit
5014e8bd35
@ -582,6 +582,75 @@ namespace Fsp
|
|||||||
Response.IoStatus.Status = (UInt32)Status;
|
Response.IoStatus.Status = (UInt32)Status;
|
||||||
Api.FspFileSystemSendResponse(_FileSystemPtr, ref Response);
|
Api.FspFileSystemSendResponse(_FileSystemPtr, ref Response);
|
||||||
}
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// Begin notifying Windows that the file system has file changes.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// <para>
|
||||||
|
/// A file system that wishes to notify Windows about file changes must
|
||||||
|
/// first issue an FspFileSystemBegin call, followed by 0 or more
|
||||||
|
/// FspFileSystemNotify calls, followed by an FspFileSystemNotifyEnd call.
|
||||||
|
/// </para><para>
|
||||||
|
/// This operation blocks concurrent file rename operations. File rename
|
||||||
|
/// operations may interfere with file notification, because a file being
|
||||||
|
/// notified may also be concurrently renamed. After all file change
|
||||||
|
/// notifications have been issued, you must make sure to call
|
||||||
|
/// FspFileSystemNotifyEnd to allow file rename operations to proceed.
|
||||||
|
/// </para>
|
||||||
|
/// </remarks>
|
||||||
|
/// <returns>
|
||||||
|
/// STATUS_SUCCESS or error code. The error code STATUS_CANT_WAIT means that
|
||||||
|
/// a file rename operation is currently in progress and the operation must be
|
||||||
|
/// retried at a later time.
|
||||||
|
/// </returns>
|
||||||
|
public Int32 NotifyBegin(UInt32 Timeout)
|
||||||
|
{
|
||||||
|
return Api.FspFileSystemNotifyBegin(_FileSystemPtr, Timeout);
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// End notifying Windows that the file system has file changes.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// <para>
|
||||||
|
/// A file system that wishes to notify Windows about file changes must
|
||||||
|
/// first issue an FspFileSystemBegin call, followed by 0 or more
|
||||||
|
/// FspFileSystemNotify calls, followed by an FspFileSystemNotifyEnd call.
|
||||||
|
/// </para><para>
|
||||||
|
/// This operation allows any blocked file rename operations to proceed.
|
||||||
|
/// </para>
|
||||||
|
/// </remarks>
|
||||||
|
/// <returns>STATUS_SUCCESS or error code.</returns>
|
||||||
|
public Int32 NotifyEnd()
|
||||||
|
{
|
||||||
|
return Api.FspFileSystemNotifyEnd(_FileSystemPtr);
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// Notify Windows that the file system has file changes.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// <para>
|
||||||
|
/// A file system that wishes to notify Windows about file changes must
|
||||||
|
/// first issue an FspFileSystemBegin call, followed by 0 or more
|
||||||
|
/// FspFileSystemNotify calls, followed by an FspFileSystemNotifyEnd call.
|
||||||
|
/// </para><para>
|
||||||
|
/// Note that FspFileSystemNotify requires file names to be normalized. A
|
||||||
|
/// normalized file name is one that contains the correct case of all characters
|
||||||
|
/// in the file name.
|
||||||
|
/// </para><para>
|
||||||
|
/// For case-sensitive file systems all file names are normalized by definition.
|
||||||
|
/// For case-insensitive file systems that implement file name normalization,
|
||||||
|
/// a normalized file name is the one that the file system specifies in the
|
||||||
|
/// response to Create or Open (see also FspFileSystemGetOpenFileInfo). For
|
||||||
|
/// case-insensitive file systems that do not implement file name normalization
|
||||||
|
/// a normalized file name is the upper case version of the file name used
|
||||||
|
/// to open the file.
|
||||||
|
/// </para>
|
||||||
|
/// </remarks>
|
||||||
|
/// <returns>STATUS_SUCCESS or error code.</returns>
|
||||||
|
public Int32 Notify(NotifyInfo[] NotifyInfoArray)
|
||||||
|
{
|
||||||
|
return Api.FspFileSystemNotify(_FileSystemPtr, NotifyInfoArray);
|
||||||
|
}
|
||||||
|
|
||||||
/* FSP_FILE_SYSTEM_INTERFACE */
|
/* FSP_FILE_SYSTEM_INTERFACE */
|
||||||
private static Byte[] ByteBufferNotNull = new Byte[0];
|
private static Byte[] ByteBufferNotNull = new Byte[0];
|
||||||
|
@ -310,6 +310,44 @@ namespace Fsp.Interop
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
internal struct NotifyInfoInternal
|
||||||
|
{
|
||||||
|
internal const int FileNameBufSize = 1024 * 2/*FSP_FSCTL_TRANSACT_PATH_SIZEMAX*/;
|
||||||
|
internal static int FileNameBufOffset =
|
||||||
|
(int)Marshal.OffsetOf(typeof(DirInfo), "FileNameBuf");
|
||||||
|
|
||||||
|
internal UInt16 Size;
|
||||||
|
internal UInt32 Filter;
|
||||||
|
internal UInt32 Action;
|
||||||
|
//internal unsafe fixed UInt16 FileNameBuf[];
|
||||||
|
internal unsafe fixed UInt16 FileNameBuf[FileNameBufSize];
|
||||||
|
|
||||||
|
internal unsafe void SetFileNameBuf(String Value)
|
||||||
|
{
|
||||||
|
fixed (UInt16 *P = FileNameBuf)
|
||||||
|
{
|
||||||
|
int Size = null != Value ? Value.Length : 0;
|
||||||
|
if (Size > FileNameBufSize)
|
||||||
|
Size = FileNameBufSize;
|
||||||
|
for (int I = 0; Size > I; I++)
|
||||||
|
P[I] = Value[I];
|
||||||
|
this.Size = (UInt16)(FileNameBufOffset + Size * 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Contains file change notification information.
|
||||||
|
/// </summary>
|
||||||
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
public struct NotifyInfo
|
||||||
|
{
|
||||||
|
public String FileName;
|
||||||
|
public UInt32 Action;
|
||||||
|
public UInt32 Filter;
|
||||||
|
}
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Sequential)]
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
internal struct FullEaInformation
|
internal struct FullEaInformation
|
||||||
{
|
{
|
||||||
@ -743,6 +781,18 @@ namespace Fsp.Interop
|
|||||||
IntPtr FileSystem,
|
IntPtr FileSystem,
|
||||||
ref FspFsctlTransactRsp Response);
|
ref FspFsctlTransactRsp Response);
|
||||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||||
|
internal delegate Int32 FspFileSystemNotifyBegin(
|
||||||
|
IntPtr FileSystem,
|
||||||
|
UInt32 Timeout);
|
||||||
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||||
|
internal delegate Int32 FspFileSystemNotifyEnd(
|
||||||
|
IntPtr FileSystem);
|
||||||
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||||
|
internal delegate Int32 FspFileSystemNotify(
|
||||||
|
IntPtr FileSystem,
|
||||||
|
IntPtr NotifyInfo,
|
||||||
|
UIntPtr Size);
|
||||||
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||||
internal unsafe delegate FspFileSystemOperationContext *FspFileSystemGetOperationContext();
|
internal unsafe delegate FspFileSystemOperationContext *FspFileSystemGetOperationContext();
|
||||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||||
internal delegate IntPtr FspFileSystemMountPointF(
|
internal delegate IntPtr FspFileSystemMountPointF(
|
||||||
@ -805,6 +855,13 @@ namespace Fsp.Interop
|
|||||||
out UInt32 PBytesTransferred);
|
out UInt32 PBytesTransferred);
|
||||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||||
[return: MarshalAs(UnmanagedType.U1)]
|
[return: MarshalAs(UnmanagedType.U1)]
|
||||||
|
internal delegate Boolean FspFileSystemAddNotifyInfo(
|
||||||
|
IntPtr NotifyInfo,
|
||||||
|
IntPtr Buffer,
|
||||||
|
UInt32 Length,
|
||||||
|
out UInt32 PBytesTransferred);
|
||||||
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||||
|
[return: MarshalAs(UnmanagedType.U1)]
|
||||||
internal delegate Boolean FspFileSystemAcquireDirectoryBuffer(
|
internal delegate Boolean FspFileSystemAcquireDirectoryBuffer(
|
||||||
ref IntPtr PDirBuffer,
|
ref IntPtr PDirBuffer,
|
||||||
[MarshalAs(UnmanagedType.U1)] Boolean Reset,
|
[MarshalAs(UnmanagedType.U1)] Boolean Reset,
|
||||||
@ -930,6 +987,9 @@ namespace Fsp.Interop
|
|||||||
internal static Proto.FspFileSystemStartDispatcher FspFileSystemStartDispatcher;
|
internal static Proto.FspFileSystemStartDispatcher FspFileSystemStartDispatcher;
|
||||||
internal static Proto.FspFileSystemStopDispatcher FspFileSystemStopDispatcher;
|
internal static Proto.FspFileSystemStopDispatcher FspFileSystemStopDispatcher;
|
||||||
internal static Proto.FspFileSystemSendResponse FspFileSystemSendResponse;
|
internal static Proto.FspFileSystemSendResponse FspFileSystemSendResponse;
|
||||||
|
internal static Proto.FspFileSystemNotifyBegin FspFileSystemNotifyBegin;
|
||||||
|
internal static Proto.FspFileSystemNotifyEnd FspFileSystemNotifyEnd;
|
||||||
|
internal static Proto.FspFileSystemNotify _FspFileSystemNotify;
|
||||||
internal static Proto.FspFileSystemGetOperationContext FspFileSystemGetOperationContext;
|
internal static Proto.FspFileSystemGetOperationContext FspFileSystemGetOperationContext;
|
||||||
internal static Proto.FspFileSystemMountPointF FspFileSystemMountPoint;
|
internal static Proto.FspFileSystemMountPointF FspFileSystemMountPoint;
|
||||||
internal static Proto.FspFileSystemSetOperationGuardStrategyF FspFileSystemSetOperationGuardStrategy;
|
internal static Proto.FspFileSystemSetOperationGuardStrategyF FspFileSystemSetOperationGuardStrategy;
|
||||||
@ -941,6 +1001,7 @@ namespace Fsp.Interop
|
|||||||
internal static Proto.FspFileSystemCanReplaceReparsePoint _FspFileSystemCanReplaceReparsePoint;
|
internal static Proto.FspFileSystemCanReplaceReparsePoint _FspFileSystemCanReplaceReparsePoint;
|
||||||
internal static Proto.FspFileSystemAddStreamInfo _FspFileSystemAddStreamInfo;
|
internal static Proto.FspFileSystemAddStreamInfo _FspFileSystemAddStreamInfo;
|
||||||
internal static Proto.FspFileSystemAddEa _FspFileSystemAddEa;
|
internal static Proto.FspFileSystemAddEa _FspFileSystemAddEa;
|
||||||
|
internal static Proto.FspFileSystemAddNotifyInfo _FspFileSystemAddNotifyInfo;
|
||||||
internal static Proto.FspFileSystemAcquireDirectoryBuffer FspFileSystemAcquireDirectoryBuffer;
|
internal static Proto.FspFileSystemAcquireDirectoryBuffer FspFileSystemAcquireDirectoryBuffer;
|
||||||
internal static Proto.FspFileSystemFillDirectoryBuffer FspFileSystemFillDirectoryBuffer;
|
internal static Proto.FspFileSystemFillDirectoryBuffer FspFileSystemFillDirectoryBuffer;
|
||||||
internal static Proto.FspFileSystemReleaseDirectoryBuffer FspFileSystemReleaseDirectoryBuffer;
|
internal static Proto.FspFileSystemReleaseDirectoryBuffer FspFileSystemReleaseDirectoryBuffer;
|
||||||
@ -1013,6 +1074,15 @@ namespace Fsp.Interop
|
|||||||
{
|
{
|
||||||
return _FspFileSystemAddStreamInfo(IntPtr.Zero, Buffer, Length, out PBytesTransferred);
|
return _FspFileSystemAddStreamInfo(IntPtr.Zero, Buffer, Length, out PBytesTransferred);
|
||||||
}
|
}
|
||||||
|
internal static unsafe Boolean FspFileSystemAddNotifyInfo(
|
||||||
|
ref NotifyInfoInternal NotifyInfo,
|
||||||
|
IntPtr Buffer,
|
||||||
|
UInt32 Length,
|
||||||
|
out UInt32 PBytesTransferred)
|
||||||
|
{
|
||||||
|
fixed (NotifyInfoInternal *P = &NotifyInfo)
|
||||||
|
return _FspFileSystemAddNotifyInfo((IntPtr)P, Buffer, Length, out PBytesTransferred);
|
||||||
|
}
|
||||||
|
|
||||||
internal delegate Int32 EnumerateEa(
|
internal delegate Int32 EnumerateEa(
|
||||||
Object FileNode,
|
Object FileNode,
|
||||||
@ -1070,6 +1140,34 @@ namespace Fsp.Interop
|
|||||||
return _FspFileSystemAddEa(IntPtr.Zero, Buffer, Length, out PBytesTransferred);
|
return _FspFileSystemAddEa(IntPtr.Zero, Buffer, Length, out PBytesTransferred);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal static unsafe Int32 FspFileSystemNotify(
|
||||||
|
IntPtr FileSystem,
|
||||||
|
NotifyInfo[] NotifyInfoArray)
|
||||||
|
{
|
||||||
|
int Length = 0;
|
||||||
|
for (int I = 0; NotifyInfoArray.Length > I; I++)
|
||||||
|
{
|
||||||
|
Length = (Length + 7) & ~7; // align to next qword boundary
|
||||||
|
Length += NotifyInfoInternal.FileNameBufOffset +
|
||||||
|
NotifyInfoArray[I].FileName.Length * 2;
|
||||||
|
}
|
||||||
|
Byte[] Buffer = new Byte[Length];
|
||||||
|
UInt32 BytesTransferred = default(UInt32);
|
||||||
|
fixed (Byte *P = Buffer)
|
||||||
|
{
|
||||||
|
for (int I = 0; NotifyInfoArray.Length > I; I++)
|
||||||
|
{
|
||||||
|
NotifyInfoInternal Internal = default(NotifyInfoInternal);
|
||||||
|
Internal.Action = NotifyInfoArray[I].Action;
|
||||||
|
Internal.Filter = NotifyInfoArray[I].Filter;
|
||||||
|
Internal.SetFileNameBuf(NotifyInfoArray[I].FileName);
|
||||||
|
FspFileSystemAddNotifyInfo(
|
||||||
|
ref Internal, (IntPtr)P, (UInt32)Length, out BytesTransferred);
|
||||||
|
}
|
||||||
|
return _FspFileSystemNotify(FileSystem, (IntPtr)P, (UIntPtr)BytesTransferred);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
internal unsafe static Object GetUserContext(
|
internal unsafe static Object GetUserContext(
|
||||||
IntPtr NativePtr)
|
IntPtr NativePtr)
|
||||||
{
|
{
|
||||||
@ -1330,6 +1428,9 @@ namespace Fsp.Interop
|
|||||||
FspFileSystemStartDispatcher = GetEntryPoint<Proto.FspFileSystemStartDispatcher>(Module);
|
FspFileSystemStartDispatcher = GetEntryPoint<Proto.FspFileSystemStartDispatcher>(Module);
|
||||||
FspFileSystemStopDispatcher = GetEntryPoint<Proto.FspFileSystemStopDispatcher>(Module);
|
FspFileSystemStopDispatcher = GetEntryPoint<Proto.FspFileSystemStopDispatcher>(Module);
|
||||||
FspFileSystemSendResponse = GetEntryPoint<Proto.FspFileSystemSendResponse>(Module);
|
FspFileSystemSendResponse = GetEntryPoint<Proto.FspFileSystemSendResponse>(Module);
|
||||||
|
FspFileSystemNotifyBegin = GetEntryPoint<Proto.FspFileSystemNotifyBegin>(Module);
|
||||||
|
FspFileSystemNotifyEnd = GetEntryPoint<Proto.FspFileSystemNotifyEnd>(Module);
|
||||||
|
_FspFileSystemNotify = GetEntryPoint<Proto.FspFileSystemNotify>(Module);
|
||||||
FspFileSystemGetOperationContext = GetEntryPoint<Proto.FspFileSystemGetOperationContext>(Module);
|
FspFileSystemGetOperationContext = GetEntryPoint<Proto.FspFileSystemGetOperationContext>(Module);
|
||||||
FspFileSystemMountPoint = GetEntryPoint<Proto.FspFileSystemMountPointF>(Module);
|
FspFileSystemMountPoint = GetEntryPoint<Proto.FspFileSystemMountPointF>(Module);
|
||||||
FspFileSystemSetOperationGuardStrategy = GetEntryPoint<Proto.FspFileSystemSetOperationGuardStrategyF>(Module);
|
FspFileSystemSetOperationGuardStrategy = GetEntryPoint<Proto.FspFileSystemSetOperationGuardStrategyF>(Module);
|
||||||
@ -1341,6 +1442,7 @@ namespace Fsp.Interop
|
|||||||
_FspFileSystemCanReplaceReparsePoint = GetEntryPoint<Proto.FspFileSystemCanReplaceReparsePoint>(Module);
|
_FspFileSystemCanReplaceReparsePoint = GetEntryPoint<Proto.FspFileSystemCanReplaceReparsePoint>(Module);
|
||||||
_FspFileSystemAddStreamInfo = GetEntryPoint<Proto.FspFileSystemAddStreamInfo>(Module);
|
_FspFileSystemAddStreamInfo = GetEntryPoint<Proto.FspFileSystemAddStreamInfo>(Module);
|
||||||
_FspFileSystemAddEa = GetEntryPoint<Proto.FspFileSystemAddEa>(Module);
|
_FspFileSystemAddEa = GetEntryPoint<Proto.FspFileSystemAddEa>(Module);
|
||||||
|
_FspFileSystemAddNotifyInfo = GetEntryPoint<Proto.FspFileSystemAddNotifyInfo>(Module);
|
||||||
FspFileSystemAcquireDirectoryBuffer = GetEntryPoint<Proto.FspFileSystemAcquireDirectoryBuffer>(Module);
|
FspFileSystemAcquireDirectoryBuffer = GetEntryPoint<Proto.FspFileSystemAcquireDirectoryBuffer>(Module);
|
||||||
FspFileSystemFillDirectoryBuffer = GetEntryPoint<Proto.FspFileSystemFillDirectoryBuffer>(Module);
|
FspFileSystemFillDirectoryBuffer = GetEntryPoint<Proto.FspFileSystemFillDirectoryBuffer>(Module);
|
||||||
FspFileSystemReleaseDirectoryBuffer = GetEntryPoint<Proto.FspFileSystemReleaseDirectoryBuffer>(Module);
|
FspFileSystemReleaseDirectoryBuffer = GetEntryPoint<Proto.FspFileSystemReleaseDirectoryBuffer>(Module);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user