windows-nt/Source/XPSP1/NT/base/ntos/raw/rawdisp.c

243 lines
5.5 KiB
C
Raw Permalink Normal View History

2020-09-26 03:20:57 -05:00
/*++
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_PNP:
if(IrpSp->MinorFunction == IRP_MN_QUERY_REMOVE_DEVICE) {
Status = STATUS_DEVICE_BUSY;
RawCompleteRequest(Irp, Status);
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));
KeBugCheckEx( FILE_SYSTEM, 0, 0, 0, 0 );
}
} 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;
}