diff --git a/src/sys/create.c b/src/sys/create.c index 33a91710..65da98ad 100644 --- a/src/sys/create.c +++ b/src/sys/create.c @@ -1451,7 +1451,7 @@ static BOOLEAN FspFsvolCreateOpenOrOverwriteOplock(PIRP Irp, const FSP_FSCTL_TRA if (STATUS_SUCCESS == Result && FlagOn(IrpSp->Parameters.Create.Options, FILE_OPEN_REQUIRING_OPLOCK)) { - Result = FspOplockFsctrlCreate(FspFileNodeAddrOfOplock(FileNode), Irp, OplockCount); + Result = FspFileNodeOplockFsctl(FileNode, Irp, OplockCount); ASSERT(STATUS_PENDING != Result); if (STATUS_SUCCESS == Result) diff --git a/src/sys/driver.h b/src/sys/driver.h index 90a099b1..c9dcf3d6 100644 --- a/src/sys/driver.h +++ b/src/sys/driver.h @@ -537,11 +537,10 @@ NTSTATUS FspCheckOplockEx( PVOID Context, POPLOCK_WAIT_COMPLETE_ROUTINE CompletionRoutine, POPLOCK_FS_PREPOST_IRP PostIrpRoutine); -NTSTATUS FspOplockFsctrlF( +NTSTATUS FspOplockFsctrl( POPLOCK Oplock, PIRP Irp, - ULONG OpenCount, - BOOLEAN Create); + ULONG OpenCount); #define FspNotifyUninitializeSync(NS)\ FsRtlNotifyUninitializeSync(NS) #define FspNotifyCleanupAll(NS, NL)\ @@ -554,10 +553,6 @@ NTSTATUS FspOplockFsctrlF( FspNotifyFullChangeDirectory(NS, NL, FC, 0, 0, FALSE, 0, 0, 0, 0) #define FspNotifyReportChange(NS, NL, FN, FO, NP, F, A)\ FspNotifyFullReportChange(NS, NL, (PSTRING)(FN), FO, 0, (PSTRING)(NP), F, A, 0) -#define FspOplockFsctrlCreate(OL, I, OC)\ - FspOplockFsctrlF(OL, I, OC, TRUE) -#define FspOplockFsctrl(OL, I, OC)\ - FspOplockFsctrlF(OL, I, OC, FALSE) /* utility: synchronous work queue */ typedef struct @@ -1242,6 +1237,11 @@ typedef struct PVOID PrepareContext; } FSP_FILE_NODE_OPLOCK_CONTEXT; static inline +NTSTATUS FspFileNodeOplockFsctl(FSP_FILE_NODE *FileNode, PIRP Irp, ULONG OpenCount) +{ + return FspOplockFsctrl(FspFileNodeAddrOfOplock(FileNode), Irp, OpenCount); +} +static inline BOOLEAN FspFileNodeOplockIsBatch(FSP_FILE_NODE *FileNode) { return FsRtlCurrentBatchOplock(FspFileNodeAddrOfOplock(FileNode)); diff --git a/src/sys/fsctl.c b/src/sys/fsctl.c index 673a0259..f1a7f5d0 100644 --- a/src/sys/fsctl.c +++ b/src/sys/fsctl.c @@ -432,30 +432,18 @@ static NTSTATUS FspFsvolFileSystemControlOplock( } /* - * It is possible for FspOplockFsctrl to complete the IRP immediately. - * In this case trying to access the IRP (to get its IrpFlags) in FspFileNodeRelease - * can lead to a bugcheck. For this reason we set the TopLevelIrp to NULL here. + * FspOplockFsctrl takes ownership of the IRP under all circumstances. * - * FspFsvolFileSystemControlOplock does not need the TopLevelIrp functionality, - * because it cannot be used recursively (I believe -- famous last words). + * We mark the IRP pending so that we can safely return STATUS_PENDING. */ - PIRP TopLevelIrp = IoGetTopLevelIrp(); + IoSetTopLevelIrp(0); - Result = FspOplockFsctrl(FspFileNodeAddrOfOplock(FileNode), Irp, OplockCount); + IoMarkIrpPending(Irp); + Result = FspFileNodeOplockFsctl(FileNode, Irp, OplockCount); FspFileNodeRelease(FileNode, Main); - if (!NT_SUCCESS(Result)) - { - /* set back the top level IRP just in case! */ - IoSetTopLevelIrp(TopLevelIrp); - - FspIrpHookReset(Irp); - FspFree(CompletionContext); - return Result; - } - return STATUS_PENDING; unlock_exit: diff --git a/src/sys/util.c b/src/sys/util.c index d8b5b80c..1175b6d7 100644 --- a/src/sys/util.c +++ b/src/sys/util.c @@ -87,11 +87,10 @@ NTSTATUS FspCheckOplockEx( PVOID Context, POPLOCK_WAIT_COMPLETE_ROUTINE CompletionRoutine, POPLOCK_FS_PREPOST_IRP PostIrpRoutine); -NTSTATUS FspOplockFsctrlF( +NTSTATUS FspOplockFsctrl( POPLOCK Oplock, PIRP Irp, - ULONG OpenCount, - BOOLEAN Create); + ULONG OpenCount); VOID FspInitializeSynchronousWorkItem(FSP_SYNCHRONOUS_WORK_ITEM *SynchronousWorkItem, PWORKER_THREAD_ROUTINE Routine, PVOID Context); VOID FspExecuteSynchronousWorkItem(FSP_SYNCHRONOUS_WORK_ITEM *SynchronousWorkItem); @@ -132,7 +131,7 @@ NTSTATUS FspIrpHookNext(PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context); #pragma alloc_text(PAGE, FspOplockBreakH) #pragma alloc_text(PAGE, FspCheckOplock) #pragma alloc_text(PAGE, FspCheckOplockEx) -#pragma alloc_text(PAGE, FspOplockFsctrlF) +#pragma alloc_text(PAGE, FspOplockFsctrl) #pragma alloc_text(PAGE, FspInitializeSynchronousWorkItem) #pragma alloc_text(PAGE, FspExecuteSynchronousWorkItem) #pragma alloc_text(PAGE, FspExecuteSynchronousWorkItemRoutine) @@ -757,11 +756,10 @@ NTSTATUS FspCheckOplockEx( return Result; } -NTSTATUS FspOplockFsctrlF( +NTSTATUS FspOplockFsctrl( POPLOCK Oplock, PIRP Irp, - ULONG OpenCount, - BOOLEAN Create) + ULONG OpenCount) { PAGED_CODE(); @@ -769,21 +767,10 @@ NTSTATUS FspOplockFsctrlF( try { - ASSERT( - (Create && IRP_MJ_CREATE == IoGetCurrentIrpStackLocation(Irp)->MajorFunction) || - (!Create && IRP_MJ_FILE_SYSTEM_CONTROL == IoGetCurrentIrpStackLocation(Irp)->MajorFunction)); - Result = FsRtlOplockFsctrl( Oplock, Irp, OpenCount); - - /* - * When the IRP is IRP_MJ_FILE_SYSTEM_CONTROL, FsRtlOplockFsctrl always takes ownership - * of the IRP (unless it raises). So return STATUS_SUCCESS in that case. - */ - if (!Create) - Result = STATUS_SUCCESS; } except (EXCEPTION_EXECUTE_HANDLER) {