Merge branch 'pvt-devctl'

This commit is contained in:
Bill Zissimopoulos
2018-05-08 20:49:22 -07:00
18 changed files with 441 additions and 7 deletions

View File

@ -162,6 +162,7 @@ FSP_API NTSTATUS FspFileSystemCreate(PWSTR DevicePath,
FileSystem->Operations[FspFsctlTransactSetVolumeInformationKind] = FspFileSystemOpSetVolumeInformation;
FileSystem->Operations[FspFsctlTransactQueryDirectoryKind] = FspFileSystemOpQueryDirectory;
FileSystem->Operations[FspFsctlTransactFileSystemControlKind] = FspFileSystemOpFileSystemControl;
FileSystem->Operations[FspFsctlTransactDeviceControlKind] = FspFileSystemOpDeviceControl;
FileSystem->Operations[FspFsctlTransactQuerySecurityKind] = FspFileSystemOpQuerySecurity;
FileSystem->Operations[FspFsctlTransactSetSecurityKind] = FspFileSystemOpSetSecurity;
FileSystem->Operations[FspFsctlTransactQueryStreamInformationKind] = FspFileSystemOpQueryStreamInformation;

View File

@ -1247,6 +1247,30 @@ FSP_API NTSTATUS FspFileSystemOpFileSystemControl(FSP_FILE_SYSTEM *FileSystem,
return Result;
}
FSP_API NTSTATUS FspFileSystemOpDeviceControl(FSP_FILE_SYSTEM *FileSystem,
FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response)
{
NTSTATUS Result;
ULONG BytesTransferred;
if (0 == FileSystem->Interface->Control)
return STATUS_INVALID_DEVICE_REQUEST;
Result = FileSystem->Interface->Control(FileSystem,
(PVOID)ValOfFileContext(Request->Req.DeviceControl),
Request->Req.DeviceControl.IoControlCode,
Request->Buffer, Request->Req.DeviceControl.Buffer.Size,
Response->Buffer, Request->Req.DeviceControl.OutputLength/* FSD guarantees correct size! */,
&BytesTransferred);
if (!NT_SUCCESS(Result))
return STATUS_BUFFER_OVERFLOW != Result ? Result : STATUS_BUFFER_TOO_SMALL;
Response->Size = (UINT16)(sizeof *Response + BytesTransferred);
Response->Rsp.DeviceControl.Buffer.Offset = 0;
Response->Rsp.DeviceControl.Buffer.Size = (UINT16)BytesTransferred;
return STATUS_SUCCESS;
}
FSP_API NTSTATUS FspFileSystemOpQuerySecurity(FSP_FILE_SYSTEM *FileSystem,
FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response)
{

View File

@ -649,6 +649,7 @@ FSP_FUSE_API struct fuse *fsp_fuse_new(struct fsp_fuse_env *env,
opt_data.VolumeParams.ReadOnlyVolume = FALSE;
opt_data.VolumeParams.PostCleanupWhenModifiedOnly = TRUE;
opt_data.VolumeParams.PassQueryDirectoryFileName = TRUE;
opt_data.VolumeParams.DeviceControl = TRUE;
opt_data.VolumeParams.UmFileContextIsUserContext2 = TRUE;
if (L'\0' == opt_data.VolumeParams.FileSystemName[0])
memcpy(opt_data.VolumeParams.FileSystemName, L"FUSE", 5 * sizeof(WCHAR));

View File

@ -2125,6 +2125,47 @@ static NTSTATUS fsp_fuse_intf_DeleteReparsePoint(FSP_FILE_SYSTEM *FileSystem,
return STATUS_ACCESS_DENIED;
}
static NTSTATUS fsp_fuse_intf_Control(FSP_FILE_SYSTEM *FileSystem,
PVOID FileNode, UINT32 ControlCode,
PVOID InputBuffer, ULONG InputBufferLength,
PVOID OutputBuffer, ULONG OutputBufferLength, PULONG PBytesTransferred)
{
struct fuse *f = FileSystem->UserContext;
struct fsp_fuse_file_desc *filedesc = FileNode;
struct fuse_file_info fi;
int cmd;
int err;
if (0 == f->ops.ioctl)
return STATUS_INVALID_DEVICE_REQUEST;
if (FSP_FUSE_DEVICE_TYPE != DEVICE_TYPE_FROM_CTL_CODE(ControlCode))
return STATUS_INVALID_DEVICE_REQUEST;
if (0 != InputBufferLength && 0 != OutputBufferLength &&
InputBufferLength != OutputBufferLength)
return STATUS_INVALID_DEVICE_REQUEST;
memset(&fi, 0, sizeof fi);
fi.flags = filedesc->OpenFlags;
fi.fh = filedesc->FileHandle;
/* construct a Linux compatible ioctl code */
cmd = FSP_FUSE_IOCTL((ControlCode >> 2) & 0xfff, InputBufferLength, OutputBufferLength);
if (0 == OutputBufferLength)
err = f->ops.ioctl(filedesc->PosixPath, cmd, 0, &fi, 0, InputBuffer);
else
{
if (0 != InputBufferLength)
// OutputBuffer points to Response->Buffer which is FSP_FSCTL_TRANSACT_RSP_BUFFER_SIZEMAX long
memcpy(OutputBuffer, InputBuffer, InputBufferLength);
err = f->ops.ioctl(filedesc->PosixPath, cmd, 0, &fi, 0, OutputBuffer);
}
return fsp_fuse_ntstatus_from_errno(f->env, err);
}
FSP_FILE_SYSTEM_INTERFACE fsp_fuse_intf =
{
fsp_fuse_intf_GetVolumeInfo,
@ -2152,6 +2193,7 @@ FSP_FILE_SYSTEM_INTERFACE fsp_fuse_intf =
fsp_fuse_intf_DeleteReparsePoint,
0,
fsp_fuse_intf_GetDirInfoByName,
fsp_fuse_intf_Control,
};
/*