334 lines
7.9 KiB
C
334 lines
7.9 KiB
C
|
/*++
|
|||
|
|
|||
|
Copyright (c) 1989 Microsoft Corporation
|
|||
|
|
|||
|
Module Name:
|
|||
|
|
|||
|
dispatch.c
|
|||
|
|
|||
|
Abstract:
|
|||
|
|
|||
|
This module contains the dispatch routines for AFD.
|
|||
|
|
|||
|
Author:
|
|||
|
|
|||
|
David Treadwell (davidtr) 21-Feb-1992
|
|||
|
|
|||
|
Revision History:
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
#include "afdp.h"
|
|||
|
|
|||
|
#ifdef ALLOC_PRAGMA
|
|||
|
#pragma alloc_text( PAGEAFD, AfdDispatch )
|
|||
|
#pragma alloc_text( PAGEAFD, AfdDispatchDeviceControl )
|
|||
|
#endif
|
|||
|
|
|||
|
|
|||
|
NTSTATUS
|
|||
|
AfdDispatch (
|
|||
|
IN PDEVICE_OBJECT DeviceObject,
|
|||
|
IN PIRP Irp
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This is the dispatch routine for AFD.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
DeviceObject - Pointer to device object for target device
|
|||
|
|
|||
|
Irp - Pointer to I/O request packet
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
NTSTATUS -- Indicates whether the request was successfully queued.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
PIO_STACK_LOCATION irpSp;
|
|||
|
NTSTATUS status;
|
|||
|
#if DBG
|
|||
|
KIRQL currentIrql;
|
|||
|
|
|||
|
currentIrql = KeGetCurrentIrql( );
|
|||
|
#endif
|
|||
|
|
|||
|
irpSp = IoGetCurrentIrpStackLocation( Irp );
|
|||
|
|
|||
|
switch ( irpSp->MajorFunction ) {
|
|||
|
|
|||
|
case IRP_MJ_WRITE:
|
|||
|
|
|||
|
//
|
|||
|
// Make the IRP look like a send IRP.
|
|||
|
//
|
|||
|
|
|||
|
ASSERT( FIELD_OFFSET( IO_STACK_LOCATION, Parameters.Write.Length ) ==
|
|||
|
FIELD_OFFSET( IO_STACK_LOCATION, Parameters.DeviceIoControl.OutputBufferLength ) );
|
|||
|
ASSERT( FIELD_OFFSET( IO_STACK_LOCATION, Parameters.Write.Key ) ==
|
|||
|
FIELD_OFFSET( IO_STACK_LOCATION, Parameters.DeviceIoControl.InputBufferLength ) );
|
|||
|
irpSp->Parameters.Write.Key = 0;
|
|||
|
|
|||
|
if (IS_SAN_ENDPOINT ((PAFD_ENDPOINT)irpSp->FileObject->FsContext)) {
|
|||
|
status = AfdSanRedirectRequest (Irp, irpSp);
|
|||
|
}
|
|||
|
else {
|
|||
|
status = AfdSend( Irp, irpSp );
|
|||
|
}
|
|||
|
|
|||
|
ASSERT( KeGetCurrentIrql( ) == currentIrql );
|
|||
|
|
|||
|
return status;
|
|||
|
|
|||
|
case IRP_MJ_READ:
|
|||
|
|
|||
|
//
|
|||
|
// Make the IRP look like a receive IRP.
|
|||
|
//
|
|||
|
|
|||
|
ASSERT( FIELD_OFFSET( IO_STACK_LOCATION, Parameters.Read.Length ) ==
|
|||
|
FIELD_OFFSET( IO_STACK_LOCATION, Parameters.DeviceIoControl.OutputBufferLength ) );
|
|||
|
ASSERT( FIELD_OFFSET( IO_STACK_LOCATION, Parameters.Read.Key ) ==
|
|||
|
FIELD_OFFSET( IO_STACK_LOCATION, Parameters.DeviceIoControl.InputBufferLength ) );
|
|||
|
irpSp->Parameters.Read.Key = 0;
|
|||
|
|
|||
|
if (IS_SAN_ENDPOINT ((PAFD_ENDPOINT)irpSp->FileObject->FsContext)) {
|
|||
|
status = AfdSanRedirectRequest (Irp, irpSp);
|
|||
|
}
|
|||
|
else {
|
|||
|
status = AfdReceive( Irp, irpSp );
|
|||
|
}
|
|||
|
|
|||
|
ASSERT( KeGetCurrentIrql( ) == currentIrql );
|
|||
|
|
|||
|
return status;
|
|||
|
|
|||
|
case IRP_MJ_CREATE:
|
|||
|
|
|||
|
status = AfdCreate( Irp, irpSp );
|
|||
|
|
|||
|
ASSERT( KeGetCurrentIrql( ) == currentIrql );
|
|||
|
|
|||
|
Irp->IoStatus.Status = status;
|
|||
|
IoCompleteRequest( Irp, AfdPriorityBoost );
|
|||
|
|
|||
|
return status;
|
|||
|
|
|||
|
case IRP_MJ_CLEANUP:
|
|||
|
|
|||
|
status = AfdCleanup( Irp, irpSp );
|
|||
|
|
|||
|
Irp->IoStatus.Status = status;
|
|||
|
IoCompleteRequest( Irp, AfdPriorityBoost );
|
|||
|
|
|||
|
ASSERT( KeGetCurrentIrql( ) == currentIrql );
|
|||
|
|
|||
|
return status;
|
|||
|
|
|||
|
case IRP_MJ_CLOSE:
|
|||
|
|
|||
|
status = AfdClose( Irp, irpSp );
|
|||
|
|
|||
|
Irp->IoStatus.Status = status;
|
|||
|
IoCompleteRequest( Irp, AfdPriorityBoost );
|
|||
|
|
|||
|
ASSERT( KeGetCurrentIrql( ) == currentIrql );
|
|||
|
|
|||
|
return status;
|
|||
|
case IRP_MJ_PNP:
|
|||
|
status = AfdPnpPower (Irp, irpSp );
|
|||
|
|
|||
|
ASSERT( KeGetCurrentIrql( ) == currentIrql );
|
|||
|
|
|||
|
return status;
|
|||
|
case IRP_MJ_DEVICE_CONTROL:
|
|||
|
|
|||
|
return AfdDispatchDeviceControl( DeviceObject, Irp );
|
|||
|
|
|||
|
//
|
|||
|
// SAN support.
|
|||
|
// Return special error code to let IO manager use default security.
|
|||
|
// (needed to support ObOpenObjectByPointer).
|
|||
|
//
|
|||
|
case IRP_MJ_QUERY_SECURITY:
|
|||
|
case IRP_MJ_SET_SECURITY:
|
|||
|
Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
|
|||
|
IoCompleteRequest( Irp, AfdPriorityBoost );
|
|||
|
return STATUS_INVALID_DEVICE_REQUEST;
|
|||
|
|
|||
|
default:
|
|||
|
KdPrintEx(( DPFLTR_WSOCKTRANSPORT_ID, DPFLTR_INFO_LEVEL,
|
|||
|
"AfdDispatch: Invalid major function %lx\n",
|
|||
|
irpSp->MajorFunction ));
|
|||
|
Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
|
|||
|
IoCompleteRequest( Irp, AfdPriorityBoost );
|
|||
|
|
|||
|
return STATUS_NOT_IMPLEMENTED;
|
|||
|
}
|
|||
|
|
|||
|
} // AfdDispatch
|
|||
|
|
|||
|
|
|||
|
NTSTATUS
|
|||
|
AfdDispatchDeviceControl (
|
|||
|
IN PDEVICE_OBJECT DeviceObject,
|
|||
|
IN PIRP Irp
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This is the dispatch routine for AFD IOCTLs.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
DeviceObject - Pointer to device object for target device
|
|||
|
|
|||
|
Irp - Pointer to I/O request packet
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
NTSTATUS -- Indicates whether the request was successfully queued.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
ULONG code;
|
|||
|
ULONG request;
|
|||
|
NTSTATUS status;
|
|||
|
PAFD_IRP_CALL irpProc;
|
|||
|
PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation (Irp);
|
|||
|
#if DBG
|
|||
|
KIRQL currentIrql;
|
|||
|
|
|||
|
currentIrql = KeGetCurrentIrql( );
|
|||
|
#endif
|
|||
|
UNREFERENCED_PARAMETER (DeviceObject);
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
// Extract the IOCTL control code and process the request.
|
|||
|
//
|
|||
|
|
|||
|
code = IrpSp->Parameters.DeviceIoControl.IoControlCode;
|
|||
|
request = _AFD_REQUEST(code);
|
|||
|
|
|||
|
if( request < AFD_NUM_IOCTLS && AfdIoctlTable[request] == code ) {
|
|||
|
|
|||
|
//
|
|||
|
// Helps in debugging.
|
|||
|
//
|
|||
|
IrpSp->MinorFunction = (UCHAR)request;
|
|||
|
|
|||
|
//
|
|||
|
// Try IRP dispatch first
|
|||
|
//
|
|||
|
irpProc = AfdIrpCallDispatch[request];
|
|||
|
if (irpProc!=NULL) {
|
|||
|
status = (*irpProc)(Irp, IrpSp);
|
|||
|
|
|||
|
ASSERT( KeGetCurrentIrql( ) == currentIrql );
|
|||
|
|
|||
|
return status;
|
|||
|
}
|
|||
|
}
|
|||
|
//
|
|||
|
// This is currently not used by helper dlls.
|
|||
|
// Commented out because of security concerns
|
|||
|
//
|
|||
|
#if 0
|
|||
|
else if (request==AFD_TRANSPORT_IOCTL) {
|
|||
|
//
|
|||
|
// This is a "special" used to pass request
|
|||
|
// to transport driver using socket handle in
|
|||
|
// order to facilitate proper completion
|
|||
|
// on sockets associated with completion port.
|
|||
|
// It accepts and properly handles all methods.
|
|||
|
//
|
|||
|
status = AfdDoTransportIoctl (Irp, IrpSp);
|
|||
|
ASSERT( KeGetCurrentIrql() == currentIrql );
|
|||
|
return status;
|
|||
|
}
|
|||
|
#endif
|
|||
|
|
|||
|
//
|
|||
|
// If we made it this far, then the ioctl is invalid.
|
|||
|
//
|
|||
|
|
|||
|
KdPrintEx(( DPFLTR_WSOCKTRANSPORT_ID, DPFLTR_WARNING_LEVEL,
|
|||
|
"AfdDispatchDeviceControl: invalid IOCTL %08lX\n",
|
|||
|
code
|
|||
|
));
|
|||
|
|
|||
|
Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
|
|||
|
IoCompleteRequest( Irp, AfdPriorityBoost );
|
|||
|
|
|||
|
return STATUS_INVALID_DEVICE_REQUEST;
|
|||
|
|
|||
|
} // AfdDispatchDeviceControl
|
|||
|
|
|||
|
NTSTATUS
|
|||
|
FASTCALL
|
|||
|
AfdDispatchImmediateIrp(
|
|||
|
IN PIRP Irp,
|
|||
|
IN PIO_STACK_LOCATION IrpSp
|
|||
|
)
|
|||
|
{
|
|||
|
PAFD_IMMEDIATE_CALL immProc;
|
|||
|
ULONG code;
|
|||
|
ULONG request;
|
|||
|
NTSTATUS status;
|
|||
|
#if DBG
|
|||
|
KIRQL currentIrql;
|
|||
|
|
|||
|
currentIrql = KeGetCurrentIrql( );
|
|||
|
#endif
|
|||
|
|
|||
|
code = IrpSp->Parameters.DeviceIoControl.IoControlCode;
|
|||
|
request = _AFD_REQUEST(code);
|
|||
|
|
|||
|
immProc = AfdImmediateCallDispatch[request];
|
|||
|
if (immProc!=NULL) {
|
|||
|
//
|
|||
|
// Must be METHOD_NEITHER for the below code to be
|
|||
|
// valid.
|
|||
|
//
|
|||
|
ASSERT ( (code & 3) == METHOD_NEITHER );
|
|||
|
#if DBG
|
|||
|
if (Irp->RequestorMode!=KernelMode) {
|
|||
|
KdPrintEx(( DPFLTR_WSOCKTRANSPORT_ID, DPFLTR_WARNING_LEVEL,
|
|||
|
"AfdDispatchDeviceControl: "
|
|||
|
"User mode application somehow bypassed fast io dispatch\n"));
|
|||
|
}
|
|||
|
#endif
|
|||
|
status = (*immProc) (
|
|||
|
IrpSp->FileObject,
|
|||
|
code,
|
|||
|
Irp->RequestorMode,
|
|||
|
IrpSp->Parameters.DeviceIoControl.Type3InputBuffer,
|
|||
|
IrpSp->Parameters.DeviceIoControl.InputBufferLength,
|
|||
|
Irp->UserBuffer,
|
|||
|
IrpSp->Parameters.DeviceIoControl.OutputBufferLength,
|
|||
|
&Irp->IoStatus.Information
|
|||
|
);
|
|||
|
|
|||
|
ASSERT( KeGetCurrentIrql( ) == currentIrql );
|
|||
|
|
|||
|
}
|
|||
|
else {
|
|||
|
ASSERT (!"Missing IOCTL in dispatch table!!!");
|
|||
|
status = STATUS_INVALID_DEVICE_REQUEST;
|
|||
|
}
|
|||
|
|
|||
|
Irp->IoStatus.Status = status;
|
|||
|
IoCompleteRequest( Irp, AfdPriorityBoost );
|
|||
|
return status;
|
|||
|
}
|