mirror of
https://github.com/winfsp/winfsp.git
synced 2025-04-22 16:33:02 -05:00
fsctl: FSP_FSCTL_VOLUME_PARAMS
This commit is contained in:
parent
ed91c26c59
commit
1c464cad2b
@ -43,7 +43,14 @@ extern const __declspec(selectany) GUID FspFsvrtDeviceClassGuid =
|
||||
#define FSP_FSCTL_TRANSACT_REQ_SIZEMAX (4096 - 64) /* 64: size for internal request header */
|
||||
#define FSP_FSCTL_TRANSACT_RSP_SIZEMAX (4096 - 64) /* symmetry! */
|
||||
|
||||
/* file metadata */
|
||||
/* volume/file metadata */
|
||||
typedef struct
|
||||
{
|
||||
UINT64 TotalAllocationUnits;
|
||||
UINT64 AvailableAllocationUnits;
|
||||
UINT16 VolumeLabelLength;
|
||||
WCHAR VolumeLabel[32];
|
||||
} FSP_FSCTL_VOLUME_INFO;
|
||||
typedef struct
|
||||
{
|
||||
UINT32 FileAttributes;
|
||||
@ -100,14 +107,28 @@ enum
|
||||
};
|
||||
typedef struct
|
||||
{
|
||||
UINT16 Version;
|
||||
UINT16 Version; /* set to 0 */
|
||||
/* volume information */
|
||||
UINT16 SectorSize;
|
||||
UINT32 SerialNumber;
|
||||
UINT32 TransactTimeout; /* milliseconds; values between 1 sec and 10 sec */
|
||||
UINT32 IrpTimeout; /* milliseconds; values between 1 min and 10 min */
|
||||
UINT32 IrpCapacity; /* maximum number of pending IRP's */
|
||||
UINT32 FileInfoTimeout; /* milliseconds */
|
||||
UINT32 EaSupported:1; /* supports extended attributes (unimplemented; set to 0) */
|
||||
UINT16 SectorsPerAllocationUnit;
|
||||
UINT16 MaxComponentLength; /* maximum file name component length (bytes) */
|
||||
UINT32 SerialNumber; /* volume serial number */
|
||||
/* I/O timeouts, capacity, etc. */
|
||||
UINT32 TransactTimeout; /* FSP_FSCTL_TRANSACT timeout (millis; 1 sec - 10 sec) */
|
||||
UINT32 IrpTimeout; /* pending IRP timeout (millis; 1 min - 10 min) */
|
||||
UINT32 IrpCapacity; /* maximum number of pending IRP's (100 - 1000)*/
|
||||
UINT32 FileInfoTimeout; /* FileInfo/VolumeInfo timeout (millis) */
|
||||
/* FILE_FS_ATTRIBUTE_INFORMATION::FileSystemAttributes */
|
||||
UINT32 CaseSensitiveSearch:1; /* file system supports case-sensitive file names */
|
||||
UINT32 CasePreservedNames:1; /* file system preserves the case of file names */
|
||||
UINT32 UnicodeOnDisk:1; /* file system supports Unicode in file names */
|
||||
UINT32 PersistentAcls:1; /* file system preserves and enforces access control lists */
|
||||
UINT32 ReparsePoints:1; /* file system supports reparse points (!!!: unimplemented) */
|
||||
UINT32 NamedStreams:1; /* file system supports named streams (!!!: unimplemented) */
|
||||
UINT32 HardLinks:1; /* unimplemented; set to 0 */
|
||||
UINT32 ExtendedAttributes:1; /* unimplemented; set to 0 */
|
||||
UINT32 ReadOnlyVolume:1;
|
||||
/* other flags */
|
||||
UINT32 FileNameRequired:1; /* FileName required for all operations (not just Create) */
|
||||
WCHAR Prefix[64]; /* UNC prefix to recognize (\\server\path format, 0-term) */
|
||||
} FSP_FSCTL_VOLUME_PARAMS;
|
||||
@ -205,8 +226,7 @@ typedef struct
|
||||
} QueryInformation;
|
||||
struct
|
||||
{
|
||||
UINT64 TotalAllocationUnits;
|
||||
UINT64 AvailableAllocationUnits;
|
||||
FSP_FSCTL_VOLUME_INFO VolumeInfo;
|
||||
} QueryVolumeInformation;
|
||||
} Rsp;
|
||||
FSP_FSCTL_DECLSPEC_ALIGN UINT8 Buffer[];
|
||||
|
@ -35,6 +35,9 @@ VOID FspFsvolDeviceDeleteContext(PDEVICE_OBJECT DeviceObject, UINT64 Identifier,
|
||||
static RTL_AVL_COMPARE_ROUTINE FspFsvolDeviceCompareElement;
|
||||
static RTL_AVL_ALLOCATE_ROUTINE FspFsvolDeviceAllocateElement;
|
||||
static RTL_AVL_FREE_ROUTINE FspFsvolDeviceFreeElement;
|
||||
VOID FspFsvolGetVolumeInfo(PDEVICE_OBJECT DeviceObject, FSP_FSCTL_VOLUME_INFO *VolumeInfo);
|
||||
BOOLEAN FspFsvolTryGetVolumeInfo(PDEVICE_OBJECT DeviceObject, FSP_FSCTL_VOLUME_INFO *VolumeInfo);
|
||||
VOID FspFsvolSetVolumeInfo(PDEVICE_OBJECT DeviceObject, const FSP_FSCTL_VOLUME_INFO *VolumeInfo);
|
||||
NTSTATUS FspDeviceCopyList(
|
||||
PDEVICE_OBJECT **PDeviceObjects, PULONG PDeviceObjectCount);
|
||||
VOID FspDeviceDeleteList(
|
||||
@ -307,6 +310,10 @@ static NTSTATUS FspFsvolDeviceInit(PDEVICE_OBJECT DeviceObject)
|
||||
IoStartTimer(DeviceObject);
|
||||
FsvolDeviceExtension->InitDoneTimer = 1;
|
||||
|
||||
/* initialize the volume information */
|
||||
KeInitializeSpinLock(&FsvolDeviceExtension->InfoSpinLock);
|
||||
FsvolDeviceExtension->InitDoneInfo = 1;
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
@ -509,6 +516,66 @@ static VOID NTAPI FspFsvolDeviceFreeElement(
|
||||
PAGED_CODE();
|
||||
}
|
||||
|
||||
VOID FspFsvolGetVolumeInfo(PDEVICE_OBJECT DeviceObject, FSP_FSCTL_VOLUME_INFO *VolumeInfo)
|
||||
{
|
||||
// !PAGED_CODE();
|
||||
|
||||
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(DeviceObject);
|
||||
FSP_FSCTL_VOLUME_INFO VolumeInfoNp;
|
||||
KIRQL Irql;
|
||||
|
||||
KeAcquireSpinLock(&FsvolDeviceExtension->InfoSpinLock, &Irql);
|
||||
VolumeInfoNp = FsvolDeviceExtension->VolumeInfo;
|
||||
KeReleaseSpinLock(&FsvolDeviceExtension->InfoSpinLock, Irql);
|
||||
|
||||
*VolumeInfo = VolumeInfoNp;
|
||||
}
|
||||
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4701) /* disable idiotic warning! */
|
||||
BOOLEAN FspFsvolTryGetVolumeInfo(PDEVICE_OBJECT DeviceObject, FSP_FSCTL_VOLUME_INFO *VolumeInfo)
|
||||
{
|
||||
// !PAGED_CODE();
|
||||
|
||||
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(DeviceObject);
|
||||
FSP_FSCTL_VOLUME_INFO VolumeInfoNp;
|
||||
KIRQL Irql;
|
||||
BOOLEAN Result;
|
||||
|
||||
KeAcquireSpinLock(&FsvolDeviceExtension->InfoSpinLock, &Irql);
|
||||
if (0 < FsvolDeviceExtension->InfoExpirationTime &&
|
||||
KeQueryInterruptTime() < FsvolDeviceExtension->InfoExpirationTime)
|
||||
{
|
||||
VolumeInfoNp = FsvolDeviceExtension->VolumeInfo;
|
||||
Result = TRUE;
|
||||
}
|
||||
else
|
||||
Result = FALSE;
|
||||
KeReleaseSpinLock(&FsvolDeviceExtension->InfoSpinLock, Irql);
|
||||
|
||||
if (Result)
|
||||
*VolumeInfo = VolumeInfoNp;
|
||||
|
||||
return Result;
|
||||
}
|
||||
#pragma warning(pop)
|
||||
|
||||
VOID FspFsvolSetVolumeInfo(PDEVICE_OBJECT DeviceObject, const FSP_FSCTL_VOLUME_INFO *VolumeInfo)
|
||||
{
|
||||
// !PAGED_CODE();
|
||||
|
||||
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(DeviceObject);
|
||||
FSP_FSCTL_VOLUME_INFO VolumeInfoNp = *VolumeInfo;
|
||||
KIRQL Irql;
|
||||
UINT64 FileInfoTimeout = FsvolDeviceExtension->VolumeParams.FileInfoTimeout * 10000ULL;
|
||||
|
||||
KeAcquireSpinLock(&FsvolDeviceExtension->InfoSpinLock, &Irql);
|
||||
FsvolDeviceExtension->VolumeInfo = VolumeInfoNp;
|
||||
FsvolDeviceExtension->InfoExpirationTime = 0 != FileInfoTimeout ?
|
||||
KeQueryInterruptTime() + FileInfoTimeout : 0;
|
||||
KeReleaseSpinLock(&FsvolDeviceExtension->InfoSpinLock, Irql);
|
||||
}
|
||||
|
||||
NTSTATUS FspDeviceCopyList(
|
||||
PDEVICE_OBJECT **PDeviceObjects, PULONG PDeviceObjectCount)
|
||||
{
|
||||
|
@ -443,7 +443,8 @@ typedef struct
|
||||
typedef struct
|
||||
{
|
||||
FSP_DEVICE_EXTENSION Base;
|
||||
UINT32 InitDoneFsvrt:1, InitDoneDelRsc:1, InitDoneIoq:1, InitDoneGenTab:1, InitDoneTimer:1;
|
||||
UINT32 InitDoneFsvrt:1, InitDoneDelRsc:1, InitDoneIoq:1, InitDoneGenTab:1, InitDoneTimer:1,
|
||||
InitDoneInfo:1;
|
||||
PDEVICE_OBJECT FsctlDeviceObject;
|
||||
PDEVICE_OBJECT FsvrtDeviceObject;
|
||||
HANDLE MupHandle;
|
||||
@ -461,6 +462,9 @@ typedef struct
|
||||
PVOID GenericTableElementStorage;
|
||||
UNICODE_STRING VolumeName;
|
||||
WCHAR VolumeNameBuf[FSP_DEVICE_VOLUME_NAME_LENMAX / sizeof(WCHAR)];
|
||||
KSPIN_LOCK InfoSpinLock;
|
||||
UINT64 InfoExpirationTime;
|
||||
FSP_FSCTL_VOLUME_INFO VolumeInfo;
|
||||
} FSP_FSVOL_DEVICE_EXTENSION;
|
||||
static inline
|
||||
FSP_DEVICE_EXTENSION *FspDeviceExtension(PDEVICE_OBJECT DeviceObject)
|
||||
@ -491,6 +495,9 @@ PVOID FspFsvolDeviceInsertContext(PDEVICE_OBJECT DeviceObject, UINT64 Identifier
|
||||
FSP_DEVICE_GENERIC_TABLE_ELEMENT *ElementStorage, PBOOLEAN PInserted);
|
||||
VOID FspFsvolDeviceDeleteContext(PDEVICE_OBJECT DeviceObject, UINT64 Identifier,
|
||||
PBOOLEAN PDeleted);
|
||||
VOID FspFsvolGetVolumeInfo(PDEVICE_OBJECT DeviceObject, FSP_FSCTL_VOLUME_INFO *VolumeInfo);
|
||||
BOOLEAN FspFsvolTryGetVolumeInfo(PDEVICE_OBJECT DeviceObject, FSP_FSCTL_VOLUME_INFO *VolumeInfo);
|
||||
VOID FspFsvolSetVolumeInfo(PDEVICE_OBJECT DeviceObject, const FSP_FSCTL_VOLUME_INFO *VolumeInfo);
|
||||
NTSTATUS FspDeviceCopyList(
|
||||
PDEVICE_OBJECT **PDeviceObjects, PULONG PDeviceObjectCount);
|
||||
VOID FspDeviceDeleteList(
|
||||
|
@ -12,12 +12,13 @@ static NTSTATUS FspFsvolQueryVolumeDeviceInformation(
|
||||
PDEVICE_OBJECT FsvolDeviceObject, PUINT8 *PBuffer, PUINT8 BufferEnd);
|
||||
static NTSTATUS FspFsvolQueryVolumeFullSizeInformation(
|
||||
PDEVICE_OBJECT FsvolDeviceObject, PUINT8 *PBuffer, PUINT8 BufferEnd,
|
||||
const UINT64 *Sizes);
|
||||
const FSP_FSCTL_VOLUME_INFO *VolumeInfo);
|
||||
static NTSTATUS FspFsvolQueryVolumeSizeInformation(
|
||||
PDEVICE_OBJECT FsvolDeviceObject, PUINT8 *PBuffer, PUINT8 BufferEnd,
|
||||
const UINT64 *Sizes);
|
||||
const FSP_FSCTL_VOLUME_INFO *VolumeInfo);
|
||||
static NTSTATUS FspFsvolQueryVolumeFsVolumeInformation(
|
||||
PDEVICE_OBJECT FsvolDeviceObject, PUINT8 *PBuffer, PUINT8 BufferEnd);
|
||||
PDEVICE_OBJECT FsvolDeviceObject, PUINT8 *PBuffer, PUINT8 BufferEnd,
|
||||
const FSP_FSCTL_VOLUME_INFO *VolumeInfo);
|
||||
static NTSTATUS FspFsvolQueryVolumeInformation(
|
||||
PDEVICE_OBJECT FsvolDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
|
||||
FSP_IOCMPL_DISPATCH FspFsvolQueryVolumeInformationComplete;
|
||||
@ -59,7 +60,7 @@ static NTSTATUS FspFsvolQueryVolumeDeviceInformation(
|
||||
|
||||
static NTSTATUS FspFsvolQueryVolumeFullSizeInformation(
|
||||
PDEVICE_OBJECT FsvolDeviceObject, PUINT8 *PBuffer, PUINT8 BufferEnd,
|
||||
const UINT64 *Sizes)
|
||||
const FSP_FSCTL_VOLUME_INFO *VolumeInfo)
|
||||
{
|
||||
PAGED_CODE();
|
||||
|
||||
@ -68,7 +69,7 @@ static NTSTATUS FspFsvolQueryVolumeFullSizeInformation(
|
||||
|
||||
static NTSTATUS FspFsvolQueryVolumeSizeInformation(
|
||||
PDEVICE_OBJECT FsvolDeviceObject, PUINT8 *PBuffer, PUINT8 BufferEnd,
|
||||
const UINT64 *Sizes)
|
||||
const FSP_FSCTL_VOLUME_INFO *VolumeInfo)
|
||||
{
|
||||
PAGED_CODE();
|
||||
|
||||
@ -76,7 +77,8 @@ static NTSTATUS FspFsvolQueryVolumeSizeInformation(
|
||||
}
|
||||
|
||||
static NTSTATUS FspFsvolQueryVolumeFsVolumeInformation(
|
||||
PDEVICE_OBJECT FsvolDeviceObject, PUINT8 *PBuffer, PUINT8 BufferEnd)
|
||||
PDEVICE_OBJECT FsvolDeviceObject, PUINT8 *PBuffer, PUINT8 BufferEnd,
|
||||
const FSP_FSCTL_VOLUME_INFO *VolumeInfo)
|
||||
{
|
||||
PAGED_CODE();
|
||||
|
||||
@ -107,7 +109,7 @@ static NTSTATUS FspFsvolQueryVolumeInformation(
|
||||
Result = FspFsvolQueryVolumeSizeInformation(FsvolDeviceObject, &Buffer, BufferEnd, 0);
|
||||
break;
|
||||
case FileFsVolumeInformation:
|
||||
Result = FspFsvolQueryVolumeFsVolumeInformation(FsvolDeviceObject, &Buffer, BufferEnd);
|
||||
Result = FspFsvolQueryVolumeFsVolumeInformation(FsvolDeviceObject, &Buffer, BufferEnd, 0);
|
||||
break;
|
||||
default:
|
||||
Result = STATUS_INVALID_PARAMETER;
|
||||
@ -158,11 +160,15 @@ VOID FspFsvolQueryVolumeInformationComplete(
|
||||
{
|
||||
case FileFsFullSizeInformation:
|
||||
Result = FspFsvolQueryVolumeFullSizeInformation(FsvolDeviceObject, &Buffer, BufferEnd,
|
||||
&Response->Rsp.QueryVolumeInformation.TotalAllocationUnits);
|
||||
&Response->Rsp.QueryVolumeInformation.VolumeInfo);
|
||||
break;
|
||||
case FileFsSizeInformation:
|
||||
Result = FspFsvolQueryVolumeSizeInformation(FsvolDeviceObject, &Buffer, BufferEnd,
|
||||
&Response->Rsp.QueryVolumeInformation.TotalAllocationUnits);
|
||||
&Response->Rsp.QueryVolumeInformation.VolumeInfo);
|
||||
break;
|
||||
case FileFsVolumeInformation:
|
||||
Result = FspFsvolQueryVolumeFsVolumeInformation(FsvolDeviceObject, &Buffer, BufferEnd,
|
||||
&Response->Rsp.QueryVolumeInformation.VolumeInfo);
|
||||
break;
|
||||
default:
|
||||
ASSERT(0);
|
||||
|
@ -87,6 +87,10 @@ NTSTATUS FspVolumeCreate(
|
||||
/* check the VolumeParams */
|
||||
if (0 == VolumeParams.SectorSize)
|
||||
VolumeParams.SectorSize = 512;
|
||||
if (0 == VolumeParams.SectorsPerAllocationUnit)
|
||||
VolumeParams.SectorsPerAllocationUnit = 1;
|
||||
if (0 == VolumeParams.MaxComponentLength)
|
||||
VolumeParams.MaxComponentLength = 255;
|
||||
if (FspFsctlTransactTimeoutMinimum > VolumeParams.TransactTimeout ||
|
||||
VolumeParams.TransactTimeout > FspFsctlTransactTimeoutMaximum)
|
||||
VolumeParams.TransactTimeout = FspFsctlTransactTimeoutDefault;
|
||||
|
Loading…
x
Reference in New Issue
Block a user