Exemple #1
0
/*
 * @implemented
 */
VOID
NTAPI
FsRtlStackOverflowRead(IN PVOID Context)
{
    PSTACK_OVERFLOW_WORK_ITEM WorkItem;

    WorkItem = (PSTACK_OVERFLOW_WORK_ITEM)Context;

    /* Put us as top IRP for current thread */
    IoSetTopLevelIrp((PIRP)FSRTL_FSP_TOP_LEVEL_IRP);
    /* And call FsRtlSORoutine */
    WorkItem->Routine(WorkItem->Context, WorkItem->Event);

    /* If we were using fallback workitem, don't free it, just reset event */
    if (WorkItem == &StackOverflowFallback)
    {
        KeSetEvent(&StackOverflowFallbackSerialEvent, 0, FALSE);
    }
    /* Otherwise, free the work item */
    else
    {
        ExFreePoolWithTag(WorkItem, 'Fsrs');
    }

    /* Reset top level */
    IoSetTopLevelIrp(NULL);
}
Exemple #2
0
VOID DDKAPI LklDequeueRequest(IN PDEVICE_OBJECT device, IN PVOID context)
{
	NTSTATUS status;
	PIRPCONTEXT irp_context;

	irp_context = (PIRPCONTEXT) context;
	ASSERT(irp_context);
	ASSERT(irp_context->id.type == IRP_CONTEXT && irp_context->id.size == sizeof(IRPCONTEXT));

	IoFreeWorkItem(irp_context->work_item);

	if (FLAG_ON(irp_context->flags, VFS_IRP_CONTEXT_NOT_TOP_LEVEL))
		IoSetTopLevelIrp((PIRP)FSRTL_FSP_TOP_LEVEL_IRP);

	SET_FLAG(irp_context->flags, VFS_IRP_CONTEXT_CAN_BLOCK);

	FsRtlEnterFileSystem();

	status = LklDispatchRequest(irp_context);

	FsRtlExitFileSystem();

	IoSetTopLevelIrp(NULL);

}
Exemple #3
0
VOID
NTAPI
FatDequeueRequest(IN PVOID Context)
{
    PFAT_IRP_CONTEXT IrpContext;

    IrpContext = (PFAT_IRP_CONTEXT) Context;

    /* Enter critical region. */
    FsRtlEnterFileSystem();

    /* Handle top level IRP Correctly. */
    if (!FlagOn(IrpContext->Flags, IRPCONTEXT_TOPLEVEL))
        IoSetTopLevelIrp((PIRP) FSRTL_FSP_TOP_LEVEL_IRP);

    /* Enable Synchronous IO. */
    SetFlag(IrpContext->Flags, IRPCONTEXT_CANWAIT);

    /* Invoke the handler routine. */
    IrpContext->QueuedOperationHandler(IrpContext);

    /* Restore top level IRP. */
	IoSetTopLevelIrp(NULL);

    /* Leave critical region. */
	FsRtlExitFileSystem();
}
Exemple #4
0
NTSTATUS
NTAPI
FatLockControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
    PFAT_IRP_CONTEXT IrpContext;
    NTSTATUS Status;
    BOOLEAN TopLevel;

    DPRINT1("FatLockControl()\n");

    /* Enter FsRtl critical region */
    FsRtlEnterFileSystem();

    /* Set Top Level IRP if not set */
    TopLevel = FatIsTopLevelIrp(Irp);

    /* Build an irp context */
    IrpContext = FatBuildIrpContext(Irp, IoIsOperationSynchronous(Irp));

    /* Call internal function */
    Status = FatiLockControl(IrpContext, Irp);

    /* Reset Top Level IRP */
    if (TopLevel) IoSetTopLevelIrp(NULL);

    /* Leave FsRtl critical region */
    FsRtlExitFileSystem();

    return Status;
}
Exemple #5
0
BOOLEAN
CdAcquireForCache (
    _Inout_ PFCB Fcb,
    _In_ BOOLEAN Wait
    )

/*++

Routine Description:

    The address of this routine is specified when creating a CacheMap for
    a file.  It is subsequently called by the Lazy Writer for synchronization.

Arguments:

    Fcb -  The pointer supplied as context to the cache initialization
           routine.

    Wait - TRUE if the caller is willing to block.

Return Value:

    None

--*/

{
    PAGED_CODE();

    NT_ASSERT(IoGetTopLevelIrp() == NULL);
    IoSetTopLevelIrp((PIRP)FSRTL_CACHE_TOP_LEVEL_IRP);

    return ExAcquireResourceSharedLite( Fcb->Resource, Wait );
}
Exemple #6
0
VOID
CdReleaseFromCache (
    _Inout_ PFCB Fcb
    )

/*++

Routine Description:

    The address of this routine is specified when creating a CacheMap for
    a virtual file.  It is subsequently called by the Lazy Writer to release
    a resource acquired above.

Arguments:

    Fcb -  The pointer supplied as context to the cache initialization
           routine.

Return Value:

    None

--*/

