mirror of
https://github.com/winfsp/winfsp.git
synced 2025-04-22 08:23:05 -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\rdwr-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\stream-tests.c" />
|
||||
<ClCompile Include="..\..\..\tst\winfsp-tests\timeout-test.c" />
|
||||
|
@ -67,6 +67,9 @@
|
||||
<ClCompile Include="..\..\..\tst\winfsp-tests\stream-tests.c">
|
||||
<Filter>Source</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\tst\winfsp-tests\resilient.c">
|
||||
<Filter>Source</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<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");
|
||||
}
|
||||
|
||||
HANDLE h = CreateFileW(
|
||||
FileNameBuf,
|
||||
dwDesiredAccess,
|
||||
dwShareMode,
|
||||
lpSecurityAttributes,
|
||||
dwCreationDisposition,
|
||||
dwFlagsAndAttributes,
|
||||
hTemplateFile);
|
||||
HANDLE h;
|
||||
if (!OptResilient)
|
||||
h = CreateFileW(
|
||||
FileNameBuf,
|
||||
dwDesiredAccess,
|
||||
dwShareMode,
|
||||
lpSecurityAttributes,
|
||||
dwCreationDisposition,
|
||||
dwFlagsAndAttributes,
|
||||
hTemplateFile);
|
||||
else
|
||||
h = ResilientCreateFileW(
|
||||
FileNameBuf,
|
||||
dwDesiredAccess,
|
||||
dwShareMode,
|
||||
lpSecurityAttributes,
|
||||
dwCreationDisposition,
|
||||
dwFlagsAndAttributes,
|
||||
hTemplateFile);
|
||||
DWORD LastError = GetLastError();
|
||||
|
||||
if (OptNoTraverseToken)
|
||||
@ -202,44 +213,24 @@ HANDLE HookCreateFileW(
|
||||
return h;
|
||||
}
|
||||
|
||||
#undef CloseHandle
|
||||
BOOL HookCloseHandle(
|
||||
HANDLE hObject)
|
||||
{
|
||||
if (!OptResilient)
|
||||
return CloseHandle(hObject);
|
||||
else
|
||||
return ResilientCloseHandle(hObject);
|
||||
}
|
||||
|
||||
#undef DeleteFileW
|
||||
BOOL HookDeleteFileW(
|
||||
LPCWSTR lpFileName)
|
||||
{
|
||||
ULONG MaxTries = 30;
|
||||
ULONG SleepTimeout = 300;
|
||||
BOOL Success;
|
||||
DWORD LastError;
|
||||
|
||||
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;
|
||||
if (!OptResilient)
|
||||
return DeleteFileW(lpFileName);
|
||||
else
|
||||
return ResilientDeleteFileW(lpFileName);
|
||||
}
|
||||
|
||||
static VOID DisableBackupRestorePrivileges(VOID)
|
||||
|
@ -8,6 +8,8 @@ PWSTR memfs_volumename(void *data);
|
||||
int mywcscmp(PWSTR a, int alen, PWSTR b, int blen);
|
||||
|
||||
#define CreateFileW HookCreateFileW
|
||||
#define CloseHandle HookCloseHandle
|
||||
#define DeleteFileW HookDeleteFileW
|
||||
HANDLE HookCreateFileW(
|
||||
LPCWSTR lpFileName,
|
||||
DWORD dwDesiredAccess,
|
||||
@ -16,11 +18,24 @@ HANDLE HookCreateFileW(
|
||||
DWORD dwCreationDisposition,
|
||||
DWORD dwFlagsAndAttributes,
|
||||
HANDLE hTemplateFile);
|
||||
|
||||
#define DeleteFileW HookDeleteFileW
|
||||
BOOL HookCloseHandle(
|
||||
HANDLE hObject);
|
||||
BOOL HookDeleteFileW(
|
||||
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
|
||||
{
|
||||
BOOLEAN Disposition;
|
||||
|
Loading…
x
Reference in New Issue
Block a user