/*++ Copyright (c) 1991 Microsoft Corporation Module Name: DevCtrl.c Abstract: This module implements the Device Control routines for Ntfs called by the dispatch driver. Author: Gary Kimura [GaryKi] 28-May-1991 Revision History: --*/ #include "NtfsProc.h" // // The local debug trace level // #define Dbg (DEBUG_TRACE_DEVCTRL) // // Local procedure prototypes // NTSTATUS DeviceControlCompletionRoutine ( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Contxt ); #ifdef ALLOC_PRAGMA #pragma alloc_text(PAGE, NtfsCommonDeviceControl) #pragma alloc_text(PAGE, NtfsFsdDeviceControl) #endif NTSTATUS NtfsFsdDeviceControl ( IN PVOLUME_DEVICE_OBJECT VolumeDeviceObject, IN PIRP Irp ) /*++ Routine Description: This routine implements the FSD part of Device Control. 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 --*/ { TOP_LEVEL_CONTEXT TopLevelContext; PTOP_LEVEL_CONTEXT ThreadTopLevelContext; NTSTATUS Status = STATUS_SUCCESS; PIRP_CONTEXT IrpContext = NULL; ASSERT_IRP( Irp ); UNREFERENCED_PARAMETER( VolumeDeviceObject ); PAGED_CODE(); DebugTrace( +1, Dbg, ("NtfsFsdDeviceControl\n") ); // // Call the common Device Control routine // FsRtlEnterFileSystem(); ThreadTopLevelContext = NtfsSetTopLevelIrp( &TopLevelContext, FALSE, FALSE ); do { try { // // We are either initiating this request or retrying it. // if (IrpContext == NULL) { IrpContext = NtfsCreateIrpContext( Irp, CanFsdWait( Irp ) ); NtfsUpdateIrpContextWithTopLevel( IrpContext, ThreadTopLevelContext ); } else if (Status == STATUS_LOG_FILE_FULL) { NtfsCheckpointForLogFileFull( IrpContext ); } Status = NtfsCommonDeviceControl( IrpContext, Irp ); break; } except(NtfsExceptionFilter( IrpContext, 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 = NtfsProcessException( IrpContext, Irp, GetExceptionCode() ); } } while (Status == STATUS_CANT_WAIT || Status == STATUS_LOG_FILE_FULL); if (ThreadTopLevelContext == &TopLevelContext) { NtfsRestoreTopLevelIrp( ThreadTopLevelContext ); } FsRtlExitFileSystem(); // // And return to our caller // DebugTrace( -1, Dbg, ("NtfsFsdDeviceControl -> %08lx\n", Status) ); return Status; } NTSTATUS NtfsCommonDeviceControl ( IN PIRP_CONTEXT IrpContext, IN PIRP Irp ) /*++ Routine Description: This is the common routine for Device Control called by both the fsd and fsp threads. Arguments: Irp - Supplies the Irp to process Return Value: NTSTATUS - The return status for the operation --*/ { NTSTATUS Status; PIO_STACK_LOCATION IrpSp; PIO_STACK_LOCATION NextIrpSp; PFILE_OBJECT FileObject; TYPE_OF_OPEN TypeOfOpen; PVCB Vcb; PFCB Fcb; PSCB Scb; PCCB Ccb; ASSERT_IRP_CONTEXT( IrpContext ); ASSERT_IRP( Irp ); PAGED_CODE(); // // Get the current Irp stack location // IrpSp = IoGetCurrentIrpStackLocation( Irp ); DebugTrace( +1, Dbg, ("NtfsCommonDeviceControl\n") ); DebugTrace( 0, Dbg, ("IrpContext = %08lx\n", IrpContext) ); DebugTrace( 0, Dbg, ("Irp = %08lx\n", Irp) ); // // Extract and decode the file object // FileObject = IrpSp->FileObject; TypeOfOpen = NtfsDecodeFileObject( IrpContext, FileObject, &Vcb, &Fcb, &Scb, &Ccb, TRUE ); // // The only type of opens we accept are user volume opens. // if (TypeOfOpen != UserVolumeOpen) { NtfsCompleteRequest( &IrpContext, &Irp, STATUS_INVALID_PARAMETER ); DebugTrace( -1, Dbg, ("NtfsCommonDeviceControl -> %08lx\n", STATUS_INVALID_PARAMETER) ); return STATUS_INVALID_PARAMETER; } // // Get the next stack location, and copy over the stack parameter // information // NextIrpSp = IoGetNextIrpStackLocation( Irp ); *NextIrpSp = *IrpSp; // // Send the request. // Status = IoCallDriver(Vcb->TargetDeviceObject, Irp); // // Free the IrpContext and return to the caller. // NtfsDeleteIrpContext( &IrpContext ); DebugTrace( -1, Dbg, ("NtfsCommonDeviceControl -> %08lx\n", Status) ); return Status; } // // Local support routine // NTSTATUS DeviceControlCompletionRoutine ( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Contxt ) { UNREFERENCED_PARAMETER( DeviceObject ); UNREFERENCED_PARAMETER( Contxt ); // // Add the hack-o-ramma to fix formats. // if ( Irp->PendingReturned ) { IoMarkIrpPending( Irp ); } return STATUS_SUCCESS; }