{
    PAGED_CODE();

    NT_ASSERT(IoGetTopLevelIrp() == (PIRP)FSRTL_CACHE_TOP_LEVEL_IRP);
    IoSetTopLevelIrp( NULL );
    
    ExReleaseResourceLite( Fcb->Resource );
}
Exemple #7
0
NTSTATUS
DokanBuildRequest(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
    BOOLEAN             AtIrqlPassiveLevel = FALSE;
    BOOLEAN             IsTopLevelIrp = FALSE;
    NTSTATUS            Status = STATUS_UNSUCCESSFUL;

    __try {

        __try {

            AtIrqlPassiveLevel = (KeGetCurrentIrql() == PASSIVE_LEVEL);

            if (AtIrqlPassiveLevel) {
                FsRtlEnterFileSystem();
            }

            if (!IoGetTopLevelIrp()) {
                IsTopLevelIrp = TRUE;
                IoSetTopLevelIrp(Irp);
            }

            Status = DokanDispatchRequest(DeviceObject, Irp);

        }
        __except (DokanExceptionFilter(Irp, GetExceptionInformation()))
        {

            Status = DokanExceptionHandler(DeviceObject, Irp, GetExceptionCode());
        }

    }
    __finally {

        if (IsTopLevelIrp) {
            IoSetTopLevelIrp(NULL);
        }

        if (AtIrqlPassiveLevel) {
            FsRtlExitFileSystem();
        }
    }

    return Status;
}
Exemple #8
0
VOID DokanNoOpRelease(__in PVOID Fcb) {
  DDbgPrint("==> DokanNoOpRelease\n");
  ASSERT(IoGetTopLevelIrp() == (PIRP)FSRTL_CACHE_TOP_LEVEL_IRP);

  IoSetTopLevelIrp(NULL);

  UNREFERENCED_PARAMETER(Fcb);

  DDbgPrint("<== DokanNoOpRelease\n");
}
Exemple #9
0
/*************************************************************************
*
* Function: UDFClose()
*
* Description:
*   The I/O Manager will invoke this routine to handle a close
*   request
*
* Expected Interrupt Level (for execution) :
*
*  IRQL_PASSIVE_LEVEL (invocation at higher IRQL will cause execution
*   to be deferred to a worker thread context)
*
* Return Value: STATUS_SUCCESS
*
*************************************************************************/
NTSTATUS
NTAPI
UDFClose(
    PDEVICE_OBJECT  DeviceObject,  // the logical volume device object
    PIRP            Irp            // I/O Request Packet
    )
{
    NTSTATUS            RC = STATUS_SUCCESS;
    PtrUDFIrpContext    PtrIrpContext = NULL;
    BOOLEAN             AreWeTopLevel = FALSE;

    AdPrint(("UDFClose: \n"));

    FsRtlEnterFileSystem();
    ASSERT(DeviceObject);
    ASSERT(Irp);

    //  If we were called with our file system device object instead of a
    //  volume device object, just complete this request with STATUS_SUCCESS
    if (UDFIsFSDevObj(DeviceObject)) {
        // this is a close of the FSD itself
        Irp->IoStatus.Status = RC;
        Irp->IoStatus.Information = 0;

        IoCompleteRequest(Irp, IO_NO_INCREMENT);
        FsRtlExitFileSystem();
        return(RC);
    }

    // set the top level context
    AreWeTopLevel = UDFIsIrpTopLevel(Irp);

    _SEH2_TRY {

        // get an IRP context structure and issue the request
        PtrIrpContext = UDFAllocateIrpContext(Irp, DeviceObject);
        ASSERT(PtrIrpContext);

        RC = UDFCommonClose(PtrIrpContext, Irp);

    } _SEH2_EXCEPT(UDFExceptionFilter(PtrIrpContext, _SEH2_GetExceptionInformation())) {

        RC = UDFExceptionHandler(PtrIrpContext, Irp);

        UDFLogEvent(UDF_ERROR_INTERNAL_ERROR, RC);
    } _SEH2_END;

    if (AreWeTopLevel) {
        IoSetTopLevelIrp(NULL);
    }

    FsRtlExitFileSystem();

    return(RC);
}
Exemple #10
0
VOID
NtfsReleaseScbFromLazyWrite (
    IN PVOID OpaqueScb
    )

/*++

Routine Description:

    The address of this routine is specified when creating a CacheMap for
    a file.  It is subsequently called by the Lazy Writer after its
    performing lazy writes to the file.

Arguments:

    Scb - The Scb which was specified as a context parameter for this
          routine.

Return Value:

    None

--*/

