IOCTL_TCP_QUERY_INFORMATION_EX IOCTL (tcpioctl.h)
[Este código de control puede modificarse o no estar disponible en versiones futuras de Windows. Use la API auxiliar de protocolo de Internet en lugar de este código de control.
Recupera información del controlador TCP/IP.
Para realizar la operación de
BOOL DeviceIoControl(
(HANDLE) hDevice, // Open handle to the TCP driver
IOCTL_TCP_QUERY_INFORMATION_EX, // dwIoControlCode
NULL, // lpInBuffer (the output buffer is used for input too)
0, // nInBufferSize
(LPVOID) lpOutBuffer, // Pointer to the output buffer
(DWORD) nOutBufferSize, // Size of the output buffer
(LPDWORD) lpBytesReturned, // Number of bytes returned (if called synchronously)
(LPOVERLAPPED) lpOverlapped // OVERLAPPED structure (if called asynchronously)
);
Observaciones
Para usar
Letras | Representar | Comentarios |
---|---|---|
"AT" | Traducción de direcciones | Resolución de direcciones, como la proporcionada por ARP (Protocolo de resolución de direcciones). |
"NL" | Capa de red | Como en el modelo de referencia de interconexión de sistemas abiertos (OSI). |
"TL" | Capa de transporte | Como en el modelo de referencia de OSI. |
"CL" | Connection-Less | Un protocolo sin conexión basado en paquetes de difusión. |
"CO" | Conexo | Un protocolo conectado basado en paquetes dirigidos. |
"ER" | Solicitud de eco/respuesta | Tipos de paquetes usados por Ping para probar la conectividad TCP/IP. |
"IF" | Interfaz | Interfaz en el sentido usado en SNMP. |
- Enumerar entidades TDI.
Para recuperar una matriz de TDIEntityID estructuras que identifican todas las entidades TCP del equipo, establezca el miembro ID.toi_entity.tei_entity de la estructura de entrada en GENERIC_ENTITY. ID.toi_class debe establecerse en INFO_CLASS_GENERIC, ID.toi_type debe establecerse en INFO_TYPE_PROVIDERy ID.toi_id debe establecerse en ENTITY_LIST_IDo se produce un error en la operación con un código de error TDI_INVALID_PARAMETER. El context miembro de la estructura de entrada se omite cuando se solicita una lista. El resultado en este caso es una matriz de estructuras de TDIEntityID. La función GetEntityArray en el primer ejemplo de código siguiente muestra cómo recuperar dicha matriz.
- Obtenga información de tipo sobre una entidad TDI específica.
Si el miembro
Los posibles valores de marca de tipo que se pueden devolver se muestran en la tabla siguiente.
Bandera | Importancia |
---|---|
AT_ARP | La entidad implementa ARP (Protocolo de resolución de direcciones). |
AT_NULL | La entidad no realiza ninguna traducción de direcciones. |
CL_NL_IP | La entidad implementa IP (Protocolo de Internet), sin conexión en la capa de red. |
CL_NL_IPX | La entidad implementa IPX (protocolo internetwork Packet Exchange), sin conexión en la capa de red. |
CL_TL_NBF | La entidad implementa NBF (protocolo NetBEUI Frame), sin conexión en la capa de transporte. |
CL_TL_UDP | La entidad implementa UDP (protocolo de datagramas de usuario) sin conexión en la capa de transporte. |
CO_TL_NBF | La entidad implementa NBF (protocolo NetBEUI Frame), paquetes dirigidos en la capa de transporte. |
CO_TL_SPP | La entidad implementa SPP (protocolo de paquetes secuenciados), paquetes dirigidos en la capa de transporte. |
CO_TL_SPX | La entidad implementa SPX (protocolo de intercambio de paquetes secuenciados), paquetes dirigidos en la capa de transporte. |
CO_TL_TCP | La entidad implementa TCP (Protocolo de control de transmisión), paquetes dirigidos en la capa de transporte. |
ER_ICMP | La entidad implementa ICMP (Protocolo de mensajes de control de Internet) para la solicitud de eco/respuesta. |
IF_GENERIC | La entidad implementa una interfaz genérica. |
IF_MIB | La entidad implementa una interfaz con compatibilidad con SNMP MIB-II. |
- Obtenga MIB-II información sobre una entidad de interfaz.
Si el tipo de entidad es IF_MIB, se puede enviar una solicitud MIB a ella que da como resultado la devolución de una estructura de IFEntry. Establezca el miembro ID.toi_entity de la estructura de entrada para identificar la entidad, el ID.toi_class en INFO_CLASS_PROTOCOL, el ID.toi_type en INFO_TYPE_PROVIDERy el ID.toi_id en IF_MIB_STATS_ID.
Tenga en cuenta que, dado que IFEntry es una estructura de longitud variable, el búfer de salida debe asignarse no solo como "sizeof(IFEntry)", sino como "sizeof(IFEntry) + MAX_ADAPTER_DESCRIPTION_LENGTH + 1".
- Obtenga MIB-II información sobre una entidad IP determinada.
La información de MIB también se puede recuperar de una entidad IP (uno cuyo tipo es CL_NL_ENTITY) estableciendo el miembro ID.toi_entity para identificar la entidad, el ID.toi_class en INFO_CLASS_PROTOCOL, el ID.toi_type en INFO_TYPE_PROVIDERy el ID.toi_id en IP_MIB_STATS_ID. En este caso, se devuelve una estructura de IPSNMPInfo y el búfer de salida se puede asignar a "sizeof(IPSNMPInfo)".
- Obtenga información de dirección sobre una entidad IP determinada.
Si el miembro ipsi_numaddr de la estructura de IPSNMPInfo devuelta para una entidad IP determinada es distinto de cero, se puede recuperar una matriz de estructuras IPAddrEntry estableciendo el miembro ID.toi_entity para identificar la entidad, el ID.toi_class en INFO_CLASS_PROTOCOL, el ID.toi_type en INFO_TYPE_PROVIDER, y el ID.toi_id para IP_MIB_ADDRTABLE_ENTRY_ID. En este caso, el búfer de salida debe asignarse para contener una matriz de tamaño:
sizeof(IPAddrEntry) * pIpSnmpInfoReturned->ipsi_numaddr
- Obtenga información de interfaz sobre una dirección IP determinada.
Se puede recuperar más información de interfaz para una dirección IP determinada devuelta en la matriz de IPAddrEntry anterior dejando el miembro de ID.toi_entity establecido para identificar la entidad IP, el ID.toi_class establecido en INFO_CLASS_PROTOCOLy el ID.toi_type establecido en INFO_TYPE_PROVIDER, y, después, establezca el ID.toi_id en IP_INTFC_INFO_ID y el miembro Context de la estructura de TCP_REQUEST_QUERY_INFORMATION_EX en la dirección IPv4 o IPv6 en cuestión.
Asigne un búfer de salida lo suficientemente grande como para contener sizeof(IPINTERFACEINFO) + MAX_PHYSADDR_SIZE
.
A cambio, el búfer de salida contiene una estructura IPInterfaceInfo rellenada.
Ejemplos
En el ejemplo siguiente se muestra cómo obtener una lista de las entidades presentes en el adaptador TCP en la máquina actual.
#define UNICODE
#define _WIN32_WINNT 0x0500
#include <stdio.h>
#include <windows.h>
#include <iptypes.h>
#include "winternl.h"
#include "tdiinfo.h"
#include "tdistat.h"
#include "tcpioctl.h"
/* Function: GetTCPHandle
Description:
Opens a handle to the TCP driver
Parameters:
pTCPDriverHandle -- Pointer to a handle variable.
Return Value (DWORD): Returns TRUE if successful, and places
a valid handle to the TCP driver in the
handle pointed to by pTCPDriverHandle, or
returns FALSE otherwise, and sets the
handle to INVALID_HANDLE_VALUE.
*/
DWORD GetTCPHandle( PHANDLE pTCPDriverHandle )
{
#define FILE_OPEN_IF 0x00000003
#define FILE_SYNCHRONOUS_IO_NONALERT 0x00000020
#define OBJ_CASE_INSENSITIVE 0x00000040L
typedef NTSTATUS (NTAPI *P_NT_CREATE_FILE)(
OUT PHANDLE FileHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes,
OUT PIO_STATUS_BLOCK IoStatusBlock,
IN PLARGE_INTEGER AllocationSize OPTIONAL,
IN ULONG FileAttributes,
IN ULONG ShareAccess,
IN ULONG CreateDisposition,
IN ULONG CreateOptions,
IN PVOID EaBuffer OPTIONAL,
IN ULONG EaLength );
HINSTANCE hNtDLL;
P_NT_CREATE_FILE pNtCreateFile;
NTSTATUS rVal;
WCHAR TCPDriverName[] = DD_TCP_DEVICE_NAME;
OBJECT_ATTRIBUTES objectAttributes;
IO_STATUS_BLOCK ioStatusBlock;
UNICODE_STRING UnicodeStr;
*pTCPDriverHandle = INVALID_HANDLE_VALUE;
if( ( hNtDLL = LoadLibrary( L"ntdll" ) ) == NULL )
return( FALSE );
pNtCreateFile = (P_NT_CREATE_FILE) GetProcAddress( hNtDLL,
"NtCreateFile" );
if( pNtCreateFile == NULL )
return( FALSE );
UnicodeStr.Buffer = TCPDriverName;
UnicodeStr.Length = (USHORT)(wcslen(TCPDriverName) * sizeof(WCHAR));
UnicodeStr.MaximumLength = UnicodeStr.Length + sizeof(UNICODE_NULL);
objectAttributes.Length = sizeof( OBJECT_ATTRIBUTES );
objectAttributes.ObjectName = &UnicodeStr;
objectAttributes.Attributes = OBJ_CASE_INSENSITIVE;
objectAttributes.RootDirectory = NULL;
objectAttributes.SecurityDescriptor = NULL;
objectAttributes.SecurityQualityOfService = NULL;
rVal = pNtCreateFile( pTCPDriverHandle,
SYNCHRONIZE | GENERIC_EXECUTE,
&objectAttributes,
&ioStatusBlock,
NULL,
FILE_ATTRIBUTE_NORMAL,
FILE_SHARE_READ | FILE_SHARE_WRITE,
FILE_OPEN_IF,
FILE_SYNCHRONOUS_IO_NONALERT,
NULL,
0 );
if( rVal < 0 )
{
printf( "\nFailed to create TCP Driver handle; NT status code = %d.", rVal );
*pTCPDriverHandle = INVALID_HANDLE_VALUE;
return( FALSE );
}
return( TRUE );
}
/* Function: GetEntityList
Description:
Allocates a buffer for and retrieves an array of TDIEntityID
structures that identifies the entities supported by
the TCP/IP device driver.
Parameters:
TCPDriverHandle -- An open handle to the TCP Driver; if
no such handle is available,
may be INVALID_HANDLE_VALUE.
lplpEntities -- Pointer to a buffer that contains
the array of TDIEntityID structures.
Must be freed by the calling process
using LocalFree( ).
Return Value:
DWORD -- the number of entity structures in the returned array
*/
DWORD GetEntityArray( IN HANDLE TCPDriverHandle,
OUT TDIEntityID **lplpEntities )
{
TCP_REQUEST_QUERY_INFORMATION_EX req;
DWORD arrayLen = sizeof(TDIEntityID) * MAX_TDI_ENTITIES;
DWORD bufferLen = arrayLen;
TDIEntityID * pEntity = NULL;
NTSTATUS status = TDI_SUCCESS;
DWORD temporaryHandle = 0;
int i;
// First, if the handle passed in is not valid, try to obtain one.
if( TCPDriverHandle == INVALID_HANDLE_VALUE )
{
if( GetTCPHandle( &TCPDriverHandle ) == FALSE )
{
*lplpEntities = NULL;
return( 0 );
}
temporaryHandle = TRUE;
}
// Next, set up the input structure for the IOCTL operation.
req.ID.toi_entity.tei_entity = GENERIC_ENTITY;
req.ID.toi_entity.tei_instance = 0;
req.ID.toi_class = INFO_CLASS_GENERIC;
req.ID.toi_type = INFO_TYPE_PROVIDER;
req.ID.toi_id = ENTITY_LIST_ID;
// The loop below is defensively engineered:
// (1) In the first place, it is unlikely that more
// than MAX_TDI_ENTITIES of TCP/IP entities exist,
// so the loop should execute only once.
// (2) Execution is limited to 4 iterations to rule out
// infinite looping in case of parameter corruption. Only 2
// iterations should ever be necessary unless entities are
// being added while the loop is running.
for( i = 0; i < 4; ++i )
{
if( pEntity != NULL )
{
LocalFree( pEntity );
pEntity = NULL;
bufferLen = arrayLen;
}
if( arrayLen == 0 )
break;
pEntity = (TDIEntityID *) LocalAlloc( LMEM_FIXED, bufferLen );
if( pEntity == NULL )
{
arrayLen = 0;
break;
}
if( !DeviceIoControl( TCPDriverHandle, // Handle to TCP driver
IOCTL_TCP_QUERY_INFORMATION_EX, // Cmd code
&req, // Pointer to input buffer
sizeof(req), // Size of ipt buffer
pEntity, // Ptr to output buffer
bufferLen, // Size of output buffer
&arrayLen, // Actual size of array
NULL ) )
status = GetLastError( );
// Even if the output buffer is too small, the TCP driver
// returns a status of TDI_SUCCESS; it is the value returned in
// arrayLen that indicates whether the entire array was
// successfully copied to the output buffer.
if( status == TDI_SUCCESS )
{
if( arrayLen && ( arrayLen <= bufferLen ) )
break;
}
else
arrayLen = 0;
}
if( temporaryHandle )
CloseHandle( TCPDriverHandle );
*lplpEntities = pEntity;
return( (DWORD)( arrayLen / sizeof(TDIEntityID) ) );
}
int main( )
{
DWORD i;
DWORD entityCount;
TDIEntityID
*entityArray,
*entityPtr;
if( !( entityCount = GetEntityArray( INVALID_HANDLE_VALUE,
&entityArray ) ) )
return( 1 );
entityPtr = entityArray;
printf( "\n\nList of %d Transport Driver Interface Entities on this machine:\n", entityCount );
for( i = 0; i < entityCount; ++i )
{
printf( "\n Entity #%d:\n Category (tei_entity) is ", i );
switch( entityPtr->tei_entity )
{
case GENERIC_ENTITY:
printf( "Generic." );
break;
case CL_NL_ENTITY:
printf( "Connectionless Network-Layer (CL_NL)" );
break;
case CO_NL_ENTITY:
printf( "Connected Network-Layer (CO_NL)" );
break;
case CL_TL_ENTITY:
printf( "Connectionless Transport-Layer (CL_TL)" );
break;
case CO_TL_ENTITY:
printf( "Connected Transport-Layer (CO_TL)" );
break;
case AT_ENTITY:
printf( "Address Translation (AT)" );
break;
case IF_ENTITY:
printf( "Interface (IF)" );
break;
case ER_ENTITY:
printf( "Echo Request/Response (ER)" );
break;
default:
printf( "[Unidentified Entity Type] = 0x%x",
entityPtr->tei_entity );
}
printf( "\n Instance (tei_instance) = %d\n",
entityPtr->tei_instance );
++entityPtr;
}
// Free the entity-array buffer before quitting.
LocalFree( entityArray );
return( 0 );
}
Requisitos
Requisito | Valor |
---|---|
encabezado de |
tcpioctl.h |
Consulte también
api auxiliar de protocolo de Internet de