windows-nt/Source/XPSP1/NT/net/sockets/winsock2/wsp/afdsys/dispatch.c
2020-09-26 16:20:57 +08:00

334 lines
7.9 KiB
C
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*++
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;
}