{
    ULONG CompressedStream = (ULONG)OpaqueScb & 1;
    PSCB Scb = (PSCB)((ULONG)OpaqueScb & ~1);
    PFCB Fcb = Scb->Fcb;

    ASSERT_SCB(Scb);

    PAGED_CODE();

    //
    //  Clear the toplevel at this point, if we set it above.
    //

    if (IoGetTopLevelIrp() == (PIRP)FSRTL_CACHE_TOP_LEVEL_IRP) {
        IoSetTopLevelIrp( NULL );
    }

    Scb->LazyWriteThread[CompressedStream] = NULL;

    if (NtfsSegmentNumber( &Fcb->FileReference ) <= MASTER_FILE_TABLE2_NUMBER) {

        NOTHING;

    } else if (Scb->Header.PagingIoResource != NULL) {
        ExReleaseResource( Scb->Header.PagingIoResource );
    } else {
        ExReleaseResource( Scb->Header.Resource );
    }

    return;
}
Exemple #11
0
VOID
FFSFloppyFlush(
	IN PVOID Parameter)
{
	PFFS_FLPFLUSH_CONTEXT Context;
	PFILE_OBJECT          FileObject;
	PFFS_FCB              Fcb;
	PFFS_VCB              Vcb;

	Context = (PFFS_FLPFLUSH_CONTEXT) Parameter;
	FileObject = Context->FileObject;
	Fcb = Context->Fcb;
	Vcb = Context->Vcb;

	FFSPrint((DBG_USER, "FFSFloppyFlushing ...\n"));

	IoSetTopLevelIrp((PIRP)FSRTL_FSP_TOP_LEVEL_IRP);

	if (Vcb)
	{
		ExAcquireSharedStarveExclusive(&Vcb->PagingIoResource, TRUE);
		ExReleaseResource(&Vcb->PagingIoResource);

		CcFlushCache(&(Vcb->SectionObject), NULL, 0, NULL);
	}

	if (FileObject)
	{
		ASSERT(Fcb == (PFFS_FCB)FileObject->FsContext);

		ExAcquireSharedStarveExclusive(&Fcb->PagingIoResource, TRUE);
		ExReleaseResource(&Fcb->PagingIoResource);

		CcFlushCache(&(Fcb->SectionObject), NULL, 0, NULL);

		ObDereferenceObject(FileObject);
	}

	IoSetTopLevelIrp(NULL);

	ExFreePool(Parameter);
}
Exemple #12
0
static void release_from_read_ahead(PVOID Context) {
    PFILE_OBJECT FileObject = Context;
    fcb* fcb = FileObject->FsContext;

    TRACE("(%p)\n", Context);

    ExReleaseResourceLite(fcb->Header.Resource);

    if (IoGetTopLevelIrp() == (PIRP)FSRTL_CACHE_TOP_LEVEL_IRP)
        IoSetTopLevelIrp(NULL);
}
Exemple #13
0
VOID
Ext2FloppyFlush(IN PVOID Parameter)
{
    PEXT2_FLPFLUSH_CONTEXT Context;
    PFILE_OBJECT           FileObject;
    PEXT2_FCB Fcb;
    PEXT2_VCB Vcb;

    Context = (PEXT2_FLPFLUSH_CONTEXT) Parameter;
    FileObject = Context->FileObject;
    Fcb = Context->Fcb;
    Vcb = Context->Vcb;

    DEBUG(DL_FLP, ("Ext2FloppyFlushing ...\n"));

    IoSetTopLevelIrp((PIRP)FSRTL_FSP_TOP_LEVEL_IRP);

    if (FileObject) {
        ASSERT(Fcb == (PEXT2_FCB)FileObject->FsContext);

        ExAcquireSharedStarveExclusive(&Fcb->PagingIoResource, TRUE);
        ExReleaseResourceLite(&Fcb->PagingIoResource);

        CcFlushCache(&(Fcb->SectionObject), NULL, 0, NULL);

        ObDereferenceObject(FileObject);
    }

    if (Vcb) {
        ExAcquireSharedStarveExclusive(&Vcb->PagingIoResource, TRUE);
        ExReleaseResourceLite(&Vcb->PagingIoResource);

        ExAcquireResourceExclusiveLite(&Vcb->sbi.s_gd_lock, TRUE);
        Ext2DropBH(Vcb);
        CcFlushCache(&(Vcb->SectionObject), NULL, 0, NULL);
        ExReleaseResourceLite(&Vcb->sbi.s_gd_lock);
    }

    IoSetTopLevelIrp(NULL);
    Ext2FreePool(Parameter, EXT2_FLPFLUSH_MAGIC);
}
Exemple #14
0
BOOLEAN
NTAPI
FatIsTopLevelIrp(IN PIRP Irp)
{
    if (!IoGetTopLevelIrp())
    {
        IoSetTopLevelIrp(Irp);
        return TRUE;
    }

    return FALSE;
}
Exemple #15
0
static BOOLEAN acquire_for_read_ahead(PVOID Context, BOOLEAN Wait) {
    PFILE_OBJECT FileObject = Context;
    fcb* fcb = FileObject->FsContext;

    TRACE("(%p, %u)\n", Context, Wait);

    if (!ExAcquireResourceSharedLite(fcb->Header.Resource, Wait))
        return FALSE;

    IoSetTopLevelIrp((PIRP)FSRTL_CACHE_TOP_LEVEL_IRP);

    return TRUE;
}
Exemple #16
0
VOID FspIopCompleteCanceledIrp(PIRP Irp)
{
    PAGED_CODE();

    DEBUGLOGIRP(Irp, STATUS_CANCELLED);

    /*
     * An IRP cancel may happen at any time including when APC's are still enabled.
     * For this reason we execute FsRtlEnterFileSystem/FsRtlExitFileSystem here.
     * This will protect ERESOURCE operations during Request finalizations.
     */
    FsRtlEnterFileSystem();

    PIRP TopLevelIrp = IoGetTopLevelIrp();
    IoSetTopLevelIrp(Irp);

    FspIopCompleteIrpEx(Irp, STATUS_CANCELLED, TRUE);

    IoSetTopLevelIrp(TopLevelIrp);

    FsRtlExitFileSystem();
}
Exemple #17
0
/*************************************************************************
*
* Function: UDFShutdown()
*
* Description:
*   All disk-based FSDs can expect to receive this shutdown notification
*   request whenever the system is about to be halted gracefully. If you
*   design and implement a network redirector, you must register explicitly
*   for shutdown notification by invoking the IoRegisterShutdownNotification()
*   routine from your driver entry.
*
*   Note that drivers that register to receive shutdown notification get
*   invoked BEFORE disk-based FSDs are told about the shutdown notification.
*
* Expected Interrupt Level (for execution) :
*
*  IRQL_PASSIVE_LEVEL
*
* Return Value: Irrelevant.
*
*************************************************************************/
NTSTATUS
NTAPI
UDFShutdown(
    PDEVICE_OBJECT   DeviceObject,       // the logical volume device object
    PIRP             Irp                 // I/O Request Packet
    )
{
    NTSTATUS         RC = STATUS_SUCCESS;
    PtrUDFIrpContext PtrIrpContext = NULL;
    BOOLEAN          AreWeTopLevel = FALSE;

    KdPrint(("UDFShutDown\n"));
//    BrutePoint();

    FsRtlEnterFileSystem();
    ASSERT(DeviceObject);
    ASSERT(Irp);

    // set the top level context
    AreWeTopLevel = UDFIsIrpTopLevel(Irp);
    //ASSERT(!UDFIsFSDevObj(DeviceObject));

    _SEH2_TRY {

        // get an IRP context structure and issue the request
        PtrIrpContext = UDFAllocateIrpContext(Irp, DeviceObject);
        if(PtrIrpContext) {
            RC = UDFCommonShutdown(PtrIrpContext, Irp);
        } else {
            RC = STATUS_INSUFFICIENT_RESOURCES;
            Irp->IoStatus.Status = RC;
            Irp->IoStatus.Information = 0;
            // complete the IRP
            IoCompleteRequest(Irp, IO_DISK_INCREMENT);
        }

    } _SEH2_EXCEPT(UDFExceptionFilter(PtrIrpContext, _SEH2_GetExceptionInformation())) {

        RC = UDFExceptionHandler(PtrIrpContext, Irp);

        UDFLogEvent(UDF_ERROR_INTERNAL_ERROR, RC);
    } _SEH2_END;

    if (AreWeTopLevel) {
        IoSetTopLevelIrp(NULL);
    }

    FsRtlExitFileSystem();

    return(RC);
} // end UDFShutdown()
Exemple #18
0
VOID
FFSDeQueueRequest(
	IN PVOID Context)
{
	PFFS_IRP_CONTEXT IrpContext;

	IrpContext = (PFFS_IRP_CONTEXT) Context;

	ASSERT(IrpContext);

	ASSERT((IrpContext->Identifier.Type == FFSICX) &&
			(IrpContext->Identifier.Size == sizeof(FFS_IRP_CONTEXT)));

	__try
	{
		__try
		{
			FsRtlEnterFileSystem();

			if (!IrpContext->IsTopLevel)
			{
				IoSetTopLevelIrp((PIRP) FSRTL_FSP_TOP_LEVEL_IRP);
			}

			FFSDispatchRequest(IrpContext);
		}
		__except (FFSExceptionFilter(IrpContext, GetExceptionInformation()))
		{
			FFSExceptionHandler(IrpContext);
		}
	}
	__finally
	{
		IoSetTopLevelIrp(NULL);

		FsRtlExitFileSystem();
	}
}
Exemple #19
0
NTSTATUS
NTAPI
NtfsFsdDirectoryControl(PDEVICE_OBJECT DeviceObject,
                        PIRP Irp)
{
    PNTFS_IRP_CONTEXT IrpContext = NULL;
    NTSTATUS Status = STATUS_UNSUCCESSFUL;

    DPRINT1("NtfsDirectoryControl() called\n");

    FsRtlEnterFileSystem();
    ASSERT(DeviceObject);
    ASSERT(Irp);

    NtfsIsIrpTopLevel(Irp);

    IrpContext = NtfsAllocateIrpContext(DeviceObject, Irp);
    if (IrpContext)
    {
        switch (IrpContext->MinorFunction)
        {
            case IRP_MN_QUERY_DIRECTORY:
                Status = NtfsQueryDirectory(IrpContext);
                break;

            case IRP_MN_NOTIFY_CHANGE_DIRECTORY:
                DPRINT1("IRP_MN_NOTIFY_CHANGE_DIRECTORY\n");
                Status = STATUS_NOT_IMPLEMENTED;
                break;

            default:
                Status = STATUS_INVALID_DEVICE_REQUEST;
                break;
        }
    }
    else
        Status = STATUS_INSUFFICIENT_RESOURCES;

    Irp->IoStatus.Status = Status;
    Irp->IoStatus.Information = 0;
    IoCompleteRequest(Irp, IO_NO_INCREMENT);

    if (IrpContext)
        ExFreePoolWithTag(IrpContext, 'PRIN');

    IoSetTopLevelIrp(NULL);
    FsRtlExitFileSystem();
    return Status;
}
Exemple #20
0
static void release_from_lazy_write(PVOID Context) {
    PFILE_OBJECT FileObject = Context;
    fcb* fcb = FileObject->FsContext;

    TRACE("(%p)\n", Context);

    fcb->lazy_writer_thread = NULL;

    ExReleaseResourceLite(fcb->Header.Resource);

    ExReleaseResourceLite(&fcb->Vcb->tree_lock);

    if (IoGetTopLevelIrp() == (PIRP)FSRTL_CACHE_TOP_LEVEL_IRP)
        IoSetTopLevelIrp(NULL);
}
Exemple #21
0
/*
 * FUNCTION: Used with IRP to set them to TopLevelIrp field
 * ARGUMENTS:
 *           Irp = The IRP to set
 * RETURNS: TRUE if top level was null, else FALSE
 */
