📄 tdi.c
字号:
* Status of operation
* May return STATUS_PENDING
*/
{
PDEVICE_OBJECT DeviceObject;
NTSTATUS Status;
AFD_DbgPrint(MAX_TRACE, ("Called\n"));
DeviceObject = IoGetRelatedDeviceObject(ConnectionObject);
Status = TdiBuildNullConnectionInfo(RequestConnectionInfo,
TDI_ADDRESS_TYPE_IP);
if (!NT_SUCCESS(Status))
return Status;
*Irp = TdiBuildInternalDeviceControlIrp(TDI_LISTEN, /* Sub function */
DeviceObject, /* Device object */
ConnectionObject, /* File object */
NULL, /* Event */
Iosb); /* Status */
if (*Irp == NULL)
{
ExFreePool(*RequestConnectionInfo);
return STATUS_INSUFFICIENT_RESOURCES;
}
TdiBuildListen(*Irp, /* IRP */
DeviceObject, /* Device object */
ConnectionObject, /* File object */
CompletionRoutine, /* Completion routine */
CompletionContext, /* Completion routine context */
0, /* Flags */
*RequestConnectionInfo, /* Request connection information */
*ReturnConnectionInfo); /* Return connection information */
Status = TdiCall(*Irp, DeviceObject, NULL /* Don't wait for completion */, Iosb);
return Status;
}
NTSTATUS TdiSetEventHandler(
PFILE_OBJECT FileObject,
LONG EventType,
PVOID Handler,
PVOID Context)
/*
* FUNCTION: Sets or resets an event handler
* ARGUMENTS:
* FileObject = Pointer to file object
* EventType = Event code
* Handler = Event handler to be called when the event occurs
* Context = Context input to handler when the event occurs
* RETURNS:
* Status of operation
* NOTES:
* Specify NULL for Handler to stop calling event handler
*/
{
PDEVICE_OBJECT DeviceObject;
IO_STATUS_BLOCK Iosb;
NTSTATUS Status;
KEVENT Event;
PIRP Irp;
AFD_DbgPrint(MAX_TRACE, ("Called\n"));
assert(FileObject);
DeviceObject = IoGetRelatedDeviceObject(FileObject);
KeInitializeEvent(&Event, NotificationEvent, FALSE);
Irp = TdiBuildInternalDeviceControlIrp(TDI_SET_EVENT_HANDLER, /* Sub function */
DeviceObject, /* Device object */
FileObject, /* File object */
&Event, /* Event */
&Iosb); /* Status */
if (!Irp)
return STATUS_INSUFFICIENT_RESOURCES;
TdiBuildSetEventHandler(Irp,
DeviceObject,
FileObject,
NULL,
NULL,
EventType,
Handler,
Context);
Status = TdiCall(Irp, DeviceObject, &Event, &Iosb);
return Status;
}
NTSTATUS TdiQueryDeviceControl(
PFILE_OBJECT FileObject,
ULONG IoControlCode,
PVOID InputBuffer,
ULONG InputBufferLength,
PVOID OutputBuffer,
ULONG OutputBufferLength,
PULONG Return)
/*
* FUNCTION: Queries a device for information
* ARGUMENTS:
* FileObject = Pointer to file object
* IoControlCode = I/O control code
* InputBuffer = Pointer to buffer with input data
* InputBufferLength = Length of InputBuffer
* OutputBuffer = Address of buffer to place output data
* OutputBufferLength = Length of OutputBuffer
* RETURNS:
* Status of operation
*/
{
PDEVICE_OBJECT DeviceObject;
IO_STATUS_BLOCK Iosb;
NTSTATUS Status;
KEVENT Event;
PIRP Irp;
DeviceObject = IoGetRelatedDeviceObject(FileObject);
KeInitializeEvent(&Event, NotificationEvent, FALSE);
Irp = IoBuildDeviceIoControlRequest(IoControlCode,
DeviceObject,
InputBuffer,
InputBufferLength,
OutputBuffer,
OutputBufferLength,
FALSE,
&Event,
&Iosb);
if (!Irp)
return STATUS_INSUFFICIENT_RESOURCES;
Status = TdiCall(Irp, DeviceObject, &Event, &Iosb);
if (Return)
*Return = Iosb.Information;
return Status;
}
NTSTATUS TdiQueryInformation(
PFILE_OBJECT FileObject,
LONG QueryType,
PMDL MdlBuffer)
/*
* FUNCTION: Query for information
* ARGUMENTS:
* FileObject = Pointer to file object
* QueryType = Query type
* MdlBuffer = Pointer to MDL buffer specific for query type
* RETURNS:
* Status of operation
*/
{
PDEVICE_OBJECT DeviceObject;
IO_STATUS_BLOCK Iosb;
NTSTATUS Status;
KEVENT Event;
PIRP Irp;
DeviceObject = IoGetRelatedDeviceObject(FileObject);
KeInitializeEvent(&Event, NotificationEvent, FALSE);
Irp = TdiBuildInternalDeviceControlIrp(IOCTL_TCP_QUERY_INFORMATION, /* Sub function */
DeviceObject, /* Device object */
ConnectionObject, /* File object */
&Event, /* Event */
&Iosb); /* Status */
if (!Irp) {
return STATUS_INSUFFICIENT_RESOURCES;
}
TdiBuildQueryInformation(
Irp,
DeviceObject,
FileObject,
NULL,
NULL,
QueryType,
MdlBuffer);
Status = TdiCall(Irp, DeviceObject, &Event, &Iosb);
return Status;
}
#if 0
NTSTATUS TdiQueryInformationEx(
PFILE_OBJECT FileObject,
ULONG Entity,
ULONG Instance,
ULONG Class,
ULONG Type,
ULONG Id,
PVOID OutputBuffer,
PULONG OutputLength)
/*
* FUNCTION: Extended query for information
* ARGUMENTS:
* FileObject = Pointer to file object
* Entity = Entity
* Instance = Instance
* Class = Entity class
* Type = Entity type
* Id = Entity id
* OutputBuffer = Address of buffer to place data
* OutputLength = Address of buffer with length of OutputBuffer (updated)
* RETURNS:
* Status of operation
*/
{
TCP_REQUEST_QUERY_INFORMATION_EX QueryInfo;
RtlZeroMemory(&QueryInfo, sizeof(TCP_REQUEST_QUERY_INFORMATION_EX));
QueryInfo.ID.toi_entity.tei_entity = Entity;
QueryInfo.ID.toi_entity.tei_instance = Instance;
QueryInfo.ID.toi_class = Class;
QueryInfo.ID.toi_type = Type;
QueryInfo.ID.toi_id = Id;
return TdiQueryDeviceControl(FileObject, /* Transport/connection object */
IOCTL_TCP_QUERY_INFORMATION_EX, /* Control code */
&QueryInfo, /* Input buffer */
sizeof(TCP_REQUEST_QUERY_INFORMATION_EX), /* Input buffer length */
OutputBuffer, /* Output buffer */
*OutputLength, /* Output buffer length */
OutputLength); /* Return information */
}
NTSTATUS TdiQueryAddress(
PFILE_OBJECT FileObject,
PULONG Address)
/*
* FUNCTION: Queries for a local IP address
* ARGUMENTS:
* FileObject = Pointer to file object
* Address = Address of buffer to place local address
* RETURNS:
* Status of operation
*/
{
UINT i;
TDIEntityID *Entities;
ULONG EntityCount;
ULONG EntityType;
IPSNMP_INFO SnmpInfo;
PIPADDR_ENTRY IpAddress;
ULONG BufferSize;
NTSTATUS Status = STATUS_SUCCESS;
AFD_DbgPrint(MAX_TRACE, ("Called\n"));
BufferSize = sizeof(TDIEntityID) * 20;
Entities = (TDIEntityID*)ExAllocatePool(NonPagedPool, BufferSize);
if (!Entities) {
AFD_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
return STATUS_INSUFFICIENT_RESOURCES;
}
/* Query device for supported entities */
Status = TdiQueryInformationEx(FileObject, /* File object */
GENERIC_ENTITY, /* Entity */
TL_INSTANCE, /* Instance */
INFO_CLASS_GENERIC, /* Entity class */
INFO_TYPE_PROVIDER, /* Entity type */
ENTITY_LIST_ID, /* Entity id */
Entities, /* Output buffer */
&BufferSize); /* Output buffer size */
if (!NT_SUCCESS(Status)) {
AFD_DbgPrint(MIN_TRACE, ("Unable to get list of supported entities (Status = 0x%X).\n", Status));
ExFreePool(Entities);
return Status;
}
/* Locate an IP entity */
EntityCount = BufferSize / sizeof(TDIEntityID);
AFD_DbgPrint(MAX_TRACE, ("EntityCount = %d\n", EntityCount));
for (i = 0; i < EntityCount; i++) {
if (Entities[i].tei_entity == CL_NL_ENTITY) {
/* Query device for entity type */
BufferSize = sizeof(EntityType);
Status = TdiQueryInformationEx(FileObject, /* File object */
CL_NL_ENTITY, /* Entity */
Entities[i].tei_instance, /* Instance */
INFO_CLASS_GENERIC, /* Entity class */
INFO_TYPE_PROVIDER, /* Entity type */
ENTITY_TYPE_ID, /* Entity id */
&EntityType, /* Output buffer */
&BufferSize); /* Output buffer size */
if (!NT_SUCCESS(Status) || (EntityType != CL_NL_IP)) {
AFD_DbgPrint(MIN_TRACE, ("Unable to get entity of type IP (Status = 0x%X).\n", Status));
break;
}
/* Query device for SNMP information */
BufferSize = sizeof(SnmpInfo);
Status = TdiQueryInformationEx(FileObject, /* File object */
CL_NL_ENTITY, /* Entity */
Entities[i].tei_instance, /* Instance */
INFO_CLASS_PROTOCOL, /* Entity class */
INFO_TYPE_PROVIDER, /* Entity type */
IP_MIB_STATS_ID, /* Entity id */
&SnmpInfo, /* Output buffer */
&BufferSize); /* Output buffer size */
if (!NT_SUCCESS(Status) || (SnmpInfo.NumAddr == 0)) {
AFD_DbgPrint(MIN_TRACE, ("Unable to get SNMP information or no IP addresses available (Status = 0x%X).\n", Status));
break;
}
/* Query device for all IP addresses */
if (SnmpInfo.NumAddr != 0) {
BufferSize = SnmpInfo.NumAddr * sizeof(IPADDR_ENTRY);
IpAddress = (PIPADDR_ENTRY)ExAllocatePool(NonPagedPool, BufferSize);
if (!IpAddress) {
AFD_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
break;
}
Status = TdiQueryInformationEx(FileObject, /* File object */
CL_NL_ENTITY, /* Entity */
Entities[i].tei_instance, /* Instance */
INFO_CLASS_PROTOCOL, /* Entity class */
INFO_TYPE_PROVIDER, /* Entity type */
IP_MIB_ADDRTABLE_ENTRY_ID, /* Entity id */
IpAddress, /* Output buffer */
&BufferSize); /* Output buffer size */
if (!NT_SUCCESS(Status)) {
AFD_DbgPrint(MIN_TRACE, ("Unable to get IP address (Status = 0x%X).\n", Status));
ExFreePool(IpAddress);
break;
}
if (SnmpInfo.NumAddr != 1) {
/* Skip loopback address */
PIPADDR_ENTRY IpAddressEntry = (PIPADDR_ENTRY)
((PCHAR)IpAddress) + sizeof(IPADDR_ENTRY);
*Address = DN2H(IpAddressEntry->Addr);
} else {
/* Select the first address returned */
*Address = DN2H(IpAddress->Addr);
}
ExFreePool(IpAddress);
} else {
Status = STATUS_UNSUCCESSFUL;
break;
}
}
}
ExFreePool(Entities);
AFD_DbgPrint(MAX_TRACE, ("Leaving\n"));
return Status;
}
#endif
NTSTATUS TdiSend
( PIRP *Irp,
PFILE_OBJECT TransportObject,
USHORT Flags,
PCHAR Buffer,
UINT BufferLength,
PIO_STATUS_BLOCK Iosb,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -