sys: IRP_MJ_CREATE: FspFsvolCreateRetryComplete: refactoring

This commit is contained in:
Bill Zissimopoulos 2016-01-27 10:55:22 -08:00
parent e86f4b0836
commit c9fb46ff11
4 changed files with 89 additions and 64 deletions

View File

@ -16,10 +16,11 @@ FSP_IOPREP_DISPATCH FspFsvolCreatePrepare;
FSP_IOCMPL_DISPATCH FspFsvolCreateComplete;
FSP_IORETR_DISPATCH FspFsvolCreateRetryComplete;
static NTSTATUS FspFsvolCreateTryOpen(PIRP Irp, FSP_FSCTL_TRANSACT_REQ *Request,
FSP_FILE_NODE *FileNode, FSP_FILE_DESC *FileDesc, PFILE_OBJECT FileObject);
FSP_FILE_NODE *FileNode, FSP_FILE_DESC *FileDesc, PFILE_OBJECT FileObject,
BOOLEAN FlushImage);
static VOID FspFsvolCreatePostClose(FSP_FILE_DESC *FileDesc);
static FSP_IOP_REQUEST_FINI FspFsvolCreateRequestFini;
static FSP_IOP_REQUEST_FINI FspFsvolCreateReservedRequestFini;
static FSP_IOP_REQUEST_FINI FspFsvolCreateTryOpenRequestFini;
static FSP_IOP_REQUEST_FINI FspFsvolCreateOverwriteRequestFini;
FSP_DRIVER_DISPATCH FspCreate;
@ -33,7 +34,7 @@ FSP_DRIVER_DISPATCH FspCreate;
#pragma alloc_text(PAGE, FspFsvolCreateTryOpen)
#pragma alloc_text(PAGE, FspFsvolCreatePostClose)
#pragma alloc_text(PAGE, FspFsvolCreateRequestFini)
#pragma alloc_text(PAGE, FspFsvolCreateReservedRequestFini)
#pragma alloc_text(PAGE, FspFsvolCreateTryOpenRequestFini)
#pragma alloc_text(PAGE, FspFsvolCreateOverwriteRequestFini)
#pragma alloc_text(PAGE, FspCreate)
#endif
@ -43,12 +44,12 @@ FSP_DRIVER_DISPATCH FspCreate;
enum
{
/* CreateRequest */
/* Create */
RequestFileDesc = 0,
RequestAccessToken = 1,
RequestProcess = 2,
/* Reserved/OverwriteRequest */
/* TryOpen/Overwrite */
//RequestFileDesc = 0,
RequestFileObject = 1,
RequestState = 2,
@ -574,20 +575,12 @@ VOID FspFsvolCreateComplete(
* If the user wants to delete on close, we must check at this
* point though.
*/
if (!FlagOn(Response->Rsp.Create.Opened.FileInfo.FileAttributes, FILE_ATTRIBUTE_DIRECTORY) &&
BOOLEAN FlushImage =
!FlagOn(Response->Rsp.Create.Opened.FileInfo.FileAttributes, FILE_ATTRIBUTE_DIRECTORY) &&
(FlagOn(Response->Rsp.Create.Opened.GrantedAccess, FILE_WRITE_DATA) ||
DeleteOnClose))
{
Result = FspFsvolCreateTryOpen(Irp, 0, FileNode, FileDesc, FileObject);
if (STATUS_PENDING == Result || !NT_SUCCESS(Result))
FSP_RETURN();
}
DeleteOnClose);
/* SUCCESS! */
FspFileNodeSetFileInfo(FileNode, &FileDesc->State.FileInfo);
FspIopRequestContext(Request, RequestFileDesc) = 0;
Irp->IoStatus.Information = (ULONG_PTR)Response->IoStatus.Information;
Result = STATUS_SUCCESS;
Result = FspFsvolCreateTryOpen(Irp, 0, FileNode, FileDesc, FileObject, FlushImage);
}
else
if (FILE_SUPERSEDED == Response->IoStatus.Information ||
@ -661,10 +654,9 @@ VOID FspFsvolCreateComplete(
}
/* file was successfully overwritten/superseded */
FileNode->Header.AllocationSize.QuadPart = Response->Rsp.Overwrite.FileInfo.AllocationSize;
FileNode->Header.FileSize.QuadPart = Response->Rsp.Overwrite.FileInfo.FileSize;
FileNode->CcStatus = FspCcSetFileSizes(
FileObject, (PCC_FILE_SIZES)&FileNode->Header.AllocationSize);
FspFileObjectSetSizes(FileObject,
Response->Rsp.Overwrite.FileInfo.AllocationSize,
Response->Rsp.Overwrite.FileInfo.FileSize);
FspFileNodeRelease(FileNode, Both);
@ -692,45 +684,38 @@ NTSTATUS FspFsvolCreateRetryComplete(
FSP_FILE_NODE *FileNode;
FSP_FILE_DESC *FileDesc;
PFILE_OBJECT FileObject;
BOOLEAN FlushImage;
ASSERT(FspFsctlTransactReservedKind == Request->Kind);
ASSERT(FspFsctlTransactCreateKind == Request->Kind);
FileDesc = FspIopRequestContext(Request, RequestFileDesc);
FileNode = FileDesc->FileNode;
FileObject = FspIopRequestContext(Request, RequestFileObject);
FlushImage = 0 != FspIopRequestContext(Request, RequestState);
Result = FspFsvolCreateTryOpen(Irp, Request, FileNode, FileDesc, FileObject);
Result = FspFsvolCreateTryOpen(Irp, Request, FileNode, FileDesc, FileObject, FlushImage);
if (STATUS_PENDING == Result)
return Result;
else
{
if (NT_SUCCESS(Result))
{
/* SUCCESS! */
FspFileNodeSetFileInfo(FileNode, &FileDesc->State.FileInfo);
FspIopRequestContext(Request, RequestFileDesc) = 0;
Irp->IoStatus.Information = FILE_OPENED;
Result = STATUS_SUCCESS;
}
DEBUGLOGIRP(Irp, Result);
FspIopCompleteIrp(Irp, Result);
return STATUS_SUCCESS;
}
}
static NTSTATUS FspFsvolCreateTryOpen(PIRP Irp, FSP_FSCTL_TRANSACT_REQ *Request,
FSP_FILE_NODE *FileNode, FSP_FILE_DESC *FileDesc, PFILE_OBJECT FileObject)
FSP_FILE_NODE *FileNode, FSP_FILE_DESC *FileDesc, PFILE_OBJECT FileObject,
BOOLEAN FlushImage)
{
PAGED_CODE();
ASSERT(0 == Request || FspFsctlTransactReservedKind == Request->Kind);
ASSERT(0 == Request || FspFsctlTransactCreateKind == Request->Kind);
BOOLEAN Success;
Success = FspFileNodeTryAcquireExclusive(FileNode, Main);
Success = FspFileNodeTryAcquireExclusive(FileNode, Both);
if (!Success)
{
/* repost the IRP to retry later */
@ -741,23 +726,15 @@ static NTSTATUS FspFsvolCreateTryOpen(PIRP Irp, FSP_FSCTL_TRANSACT_REQ *Request,
if (0 == Request)
{
/* delete the old request */
/* disassociate the FileDesc momentarily from the Request */
Request = FspIrpRequest(Irp);
FspIrpRequest(Irp) = 0;
FspIopRequestContext(Request, RequestFileDesc) = 0;
/* disassociate the FileDesc from the old Request as we want to keep it around! */
FspIopDeleteRequest(Request);
/* create the special Reserved request */
FspIopCreateRequestFunnel(Irp, 0, 0,
FspFsvolCreateReservedRequestFini, TRUE,
&Request);
/* associate the FileDesc and FileObject with the Reserved request */
/* reset the Request and reassociate the FileDesc and FileObject with it */
FspIopResetRequest(Request, FspFsvolCreateTryOpenRequestFini);
FspIopRequestContext(Request, RequestFileDesc) = FileDesc;
FspIopRequestContext(Request, RequestFileObject) = FileObject;
Request->Kind = FspFsctlTransactReservedKind;
FspIopRequestContext(Request, RequestState) = (PVOID)(UINT_PTR)FlushImage;
}
FspIoqRetryCompleteIrp(FsvolDeviceExtension->Ioq, Irp, &Result);
@ -765,9 +742,14 @@ static NTSTATUS FspFsvolCreateTryOpen(PIRP Irp, FSP_FSCTL_TRANSACT_REQ *Request,
return Result;
}
FspFileObjectSetSizes(FileObject,
FileDesc->State.FileInfo.AllocationSize, FileDesc->State.FileInfo.FileSize);
if (FlushImage)
{
Success = MmFlushImageSection(&FileNode->NonPaged->SectionObjectPointers,
MmFlushForWrite);
FspFileNodeRelease(FileNode, Main);
FspFileNodeRelease(FileNode, Both);
if (!Success)
{
PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
@ -781,7 +763,14 @@ static NTSTATUS FspFsvolCreateTryOpen(PIRP Irp, FSP_FSCTL_TRANSACT_REQ *Request,
return DeleteOnClose ? STATUS_CANNOT_DELETE : STATUS_SHARING_VIOLATION;
}
}
else
FspFileNodeRelease(FileNode, Both);
/* SUCCESS! */
FspFileNodeSetFileInfo(FileNode, &FileDesc->State.FileInfo);
FspIopRequestContext(Request, RequestFileDesc) = 0;
Irp->IoStatus.Information = FILE_OPENED;
return STATUS_SUCCESS;
}
@ -859,7 +848,7 @@ static VOID FspFsvolCreateRequestFini(PVOID Context[3])
Context[RequestFileDesc] = Context[RequestAccessToken] = Context[RequestProcess] = 0;
}
static VOID FspFsvolCreateReservedRequestFini(PVOID Context[3])
static VOID FspFsvolCreateTryOpenRequestFini(PVOID Context[3])
{
PAGED_CODE();
@ -876,7 +865,7 @@ static VOID FspFsvolCreateReservedRequestFini(PVOID Context[3])
FspFileDescDelete(FileDesc);
}
Context[RequestFileDesc] = Context[RequestFileObject] = 0;
Context[RequestFileDesc] = Context[RequestFileObject] = Context[RequestState] = 0;
}
static VOID FspFsvolCreateOverwriteRequestFini(PVOID Context[3])

View File

@ -415,6 +415,7 @@ NTSTATUS FspIopCreateRequestFunnel(
BOOLEAN MustSucceed,
FSP_FSCTL_TRANSACT_REQ **PRequest);
VOID FspIopDeleteRequest(FSP_FSCTL_TRANSACT_REQ *Request);
VOID FspIopResetRequest(FSP_FSCTL_TRANSACT_REQ *Request, FSP_IOP_REQUEST_FINI *RequestFini);
PVOID *FspIopRequestContextAddress(FSP_FSCTL_TRANSACT_REQ *Request, ULONG I);
NTSTATUS FspIopPostWorkRequestFunnel(PDEVICE_OBJECT DeviceObject,
FSP_FSCTL_TRANSACT_REQ *Request, BOOLEAN BestEffort);
@ -622,6 +623,8 @@ BOOLEAN FspFileNodeTryGetFileInfo(FSP_FILE_NODE *FileNode, FSP_FSCTL_FILE_INFO *
VOID FspFileNodeSetFileInfo(FSP_FILE_NODE *FileNode, const FSP_FSCTL_FILE_INFO *FileInfo);
NTSTATUS FspFileDescCreate(FSP_FILE_DESC **PFileDesc);
VOID FspFileDescDelete(FSP_FILE_DESC *FileDesc);
VOID FspFileObjectSetSizes(PFILE_OBJECT FileObject,
UINT64 AllocationSize, UINT64 FileSize);
#define FspFileNodeAcquireShared(N,F) FspFileNodeAcquireSharedF(N, FspFileNodeAcquire ## F)
#define FspFileNodeTryAcquireShared(N,F) FspFileNodeTryAcquireSharedF(N, FspFileNodeAcquire ## F)
#define FspFileNodeAcquireExclusive(N,F) FspFileNodeAcquireExclusiveF(N, FspFileNodeAcquire ## F)

View File

@ -23,6 +23,8 @@ BOOLEAN FspFileNodeTryGetFileInfo(FSP_FILE_NODE *FileNode, FSP_FSCTL_FILE_INFO *
VOID FspFileNodeSetFileInfo(FSP_FILE_NODE *FileNode, const FSP_FSCTL_FILE_INFO *FileInfo);
NTSTATUS FspFileDescCreate(FSP_FILE_DESC **PFileDesc);
VOID FspFileDescDelete(FSP_FILE_DESC *FileDesc);
VOID FspFileObjectSetSizes(PFILE_OBJECT FileObject,
UINT64 AllocationSize, UINT64 FileSize);
#ifdef ALLOC_PRAGMA
#pragma alloc_text(PAGE, FspFileNodeCreate)
@ -39,6 +41,7 @@ VOID FspFileDescDelete(FSP_FILE_DESC *FileDesc);
#pragma alloc_text(PAGE, FspFileNodeSetFileInfo)
#pragma alloc_text(PAGE, FspFileDescCreate)
#pragma alloc_text(PAGE, FspFileDescDelete)
#pragma alloc_text(PAGE, FspFileObjectSetSizes)
#endif
NTSTATUS FspFileNodeCreate(PDEVICE_OBJECT DeviceObject,
@ -430,3 +433,18 @@ VOID FspFileDescDelete(FSP_FILE_DESC *FileDesc)
FspFree(FileDesc);
}
VOID FspFileObjectSetSizes(PFILE_OBJECT FileObject,
UINT64 AllocationSize, UINT64 FileSize)
{
PAGED_CODE();
FSP_FILE_NODE *FileNode = FileObject->FsContext;
ASSERT(ExIsResourceAcquiredExclusiveLite(FileNode->Header.PagingIoResource));
FileNode->Header.AllocationSize.QuadPart = AllocationSize;
FileNode->Header.FileSize.QuadPart = FileSize;
FileNode->CcStatus = FspCcSetFileSizes(
FileObject, (PCC_FILE_SIZES)&FileNode->Header.AllocationSize);
}

View File

@ -11,6 +11,7 @@ NTSTATUS FspIopCreateRequestFunnel(
BOOLEAN MustSucceed,
FSP_FSCTL_TRANSACT_REQ **PRequest);
VOID FspIopDeleteRequest(FSP_FSCTL_TRANSACT_REQ *Request);
VOID FspIopResetRequest(FSP_FSCTL_TRANSACT_REQ *Request, FSP_IOP_REQUEST_FINI *RequestFini);
PVOID *FspIopRequestContextAddress(FSP_FSCTL_TRANSACT_REQ *Request, ULONG I);
NTSTATUS FspIopPostWorkRequestFunnel(PDEVICE_OBJECT DeviceObject,
FSP_FSCTL_TRANSACT_REQ *Request, BOOLEAN AllocateIrpMustSucceed);
@ -24,6 +25,7 @@ NTSTATUS FspIopDispatchRetryComplete(PIRP Irp);
#ifdef ALLOC_PRAGMA
#pragma alloc_text(PAGE, FspIopCreateRequestFunnel)
#pragma alloc_text(PAGE, FspIopDeleteRequest)
#pragma alloc_text(PAGE, FspIopResetRequest)
#pragma alloc_text(PAGE, FspIopRequestContextAddress)
#pragma alloc_text(PAGE, FspIopPostWorkRequestFunnel)
#pragma alloc_text(PAGE, FspIopCompleteIrpEx)
@ -143,6 +145,19 @@ VOID FspIopDeleteRequest(FSP_FSCTL_TRANSACT_REQ *Request)
FspFree(RequestHeader);
}
VOID FspIopResetRequest(FSP_FSCTL_TRANSACT_REQ *Request, FSP_IOP_REQUEST_FINI *RequestFini)
{
PAGED_CODE();
FSP_FSCTL_TRANSACT_REQ_HEADER *RequestHeader = (PVOID)((PUINT8)Request - sizeof *RequestHeader);
if (0 != RequestHeader->RequestFini)
RequestHeader->RequestFini(RequestHeader->Context);
RtlZeroMemory(&RequestHeader->Context, sizeof RequestHeader->Context);
RequestHeader->RequestFini = RequestFini;
}
PVOID *FspIopRequestContextAddress(FSP_FSCTL_TRANSACT_REQ *Request, ULONG I)
{
PAGED_CODE();