sys: IRP_MJ_SET_INFORMATION

This commit is contained in:
Bill Zissimopoulos
2016-02-05 18:30:34 -08:00
parent dc77a1109f
commit 66f54294a2
6 changed files with 253 additions and 16 deletions

View File

@ -17,13 +17,88 @@ FSP_API NTSTATUS FspFileSystemOpQueryInformation(FSP_FILE_SYSTEM *FileSystem,
memset(&FileInfo, 0, sizeof FileInfo);
Result = FileSystem->Interface->GetFileInfo(FileSystem, Request,
(PVOID)Request->Req.Close.UserContext, &FileInfo);
(PVOID)Request->Req.QueryInformation.UserContext, &FileInfo);
if (!NT_SUCCESS(Result))
return FspFileSystemSendResponseWithStatus(FileSystem, Request, Result);
return FspFileSystemSendQueryInformationResponse(FileSystem, Request, &FileInfo);
}
FSP_API NTSTATUS FspFileSystemOpSetInformation(FSP_FILE_SYSTEM *FileSystem,
FSP_FSCTL_TRANSACT_REQ *Request)
{
NTSTATUS Result;
FSP_FSCTL_FILE_INFO FileInfo;
Result = STATUS_INVALID_DEVICE_REQUEST;
memset(&FileInfo, 0, sizeof FileInfo);
switch (Request->Req.SetInformation.FileInformationClass)
{
case 4/*FileBasicInformation*/:
if (0 != FileSystem->Interface->SetBasicInfo)
Result = FileSystem->Interface->SetBasicInfo(FileSystem, Request,
(PVOID)Request->Req.SetInformation.UserContext,
Request->Req.SetInformation.Info.Basic.FileAttributes,
Request->Req.SetInformation.Info.Basic.CreationTime,
Request->Req.SetInformation.Info.Basic.LastAccessTime,
Request->Req.SetInformation.Info.Basic.LastWriteTime,
&FileInfo);
break;
case 19/*FileAllocationInformation*/:
if (0 != FileSystem->Interface->SetAllocationSize)
Result = FileSystem->Interface->SetAllocationSize(FileSystem, Request,
(PVOID)Request->Req.SetInformation.UserContext,
Request->Req.SetInformation.Info.Allocation.AllocationSize,
&FileInfo);
else
if (0 != FileSystem->Interface->GetFileInfo &&
0 != FileSystem->Interface->SetFileSize)
{
Result = FileSystem->Interface->GetFileInfo(FileSystem, Request,
(PVOID)Request->Req.SetInformation.UserContext, &FileInfo);
if (NT_SUCCESS(Result) &&
Request->Req.SetInformation.Info.Allocation.AllocationSize < FileInfo.FileSize)
{
Result = FileSystem->Interface->SetFileSize(FileSystem, Request,
(PVOID)Request->Req.SetInformation.UserContext,
Request->Req.SetInformation.Info.Allocation.AllocationSize,
FALSE,
&FileInfo);
}
}
break;
case 20/*FileEndOfFileInformation*/:
if (0 != FileSystem->Interface->SetFileSize)
Result = FileSystem->Interface->SetFileSize(FileSystem, Request,
(PVOID)Request->Req.SetInformation.UserContext,
Request->Req.SetInformation.Info.EndOfFile.FileSize,
Request->Req.SetInformation.Info.EndOfFile.AdvanceOnly,
&FileInfo);
break;
case 13/*FileDispositionInformation*/:
if (0 != FileSystem->Interface->CanDelete)
if (Request->Req.SetInformation.Info.Disposition.Delete)
Result = FileSystem->Interface->CanDelete(FileSystem, Request,
(PVOID)Request->Req.Close.UserContext);
else
Result = STATUS_SUCCESS;
break;
case 10/*FileRenameInformation*/:
if (0 != FileSystem->Interface->Rename)
Result = FileSystem->Interface->Rename(FileSystem, Request,
(PVOID)Request->Req.SetInformation.UserContext,
(PWSTR)Request->Buffer,
(PWSTR)(Request->Buffer + Request->Req.SetInformation.Info.Rename.NewFileName.Offset),
Request->Req.SetInformation.Info.Rename.ReplaceIfExists);
break;
}
if (!NT_SUCCESS(Result))
return FspFileSystemSendResponseWithStatus(FileSystem, Request, Result);
return FspFileSystemSendSetInformationResponse(FileSystem, Request, &FileInfo);
}
FSP_API NTSTATUS FspFileSystemSendQueryInformationResponse(FSP_FILE_SYSTEM *FileSystem,
FSP_FSCTL_TRANSACT_REQ *Request, const FSP_FSCTL_FILE_INFO *FileInfo)
{
@ -38,3 +113,18 @@ FSP_API NTSTATUS FspFileSystemSendQueryInformationResponse(FSP_FILE_SYSTEM *File
Response.Rsp.QueryInformation.FileInfo = *FileInfo;
return FspFileSystemSendResponse(FileSystem, &Response);
}
FSP_API NTSTATUS FspFileSystemSendSetInformationResponse(FSP_FILE_SYSTEM *FileSystem,
FSP_FSCTL_TRANSACT_REQ *Request, const FSP_FSCTL_FILE_INFO *FileInfo)
{
FSP_FSCTL_TRANSACT_RSP Response;
memset(&Response, 0, sizeof Response);
Response.Size = sizeof Response;
Response.Kind = FspFsctlTransactSetInformationKind;
Response.Hint = Request->Hint;
Response.IoStatus.Status = STATUS_SUCCESS;
Response.IoStatus.Information = 0;
Response.Rsp.SetInformation.FileInfo = *FileInfo;
return FspFileSystemSendResponse(FileSystem, &Response);
}

View File

@ -116,7 +116,8 @@ static NTSTATUS FspFsvolCreate(
USHORT FileAttributes = IrpSp->Parameters.Create.FileAttributes;
PSECURITY_DESCRIPTOR SecurityDescriptor = AccessState->SecurityDescriptor;
ULONG SecurityDescriptorSize = 0;
LARGE_INTEGER AllocationSize = Irp->Overlay.AllocationSize;
UINT64 AllocationSize = Irp->Overlay.AllocationSize.QuadPart;
UINT64 AllocationUnit;
ACCESS_MASK DesiredAccess = IrpSp->Parameters.Create.SecurityContext->DesiredAccess;
USHORT ShareAccess = IrpSp->Parameters.Create.ShareAccess;
PFILE_FULL_EA_INFORMATION EaBuffer = Irp->AssociatedIrp.SystemBuffer;
@ -156,6 +157,11 @@ static NTSTATUS FspFsvolCreate(
SecurityDescriptorSize = RtlLengthSecurityDescriptor(SecurityDescriptor);
}
/* align allocation size */
AllocationUnit = FsvolDeviceExtension->VolumeParams.SectorSize *
FsvolDeviceExtension->VolumeParams.SectorsPerAllocationUnit;
AllocationSize = (AllocationSize + AllocationUnit - 1) / AllocationUnit * AllocationUnit;
/* according to fastfat, filenames that begin with two backslashes are ok */
if (sizeof(WCHAR) * 2 <= FileName.Length &&
L'\\' == FileName.Buffer[1] && L'\\' == FileName.Buffer[0])
@ -323,7 +329,7 @@ static NTSTATUS FspFsvolCreate(
Request->Req.Create.SecurityDescriptor.Offset = 0 == SecurityDescriptorSize ? 0 :
FSP_FSCTL_DEFAULT_ALIGN_UP(Request->FileName.Size);
Request->Req.Create.SecurityDescriptor.Size = (UINT16)SecurityDescriptorSize;
Request->Req.Create.AllocationSize = AllocationSize.QuadPart;
Request->Req.Create.AllocationSize = AllocationSize;
Request->Req.Create.AccessToken = 0;
Request->Req.Create.DesiredAccess = DesiredAccess;
Request->Req.Create.ShareAccess = ShareAccess;

View File

@ -401,10 +401,18 @@ VOID FspFileNodeSetFileInfo(FSP_FILE_NODE *FileNode, PFILE_OBJECT CcFileObject,
{
PAGED_CODE();
UINT64 FileInfoTimeout = FspFsvolDeviceExtension(FileNode->FsvolDeviceObject)->
VolumeParams.FileInfoTimeout * 10000ULL;
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension =
FspFsvolDeviceExtension(FileNode->FsvolDeviceObject);
UINT64 FileInfoTimeout = FsvolDeviceExtension->VolumeParams.FileInfoTimeout * 10000ULL;
UINT64 AllocationSize = FileInfo->AllocationSize > FileInfo->FileSize ?
FileInfo->AllocationSize : FileInfo->FileSize;
UINT64 AllocationUnit;
FileNode->Header.AllocationSize.QuadPart = FileInfo->AllocationSize;
AllocationUnit = FsvolDeviceExtension->VolumeParams.SectorSize *
FsvolDeviceExtension->VolumeParams.SectorsPerAllocationUnit;
AllocationSize = (AllocationSize + AllocationUnit - 1) / AllocationUnit * AllocationUnit;
FileNode->Header.AllocationSize.QuadPart = AllocationSize;
FileNode->Header.FileSize.QuadPart = FileInfo->FileSize;
FileNode->FileAttributes = FileInfo->FileAttributes;

View File

@ -531,9 +531,17 @@ static NTSTATUS FspFsvolSetAllocationInformation(PFILE_OBJECT FileObject,
return STATUS_SUCCESS;
PFILE_ALLOCATION_INFORMATION Info = (PFILE_ALLOCATION_INFORMATION)Buffer;
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension =
FspFsvolDeviceExtension(FileObject->DeviceObject);
UINT64 AllocationSize = Info->AllocationSize.QuadPart;
UINT64 AllocationUnit;
BOOLEAN Success;
Request->Req.SetInformation.Info.Allocation.AllocationSize = Info->AllocationSize.QuadPart;
AllocationUnit = FsvolDeviceExtension->VolumeParams.SectorSize *
FsvolDeviceExtension->VolumeParams.SectorsPerAllocationUnit;
AllocationSize = (AllocationSize + AllocationUnit - 1) / AllocationUnit * AllocationUnit;
Request->Req.SetInformation.Info.Allocation.AllocationSize = AllocationSize;
Success = MmCanFileBeTruncated(FileObject->SectionObjectPointer, &Info->AllocationSize);
if (!Success)
@ -599,11 +607,14 @@ static NTSTATUS FspFsvolSetDispositionInformation(PFILE_OBJECT FileObject,
PFILE_DISPOSITION_INFORMATION Info = (PFILE_DISPOSITION_INFORMATION)Buffer;
BOOLEAN Success;
/* make sure no process is mapping the file as an image */
Success = MmFlushImageSection(FileObject->SectionObjectPointer,
MmFlushForDelete);
if (!Success)
return STATUS_CANNOT_DELETE;
if (Info->DeleteFile)
{
/* make sure no process is mapping the file as an image */
Success = MmFlushImageSection(FileObject->SectionObjectPointer,
MmFlushForDelete);
if (!Success)
return STATUS_CANNOT_DELETE;
}
Request->Req.SetInformation.Info.Disposition.Delete = Info->DeleteFile;
@ -802,20 +813,21 @@ NTSTATUS FspFsvolSetInformationComplete(
ULONG Length = IrpSp->Parameters.SetFile.Length;
FSP_FSCTL_TRANSACT_REQ *Request = FspIrpRequest(Irp);
FspFileNodeSetFileInfo(FileNode, FileObject, &Response->Rsp.SetInformation.FileInfo);
switch (FileInformationClass)
{
case FileAllocationInformation:
FspFileNodeSetFileInfo(FileNode, FileObject, &Response->Rsp.SetInformation.FileInfo);
Result = FspFsvolSetAllocationInformation(FileObject, Buffer, Length, Request, Response);
break;
case FileBasicInformation:
FspFileNodeSetFileInfo(FileNode, FileObject, &Response->Rsp.SetInformation.FileInfo);
Result = FspFsvolSetBasicInformation(FileObject, Buffer, Length, Request, Response);
break;
case FileDispositionInformation:
Result = FspFsvolSetDispositionInformation(FileObject, Buffer, Length, Request, Response);
break;
case FileEndOfFileInformation:
FspFileNodeSetFileInfo(FileNode, FileObject, &Response->Rsp.SetInformation.FileInfo);
Result = FspFsvolSetEndOfFileInformation(FileObject, Buffer, Length,
IrpSp->Parameters.SetFile.AdvanceOnly, Request, Response);
break;