ADDRINFOEX4
構造体サイズ=各フィールドのバイト数(x64/x86 で異なる場合は x64/x86 と併記)。x64/x86 列=フィールドのバイトオフセット(HSPで dupptr / lpoke / wpoke 等に使用)。
フィールド
| フィールド | 型 | サイズ | x64 | x86 | 説明 | ||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| ai_flags | INT | 4 | +0 | +0 | GetAddrInfoEx 関数で使用されるオプションを示すフラグです。 ai_flags メンバーでサポートされる値は Winsock2.h インクルードファイルで定義されており、次のオプションの組み合わせを指定できます。
| ||||||||||||||||||||||||||||||
| ai_family | INT | 4 | +4 | +4 | アドレスファミリーです。 アドレスファミリーに指定できる値は Ws2def.h ヘッダーファイルで定義されています。Ws2def.h ヘッダーファイルは Winsock2.h に自動的に含まれるため、直接使用しないでください。 現在サポートされている値は AF_INET または AF_INET6 で、これらは IPv4 および IPv6 のインターネットアドレスファミリー形式です。アドレスファミリーのその他の選択肢 (NetBIOS で使用する AF_NETBIOS など) は、そのアドレスファミリー用の Windows ソケットサービスプロバイダーがインストールされている場合にサポートされます。AF_ アドレスファミリー定数と PF_ プロトコルファミリー定数の値は同一である (たとえば AF_INET と PF_INET) ため、どちらの定数も使用できます。 次の表はアドレスファミリーの代表的な値を示しますが、他にも多くの値を指定できます。
| ||||||||||||||||||||||||||||||
| ai_socktype | INT | 4 | +8 | +8 | ソケットの種類です。ソケットの種類に指定できる値は Winsock2.h インクルードファイルで定義されています。 次の表は、Windows Sockets 2 でサポートされるソケットの種類の値を示します。
Windows Sockets 2 では、新しいソケットの種類が導入されました。アプリケーションは WSAEnumProtocols 関数を使用して、利用可能な各トランスポートプロトコルの属性を動的に調べることができます。そのため、アプリケーションはアドレスファミリーに対して指定できるソケットの種類とプロトコルのオプションを判別し、この情報をこのパラメーターの指定に利用できます。Winsock2.h および Ws2def.h ヘッダーファイル内のソケットの種類の定義は、新しいソケットの種類、アドレスファミリー、プロトコルが定義されるのに伴って随時更新されます。 Windows Sockets 1.1 では、指定できるソケットの種類は SOCK_DATAGRAM と SOCK_STREAM のみです。 | ||||||||||||||||||||||||||||||
| ai_protocol | INT | 4 | +12 | +12 | プロトコルの種類です。指定できるオプションは、指定したアドレスファミリーとソケットの種類に固有です。ai_protocol に指定できる値は Winsock2.h および Wsrm.h ヘッダーファイルで定義されています。 Windows Vista 以降向けにリリースされた Windows SDK ではヘッダーファイルの構成が変更されており、このメンバーには Ws2def.h ヘッダーファイルで定義されている IPPROTO 列挙型の値のいずれかを指定できます。Ws2def.h ヘッダーファイルは Winsock2.h に自動的に含まれるため、直接使用しないでください。 ai_protocol に 0 を指定した場合、呼び出し元はプロトコルを指定しないことを意味し、使用する ai_protocol はサービスプロバイダーが選択します。IPv4 および IPv6 以外のプロトコルでは、ai_protocol に 0 を設定してください。 次の表は ai_protocol メンバーの代表的な値を示しますが、他にも多くの値を指定できます。
ai_family メンバーが AF_IRDA の場合、ai_protocol は 0 でなければなりません。 | ||||||||||||||||||||||||||||||
| ai_addrlen | UINT_PTR | 8/4 | +16 | +16 | ai_addr メンバーが指すバッファーの長さ (バイト単位) です。 | ||||||||||||||||||||||||||||||
| ai_canonname | LPWSTR | 8/4 | +24 | +20 | ホストの正規名です。 | ||||||||||||||||||||||||||||||
| ai_addr | SOCKADDR* | 8/4 | +32 | +24 | sockaddr 構造体へのポインターです。返される各 addrinfoex4 構造体の ai_addr メンバーは、値が設定されたソケットアドレス構造体を指します。返される各 addrinfoex4 構造体の長さ (バイト単位) は ai_addrlen メンバーで指定されます。 | ||||||||||||||||||||||||||||||
| ai_blob | void* | 8/4 | +40 | +28 | アドレスの一覧以外に、名前に関連付けられたプロバイダー固有の名前空間情報を返すために使用されるデータへのポインターです。ai_blob が指すバッファーの長さ (バイト単位) は ai_bloblen メンバーで指定する必要があります。 | ||||||||||||||||||||||||||||||
| ai_bloblen | UINT_PTR | 8/4 | +48 | +32 | ai_blob メンバーの長さ (バイト単位) です。 | ||||||||||||||||||||||||||||||
| ai_provider | GUID* | 8/4 | +56 | +36 | 特定の名前空間プロバイダーの GUID へのポインターです。 | ||||||||||||||||||||||||||||||
| ai_next | ADDRINFOEX4* | 8/4 | +64 | +40 | リンクリスト内の次の構造体へのポインターです。このパラメーターは、リンクリストの最後の addrinfoex4 構造体では NULL に設定されます。 | ||||||||||||||||||||||||||||||
| ai_version | INT | 4 | +72 | +44 | この構造体のバージョン番号です。このバージョンの構造体で現在使用されている値は 4 です。 | ||||||||||||||||||||||||||||||
| ai_fqdn | LPWSTR | 8/4 | +80 | +48 | ホストの完全修飾ドメイン名です。 | ||||||||||||||||||||||||||||||
| ai_interfaceindex | INT | 4 | +88 | +52 | GetAdaptersAddresses で返される IP_ADAPTER_ADDRESSES.IfIndex プロパティで定義されるインターフェイスインデックスです。 | ||||||||||||||||||||||||||||||
| ai_resolutionhandle | HANDLE | 8/4 | +96 | +56 | ホストの完全修飾ドメイン名を指すハンドルです。 |
公式ドキュメント
addrinfoex4 構造体は、特定のネットワークインターフェイスが要求された場合に、ホストのアドレス情報を保持するために GetAddrInfoEx 関数によって使用されます。
解説(Remarks)
addrinfoex4 構造体は Windows 10 および Windows Server 2016 でサポートされます。
addrinfoex4 構造体は、GetAddrInfoEx の hints パラメーターで渡す addrinfoex4.ai_flags メンバーに AI_EXTENDED | AI_FQDN | AI_CANONNAME | AI_RESOLUTION_HANDLE の各ビットが設定されている場合に、ホストのアドレス情報を保持するために GetAddrInfoEx 関数によって使用されます。
addrinfoex4 構造体は addrinfoex 構造体を拡張したもので、正規名、ホストの完全修飾ドメイン名、および完全修飾ドメイン名へのハンドルを返すことができます。また GetAddrInfoEx は、getaddrinfo および GetAddrInfoW 関数で使用される addrinfo および addrinfoW 構造体を拡張したものです。GetAddrInfoEx 関数では、クエリを解決する名前空間プロバイダーを指定できます。IPv6 および IPv4 プロトコルで使用する場合、名前解決はドメインネームシステム (DNS)、ローカルの hosts ファイル、電子メールプロバイダー (NS_EMAIL 名前空間)、またはその他の名前付けの仕組みによって行われます。
ai_blob メンバーの blob データは、名前に関連付けられたプロバイダー固有の追加の名前空間情報を返すために使用されます。ai_blob メンバー内のデータ形式は、名前空間プロバイダーごとに固有です。現在、blob データは追加情報を提供するために NS_EMAIL 名前空間プロバイダーによって使用されています。
UNICODE または _UNICODE が定義されている場合、addrinfoex4 はこの構造体の Unicode 版である addrinfoex4W として定義されます。文字列パラメーターは PWSTR データ型として定義され、addrinfoex4W 構造体が使用されます。
UNICODE または _UNICODE が定義されていない場合、addrinfoex4 はこの構造体の ANSI 版である addrinfoex4A として定義されます。文字列パラメーターは char * データ型となり、addrinfoex4A 構造体が使用されます。
GetAddrInfoEx の呼び出しに成功すると、 addrinfoex4 構造体のリンクリストが、GetAddrInfoEx 関数に渡した ppResult パラメーターに返されます。このリストは、返された各 addrinfoex4 構造体の ai_next メンバーに設定されたポインターを NULL ポインターに達するまでたどることで処理できます。返される各 addrinfoex4 構造体の ai_family、ai_socktype、ai_protocol の各メンバーは、 socket 関数または WSASocket 関数の呼び出しにおける対応する引数に相当します。また、返される各 addrinfoex4 構造体の ai_addr メンバーは、値が設定されたソケットアドレス構造体を指し、その長さは同構造体の ai_addrlen メンバーで指定されます。
例
次のコードは、FQDN へのハンドルを取得するために addrinfoex4 構造体を指定して GetAddrInfoEx を呼び出す方法を示しています。続いて、このサンプルでは ASSOCIATE_NAMERES_CONTEXT_INPUT 構造体を指定して WSAIoctl を呼び出します。
//
// Connect to a server using its IPv4 addresses
//
VOID
ConnectServer(
PCWSTR server)
{
int iResult;
PADDRINFOEX4 pResult = NULL;
ADDRINFOEX3 hints = { 0 };
PADDRINFOEX4 pCur = NULL;
WSADATA wsaData;
SOCKET connectSocket = INVALID_SOCKET;
ULONG bytesReturned = 0;
ASSOCIATE_NAMERES_CONTEXT_INPUT input = { 0 };
SOCKADDR_IN clientService;
wchar_t ipstringbuffer[46];
String string;
DWORD dwRetval;
//
// Initialize Winsock
//
iResult = WSAStartup(
MAKEWORD(2, 2),
&wsaData);
if (iResult != 0) {
printf("WSAStartup failed: %d\n", iResult);
goto Exit;
}
//
// Create a SOCKET for connection
//
connectSocket = socket(
AF_UNSPEC,
SOCK_STREAM,
IPPROTO_TCP);
if (connectSocket == INVALID_SOCKET)
{
printf("socket failed: %d\n", WSAGetLastError());
goto Exit;
}
//
// Do name resolution
//
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_EXTENDED | AI_FQDN | AI_CANONNAME | AI_RESOLUTION_HANDLE;
hints.ai_version = ADDRINFOEX_VERSION_4;
dwRetval = GetAddrInfoExW(
server,
NULL,
NS_DNS,
NULL,
(const ADDRINFOEXW*)&hints,
(PADDRINFOEXW*)&pResult,
NULL,
NULL,
NULL, NULL);
if (dwRetval != 0) {
printf("GetAddrInfoEx failed with error: %d\n", dwRetval);
goto Exit;
}
input.TransportSettingId.Guid = ASSOCIATE_NAMERES_CONTEXT;
input.Handle = pResult->ai_resolutionhandle;
//
// Associate socket with the handle
//
if (WSAIoctl(
connectSocket,
SIO_APPLY_TRANSPORT_SETTING,
(VOID *)&input,
sizeof(input),
NULL,
0,
&bytesReturned,
NULL,
NULL) == SOCKET_ERROR)
if (iResult != 0){
printf("WSAIoctl failed: %d\n", WSAGetLastError());
goto Exit;
}
//
// Connect to server
//
pCur = pResult;
while (pCur != NULL)
{
if (pCur->ai_addr->sa_family == AF_INET)
{
clientService = *(const sockaddr_in*)pCur->ai_addr;
clientService.sin_port = htons(80);
if (connect(
connectSocket,
(const SOCKADDR *)&clientService,
sizeof(clientService)) == SOCKET_ERROR)
{
printf("connect failed: %d\n", WSAGetLastError());
goto Exit;
}
}
pCur = pCur->ai_next;
}
Exit:
if (connectSocket != INVALID_SOCKET)
{
closesocket(connectSocket);
}
if (pResult)
{
FreeAddrInfoExW((ADDRINFOEXW*)pResult);
}
WSACleanup();
return;
}
Microsoft 公式リファレンス: 英語 (en-us) · 日本語 (ja-jp) · 原文ソース (GitHub)
各言語での定義
#include <windows.h>
// ADDRINFOEX4 (x64 104 / x86 60 バイト)
typedef struct ADDRINFOEX4 {
INT ai_flags;
INT ai_family;
INT ai_socktype;
INT ai_protocol;
UINT_PTR ai_addrlen;
LPWSTR ai_canonname;
SOCKADDR* ai_addr;
void* ai_blob;
UINT_PTR ai_bloblen;
GUID* ai_provider;
ADDRINFOEX4* ai_next;
INT ai_version;
LPWSTR ai_fqdn;
INT ai_interfaceindex;
HANDLE ai_resolutionhandle;
} ADDRINFOEX4;using System;
using System.Runtime.InteropServices;
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct ADDRINFOEX4
{
public int ai_flags;
public int ai_family;
public int ai_socktype;
public int ai_protocol;
public UIntPtr ai_addrlen;
public IntPtr ai_canonname;
public IntPtr ai_addr;
public IntPtr ai_blob;
public UIntPtr ai_bloblen;
public IntPtr ai_provider;
public IntPtr ai_next;
public int ai_version;
public IntPtr ai_fqdn;
public int ai_interfaceindex;
public IntPtr ai_resolutionhandle;
}Imports System.Runtime.InteropServices
<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)>
Public Structure ADDRINFOEX4
Public ai_flags As Integer
Public ai_family As Integer
Public ai_socktype As Integer
Public ai_protocol As Integer
Public ai_addrlen As UIntPtr
Public ai_canonname As IntPtr
Public ai_addr As IntPtr
Public ai_blob As IntPtr
Public ai_bloblen As UIntPtr
Public ai_provider As IntPtr
Public ai_next As IntPtr
Public ai_version As Integer
Public ai_fqdn As IntPtr
Public ai_interfaceindex As Integer
Public ai_resolutionhandle As IntPtr
End Structureimport ctypes
from ctypes import wintypes
class ADDRINFOEX4(ctypes.Structure):
_fields_ = [
("ai_flags", ctypes.c_int),
("ai_family", ctypes.c_int),
("ai_socktype", ctypes.c_int),
("ai_protocol", ctypes.c_int),
("ai_addrlen", ctypes.c_size_t),
("ai_canonname", ctypes.c_void_p),
("ai_addr", ctypes.c_void_p),
("ai_blob", ctypes.c_void_p),
("ai_bloblen", ctypes.c_size_t),
("ai_provider", ctypes.c_void_p),
("ai_next", ctypes.c_void_p),
("ai_version", ctypes.c_int),
("ai_fqdn", ctypes.c_void_p),
("ai_interfaceindex", ctypes.c_int),
("ai_resolutionhandle", ctypes.c_void_p),
]#[repr(C)]
pub struct ADDRINFOEX4 {
pub ai_flags: i32,
pub ai_family: i32,
pub ai_socktype: i32,
pub ai_protocol: i32,
pub ai_addrlen: usize,
pub ai_canonname: *mut core::ffi::c_void,
pub ai_addr: *mut core::ffi::c_void,
pub ai_blob: *mut core::ffi::c_void,
pub ai_bloblen: usize,
pub ai_provider: *mut core::ffi::c_void,
pub ai_next: *mut core::ffi::c_void,
pub ai_version: i32,
pub ai_fqdn: *mut core::ffi::c_void,
pub ai_interfaceindex: i32,
pub ai_resolutionhandle: *mut core::ffi::c_void,
}import "golang.org/x/sys/windows"
type ADDRINFOEX4 struct {
ai_flags int32
ai_family int32
ai_socktype int32
ai_protocol int32
ai_addrlen uintptr
ai_canonname uintptr
ai_addr uintptr
ai_blob uintptr
ai_bloblen uintptr
ai_provider uintptr
ai_next uintptr
ai_version int32
ai_fqdn uintptr
ai_interfaceindex int32
ai_resolutionhandle uintptr
}type
ADDRINFOEX4 = record
ai_flags: Integer;
ai_family: Integer;
ai_socktype: Integer;
ai_protocol: Integer;
ai_addrlen: NativeUInt;
ai_canonname: Pointer;
ai_addr: Pointer;
ai_blob: Pointer;
ai_bloblen: NativeUInt;
ai_provider: Pointer;
ai_next: Pointer;
ai_version: Integer;
ai_fqdn: Pointer;
ai_interfaceindex: Integer;
ai_resolutionhandle: Pointer;
end;const ADDRINFOEX4 = extern struct {
ai_flags: i32,
ai_family: i32,
ai_socktype: i32,
ai_protocol: i32,
ai_addrlen: usize,
ai_canonname: ?*anyopaque,
ai_addr: ?*anyopaque,
ai_blob: ?*anyopaque,
ai_bloblen: usize,
ai_provider: ?*anyopaque,
ai_next: ?*anyopaque,
ai_version: i32,
ai_fqdn: ?*anyopaque,
ai_interfaceindex: i32,
ai_resolutionhandle: ?*anyopaque,
};type
ADDRINFOEX4 {.bycopy.} = object
ai_flags: int32
ai_family: int32
ai_socktype: int32
ai_protocol: int32
ai_addrlen: uint
ai_canonname: pointer
ai_addr: pointer
ai_blob: pointer
ai_bloblen: uint
ai_provider: pointer
ai_next: pointer
ai_version: int32
ai_fqdn: pointer
ai_interfaceindex: int32
ai_resolutionhandle: pointerstruct ADDRINFOEX4
{
int ai_flags;
int ai_family;
int ai_socktype;
int ai_protocol;
size_t ai_addrlen;
void* ai_canonname;
void* ai_addr;
void* ai_blob;
size_t ai_bloblen;
void* ai_provider;
void* ai_next;
int ai_version;
void* ai_fqdn;
int ai_interfaceindex;
void* ai_resolutionhandle;
}HSP用 定義
HSP3.7/3.8 は構造体機能が無いため4byte整数配列(dim)+peek/poke で操作(32/64bitでサイズ・位置が異なる場合はタブで分割)。IronHSP は NSTRUCT(#defstruct/stdim/->)で32/64bit共通。
; HSP3.7/3.8 は構造体機能が無いため、4byte整数の配列変数で操作します。(x86 レイアウト)
; ADDRINFOEX4 サイズ: 60 バイト(x86)
dim st, 15 ; 4byte整数×15(構造体サイズ 60 / 4 切り上げ)
; ai_flags : INT (+0, 4byte) st.0 = 値 / 値 = st.0 (lpoke/lpeek も可)
; ai_family : INT (+4, 4byte) st.1 = 値 / 値 = st.1 (lpoke/lpeek も可)
; ai_socktype : INT (+8, 4byte) st.2 = 値 / 値 = st.2 (lpoke/lpeek も可)
; ai_protocol : INT (+12, 4byte) st.3 = 値 / 値 = st.3 (lpoke/lpeek も可)
; ai_addrlen : UINT_PTR (+16, 4byte) st.4 = 値 / 値 = st.4 (lpoke/lpeek も可)
; ai_canonname : LPWSTR (+20, 4byte) st.5 = 値 / 値 = st.5 (lpoke/lpeek も可)
; ai_addr : SOCKADDR* (+24, 4byte) varptr(st)+24 を基点に操作(4byte:入れ子/配列)
; ai_blob : void* (+28, 4byte) st.7 = 値 / 値 = st.7 (lpoke/lpeek も可)
; ai_bloblen : UINT_PTR (+32, 4byte) st.8 = 値 / 値 = st.8 (lpoke/lpeek も可)
; ai_provider : GUID* (+36, 4byte) varptr(st)+36 を基点に操作(4byte:入れ子/配列)
; ai_next : ADDRINFOEX4* (+40, 4byte) varptr(st)+40 を基点に操作(4byte:入れ子/配列)
; ai_version : INT (+44, 4byte) st.11 = 値 / 値 = st.11 (lpoke/lpeek も可)
; ai_fqdn : LPWSTR (+48, 4byte) st.12 = 値 / 値 = st.12 (lpoke/lpeek も可)
; ai_interfaceindex : INT (+52, 4byte) st.13 = 値 / 値 = st.13 (lpoke/lpeek も可)
; ai_resolutionhandle : HANDLE (+56, 4byte) st.14 = 値 / 値 = st.14 (lpoke/lpeek も可)
; ※4byte境界の整数は添字 st.N(N=オフセット/4)で読み書き可。それ以外は peek/poke 系を使用。; HSP3.7/3.8 は構造体機能が無いため、4byte整数の配列変数で操作します。(x64 レイアウト)
; ADDRINFOEX4 サイズ: 104 バイト(x64)
dim st, 26 ; 4byte整数×26(構造体サイズ 104 / 4 切り上げ)
; ai_flags : INT (+0, 4byte) st.0 = 値 / 値 = st.0 (lpoke/lpeek も可)
; ai_family : INT (+4, 4byte) st.1 = 値 / 値 = st.1 (lpoke/lpeek も可)
; ai_socktype : INT (+8, 4byte) st.2 = 値 / 値 = st.2 (lpoke/lpeek も可)
; ai_protocol : INT (+12, 4byte) st.3 = 値 / 値 = st.3 (lpoke/lpeek も可)
; ai_addrlen : UINT_PTR (+16, 8byte) qpoke st,16,値 / qpeek(st,16) ※IronHSPのみ。3.7/3.8は lpoke st,16,下位 : lpoke st,20,上位
; ai_canonname : LPWSTR (+24, 8byte) qpoke st,24,値 / qpeek(st,24) ※IronHSPのみ。3.7/3.8は lpoke st,24,下位 : lpoke st,28,上位
; ai_addr : SOCKADDR* (+32, 8byte) varptr(st)+32 を基点に操作(8byte:入れ子/配列)
; ai_blob : void* (+40, 8byte) qpoke st,40,値 / qpeek(st,40) ※IronHSPのみ。3.7/3.8は lpoke st,40,下位 : lpoke st,44,上位
; ai_bloblen : UINT_PTR (+48, 8byte) qpoke st,48,値 / qpeek(st,48) ※IronHSPのみ。3.7/3.8は lpoke st,48,下位 : lpoke st,52,上位
; ai_provider : GUID* (+56, 8byte) varptr(st)+56 を基点に操作(8byte:入れ子/配列)
; ai_next : ADDRINFOEX4* (+64, 8byte) varptr(st)+64 を基点に操作(8byte:入れ子/配列)
; ai_version : INT (+72, 4byte) st.18 = 値 / 値 = st.18 (lpoke/lpeek も可)
; ai_fqdn : LPWSTR (+80, 8byte) qpoke st,80,値 / qpeek(st,80) ※IronHSPのみ。3.7/3.8は lpoke st,80,下位 : lpoke st,84,上位
; ai_interfaceindex : INT (+88, 4byte) st.22 = 値 / 値 = st.22 (lpoke/lpeek も可)
; ai_resolutionhandle : HANDLE (+96, 8byte) qpoke st,96,値 / qpeek(st,96) ※IronHSPのみ。3.7/3.8は lpoke st,96,下位 : lpoke st,100,上位
; ※4byte境界の整数は添字 st.N(N=オフセット/4)で読み書き可。それ以外は peek/poke 系を使用。; IronHSP は NSTRUCT(構造体)をサポート。32bit/64bit どちらでも同じコードで動作します。
#defstruct global ADDRINFOEX4
#field int ai_flags
#field int ai_family
#field int ai_socktype
#field int ai_protocol
#field intptr ai_addrlen
#field intptr ai_canonname
#field intptr ai_addr
#field intptr ai_blob
#field intptr ai_bloblen
#field intptr ai_provider
#field intptr ai_next
#field int ai_version
#field intptr ai_fqdn
#field int ai_interfaceindex
#field intptr ai_resolutionhandle
#endstruct
stdim st, ADDRINFOEX4 ; NSTRUCT 変数を確保
st->ai_flags = 100
mes "ai_flags=" + st->ai_flags