|
|
|
@ -21,6 +21,7 @@
|
|
|
|
|
|
|
|
|
|
#define WINFSP_TESTS_NO_HOOKS
|
|
|
|
|
#include "winfsp-tests.h"
|
|
|
|
|
#include <winfsp/winfsp.h>
|
|
|
|
|
|
|
|
|
|
#define FILENAMEBUF_SIZE 1024
|
|
|
|
|
|
|
|
|
@ -107,6 +108,75 @@ static VOID PrepareFileName(PCWSTR FileName, PWSTR FileNameBuf)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
typedef struct
|
|
|
|
|
{
|
|
|
|
|
HANDLE VolumeHandle;
|
|
|
|
|
FSP_FSCTL_NOTIFY_INFO *NotifyInfo;
|
|
|
|
|
} MAYBE_NOTIFY_DATA;
|
|
|
|
|
|
|
|
|
|
static DWORD WINAPI MaybeNotifyRoutine(PVOID Context)
|
|
|
|
|
{
|
|
|
|
|
MAYBE_NOTIFY_DATA *NotifyData = Context;
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* The supplied VolumeHandle may be invalid or refer to the wrong object.
|
|
|
|
|
* This is ok because:
|
|
|
|
|
*
|
|
|
|
|
* - If the VolumeHandle is invalid, Windows will catch it and will fail the operation.
|
|
|
|
|
* - If the VolumeHandle refers to the wrong object, the FspFsctlNotify "should" fail
|
|
|
|
|
* because of an unknown DeviceIoControl code.
|
|
|
|
|
* - If the VolumeHandle refers to the wrong file system, it is still ok if we send an
|
|
|
|
|
* extraneous notify.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
FspFsctlNotify(NotifyData->VolumeHandle,
|
|
|
|
|
NotifyData->NotifyInfo, NotifyData->NotifyInfo->Size);
|
|
|
|
|
|
|
|
|
|
HeapFree(GetProcessHeap(), 0, NotifyData->NotifyInfo);
|
|
|
|
|
HeapFree(GetProcessHeap(), 0, NotifyData);
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static VOID MaybeNotify(PWSTR FileName, ULONG Filter, ULONG Action)
|
|
|
|
|
{
|
|
|
|
|
static WCHAR DevicePrefix[] =
|
|
|
|
|
L"\\\\?\\GLOBALROOT\\Device\\Volume{01234567-0123-0123-0101-010101010101}";
|
|
|
|
|
static WCHAR MemfsSharePrefix[] =
|
|
|
|
|
L"\\\\memfs\\share";
|
|
|
|
|
MAYBE_NOTIFY_DATA *NotifyData;
|
|
|
|
|
FSP_FSCTL_NOTIFY_INFO *NotifyInfo;
|
|
|
|
|
size_t L;
|
|
|
|
|
|
|
|
|
|
if (!OptNotify || OptExternal || 0 == memfs_handle)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
if (0 == wcsncmp(FileName, DevicePrefix, wcschr(DevicePrefix, L'{') - DevicePrefix))
|
|
|
|
|
FileName += wcslen(DevicePrefix);
|
|
|
|
|
else if (0 == mywcscmp(
|
|
|
|
|
FileName, (int)wcslen(MemfsSharePrefix), MemfsSharePrefix, (int)wcslen(MemfsSharePrefix)))
|
|
|
|
|
FileName += wcslen(MemfsSharePrefix);
|
|
|
|
|
else
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
L = wcslen(FileName);
|
|
|
|
|
NotifyData = HeapAlloc(GetProcessHeap(), 0, sizeof *NotifyData);
|
|
|
|
|
NotifyInfo = HeapAlloc(GetProcessHeap(), 0, sizeof *NotifyInfo + L * sizeof(WCHAR));
|
|
|
|
|
if (0 == NotifyData || 0 == NotifyInfo)
|
|
|
|
|
ABORT("cannot malloc notify data");
|
|
|
|
|
|
|
|
|
|
NotifyInfo->Size = (UINT16)(sizeof *NotifyInfo + L * sizeof(WCHAR));
|
|
|
|
|
NotifyInfo->Filter = Filter;
|
|
|
|
|
NotifyInfo->Action = Action;
|
|
|
|
|
memcpy(NotifyInfo->FileNameBuf, FileName, L * sizeof(WCHAR));
|
|
|
|
|
|
|
|
|
|
NotifyData->VolumeHandle = memfs_handle;
|
|
|
|
|
NotifyData->NotifyInfo = NotifyInfo;
|
|
|
|
|
|
|
|
|
|
if (!QueueUserWorkItem(MaybeNotifyRoutine, NotifyData, 0))
|
|
|
|
|
ABORT("cannot queue notify data");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
typedef struct
|
|
|
|
|
{
|
|
|
|
|
HANDLE File;
|
|
|
|
@ -210,6 +280,9 @@ HANDLE WINAPI HookCreateFileW(
|
|
|
|
|
|
|
|
|
|
PrepareFileName(lpFileName, FileNameBuf);
|
|
|
|
|
|
|
|
|
|
MaybeNotify(FileNameBuf,
|
|
|
|
|
FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE, FILE_ACTION_MODIFIED);
|
|
|
|
|
|
|
|
|
|
MaybeRequestOplock(FileNameBuf);
|
|
|
|
|
|
|
|
|
|
MaybeAdjustTraversePrivilege(FALSE);
|
|
|
|
@ -241,6 +314,9 @@ BOOL WINAPI HookSetFileAttributesW(
|
|
|
|
|
|
|
|
|
|
PrepareFileName(lpFileName, FileNameBuf);
|
|
|
|
|
|
|
|
|
|
MaybeNotify(FileNameBuf,
|
|
|
|
|
FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE, FILE_ACTION_MODIFIED);
|
|
|
|
|
|
|
|
|
|
MaybeAdjustTraversePrivilege(FALSE);
|
|
|
|
|
Success = SetFileAttributesW(FileNameBuf, dwFileAttributes);
|
|
|
|
|
MaybeAdjustTraversePrivilege(TRUE);
|
|
|
|
@ -256,6 +332,9 @@ BOOL WINAPI HookCreateDirectoryW(
|
|
|
|
|
|
|
|
|
|
PrepareFileName(lpPathName, FileNameBuf);
|
|
|
|
|
|
|
|
|
|
MaybeNotify(FileNameBuf,
|
|
|
|
|
FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE, FILE_ACTION_MODIFIED);
|
|
|
|
|
|
|
|
|
|
MaybeAdjustTraversePrivilege(FALSE);
|
|
|
|
|
Success = CreateDirectoryW(FileNameBuf, lpSecurityAttributes);
|
|
|
|
|
MaybeAdjustTraversePrivilege(TRUE);
|
|
|
|
@ -270,6 +349,9 @@ BOOL WINAPI HookDeleteFileW(
|
|
|
|
|
|
|
|
|
|
PrepareFileName(lpFileName, FileNameBuf);
|
|
|
|
|
|
|
|
|
|
MaybeNotify(FileNameBuf,
|
|
|
|
|
FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE, FILE_ACTION_MODIFIED);
|
|
|
|
|
|
|
|
|
|
MaybeRequestOplock(FileNameBuf);
|
|
|
|
|
|
|
|
|
|
MaybeAdjustTraversePrivilege(FALSE);
|
|
|
|
@ -287,6 +369,9 @@ BOOL WINAPI HookRemoveDirectoryW(
|
|
|
|
|
|
|
|
|
|
PrepareFileName(lpPathName, FileNameBuf);
|
|
|
|
|
|
|
|
|
|
MaybeNotify(FileNameBuf,
|
|
|
|
|
FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE, FILE_ACTION_MODIFIED);
|
|
|
|
|
|
|
|
|
|
MaybeAdjustTraversePrivilege(FALSE);
|
|
|
|
|
Success = (OptResilient ? ResilientRemoveDirectoryW : RemoveDirectoryW)(
|
|
|
|
|
FileNameBuf);
|
|
|
|
@ -306,6 +391,13 @@ BOOL WINAPI HookMoveFileExW(
|
|
|
|
|
PrepareFileName(lpExistingFileName, OldFileNameBuf);
|
|
|
|
|
PrepareFileName(lpNewFileName, NewFileNameBuf);
|
|
|
|
|
|
|
|
|
|
MaybeNotify(OldFileNameBuf,
|
|
|
|
|
FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE, FILE_ACTION_MODIFIED);
|
|
|
|
|
if (OptCaseInsensitive ?
|
|
|
|
|
_wcsicmp(OldFileNameBuf, NewFileNameBuf) : wcscmp(OldFileNameBuf, NewFileNameBuf))
|
|
|
|
|
MaybeNotify(NewFileNameBuf,
|
|
|
|
|
FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE, FILE_ACTION_MODIFIED);
|
|
|
|
|
|
|
|
|
|
MaybeRequestOplock(OldFileNameBuf);
|
|
|
|
|
if (OptCaseInsensitive ?
|
|
|
|
|
_wcsicmp(OldFileNameBuf, NewFileNameBuf) : wcscmp(OldFileNameBuf, NewFileNameBuf))
|
|
|
|
@ -326,6 +418,9 @@ HANDLE WINAPI HookFindFirstFileW(
|
|
|
|
|
|
|
|
|
|
PrepareFileName(lpFileName, FileNameBuf);
|
|
|
|
|
|
|
|
|
|
MaybeNotify(FileNameBuf,
|
|
|
|
|
FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE, FILE_ACTION_MODIFIED);
|
|
|
|
|
|
|
|
|
|
MaybeAdjustTraversePrivilege(FALSE);
|
|
|
|
|
Handle = FindFirstFileW(FileNameBuf, lpFindFileData);
|
|
|
|
|
MaybeAdjustTraversePrivilege(TRUE);
|
|
|
|
@ -343,6 +438,9 @@ HANDLE WINAPI HookFindFirstStreamW(
|
|
|
|
|
|
|
|
|
|
PrepareFileName(lpFileName, FileNameBuf);
|
|
|
|
|
|
|
|
|
|
MaybeNotify(FileNameBuf,
|
|
|
|
|
FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE, FILE_ACTION_MODIFIED);
|
|
|
|
|
|
|
|
|
|
MaybeAdjustTraversePrivilege(FALSE);
|
|
|
|
|
Handle = FindFirstStreamW(FileNameBuf, InfoLevel, lpFindStreamData, dwFlags);
|
|
|
|
|
MaybeAdjustTraversePrivilege(TRUE);
|
|
|
|
@ -426,6 +524,9 @@ BOOL WINAPI HookSetCurrentDirectoryW(
|
|
|
|
|
|
|
|
|
|
PrepareFileName(lpPathName, FileNameBuf);
|
|
|
|
|
|
|
|
|
|
MaybeNotify(FileNameBuf,
|
|
|
|
|
FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE, FILE_ACTION_MODIFIED);
|
|
|
|
|
|
|
|
|
|
MaybeAdjustTraversePrivilege(FALSE);
|
|
|
|
|
Success = SetCurrentDirectoryW(FileNameBuf);
|
|
|
|
|
MaybeAdjustTraversePrivilege(TRUE);
|
|
|
|
@ -449,6 +550,9 @@ BOOL WINAPI HookCreateProcessW(
|
|
|
|
|
|
|
|
|
|
PrepareFileName(lpApplicationName, FileNameBuf);
|
|
|
|
|
|
|
|
|
|
MaybeNotify(FileNameBuf,
|
|
|
|
|
FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE, FILE_ACTION_MODIFIED);
|
|
|
|
|
|
|
|
|
|
MaybeAdjustTraversePrivilege(FALSE);
|
|
|
|
|
Success = CreateProcessW(FileNameBuf,
|
|
|
|
|
lpCommandLine, /* we should probably change this as well */
|
|
|
|
|