NTSTATUS FatFsdPostRequest( IN PIRP_CONTEXT IrpContext, IN PIRP Irp ) /*++ Routine Description: This routine enqueues the request packet specified by IrpContext to the Ex Worker threads. This is a FSD routine. Arguments: IrpContext - Pointer to the IrpContext to be queued to the Fsp Irp - I/O Request Packet, or NULL if it has already been completed. Return Value: STATUS_PENDING --*/ { PAGED_CODE(); NT_ASSERT( ARGUMENT_PRESENT(Irp) ); NT_ASSERT( IrpContext->OriginatingIrp == Irp ); FatPrePostIrp( IrpContext, Irp ); FatAddToWorkque( IrpContext, Irp ); // // And return to our caller // return STATUS_PENDING; }
NTSTATUS FatPostStackOverflowRead ( IN PIRP_CONTEXT IrpContext, IN PIRP Irp, IN PFCB Fcb ) /*++ Routine Description: This routine posts a read request that could not be processed by the fsp thread because of stack overflow potential. Arguments: Irp - Supplies the request to process. Fcb - Supplies the file. Return Value: STATUS_PENDING. --*/ { KEVENT Event; PERESOURCE Resource; PVCB Vcb; PAGED_CODE(); DebugTrace(0, Dbg, "Getting too close to stack limit pass request to Fsp\n", 0 ); // // Initialize an event and get shared on the resource we will // be later using the common read. // KeInitializeEvent( &Event, NotificationEvent, FALSE ); // // Preacquire the resource the read path will require so we know the // worker thread can proceed without waiting. // if (FlagOn(Irp->Flags, IRP_PAGING_IO) && (Fcb->Header.PagingIoResource != NULL)) { Resource = Fcb->Header.PagingIoResource; } else { Resource = Fcb->Header.Resource; } // // If there are no resources assodicated with the file (case: the virtual // volume file), it is OK. No resources will be acquired on the other side // as well. // if (Resource) { ExAcquireResourceSharedLite( Resource, TRUE ); } if (NodeType( Fcb ) == FAT_NTC_VCB) { Vcb = (PVCB) Fcb; } else { Vcb = Fcb->Vcb; } try { // // Make the Irp just like a regular post request and // then send the Irp to the special overflow thread. // After the post we will wait for the stack overflow // read routine to set the event that indicates we can // now release the scb resource and return. // FatPrePostIrp( IrpContext, Irp ); // // If this read is the result of a verify, we have to // tell the overflow read routne to temporarily // hijack the Vcb->VerifyThread field so that reads // can go through. // if (Vcb->VerifyThread == KeGetCurrentThread()) { SetFlag(IrpContext->Flags, IRP_CONTEXT_FLAG_VERIFY_READ); } FsRtlPostStackOverflow( IrpContext, &Event, FatStackOverflowRead ); // // And wait for the worker thread to complete the item // KeWaitForSingleObject( &Event, Executive, KernelMode, FALSE, NULL ); } finally { if (Resource) { ExReleaseResourceLite( Resource ); } } return STATUS_PENDING; }
NTSTATUS FatPostStackOverflowRead ( IN PIRP_CONTEXT IrpContext, IN PIRP Irp, IN PFCB Fcb ) /*++ Routine Description: This routine posts a read request that could not be processed by the fsp thread because of stack overflow potential. Arguments: Irp - Supplies the request to process. Fcb - Supplies the file. Return Value: STATUS_PENDING. --*/ { PKEVENT Event; PERESOURCE Resource; DebugTrace(0, Dbg, "Getting too close to stack limit pass request to Fsp\n", 0 ); // // Allocate an event and get shared on the resource we will // be later using the common read. // Event = FsRtlAllocatePool( NonPagedPool, sizeof(KEVENT) ); KeInitializeEvent( Event, NotificationEvent, FALSE ); if (FlagOn(Irp->Flags, IRP_PAGING_IO) && (Fcb->Header.PagingIoResource != NULL)) { Resource = Fcb->Header.PagingIoResource; } else { Resource = Fcb->Header.Resource; } ExAcquireResourceShared( Resource, TRUE ); try { // // Make the Irp just like a regular post request and // then send the Irp to the special overflow thread. // After the post we will wait for the stack overflow // read routine to set the event that indicates we can // now release the scb resource and return. // FatPrePostIrp( IrpContext, Irp ); // // If this read is the result of a verify, we have to // tell the overflow read routne to temporarily // hijack the Vcb->VerifyThread field so that reads // can go through. // if (Fcb->Vcb->VerifyThread == KeGetCurrentThread()) { SetFlag(IrpContext->Flags, IRP_CONTEXT_FLAG_VERIFY_READ); } FsRtlPostStackOverflow( IrpContext, Event, FatStackOverflowRead ); // // And wait for the worker thread to complete the item // (VOID) KeWaitForSingleObject( Event, Executive, KernelMode, FALSE, NULL ); } finally { ExReleaseResource( Resource ); ExFreePool( Event ); } return STATUS_PENDING; }