sys: IRP_MJ_SET_INFORMATION

This commit is contained in:
Bill Zissimopoulos 2016-02-03 17:45:27 -08:00
parent 71eed46e42
commit fcd9945506
2 changed files with 211 additions and 129 deletions

View File

@ -307,8 +307,6 @@ static NTSTATUS FspFsvolCreate(
ClearFlag(FileAttributes, FILE_ATTRIBUTE_NORMAL | FILE_ATTRIBUTE_DIRECTORY); ClearFlag(FileAttributes, FILE_ATTRIBUTE_NORMAL | FILE_ATTRIBUTE_DIRECTORY);
if (CreateOptions & FILE_DIRECTORY_FILE) if (CreateOptions & FILE_DIRECTORY_FILE)
SetFlag(FileAttributes, FILE_ATTRIBUTE_DIRECTORY); SetFlag(FileAttributes, FILE_ATTRIBUTE_DIRECTORY);
else
ClearFlag(FileAttributes, FILE_ATTRIBUTE_DIRECTORY);
/* /*
* The new request is associated with our IRP. Go ahead and associate our FileNode/FileDesc * The new request is associated with our IRP. Go ahead and associate our FileNode/FileDesc
@ -567,7 +565,7 @@ NTSTATUS FspFsvolCreateComplete(
* point though. * point though.
*/ */
BOOLEAN FlushImage = BOOLEAN FlushImage =
!FlagOn(Response->Rsp.Create.Opened.FileInfo.FileAttributes, FILE_ATTRIBUTE_DIRECTORY) && !FileNode->IsDirectory &&
(FlagOn(Response->Rsp.Create.Opened.GrantedAccess, FILE_WRITE_DATA) || (FlagOn(Response->Rsp.Create.Opened.GrantedAccess, FILE_WRITE_DATA) ||
BooleanFlagOn(IrpSp->Parameters.Create.Options, FILE_DELETE_ON_CLOSE)); BooleanFlagOn(IrpSp->Parameters.Create.Options, FILE_DELETE_ON_CLOSE));
@ -579,12 +577,11 @@ NTSTATUS FspFsvolCreateComplete(
* Oh, noes! We have to go back to user mode to overwrite the file! * Oh, noes! We have to go back to user mode to overwrite the file!
*/ */
/* save the old Request FileAttributes and make them compatible with the open file */ USHORT FileAttributes = IrpSp->Parameters.Create.FileAttributes;
UINT32 FileAttributes = Request->Req.Create.FileAttributes;
if (FlagOn(Response->Rsp.Create.Opened.FileInfo.FileAttributes, FILE_ATTRIBUTE_DIRECTORY)) ClearFlag(FileAttributes, FILE_ATTRIBUTE_NORMAL | FILE_ATTRIBUTE_DIRECTORY);
if (FileNode->IsDirectory)
SetFlag(FileAttributes, FILE_ATTRIBUTE_DIRECTORY); SetFlag(FileAttributes, FILE_ATTRIBUTE_DIRECTORY);
else
ClearFlag(FileAttributes, FILE_ATTRIBUTE_DIRECTORY);
/* delete the old request */ /* delete the old request */
FspIrpRequest(Irp) = 0; FspIrpRequest(Irp) = 0;

View File

@ -43,8 +43,7 @@ static NTSTATUS FspFsvolSetEndOfFileInformation(PFILE_OBJECT FileObject,
PVOID Buffer, ULONG Length, BOOLEAN AdvanceOnly, PVOID Buffer, ULONG Length, BOOLEAN AdvanceOnly,
FSP_FSCTL_TRANSACT_REQ *Request, const FSP_FSCTL_TRANSACT_RSP *Response); FSP_FSCTL_TRANSACT_REQ *Request, const FSP_FSCTL_TRANSACT_RSP *Response);
static NTSTATUS FspFsvolSetPositionInformation(PFILE_OBJECT FileObject, static NTSTATUS FspFsvolSetPositionInformation(PFILE_OBJECT FileObject,
PVOID Buffer, ULONG Length, PVOID Buffer, ULONG Length);
FSP_FSCTL_TRANSACT_REQ *Request, const FSP_FSCTL_TRANSACT_RSP *Response);
static NTSTATUS FspFsvolSetRenameInformation(PFILE_OBJECT FileObject, static NTSTATUS FspFsvolSetRenameInformation(PFILE_OBJECT FileObject,
PVOID Buffer, ULONG Length, PVOID Buffer, ULONG Length,
FSP_FSCTL_TRANSACT_REQ *Request, const FSP_FSCTL_TRANSACT_RSP *Response); FSP_FSCTL_TRANSACT_REQ *Request, const FSP_FSCTL_TRANSACT_RSP *Response);
@ -511,56 +510,34 @@ NTSTATUS FspFsvolQueryInformationComplete(
IrpSp->FileObject); IrpSp->FileObject);
} }
#if 0
static NTSTATUS FspFsvolSetAllocationInformation(PFILE_OBJECT FileObject, static NTSTATUS FspFsvolSetAllocationInformation(PFILE_OBJECT FileObject,
PVOID Buffer, ULONG Length, PVOID Buffer, ULONG Length,
FSP_FSCTL_TRANSACT_REQ *Request, const FSP_FSCTL_TRANSACT_RSP *Response) FSP_FSCTL_TRANSACT_REQ *Request, const FSP_FSCTL_TRANSACT_RSP *Response)
{ {
PAGED_CODE(); PAGED_CODE();
if (0 != Request) if (0 == Request)
{ {
if (sizeof(FILE_ALLOCATION_INFORMATION) > Length) if (sizeof(FILE_ALLOCATION_INFORMATION) > Length)
return STATUS_INVALID_PARAMETER; return STATUS_INVALID_PARAMETER;
return STATUS_SUCCESS;
}
if (0 != Response)
return STATUS_SUCCESS;
PFILE_ALLOCATION_INFORMATION Info = (PFILE_ALLOCATION_INFORMATION)Buffer; PFILE_ALLOCATION_INFORMATION Info = (PFILE_ALLOCATION_INFORMATION)Buffer;
FSP_FILE_NODE *FileNode = FileObject->FsContext;
BOOLEAN Success; BOOLEAN Success;
Request->Req.SetInformation.Info.Allocation.AllocationSize = Info->AllocationSize.QuadPart; Request->Req.SetInformation.Info.Allocation.AllocationSize = Info->AllocationSize.QuadPart;
FspFileNodeAcquireExclusive(FileNode, Full);
Success = MmCanFileBeTruncated(FileObject->SectionObjectPointer, &Info->AllocationSize); Success = MmCanFileBeTruncated(FileObject->SectionObjectPointer, &Info->AllocationSize);
if (!Success) if (!Success)
{
FspFileNodeRelease(FileNode, Full);
return STATUS_USER_MAPPED_FILE; return STATUS_USER_MAPPED_FILE;
}
FspIopRequestContext(Request, RequestFileNode) = FileNode;
FspIopRequestContext(Request, RequestAcquireFlags) = (PVOID)FspFileNodeAcquireFull;
return FSP_STATUS_IOQ_POST;
}
else
{
FspIopRequestContext(Request, RequestFileNode) = 0;
FspIopRequestContext(Request, RequestAcquireFlags) = 0;
FSP_FILE_NODE *FileNode = FileObject->FsContext;
FileNode->Header.AllocationSize.QuadPart = Response->Rsp.SetInformation.FileInfo.AllocationSize;
FileNode->Header.FileSize.QuadPart = Response->Rsp.SetInformation.FileInfo.FileSize;
FileNode->CcStatus = FspCcSetFileSizes(
FileObject, (PCC_FILE_SIZES)&FileNode->Header.AllocationSize);
FspFileNodeRelease(FileNode, Full);
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
}
static NTSTATUS FspFsvolSetBasicInformation(PFILE_OBJECT FileObject, static NTSTATUS FspFsvolSetBasicInformation(PFILE_OBJECT FileObject,
PVOID Buffer, ULONG Length, PVOID Buffer, ULONG Length,
@ -568,7 +545,36 @@ static NTSTATUS FspFsvolSetBasicInformation(PFILE_OBJECT FileObject,
{ {
PAGED_CODE(); PAGED_CODE();
return STATUS_INVALID_DEVICE_REQUEST; if (0 == Request)
{
if (sizeof(FILE_BASIC_INFORMATION) > Length)
return STATUS_INVALID_PARAMETER;
return STATUS_SUCCESS;
}
if (0 != Response)
return STATUS_SUCCESS;
PFILE_BASIC_INFORMATION Info = (PFILE_BASIC_INFORMATION)Buffer;
FSP_FILE_NODE *FileNode = FileObject->FsContext;
UINT32 FileAttributes = Info->FileAttributes;
if (0 == FileAttributes)
FileAttributes = ((UINT32)-1);
else
{
ClearFlag(FileAttributes, FILE_ATTRIBUTE_NORMAL | FILE_ATTRIBUTE_DIRECTORY);
if (FileNode->IsDirectory)
SetFlag(FileAttributes, FILE_ATTRIBUTE_DIRECTORY);
}
Request->Req.SetInformation.Info.Basic.FileAttributes = Info->FileAttributes;
Request->Req.SetInformation.Info.Basic.CreationTime = Info->CreationTime.QuadPart;
Request->Req.SetInformation.Info.Basic.LastAccessTime = Info->LastAccessTime.QuadPart;
Request->Req.SetInformation.Info.Basic.LastWriteTime = Info->LastWriteTime.QuadPart;
return STATUS_SUCCESS;
} }
static NTSTATUS FspFsvolSetDispositionInformation(PFILE_OBJECT FileObject, static NTSTATUS FspFsvolSetDispositionInformation(PFILE_OBJECT FileObject,
@ -577,7 +583,32 @@ static NTSTATUS FspFsvolSetDispositionInformation(PFILE_OBJECT FileObject,
{ {
PAGED_CODE(); PAGED_CODE();
return STATUS_INVALID_DEVICE_REQUEST; if (0 == Request)
{
if (sizeof(FILE_DISPOSITION_INFORMATION) > Length)
return STATUS_INVALID_PARAMETER;
return STATUS_SUCCESS;
}
if (0 == Response)
{
PFILE_DISPOSITION_INFORMATION Info = (PFILE_DISPOSITION_INFORMATION)Buffer;
Request->Req.SetInformation.Info.Disposition.Delete = Info->DeleteFile;
return STATUS_SUCCESS;
}
else
{
PFILE_DISPOSITION_INFORMATION Info = (PFILE_DISPOSITION_INFORMATION)Buffer;
FSP_FILE_NODE *FileNode = FileObject->FsContext;
FileNode->DeletePending = Info->DeleteFile;
FileObject->DeletePending = Info->DeleteFile;
return STATUS_SUCCESS;
}
} }
static NTSTATUS FspFsvolSetEndOfFileInformation(PFILE_OBJECT FileObject, static NTSTATUS FspFsvolSetEndOfFileInformation(PFILE_OBJECT FileObject,
@ -586,16 +617,49 @@ static NTSTATUS FspFsvolSetEndOfFileInformation(PFILE_OBJECT FileObject,
{ {
PAGED_CODE(); PAGED_CODE();
return STATUS_INVALID_DEVICE_REQUEST; if (0 == Request)
{
if (sizeof(FILE_END_OF_FILE_INFORMATION) > Length)
return STATUS_INVALID_PARAMETER;
return STATUS_SUCCESS;
}
if (0 != Response)
return STATUS_SUCCESS;
PFILE_END_OF_FILE_INFORMATION Info = (PFILE_END_OF_FILE_INFORMATION)Buffer;
BOOLEAN Success;
Request->Req.SetInformation.Info.EndOfFile.FileSize = Info->EndOfFile.QuadPart;
Request->Req.SetInformation.Info.EndOfFile.AdvanceOnly = AdvanceOnly;
// !!!: REVISIT after better understanding relationship between AllocationSize and FileSize
Success = MmCanFileBeTruncated(FileObject->SectionObjectPointer, &Info->EndOfFile);
if (!Success)
return STATUS_USER_MAPPED_FILE;
return STATUS_SUCCESS;
} }
static NTSTATUS FspFsvolSetPositionInformation(PFILE_OBJECT FileObject, static NTSTATUS FspFsvolSetPositionInformation(PFILE_OBJECT FileObject,
PVOID Buffer, ULONG Length, PVOID Buffer, ULONG Length)
FSP_FSCTL_TRANSACT_REQ *Request, const FSP_FSCTL_TRANSACT_RSP *Response)
{ {
PAGED_CODE(); PAGED_CODE();
return STATUS_INVALID_DEVICE_REQUEST; if (sizeof(FILE_POSITION_INFORMATION) > Length)
return STATUS_INVALID_PARAMETER;
PFILE_POSITION_INFORMATION Info = (PFILE_POSITION_INFORMATION)Buffer;
FSP_FILE_NODE *FileNode = FileObject->FsContext;
FspFileNodeAcquireExclusive(FileNode, Main);
FileObject->CurrentByteOffset = Info->CurrentByteOffset;
FspFileNodeRelease(FileNode, Main);
return STATUS_SUCCESS;
} }
static NTSTATUS FspFsvolSetRenameInformation(PFILE_OBJECT FileObject, static NTSTATUS FspFsvolSetRenameInformation(PFILE_OBJECT FileObject,
@ -606,27 +670,61 @@ static NTSTATUS FspFsvolSetRenameInformation(PFILE_OBJECT FileObject,
return STATUS_INVALID_DEVICE_REQUEST; return STATUS_INVALID_DEVICE_REQUEST;
} }
#endif
static NTSTATUS FspFsvolSetInformation( static NTSTATUS FspFsvolSetInformation(
PDEVICE_OBJECT FsvolDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp) PDEVICE_OBJECT FsvolDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
{ {
PAGED_CODE(); PAGED_CODE();
#if 0
/* is this a valid FileObject? */ /* is this a valid FileObject? */
if (!FspFileNodeIsValid(IrpSp->FileObject->FsContext)) if (!FspFileNodeIsValid(IrpSp->FileObject->FsContext))
return STATUS_INVALID_DEVICE_REQUEST; return STATUS_INVALID_DEVICE_REQUEST;
NTSTATUS Result; NTSTATUS Result;
FILE_INFORMATION_CLASS FileInformationClass = IrpSp->Parameters.SetFile.FileInformationClass;
PFILE_OBJECT FileObject = IrpSp->FileObject;
PVOID Buffer = Irp->AssociatedIrp.SystemBuffer;
ULONG Length = IrpSp->Parameters.SetFile.Length;
switch (FileInformationClass)
{
case FileAllocationInformation:
Result = FspFsvolSetAllocationInformation(FileObject, Buffer, Length, 0, 0);
break;
case FileBasicInformation:
Result = FspFsvolSetBasicInformation(FileObject, Buffer, Length, 0, 0);
break;
case FileDispositionInformation:
Result = FspFsvolSetDispositionInformation(FileObject, Buffer, Length, 0, 0);
break;
case FileEndOfFileInformation:
Result = FspFsvolSetEndOfFileInformation(FileObject, Buffer, Length,
IrpSp->Parameters.SetFile.AdvanceOnly, 0, 0);
break;
case FileLinkInformation:
Result = STATUS_INVALID_PARAMETER; /* no hard link support */
return Result;
case FilePositionInformation:
Result = FspFsvolSetPositionInformation(FileObject, Buffer, Length);
return Result;
case FileRenameInformation:
Result = FspFsvolSetRenameInformation(FileObject, Buffer, Length, 0, 0);
break;
case FileValidDataLengthInformation:
Result = STATUS_INVALID_PARAMETER; /* no ValidDataLength support */
return Result;
default:
Result = STATUS_INVALID_PARAMETER;
return Result;
}
if (!NT_SUCCESS(Result))
return Result;
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(FsvolDeviceObject); FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(FsvolDeviceObject);
BOOLEAN FileNameRequired = 0 != FsvolDeviceExtension->VolumeParams.FileNameRequired; BOOLEAN FileNameRequired = 0 != FsvolDeviceExtension->VolumeParams.FileNameRequired;
PFILE_OBJECT FileObject = IrpSp->FileObject;
FSP_FILE_NODE *FileNode = FileObject->FsContext; FSP_FILE_NODE *FileNode = FileObject->FsContext;
FSP_FILE_DESC *FileDesc = FileObject->FsContext2; FSP_FILE_DESC *FileDesc = FileObject->FsContext2;
FILE_INFORMATION_CLASS FileInformationClass = IrpSp->Parameters.SetFile.FileInformationClass;
PVOID Buffer = Irp->AssociatedIrp.SystemBuffer;
ULONG Length = IrpSp->Parameters.QueryFile.Length;
FSP_FSCTL_TRANSACT_REQ *Request; FSP_FSCTL_TRANSACT_REQ *Request;
ASSERT(FileNode == FileDesc->FileNode); ASSERT(FileNode == FileDesc->FileNode);
@ -641,6 +739,10 @@ static NTSTATUS FspFsvolSetInformation(
Request->Req.SetInformation.UserContext2 = FileDesc->UserContext2; Request->Req.SetInformation.UserContext2 = FileDesc->UserContext2;
Request->Req.SetInformation.FileInformationClass = FileInformationClass; Request->Req.SetInformation.FileInformationClass = FileInformationClass;
FspFileNodeAcquireExclusive(FileNode, Full);
FspFileNodeSetOwner(FileNode, Full, Request);
FspIopRequestContext(Request, RequestFileNode) = FileNode;
switch (FileInformationClass) switch (FileInformationClass)
{ {
case FileAllocationInformation: case FileAllocationInformation:
@ -656,87 +758,70 @@ static NTSTATUS FspFsvolSetInformation(
Result = FspFsvolSetEndOfFileInformation(FileObject, Buffer, Length, Result = FspFsvolSetEndOfFileInformation(FileObject, Buffer, Length,
IrpSp->Parameters.SetFile.AdvanceOnly, Request, 0); IrpSp->Parameters.SetFile.AdvanceOnly, Request, 0);
break; break;
case FileLinkInformation:
Result = STATUS_INVALID_PARAMETER; /* no hard link support */
break;
case FilePositionInformation:
Result = FspFsvolSetPositionInformation(FileObject, Buffer, Length, Request, 0);
break;
case FileRenameInformation: case FileRenameInformation:
Result = FspFsvolSetRenameInformation(FileObject, Buffer, Length, Request, 0); Result = FspFsvolSetRenameInformation(FileObject, Buffer, Length, Request, 0);
break; break;
case FileValidDataLengthInformation:
Result = STATUS_INVALID_PARAMETER; /* no ValidDataLength support */
break;
default:
Result = STATUS_INVALID_PARAMETER;
break;
}
return Result;
#else
return STATUS_INVALID_DEVICE_REQUEST;
#endif
}
NTSTATUS FspFsvolSetInformationComplete(
PIRP Irp, const FSP_FSCTL_TRANSACT_RSP *Response)
{
FSP_ENTER_IOC(PAGED_CODE());
#if 0
if (!NT_SUCCESS(Response->IoStatus.Status))
{
Irp->IoStatus.Information = Response->IoStatus.Information;
Result = Response->IoStatus.Status;
FSP_RETURN();
}
PFILE_OBJECT FileObject = IrpSp->FileObject;
FSP_FILE_NODE *FileNode = FileObject->FsContext;
FILE_INFORMATION_CLASS FileInformationClass = IrpSp->Parameters.SetFile.FileInformationClass;
PVOID Buffer = Irp->AssociatedIrp.SystemBuffer;
ULONG Length = IrpSp->Parameters.QueryFile.Length;
FspFileNodeSetFileInfo(FileNode, &Response->Rsp.SetInformation.FileInfo);
switch (FileInformationClass)
{
case FileAllocationInformation:
Result = FspFsvolSetAllocationInformation(FileObject, Buffer, Length, 0, Response);
break;
case FileBasicInformation:
Result = FspFsvolSetBasicInformation(FileObject, Buffer, Length, 0, Response);
break;
case FileDispositionInformation:
Result = FspFsvolSetDispositionInformation(FileObject, Buffer, Length, 0, Response);
break;
case FileEndOfFileInformation:
Result = FspFsvolSetEndOfFileInformation(FileObject, Buffer, Length,
IrpSp->Parameters.SetFile.AdvanceOnly, 0, Response);
break;
case FileLinkInformation:
Result = STATUS_INVALID_PARAMETER; /* no hard link support */
break;
case FilePositionInformation:
Result = FspFsvolSetPositionInformation(FileObject, Buffer, Length, 0, Response);
break;
case FileRenameInformation:
Result = FspFsvolSetRenameInformation(FileObject, Buffer, Length, 0, Response);
break;
case FileValidDataLengthInformation:
Result = STATUS_INVALID_PARAMETER; /* no ValidDataLength support */
break;
default: default:
ASSERT(0); ASSERT(0);
Result = STATUS_INVALID_PARAMETER; Result = STATUS_INVALID_PARAMETER;
break; break;
} }
ASSERT(FSP_STATUS_IOQ_POST != Result); if (!NT_SUCCESS(Result))
return Result;
return FSP_STATUS_IOQ_POST;
}
NTSTATUS FspFsvolSetInformationComplete(
PIRP Irp, const FSP_FSCTL_TRANSACT_RSP *Response)
{
FSP_ENTER_IOC(PAGED_CODE());
if (!NT_SUCCESS(Response->IoStatus.Status))
{
Irp->IoStatus.Information = 0;
Result = Response->IoStatus.Status;
FSP_RETURN();
}
FILE_INFORMATION_CLASS FileInformationClass = IrpSp->Parameters.SetFile.FileInformationClass;
PFILE_OBJECT FileObject = IrpSp->FileObject;
FSP_FILE_NODE *FileNode = FileObject->FsContext;
PVOID Buffer = Irp->AssociatedIrp.SystemBuffer;
ULONG Length = IrpSp->Parameters.SetFile.Length;
FSP_FSCTL_TRANSACT_REQ *Request = FspIrpRequest(Irp);
FspFileNodeSetFileInfo(FileNode, FileObject, &Response->Rsp.SetInformation.FileInfo);
switch (FileInformationClass)
{
case FileAllocationInformation:
Result = FspFsvolSetAllocationInformation(FileObject, Buffer, Length, Request, Response);
break;
case FileBasicInformation:
Result = FspFsvolSetBasicInformation(FileObject, Buffer, Length, Request, Response);
break;
case FileDispositionInformation:
Result = FspFsvolSetDispositionInformation(FileObject, Buffer, Length, Request, Response);
break;
case FileEndOfFileInformation:
Result = FspFsvolSetEndOfFileInformation(FileObject, Buffer, Length,
IrpSp->Parameters.SetFile.AdvanceOnly, Request, Response);
break;
case FileRenameInformation:
Result = FspFsvolSetRenameInformation(FileObject, Buffer, Length, Request, Response);
break;
default:
ASSERT(0);
Result = STATUS_INVALID_PARAMETER;
break;
}
FspIopRequestContext(Request, RequestFileNode) = 0;
FspFileNodeReleaseOwner(FileNode, Full, Request);
Irp->IoStatus.Information = 0; Irp->IoStatus.Information = 0;
#endif
FSP_LEAVE_IOC("%s, FileObject=%p", FSP_LEAVE_IOC("%s, FileObject=%p",
FileInformationClassSym(IrpSp->Parameters.SetFile.FileInformationClass), FileInformationClassSym(IrpSp->Parameters.SetFile.FileInformationClass),