mirror of
https://github.com/winfsp/winfsp.git
synced 2025-06-08 04:52:10 -05:00
tst: winfsp-tests: --resilient command line option
This commit is contained in:
parent
3f79b2e46d
commit
badaf82462
@ -194,6 +194,7 @@
|
|||||||
<ClCompile Include="..\..\..\tst\winfsp-tests\posix-test.c" />
|
<ClCompile Include="..\..\..\tst\winfsp-tests\posix-test.c" />
|
||||||
<ClCompile Include="..\..\..\tst\winfsp-tests\rdwr-test.c" />
|
<ClCompile Include="..\..\..\tst\winfsp-tests\rdwr-test.c" />
|
||||||
<ClCompile Include="..\..\..\tst\winfsp-tests\reparse-test.c" />
|
<ClCompile Include="..\..\..\tst\winfsp-tests\reparse-test.c" />
|
||||||
|
<ClCompile Include="..\..\..\tst\winfsp-tests\resilient.c" />
|
||||||
<ClCompile Include="..\..\..\tst\winfsp-tests\security-test.c" />
|
<ClCompile Include="..\..\..\tst\winfsp-tests\security-test.c" />
|
||||||
<ClCompile Include="..\..\..\tst\winfsp-tests\stream-tests.c" />
|
<ClCompile Include="..\..\..\tst\winfsp-tests\stream-tests.c" />
|
||||||
<ClCompile Include="..\..\..\tst\winfsp-tests\timeout-test.c" />
|
<ClCompile Include="..\..\..\tst\winfsp-tests\timeout-test.c" />
|
||||||
|
@ -67,6 +67,9 @@
|
|||||||
<ClCompile Include="..\..\..\tst\winfsp-tests\stream-tests.c">
|
<ClCompile Include="..\..\..\tst\winfsp-tests\stream-tests.c">
|
||||||
<Filter>Source</Filter>
|
<Filter>Source</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\..\tst\winfsp-tests\resilient.c">
|
||||||
|
<Filter>Source</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="..\..\..\ext\tlib\testsuite.h">
|
<ClInclude Include="..\..\..\ext\tlib\testsuite.h">
|
||||||
|
134
tst/winfsp-tests/resilient.c
Normal file
134
tst/winfsp-tests/resilient.c
Normal file
@ -0,0 +1,134 @@
|
|||||||
|
/**
|
||||||
|
* @file tst/resilient.c
|
||||||
|
*
|
||||||
|
* @copyright 2015-2016 Bill Zissimopoulos
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* This file is part of WinFsp.
|
||||||
|
*
|
||||||
|
* You can redistribute it and/or modify it under the terms of the GNU
|
||||||
|
* General Public License version 3 as published by the Free Software
|
||||||
|
* Foundation.
|
||||||
|
*
|
||||||
|
* Licensees holding a valid commercial license may use this file in
|
||||||
|
* accordance with the commercial license agreement provided with the
|
||||||
|
* software.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
#define DeleteMaxTries 30
|
||||||
|
#define DeleteSleepTimeout 300
|
||||||
|
|
||||||
|
static VOID WaitDeletePending(PCWSTR FileName);
|
||||||
|
|
||||||
|
HANDLE ResilientCreateFileW(
|
||||||
|
LPCWSTR lpFileName,
|
||||||
|
DWORD dwDesiredAccess,
|
||||||
|
DWORD dwShareMode,
|
||||||
|
LPSECURITY_ATTRIBUTES lpSecurityAttributes,
|
||||||
|
DWORD dwCreationDisposition,
|
||||||
|
DWORD dwFlagsAndAttributes,
|
||||||
|
HANDLE hTemplateFile)
|
||||||
|
{
|
||||||
|
HANDLE Handle;
|
||||||
|
DWORD LastError;
|
||||||
|
|
||||||
|
Handle = CreateFileW(
|
||||||
|
lpFileName,
|
||||||
|
dwDesiredAccess,
|
||||||
|
dwShareMode,
|
||||||
|
lpSecurityAttributes,
|
||||||
|
dwCreationDisposition,
|
||||||
|
dwFlagsAndAttributes,
|
||||||
|
hTemplateFile);
|
||||||
|
LastError = GetLastError();
|
||||||
|
|
||||||
|
if (INVALID_HANDLE_VALUE != Handle &&
|
||||||
|
(FILE_FLAG_DELETE_ON_CLOSE & dwFlagsAndAttributes))
|
||||||
|
{
|
||||||
|
/* HACK: remember FILE_FLAG_DELETE_ON_CLOSE through HANDLE_FLAG_PROTECT_FROM_CLOSE */
|
||||||
|
SetHandleInformation(Handle,
|
||||||
|
HANDLE_FLAG_PROTECT_FROM_CLOSE, HANDLE_FLAG_PROTECT_FROM_CLOSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
SetLastError(LastError);
|
||||||
|
return Handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL ResilientCloseHandle(
|
||||||
|
HANDLE hObject)
|
||||||
|
{
|
||||||
|
BOOL Success;
|
||||||
|
DWORD LastError;
|
||||||
|
DWORD HandleFlags = 0, FileNameLen;
|
||||||
|
WCHAR FileNameBuf[sizeof "\\\\?\\GLOBALROOT" - 1 + 1024] = L"\\\\?\\GLOBALROOT";
|
||||||
|
|
||||||
|
if (GetHandleInformation(hObject, &HandleFlags) &&
|
||||||
|
(HANDLE_FLAG_PROTECT_FROM_CLOSE & HandleFlags))
|
||||||
|
{
|
||||||
|
SetHandleInformation(hObject,
|
||||||
|
HANDLE_FLAG_PROTECT_FROM_CLOSE, 0);
|
||||||
|
FileNameLen = GetFinalPathNameByHandle(hObject,
|
||||||
|
FileNameBuf + sizeof "\\\\?\\GLOBALROOT" - 1, 1023,
|
||||||
|
FILE_NAME_OPENED | VOLUME_NAME_NT);
|
||||||
|
if (0 == FileNameLen || FileNameLen >= 1024)
|
||||||
|
HandleFlags = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Success = CloseHandle(
|
||||||
|
hObject);
|
||||||
|
LastError = GetLastError();
|
||||||
|
|
||||||
|
if (Success)
|
||||||
|
{
|
||||||
|
if (HANDLE_FLAG_PROTECT_FROM_CLOSE & HandleFlags)
|
||||||
|
WaitDeletePending(FileNameBuf);
|
||||||
|
}
|
||||||
|
|
||||||
|
SetLastError(LastError);
|
||||||
|
return Success;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL ResilientDeleteFileW(
|
||||||
|
LPCWSTR lpFileName)
|
||||||
|
{
|
||||||
|
BOOL Success;
|
||||||
|
DWORD LastError;
|
||||||
|
|
||||||
|
Success = DeleteFileW(lpFileName);
|
||||||
|
LastError = GetLastError();
|
||||||
|
|
||||||
|
if (Success)
|
||||||
|
WaitDeletePending(lpFileName);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (ULONG MaxTries = DeleteMaxTries;
|
||||||
|
!Success && ERROR_SHARING_VIOLATION == GetLastError() && 0 != MaxTries;
|
||||||
|
MaxTries--)
|
||||||
|
{
|
||||||
|
Sleep(DeleteSleepTimeout);
|
||||||
|
Success = DeleteFileW(lpFileName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SetLastError(LastError);
|
||||||
|
return Success;
|
||||||
|
}
|
||||||
|
|
||||||
|
static VOID WaitDeletePending(PCWSTR FileName)
|
||||||
|
{
|
||||||
|
for (ULONG MaxTries = DeleteMaxTries; 0 != MaxTries; MaxTries--)
|
||||||
|
{
|
||||||
|
HANDLE Handle = CreateFileW(FileName,
|
||||||
|
FILE_READ_ATTRIBUTES, 0, 0, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0);
|
||||||
|
if (INVALID_HANDLE_VALUE != Handle)
|
||||||
|
/* should never happen! */
|
||||||
|
CloseHandle(Handle);
|
||||||
|
else if (ERROR_ACCESS_DENIED == GetLastError())
|
||||||
|
/* STATUS_DELETE_PENDING */
|
||||||
|
Sleep(DeleteSleepTimeout);
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
@ -167,14 +167,25 @@ HANDLE HookCreateFileW(
|
|||||||
ABORT("cannot disable traverse privilege");
|
ABORT("cannot disable traverse privilege");
|
||||||
}
|
}
|
||||||
|
|
||||||
HANDLE h = CreateFileW(
|
HANDLE h;
|
||||||
FileNameBuf,
|
if (!OptResilient)
|
||||||
dwDesiredAccess,
|
h = CreateFileW(
|
||||||
dwShareMode,
|
FileNameBuf,
|
||||||
lpSecurityAttributes,
|
dwDesiredAccess,
|
||||||
dwCreationDisposition,
|
dwShareMode,
|
||||||
dwFlagsAndAttributes,
|
lpSecurityAttributes,
|
||||||
hTemplateFile);
|
dwCreationDisposition,
|
||||||
|
dwFlagsAndAttributes,
|
||||||
|
hTemplateFile);
|
||||||
|
else
|
||||||
|
h = ResilientCreateFileW(
|
||||||
|
FileNameBuf,
|
||||||
|
dwDesiredAccess,
|
||||||
|
dwShareMode,
|
||||||
|
lpSecurityAttributes,
|
||||||
|
dwCreationDisposition,
|
||||||
|
dwFlagsAndAttributes,
|
||||||
|
hTemplateFile);
|
||||||
DWORD LastError = GetLastError();
|
DWORD LastError = GetLastError();
|
||||||
|
|
||||||
if (OptNoTraverseToken)
|
if (OptNoTraverseToken)
|
||||||
@ -202,44 +213,24 @@ HANDLE HookCreateFileW(
|
|||||||
return h;
|
return h;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#undef CloseHandle
|
||||||
|
BOOL HookCloseHandle(
|
||||||
|
HANDLE hObject)
|
||||||
|
{
|
||||||
|
if (!OptResilient)
|
||||||
|
return CloseHandle(hObject);
|
||||||
|
else
|
||||||
|
return ResilientCloseHandle(hObject);
|
||||||
|
}
|
||||||
|
|
||||||
#undef DeleteFileW
|
#undef DeleteFileW
|
||||||
BOOL HookDeleteFileW(
|
BOOL HookDeleteFileW(
|
||||||
LPCWSTR lpFileName)
|
LPCWSTR lpFileName)
|
||||||
{
|
{
|
||||||
ULONG MaxTries = 30;
|
if (!OptResilient)
|
||||||
ULONG SleepTimeout = 300;
|
return DeleteFileW(lpFileName);
|
||||||
BOOL Success;
|
else
|
||||||
DWORD LastError;
|
return ResilientDeleteFileW(lpFileName);
|
||||||
|
|
||||||
Success = DeleteFileW(lpFileName);
|
|
||||||
LastError = GetLastError();
|
|
||||||
if (OptResilient)
|
|
||||||
{
|
|
||||||
if (!Success)
|
|
||||||
{
|
|
||||||
while (!Success && ERROR_SHARING_VIOLATION == GetLastError() && 0 != MaxTries--)
|
|
||||||
{
|
|
||||||
Sleep(SleepTimeout);
|
|
||||||
Success = DeleteFileW(lpFileName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
while (0 != MaxTries--)
|
|
||||||
{
|
|
||||||
HANDLE Handle = CreateFileW(lpFileName, FILE_READ_ATTRIBUTES, 0, 0, OPEN_EXISTING, 0, 0);
|
|
||||||
if (INVALID_HANDLE_VALUE != Handle)
|
|
||||||
CloseHandle(Handle); /* should never happen! */
|
|
||||||
else if (ERROR_ACCESS_DENIED == GetLastError())
|
|
||||||
Sleep(SleepTimeout);
|
|
||||||
else
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SetLastError(LastError);
|
|
||||||
return Success;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static VOID DisableBackupRestorePrivileges(VOID)
|
static VOID DisableBackupRestorePrivileges(VOID)
|
||||||
|
@ -8,6 +8,8 @@ PWSTR memfs_volumename(void *data);
|
|||||||
int mywcscmp(PWSTR a, int alen, PWSTR b, int blen);
|
int mywcscmp(PWSTR a, int alen, PWSTR b, int blen);
|
||||||
|
|
||||||
#define CreateFileW HookCreateFileW
|
#define CreateFileW HookCreateFileW
|
||||||
|
#define CloseHandle HookCloseHandle
|
||||||
|
#define DeleteFileW HookDeleteFileW
|
||||||
HANDLE HookCreateFileW(
|
HANDLE HookCreateFileW(
|
||||||
LPCWSTR lpFileName,
|
LPCWSTR lpFileName,
|
||||||
DWORD dwDesiredAccess,
|
DWORD dwDesiredAccess,
|
||||||
@ -16,11 +18,24 @@ HANDLE HookCreateFileW(
|
|||||||
DWORD dwCreationDisposition,
|
DWORD dwCreationDisposition,
|
||||||
DWORD dwFlagsAndAttributes,
|
DWORD dwFlagsAndAttributes,
|
||||||
HANDLE hTemplateFile);
|
HANDLE hTemplateFile);
|
||||||
|
BOOL HookCloseHandle(
|
||||||
#define DeleteFileW HookDeleteFileW
|
HANDLE hObject);
|
||||||
BOOL HookDeleteFileW(
|
BOOL HookDeleteFileW(
|
||||||
LPCWSTR lpFileName);
|
LPCWSTR lpFileName);
|
||||||
|
|
||||||
|
HANDLE ResilientCreateFileW(
|
||||||
|
LPCWSTR lpFileName,
|
||||||
|
DWORD dwDesiredAccess,
|
||||||
|
DWORD dwShareMode,
|
||||||
|
LPSECURITY_ATTRIBUTES lpSecurityAttributes,
|
||||||
|
DWORD dwCreationDisposition,
|
||||||
|
DWORD dwFlagsAndAttributes,
|
||||||
|
HANDLE hTemplateFile);
|
||||||
|
BOOL ResilientCloseHandle(
|
||||||
|
HANDLE hObject);
|
||||||
|
BOOL ResilientDeleteFileW(
|
||||||
|
LPCWSTR lpFileName);
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
BOOLEAN Disposition;
|
BOOLEAN Disposition;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user