BOOLEAN
NtfsIsIrpTopLevel(PIRP Irp)
{
    BOOLEAN ReturnCode = FALSE;

    TRACE_(NTFS, "NtfsIsIrpTopLevel()\n");

    if (IoGetTopLevelIrp() == NULL)
    {
        IoSetTopLevelIrp(Irp);
        ReturnCode = TRUE;
    }

    return ReturnCode;
}
Exemple #22
0
BOOLEAN
DokanNoOpAcquire(__in PVOID Fcb, __in BOOLEAN Wait) {
  UNREFERENCED_PARAMETER(Fcb);
  UNREFERENCED_PARAMETER(Wait);

  DDbgPrint("==> DokanNoOpAcquire\n");

  ASSERT(IoGetTopLevelIrp() == NULL);

  IoSetTopLevelIrp((PIRP)FSRTL_CACHE_TOP_LEVEL_IRP);

  DDbgPrint("<== DokanNoOpAcquire\n");

  return TRUE;
}
Exemple #23
0
/*
 * FUNCTION: This function manages IRP for various major functions
 * ARGUMENTS:
 *           DriverObject = object describing this driver
 *           Irp = IRP to be passed to internal functions
 * RETURNS: Status of I/O Request
 */
NTSTATUS NTAPI
NtfsFsdDispatch(PDEVICE_OBJECT DeviceObject,
                PIRP Irp)
{
  PNTFS_IRP_CONTEXT IrpContext = NULL;
  NTSTATUS Status = STATUS_UNSUCCESSFUL;
  
  TRACE_(NTFS, "NtfsFsdDispatch()\n");
  
  FsRtlEnterFileSystem();
  ASSERT(DeviceObject);
  ASSERT(Irp);
  
  NtfsIsIrpTopLevel(Irp);
  
  IrpContext = NtfsAllocateIrpContext(DeviceObject, Irp);
  if (IrpContext)
  {
    switch (IrpContext->MajorFunction)
    {
      case IRP_MJ_QUERY_VOLUME_INFORMATION:
      {
        Status = NtfsQueryVolumeInformation(IrpContext);
        break;
      }
      case IRP_MJ_SET_VOLUME_INFORMATION:
      {
        Status = NtfsSetVolumeInformation(IrpContext);
        break;
      }
    }
  }
  else
    Status = STATUS_INSUFFICIENT_RESOURCES;
	
  Irp->IoStatus.Status = Status;
  IoCompleteRequest(Irp, IO_NO_INCREMENT);
	
	if (IrpContext)
    ExFreePoolWithTag(IrpContext, 'PRIN');
	
  IoSetTopLevelIrp(NULL);
  FsRtlExitFileSystem();
  return Status;
}
Exemple #24
0
/*************************************************************************
*
* Function: Ext2Close()
*
* Description:
*	The I/O Manager will invoke this routine to handle a close
*	request
*
* Expected Interrupt Level (for execution) :
*
*  IRQL_PASSIVE_LEVEL (invocation at higher IRQL will cause execution
*	to be deferred to a worker thread context)
*
* Return Value: Does not matter!
*
*************************************************************************/
NTSTATUS NTAPI Ext2Close(
PDEVICE_OBJECT		DeviceObject,		// the logical volume device object
PIRP					Irp)					// I/O Request Packet
{
	NTSTATUS				RC = STATUS_SUCCESS;
	PtrExt2IrpContext	PtrIrpContext = NULL;
	BOOLEAN				AreWeTopLevel = FALSE;

	DebugTrace(DEBUG_TRACE_IRP_ENTRY, "Close IRP Received...", 0);
	

	FsRtlEnterFileSystem();

	ASSERT(DeviceObject);
	ASSERT(Irp);

	// set the top level context
	AreWeTopLevel = Ext2IsIrpTopLevel(Irp);

	try 
	{

		// get an IRP context structure and issue the request
		PtrIrpContext = Ext2AllocateIrpContext(Irp, DeviceObject);
		ASSERT(PtrIrpContext);

		RC = Ext2CommonClose(PtrIrpContext, Irp, TRUE);

	}
	except (Ext2ExceptionFilter(PtrIrpContext, GetExceptionInformation())) 
	{

		RC = Ext2ExceptionHandler(PtrIrpContext, Irp);
		Ext2LogEvent(EXT2_ERROR_INTERNAL_ERROR, RC);
	}

	if (AreWeTopLevel) 
	{
		IoSetTopLevelIrp(NULL);
	}

	FsRtlExitFileSystem();

	return(RC);
}
Exemple #25
0
NTSTATUS DDKAPI VfsDirectoryControl(PDEVICE_OBJECT device, PIRP irp)
{
	NTSTATUS status = STATUS_SUCCESS;
	PIRPCONTEXT irp_context = NULL;
	BOOLEAN top_level = FALSE;
	
	FsRtlEnterFileSystem();

	top_level = LklIsIrpTopLevel(irp);

	irp_context = AllocIrpContext(irp, device);
	status = CommonDirectoryControl(irp_context, irp);

	if (top_level) 
		IoSetTopLevelIrp(NULL);

	FsRtlExitFileSystem();

	return status;
}
Exemple #26
0
static BOOLEAN acquire_for_lazy_write(PVOID Context, BOOLEAN Wait) {
    PFILE_OBJECT FileObject = Context;
    fcb* fcb = FileObject->FsContext;

    TRACE("(%p, %u)\n", Context, Wait);

    if (!ExAcquireResourceSharedLite(&fcb->Vcb->tree_lock, Wait))
        return FALSE;

    if (!ExAcquireResourceExclusiveLite(fcb->Header.Resource, Wait)) {
        ExReleaseResourceLite(&fcb->Vcb->tree_lock);
        return FALSE;
    }

    fcb->lazy_writer_thread = KeGetCurrentThread();

    IoSetTopLevelIrp((PIRP)FSRTL_CACHE_TOP_LEVEL_IRP);

    return TRUE;
}
Exemple #27
0
static NTSTATUS FspFsvolLockControlRetry(
    PDEVICE_OBJECT FsvolDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp,
    BOOLEAN CanWait)
{
    PAGED_CODE();

    NTSTATUS Result;
    PFILE_OBJECT FileObject = IrpSp->FileObject;
    FSP_FILE_NODE *FileNode = FileObject->FsContext;
    BOOLEAN Success;

    /* try to acquire the FileNode shared Main */
    Success = DEBUGTEST(90) &&
        FspFileNodeTryAcquireSharedF(FileNode, FspFileNodeAcquireMain, CanWait);
    if (!Success)
        return FspWqRepostIrpWorkItem(Irp, FspFsvolLockControlRetry, 0);

    /* perform oplock check; we are only implementing Win7 behavior */
    Result = FspFileNodeOplockCheckAsync(
        FileNode, FspFileNodeAcquireMain, FspFsvolLockControlRetry,
        Irp);
    if (STATUS_PENDING == Result)
        return Result;
    if (!NT_SUCCESS(Result))
    {
        FspFileNodeRelease(FileNode, Main);
        return Result;
    }

    ULONG IrpFlags = FspIrpFlags(Irp);
    IoSetTopLevelIrp(0);

    /* let the FSRTL package handle this one! */
    Result = FspFileNodeProcessLockIrp(FileNode, Irp);

    FspFileNodeReleaseF(FileNode, IrpFlags);

    return Result | FSP_STATUS_IGNORE_BIT;
}
Exemple #28
0
NTSTATUS
NTAPI
FatRead(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
    NTSTATUS Status;
    BOOLEAN TopLevel, CanWait;
    PFAT_IRP_CONTEXT IrpContext;

    CanWait = TRUE;
    TopLevel = FALSE;
    Status = STATUS_INVALID_DEVICE_REQUEST;
    /* Get CanWait flag */
    if (IoGetCurrentIrpStackLocation(Irp)->FileObject != NULL)
        CanWait = IoIsOperationSynchronous(Irp);

    /* Enter FsRtl critical region */
    FsRtlEnterFileSystem();

    if (DeviceObject != FatGlobalData.DiskDeviceObject)
    {
        /* Set Top Level IRP if not set */
        TopLevel = FatIsTopLevelIrp(Irp);

        /* Build an irp context */
        IrpContext = FatBuildIrpContext(Irp, CanWait);

        /* Perform the actual read */
        Status = FatiRead(IrpContext);

        /* Restore top level Irp */
        if (TopLevel)
            IoSetTopLevelIrp(NULL);
    }
    /* Leave FsRtl critical region */
    FsRtlExitFileSystem();

    return Status;
}
Exemple #29
0
VOID
CdSetThreadContext (
    _Inout_ PIRP_CONTEXT IrpContext,
    _In_ PTHREAD_CONTEXT ThreadContext
    )

