mirror of
https://github.com/winfsp/winfsp.git
synced 2025-04-22 08:23:05 -05:00
sys: notify implementation
This commit is contained in:
parent
7f360827f6
commit
88edf5723e
@ -1186,9 +1186,49 @@ FSP_API VOID FspFileSystemStopDispatcher(FSP_FILE_SYSTEM *FileSystem);
|
|||||||
*/
|
*/
|
||||||
FSP_API VOID FspFileSystemSendResponse(FSP_FILE_SYSTEM *FileSystem,
|
FSP_API VOID FspFileSystemSendResponse(FSP_FILE_SYSTEM *FileSystem,
|
||||||
FSP_FSCTL_TRANSACT_RSP *Response);
|
FSP_FSCTL_TRANSACT_RSP *Response);
|
||||||
|
/**
|
||||||
|
* Begin notifying Windows that the file system has file changes.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* @param FileSystem
|
||||||
|
* The file system object.
|
||||||
|
* @return
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
FSP_API NTSTATUS FspFileSystemNotifyBegin(FSP_FILE_SYSTEM *FileSystem, ULONG Timeout);
|
||||||
|
/**
|
||||||
|
* End notifying Windows that the file system has file changes.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* This operation allows any blocked file rename operations to proceed.
|
||||||
|
*
|
||||||
|
* @param FileSystem
|
||||||
|
* The file system object.
|
||||||
|
* @return
|
||||||
|
* STATUS_SUCCESS or error code.
|
||||||
|
*/
|
||||||
|
FSP_API NTSTATUS FspFileSystemNotifyEnd(FSP_FILE_SYSTEM *FileSystem);
|
||||||
/**
|
/**
|
||||||
* Notify Windows that the file system has file changes.
|
* Notify Windows that the file system has file changes.
|
||||||
*
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
* @param FileSystem
|
* @param FileSystem
|
||||||
* The file system object.
|
* The file system object.
|
||||||
* @param NotifyInfo
|
* @param NotifyInfo
|
||||||
|
46
src/dll/fs.c
46
src/dll/fs.c
@ -432,6 +432,52 @@ FSP_API FSP_FILE_SYSTEM_OPERATION_CONTEXT *FspFileSystemGetOperationContext(VOID
|
|||||||
return (FSP_FILE_SYSTEM_OPERATION_CONTEXT *)TlsGetValue(FspFileSystemTlsKey);
|
return (FSP_FILE_SYSTEM_OPERATION_CONTEXT *)TlsGetValue(FspFileSystemTlsKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FSP_API NTSTATUS FspFileSystemNotifyBegin(FSP_FILE_SYSTEM *FileSystem, ULONG Timeout)
|
||||||
|
{
|
||||||
|
static const ULONG Delays[] =
|
||||||
|
{
|
||||||
|
10/*ms*/,
|
||||||
|
10/*ms*/,
|
||||||
|
50/*ms*/,
|
||||||
|
50/*ms*/,
|
||||||
|
100/*ms*/,
|
||||||
|
100/*ms*/,
|
||||||
|
300/*ms*/,
|
||||||
|
};
|
||||||
|
ULONG Total = 0, Delay;
|
||||||
|
NTSTATUS Result;
|
||||||
|
|
||||||
|
for (ULONG i = 0, n = sizeof(Delays) / sizeof(Delays[0]);; i++)
|
||||||
|
{
|
||||||
|
Result = FspFsctlNotify(FileSystem->VolumeHandle, 0, 0);
|
||||||
|
if (STATUS_CANT_WAIT != Result)
|
||||||
|
return Result;
|
||||||
|
|
||||||
|
Delay = n > i ? Delays[i] : Delays[n - 1];
|
||||||
|
if (INFINITE == Timeout)
|
||||||
|
Sleep(Delay);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (Total >= Timeout)
|
||||||
|
break;
|
||||||
|
if (Total + Delay > Timeout)
|
||||||
|
Delay = Timeout - Total;
|
||||||
|
Total += Delay;
|
||||||
|
Sleep(Delay);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
FSP_API NTSTATUS FspFileSystemNotifyEnd(FSP_FILE_SYSTEM *FileSystem)
|
||||||
|
{
|
||||||
|
FSP_FSCTL_NOTIFY_INFO NotifyInfo;
|
||||||
|
|
||||||
|
memset(&NotifyInfo, 0, sizeof NotifyInfo);
|
||||||
|
return FspFsctlNotify(FileSystem->VolumeHandle, &NotifyInfo, sizeof NotifyInfo.Size);
|
||||||
|
}
|
||||||
|
|
||||||
FSP_API NTSTATUS FspFileSystemNotify(FSP_FILE_SYSTEM *FileSystem,
|
FSP_API NTSTATUS FspFileSystemNotify(FSP_FILE_SYSTEM *FileSystem,
|
||||||
FSP_FSCTL_NOTIFY_INFO *NotifyInfo, SIZE_T Size)
|
FSP_FSCTL_NOTIFY_INFO *NotifyInfo, SIZE_T Size)
|
||||||
{
|
{
|
||||||
|
@ -111,11 +111,52 @@ void notify_abandon_rename_test(void)
|
|||||||
notify_abandon_rename_dotest(MemfsNet, L"\\\\memfs\\share");
|
notify_abandon_rename_dotest(MemfsNet, L"\\\\memfs\\share");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
void notify_timeout_dotest(ULONG Flags)
|
||||||
|
{
|
||||||
|
void *memfs = memfs_start(Flags);
|
||||||
|
FSP_FILE_SYSTEM *FileSystem = MemfsFileSystem(memfs);
|
||||||
|
NTSTATUS Result;
|
||||||
|
|
||||||
|
Result = FspFsctlNotify(FileSystem->VolumeHandle, 0, 0);
|
||||||
|
ASSERT(STATUS_SUCCESS == Result);
|
||||||
|
|
||||||
|
Result = FspFileSystemNotifyBegin(FileSystem, 0);
|
||||||
|
ASSERT(STATUS_CANT_WAIT == Result);
|
||||||
|
|
||||||
|
Result = FspFileSystemNotifyBegin(FileSystem, 9);
|
||||||
|
ASSERT(STATUS_CANT_WAIT == Result);
|
||||||
|
|
||||||
|
Result = FspFileSystemNotifyBegin(FileSystem, 10);
|
||||||
|
ASSERT(STATUS_CANT_WAIT == Result);
|
||||||
|
|
||||||
|
Result = FspFileSystemNotifyBegin(FileSystem, 11);
|
||||||
|
ASSERT(STATUS_CANT_WAIT == Result);
|
||||||
|
|
||||||
|
Result = FspFileSystemNotifyBegin(FileSystem, 20);
|
||||||
|
ASSERT(STATUS_CANT_WAIT == Result);
|
||||||
|
|
||||||
|
Result = FspFileSystemNotifyBegin(FileSystem, 1000);
|
||||||
|
ASSERT(STATUS_CANT_WAIT == Result);
|
||||||
|
|
||||||
|
memfs_stop(memfs);
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
void notify_timeout_test(void)
|
||||||
|
{
|
||||||
|
if (WinFspDiskTests)
|
||||||
|
notify_timeout_dotest(MemfsDisk);
|
||||||
|
if (WinFspNetTests)
|
||||||
|
notify_timeout_dotest(MemfsNet);
|
||||||
|
}
|
||||||
|
|
||||||
void notify_tests(void)
|
void notify_tests(void)
|
||||||
{
|
{
|
||||||
if (!OptExternal)
|
if (!OptExternal)
|
||||||
{
|
{
|
||||||
TEST(notify_abandon_test);
|
TEST(notify_abandon_test);
|
||||||
TEST(notify_abandon_rename_test);
|
TEST(notify_abandon_rename_test);
|
||||||
|
TEST(notify_timeout_test);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user