mirror of
https://github.com/winfsp/winfsp.git
synced 2025-04-22 16:33:02 -05:00
sys: fsext: allow multiple providers (up to 4)
This commit is contained in:
parent
3c391ca711
commit
29fd9bf779
@ -22,8 +22,41 @@
|
|||||||
#include <sys/driver.h>
|
#include <sys/driver.h>
|
||||||
#include <winfsp/fsext.h>
|
#include <winfsp/fsext.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Maximum number of allowed fsext providers. This must be kept small,
|
||||||
|
* because we do a linear search to find the provider. If this changes
|
||||||
|
* the data structure used to store providers (currently 2 parallel
|
||||||
|
* arrays) must be revisited.
|
||||||
|
*/
|
||||||
|
#define FSP_FSEXT_PROVIDER_COUNTMAX 4
|
||||||
|
|
||||||
static KSPIN_LOCK FsextSpinLock = 0;
|
static KSPIN_LOCK FsextSpinLock = 0;
|
||||||
FSP_FSEXT_PROVIDER *FsextProvider;
|
static UINT32 FsextControlCodes[FSP_FSEXT_PROVIDER_COUNTMAX];
|
||||||
|
static FSP_FSEXT_PROVIDER *FsextProviders[FSP_FSEXT_PROVIDER_COUNTMAX];
|
||||||
|
|
||||||
|
static inline
|
||||||
|
FSP_FSEXT_PROVIDER *FspFsextProviderGet(UINT32 FsextControlCode)
|
||||||
|
{
|
||||||
|
#if 0
|
||||||
|
for (ULONG I = 0; FSP_FSEXT_PROVIDER_COUNTMAX > I; I++)
|
||||||
|
if (FsextControlCode == FsextControlCodes[I])
|
||||||
|
return FsextProviders[I];
|
||||||
|
#else
|
||||||
|
/* unroll by hand */
|
||||||
|
FSP_FSCTL_STATIC_ASSERT(4 == FSP_FSEXT_PROVIDER_COUNTMAX,
|
||||||
|
"unrolled loop expects FsextProviders to have 4 elements");
|
||||||
|
if (FsextControlCode == FsextControlCodes[0])
|
||||||
|
return FsextProviders[0];
|
||||||
|
if (FsextControlCode == FsextControlCodes[1])
|
||||||
|
return FsextProviders[1];
|
||||||
|
if (FsextControlCode == FsextControlCodes[2])
|
||||||
|
return FsextProviders[2];
|
||||||
|
if (FsextControlCode == FsextControlCodes[3])
|
||||||
|
return FsextProviders[3];
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
FSP_FSEXT_PROVIDER *FspFsextProvider(UINT32 FsextControlCode, PNTSTATUS PLoadResult)
|
FSP_FSEXT_PROVIDER *FspFsextProvider(UINT32 FsextControlCode, PNTSTATUS PLoadResult)
|
||||||
{
|
{
|
||||||
@ -31,10 +64,9 @@ FSP_FSEXT_PROVIDER *FspFsextProvider(UINT32 FsextControlCode, PNTSTATUS PLoadRes
|
|||||||
KIRQL Irql;
|
KIRQL Irql;
|
||||||
|
|
||||||
KeAcquireSpinLock(&FsextSpinLock, &Irql);
|
KeAcquireSpinLock(&FsextSpinLock, &Irql);
|
||||||
Provider = FsextProvider;
|
Provider = FspFsextProviderGet(FsextControlCode);
|
||||||
KeReleaseSpinLock(&FsextSpinLock, Irql);
|
KeReleaseSpinLock(&FsextSpinLock, Irql);
|
||||||
if (0 != Provider && FsextControlCode != Provider->DeviceTransactCode)
|
ASSERT(0 == Provider || FsextControlCode == Provider->DeviceTransactCode);
|
||||||
Provider = 0;
|
|
||||||
|
|
||||||
if (0 != PLoadResult)
|
if (0 != PLoadResult)
|
||||||
{
|
{
|
||||||
@ -81,10 +113,9 @@ FSP_FSEXT_PROVIDER *FspFsextProvider(UINT32 FsextControlCode, PNTSTATUS PLoadRes
|
|||||||
}
|
}
|
||||||
|
|
||||||
KeAcquireSpinLock(&FsextSpinLock, &Irql);
|
KeAcquireSpinLock(&FsextSpinLock, &Irql);
|
||||||
Provider = FsextProvider;
|
Provider = FspFsextProviderGet(FsextControlCode);
|
||||||
KeReleaseSpinLock(&FsextSpinLock, Irql);
|
KeReleaseSpinLock(&FsextSpinLock, Irql);
|
||||||
if (0 != Provider && FsextControlCode != Provider->DeviceTransactCode)
|
ASSERT(0 == Provider || FsextControlCode == Provider->DeviceTransactCode);
|
||||||
Provider = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
*PLoadResult = 0 != Provider ? STATUS_SUCCESS : STATUS_OBJECT_NAME_NOT_FOUND;
|
*PLoadResult = 0 != Provider ? STATUS_SUCCESS : STATUS_OBJECT_NAME_NOT_FOUND;
|
||||||
@ -100,18 +131,17 @@ NTSTATUS FspFsextProviderRegister(FSP_FSEXT_PROVIDER *Provider)
|
|||||||
|
|
||||||
KeAcquireSpinLock(&FsextSpinLock, &Irql);
|
KeAcquireSpinLock(&FsextSpinLock, &Irql);
|
||||||
|
|
||||||
if (0 != FsextProvider)
|
Result = STATUS_TOO_LATE;
|
||||||
{
|
for (ULONG I = 0; FSP_FSEXT_PROVIDER_COUNTMAX > I; I++)
|
||||||
Result = STATUS_TOO_LATE;
|
if (0 == FsextControlCodes[I])
|
||||||
goto exit;
|
{
|
||||||
}
|
Provider->DeviceExtensionOffset = FIELD_OFFSET(FSP_FSVOL_DEVICE_EXTENSION, FsextData);
|
||||||
|
FsextControlCodes[I] = Provider->DeviceTransactCode;
|
||||||
|
FsextProviders[I] = Provider;
|
||||||
|
Result = STATUS_SUCCESS;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
Provider->DeviceExtensionOffset = FIELD_OFFSET(FSP_FSVOL_DEVICE_EXTENSION, FsextData);
|
|
||||||
FsextProvider = Provider;
|
|
||||||
|
|
||||||
Result = STATUS_SUCCESS;
|
|
||||||
|
|
||||||
exit:
|
|
||||||
KeReleaseSpinLock(&FsextSpinLock, Irql);
|
KeReleaseSpinLock(&FsextSpinLock, Irql);
|
||||||
|
|
||||||
return Result;
|
return Result;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user