360 lines
7.9 KiB
C
360 lines
7.9 KiB
C
/*++
|
|
|
|
Copyright (c) 1998-2002 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
devctrl.c
|
|
|
|
Abstract:
|
|
|
|
This module contains the dispatcher for device control IRPs.
|
|
|
|
Author:
|
|
|
|
Keith Moore (keithmo) 10-Jun-1998
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
|
|
#include "precomp.h"
|
|
#include "ioctlp.h"
|
|
|
|
|
|
#ifdef ALLOC_PRAGMA
|
|
#endif // ALLOC_PRAGMA
|
|
#if 0
|
|
NOT PAGEABLE -- UlDeviceControl
|
|
#endif
|
|
|
|
|
|
//
|
|
// Lookup table to verify incoming IOCTL codes.
|
|
//
|
|
|
|
typedef
|
|
NTSTATUS
|
|
(NTAPI * PFN_IOCTL_HANDLER)(
|
|
IN PIRP Irp,
|
|
IN PIO_STACK_LOCATION IrpSp
|
|
);
|
|
|
|
typedef struct _UL_IOCTL_TABLE
|
|
{
|
|
ULONG IoControlCode;
|
|
|
|
#if DBG
|
|
PCSTR IoControlName;
|
|
# define UL_IOCTL(code) IOCTL_HTTP_##code, #code
|
|
#else // !DBG
|
|
# define UL_IOCTL(code) IOCTL_HTTP_##code
|
|
#endif // !DBG
|
|
|
|
PFN_IOCTL_HANDLER Handler;
|
|
} UL_IOCTL_TABLE, *PUL_IOCTL_TABLE;
|
|
|
|
|
|
UL_IOCTL_TABLE UlIoctlTable[] =
|
|
{
|
|
{ UL_IOCTL(QUERY_CONTROL_CHANNEL),
|
|
&UlQueryControlChannelIoctl
|
|
},
|
|
{ UL_IOCTL(SET_CONTROL_CHANNEL),
|
|
&UlSetControlChannelIoctl
|
|
},
|
|
{ UL_IOCTL(CREATE_CONFIG_GROUP),
|
|
&UlCreateConfigGroupIoctl
|
|
},
|
|
{ UL_IOCTL(DELETE_CONFIG_GROUP),
|
|
&UlDeleteConfigGroupIoctl
|
|
},
|
|
{ UL_IOCTL(QUERY_CONFIG_GROUP),
|
|
&UlQueryConfigGroupIoctl
|
|
},
|
|
{ UL_IOCTL(SET_CONFIG_GROUP),
|
|
&UlSetConfigGroupIoctl
|
|
},
|
|
{ UL_IOCTL(ADD_URL_TO_CONFIG_GROUP),
|
|
&UlAddUrlToConfigGroupIoctl
|
|
},
|
|
{ UL_IOCTL(REMOVE_URL_FROM_CONFIG_GROUP),
|
|
&UlRemoveUrlFromConfigGroupIoctl
|
|
},
|
|
{ UL_IOCTL(REMOVE_ALL_URLS_FROM_CONFIG_GROUP),
|
|
&UlRemoveAllUrlsFromConfigGroupIoctl
|
|
},
|
|
{ UL_IOCTL(QUERY_APP_POOL_INFORMATION),
|
|
&UlQueryAppPoolInformationIoctl
|
|
},
|
|
{ UL_IOCTL(SET_APP_POOL_INFORMATION),
|
|
&UlSetAppPoolInformationIoctl
|
|
},
|
|
{ UL_IOCTL(SHUTDOWN_APP_POOL),
|
|
&UlShutdownAppPoolIoctl
|
|
},
|
|
{ UL_IOCTL(RECEIVE_HTTP_REQUEST),
|
|
&UlReceiveHttpRequestIoctl
|
|
},
|
|
{ UL_IOCTL(RECEIVE_ENTITY_BODY),
|
|
&UlReceiveEntityBodyIoctl
|
|
},
|
|
{ UL_IOCTL(SEND_HTTP_RESPONSE),
|
|
&UlSendHttpResponseIoctl
|
|
},
|
|
{ UL_IOCTL(SEND_ENTITY_BODY),
|
|
&UlSendEntityBodyIoctl
|
|
},
|
|
{ UL_IOCTL(FLUSH_RESPONSE_CACHE),
|
|
&UlFlushResponseCacheIoctl
|
|
},
|
|
{ UL_IOCTL(WAIT_FOR_DEMAND_START),
|
|
&UlWaitForDemandStartIoctl
|
|
},
|
|
{ UL_IOCTL(WAIT_FOR_DISCONNECT),
|
|
&UlWaitForDisconnectIoctl
|
|
},
|
|
{ UL_IOCTL(FILTER_ACCEPT),
|
|
&UlFilterAcceptIoctl
|
|
},
|
|
{ UL_IOCTL(FILTER_CLOSE),
|
|
&UlFilterCloseIoctl
|
|
},
|
|
{ UL_IOCTL(FILTER_RAW_READ),
|
|
&UlFilterRawReadIoctl
|
|
},
|
|
{ UL_IOCTL(FILTER_RAW_WRITE),
|
|
&UlFilterRawWriteIoctl
|
|
},
|
|
{ UL_IOCTL(FILTER_APP_READ),
|
|
&UlFilterAppReadIoctl
|
|
},
|
|
{ UL_IOCTL(FILTER_APP_WRITE),
|
|
&UlFilterAppWriteIoctl
|
|
},
|
|
{ UL_IOCTL(FILTER_RECEIVE_CLIENT_CERT),
|
|
&UlReceiveClientCertIoctl
|
|
},
|
|
{ UL_IOCTL(SHUTDOWN_FILTER_CHANNEL),
|
|
&UlShutdownFilterIoctl
|
|
},
|
|
{ UL_IOCTL(GET_COUNTERS),
|
|
&UlGetCountersIoctl
|
|
},
|
|
{ UL_IOCTL(ADD_FRAGMENT_TO_CACHE),
|
|
&UlAddFragmentToCacheIoctl
|
|
},
|
|
{ UL_IOCTL(READ_FRAGMENT_FROM_CACHE),
|
|
&UlReadFragmentFromCacheIoctl
|
|
},
|
|
{ UL_IOCTL(SEND_REQUEST),
|
|
&UcSendRequestIoctl
|
|
},
|
|
{ UL_IOCTL(SEND_REQUEST_ENTITY_BODY),
|
|
&UcSendEntityBodyIoctl
|
|
},
|
|
{ UL_IOCTL(RECEIVE_RESPONSE),
|
|
&UcReceiveResponseIoctl
|
|
},
|
|
{ UL_IOCTL(QUERY_SERVER_CONTEXT_INFORMATION),
|
|
&UcQueryServerContextInformationIoctl,
|
|
},
|
|
{ UL_IOCTL(SET_SERVER_CONTEXT_INFORMATION),
|
|
&UcSetServerContextInformationIoctl,
|
|
},
|
|
{ UL_IOCTL(CANCEL_REQUEST),
|
|
&UcCancelRequestIoctl
|
|
},
|
|
};
|
|
|
|
C_ASSERT( HTTP_NUM_IOCTLS == DIMENSION(UlIoctlTable) );
|
|
|
|
//
|
|
// Private functions.
|
|
//
|
|
|
|
/***************************************************************************++
|
|
|
|
Routine Description:
|
|
|
|
Dummy Handler
|
|
|
|
Arguments:
|
|
|
|
pIrp - Supplies a pointer to the IO request packet.
|
|
|
|
pIrpSp - Supplies a pointer to the IO stack location to use for this
|
|
request.
|
|
|
|
Return Value:
|
|
|
|
NTSTATUS - Completion status.
|
|
|
|
--***************************************************************************/
|
|
NTSTATUS
|
|
UlpDummyIoctl(
|
|
IN PIRP pIrp,
|
|
IN PIO_STACK_LOCATION pIrpSp
|
|
)
|
|
{
|
|
NTSTATUS Status = STATUS_INVALID_DEVICE_REQUEST;
|
|
|
|
UNREFERENCED_PARAMETER( pIrpSp );
|
|
|
|
PAGED_CODE();
|
|
|
|
//
|
|
// OBSOLETE
|
|
//
|
|
|
|
COMPLETE_REQUEST_AND_RETURN( pIrp, Status );
|
|
|
|
} // UlpDummyIoctl
|
|
|
|
|
|
/***************************************************************************++
|
|
|
|
Routine Description:
|
|
|
|
Disables a particular IOCTL.
|
|
|
|
Arguments:
|
|
|
|
ioctl - The IO control code.
|
|
|
|
Return Value:
|
|
|
|
VOID
|
|
|
|
--***************************************************************************/
|
|
VOID
|
|
UlpSetDummyIoctl(
|
|
ULONG ioctl
|
|
)
|
|
{
|
|
ULONG request;
|
|
|
|
request = _HTTP_REQUEST(ioctl);
|
|
|
|
ASSERT(request < HTTP_NUM_IOCTLS &&
|
|
UlIoctlTable[request].IoControlCode == ioctl);
|
|
|
|
UlIoctlTable[request].Handler = UlpDummyIoctl;
|
|
}
|
|
|
|
//
|
|
// Public functions.
|
|
//
|
|
|
|
/***************************************************************************++
|
|
|
|
Routine Description:
|
|
|
|
This is the dispatch routine for IOCTL IRPs.
|
|
|
|
Arguments:
|
|
|
|
pDeviceObject - Pointer to device object for target device.
|
|
|
|
pIrp - Pointer to IO request packet.
|
|
|
|
Return Value:
|
|
|
|
NTSTATUS -- Indicates whether the request was successfully queued.
|
|
|
|
--***************************************************************************/
|
|
NTSTATUS
|
|
UlDeviceControl(
|
|
IN PDEVICE_OBJECT pDeviceObject,
|
|
IN PIRP pIrp
|
|
)
|
|
{
|
|
ULONG code;
|
|
ULONG request;
|
|
NTSTATUS status;
|
|
PIO_STACK_LOCATION pIrpSp;
|
|
|
|
UNREFERENCED_PARAMETER( pDeviceObject );
|
|
|
|
UL_ENTER_DRIVER( "UlDeviceControl", pIrp );
|
|
|
|
//
|
|
// Snag the current IRP stack pointer.
|
|
//
|
|
|
|
pIrpSp = IoGetCurrentIrpStackLocation( pIrp );
|
|
|
|
//
|
|
// Extract the IOCTL control code and process the request.
|
|
//
|
|
|
|
code = pIrpSp->Parameters.DeviceIoControl.IoControlCode;
|
|
request = _HTTP_REQUEST(code);
|
|
|
|
if (request < HTTP_NUM_IOCTLS &&
|
|
UlIoctlTable[request].IoControlCode == code)
|
|
{
|
|
#if DBG
|
|
KIRQL oldIrql = KeGetCurrentIrql();
|
|
#endif // DBG
|
|
|
|
UlTrace(IOCTL,
|
|
("UlDeviceControl: %-30s code=0x%08lx, "
|
|
"pIrp=%p, pIrpSp=%p.\n",
|
|
UlIoctlTable[request].IoControlName, code,
|
|
pIrp, pIrpSp
|
|
));
|
|
|
|
UlInitializeWorkItem(UL_WORK_ITEM_FROM_IRP( pIrp ));
|
|
|
|
status = (UlIoctlTable[request].Handler)( pIrp, pIrpSp );
|
|
|
|
ASSERT( KeGetCurrentIrql() == oldIrql );
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// If we made it this far, then the ioctl is invalid.
|
|
//
|
|
|
|
UlTrace(IOCTL, ( "UlDeviceControl: invalid IOCTL %08lX\n", code ));
|
|
|
|
status = STATUS_INVALID_DEVICE_REQUEST;
|
|
pIrp->IoStatus.Status = status;
|
|
|
|
UlCompleteRequest( pIrp, IO_NO_INCREMENT );
|
|
}
|
|
|
|
UL_LEAVE_DRIVER( "UlDeviceControl" );
|
|
|
|
return status;
|
|
|
|
} // UlDeviceControl
|
|
|
|
/***************************************************************************++
|
|
|
|
Routine Description:
|
|
|
|
Disables some of the IOCTLs we don't use.
|
|
|
|
Arguments:
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--***************************************************************************/
|
|
VOID
|
|
UlSetDummyIoctls(
|
|
VOID
|
|
)
|
|
{
|
|
UlpSetDummyIoctl(IOCTL_HTTP_SEND_REQUEST);
|
|
UlpSetDummyIoctl(IOCTL_HTTP_SEND_REQUEST_ENTITY_BODY);
|
|
UlpSetDummyIoctl(IOCTL_HTTP_RECEIVE_RESPONSE);
|
|
UlpSetDummyIoctl(IOCTL_HTTP_QUERY_SERVER_CONTEXT_INFORMATION);
|
|
UlpSetDummyIoctl(IOCTL_HTTP_SET_SERVER_CONTEXT_INFORMATION);
|
|
UlpSetDummyIoctl(IOCTL_HTTP_CANCEL_REQUEST);
|
|
}
|