mirror of
https://github.com/winfsp/winfsp.git
synced 2025-06-07 12:32:11 -05:00
dll: use adaptive locks when starting/stopping FSD
This commit is contained in:
parent
be5faf34bc
commit
65bf8c5319
@ -431,7 +431,23 @@ FSP_API NTSTATUS FspFsctlServiceVersion(PUINT32 PVersion)
|
||||
return 0 != FspFsctlServiceVersionValue ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
static SRWLOCK FspFsctlStartStopServiceLock = SRWLOCK_INIT;
|
||||
static FSP_ADAPTIVE_LOCK FspFsctlStartStopServiceLock = FSP_ADAPTIVE_LOCK_INIT;
|
||||
static VOID FspFsctlStartStopServiceLockAcquire(VOID)
|
||||
{
|
||||
extern HINSTANCE DllInstance;
|
||||
WCHAR DllPath[MAX_PATH];
|
||||
PWSTR FileName = 0;
|
||||
|
||||
if (0 != GetModuleFileNameW(DllInstance, DllPath, MAX_PATH))
|
||||
FileName = DllPath;
|
||||
|
||||
FspAdaptiveLockAcquire(&FspFsctlStartStopServiceLock,
|
||||
FileName, 0xfffffffffffffff0ull, (10 + 1) * 1000);
|
||||
}
|
||||
static VOID FspFsctlStartStopServiceLockRelease(VOID)
|
||||
{
|
||||
FspAdaptiveLockRelease(&FspFsctlStartStopServiceLock);
|
||||
}
|
||||
|
||||
static BOOLEAN FspFsctlRunningInContainer(VOID)
|
||||
{
|
||||
@ -455,7 +471,7 @@ static NTSTATUS FspFsctlStartServiceByName(PWSTR DriverName)
|
||||
DWORD LastError;
|
||||
NTSTATUS Result;
|
||||
|
||||
AcquireSRWLockExclusive(&FspFsctlStartStopServiceLock);
|
||||
FspFsctlStartStopServiceLockAcquire();
|
||||
|
||||
if (FspFsctlRunningInContainer())
|
||||
{
|
||||
@ -517,7 +533,7 @@ exit:
|
||||
if (0 != ScmHandle)
|
||||
CloseServiceHandle(ScmHandle);
|
||||
|
||||
ReleaseSRWLockExclusive(&FspFsctlStartStopServiceLock);
|
||||
FspFsctlStartStopServiceLockRelease();
|
||||
|
||||
return Result;
|
||||
}
|
||||
@ -587,7 +603,7 @@ FSP_API NTSTATUS FspFsctlStopService(VOID)
|
||||
|
||||
FspSxsAppendSuffix(DriverName, sizeof DriverName, L"" FSP_FSCTL_DRIVER_NAME);
|
||||
|
||||
AcquireSRWLockExclusive(&FspFsctlStartStopServiceLock);
|
||||
FspFsctlStartStopServiceLockAcquire();
|
||||
|
||||
if (FspFsctlRunningInContainer())
|
||||
{
|
||||
@ -659,7 +675,7 @@ exit:
|
||||
if (0 != ProcessToken)
|
||||
CloseHandle(ProcessToken);
|
||||
|
||||
ReleaseSRWLockExclusive(&FspFsctlStartStopServiceLock);
|
||||
FspFsctlStartStopServiceLockRelease();
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
@ -106,6 +106,21 @@ NTSTATUS FspGetModuleFileName(
|
||||
ULONG Size,
|
||||
PWSTR RelativePath);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
SRWLOCK Lock;
|
||||
HANDLE Handle;
|
||||
UINT64 Offset;
|
||||
} FSP_ADAPTIVE_LOCK;
|
||||
#define FSP_ADAPTIVE_LOCK_INIT { SRWLOCK_INIT, INVALID_HANDLE_VALUE, 0 }
|
||||
VOID FspAdaptiveLockAcquire(
|
||||
FSP_ADAPTIVE_LOCK *Lock,
|
||||
PWSTR FileName,
|
||||
UINT64 Offset,
|
||||
DWORD Timeout);
|
||||
VOID FspAdaptiveLockRelease(
|
||||
FSP_ADAPTIVE_LOCK *Lock);
|
||||
|
||||
#define FspFileSystemDirectoryBufferEntryInvalid ((ULONG)-1)
|
||||
VOID FspFileSystemPeekInDirectoryBuffer(PVOID *PDirBuffer,
|
||||
PUINT8 *PBuffer, PULONG *PIndex, PULONG PCount);
|
||||
|
@ -418,3 +418,74 @@ NTSTATUS FspGetModuleFileName(
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
VOID FspAdaptiveLockAcquire(
|
||||
FSP_ADAPTIVE_LOCK *Lock,
|
||||
PWSTR FileName,
|
||||
UINT64 Offset,
|
||||
DWORD Timeout)
|
||||
{
|
||||
AcquireSRWLockExclusive(&Lock->Lock);
|
||||
|
||||
if (0 != FileName)
|
||||
{
|
||||
HANDLE Handle;
|
||||
DWORD BytesTransferred;
|
||||
OVERLAPPED Overlapped;
|
||||
BOOL Success;
|
||||
|
||||
Handle = CreateFileW(
|
||||
FileName,
|
||||
FILE_READ_DATA,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
|
||||
0,
|
||||
OPEN_EXISTING,
|
||||
FILE_FLAG_OVERLAPPED,
|
||||
0);
|
||||
if (INVALID_HANDLE_VALUE != Handle)
|
||||
{
|
||||
memset(&Overlapped, 0, sizeof Overlapped);
|
||||
Overlapped.Offset = ((PLARGE_INTEGER)&Offset)->LowPart;
|
||||
Overlapped.OffsetHigh = ((PLARGE_INTEGER)&Offset)->HighPart;
|
||||
|
||||
Success = LockFileEx(
|
||||
Handle,
|
||||
LOCKFILE_EXCLUSIVE_LOCK, 0,
|
||||
1, 0,
|
||||
&Overlapped);
|
||||
if (Success || ERROR_IO_PENDING == GetLastError())
|
||||
{
|
||||
Success = FALSE;
|
||||
if (WAIT_OBJECT_0 == WaitForSingleObject(Handle, Timeout))
|
||||
Success = GetOverlappedResult(Handle, &Overlapped, &BytesTransferred, TRUE);
|
||||
}
|
||||
|
||||
if (Success)
|
||||
{
|
||||
Lock->Handle = Handle;
|
||||
Lock->Offset = Offset;
|
||||
}
|
||||
else
|
||||
CloseHandle(Handle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
VOID FspAdaptiveLockRelease(
|
||||
FSP_ADAPTIVE_LOCK *Lock)
|
||||
{
|
||||
if (INVALID_HANDLE_VALUE != Lock->Handle)
|
||||
{
|
||||
HANDLE Handle = Lock->Handle;
|
||||
LARGE_INTEGER LargeOffset = *(PLARGE_INTEGER)&Lock->Offset;
|
||||
|
||||
UnlockFile(Handle, LargeOffset.LowPart, LargeOffset.HighPart, 1, 0);
|
||||
|
||||
CloseHandle(Handle);
|
||||
|
||||
Lock->Handle = INVALID_HANDLE_VALUE;
|
||||
Lock->Offset = 0;
|
||||
}
|
||||
|
||||
ReleaseSRWLockExclusive(&Lock->Lock);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user