dispatch.c
来自「这是一个开放源代码的与WINNT/WIN2K/WIN2003兼容的操作系统」· C语言 代码 · 共 1,574 行 · 第 1/4 页
C
1,574 行
ObDereferenceObject(FileObject);
return Status;
}
NTSTATUS DispTdiConnect(
PIRP Irp)
/*
* FUNCTION: TDI_CONNECT handler
* ARGUMENTS:
* Irp = Pointer to an I/O request packet
* RETURNS:
* Status of operation
*/
{
PCONNECTION_ENDPOINT Connection;
PTDI_REQUEST_KERNEL Parameters;
PTRANSPORT_CONTEXT TranContext;
PIO_STACK_LOCATION IrpSp;
NTSTATUS Status;
TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
IrpSp = IoGetCurrentIrpStackLocation(Irp);
/* Get associated connection endpoint file object. Quit if none exists */
TranContext = IrpSp->FileObject->FsContext;
if (!TranContext) {
TI_DbgPrint(MID_TRACE, ("Bad transport context.\n"));
return STATUS_INVALID_CONNECTION;
}
Connection = (PCONNECTION_ENDPOINT)TranContext->Handle.ConnectionContext;
if (!Connection) {
TI_DbgPrint(MID_TRACE, ("No connection endpoint file object.\n"));
return STATUS_INVALID_CONNECTION;
}
Parameters = (PTDI_REQUEST_KERNEL)&IrpSp->Parameters;
Status = TCPConnect(
TranContext->Handle.ConnectionContext,
Parameters->RequestConnectionInformation,
Parameters->ReturnConnectionInformation,
DispDataRequestComplete,
Irp );
TI_DbgPrint(MAX_TRACE, ("TCP Connect returned %08x\n", Status));
return Status;
}
NTSTATUS DispTdiDisassociateAddress(
PIRP Irp)
/*
* FUNCTION: TDI_DISASSOCIATE_ADDRESS handler
* ARGUMENTS:
* Irp = Pointer to an I/O request packet
* RETURNS:
* Status of operation
*/
{
PCONNECTION_ENDPOINT Connection;
PTRANSPORT_CONTEXT TranContext;
PIO_STACK_LOCATION IrpSp;
TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
IrpSp = IoGetCurrentIrpStackLocation(Irp);
/* Get associated connection endpoint file object. Quit if none exists */
TranContext = IrpSp->FileObject->FsContext;
if (!TranContext) {
TI_DbgPrint(MID_TRACE, ("Bad transport context.\n"));
return STATUS_INVALID_PARAMETER;
}
Connection = (PCONNECTION_ENDPOINT)TranContext->Handle.ConnectionContext;
if (!Connection) {
TI_DbgPrint(MID_TRACE, ("No connection endpoint file object.\n"));
return STATUS_INVALID_PARAMETER;
}
if (!Connection->AddressFile) {
TI_DbgPrint(MID_TRACE, ("No address file is asscociated.\n"));
return STATUS_INVALID_PARAMETER;
}
return STATUS_SUCCESS;
}
NTSTATUS DispTdiDisconnect(
PIRP Irp)
/*
* FUNCTION: TDI_DISCONNECT handler
* ARGUMENTS:
* Irp = Pointer to an I/O request packet
* RETURNS:
* Status of operation
*/
{
NTSTATUS Status;
PTDI_REQUEST_KERNEL_DISCONNECT DisReq;
PCONNECTION_ENDPOINT Connection;
PTRANSPORT_CONTEXT TranContext;
PIO_STACK_LOCATION IrpSp;
TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
IrpSp = IoGetCurrentIrpStackLocation(Irp);
DisReq = (PTDI_REQUEST_KERNEL_DISCONNECT)&IrpSp->Parameters;
/* Get associated connection endpoint file object. Quit if none exists */
TranContext = IrpSp->FileObject->FsContext;
if (!TranContext) {
TI_DbgPrint(MID_TRACE, ("Bad transport context.\n"));
return STATUS_INVALID_CONNECTION;
}
Connection = (PCONNECTION_ENDPOINT)TranContext->Handle.ConnectionContext;
if (!Connection) {
TI_DbgPrint(MID_TRACE, ("No connection endpoint file object.\n"));
return STATUS_INVALID_CONNECTION;
}
Status = TCPDisconnect(
TranContext->Handle.ConnectionContext,
DisReq->RequestFlags,
DisReq->RequestConnectionInformation,
DisReq->ReturnConnectionInformation,
DispDataRequestComplete,
Irp );
TI_DbgPrint(MAX_TRACE, ("TCP Connect returned %08x\n", Status));
return Status;
}
NTSTATUS DispTdiListen(
PIRP Irp)
/*
* FUNCTION: TDI_LISTEN handler
* ARGUMENTS:
* Irp = Pointer to an I/O request packet
* RETURNS:
* Status of operation
*/
{
PCONNECTION_ENDPOINT Connection;
PTDI_REQUEST_KERNEL Parameters;
PTRANSPORT_CONTEXT TranContext;
PIO_STACK_LOCATION IrpSp;
NTSTATUS Status = STATUS_SUCCESS;
TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
IrpSp = IoGetCurrentIrpStackLocation(Irp);
/* Get associated connection endpoint file object. Quit if none exists */
TranContext = IrpSp->FileObject->FsContext;
if (TranContext == NULL)
{
TI_DbgPrint(MID_TRACE, ("Bad transport context.\n"));
return STATUS_INVALID_CONNECTION;
}
Connection = (PCONNECTION_ENDPOINT)TranContext->Handle.ConnectionContext;
if (Connection == NULL)
{
TI_DbgPrint(MID_TRACE, ("No connection endpoint file object.\n"));
return STATUS_INVALID_CONNECTION;
}
Parameters = (PTDI_REQUEST_KERNEL)&IrpSp->Parameters;
TI_DbgPrint(MIN_TRACE, ("Connection->AddressFile: %x\n",
Connection->AddressFile ));
if( Connection->AddressFile ) {
TI_DbgPrint(MIN_TRACE, ("Connection->AddressFile->Listener: %x\n",
Connection->AddressFile->Listener));
}
/* Listening will require us to create a listening socket and store it in
* the address file. It will be signalled, and attempt to complete an irp
* when a new connection arrives. */
/* The important thing to note here is that the irp we'll complete belongs
* to the socket to be accepted onto, not the listener */
if( !Connection->AddressFile->Listener ) {
Connection->AddressFile->Listener =
TCPAllocateConnectionEndpoint( NULL );
if( !Connection->AddressFile->Listener )
Status = STATUS_NO_MEMORY;
if( NT_SUCCESS(Status) ) {
Connection->AddressFile->Listener->AddressFile =
Connection->AddressFile;
Status = TCPSocket( Connection->AddressFile->Listener,
Connection->AddressFile->Family,
SOCK_STREAM,
Connection->AddressFile->Protocol );
}
if( NT_SUCCESS(Status) )
Status = TCPListen( Connection->AddressFile->Listener, 1024 );
/* BACKLOG */
}
if( NT_SUCCESS(Status) ) {
Status = DispPrepareIrpForCancel
(TranContext->Handle.ConnectionContext,
Irp,
(PDRIVER_CANCEL)DispCancelListenRequest);
}
if( NT_SUCCESS(Status) ) {
Status = TCPAccept
( (PTDI_REQUEST)Parameters,
Connection->AddressFile->Listener,
Connection,
DispDataRequestComplete,
Irp );
}
TI_DbgPrint(MID_TRACE,("Leaving %x\n", Status));
return Status;
}
NTSTATUS DispTdiQueryInformation(
PDEVICE_OBJECT DeviceObject,
PIRP Irp)
/*
* FUNCTION: TDI_QUERY_INFORMATION handler
* ARGUMENTS:
* DeviceObject = Pointer to device object structure
* Irp = Pointer to an I/O request packet
* RETURNS:
* Status of operation
*/
{
PTDI_REQUEST_KERNEL_QUERY_INFORMATION Parameters;
PTRANSPORT_CONTEXT TranContext;
PIO_STACK_LOCATION IrpSp;
TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
IrpSp = IoGetCurrentIrpStackLocation(Irp);
Parameters = (PTDI_REQUEST_KERNEL_QUERY_INFORMATION)&IrpSp->Parameters;
TranContext = IrpSp->FileObject->FsContext;
if (!TranContext) {
TI_DbgPrint(MID_TRACE, ("Bad transport context.\n"));
return STATUS_INVALID_CONNECTION;
}
switch (Parameters->QueryType)
{
case TDI_QUERY_ADDRESS_INFO:
{
PTDI_ADDRESS_INFO AddressInfo;
PADDRESS_FILE AddrFile;
PTA_IP_ADDRESS Address;
AddressInfo = (PTDI_ADDRESS_INFO)MmGetSystemAddressForMdl(Irp->MdlAddress);
switch ((ULONG)IrpSp->FileObject->FsContext2) {
case TDI_TRANSPORT_ADDRESS_FILE:
AddrFile = (PADDRESS_FILE)TranContext->Handle.AddressHandle;
break;
case TDI_CONNECTION_FILE:
AddrFile =
((PCONNECTION_ENDPOINT)TranContext->Handle.ConnectionContext)->
AddressFile;
break;
default:
TI_DbgPrint(MIN_TRACE, ("Invalid transport context\n"));
return STATUS_INVALID_PARAMETER;
}
if (!AddrFile) {
TI_DbgPrint(MID_TRACE, ("No address file object.\n"));
return STATUS_INVALID_PARAMETER;
}
if (MmGetMdlByteCount(Irp->MdlAddress) <
(FIELD_OFFSET(TDI_ADDRESS_INFO, Address.Address[0].Address) +
sizeof(TDI_ADDRESS_IP))) {
TI_DbgPrint(MID_TRACE, ("MDL buffer too small.\n"));
return STATUS_BUFFER_OVERFLOW;
}
Address = (PTA_IP_ADDRESS)&AddressInfo->Address;
Address->TAAddressCount = 1;
Address->Address[0].AddressLength = TDI_ADDRESS_LENGTH_IP;
Address->Address[0].AddressType = TDI_ADDRESS_TYPE_IP;
Address->Address[0].Address[0].sin_port = AddrFile->Port;
Address->Address[0].Address[0].in_addr =
AddrFile->Address.Address.IPv4Address;
RtlZeroMemory(
&Address->Address[0].Address[0].sin_zero,
sizeof(Address->Address[0].Address[0].sin_zero));
return STATUS_SUCCESS;
}
case TDI_QUERY_CONNECTION_INFO:
{
PTDI_CONNECTION_INFORMATION AddressInfo;
PADDRESS_FILE AddrFile;
PCONNECTION_ENDPOINT Endpoint = NULL;
AddressInfo = (PTDI_CONNECTION_INFORMATION)
MmGetSystemAddressForMdl(Irp->MdlAddress);
switch ((ULONG)IrpSp->FileObject->FsContext2) {
case TDI_TRANSPORT_ADDRESS_FILE:
AddrFile = (PADDRESS_FILE)TranContext->Handle.AddressHandle;
break;
case TDI_CONNECTION_FILE:
Endpoint =
(PCONNECTION_ENDPOINT)TranContext->Handle.ConnectionContext;
break;
default:
TI_DbgPrint(MIN_TRACE, ("Invalid transport context\n"));
return STATUS_INVALID_PARAMETER;
}
if (!Endpoint) {
TI_DbgPrint(MID_TRACE, ("No connection object.\n"));
return STATUS_INVALID_PARAMETER;
}
if (MmGetMdlByteCount(Irp->MdlAddress) <
(FIELD_OFFSET(TDI_CONNECTION_INFORMATION, RemoteAddress) +
sizeof(PVOID))) {
TI_DbgPrint(MID_TRACE, ("MDL buffer too small (ptr).\n"));
return STATUS_BUFFER_OVERFLOW;
}
return TCPGetPeerAddress( Endpoint, AddressInfo->RemoteAddress );
}
}
return STATUS_NOT_IMPLEMENTED;
}
NTSTATUS DispTdiReceive(
PIRP Irp)
/*
* FUNCTION: TDI_RECEIVE handler
* ARGUMENTS:
* Irp = Pointer to an I/O request packet
* RETURNS:
* Status of operation
*/
{
PIO_STACK_LOCATION IrpSp;
PTDI_REQUEST_KERNEL_RECEIVE ReceiveInfo;
PTRANSPORT_CONTEXT TranContext;
NTSTATUS Status;
ULONG BytesReceived;
TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
IrpSp = IoGetCurrentIrpStackLocation(Irp);
ReceiveInfo = (PTDI_REQUEST_KERNEL_RECEIVE)&(IrpSp->Parameters);
TranContext = IrpSp->FileObject->FsContext;
if (TranContext == NULL)
{
TI_DbgPrint(MID_TRACE, ("Bad transport context.\n"));
return STATUS_INVALID_CONNECTION;
}
if (TranContext->Handle.ConnectionContext == NULL)
{
TI_DbgPrint(MID_TRACE, ("No connection endpoint file object.\n"));
return STATUS_INVALID_CONNECTION;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?