none
Problem with oplock. Need help please RRS feed

  • Question

  • Hello

    I implement a oplock in my driver filesystem.

    When Windows  use function oplock , no bsod , but when i (shutdown/restart) then sometime the system wait time infinity (STATUS_PENDING equivalent).

    I use FsRtlOplockFsctrl in ioctl function

     FSCTL_REQUEST_OPLOCK_LEVEL_1:
         FSCTL_REQUEST_OPLOCK_LEVEL_2:
         FSCTL_REQUEST_BATCH_OPLOCK:
         FSCTL_OPLOCK_BREAK_ACKNOWLEDGE:
         FSCTL_OPBATCH_ACK_CLOSE_PENDING:
         FSCTL_OPLOCK_BREAK_NOTIFY:
         FSCTL_OPLOCK_BREAK_ACK_NO_2:
         FSCTL_REQUEST_FILTER_OPLOCK:
         FSCTL_REQUEST_OPLOCK.

    But not used in the ioctl IRP_MJ_CREATE.

    TSTATUS FatOplockRequest(PDEVICE_OBJECT DeviceObject, PIRP *irp, PIO_STACK_LOCATION irps)
    {
    	NTSTATUS status = STATUS_OBJECT_NAME_NOT_FOUND;
    	BOOLEAN ISVCB = FALSE;
    	PPARAMVDF vdf= vdf_GetParamAndVCB(DeviceObject, &ISVCB);
    	if (vdf != NULL)
    	{
    		if (isoplock(vdf) == FALSE)
    		{
    			KdPrintfd2(("OPLOCK NOT ENABLED\n"));
    			status = STATUS_NOT_IMPLEMENTED;
    		}
    		else
    		{
    			ULONG FsControlCode;
    
    
    			PCCB Ccb;
    
    			PFILE_OBJECT fileObject = irps->FileObject;
    
    			Ccb = (PCCB)fileObject->FsContext2;
    
    			PsharevdfsFCB Fcb = Ccb->Fcb;
    			if (Fcb == NULL)
    			{
    				KdPrintfd2(("[FatOplockRequest] FCB=NULL\n"));
    				status = STATUS_INTERNAL_ERROR;
    				goto fb;
    
    			}
    
    			ULONG OplockCount = 0;
    
    			PIO_STACK_LOCATION IrpSp = irps;
    
    			BOOLEAN AcquiredVcb = FALSE;
    			//BOOLEAN AcquiredFcb = FALSE;
    
    			PREQUEST_OPLOCK_INPUT_BUFFER InputBuffer = NULL;
    			ULONG InputBufferLength;
    			ULONG OutputBufferLength;
    
    			PAGED_CODE();
    
    			//
    			//  Save some references to make our life a little easier
    			//
    
    			FsControlCode = IrpSp->Parameters.FileSystemControl.FsControlCode;
    
    			KdPrintfd2(("FatOplockRequest...\n"));
    			KdPrintfd2(("FsControlCode = %08lx\n", FsControlCode));
    
    			//
    			//  We only permit oplock requests on files.
    			//
    
    			/*if (FatDecodeFileObject(IrpSp->FileObject,
    				&Vcb,
    				&Fcb,
    				&Ccb) != UserFileOpen) {
    
    				FatCompleteRequest(IrpContext, Irp, STATUS_INVALID_PARAMETER);
    				DebugTrace(-1, Dbg, "FatOplockRequest -> STATUS_INVALID_PARAMETER\n", 0);
    				return STATUS_INVALID_PARAMETER;
    			}*/
    
    			//
    			//  Get the input & output buffer lengths and pointers.
    			//
    
    			if (FsControlCode == FSCTL_REQUEST_OPLOCK) {
    
    				InputBufferLength = irps->Parameters.FileSystemControl.InputBufferLength;
    				InputBuffer = (PREQUEST_OPLOCK_INPUT_BUFFER)(*irp)->AssociatedIrp.SystemBuffer;
    
    				OutputBufferLength = IrpSp->Parameters.FileSystemControl.OutputBufferLength;
    
    				//
    				//  Check for a minimum length on the input and ouput buffers.
    				//
    
    				if ((InputBufferLength < sizeof(REQUEST_OPLOCK_INPUT_BUFFER)) ||
    					(OutputBufferLength < sizeof(REQUEST_OPLOCK_OUTPUT_BUFFER))) {
    
    					/*FatCompleteRequest(IrpContext, Irp, STATUS_BUFFER_TOO_SMALL);*/
    					KdPrintfd2(("FatOplockRequest -> STATUS_BUFFER_TOO_SMALL\n"));
    					////////*irp = NULL; /////NO BECAUSE IT SHOUµLD PROCESS ERROR IRP
    					return STATUS_BUFFER_TOO_SMALL;
    				}
    			}
    
    			//
    			//  Make this a waitable Irpcontext so we don't fail to acquire
    			//  the resources.
    			//
    
    			//SetFlag((*irp)->Flags, IRP_CONTEXT_FLAG_WAIT);
    
    			//
    			//  Use a try finally to free the Fcb/Vcb
    			//
    
    			try {
    
    				//
    				//  We grab the Fcb exclusively for oplock requests, shared for oplock
    				//  break acknowledgement.
    				//
    
    				if ((FsControlCode == FSCTL_REQUEST_OPLOCK_LEVEL_1) ||
    					(FsControlCode == FSCTL_REQUEST_BATCH_OPLOCK) ||
    					(FsControlCode == FSCTL_REQUEST_FILTER_OPLOCK) ||
    					(FsControlCode == FSCTL_REQUEST_OPLOCK_LEVEL_2) ||
    					((FsControlCode == FSCTL_REQUEST_OPLOCK) &&
    						FlagOn(InputBuffer->Flags, REQUEST_OPLOCK_INPUT_FLAG_REQUEST))) {
    
    					/*FatAcquireSharedVcb(IrpContext, Fcb->Vcb);
    					AcquiredVcb = TRUE;
    					FatAcquireExclusiveFcb(IrpContext, Fcb);
    					AcquiredFcb = TRUE;*/
    					KdPrintfd2(("[fatoplockrequest] Acquire resource1\n"));
    					AcquiredVcb = ExAcquireResourceSharedLite(&vdf->Resource, TRUE);
    					KdPrintfd2(("[fatoplockrequest] Acquire resource2\n"));
    					if (FsRtlOplockIsSharedRequest(*irp)) {
    						KdPrintfd2(("[fatoplockrequest] FsRtlOplockIsSharedRequest\n"));
    						OplockCount = (ULONG)FsRtlAreThereCurrentFileLocks(&Fcb->FileLock);
    						KdPrintfd2(("[fatoplockrequest] FsRtlOplockIsSharedRequest return %d\n", OplockCount));
    					}
    					else {
    
    						OplockCount = 0;// Fcb->UncleanCount;
    					}
    
    				}
    				/*else if ((FsControlCode == FSCTL_OPLOCK_BREAK_ACKNOWLEDGE) ||
    					(FsControlCode == FSCTL_OPBATCH_ACK_CLOSE_PENDING) ||
    					(FsControlCode == FSCTL_OPLOCK_BREAK_NOTIFY) ||
    					(FsControlCode == FSCTL_OPLOCK_BREAK_ACK_NO_2) ||
    					((FsControlCode == FSCTL_REQUEST_OPLOCK) &&
    						FlagOn(InputBuffer->Flags, REQUEST_OPLOCK_INPUT_FLAG_ACK))) {
    
    					FatAcquireSharedFcb(IrpContext, Fcb);
    					AcquiredFcb = TRUE;
    
    				}
    				else {
    
    	#pragma prefast( suppress:28159, "things are seriously wrong if we get here" )
    					FatBugCheck(FsControlCode, 0, 0);
    				}*/
    
    				//
    				//  Call the FsRtl routine to grant/acknowledge oplock.
    				//
    
    				status = FsRtlOplockFsctrl(&Fcb->FileOplock,
    					*irp,
    					OplockCount);
    				*irp = NULL;
    
    				//
    				//  Set the flag indicating if Fast I/O is possible
    				//
    
    				//Fcb->Header.IsFastIoPossible = FatIsFastIoPossible(Fcb);
    
    			}
    			finally {
    				if (AcquiredVcb) {
    					ExReleaseResourceLite(&vdf->Resource);
    					AcquiredVcb = FALSE;
    				}
    
    				//DebugUnwind(FatOplockRequest);
    
    				//
    				//  Release all of our resources
    				//
    
    				/*if (AcquiredVcb) {
    
    	#pragma prefast(suppress: 28107, "prefast cannot work out that the Vcb is held")
    					FatReleaseVcb(IrpContext, Fcb->Vcb);
    				}
    
    				if (AcquiredFcb) {
    
    	#pragma prefast( suppress:28107, "prefast is having trouble figuring out that Fcb is acquired" )
    					FatReleaseFcb(IrpContext, Fcb);
    				}
    
    				if (!AbnormalTermination()) {
    
    					FatCompleteRequest(IrpContext, FatNull, 0);
    				}
    
    				DebugTrace(-1, Dbg, "FatOplockRequest -> %08lx\n", Status);*/
    			}
    		}
    	}
    fb:;
    	return status;
    
    }

    Thank.


    • Edited by Sizy458 Saturday, September 23, 2017 8:01 PM
    Saturday, September 23, 2017 7:54 PM