mirror of
https://github.com/winfsp/winfsp.git
synced 2025-06-08 04:52:10 -05:00
sys: FspFsvolCreateTryFlushImage
This commit is contained in:
parent
8264ace57a
commit
12cec5dc22
@ -48,7 +48,7 @@ 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 */
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
FspFsctlTransactUnknownKind = 0,
|
FspFsctlTransactReservedKind = 0,
|
||||||
FspFsctlTransactCreateKind,
|
FspFsctlTransactCreateKind,
|
||||||
FspFsctlTransactOverwriteKind,
|
FspFsctlTransactOverwriteKind,
|
||||||
FspFsctlTransactCleanupKind,
|
FspFsctlTransactCleanupKind,
|
||||||
|
133
src/sys/create.c
133
src/sys/create.c
@ -15,7 +15,10 @@ static NTSTATUS FspFsvolCreate(
|
|||||||
FSP_IOPREP_DISPATCH FspFsvolCreatePrepare;
|
FSP_IOPREP_DISPATCH FspFsvolCreatePrepare;
|
||||||
FSP_IOCMPL_DISPATCH FspFsvolCreateComplete;
|
FSP_IOCMPL_DISPATCH FspFsvolCreateComplete;
|
||||||
static VOID FspFsvolCreatePostClose(FSP_FILE_DESC *FileDesc);
|
static VOID FspFsvolCreatePostClose(FSP_FILE_DESC *FileDesc);
|
||||||
|
static NTSTATUS FspFsvolCreateTryFlushImage(PIRP Irp, FSP_FSCTL_TRANSACT_REQ *Request,
|
||||||
|
FSP_FILE_NODE *FileNode, FSP_FILE_DESC *FileDesc, PFILE_OBJECT FileObject);
|
||||||
static FSP_IOP_REQUEST_FINI FspFsvolCreateRequestFini;
|
static FSP_IOP_REQUEST_FINI FspFsvolCreateRequestFini;
|
||||||
|
static FSP_IOP_REQUEST_FINI FspFsvolCreateReservedRequestFini;
|
||||||
static FSP_IOP_REQUEST_FINI FspFsvolCreateOverwriteRequestFini;
|
static FSP_IOP_REQUEST_FINI FspFsvolCreateOverwriteRequestFini;
|
||||||
FSP_DRIVER_DISPATCH FspCreate;
|
FSP_DRIVER_DISPATCH FspCreate;
|
||||||
|
|
||||||
@ -26,7 +29,9 @@ FSP_DRIVER_DISPATCH FspCreate;
|
|||||||
#pragma alloc_text(PAGE, FspFsvolCreatePrepare)
|
#pragma alloc_text(PAGE, FspFsvolCreatePrepare)
|
||||||
#pragma alloc_text(PAGE, FspFsvolCreateComplete)
|
#pragma alloc_text(PAGE, FspFsvolCreateComplete)
|
||||||
#pragma alloc_text(PAGE, FspFsvolCreatePostClose)
|
#pragma alloc_text(PAGE, FspFsvolCreatePostClose)
|
||||||
|
#pragma alloc_text(PAGE, FspFsvolCreateTryFlushImage)
|
||||||
#pragma alloc_text(PAGE, FspFsvolCreateRequestFini)
|
#pragma alloc_text(PAGE, FspFsvolCreateRequestFini)
|
||||||
|
#pragma alloc_text(PAGE, FspFsvolCreateReservedRequestFini)
|
||||||
#pragma alloc_text(PAGE, FspFsvolCreateOverwriteRequestFini)
|
#pragma alloc_text(PAGE, FspFsvolCreateOverwriteRequestFini)
|
||||||
#pragma alloc_text(PAGE, FspCreate)
|
#pragma alloc_text(PAGE, FspCreate)
|
||||||
#endif
|
#endif
|
||||||
@ -41,7 +46,7 @@ enum
|
|||||||
RequestAccessToken = 1,
|
RequestAccessToken = 1,
|
||||||
RequestProcess = 2,
|
RequestProcess = 2,
|
||||||
|
|
||||||
/* OverwriteRequest */
|
/* Reserved/OverwriteRequest */
|
||||||
//RequestFileDesc = 0,
|
//RequestFileDesc = 0,
|
||||||
RequestFileObject = 1,
|
RequestFileObject = 1,
|
||||||
RequestState = 2,
|
RequestState = 2,
|
||||||
@ -347,7 +352,37 @@ NTSTATUS FspFsvolCreatePrepare(
|
|||||||
FSP_FILE_DESC *FileDesc;
|
FSP_FILE_DESC *FileDesc;
|
||||||
PFILE_OBJECT FileObject;
|
PFILE_OBJECT FileObject;
|
||||||
|
|
||||||
if (FspFsctlTransactCreateKind == Request->Kind)
|
if (FspFsctlTransactReservedKind == Request->Kind)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* This branch is not taken during IRP preparation, but rather during IRP completion
|
||||||
|
* when FlushImageSection needs to be retried.
|
||||||
|
*/
|
||||||
|
FileDesc = FspIopRequestContext(Request, RequestFileDesc);
|
||||||
|
FileNode = FileDesc->FileNode;
|
||||||
|
FileObject = FspIopRequestContext(Request, RequestFileObject);
|
||||||
|
|
||||||
|
Result = FspFsvolCreateTryFlushImage(Irp, Request, FileNode, FileDesc, FileObject);
|
||||||
|
if (STATUS_PENDING == Result)
|
||||||
|
return Result;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (NT_SUCCESS(Result))
|
||||||
|
{
|
||||||
|
/* SUCCESS! */
|
||||||
|
FspIopRequestContext(Request, RequestFileDesc) = 0;
|
||||||
|
Irp->IoStatus.Information = FILE_OPENED;
|
||||||
|
Result = STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
DEBUGLOGIRP(Irp, Result);
|
||||||
|
|
||||||
|
FspIopCompleteIrp(Irp, Result);
|
||||||
|
|
||||||
|
return FSP_STATUS_COMPLETED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (FspFsctlTransactCreateKind == Request->Kind)
|
||||||
{
|
{
|
||||||
SecuritySubjectContext = &IrpSp->Parameters.Create.SecurityContext->
|
SecuritySubjectContext = &IrpSp->Parameters.Create.SecurityContext->
|
||||||
AccessState->SubjectSecurityContext;
|
AccessState->SubjectSecurityContext;
|
||||||
@ -558,15 +593,9 @@ VOID FspFsvolCreateComplete(
|
|||||||
if (FlagOn(Response->Rsp.Create.Opened.GrantedAccess, FILE_WRITE_DATA) ||
|
if (FlagOn(Response->Rsp.Create.Opened.GrantedAccess, FILE_WRITE_DATA) ||
|
||||||
DeleteOnClose)
|
DeleteOnClose)
|
||||||
{
|
{
|
||||||
if (!MmFlushImageSection(&FileNode->NonPaged->SectionObjectPointers,
|
Result = FspFsvolCreateTryFlushImage(Irp, 0, FileNode, FileDesc, FileObject);
|
||||||
MmFlushForWrite))
|
if (STATUS_PENDING == Result || !NT_SUCCESS(Result))
|
||||||
{
|
|
||||||
FspFsvolCreatePostClose(FileDesc);
|
|
||||||
FspFileNodeClose(FileNode, FileObject, 0);
|
|
||||||
|
|
||||||
Result = DeleteOnClose ? STATUS_CANNOT_DELETE : STATUS_SHARING_VIOLATION;
|
|
||||||
FSP_RETURN();
|
FSP_RETURN();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* SUCCESS! */
|
/* SUCCESS! */
|
||||||
@ -690,6 +719,70 @@ static VOID FspFsvolCreatePostClose(FSP_FILE_DESC *FileDesc)
|
|||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static NTSTATUS FspFsvolCreateTryFlushImage(PIRP Irp, FSP_FSCTL_TRANSACT_REQ *Request,
|
||||||
|
FSP_FILE_NODE *FileNode, FSP_FILE_DESC *FileDesc, PFILE_OBJECT FileObject)
|
||||||
|
{
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
ASSERT(0 == Request || FspFsctlTransactReservedKind == Request->Kind);
|
||||||
|
|
||||||
|
BOOLEAN Success;
|
||||||
|
|
||||||
|
Success = FspFileNodeTryAcquireExclusive(FileNode, Main);
|
||||||
|
if (!Success)
|
||||||
|
{
|
||||||
|
/* repost the IRP to retry later */
|
||||||
|
NTSTATUS Result;
|
||||||
|
PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
|
||||||
|
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension =
|
||||||
|
FspFsvolDeviceExtension(IrpSp->DeviceObject);
|
||||||
|
|
||||||
|
if (0 == Request)
|
||||||
|
{
|
||||||
|
/* delete the old 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 */
|
||||||
|
FspIopRequestContext(Request, RequestFileDesc) = FileDesc;
|
||||||
|
FspIopRequestContext(Request, RequestFileObject) = FileObject;
|
||||||
|
|
||||||
|
Request->Kind = FspFsctlTransactReservedKind;
|
||||||
|
}
|
||||||
|
|
||||||
|
FspIoqPostIrpBestEffort(FsvolDeviceExtension->Ioq, Irp, &Result);
|
||||||
|
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
Success = MmFlushImageSection(&FileNode->NonPaged->SectionObjectPointers,
|
||||||
|
MmFlushForWrite);
|
||||||
|
FspFileNodeRelease(FileNode, Main);
|
||||||
|
if (!Success)
|
||||||
|
{
|
||||||
|
PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
|
||||||
|
BOOLEAN DeleteOnClose = BooleanFlagOn(IrpSp->Parameters.Create.Options, FILE_DELETE_ON_CLOSE);
|
||||||
|
|
||||||
|
if (0 == Request)
|
||||||
|
{
|
||||||
|
FspFsvolCreatePostClose(FileDesc);
|
||||||
|
FspFileNodeClose(FileNode, FileObject, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return DeleteOnClose ? STATUS_CANNOT_DELETE : STATUS_SHARING_VIOLATION;
|
||||||
|
}
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
static VOID FspFsvolCreateRequestFini(PVOID Context[3])
|
static VOID FspFsvolCreateRequestFini(PVOID Context[3])
|
||||||
{
|
{
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
@ -731,6 +824,26 @@ static VOID FspFsvolCreateRequestFini(PVOID Context[3])
|
|||||||
Context[RequestFileDesc] = Context[RequestAccessToken] = Context[RequestProcess] = 0;
|
Context[RequestFileDesc] = Context[RequestAccessToken] = Context[RequestProcess] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static VOID FspFsvolCreateReservedRequestFini(PVOID Context[3])
|
||||||
|
{
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
FSP_FILE_DESC *FileDesc = Context[RequestFileDesc];
|
||||||
|
PFILE_OBJECT FileObject = Context[RequestFileObject];
|
||||||
|
|
||||||
|
if (0 != FileDesc)
|
||||||
|
{
|
||||||
|
ASSERT(0 != FileObject);
|
||||||
|
|
||||||
|
FspFsvolCreatePostClose(FileDesc);
|
||||||
|
FspFileNodeClose(FileDesc->FileNode, FileObject, 0);
|
||||||
|
FspFileNodeDereference(FileDesc->FileNode);
|
||||||
|
FspFileDescDelete(FileDesc);
|
||||||
|
}
|
||||||
|
|
||||||
|
Context[RequestFileDesc] = Context[RequestFileObject] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
static VOID FspFsvolCreateOverwriteRequestFini(PVOID Context[3])
|
static VOID FspFsvolCreateOverwriteRequestFini(PVOID Context[3])
|
||||||
{
|
{
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
@ -29,6 +29,7 @@
|
|||||||
#define FSP_STATUS_PRIVATE_BIT (0x20000000)
|
#define FSP_STATUS_PRIVATE_BIT (0x20000000)
|
||||||
#define FSP_STATUS_IOQ_POST (FSP_STATUS_PRIVATE_BIT | 0x0000)
|
#define FSP_STATUS_IOQ_POST (FSP_STATUS_PRIVATE_BIT | 0x0000)
|
||||||
#define FSP_STATUS_IOQ_POST_BEST_EFFORT (FSP_STATUS_PRIVATE_BIT | 0x0001)
|
#define FSP_STATUS_IOQ_POST_BEST_EFFORT (FSP_STATUS_PRIVATE_BIT | 0x0001)
|
||||||
|
#define FSP_STATUS_COMPLETED (FSP_STATUS_PRIVATE_BIT | 0x0002)
|
||||||
|
|
||||||
/* misc macros */
|
/* misc macros */
|
||||||
#define FSP_ALLOC_INTERNAL_TAG 'IpsF'
|
#define FSP_ALLOC_INTERNAL_TAG 'IpsF'
|
||||||
@ -43,6 +44,13 @@
|
|||||||
#define DEBUGLOG(fmt, ...) ((void)0)
|
#define DEBUGLOG(fmt, ...) ((void)0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* DEBUGLOGIRP */
|
||||||
|
#if DBG
|
||||||
|
#define DEBUGLOGIRP(Irp, Result) FspDebugLogIrp(Irp, Result)
|
||||||
|
#else
|
||||||
|
#define DEBUGLOGIRP(Irp, Result) ((void)0)
|
||||||
|
#endif
|
||||||
|
|
||||||
/* DEBUGBREAK */
|
/* DEBUGBREAK */
|
||||||
#if DBG
|
#if DBG
|
||||||
extern __declspec(selectany) int fsp_bp = 1;
|
extern __declspec(selectany) int fsp_bp = 1;
|
||||||
@ -590,6 +598,19 @@ const char *NtStatusSym(NTSTATUS Status);
|
|||||||
const char *IrpMajorFunctionSym(UCHAR MajorFunction);
|
const char *IrpMajorFunctionSym(UCHAR MajorFunction);
|
||||||
const char *IrpMinorFunctionSym(UCHAR MajorFunction, UCHAR MinorFunction);
|
const char *IrpMinorFunctionSym(UCHAR MajorFunction, UCHAR MinorFunction);
|
||||||
const char *IoctlCodeSym(ULONG ControlCode);
|
const char *IoctlCodeSym(ULONG ControlCode);
|
||||||
|
static inline
|
||||||
|
VOID FspDebugLogIrp(PIRP Irp, NTSTATUS Result)
|
||||||
|
{
|
||||||
|
PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
|
||||||
|
DEBUGLOG("IRP=%p, %s%c, %s%s, IoStatus=%s[%lld]",
|
||||||
|
Irp,
|
||||||
|
(const char *)&FspDeviceExtension(IrpSp->DeviceObject)->Kind,
|
||||||
|
Irp->RequestorMode == KernelMode ? 'K' : 'U',
|
||||||
|
IrpMajorFunctionSym(IrpSp->MajorFunction),
|
||||||
|
IrpMinorFunctionSym(IrpSp->MajorFunction, IrpSp->MinorFunction),
|
||||||
|
NtStatusSym(Result),
|
||||||
|
(LONGLONG)Irp->IoStatus.Information);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* extern */
|
/* extern */
|
||||||
|
@ -238,15 +238,7 @@ VOID FspIopCompleteCanceledIrp(PIRP Irp)
|
|||||||
{
|
{
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
|
||||||
#if DBG
|
DEBUGLOGIRP(Irp, STATUS_CANCELLED);
|
||||||
PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
|
|
||||||
DEBUGLOG("IRP=%p, %s%c, %s%s",
|
|
||||||
Irp,
|
|
||||||
(const char *)&FspDeviceExtension(IrpSp->DeviceObject)->Kind,
|
|
||||||
Irp->RequestorMode == KernelMode ? 'K' : 'U',
|
|
||||||
IrpMajorFunctionSym(IrpSp->MajorFunction),
|
|
||||||
IrpMinorFunctionSym(IrpSp->MajorFunction, IrpSp->MinorFunction));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
FspIopCompleteIrpEx(Irp, STATUS_CANCELLED, TRUE);
|
FspIopCompleteIrpEx(Irp, STATUS_CANCELLED, TRUE);
|
||||||
}
|
}
|
||||||
|
@ -565,7 +565,9 @@ NTSTATUS FspVolumeTransact(
|
|||||||
PendingIrpRequest = FspIrpRequest(PendingIrp);
|
PendingIrpRequest = FspIrpRequest(PendingIrp);
|
||||||
|
|
||||||
Result = FspIopDispatchPrepare(PendingIrp, PendingIrpRequest);
|
Result = FspIopDispatchPrepare(PendingIrp, PendingIrpRequest);
|
||||||
if (STATUS_PENDING == Result)
|
if (FSP_STATUS_COMPLETED == Result)
|
||||||
|
;
|
||||||
|
else if (STATUS_PENDING == Result)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* The IRP has been reposted to our Ioq. Remember the first such IRP,
|
* The IRP has been reposted to our Ioq. Remember the first such IRP,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user