/*++

Routine Description:

    This routine is called at each Fsd/Fsp entry point set up the IrpContext
    and thread local storage to track top level requests.  If there is
    not a Cdfs context in the thread local storage then we use the input one.
    Otherwise we use the one already there.  This routine also updates the
    IrpContext based on the state of the top-level context.

    If the TOP_LEVEL flag in the IrpContext is already set when we are called
    then we force this request to appear top level.

Arguments:

    ThreadContext - Address on stack for local storage if not already present.

    ForceTopLevel - We force this request to appear top level regardless of
        any previous stack value.

Return Value:

    None

--*/

{
    PTHREAD_CONTEXT CurrentThreadContext;

    PAGED_CODE();

    ASSERT_IRP_CONTEXT( IrpContext );

    //
    //  Get the current top-level irp out of the thread storage.
    //  If NULL then this is the top-level request.
    //

    CurrentThreadContext = (PTHREAD_CONTEXT) IoGetTopLevelIrp();

    if (CurrentThreadContext == NULL) {

        SetFlag( IrpContext->Flags, IRP_CONTEXT_FLAG_TOP_LEVEL );
    }

    //
    //  Initialize the input context unless we are using the current
    //  thread context block.  We use the new block if our caller
    //  specified this or the existing block is invalid.
    //
    //  The following must be true for the current to be a valid Cdfs context.
    //
    //      Structure must lie within current stack.
    //      Address must be ULONG aligned.
    //      Cdfs signature must be present.
    //
    //  If this is not a valid Cdfs context then use the input thread
    //  context and store it in the top level context.
    //
#pragma warning(suppress: 6011) // Bug in PREFast around bitflag operations
    if (FlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_TOP_LEVEL ) ||
        (!IoWithinStackLimits( (ULONG_PTR)CurrentThreadContext, sizeof( THREAD_CONTEXT ) ) ||
         FlagOn( (ULONG_PTR) CurrentThreadContext, 0x3 ) ||
         (CurrentThreadContext->Cdfs != 0x53464443))) {

        ThreadContext->Cdfs = 0x53464443;
        ThreadContext->SavedTopLevelIrp = (PIRP) CurrentThreadContext;
        ThreadContext->TopLevelIrpContext = IrpContext;
        IoSetTopLevelIrp( (PIRP) ThreadContext );

        IrpContext->TopLevel = IrpContext;
        IrpContext->ThreadContext = ThreadContext;

        SetFlag( IrpContext->Flags, IRP_CONTEXT_FLAG_TOP_LEVEL_CDFS );

    //
    //  Otherwise use the IrpContext in the thread context.
    //

    } else {

        IrpContext->TopLevel = CurrentThreadContext->TopLevelIrpContext;
    }

    return;
}
Exemple #30
0
NTSTATUS
FatFsdClose (
    _In_ PVOLUME_DEVICE_OBJECT VolumeDeviceObject,
    _Inout_ PIRP Irp
    )

