sys: FSP_FSCTL_VOLUME_PARAMS

This commit is contained in:
Bill Zissimopoulos 2015-11-28 17:14:11 -08:00
parent d724b3a307
commit 76af18e4d0
4 changed files with 32 additions and 15 deletions

View File

@ -45,8 +45,14 @@ extern const __declspec(selectany) GUID FspFsvrtDeviceClassGuid =
#pragma warning(disable:4200) /* zero-sized array in struct/union */ #pragma warning(disable:4200) /* zero-sized array in struct/union */
typedef struct typedef struct
{ {
UINT16 Version;
UINT16 SectorSize;
} FSP_FSCTL_VOLUME_PARAMS;
typedef struct
{
UINT16 Version;
UINT16 Size;
UINT64 Hint; UINT64 Hint;
UINT32 Size;
UINT8 Kind; UINT8 Kind;
union union
{ {
@ -55,8 +61,9 @@ typedef struct
} FSP_FSCTL_TRANSACT_REQ; } FSP_FSCTL_TRANSACT_REQ;
typedef struct typedef struct
{ {
UINT16 Version;
UINT16 Size;
UINT64 Hint; UINT64 Hint;
UINT32 Size;
struct struct
{ {
UINT32 Status; UINT32 Status;
@ -101,7 +108,8 @@ static inline const FSP_FSCTL_TRANSACT_RSP *FspFsctlTransactConsumeResponse(
} }
#if !defined(WINFSP_SYS_INTERNAL) #if !defined(WINFSP_SYS_INTERNAL)
FSP_API NTSTATUS FspFsctlCreateVolume(PWSTR DevicePath, PSECURITY_DESCRIPTOR SecurityDescriptor, FSP_API NTSTATUS FspFsctlCreateVolume(PWSTR DevicePath,
const FSP_FSCTL_VOLUME_PARAMS *Params, PSECURITY_DESCRIPTOR SecurityDescriptor,
PHANDLE *PVolumeHandle); PHANDLE *PVolumeHandle);
FSP_API NTSTATUS FspFsctlOpenVolume(PWSTR VolumePath, FSP_API NTSTATUS FspFsctlOpenVolume(PWSTR VolumePath,
PHANDLE *PVolumeHandle); PHANDLE *PVolumeHandle);

View File

@ -16,12 +16,14 @@ static inline VOID GlobalDevicePath(PWCHAR DevicePathBuf, SIZE_T DevicePathSize,
L'\\' == DevicePath[0] ? GLOBALROOT "%S" : GLOBALROOT "\\Device\\%S", DevicePath); L'\\' == DevicePath[0] ? GLOBALROOT "%S" : GLOBALROOT "\\Device\\%S", DevicePath);
} }
FSP_API NTSTATUS FspFsctlCreateVolume(PWSTR DevicePath, PSECURITY_DESCRIPTOR SecurityDescriptor, FSP_API NTSTATUS FspFsctlCreateVolume(PWSTR DevicePath,
const FSP_FSCTL_VOLUME_PARAMS *Params, PSECURITY_DESCRIPTOR SecurityDescriptor,
PHANDLE *PVolumeHandle) PHANDLE *PVolumeHandle)
{ {
NTSTATUS Result = STATUS_SUCCESS; NTSTATUS Result = STATUS_SUCCESS;
WCHAR DevicePathBuf[(sizeof GLOBALROOT + FSP_FSCTL_CREATE_BUFFER_SIZE) / sizeof(WCHAR)]; WCHAR DevicePathBuf[(sizeof GLOBALROOT + FSP_FSCTL_CREATE_BUFFER_SIZE) / sizeof(WCHAR)];
WCHAR VolumePathBuf[FSP_FSCTL_CREATE_BUFFER_SIZE / sizeof(WCHAR)]; WCHAR VolumePathBuf[FSP_FSCTL_CREATE_BUFFER_SIZE / sizeof(WCHAR)];
FSP_FSCTL_VOLUME_PARAMS *ParamsBuf;
PSECURITY_DESCRIPTOR SecurityDescriptorBuf = 0; PSECURITY_DESCRIPTOR SecurityDescriptorBuf = 0;
DWORD SecurityDescriptorSize, Bytes; DWORD SecurityDescriptorSize, Bytes;
HANDLE DeviceHandle = INVALID_HANDLE_VALUE; HANDLE DeviceHandle = INVALID_HANDLE_VALUE;
@ -33,17 +35,19 @@ FSP_API NTSTATUS FspFsctlCreateVolume(PWSTR DevicePath, PSECURITY_DESCRIPTOR Sec
SecurityDescriptorSize = 0; SecurityDescriptorSize = 0;
if (!MakeSelfRelativeSD(SecurityDescriptor, 0, &SecurityDescriptorSize)) if (!MakeSelfRelativeSD(SecurityDescriptor, 0, &SecurityDescriptorSize))
{ {
SecurityDescriptorBuf = malloc(SecurityDescriptorSize); ParamsBuf = malloc(sizeof *ParamsBuf + SecurityDescriptorSize);
if (0 == SecurityDescriptorBuf) if (0 == ParamsBuf)
{ {
Result = STATUS_INSUFFICIENT_RESOURCES; Result = STATUS_INSUFFICIENT_RESOURCES;
goto exit; goto exit;
} }
SecurityDescriptorBuf = (PVOID)(ParamsBuf + 1);
if (!MakeSelfRelativeSD(SecurityDescriptor, SecurityDescriptorBuf, &SecurityDescriptorSize)) if (!MakeSelfRelativeSD(SecurityDescriptor, SecurityDescriptorBuf, &SecurityDescriptorSize))
{ {
Result = FspNtStatusFromWin32(GetLastError()); Result = FspNtStatusFromWin32(GetLastError());
goto exit; goto exit;
} }
*ParamsBuf = *Params;
} }
DeviceHandle = CreateFileW(DevicePathBuf, DeviceHandle = CreateFileW(DevicePathBuf,
@ -55,7 +59,7 @@ FSP_API NTSTATUS FspFsctlCreateVolume(PWSTR DevicePath, PSECURITY_DESCRIPTOR Sec
} }
if (!DeviceIoControl(DeviceHandle, FSP_FSCTL_CREATE, if (!DeviceIoControl(DeviceHandle, FSP_FSCTL_CREATE,
SecurityDescriptorBuf, SecurityDescriptorSize, VolumePathBuf, sizeof VolumePathBuf, ParamsBuf, sizeof *ParamsBuf + SecurityDescriptorSize, VolumePathBuf, sizeof VolumePathBuf,
&Bytes, 0)) &Bytes, 0))
{ {
Result = FspNtStatusFromWin32(GetLastError()); Result = FspNtStatusFromWin32(GetLastError());

View File

@ -253,6 +253,7 @@ typedef struct
typedef struct typedef struct
{ {
FSP_DEVICE_EXTENSION Base; FSP_DEVICE_EXTENSION Base;
FSP_FSCTL_VOLUME_PARAMS VolumeParams;
FSP_IOQ Ioq; FSP_IOQ Ioq;
UINT8 SecurityDescriptorBuf[]; UINT8 SecurityDescriptorBuf[];
} FSP_FSVRT_DEVICE_EXTENSION; } FSP_FSVRT_DEVICE_EXTENSION;

View File

@ -44,8 +44,11 @@ static NTSTATUS FspFsctlCreateVolume(
ULONG InputBufferLength = IrpSp->Parameters.FileSystemControl.InputBufferLength; ULONG InputBufferLength = IrpSp->Parameters.FileSystemControl.InputBufferLength;
ULONG OutputBufferLength = IrpSp->Parameters.FileSystemControl.OutputBufferLength; ULONG OutputBufferLength = IrpSp->Parameters.FileSystemControl.OutputBufferLength;
PVOID SystemBuffer = Irp->AssociatedIrp.SystemBuffer; PVOID SystemBuffer = Irp->AssociatedIrp.SystemBuffer;
if (0 == InputBufferLength || 0 == SystemBuffer || const FSP_FSCTL_VOLUME_PARAMS *Params = SystemBuffer;
!RtlValidRelativeSecurityDescriptor(SystemBuffer, InputBufferLength, PSECURITY_DESCRIPTOR SecurityDescriptor = (PVOID)(Params + 1);
DWORD SecurityDescriptorSize = InputBufferLength - sizeof *Params;
if (sizeof *Params >= InputBufferLength || 0 == SystemBuffer ||
!RtlValidRelativeSecurityDescriptor(SecurityDescriptor, SecurityDescriptorSize,
OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION)) OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION))
return STATUS_INVALID_PARAMETER; return STATUS_INVALID_PARAMETER;
if (FSP_FSCTL_CREATE_BUFFER_SIZE > OutputBufferLength) if (FSP_FSCTL_CREATE_BUFFER_SIZE > OutputBufferLength)
@ -60,10 +63,10 @@ static NTSTATUS FspFsctlCreateVolume(
return Result; return Result;
/* copy the security descriptor from the system buffer to a temporary one */ /* copy the security descriptor from the system buffer to a temporary one */
PVOID SecurityDescriptor = ExAllocatePoolWithTag(PagedPool, InputBufferLength, FSP_TAG); PVOID SecurityDescriptorBuf = ExAllocatePoolWithTag(PagedPool, SecurityDescriptorSize, FSP_TAG);
if (0 == SecurityDescriptor) if (0 == SecurityDescriptorBuf)
return STATUS_INSUFFICIENT_RESOURCES; return STATUS_INSUFFICIENT_RESOURCES;
RtlCopyMemory(SecurityDescriptor, SystemBuffer, InputBufferLength); RtlCopyMemory(SecurityDescriptorBuf, SecurityDescriptor, SecurityDescriptorSize);
/* create the virtual volume device */ /* create the virtual volume device */
PDEVICE_OBJECT FsvrtDeviceObject; PDEVICE_OBJECT FsvrtDeviceObject;
@ -78,7 +81,7 @@ static NTSTATUS FspFsctlCreateVolume(
Guid.Data4[4], Guid.Data4[5], Guid.Data4[6], Guid.Data4[7]); Guid.Data4[4], Guid.Data4[5], Guid.Data4[6], Guid.Data4[7]);
ASSERT(NT_SUCCESS(Result)); ASSERT(NT_SUCCESS(Result));
Result = IoCreateDeviceSecure(DeviceObject->DriverObject, Result = IoCreateDeviceSecure(DeviceObject->DriverObject,
sizeof(FSP_FSVRT_DEVICE_EXTENSION) + InputBufferLength, &DeviceName, FILE_DEVICE_VIRTUAL_DISK, sizeof(FSP_FSVRT_DEVICE_EXTENSION) + SecurityDescriptorSize, &DeviceName, FILE_DEVICE_VIRTUAL_DISK,
FILE_DEVICE_SECURE_OPEN, FALSE, FILE_DEVICE_SECURE_OPEN, FALSE,
&DeviceSddl, 0, &DeviceSddl, 0,
&FsvrtDeviceObject); &FsvrtDeviceObject);
@ -86,14 +89,15 @@ static NTSTATUS FspFsctlCreateVolume(
{ {
FSP_FSVRT_DEVICE_EXTENSION *FsvrtDeviceExtension = FspFsvrtDeviceExtension(FsvrtDeviceObject); FSP_FSVRT_DEVICE_EXTENSION *FsvrtDeviceExtension = FspFsvrtDeviceExtension(FsvrtDeviceObject);
FsvrtDeviceExtension->Base.Kind = FspFsvrtDeviceExtensionKind; FsvrtDeviceExtension->Base.Kind = FspFsvrtDeviceExtensionKind;
FsvrtDeviceExtension->VolumeParams = *Params;
FspIoqInitialize(&FsvrtDeviceExtension->Ioq); FspIoqInitialize(&FsvrtDeviceExtension->Ioq);
RtlCopyMemory(FspFsvrtDeviceExtension(FsvrtDeviceObject)->SecurityDescriptorBuf, RtlCopyMemory(FspFsvrtDeviceExtension(FsvrtDeviceObject)->SecurityDescriptorBuf,
SecurityDescriptor, InputBufferLength); SecurityDescriptorBuf, SecurityDescriptorSize);
Irp->IoStatus.Information = DeviceName.Length + 1; Irp->IoStatus.Information = DeviceName.Length + 1;
} }
/* free the temporary security descriptor */ /* free the temporary security descriptor */
ExFreePoolWithTag(SecurityDescriptor, FSP_TAG); ExFreePoolWithTag(SecurityDescriptorBuf, FSP_TAG);
return Result; return Result;
} }