IOCTL_TCP_QUERY_INFORMATION_EX IOCTL (tcpioctl.h)
[Dieser Steuerelementcode kann in zukünftigen Versionen von Windows geändert oder nicht verfügbar sein. Verwenden Sie die Internetprotokoll-Hilfs-API anstelle dieses Steuerelementcodes.]
Ruft Informationen vom TCP/IP-Treiber ab.
Rufen Sie zum Ausführen des IOCTL_TCP_QUERY_INFORMATION_EX Vorgangs die DeviceIoControl--Funktion mit den folgenden Parametern auf.
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)
);
Bemerkungen
Um IOCTL_TCP_QUERY_INFORMATION_EXzu verwenden, sollten Sie mit der Entwicklung von Windows-Treibern vertraut sein, wie im Windows Driver Kit (WDK)und speziell mit TDI-Treibern (Transport Driver Interface) dokumentiert.
Buchstaben | Stand für | Kommentare |
---|---|---|
"AT" | Adressenübersetzung | Adressauflösung, z. B. die von ARP (Address Resolution Protocol) bereitgestellt wird. |
"NL" | Vermittlungsschicht | Wie im Open Systems Interconnection (OSI)-Referenzmodell. |
"TL" | Transportschicht | Wie im OSI-Referenzmodell. |
"CL" | Connection-Less | Ein verbindungsloses Protokoll, das auf Übertragungspaketen basiert. |
"CO" | Verbunden | Ein verbundenes Protokoll basierend auf weitergeleiteten Paketen. |
"ER" | Echoanfrage/Antwort | Pakettypen, die von Ping zum Testen der TCP/IP-Konnektivität verwendet werden. |
"WENN" | Schnittstelle | Eine Schnittstelle im Sinne von SNMP. |
- Aufzählen von TDI-Entitäten.
Um ein Array von TDIEntityID Strukturen abzurufen, die alle TCP-Entitäten auf dem Computer identifiziert, legen Sie das ID.toi_entity.tei_entity Member der Eingabestruktur auf GENERIC_ENTITYfest. ID.toi_class muss dann auf INFO_CLASS_GENERICfestgelegt sein, ID.toi_type muss auf INFO_TYPE_PROVIDERfestgelegt sein, und ID.toi_id muss auf ENTITY_LIST_IDfestgelegt werden, oder der Vorgang schlägt mit einem TDI_INVALID_PARAMETER Fehlercode fehl. Das Kontextelement der Eingabestruktur wird ignoriert, wenn eine Liste angefordert wird. Die Ausgabe in diesem Fall ist ein Array TDIEntityID- Strukturen. Die GetEntityArray--Funktion im ersten Codebeispiel unten zeigt, wie ein solches Array abgerufen wird.
- Abrufen von Typinformationen zu einer bestimmten TDI-Entität.
Wenn das ID.toi_entity Element der Eingabestruktur eine bestimmte Entität identifiziert (wie im Fall der TDIEntityID Strukturen, die von der oben angegebenen Enumerationsanforderung zurückgegeben werden), wird die ID.toi_class auf INFO_CLASS_GENERICfestgelegt, die ID.toi_type auf INFO_TYPE_PROVIDER, und die ID.toi_id, um ENTITY_TYPE_ID bewirkt, dass mindestens ein Flagwert zu ENTITY_TYPE_ID wird in eine nicht signierte lange zurückgegeben, auf die der lpOutBuffer-Parameter verweist. Diese Flagwerte identifizieren den Typ der angegebenen Entität. Erneut wird das Context Member der Eingabestruktur ignoriert.
Die möglichen Typkennzeichnungswerte, die zurückgegeben werden können, sind in der folgenden Tabelle aufgeführt.
Flagge | Bedeutung |
---|---|
AT_ARP | Die Entität implementiert ARP (Address Resolution Protocol). |
AT_NULL | Die Entität führt keine Adressübersetzung durch. |
CL_NL_IP | Die Entität implementiert IP (Internet Protocol), ohne Verbindung auf der Netzwerkebene. |
CL_NL_IPX | Entität implementiert IPX (Internetwork Packet Exchange-Protokoll), ohne Verbindung auf der Netzwerkebene. |
CL_TL_NBF | Entität implementiert NBF (NetBEUI Frame-Protokoll), verbindungslos auf der Transportschicht. |
CL_TL_UDP | Die Entität implementiert UDP (User Datagram Protocol) ohne Verbindung auf der Transportebene. |
CO_TL_NBF | Entität implementiert NBF (NetBEUI Frame-Protokoll), gerichtete Pakete auf der Transportebene. |
CO_TL_SPP | Die Entität implementiert SPP (Sequenced Packet Protocol), gerichtete Pakete auf der Transportebene. |
CO_TL_SPX | Entität implementiert SPX (Sequenced Packet Exchange-Protokoll), gerichtete Pakete auf der Transportebene. |
CO_TL_TCP | Die Entität implementiert TCP (Transmission Control Protocol), gerichtete Pakete auf der Transportebene. |
ER_ICMP | Die Entität implementiert ICMP (Internet Control Message Protocol) für Echo-Anforderung/Antwort. |
IF_GENERIC | Die Entität implementiert eine generische Schnittstelle. |
IF_MIB | Die Entität implementiert eine Schnittstelle mit SNMP MIB-II Unterstützung. |
- Rufen Sie MIB-II Informationen zu einer Schnittstellenentität ab.
Wenn der Entitätstyp IF_MIB ist, kann eine MIB-Anforderung an sie gesendet werden, die zur Rückgabe einer IFEntry--Struktur führt. Legen Sie das ID.toi_entity Element der Eingabestruktur fest, um die Entität zu identifizieren, die ID.toi_class auf INFO_CLASS_PROTOCOL, die ID.toi_type auf INFO_TYPE_PROVIDERund die ID.toi_id auf IF_MIB_STATS_ID.
Beachten Sie, dass IFEntry- eine Struktur mit variabler Länge ist, sollte der Ausgabepuffer nicht nur als "sizeof(IFEntry)" sondern als "sizeof(IFEntry) + MAX_ADAPTER_DESCRIPTION_LENGTH + 1" zugewiesen werden.
- Rufen Sie MIB-II Informationen zu einer bestimmten IP-Entität ab.
MIB-Informationen können auch aus einer IP-Entität (einer, deren Typ CL_NL_ENTITYist) abgerufen werden, indem sie das ID.toi_entity Mitglied festlegen, um die Entität, die ID.toi_class zu INFO_CLASS_PROTOCOL, die ID.toi_type zu INFO_TYPE_PROVIDERund die ID.toi_id auf IP_MIB_STATS_IDfestzulegen. In diesem Fall wird eine IPSNMPInfo- Struktur zurückgegeben, und der Ausgabepuffer kann "sizeof(IPSNMPInfo)" zugeordnet werden.
- Abrufen von Adressinformationen zu einer bestimmten IP-Entität.
Wenn das ipsi_numaddr Element der IPSNMPInfo- Struktur, die für eine bestimmte IP-Entität zurückgegeben wird, ungleich Null ist, kann ein Array IPAddrEntry--Strukturen abgerufen werden, indem das ID.toi_entity-Element zum Identifizieren der Entität festgelegt wird, die ID.toi_class, die INFO_CLASS_PROTOCOL, die ID.toi_type auf INFO_TYPE_PROVIDER, und die ID.toi_id, um IP_MIB_ADDRTABLE_ENTRY_ID. In diesem Fall sollte der Ausgabepuffer zugewiesen werden, um ein Array von Größe zu enthalten:
sizeof(IPAddrEntry) * pIpSnmpInfoReturned->ipsi_numaddr
- Abrufen von Schnittstelleninformationen zu einer bestimmten IP-Adresse.
Weitere Schnittstelleninformationen können für eine bestimmte IP-Adresse abgerufen werden, die im IPAddrEntry Array oben zurückgegeben wird, indem sie den ID.toi_entity Membersatz verlassen, um die IP-Entität zu identifizieren, die ID.toi_class auf INFO_CLASS_PROTOCOLfestgelegt und die ID.toi_type auf INFO_TYPE_PROVIDERfestgelegt ist. und legen Sie dann die ID.toi_id auf IP_INTFC_INFO_ID und das Context Member der TCP_REQUEST_QUERY_INFORMATION_EX Struktur auf die betreffende IPv4- oder IPv6-Adresse fest.
Weisen Sie einen Ausgabepuffer groß genug zu, um sizeof(IPINTERFACEINFO) + MAX_PHYSADDR_SIZE
zu enthalten.
Beim Zurückgeben enthält der Ausgabepuffer eine ausgefüllte IPInterfaceInfo- Struktur.
Beispiele
Das folgende Beispiel zeigt, wie Sie eine Liste der Entitäten abrufen, die auf dem TCP-Adapter auf dem aktuellen Computer vorhanden sind.
#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 );
}
Anforderungen
Anforderung | Wert |
---|---|
Header- | tcpioctl.h |