Skip to content

Commit

Permalink
Merge pull request #286 from bailey27/more_FsRtlCheckOplock
Browse files Browse the repository at this point in the history
More fs rtl check oplock
  • Loading branch information
Liryna authored Jul 8, 2016
2 parents 9d6bace + 0c64b84 commit b845c08
Show file tree
Hide file tree
Showing 6 changed files with 105 additions and 3 deletions.
17 changes: 17 additions & 0 deletions sys/cleanup.c
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,23 @@ Return Value:
eventContext->Operation.Cleanup.FileNameLength = fcb->FileName.Length;
RtlCopyMemory(eventContext->Operation.Cleanup.FileName,
fcb->FileName.Buffer, fcb->FileName.Length);


status = FsRtlCheckOplock(DokanGetFcbOplock(fcb), Irp, eventContext,
DokanOplockComplete, DokanPrePostIrp);

//
// if FsRtlCheckOplock returns STATUS_PENDING the IRP has been posted
// to service an oplock break and we need to leave now.
//
if (status != STATUS_SUCCESS) {
if (status == STATUS_PENDING) {
DDbgPrint(" FsRtlCheckOplock returned STATUS_PENDING\n");
} else {
DokanFreeEventContext(eventContext);
}
__leave;
}

// register this IRP to pending IRP list
status = DokanRegisterPendingIrp(DeviceObject, Irp, eventContext, 0);
Expand Down
16 changes: 16 additions & 0 deletions sys/fileinfo.c
Original file line number Diff line number Diff line change
Expand Up @@ -459,6 +459,22 @@ DokanDispatchSetInformation(__in PDEVICE_OBJECT DeviceObject, __in PIRP Irp) {
eventContext->Operation.SetFile.FileNameLength = fcb->FileName.Length;
RtlCopyMemory(eventContext->Operation.SetFile.FileName,
fcb->FileName.Buffer, fcb->FileName.Length);

status = FsRtlCheckOplock(DokanGetFcbOplock(fcb), Irp, eventContext,
DokanOplockComplete, DokanPrePostIrp);

//
// if FsRtlCheckOplock returns STATUS_PENDING the IRP has been posted
// to service an oplock break and we need to leave now.
//
if (status != STATUS_SUCCESS) {
if (status == STATUS_PENDING) {
DDbgPrint(" FsRtlCheckOplock returned STATUS_PENDING\n");
} else {
DokanFreeEventContext(eventContext);
}
__leave;
}

// register this IRP to waiting IRP list and make it pending status
status = DokanRegisterPendingIrp(DeviceObject, Irp, eventContext, 0);
Expand Down
16 changes: 16 additions & 0 deletions sys/flush.c
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,22 @@ DokanDispatchFlush(__in PDEVICE_OBJECT DeviceObject, __in PIRP Irp) {

CcUninitializeCacheMap(fileObject, NULL, NULL);
// fileObject->Flags &= FO_CLEANUP_COMPLETE;

status = FsRtlCheckOplock(DokanGetFcbOplock(fcb), Irp, eventContext,
DokanOplockComplete, DokanPrePostIrp);

//
// if FsRtlCheckOplock returns STATUS_PENDING the IRP has been posted
// to service an oplock break and we need to leave now.
//
if (status != STATUS_SUCCESS) {
if (status == STATUS_PENDING) {
DDbgPrint(" FsRtlCheckOplock returned STATUS_PENDING\n");
} else {
DokanFreeEventContext(eventContext);
}
__leave;
}

// register this IRP to waiting IRP list and make it pending status
status = DokanRegisterPendingIrp(DeviceObject, Irp, eventContext, 0);
Expand Down
2 changes: 1 addition & 1 deletion sys/fscontrol.c
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ NTSTATUS DokanOplockRequest(__in PIRP *pIrp) {
) {

AcquiredVcb = ExAcquireResourceSharedLite(&(Fcb->Vcb->Resource), TRUE);
AcquiredFcb = ExAcquireResourceSharedLite(&(Fcb->Resource), TRUE);
AcquiredFcb = ExAcquireResourceExclusiveLite(&(Fcb->Resource), TRUE);

#if (NTDDI_VERSION >= NTDDI_WIN7)
if (!Dcb->FileLockInUserMode && FsRtlOplockIsSharedRequest(Irp)) {
Expand Down
8 changes: 6 additions & 2 deletions sys/read.c
Original file line number Diff line number Diff line change
Expand Up @@ -203,8 +203,12 @@ Return Value:
// if FsRtlCheckOplock returns STATUS_PENDING the IRP has been posted
// to service an oplock break and we need to leave now.
//
if (status == STATUS_PENDING) {
DDbgPrint(" FsRtlCheckOplock returned STATUS_PENDING\n");
if (status != STATUS_SUCCESS) {
if (status == STATUS_PENDING) {
DDbgPrint(" FsRtlCheckOplock returned STATUS_PENDING\n");
} else {
DokanFreeEventContext(eventContext);
}
__leave;
}

Expand Down
49 changes: 49 additions & 0 deletions sys/write.c
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,8 @@ DokanDispatchWrite(__in PDEVICE_OBJECT DeviceObject, __in PIRP Irp) {
eventContext->Operation.Write.FileNameLength = fcb->FileName.Length;
RtlCopyMemory(eventContext->Operation.Write.FileName, fcb->FileName.Buffer,
fcb->FileName.Length);



// When eventlength is less than event notification buffer,
// returns it to user-mode using pending event.
Expand All @@ -180,6 +182,29 @@ DokanDispatchWrite(__in PDEVICE_OBJECT DeviceObject, __in PIRP Irp) {

// EventContext is no longer needed, clear it
Irp->Tail.Overlay.DriverContext[DRIVER_CONTEXT_EVENT] = 0;


//
// We now check whether we can proceed based on the state of
// the file oplocks.
//
if (!FlagOn(Irp->Flags, IRP_PAGING_IO)) {
status = FsRtlCheckOplock(DokanGetFcbOplock(fcb), Irp, eventContext,
DokanOplockComplete, DokanPrePostIrp);

//
// if FsRtlCheckOplock returns STATUS_PENDING the IRP has been posted
// to service an oplock break and we need to leave now.
//
if (status != STATUS_SUCCESS) {
if (status == STATUS_PENDING) {
DDbgPrint(" FsRtlCheckOplock returned STATUS_PENDING\n");
} else {
DokanFreeEventContext(eventContext);
}
__leave;
}
}

// register this IRP to IRP waiting list and make it pending status
status = DokanRegisterPendingIrp(DeviceObject, Irp, eventContext, 0);
Expand Down Expand Up @@ -214,6 +239,30 @@ DokanDispatchWrite(__in PDEVICE_OBJECT DeviceObject, __in PIRP Irp) {
requestContext->Length = requestContextLength;
// requsts enough size to copy EventContext
requestContext->Operation.Write.RequestLength = eventLength;

//
// We now check whether we can proceed based on the state of
// the file oplocks.
//
if (!FlagOn(Irp->Flags, IRP_PAGING_IO)) {
status = FsRtlCheckOplock(DokanGetFcbOplock(fcb), Irp, requestContext,
DokanOplockComplete, DokanPrePostIrp);

//
// if FsRtlCheckOplock returns STATUS_PENDING the IRP has been posted
// to service an oplock break and we need to leave now.
//
if (status != STATUS_SUCCESS) {
if (status == STATUS_PENDING) {
DDbgPrint(" FsRtlCheckOplock returned STATUS_PENDING\n");
} else {
DokanFreeEventContext(requestContext);
Irp->Tail.Overlay.DriverContext[DRIVER_CONTEXT_EVENT] = 0;
DokanFreeEventContext(eventContext);
}
__leave;
}
}

// regiters this IRP to IRP wainting list and make it pending status
status = DokanRegisterPendingIrp(DeviceObject, Irp, requestContext, 0);
Expand Down

0 comments on commit b845c08

Please sign in to comment.