/*++

Routine Description:

    This routine implements the FSD part of Close.

Arguments:

    VolumeDeviceObject - Supplies the volume device object where the
        file exists

    Irp - Supplies the Irp being processed

Return Value:

    NTSTATUS - The FSD status for the IRP

--*/

{
    NTSTATUS Status = STATUS_SUCCESS;
    PIO_STACK_LOCATION IrpSp;
    PFILE_OBJECT FileObject;

    PVCB Vcb;
    PFCB Fcb;
    PCCB Ccb;
    TYPE_OF_OPEN TypeOfOpen;

    BOOLEAN TopLevel;
    BOOLEAN VcbDeleted = FALSE;

    PAGED_CODE();

    //
    //  If we were called with our file system device object instead of a
    //  volume device object, just complete this request with STATUS_SUCCESS
    //

    if (FatDeviceIsFatFsdo( VolumeDeviceObject))  {

        Irp->IoStatus.Status = STATUS_SUCCESS;
        Irp->IoStatus.Information = FILE_OPENED;

        IoCompleteRequest( Irp, IO_DISK_INCREMENT );

        return STATUS_SUCCESS;
    }

    DebugTrace(+1, Dbg, "FatFsdClose\n", 0);

    //
    //  Call the common Close routine
    //

    FsRtlEnterFileSystem();

    TopLevel = FatIsIrpTopLevel( Irp );

    //
    //  Get a pointer to the current stack location and the file object
    //

    IrpSp = IoGetCurrentIrpStackLocation( Irp );

    FileObject = IrpSp->FileObject;

    //
    //  Decode the file object and set the read-only bit in the Ccb.
    //

    TypeOfOpen = FatDecodeFileObject( FileObject, &Vcb, &Fcb, &Ccb );

    if (Ccb && IsFileObjectReadOnly(FileObject)) {

        SetFlag( Ccb->Flags, CCB_FLAG_READ_ONLY );
    }

    try {

        PCLOSE_CONTEXT CloseContext = NULL;

        //
        //  If we are top level, WAIT can be TRUE, otherwise make it FALSE
        //  to avoid deadlocks, unless this is a top
        //  level request not originating from the system process.
        //

        BOOLEAN Wait = TopLevel && (PsGetCurrentProcess() != FatData.OurProcess);

#if (NTDDI_VERSION >= NTDDI_WIN8)

        //
        //  To catch the odd case where a close comes in without a preceding cleanup,
        //  call the oplock package to get rid of any oplock state.  This can only
        //  be safely done in the FSD path.
        //
        
        if ((Fcb != NULL) &&
            !FlagOn( FileObject->Flags, FO_CLEANUP_COMPLETE ) &&
            FatIsFileOplockable( Fcb )) {
        
            //
            //  This is equivalent to handling cleanup, and it always cleans up any
            //  oplock immediately.  Also, we don't need any locking of the FCB here;
            //  the oplock's own lock will be sufficient for this purpose.
            //
        
            FsRtlCheckOplockEx( FatGetFcbOplock(Fcb),
                                Irp,
                                0,
                                NULL,
                                NULL,
                                NULL );
        }
#endif

        //
        //  Call the common Close routine if we are not delaying this close.
        //

        if ((((TypeOfOpen == UserFileOpen) ||
              (TypeOfOpen == UserDirectoryOpen)) &&
             FlagOn(Fcb->FcbState, FCB_STATE_DELAY_CLOSE) &&
             !FatData.ShutdownStarted) ||
            (FatCommonClose( Vcb, Fcb, Ccb, TypeOfOpen, Wait, TopLevel, &VcbDeleted ) == STATUS_PENDING)) {

            //
            //  Metadata streams have had close contexts preallocated.
            //

            if (TypeOfOpen == VirtualVolumeFile) {
                
                NT_ASSERT( Vcb->CloseContext != NULL );
                CloseContext = Vcb->CloseContext;
                Vcb->CloseContext = NULL;
                CloseContext->Free = TRUE;
            }
            else if ((TypeOfOpen == DirectoryFile) || (TypeOfOpen == EaFile)) {

                CloseContext = FatAllocateCloseContext( Vcb);
                NT_ASSERT( CloseContext != NULL );
                CloseContext->Free = TRUE;

            } else {

                //
                //  Free up any query template strings before using the close context fields,
                //  which overlap (union)
                //

                FatDeallocateCcbStrings( Ccb );

                CloseContext = &Ccb->CloseContext;
                CloseContext->Free = FALSE;
                
                SetFlag( Ccb->Flags, CCB_FLAG_CLOSE_CONTEXT );
            }

            //
            //  If the status is pending, then let's get the information we
            //  need into the close context we already have bagged, complete
            //  the request, and post it.  It is important we allocate nothing
            //  in the close path.
            //

            CloseContext->Vcb = Vcb;
            CloseContext->Fcb = Fcb;
            CloseContext->TypeOfOpen = TypeOfOpen;

            //
            //  Send it off, either to an ExWorkerThread or to the async
            //  close list.
            //

            FatQueueClose( CloseContext,
                           (BOOLEAN)(Fcb && FlagOn(Fcb->FcbState, FCB_STATE_DELAY_CLOSE)));
        } else {
            
            //
            //  The close proceeded synchronously, so for the metadata objects we
            //  can now drop the close context we preallocated.
            //
            
            if ((TypeOfOpen == VirtualVolumeFile) ||
                (TypeOfOpen == DirectoryFile) ||
                (TypeOfOpen == EaFile)) {

                if (TypeOfOpen == VirtualVolumeFile) {

                    //
                    //  If the VCB was deleted during the close, the close context for this
                    //  open has already been freed.
                    //

                    if (!VcbDeleted) {

                        CloseContext = Vcb->CloseContext;   
                        Vcb->CloseContext = NULL;

                        NT_ASSERT( CloseContext != NULL );

                    } else {

                        CloseContext = NULL;
                    }
                }
                else {

                    CloseContext = FatAllocateCloseContext( (VcbDeleted ? NULL : Vcb) );

                    NT_ASSERT( CloseContext != NULL );
                }

                if (CloseContext != NULL) {

                    ExFreePool( CloseContext );
                }
            }
        }

        FatCompleteRequest( FatNull, Irp, Status );

    } 
    except(FatExceptionFilter( NULL, GetExceptionInformation() )) {

        //
        //  We had some trouble trying to perform the requested
        //  operation, so we'll abort the I/O request with the 
        //  error status that we get back from the execption code.
        //

        Status = FatProcessException( NULL, Irp, GetExceptionCode() );
    }

    if (TopLevel) { IoSetTopLevelIrp( NULL ); }

    FsRtlExitFileSystem();

    //
    //  And return to our caller
    //

    DebugTrace(-1, Dbg, "FatFsdClose -> %08lx\n", Status);

    UNREFERENCED_PARAMETER( VolumeDeviceObject );

    return Status;
}