diff --git a/tst/winfsp-tests/hooks.c b/tst/winfsp-tests/hooks.c index a4c44d25..b46d1812 100644 --- a/tst/winfsp-tests/hooks.c +++ b/tst/winfsp-tests/hooks.c @@ -19,6 +19,15 @@ * associated repository. */ +#define WIN32_NO_STATUS +#include +#undef WIN32_NO_STATUS +#include +#pragma warning(push) +#pragma warning(disable:4005) /* macro redefinition */ +#include +#pragma warning(pop) + #define WINFSP_TESTS_NO_HOOKS #include "winfsp-tests.h" #include @@ -266,6 +275,40 @@ static VOID MaybeAdjustTraversePrivilege(BOOL Enable) } } +NTSTATUS NTAPI HookNtCreateFile( + PHANDLE FileHandle, + ACCESS_MASK DesiredAccess, + POBJECT_ATTRIBUTES ObjectAttributes, + PIO_STATUS_BLOCK IoStatusBlock, + PLARGE_INTEGER AllocationSize, + ULONG FileAttributes, + ULONG ShareAccess, + ULONG CreateDisposition, + ULONG CreateOptions, + PVOID EaBuffer, + ULONG EaLength) +{ + return (OptResilient ? ResilientNtCreateFile : NtCreateFile)( + FileHandle, + DesiredAccess, + ObjectAttributes, + IoStatusBlock, + AllocationSize, + FileAttributes, + ShareAccess, + CreateDisposition, + CreateOptions, + EaBuffer, + EaLength); +} + +NTSTATUS NTAPI HookNtClose( + HANDLE Handle) +{ + return (OptResilient ? ResilientNtClose : NtClose)( + Handle); +} + HANDLE WINAPI HookCreateFileW( LPCWSTR lpFileName, DWORD dwDesiredAccess, diff --git a/tst/winfsp-tests/resilient.c b/tst/winfsp-tests/resilient.c index 90a770cf..ed955012 100644 --- a/tst/winfsp-tests/resilient.c +++ b/tst/winfsp-tests/resilient.c @@ -19,13 +19,94 @@ * associated repository. */ +#define WIN32_NO_STATUS #include +#undef WIN32_NO_STATUS +#include +#pragma warning(push) +#pragma warning(disable:4005) /* macro redefinition */ +#include +#pragma warning(pop) #define DeleteMaxTries 30 #define DeleteSleepTimeout 300 static VOID WaitDeletePending(PCWSTR FileName); +NTSTATUS NTAPI ResilientNtCreateFile( + PHANDLE PFileHandle, + ACCESS_MASK DesiredAccess, + POBJECT_ATTRIBUTES ObjectAttributes, + PIO_STATUS_BLOCK IoStatusBlock, + PLARGE_INTEGER AllocationSize, + ULONG FileAttributes, + ULONG ShareAccess, + ULONG CreateDisposition, + ULONG CreateOptions, + PVOID EaBuffer, + ULONG EaLength) +{ + DWORD LastError = GetLastError(); /* preserve last error */ + NTSTATUS Result; + + Result = NtCreateFile( + PFileHandle, + DesiredAccess, + ObjectAttributes, + IoStatusBlock, + AllocationSize, + FileAttributes, + ShareAccess, + CreateDisposition, + CreateOptions, + EaBuffer, + EaLength); + + if (NT_SUCCESS(Result) && + (FILE_DELETE_ON_CLOSE & CreateOptions)) + { + /* HACK: remember FILE_DELETE_ON_CLOSE through HANDLE_FLAG_PROTECT_FROM_CLOSE */ + SetHandleInformation(*PFileHandle, + HANDLE_FLAG_PROTECT_FROM_CLOSE, HANDLE_FLAG_PROTECT_FROM_CLOSE); + } + + SetLastError(LastError); + return Result; +} + +NTSTATUS NTAPI ResilientNtClose( + HANDLE Handle) +{ + DWORD LastError = GetLastError(); /* preserve last error */ + NTSTATUS Result; + DWORD HandleFlags = 0, FileNameLen; + WCHAR FileNameBuf[sizeof "\\\\?\\GLOBALROOT" - 1 + 1024] = L"\\\\?\\GLOBALROOT"; + + if (GetHandleInformation(Handle, &HandleFlags) && + (HANDLE_FLAG_PROTECT_FROM_CLOSE & HandleFlags)) + { + SetHandleInformation(Handle, + HANDLE_FLAG_PROTECT_FROM_CLOSE, 0); + FileNameLen = GetFinalPathNameByHandle(Handle, + FileNameBuf + sizeof "\\\\?\\GLOBALROOT" - 1, 1023, + FILE_NAME_OPENED | VOLUME_NAME_NT); + if (0 == FileNameLen || FileNameLen >= 1024) + HandleFlags = 0; + } + + Result = NtClose( + Handle); + + if (NT_SUCCESS(Result)) + { + if (HANDLE_FLAG_PROTECT_FROM_CLOSE & HandleFlags) + WaitDeletePending(FileNameBuf); + } + + SetLastError(LastError); + return Result; +} + HANDLE WINAPI ResilientCreateFileW( LPCWSTR lpFileName, DWORD dwDesiredAccess, diff --git a/tst/winfsp-tests/winfsp-tests.h b/tst/winfsp-tests/winfsp-tests.h index 92c1fcda..c44c00cd 100644 --- a/tst/winfsp-tests/winfsp-tests.h +++ b/tst/winfsp-tests/winfsp-tests.h @@ -32,6 +32,22 @@ #define testalpha(c) ('a' <= ((c) | 0x20) && ((c) | 0x20) <= 'z') #define togglealpha(c) ((c) ^ 0x20) +#if defined (_WINTERNL_) +NTSTATUS NTAPI HookNtCreateFile( + PHANDLE FileHandle, + ACCESS_MASK DesiredAccess, + POBJECT_ATTRIBUTES ObjectAttributes, + PIO_STATUS_BLOCK IoStatusBlock, + PLARGE_INTEGER AllocationSize, + ULONG FileAttributes, + ULONG ShareAccess, + ULONG CreateDisposition, + ULONG CreateOptions, + PVOID EaBuffer, + ULONG EaLength); +NTSTATUS NTAPI HookNtClose( + HANDLE Handle); +#endif HANDLE WINAPI HookCreateFileW( LPCWSTR lpFileName, DWORD dwDesiredAccess, @@ -106,6 +122,8 @@ BOOL WINAPI HookCreateProcessW( LPSTARTUPINFOW lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation); #if !defined(WINFSP_TESTS_NO_HOOKS) +#define NtCreateFile HookNtCreateFile +#define NtClose HookNtClose #define CreateFileW HookCreateFileW #define CloseHandle HookCloseHandle #define SetFileAttributesW HookSetFileAttributesW @@ -122,6 +140,22 @@ BOOL WINAPI HookCreateProcessW( #define CreateProcessW HookCreateProcessW #endif +#if defined (_WINTERNL_) +NTSTATUS NTAPI ResilientNtCreateFile( + PHANDLE FileHandle, + ACCESS_MASK DesiredAccess, + POBJECT_ATTRIBUTES ObjectAttributes, + PIO_STATUS_BLOCK IoStatusBlock, + PLARGE_INTEGER AllocationSize, + ULONG FileAttributes, + ULONG ShareAccess, + ULONG CreateDisposition, + ULONG CreateOptions, + PVOID EaBuffer, + ULONG EaLength); +NTSTATUS NTAPI ResilientNtClose( + HANDLE Handle); +#endif HANDLE WINAPI ResilientCreateFileW( LPCWSTR lpFileName, DWORD dwDesiredAccess,