/*++ Copyright (c) 1989 Microsoft Corporation Module Name: RawDisp.c Abstract: This module is the main entry point for all major function codes. It is responsible for dispatching the request to the appropriate routine. Author: David Goebel [DavidGoe] 28-Feb-1991 Revision History: --*/ #include "RawProcs.h" #ifdef ALLOC_PRAGMA #pragma alloc_text(PAGE, RawDispatch) #endif NTSTATUS RawDispatch ( IN PVOLUME_DEVICE_OBJECT VolumeDeviceObject, IN PIRP Irp ) /*++ Routine Description: Dispatch the request to the appropriate function. It is the worker function's responsibility to appropriately complete the IRP. Arguments: VolumeDeviceObject - Supplies the volume device object to use. Irp - Supplies the Irp being processed Return Value: NTSTATUS - The status for the IRP --*/ { NTSTATUS Status; PIO_STACK_LOCATION IrpSp; PVCB Vcb; PAGED_CODE(); // // Get a pointer to the current stack location. This location contains // the function codes and parameters for this particular request. // IrpSp = IoGetCurrentIrpStackLocation( Irp ); // // Check for operations associated with our FileSystemDeviceObjects // as opposed to our VolumeDeviceObjects. Only mount is allowed to // continue through the normal dispatch in this case. // if ((((PDEVICE_OBJECT)VolumeDeviceObject)->Size == sizeof(DEVICE_OBJECT)) && !((IrpSp->MajorFunction == IRP_MJ_FILE_SYSTEM_CONTROL) && (IrpSp->MinorFunction == IRP_MN_MOUNT_VOLUME))) { if ((IrpSp->MajorFunction == IRP_MJ_CREATE) || (IrpSp->MajorFunction == IRP_MJ_CLEANUP) || (IrpSp->MajorFunction == IRP_MJ_CLOSE)) { Status = STATUS_SUCCESS; } else { Status = STATUS_INVALID_DEVICE_REQUEST; } RawCompleteRequest( Irp, Status ); return Status; } FsRtlEnterFileSystem(); // // Get a pointer to the Vcb. Note that is we are mount a volume this // pointer will not have meaning, but that is OK since we will not // use it in that case. // Vcb = &VolumeDeviceObject->Vcb; // // Case on the function that is being performed by the requestor. We // should only see expected requests since we filled the dispatch table // by hand. // try { switch ( IrpSp->MajorFunction ) { case IRP_MJ_CLEANUP: Status = RawCleanup( Vcb, Irp, IrpSp ); break; case IRP_MJ_CLOSE: Status = RawClose( Vcb, Irp, IrpSp ); break; case IRP_MJ_CREATE: Status = RawCreate( Vcb, Irp, IrpSp ); break; case IRP_MJ_FILE_SYSTEM_CONTROL: Status = RawFileSystemControl( Vcb, Irp, IrpSp ); break; case IRP_MJ_READ: case IRP_MJ_WRITE: case IRP_MJ_DEVICE_CONTROL: Status = RawReadWriteDeviceControl( Vcb, Irp, IrpSp ); break; case IRP_MJ_QUERY_INFORMATION: Status = RawQueryInformation( Vcb, Irp, IrpSp ); break; case IRP_MJ_SET_INFORMATION: Status = RawSetInformation( Vcb, Irp, IrpSp ); break; case IRP_MJ_QUERY_VOLUME_INFORMATION: Status = RawQueryVolumeInformation( Vcb, Irp, IrpSp ); break; default: // // We should never get a request we don't expect. // KdPrint(("Raw: Illegal Irp major function code 0x%x.\n", IrpSp->MajorFunction)); KeBugCheck( FILE_SYSTEM ); } } except( FsRtlIsNtstatusExpected(GetExceptionCode()) ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH ) { // // No routine we call should ever generate an exception // Status = GetExceptionCode(); KdPrint(("Raw: Unexpected excpetion %X.\n", Status)); } // // And return to our caller // FsRtlExitFileSystem(); return Status; } // // Completion routine for read, write, and device control to deal with // verify issues. Implemented in RawDisp.c // NTSTATUS RawCompletionRoutine( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context ) { PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation( Irp ); // // Simply update the file pointer context in the file object if we // were successful and this was a synrhonous read or write. // if (((IrpSp->MajorFunction == IRP_MJ_READ) || (IrpSp->MajorFunction == IRP_MJ_WRITE)) && (IrpSp->FileObject != NULL) && FlagOn(IrpSp->FileObject->Flags, FO_SYNCHRONOUS_IO) && NT_SUCCESS(Irp->IoStatus.Status)) { IrpSp->FileObject->CurrentByteOffset.QuadPart = IrpSp->FileObject->CurrentByteOffset.QuadPart + Irp->IoStatus.Information; } // // If IoCallDriver returned PENDING, mark our stack location // with pending. // if ( Irp->PendingReturned ) { IoMarkIrpPending( Irp ); } UNREFERENCED_PARAMETER( DeviceObject ); UNREFERENCED_PARAMETER( Context ); return STATUS_SUCCESS; }