mirror of
https://github.com/winfsp/winfsp.git
synced 2025-04-22 08:23:05 -05:00
sys: implement SectorSize queries
- IRP_MJ_QUERY_VOLUME_INFORMATION/FileFsSectorSizeInformation - IOCTL_STORAGE_QUERY_PROPERTY/StorageAccessAlignmentProperty
This commit is contained in:
parent
de75454d50
commit
9436fd8402
@ -23,6 +23,9 @@
|
||||
|
||||
static NTSTATUS FspFsvrtDeviceControl(
|
||||
PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
|
||||
static BOOLEAN FspFsvrtDeviceControlStorageQuery(
|
||||
PDEVICE_OBJECT FsvrtDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp,
|
||||
PNTSTATUS PResult);
|
||||
static NTSTATUS FspFsvolDeviceControl(
|
||||
PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
|
||||
FSP_IOCMPL_DISPATCH FspFsvolDeviceControlComplete;
|
||||
@ -31,6 +34,7 @@ FSP_DRIVER_DISPATCH FspDeviceControl;
|
||||
|
||||
#ifdef ALLOC_PRAGMA
|
||||
#pragma alloc_text(PAGE, FspFsvrtDeviceControl)
|
||||
#pragma alloc_text(PAGE, FspFsvrtDeviceControlStorageQuery)
|
||||
#pragma alloc_text(PAGE, FspFsvolDeviceControl)
|
||||
#pragma alloc_text(PAGE, FspFsvolDeviceControlComplete)
|
||||
#pragma alloc_text(PAGE, FspFsvolDeviceControlRequestFini)
|
||||
@ -49,6 +53,9 @@ static NTSTATUS FspFsvrtDeviceControl(
|
||||
|
||||
NTSTATUS Result;
|
||||
|
||||
if (FspFsvrtDeviceControlStorageQuery(FsvrtDeviceObject, Irp, IrpSp, &Result))
|
||||
return Result;
|
||||
|
||||
if (FspMountdevDeviceControl(FsvrtDeviceObject, Irp, IrpSp, &Result))
|
||||
return Result;
|
||||
|
||||
@ -69,6 +76,62 @@ static NTSTATUS FspFsvrtDeviceControl(
|
||||
return STATUS_UNRECOGNIZED_VOLUME;
|
||||
}
|
||||
|
||||
static BOOLEAN FspFsvrtDeviceControlStorageQuery(
|
||||
PDEVICE_OBJECT FsvrtDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp,
|
||||
PNTSTATUS PResult)
|
||||
{
|
||||
PAGED_CODE();
|
||||
|
||||
/*
|
||||
* SQL Server insists on sending us storage level IOCTL's even though
|
||||
* WinFsp file systems are not on top of a real disk. So bite the bullet
|
||||
* and implement some of those storage IOCTL's to make SQL Server happy.
|
||||
*/
|
||||
|
||||
if (IOCTL_STORAGE_QUERY_PROPERTY != IrpSp->Parameters.DeviceIoControl.IoControlCode ||
|
||||
sizeof(STORAGE_PROPERTY_QUERY) > IrpSp->Parameters.DeviceIoControl.InputBufferLength)
|
||||
return FALSE;
|
||||
|
||||
PSTORAGE_PROPERTY_QUERY Query = Irp->AssociatedIrp.SystemBuffer;
|
||||
switch (Query->PropertyId)
|
||||
{
|
||||
case StorageAccessAlignmentProperty:
|
||||
if (PropertyExistsQuery == Query->QueryType)
|
||||
*PResult = STATUS_SUCCESS;
|
||||
else if (PropertyStandardQuery == Query->QueryType)
|
||||
{
|
||||
FSP_FSVRT_DEVICE_EXTENSION *FsvrtDeviceExtension = FspFsvrtDeviceExtension(FsvrtDeviceObject);
|
||||
PSTORAGE_ACCESS_ALIGNMENT_DESCRIPTOR Descriptor = Irp->AssociatedIrp.SystemBuffer;
|
||||
ULONG OutputBufferLength = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
|
||||
|
||||
if (sizeof(STORAGE_DESCRIPTOR_HEADER) > OutputBufferLength)
|
||||
*PResult = STATUS_BUFFER_TOO_SMALL;
|
||||
else if (sizeof(STORAGE_ACCESS_ALIGNMENT_DESCRIPTOR) > OutputBufferLength)
|
||||
{
|
||||
Descriptor->Version = sizeof(STORAGE_ACCESS_ALIGNMENT_DESCRIPTOR);
|
||||
Descriptor->Size = sizeof(STORAGE_ACCESS_ALIGNMENT_DESCRIPTOR);
|
||||
Irp->IoStatus.Information = sizeof(STORAGE_DESCRIPTOR_HEADER);
|
||||
*PResult = STATUS_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
RtlZeroMemory(Descriptor, sizeof(STORAGE_ACCESS_ALIGNMENT_DESCRIPTOR));
|
||||
Descriptor->Version = sizeof(STORAGE_ACCESS_ALIGNMENT_DESCRIPTOR);
|
||||
Descriptor->Size = sizeof(STORAGE_ACCESS_ALIGNMENT_DESCRIPTOR);
|
||||
Descriptor->BytesPerLogicalSector = FsvrtDeviceExtension->SectorSize;
|
||||
Descriptor->BytesPerPhysicalSector = FsvrtDeviceExtension->SectorSize;
|
||||
Irp->IoStatus.Information = sizeof(STORAGE_ACCESS_ALIGNMENT_DESCRIPTOR);
|
||||
*PResult = STATUS_SUCCESS;
|
||||
}
|
||||
}
|
||||
else
|
||||
*PResult = STATUS_NOT_SUPPORTED;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static NTSTATUS FspFsvolDeviceControl(
|
||||
PDEVICE_OBJECT FsvolDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
|
||||
{
|
||||
@ -79,11 +142,6 @@ static NTSTATUS FspFsvolDeviceControl(
|
||||
ULONG IoControlCode = IrpSp->Parameters.DeviceIoControl.IoControlCode;
|
||||
NTSTATUS Result;
|
||||
|
||||
#if 0
|
||||
if (FspMountdevDeviceControl(FsvolDeviceExtension->FsvrtDeviceObject, Irp, IrpSp, &Result))
|
||||
return Result;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Possibly forward the IOCTL request to the user mode file system. The rules are:
|
||||
*
|
||||
@ -92,7 +150,6 @@ static NTSTATUS FspFsvolDeviceControl(
|
||||
* METHOD_BUFFERED will be forwarded.
|
||||
*/
|
||||
|
||||
|
||||
/* do we support DeviceControl? */
|
||||
if (!FsvolDeviceExtension->VolumeParams.DeviceControl)
|
||||
return STATUS_INVALID_DEVICE_REQUEST;
|
||||
|
@ -27,6 +27,7 @@
|
||||
#define POOL_NX_OPTIN 1
|
||||
#include <ntifs.h>
|
||||
#include <mountdev.h>
|
||||
#include <ntddstor.h>
|
||||
#include <ntstrsafe.h>
|
||||
#include <wdmsec.h>
|
||||
#include <winfsp/fsctl.h>
|
||||
@ -1106,6 +1107,7 @@ typedef struct
|
||||
typedef struct
|
||||
{
|
||||
FSP_DEVICE_EXTENSION Base;
|
||||
UINT16 SectorSize;
|
||||
LONG IsMountdev;
|
||||
BOOLEAN Persistent;
|
||||
GUID UniqueId;
|
||||
|
@ -28,6 +28,9 @@ static NTSTATUS FspFsvolQueryFsDeviceInformation(
|
||||
static NTSTATUS FspFsvolQueryFsFullSizeInformation(
|
||||
PDEVICE_OBJECT FsvolDeviceObject, PUINT8 *PBuffer, PUINT8 BufferEnd,
|
||||
const FSP_FSCTL_VOLUME_INFO *VolumeInfo);
|
||||
static NTSTATUS FspFsvolQueryFsSectorSizeInformation(
|
||||
PDEVICE_OBJECT FsvolDeviceObject, PUINT8 *PBuffer, PUINT8 BufferEnd,
|
||||
const FSP_FSCTL_VOLUME_INFO *VolumeInfo);
|
||||
static NTSTATUS FspFsvolQueryFsSizeInformation(
|
||||
PDEVICE_OBJECT FsvolDeviceObject, PUINT8 *PBuffer, PUINT8 BufferEnd,
|
||||
const FSP_FSCTL_VOLUME_INFO *VolumeInfo);
|
||||
@ -50,6 +53,7 @@ FSP_DRIVER_DISPATCH FspSetVolumeInformation;
|
||||
#pragma alloc_text(PAGE, FspFsvolQueryFsAttributeInformation)
|
||||
#pragma alloc_text(PAGE, FspFsvolQueryFsDeviceInformation)
|
||||
#pragma alloc_text(PAGE, FspFsvolQueryFsFullSizeInformation)
|
||||
#pragma alloc_text(PAGE, FspFsvolQueryFsSectorSizeInformation)
|
||||
#pragma alloc_text(PAGE, FspFsvolQueryFsSizeInformation)
|
||||
#pragma alloc_text(PAGE, FspFsvolQueryFsVolumeInformation)
|
||||
#pragma alloc_text(PAGE, FspFsvolQueryVolumeInformation)
|
||||
@ -186,6 +190,35 @@ static NTSTATUS FspFsvolQueryFsFullSizeInformation(
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static NTSTATUS FspFsvolQueryFsSectorSizeInformation(
|
||||
PDEVICE_OBJECT FsvolDeviceObject, PUINT8 *PBuffer, PUINT8 BufferEnd,
|
||||
const FSP_FSCTL_VOLUME_INFO *VolumeInfo)
|
||||
{
|
||||
PAGED_CODE();
|
||||
|
||||
if (*PBuffer + sizeof(FILE_FS_SECTOR_SIZE_INFORMATION) > BufferEnd)
|
||||
return STATUS_BUFFER_TOO_SMALL;
|
||||
|
||||
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(FsvolDeviceObject);
|
||||
PFILE_FS_SECTOR_SIZE_INFORMATION Info = (PFILE_FS_SECTOR_SIZE_INFORMATION)*PBuffer;
|
||||
|
||||
Info->LogicalBytesPerSector =
|
||||
Info->PhysicalBytesPerSectorForAtomicity =
|
||||
Info->PhysicalBytesPerSectorForPerformance =
|
||||
Info->FileSystemEffectivePhysicalBytesPerSectorForAtomicity =
|
||||
FsvolDeviceExtension->VolumeParams.SectorSize;
|
||||
Info->Flags =
|
||||
SSINFO_FLAGS_ALIGNED_DEVICE |
|
||||
SSINFO_FLAGS_PARTITION_ALIGNED_ON_DEVICE |
|
||||
SSINFO_FLAGS_NO_SEEK_PENALTY;
|
||||
Info->ByteOffsetForSectorAlignment = 0;
|
||||
Info->ByteOffsetForPartitionAlignment = 0;
|
||||
|
||||
*PBuffer += sizeof(FILE_FS_SECTOR_SIZE_INFORMATION);
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static NTSTATUS FspFsvolQueryFsSizeInformation(
|
||||
PDEVICE_OBJECT FsvolDeviceObject, PUINT8 *PBuffer, PUINT8 BufferEnd,
|
||||
const FSP_FSCTL_VOLUME_INFO *VolumeInfo)
|
||||
@ -255,7 +288,7 @@ static NTSTATUS FspFsvolQueryVolumeInformation(
|
||||
|
||||
NTSTATUS Result;
|
||||
PUINT8 Buffer = Irp->AssociatedIrp.SystemBuffer;
|
||||
PUINT8 BufferEnd = Buffer + IrpSp->Parameters.QueryFile.Length;
|
||||
PUINT8 BufferEnd = Buffer + IrpSp->Parameters.QueryVolume.Length;
|
||||
|
||||
switch (IrpSp->Parameters.QueryVolume.FsInformationClass)
|
||||
{
|
||||
@ -268,6 +301,9 @@ static NTSTATUS FspFsvolQueryVolumeInformation(
|
||||
case FileFsFullSizeInformation:
|
||||
Result = FspFsvolQueryFsFullSizeInformation(FsvolDeviceObject, &Buffer, BufferEnd, 0);
|
||||
break;
|
||||
case FileFsSectorSizeInformation:
|
||||
Result = FspFsvolQueryFsSectorSizeInformation(FsvolDeviceObject, &Buffer, BufferEnd, 0);
|
||||
break;
|
||||
case FileFsSizeInformation:
|
||||
Result = FspFsvolQueryFsSizeInformation(FsvolDeviceObject, &Buffer, BufferEnd, 0);
|
||||
break;
|
||||
@ -310,7 +346,7 @@ NTSTATUS FspFsvolQueryVolumeInformationComplete(
|
||||
|
||||
PDEVICE_OBJECT FsvolDeviceObject = IrpSp->DeviceObject;
|
||||
PUINT8 Buffer = Irp->AssociatedIrp.SystemBuffer;
|
||||
PUINT8 BufferEnd = Buffer + IrpSp->Parameters.QueryFile.Length;
|
||||
PUINT8 BufferEnd = Buffer + IrpSp->Parameters.QueryVolume.Length;
|
||||
|
||||
FspFsvolDeviceSetVolumeInfo(FsvolDeviceObject, &Response->Rsp.QueryVolumeInformation.VolumeInfo);
|
||||
|
||||
|
@ -281,7 +281,11 @@ static NTSTATUS FspVolumeCreateNoLock(
|
||||
if (NT_SUCCESS(Result))
|
||||
{
|
||||
if (0 != FsvrtDeviceObject)
|
||||
{
|
||||
FspFsvrtDeviceExtension(FsvrtDeviceObject)->SectorSize =
|
||||
FsvolDeviceExtension->VolumeParams.SectorSize;
|
||||
Result = FspDeviceInitialize(FsvrtDeviceObject);
|
||||
}
|
||||
}
|
||||
if (!NT_SUCCESS(Result))
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user