mirror of
https://github.com/winfsp/winfsp.git
synced 2025-06-08 04:52:10 -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(
|
static NTSTATUS FspFsvrtDeviceControl(
|
||||||
PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
|
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(
|
static NTSTATUS FspFsvolDeviceControl(
|
||||||
PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
|
PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
|
||||||
FSP_IOCMPL_DISPATCH FspFsvolDeviceControlComplete;
|
FSP_IOCMPL_DISPATCH FspFsvolDeviceControlComplete;
|
||||||
@ -31,6 +34,7 @@ FSP_DRIVER_DISPATCH FspDeviceControl;
|
|||||||
|
|
||||||
#ifdef ALLOC_PRAGMA
|
#ifdef ALLOC_PRAGMA
|
||||||
#pragma alloc_text(PAGE, FspFsvrtDeviceControl)
|
#pragma alloc_text(PAGE, FspFsvrtDeviceControl)
|
||||||
|
#pragma alloc_text(PAGE, FspFsvrtDeviceControlStorageQuery)
|
||||||
#pragma alloc_text(PAGE, FspFsvolDeviceControl)
|
#pragma alloc_text(PAGE, FspFsvolDeviceControl)
|
||||||
#pragma alloc_text(PAGE, FspFsvolDeviceControlComplete)
|
#pragma alloc_text(PAGE, FspFsvolDeviceControlComplete)
|
||||||
#pragma alloc_text(PAGE, FspFsvolDeviceControlRequestFini)
|
#pragma alloc_text(PAGE, FspFsvolDeviceControlRequestFini)
|
||||||
@ -49,6 +53,9 @@ static NTSTATUS FspFsvrtDeviceControl(
|
|||||||
|
|
||||||
NTSTATUS Result;
|
NTSTATUS Result;
|
||||||
|
|
||||||
|
if (FspFsvrtDeviceControlStorageQuery(FsvrtDeviceObject, Irp, IrpSp, &Result))
|
||||||
|
return Result;
|
||||||
|
|
||||||
if (FspMountdevDeviceControl(FsvrtDeviceObject, Irp, IrpSp, &Result))
|
if (FspMountdevDeviceControl(FsvrtDeviceObject, Irp, IrpSp, &Result))
|
||||||
return Result;
|
return Result;
|
||||||
|
|
||||||
@ -69,6 +76,62 @@ static NTSTATUS FspFsvrtDeviceControl(
|
|||||||
return STATUS_UNRECOGNIZED_VOLUME;
|
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(
|
static NTSTATUS FspFsvolDeviceControl(
|
||||||
PDEVICE_OBJECT FsvolDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
|
PDEVICE_OBJECT FsvolDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
|
||||||
{
|
{
|
||||||
@ -79,11 +142,6 @@ static NTSTATUS FspFsvolDeviceControl(
|
|||||||
ULONG IoControlCode = IrpSp->Parameters.DeviceIoControl.IoControlCode;
|
ULONG IoControlCode = IrpSp->Parameters.DeviceIoControl.IoControlCode;
|
||||||
NTSTATUS Result;
|
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:
|
* 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.
|
* METHOD_BUFFERED will be forwarded.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
/* do we support DeviceControl? */
|
/* do we support DeviceControl? */
|
||||||
if (!FsvolDeviceExtension->VolumeParams.DeviceControl)
|
if (!FsvolDeviceExtension->VolumeParams.DeviceControl)
|
||||||
return STATUS_INVALID_DEVICE_REQUEST;
|
return STATUS_INVALID_DEVICE_REQUEST;
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
#define POOL_NX_OPTIN 1
|
#define POOL_NX_OPTIN 1
|
||||||
#include <ntifs.h>
|
#include <ntifs.h>
|
||||||
#include <mountdev.h>
|
#include <mountdev.h>
|
||||||
|
#include <ntddstor.h>
|
||||||
#include <ntstrsafe.h>
|
#include <ntstrsafe.h>
|
||||||
#include <wdmsec.h>
|
#include <wdmsec.h>
|
||||||
#include <winfsp/fsctl.h>
|
#include <winfsp/fsctl.h>
|
||||||
@ -1106,6 +1107,7 @@ typedef struct
|
|||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
FSP_DEVICE_EXTENSION Base;
|
FSP_DEVICE_EXTENSION Base;
|
||||||
|
UINT16 SectorSize;
|
||||||
LONG IsMountdev;
|
LONG IsMountdev;
|
||||||
BOOLEAN Persistent;
|
BOOLEAN Persistent;
|
||||||
GUID UniqueId;
|
GUID UniqueId;
|
||||||
|
@ -28,6 +28,9 @@ static NTSTATUS FspFsvolQueryFsDeviceInformation(
|
|||||||
static NTSTATUS FspFsvolQueryFsFullSizeInformation(
|
static NTSTATUS FspFsvolQueryFsFullSizeInformation(
|
||||||
PDEVICE_OBJECT FsvolDeviceObject, PUINT8 *PBuffer, PUINT8 BufferEnd,
|
PDEVICE_OBJECT FsvolDeviceObject, PUINT8 *PBuffer, PUINT8 BufferEnd,
|
||||||
const FSP_FSCTL_VOLUME_INFO *VolumeInfo);
|
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(
|
static NTSTATUS FspFsvolQueryFsSizeInformation(
|
||||||
PDEVICE_OBJECT FsvolDeviceObject, PUINT8 *PBuffer, PUINT8 BufferEnd,
|
PDEVICE_OBJECT FsvolDeviceObject, PUINT8 *PBuffer, PUINT8 BufferEnd,
|
||||||
const FSP_FSCTL_VOLUME_INFO *VolumeInfo);
|
const FSP_FSCTL_VOLUME_INFO *VolumeInfo);
|
||||||
@ -50,6 +53,7 @@ FSP_DRIVER_DISPATCH FspSetVolumeInformation;
|
|||||||
#pragma alloc_text(PAGE, FspFsvolQueryFsAttributeInformation)
|
#pragma alloc_text(PAGE, FspFsvolQueryFsAttributeInformation)
|
||||||
#pragma alloc_text(PAGE, FspFsvolQueryFsDeviceInformation)
|
#pragma alloc_text(PAGE, FspFsvolQueryFsDeviceInformation)
|
||||||
#pragma alloc_text(PAGE, FspFsvolQueryFsFullSizeInformation)
|
#pragma alloc_text(PAGE, FspFsvolQueryFsFullSizeInformation)
|
||||||
|
#pragma alloc_text(PAGE, FspFsvolQueryFsSectorSizeInformation)
|
||||||
#pragma alloc_text(PAGE, FspFsvolQueryFsSizeInformation)
|
#pragma alloc_text(PAGE, FspFsvolQueryFsSizeInformation)
|
||||||
#pragma alloc_text(PAGE, FspFsvolQueryFsVolumeInformation)
|
#pragma alloc_text(PAGE, FspFsvolQueryFsVolumeInformation)
|
||||||
#pragma alloc_text(PAGE, FspFsvolQueryVolumeInformation)
|
#pragma alloc_text(PAGE, FspFsvolQueryVolumeInformation)
|
||||||
@ -186,6 +190,35 @@ static NTSTATUS FspFsvolQueryFsFullSizeInformation(
|
|||||||
return STATUS_SUCCESS;
|
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(
|
static NTSTATUS FspFsvolQueryFsSizeInformation(
|
||||||
PDEVICE_OBJECT FsvolDeviceObject, PUINT8 *PBuffer, PUINT8 BufferEnd,
|
PDEVICE_OBJECT FsvolDeviceObject, PUINT8 *PBuffer, PUINT8 BufferEnd,
|
||||||
const FSP_FSCTL_VOLUME_INFO *VolumeInfo)
|
const FSP_FSCTL_VOLUME_INFO *VolumeInfo)
|
||||||
@ -255,7 +288,7 @@ static NTSTATUS FspFsvolQueryVolumeInformation(
|
|||||||
|
|
||||||
NTSTATUS Result;
|
NTSTATUS Result;
|
||||||
PUINT8 Buffer = Irp->AssociatedIrp.SystemBuffer;
|
PUINT8 Buffer = Irp->AssociatedIrp.SystemBuffer;
|
||||||
PUINT8 BufferEnd = Buffer + IrpSp->Parameters.QueryFile.Length;
|
PUINT8 BufferEnd = Buffer + IrpSp->Parameters.QueryVolume.Length;
|
||||||
|
|
||||||
switch (IrpSp->Parameters.QueryVolume.FsInformationClass)
|
switch (IrpSp->Parameters.QueryVolume.FsInformationClass)
|
||||||
{
|
{
|
||||||
@ -268,6 +301,9 @@ static NTSTATUS FspFsvolQueryVolumeInformation(
|
|||||||
case FileFsFullSizeInformation:
|
case FileFsFullSizeInformation:
|
||||||
Result = FspFsvolQueryFsFullSizeInformation(FsvolDeviceObject, &Buffer, BufferEnd, 0);
|
Result = FspFsvolQueryFsFullSizeInformation(FsvolDeviceObject, &Buffer, BufferEnd, 0);
|
||||||
break;
|
break;
|
||||||
|
case FileFsSectorSizeInformation:
|
||||||
|
Result = FspFsvolQueryFsSectorSizeInformation(FsvolDeviceObject, &Buffer, BufferEnd, 0);
|
||||||
|
break;
|
||||||
case FileFsSizeInformation:
|
case FileFsSizeInformation:
|
||||||
Result = FspFsvolQueryFsSizeInformation(FsvolDeviceObject, &Buffer, BufferEnd, 0);
|
Result = FspFsvolQueryFsSizeInformation(FsvolDeviceObject, &Buffer, BufferEnd, 0);
|
||||||
break;
|
break;
|
||||||
@ -310,7 +346,7 @@ NTSTATUS FspFsvolQueryVolumeInformationComplete(
|
|||||||
|
|
||||||
PDEVICE_OBJECT FsvolDeviceObject = IrpSp->DeviceObject;
|
PDEVICE_OBJECT FsvolDeviceObject = IrpSp->DeviceObject;
|
||||||
PUINT8 Buffer = Irp->AssociatedIrp.SystemBuffer;
|
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);
|
FspFsvolDeviceSetVolumeInfo(FsvolDeviceObject, &Response->Rsp.QueryVolumeInformation.VolumeInfo);
|
||||||
|
|
||||||
|
@ -281,8 +281,12 @@ static NTSTATUS FspVolumeCreateNoLock(
|
|||||||
if (NT_SUCCESS(Result))
|
if (NT_SUCCESS(Result))
|
||||||
{
|
{
|
||||||
if (0 != FsvrtDeviceObject)
|
if (0 != FsvrtDeviceObject)
|
||||||
|
{
|
||||||
|
FspFsvrtDeviceExtension(FsvrtDeviceObject)->SectorSize =
|
||||||
|
FsvolDeviceExtension->VolumeParams.SectorSize;
|
||||||
Result = FspDeviceInitialize(FsvrtDeviceObject);
|
Result = FspDeviceInitialize(FsvrtDeviceObject);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (!NT_SUCCESS(Result))
|
if (!NT_SUCCESS(Result))
|
||||||
{
|
{
|
||||||
if (0 != FsvrtDeviceObject)
|
if (0 != FsvrtDeviceObject)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user