dispatch.c
来自「一个类似windows」· C语言 代码 · 共 1,568 行 · 第 1/4 页
C
1,568 行
(PTDI_IND_CHAINED_RECEIVE_EXPEDITED)Parameters->EventHandler;
AddrFile->ChainedReceiveExpeditedHandlerContext = Parameters->EventContext;
AddrFile->RegisteredChainedReceiveExpeditedHandler = TRUE;
}
break;
default:
TI_DbgPrint(MIN_TRACE, ("Unknown event type (0x%X).\n",
Parameters->EventType));
Status = STATUS_INVALID_PARAMETER;
}
TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql);
return Status;
}
NTSTATUS DispTdiSetInformation(
PIRP Irp)
/*
* FUNCTION: TDI_SET_INFORMATION handler
* ARGUMENTS:
* Irp = Pointer to an I/O request packet
* RETURNS:
* Status of operation
*/
{
TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
return STATUS_NOT_IMPLEMENTED;
}
VOID DispTdiQueryInformationExComplete(
PVOID Context,
ULONG Status,
UINT ByteCount)
/*
* FUNCTION: Completes a TDI QueryInformationEx request
* ARGUMENTS:
* Context = Pointer to the IRP for the request
* Status = TDI status of the request
* ByteCount = Number of bytes returned in output buffer
*/
{
PTI_QUERY_CONTEXT QueryContext;
UINT Count = 0;
QueryContext = (PTI_QUERY_CONTEXT)Context;
if (NT_SUCCESS(Status)) {
Count = CopyBufferToBufferChain(
QueryContext->InputMdl,
FIELD_OFFSET(TCP_REQUEST_QUERY_INFORMATION_EX, Context),
(PCHAR)&QueryContext->QueryInfo.Context,
CONTEXT_SIZE);
}
MmUnlockPages(QueryContext->InputMdl);
IoFreeMdl(QueryContext->InputMdl);
if( QueryContext->OutputMdl ) {
MmUnlockPages(QueryContext->OutputMdl);
IoFreeMdl(QueryContext->OutputMdl);
}
QueryContext->Irp->IoStatus.Information = ByteCount;
QueryContext->Irp->IoStatus.Status = Status;
ExFreePool(QueryContext);
}
NTSTATUS DispTdiQueryInformationEx(
PIRP Irp,
PIO_STACK_LOCATION IrpSp)
/*
* FUNCTION: TDI QueryInformationEx handler
* ARGUMENTS:
* Irp = Pointer to I/O request packet
* IrpSp = Pointer to current stack location of Irp
* RETURNS:
* Status of operation
*/
{
PTCP_REQUEST_QUERY_INFORMATION_EX InputBuffer;
PTRANSPORT_CONTEXT TranContext;
PTI_QUERY_CONTEXT QueryContext;
PVOID OutputBuffer;
TDI_REQUEST Request;
UINT Size;
UINT InputBufferLength;
UINT OutputBufferLength;
BOOLEAN InputMdlLocked = FALSE;
BOOLEAN OutputMdlLocked = FALSE;
PMDL InputMdl = NULL;
PMDL OutputMdl = NULL;
NTSTATUS Status = STATUS_SUCCESS;
TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
TranContext = (PTRANSPORT_CONTEXT)IrpSp->FileObject->FsContext;
switch ((ULONG)IrpSp->FileObject->FsContext2) {
case TDI_TRANSPORT_ADDRESS_FILE:
Request.Handle.AddressHandle = TranContext->Handle.AddressHandle;
break;
case TDI_CONNECTION_FILE:
Request.Handle.ConnectionContext = TranContext->Handle.ConnectionContext;
break;
case TDI_CONTROL_CHANNEL_FILE:
Request.Handle.ControlChannel = TranContext->Handle.ControlChannel;
break;
default:
TI_DbgPrint(MIN_TRACE, ("Invalid transport context\n"));
return STATUS_INVALID_PARAMETER;
}
InputBufferLength = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
OutputBufferLength = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
/* Validate parameters */
if ((InputBufferLength == sizeof(TCP_REQUEST_QUERY_INFORMATION_EX)) &&
(OutputBufferLength != 0)) {
InputBuffer = (PTCP_REQUEST_QUERY_INFORMATION_EX)
IrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
OutputBuffer = Irp->UserBuffer;
QueryContext = ExAllocatePool(NonPagedPool, sizeof(TI_QUERY_CONTEXT));
if (QueryContext) {
_SEH_TRY {
InputMdl = IoAllocateMdl(InputBuffer,
sizeof(TCP_REQUEST_QUERY_INFORMATION_EX),
FALSE, TRUE, NULL);
OutputMdl = IoAllocateMdl(OutputBuffer,
OutputBufferLength, FALSE, TRUE, NULL);
if (InputMdl && OutputMdl) {
MmProbeAndLockPages(InputMdl, Irp->RequestorMode,
IoModifyAccess);
InputMdlLocked = TRUE;
MmProbeAndLockPages(OutputMdl, Irp->RequestorMode,
IoWriteAccess);
OutputMdlLocked = TRUE;
RtlCopyMemory(&QueryContext->QueryInfo,
InputBuffer, sizeof(TCP_REQUEST_QUERY_INFORMATION_EX));
} else
Status = STATUS_INSUFFICIENT_RESOURCES;
} _SEH_HANDLE {
Status = _SEH_GetExceptionCode();
} _SEH_END;
if (NT_SUCCESS(Status)) {
Size = MmGetMdlByteCount(OutputMdl);
QueryContext->Irp = Irp;
QueryContext->InputMdl = InputMdl;
QueryContext->OutputMdl = OutputMdl;
Request.RequestNotifyObject = DispTdiQueryInformationExComplete;
Request.RequestContext = QueryContext;
Status = InfoTdiQueryInformationEx(&Request,
&QueryContext->QueryInfo.ID, OutputMdl,
&Size, &QueryContext->QueryInfo.Context);
DispTdiQueryInformationExComplete(QueryContext, Status, Size);
TI_DbgPrint(MAX_TRACE, ("Leaving. Status = (0x%X)\n", Status));
return Status;
}
/* An error occurred if we get here */
if (InputMdl) {
if (InputMdlLocked)
MmUnlockPages(InputMdl);
IoFreeMdl(InputMdl);
}
if (OutputMdl) {
if (OutputMdlLocked)
MmUnlockPages(OutputMdl);
IoFreeMdl(OutputMdl);
}
ExFreePool(QueryContext);
} else
Status = STATUS_INSUFFICIENT_RESOURCES;
} else if( InputBufferLength ==
sizeof(TCP_REQUEST_QUERY_INFORMATION_EX) ) {
/* Handle the case where the user is probing the buffer for length */
TI_DbgPrint(MAX_TRACE, ("InputBufferLength %d OutputBufferLength %d\n",
InputBufferLength, OutputBufferLength));
InputBuffer = (PTCP_REQUEST_QUERY_INFORMATION_EX)
IrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
Size = 0;
QueryContext = ExAllocatePool(NonPagedPool, sizeof(TI_QUERY_CONTEXT));
if (!QueryContext) return STATUS_INSUFFICIENT_RESOURCES;
_SEH_TRY {
InputMdl = IoAllocateMdl(InputBuffer,
sizeof(TCP_REQUEST_QUERY_INFORMATION_EX),
FALSE, TRUE, NULL);
MmProbeAndLockPages(InputMdl, Irp->RequestorMode,
IoModifyAccess);
InputMdlLocked = TRUE;
Status = STATUS_SUCCESS;
} _SEH_HANDLE {
TI_DbgPrint(MAX_TRACE, ("Failed to acquire client buffer\n"));
Status = _SEH_GetExceptionCode();
} _SEH_END;
if( !NT_SUCCESS(Status) || !InputMdl ) {
if( InputMdl ) IoFreeMdl( InputMdl );
ExFreePool(QueryContext);
return Status;
}
RtlCopyMemory(&QueryContext->QueryInfo,
InputBuffer, sizeof(TCP_REQUEST_QUERY_INFORMATION_EX));
QueryContext->Irp = Irp;
QueryContext->InputMdl = InputMdl;
QueryContext->OutputMdl = NULL;
Request.RequestNotifyObject = DispTdiQueryInformationExComplete;
Request.RequestContext = QueryContext;
Status = InfoTdiQueryInformationEx(&Request,
&QueryContext->QueryInfo.ID,
NULL,
&Size,
&QueryContext->QueryInfo.Context);
DispTdiQueryInformationExComplete(QueryContext, Status, Size);
TI_DbgPrint(MAX_TRACE, ("Leaving. Status = (0x%X)\n", Status));
} else Status = STATUS_INVALID_PARAMETER;
TI_DbgPrint(MIN_TRACE, ("Leaving. Status = (0x%X)\n", Status));
return Status;
}
NTSTATUS DispTdiSetInformationEx(
PIRP Irp,
PIO_STACK_LOCATION IrpSp)
/*
* FUNCTION: TDI SetInformationEx handler
* ARGUMENTS:
* Irp = Pointer to I/O request packet
* IrpSp = Pointer to current stack location of Irp
* RETURNS:
* Status of operation
*/
{
PTRANSPORT_CONTEXT TranContext;
PTCP_REQUEST_SET_INFORMATION_EX Info;
TDI_REQUEST Request;
TDI_STATUS Status;
KIRQL OldIrql;
TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
TranContext = (PTRANSPORT_CONTEXT)IrpSp->FileObject->FsContext;
Info = (PTCP_REQUEST_SET_INFORMATION_EX)Irp->AssociatedIrp.SystemBuffer;
switch ((ULONG)IrpSp->FileObject->FsContext2) {
case TDI_TRANSPORT_ADDRESS_FILE:
Request.Handle.AddressHandle = TranContext->Handle.AddressHandle;
break;
case TDI_CONNECTION_FILE:
Request.Handle.ConnectionContext = TranContext->Handle.ConnectionContext;
break;
case TDI_CONTROL_CHANNEL_FILE:
Request.Handle.ControlChannel = TranContext->Handle.ControlChannel;
break;
default:
Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
Irp->IoStatus.Information = 0;
TI_DbgPrint(DEBUG_IRP, ("Completing IRP at (0x%X).\n", Irp));
return IRPFinish(Irp, STATUS_INVALID_PARAMETER);
}
Status = DispPrepareIrpForCancel(TranContext, Irp, NULL);
if (NT_SUCCESS(Status)) {
Request.RequestNotifyObject = DispDataRequestComplete;
Request.RequestContext = Irp;
Status = InfoTdiSetInformationEx(&Request, &Info->ID,
&Info->Buffer, Info->BufferSize);
if (Status != STATUS_PENDING) {
IoAcquireCancelSpinLock(&OldIrql);
(void)IoSetCancelRoutine(Irp, NULL);
IoReleaseCancelSpinLock(OldIrql);
}
}
return Status;
}
/* TODO: Support multiple addresses per interface.
* For now just set the nte context to the interface index.
*
* Later on, create an NTE context and NTE instance
*/
NTSTATUS DispTdiSetIPAddress( PIRP Irp, PIO_STACK_LOCATION IrpSp ) {
NTSTATUS Status = STATUS_DEVICE_DOES_NOT_EXIST;
PIP_SET_ADDRESS IpAddrChange =
(PIP_SET_ADDRESS)Irp->AssociatedIrp.SystemBuffer;
IF_LIST_ITER(IF);
TI_DbgPrint(MID_TRACE,("Setting IP Address for adapter %d\n",
IpAddrChange->NteIndex));
ForEachInterface(IF) {
TI_DbgPrint(MID_TRACE,("Looking at adapter %d\n", IF->Index));
if( IF->Unicast.Address.IPv4Address == IpAddrChange->Address ) {
Status = STATUS_DUPLICATE_OBJECTID;
break;
}
if( IF->Index == IpAddrChange->NteIndex ) {
IPRemoveInterfaceRoute( IF );
IF->Unicast.Type = IP_ADDRESS_V4;
IF->Unicast.Address.IPv4Address = IpAddrChange->Address;
IF->Netmask.Type = IP_ADDRESS_V4;
IF->Netmask.Address.IPv4Address = IpAddrChange->Netmask;
IF->Broadcast.Address.IPv4Address =
IF->Unicast.Address.IPv4Address |
~IF->Netmask.Address.IPv4Address;
TI_DbgPrint(MID_TRACE,("New Unicast Address: %x\n",
IF->Unicast.Address.IPv4Address));
TI_DbgPrint(MID_TRACE,("New Netmask : %x\n",
IF->Netmask.Address.IPv4Address));
IPAddInterfaceRoute( IF );
IpAddrChange->Address = IF->Index;
Status = STATUS_SUCCESS;
Irp->IoStatus.Information = IF->Index;
break;
}
} EndFor(IF);
Irp->IoStatus.Status = Status;
return Status;
}
NTSTATUS DispTdiDeleteIPAddress( PIRP Irp, PIO_STACK_LOCATION IrpSp ) {
NTSTATUS Status = STATUS_UNSUCCESSFUL;
PUSHORT NteIndex = Irp->AssociatedIrp.SystemBuffer;
IF_LIST_ITER(IF);
ForEachInterface(IF) {
if( IF->Index == *NteIndex ) {
IPRemoveInterfaceRoute( IF );
IF->Unicast.Type = IP_ADDRESS_V4;
IF->Unicast.Address.IPv4Address = 0;
IF->Netmask.Type = IP_ADDRESS_V4;
IF->Netmask.Address.IPv4Address = 0;
Status = STATUS_SUCCESS;
}
} EndFor(IF);
Irp->IoStatus.Status = Status;
return Status;
}
/* EOF */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?