Win32 API 日本語リファレンス
ホームNetworking.WinSock › WSASocketW

WSASocketW

関数
プロトコル情報やフラグを指定してソケットを作成する。
DLLWS2_32.dll文字セットUnicode (-W)呼出規約winapiSetLastErrorあり対応OSWindows 8.1 以降

シグネチャ

// WS2_32.dll  (Unicode / -W)
#include <windows.h>

SOCKET WSASocketW(
    INT af,
    INT type,
    INT protocol,
    WSAPROTOCOL_INFOW* lpProtocolInfo,   // optional
    DWORD g,
    DWORD dwFlags
);

パラメーター

名前方向説明
afINTin

アドレスファミリの指定。アドレスファミリに指定できる値は Winsock2.h ヘッダーファイルで定義されています。

Windows Vista 以降向けにリリースされた Windows SDK では、ヘッダーファイルの構成が変更され、アドレスファミリに指定できる値は Ws2def.h ヘッダーファイルで定義されています。なお、Ws2def.h ヘッダーファイルは Winsock2.h に自動的にインクルードされるため、直接使用してはいけません。

現在サポートされている値は AF_INET または AF_INET6 で、これらはそれぞれ IPv4 と IPv6 のインターネット アドレスファミリ形式です。アドレスファミリのその他のオプション(例えば NetBIOS で使用する AF_NETBIOS など)は、そのアドレスファミリ用の Windows Sockets サービスプロバイダーがインストールされている場合にサポートされます。なお、AF_ アドレスファミリ定数と PF_ プロトコルファミリ定数の値は同一であるため(例えば AF_INETPF_INET)、どちらの定数も使用できます。

以下の表は、アドレスファミリの一般的な値を示しています。ただし、他にも多くの値が使用可能です。

Af 意味
AF_UNSPEC
0
アドレスファミリは未指定です。
AF_INET
2
Internet Protocol version 4 (IPv4) アドレスファミリ。
AF_IPX
6
IPX/SPX アドレスファミリ。このアドレスファミリは、NWLink IPX/SPX NetBIOS Compatible Transport プロトコルがインストールされている場合にのみサポートされます。

このアドレスファミリは Windows Vista 以降ではサポートされません。

AF_APPLETALK
16
AppleTalk アドレスファミリ。このアドレスファミリは、AppleTalk プロトコルがインストールされている場合にのみサポートされます。

このアドレスファミリは Windows Vista 以降ではサポートされません。

AF_NETBIOS
17
NetBIOS アドレスファミリ。このアドレスファミリは、NetBIOS 用の Windows Sockets プロバイダーがインストールされている場合にのみサポートされます。

NetBIOS 用の Windows Sockets プロバイダーは、32 ビット版の Windows でサポートされます。このプロバイダーは 32 ビット版の Windows に既定でインストールされます。

NetBIOS 用の Windows Sockets プロバイダーは、Windows 7、Windows Server 2008、Windows Vista、Windows Server 2003、Windows XP を含む 64 ビット版の Windows ではサポートされません。

NetBIOS 用の Windows Sockets プロバイダーは、type パラメーターが SOCK_DGRAM に設定されているソケットのみをサポートします。

NetBIOS 用の Windows Sockets プロバイダーは、NetBIOS プログラミングインターフェイスと直接の関係はありません。NetBIOS プログラミングインターフェイスは Windows Vista、Windows Server 2008 以降ではサポートされません。

AF_INET6
23
Internet Protocol version 6 (IPv6) アドレスファミリ。
AF_IRDA
26
Infrared Data Association (IrDA) アドレスファミリ。

このアドレスファミリは、コンピューターに赤外線ポートとドライバーがインストールされている場合にのみサポートされます。

AF_BTH
32
Bluetooth アドレスファミリ。

このアドレスファミリは、コンピューターに Bluetooth アダプターとドライバーがインストールされている Windows XP with SP2 以降でサポートされます。

typeINTin

新しいソケットの種類の指定。

ソケットの種類に指定できる値は Winsock2.h ヘッダーファイルで定義されています。

以下の表は、Windows Sockets 2 でサポートされる type パラメーターに指定可能な値を示しています。

Type 意味
SOCK_STREAM
1
順序付けされた、信頼性のある、双方向の、接続ベースのバイトストリームを、OOB データ送信機構とともに提供するソケットの種類です。このソケットの種類は、インターネットアドレスファミリ(AF_INET または AF_INET6)で Transmission Control Protocol (TCP) を使用します。
SOCK_DGRAM
2
データグラムをサポートするソケットの種類です。データグラムは、コネクションレスで信頼性がなく、固定された(通常は小さい)最大長を持つバッファーです。このソケットの種類は、インターネットアドレスファミリ(AF_INET または AF_INET6)で User Datagram Protocol (UDP) を使用します。
SOCK_RAW
3
アプリケーションが上位層のプロトコルヘッダーを操作できる raw ソケットを提供するソケットの種類です。IPv4 ヘッダーを操作するには、ソケットに IP_HDRINCL ソケットオプションを設定する必要があります。IPv6 ヘッダーを操作するには、ソケットに IPV6_HDRINCL ソケットオプションを設定する必要があります。
SOCK_RDM
4
信頼性のあるメッセージデータグラムを提供するソケットの種類です。この種類の例としては、Windows における Pragmatic General Multicast (PGM) マルチキャストプロトコルの実装があり、しばしば 信頼性のあるマルチキャストプログラミングと呼ばれます。

この type の値は、Reliable Multicast Protocol がインストールされている場合にのみサポートされます。

SOCK_SEQPACKET
5
データグラムに基づく疑似ストリームパケットを提供するソケットの種類です。

Windows Sockets 2 では、新しいソケットの種類が導入されました。アプリケーションは、 WSAEnumProtocols 関数を通じて、利用可能な各トランスポートプロトコルの属性を動的に検出できます。したがって、アプリケーションはアドレスファミリに対して可能なソケットの種類とプロトコルオプションを判別し、その情報をこのパラメーターの指定に利用できます。Winsock2.h および Ws2def.h ヘッダーファイル内のソケットの種類の定義は、新しいソケットの種類、アドレスファミリ、プロトコルが定義されるにつれて定期的に更新されます。

Windows Sockets 1.1 では、使用可能なソケットの種類は SOCK_DGRAMSOCK_STREAM のみです。

protocolINTin

使用するプロトコル。protocol パラメーターに指定可能なオプションは、指定されたアドレスファミリとソケットの種類に固有です。protocol に指定可能な値は Winsock2.h および Wsrm.h ヘッダーファイルで定義されています。

Windows Vista 以降向けにリリースされた Windows SDK では、ヘッダーファイルの構成が変更され、このパラメーターには Ws2def.h ヘッダーファイルで定義された IPPROTO 列挙型の値のいずれかを指定できます。なお、Ws2def.h ヘッダーファイルは Winsock2.h に自動的にインクルードされるため、直接使用してはいけません。

値 0 を指定した場合、呼び出し元はプロトコルを指定しないことを意味し、サービスプロバイダーが使用する protocol を選択します。

af パラメーターが AF_INET または AF_INET6 で、typeSOCK_RAW の場合、protocol に指定された値は IPv6 または IPv4 パケットヘッダーのプロトコルフィールドに設定されます。

以下の表は、protocol の一般的な値を示しています。ただし、他にも多くの値が使用可能です。

protocol 意味
IPPROTO_ICMP
1
Internet Control Message Protocol (ICMP)。これは、af パラメーターが AF_UNSPECAF_INET、または AF_INET6 で、type パラメーターが SOCK_RAW または未指定の場合に指定可能な値です。

この protocol 値は Windows XP 以降でサポートされます。

IPPROTO_IGMP
2
Internet Group Management Protocol (IGMP)。これは、af パラメーターが AF_UNSPECAF_INET、または AF_INET6 で、type パラメーターが SOCK_RAW または未指定の場合に指定可能な値です。

この protocol 値は Windows XP 以降でサポートされます。

BTHPROTO_RFCOMM
3
Bluetooth Radio Frequency Communications (Bluetooth RFCOMM) プロトコル。これは、af パラメーターが AF_BTH で、type パラメーターが SOCK_STREAM の場合に指定可能な値です。

この protocol 値は Windows XP with SP2 以降でサポートされます。

IPPROTO_TCP
6
Transmission Control Protocol (TCP)。これは、af パラメーターが AF_INET または AF_INET6 で、type パラメーターが SOCK_STREAM の場合に指定可能な値です。
IPPROTO_UDP
17
User Datagram Protocol (UDP)。これは、af パラメーターが AF_INET または AF_INET6 で、type パラメーターが SOCK_DGRAM の場合に指定可能な値です。
IPPROTO_ICMPV6
58
Internet Control Message Protocol Version 6 (ICMPv6)。これは、af パラメーターが AF_UNSPECAF_INET、または AF_INET6 で、type パラメーターが SOCK_RAW または未指定の場合に指定可能な値です。

この protocol 値は Windows XP 以降でサポートされます。

IPPROTO_RM
113
信頼性のあるマルチキャストのための PGM プロトコル。これは、af パラメーターが AF_INET で、type パラメーターが SOCK_RDM の場合に指定可能な値です。Windows Vista 以降向けにリリースされた Windows SDK では、このプロトコルは IPPROTO_PGM とも呼ばれます。

この protocol 値は、Reliable Multicast Protocol がインストールされている場合にのみサポートされます。

lpProtocolInfoWSAPROTOCOL_INFOW*inoptional作成するソケットの特性を定義する WSAPROTOCOL_INFO 構造体へのポインター。このパラメーターが NULL でない場合、ソケットは指定された WSAPROTOCOL_INFO 構造体に関連付けられたプロバイダーにバインドされます。
gDWORDin

既存のソケットグループ ID、または新しいソケットと新しいソケットグループを作成する際に取るべき適切なアクション。

g が既存のソケットグループ ID の場合、このグループが設定するすべての要件が満たされていれば、新しいソケットをこのソケットグループに参加させます。

g が既存のソケットグループ ID でない場合、以下の値が指定可能です。

g 意味
0
グループ操作は実行されません。
SG_UNCONSTRAINED_GROUP
0x01
制約のないソケットグループを作成し、新しいソケットをその最初のメンバーにします。制約のないグループでは、Winsock はソケットグループ内のすべてのソケットが type および protocol パラメーターに同じ値で作成されることを強制しません。
SG_CONSTRAINED_GROUP
0x02
制約のあるソケットグループを作成し、新しいソケットをその最初のメンバーにします。制約のあるソケットグループでは、Winsock はソケットグループ内のすべてのソケットが type および protocol パラメーターに同じ値で作成されることを強制します。制約のあるソケットグループはコネクション指向のソケットのみで構成でき、グループ化されたすべてのソケットの接続が同じホスト上の同じアドレスへの接続であることを必要とします。
注意 SG_UNCONSTRAINED_GROUP および SG_CONSTRAINED_GROUP 定数は、現在パブリックなヘッダーファイルでは定義されていません。
dwFlagsDWORDin

追加のソケット属性を指定するために使用するフラグのセット。

これらのフラグの組み合わせを設定できますが、一部の組み合わせは許可されません。

意味
WSA_FLAG_OVERLAPPED
0x01
オーバーラップ I/O 操作をサポートするソケットを作成します。

ほとんどのソケットはこのフラグを設定して作成すべきです。オーバーラップソケットは、オーバーラップ I/O 操作のために WSASendWSASendToWSARecvWSARecvFromWSAIoctl を利用でき、複数の操作を同時に開始し進行させることができます。

オーバーラップ操作を許可するすべての関数(WSASendWSARecvWSASendToWSARecvFromWSAIoctl)は、オーバーラップ操作に関連するパラメーターの値が NULL であれば、オーバーラップソケット上での非オーバーラップ使用もサポートします。

WSA_FLAG_MULTIPOINT_C_ROOT
0x02
マルチポイントセッションで c_root となるソケットを作成します。

この属性は、ソケットを作成するトランスポートプロバイダーの WSAPROTOCOL_INFO 構造体がマルチポイントまたはマルチキャスト機構をサポートし、かつマルチポイントセッションのコントロールプレーンがルート化されている場合にのみ許可されます。これは、WSAPROTOCOL_INFO 構造体の dwServiceFlags1 メンバーで XP1_SUPPORT_MULTIPOINT および XP1_MULTIPOINT_CONTROL_PLANE フラグが設定されていることで示されます。

lpProtocolInfo パラメーターが NULL でない場合、トランスポートプロバイダーの WSAPROTOCOL_INFO 構造体は lpProtocolInfo パラメーターによって指し示されます。lpProtocolInfo パラメーターが NULL の場合、WSAPROTOCOL_INFO 構造体は、aftypeprotocol パラメーターに指定された値によって選択されたトランスポートプロバイダーに基づきます。

マルチポイントセッションに関する追加情報については、 Multipoint and Multicast Semantics を参照してください。

WSA_FLAG_MULTIPOINT_C_LEAF
0x04
マルチポイントセッションで c_leaf となるソケットを作成します。

この属性は、ソケットを作成するトランスポートプロバイダーの WSAPROTOCOL_INFO 構造体がマルチポイントまたはマルチキャスト機構をサポートし、かつマルチポイントセッションのコントロールプレーンが非ルート化である場合にのみ許可されます。これは、WSAPROTOCOL_INFO 構造体の dwServiceFlags1 メンバーで XP1_SUPPORT_MULTIPOINT フラグが設定され、XP1_MULTIPOINT_CONTROL_PLANE フラグが設定されていないことで示されます。

lpProtocolInfo パラメーターが NULL でない場合、トランスポートプロバイダーの WSAPROTOCOL_INFO 構造体は lpProtocolInfo パラメーターによって指し示されます。lpProtocolInfo パラメーターが NULL の場合、WSAPROTOCOL_INFO 構造体は、aftypeprotocol パラメーターに指定された値によって選択されたトランスポートプロバイダーに基づきます。

マルチポイントセッションに関する追加情報については、 Multipoint and Multicast Semantics を参照してください。

WSA_FLAG_MULTIPOINT_D_ROOT
0x08
マルチポイントセッションで d_root となるソケットを作成します。

この属性は、ソケットを作成するトランスポートプロバイダーの WSAPROTOCOL_INFO 構造体がマルチポイントまたはマルチキャスト機構をサポートし、かつマルチポイントセッションのデータプレーンがルート化されている場合にのみ許可されます。これは、WSAPROTOCOL_INFO 構造体の dwServiceFlags1 メンバーで XP1_SUPPORT_MULTIPOINT および XP1_MULTIPOINT_DATA_PLANE フラグが設定されていることで示されます。

lpProtocolInfo パラメーターが NULL でない場合、トランスポートプロバイダーの WSAPROTOCOL_INFO 構造体は lpProtocolInfo パラメーターによって指し示されます。lpProtocolInfo パラメーターが NULL の場合、WSAPROTOCOL_INFO 構造体は、aftypeprotocol パラメーターに指定された値によって選択されたトランスポートプロバイダーに基づきます。

マルチポイントセッションに関する追加情報については、 Multipoint and Multicast Semantics を参照してください。

WSA_FLAG_MULTIPOINT_D_LEAF
0x10
マルチポイントセッションで d_leaf となるソケットを作成します。

この属性は、ソケットを作成するトランスポートプロバイダーの WSAPROTOCOL_INFO 構造体がマルチポイントまたはマルチキャスト機構をサポートし、かつマルチポイントセッションのデータプレーンが非ルート化である場合にのみ許可されます。これは、WSAPROTOCOL_INFO 構造体の dwServiceFlags1 メンバーで XP1_SUPPORT_MULTIPOINT フラグが設定され、XP1_MULTIPOINT_DATA_PLANE フラグが設定されていないことで示されます。

lpProtocolInfo パラメーターが NULL でない場合、トランスポートプロバイダーの WSAPROTOCOL_INFO 構造体は lpProtocolInfo パラメーターによって指し示されます。lpProtocolInfo パラメーターが NULL の場合、WSAPROTOCOL_INFO 構造体は、aftypeprotocol パラメーターに指定された値によって選択されたトランスポートプロバイダーに基づきます。

マルチポイントセッションに関する追加情報については、 Multipoint and Multicast Semantics を参照してください。

WSA_FLAG_ACCESS_SYSTEM_SECURITY
0x40
任意アクセス制御リスト (DACL) だけでなく、システムアクセス制御リスト (SACL) を含むセキュリティ記述子をソケットに設定できるソケットを作成します。

SACL は、オブジェクトに対するアクセスチェックが発生したときに監査やアラームを生成するために使用されます。ソケットの場合、ソケットが bind 関数に指定された特定のアドレスへのバインドを許可されるべきかどうかを判断するためにアクセスチェックが発生します。

ACCESS_SYSTEM_SECURITY アクセス権は、オブジェクトのセキュリティ記述子内の SACL を取得または設定する機能を制御します。システムは、要求元スレッドのアクセストークンで SE_SECURITY_NAME 特権が有効になっている場合にのみ、このアクセス権を付与します。

WSA_FLAG_NO_HANDLE_INHERIT
0x80
継承不可能なソケットを作成します。

WSASocket 関数または socket 関数によって作成されたソケットハンドルは、既定で継承可能です。このフラグが設定されると、ソケットハンドルは継承不可能になります。

GetHandleInformation 関数を使用して、ソケットハンドルが WSA_FLAG_NO_HANDLE_INHERIT フラグを設定して作成されたかどうかを判断できます。GetHandleInformation 関数は HANDLE_FLAG_INHERIT 値が設定されていることを返します。

このフラグは Windows 7 with SP1、Windows Server 2008 R2 with SP1 以降でサポートされます。

重要 マルチポイントソケットでは、WSA_FLAG_MULTIPOINT_C_ROOT または WSA_FLAG_MULTIPOINT_C_LEAF フラグのいずれか一方のみを指定でき、また WSA_FLAG_MULTIPOINT_D_ROOT または WSA_FLAG_MULTIPOINT_D_LEAF フラグのいずれか一方のみを指定できます。追加情報については Multipoint and Multicast Semantics を参照してください。

戻り値の型: SOCKET

公式ドキュメント

WSASocket 関数は、特定のトランスポートサービスプロバイダーにバインドされたソケットを作成します。(Unicode)

戻り値

エラーが発生しなかった場合、 WSASocket は新しいソケットを参照する記述子を返します。それ以外の場合は INVALID_SOCKET の値が返され、 WSAGetLastError を呼び出すことで特定のエラーコードを取得できます。

注意 このエラーコードの説明は Microsoft 固有のものです。
エラーコード 意味
WSANOTINITIALISED
この関数を使用する前に、 WSAStartup の呼び出しが成功している必要があります。
WSAENETDOWN
ネットワークサブシステムに障害が発生しました。
WSAEAFNOSUPPORT
指定されたアドレスファミリはサポートされていません。
WSAEFAULT
lpProtocolInfo パラメーターがプロセスアドレス空間の有効な部分にありません。
WSAEINPROGRESS
ブロッキング型の Windows Sockets 1.1 呼び出しが進行中であるか、サービスプロバイダーがコールバック関数をまだ処理中です。
WSAEINVAL
この値は、以下のいずれかの条件に該当する場合に発生します。
  • 指定された g パラメーターが有効でありません。
  • lpProtocolInfo が指す WSAPROTOCOL_INFO 構造体が不完全であるか、内容が無効であるか、または WSAPROTOCOL_INFO 構造体が以前のソケット複製操作で既に使用されています。
  • ソケットの三つ組 <aftypeprotocol> のメンバーに指定された値は個別にはサポートされていますが、その組み合わせはサポートされていません。
WSAEINVALIDPROVIDER
サービスプロバイダーが 2.2 以外のバージョンを返しました。
WSAEINVALIDPROCTABLE
サービスプロバイダーが WSPStartup に無効または不完全なプロシージャテーブルを返しました。
WSAEMFILE
使用可能なソケット記述子がこれ以上ありません。
WSAENOBUFS
使用可能なバッファー領域がありません。ソケットを作成できません。
WSAEPROTONOSUPPORT
指定されたプロトコルはサポートされていません。
WSAEPROTOTYPE
指定されたプロトコルは、このソケットには不適切な種類です。
WSAEPROVIDERFAILEDINIT
サービスプロバイダーの初期化に失敗しました。このエラーは、レイヤードサービスプロバイダー (LSP) または名前空間プロバイダーが正しくインストールされていない場合、あるいはプロバイダーが正しく動作しない場合に返されます。
WSAESOCKTNOSUPPORT
指定されたソケットの種類は、このアドレスファミリではサポートされていません。

解説(Remarks)

WSASocket 関数は、ソケット記述子および関連するリソースを割り当て、トランスポートサービスプロバイダーに関連付けます。ほとんどのソケットは、dwFlags パラメーターに WSA_FLAG_OVERLAPPED 属性を設定して作成すべきです。この属性を設定して作成されたソケットは、より高いパフォーマンスを提供するオーバーラップ I/O 操作の使用をサポートします。既定では、WSASocket 関数で作成されたソケットにはこのオーバーラップ属性は設定されません。これに対して、socket 関数は、既定の動作としてオーバーラップ I/O 操作をサポートするソケットを作成します。

lpProtocolInfo パラメーターが NULL の場合、Winsock は、aftypeprotocol パラメーターで指定された、要求されたアドレスファミリ、ソケットの種類、プロトコルの組み合わせをサポートする最初に利用可能なトランスポートサービスプロバイダーを利用します。

lpProtocolInfo パラメーターが NULL でない場合、ソケットは指定された WSAPROTOCOL_INFO 構造体に関連付けられたプロバイダーにバインドされます。この場合、アプリケーションは aftypeprotocol パラメーターのいずれの値としてもマニフェスト定数 FROM_PROTOCOL_INFO を指定できます。これは、指定された WSAPROTOCOL_INFO 構造体の対応する値(iAddressFamilyiSocketTypeiProtocol)が想定されることを示します。いずれの場合も、aftypeprotocol に指定された値は変更されることなくトランスポートサービスプロバイダーに渡されます。

aftypeprotocol に基づいてプロトコルとそれをサポートするサービスプロバイダーを選択する際、この手続きはベースプロトコルまたはプロトコルチェーンのみを選択し、プロトコルレイヤー単独は選択しません。チェーン化されていないプロトコルレイヤーは、type または af の部分一致を持つとも見なされません。つまり、適切なプロトコルが見つからなかった場合でも、それらは WSAEAFNOSUPPORTWSAEPROTONOSUPPORT のエラーコードにはつながりません。

注意 マニフェスト定数 AF_UNSPEC は引き続きヘッダーファイルで定義されていますが、その使用は強く非推奨です。protocol パラメーターの値の解釈にあいまいさを生じさせる可能性があるためです。
アプリケーションは、af パラメーターに AF_INET6 を使用し、IPv4 と IPv6 の両方で使用できるデュアルモードソケットを作成することが推奨されます。

WSASocket 関数を使用してソケットを作成した場合、SO_RCVTIMEO または SO_SNDTIMEO ソケットオプションが正しく機能するには、dwFlags パラメーターに WSA_FLAG_OVERLAPPED 属性が設定されている必要があります。そうでない場合、タイムアウトはソケットに対して有効になりません。

SOCK_STREAM のようなコネクション指向のソケットは、全二重接続を提供し、データを送受信する前に接続状態になっている必要があります。指定されたソケットへの接続は、 connect または WSAConnect 関数の呼び出しによって確立されます。接続後は、 send/WSASend および recv/WSARecv の呼び出しを使用してデータを転送できます。セッションが完了したら、ソケットに関連付けられたリソースを解放するために closesocket 関数を呼び出すべきです。コネクション指向のソケットの場合、closesocket 関数を呼び出す前に、ソケット上のデータ転送を停止するために shutdown 関数を呼び出すべきです。

信頼性のあるコネクション指向のソケットを実装するために使用される通信プロトコルは、データが失われたり重複したりしないことを保証します。ピアプロトコルにバッファー領域があるデータが妥当な時間内に正常に送信できなかった場合、接続は切断されたと見なされ、以降の呼び出しは WSAETIMEDOUT に設定されたエラーコードで失敗します。

コネクションレスでメッセージ指向のソケットは、 sendto/WSASendTo および recvfrom/WSARecvFrom を使用して、任意のピアとの間でデータグラムを送受信できます。そのようなソケットが特定のピアに接続されている場合、 send/WSASend を使用してそのピアにデータグラムを送信でき、 recv/WSARecv を使用して(そのピアからのみ)受信できます。

SOCK_RAW 種類のソケットのサポートは必須ではありませんが、サービスプロバイダーは可能な限り raw ソケットをサポートすることが推奨されます。

WSASocket 関数は、サービスで使用するソケットを作成するために使用できます。これにより、別のソケットがそのサービスで使用されているのと同じポートにバインドしようとした場合に、監査レコードが生成されます。このオプションを有効にするには、アプリケーションは次の操作を行う必要があります。

ACCESS_SYSTEM_SECURITY の詳細については、Authorization ドキュメントの SACL Access Right および Audit Generation を参照してください。

ソケットグループ

WinSock 2 では、アプリケーション、または連携するアプリケーションのセットが、特定のソケットのセットが関連していること、およびそうして形成されたグループが特定の属性を持つことを、基盤となるサービスプロバイダーに示す手段として、ソケットグループという概念が導入されました。グループ属性には、グループ内の個々のソケットの相対的な優先順位と、グループのサービス品質仕様が含まれます。

ネットワーク上でマルチメディアストリームを交換する必要があるアプリケーションは、ソケットのセット間に特定の関係を確立できることが有益となる例です。ソケットグループをどのように扱うかはトランスポート次第です。

WSASocket および WSAAccept 関数を使用して、新しいソケットを作成する際にソケットグループを明示的に作成して参加させることができます。ソケットのソケットグループ ID は、getsockopt 関数で level パラメーターを SOL_SOCKET に、optname パラメーターを SO_GROUP_ID に設定することで取得できます。ソケットグループとそれに関連付けられたソケットグループ ID は、このソケットグループに属する最後のソケットが閉じられるまで有効なままです。ソケットグループ ID は、特定のサービスプロバイダーに対するすべてのプロセスにわたって一意です。ソケットグループが 0 の場合、そのソケットがソケットグループのメンバーでないことを示します。

ソケットグループの相対的なグループ優先順位には、getsockopt 関数で level パラメーターを SOL_SOCKET に、optname パラメーターを SO_GROUP_PRIORITY に設定することでアクセスできます。ソケットグループの相対的なグループ優先順位は、setsockoptlevel パラメーターを SOL_SOCKET に、optname パラメーターを SO_GROUP_PRIORITY に設定することで設定できます。

Windows に含まれる Winsock プロバイダーは、ソケットグループの作成を許可し、SG_CONSTRAINED_GROUP を強制します。制約のあるソケットグループ内のすべてのソケットは、type および protocol パラメーターに同じ値で作成される必要があります。制約のあるソケットグループはコネクション指向のソケットのみで構成でき、グループ化されたすべてのソケットの接続が同じホスト上の同じアドレスへの接続であることを必要とします。これが、Windows に含まれる Winsock プロバイダーがソケットグループに適用する唯一の制限です。ソケットグループの優先順位は、Windows に含まれる Winsock プロバイダーや TCP/IP スタックでは現在使用されていません。

コード例

以下の例は、WSASocket 関数の使用方法を示しています。
#ifndef UNICODE
#define UNICODE 1
#endif

// link with Ws2_32.lib
#pragma comment(lib,"Ws2_32.lib")

#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>
#include <stdlib.h>   // Needed for _wtoi


int __cdecl wmain(int argc, wchar_t **argv)
{

    //-----------------------------------------
    // Declare and initialize variables
    WSADATA wsaData = {0};
    int iResult = 0;

//    int i = 1;

    SOCKET sock = INVALID_SOCKET;
    int iFamily = AF_UNSPEC;
    int iType = 0;
    int iProtocol = 0;
    DWORD dwFlags = 0;

    // Validate the parameters
    if (argc != 5) {
        wprintf(L"usage: %s <addressfamily> <type> <protocol> <flags>\n", argv[0]);
        wprintf(L"       opens a socket for the specified family, type, protocol, and flags\n");
        wprintf(L"       flags value must be in decimal, not hex\n");
        wprintf(L"%ws example usage\n", argv[0]);
        wprintf(L"   %ws 0 2 17 1\n", argv[0]);
        wprintf(L"   where AF_UNSPEC=0 SOCK_DGRAM=2 IPPROTO_UDP=17 OVERLAPPED\n", argv[0]);
        return 1;
    }

    iFamily = _wtoi(argv[1]);
    iType = _wtoi(argv[2]);
    iProtocol = _wtoi(argv[3]);
    dwFlags = _wtoi(argv[4]);
    
    // Initialize Winsock
    iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
    if (iResult != 0) {
        wprintf(L"WSAStartup failed: %d\n", iResult);
        return 1;
    }

    wprintf(L"Calling socket with following parameters:\n");
    wprintf(L"  Address Family = ");
    switch (iFamily) {
    case AF_UNSPEC:
        wprintf(L"Unspecified");
        break;
    case AF_INET:
        wprintf(L"AF_INET (IPv4)");
        break;
    case AF_INET6:
        wprintf(L"AF_INET6 (IPv6)");
        break;
    case AF_NETBIOS:
        wprintf(L"AF_NETBIOS (NetBIOS)");
        break;
    case AF_BTH:
        wprintf(L"AF_BTH (Bluetooth)");
        break;
    default:
        wprintf(L"Other");
        break;
    }
    wprintf(L" (%d)\n", iFamily);
    
    wprintf(L"  Socket type = ");
    switch (iType) {
    case 0:
        wprintf(L"Unspecified");
        break;
    case SOCK_STREAM:
        wprintf(L"SOCK_STREAM (stream)");
        break;
    case SOCK_DGRAM:
        wprintf(L"SOCK_DGRAM (datagram)");
        break;
    case SOCK_RAW:
        wprintf(L"SOCK_RAW (raw)");
        break;
    case SOCK_RDM:
        wprintf(L"SOCK_RDM (reliable message datagram)");
        break;
    case SOCK_SEQPACKET:
        wprintf(L"SOCK_SEQPACKET (pseudo-stream packet)");
        break;
    default:
        wprintf(L"Other");
        break;
    }
    wprintf(L" (%d)\n", iType);

    wprintf(L"  Protocol = %d = ", iProtocol);
    switch (iProtocol) {
    case 0:
        wprintf(L"Unspecified");
        break;
    case IPPROTO_ICMP:
        wprintf(L"IPPROTO_ICMP (ICMP)");
        break;
    case IPPROTO_IGMP:
        wprintf(L"IPPROTO_IGMP (IGMP)");
        break;
    case IPPROTO_TCP:
        wprintf(L"IPPROTO_TCP (TCP)");
        break;
    case IPPROTO_UDP:
        wprintf(L"IPPROTO_UDP (UDP)");
        break;
    case IPPROTO_ICMPV6:
        wprintf(L"IPPROTO_ICMPV6 (ICMP Version 6)");
        break;
    default:
        wprintf(L"Other");
        break;
    }
    wprintf(L" (%d)\n", iProtocol);

    wprintf(L"  Flags = ");
    if (dwFlags & WSA_FLAG_OVERLAPPED)
        wprintf(L"  WSA_FLAG_OVERLAPPED");
    if (dwFlags & WSA_FLAG_MULTIPOINT_C_ROOT)
        wprintf(L"  WSA_FLAG_MULTIPOINT_C_ROOT");
    if (dwFlags & WSA_FLAG_MULTIPOINT_C_LEAF)
        wprintf(L"  WSA_FLAG_MULTIPOINT_C_LEAF");
    if (dwFlags & WSA_FLAG_MULTIPOINT_D_ROOT)
        wprintf(L"  WSA_FLAG_MULTIPOINT_D_ROOT");
    if (dwFlags & WSA_FLAG_MULTIPOINT_D_LEAF)
        wprintf(L"  WSA_FLAG_MULTIPOINT_D_LEAF");
    if (dwFlags & WSA_FLAG_ACCESS_SYSTEM_SECURITY)
        wprintf(L"  WSA_FLAG_ACCESS_SYSTEM_SECURITY");
#ifdef WSA_FLAG_NO_HANDLE_INHERIT 
    if (dwFlags & WSA_FLAG_NO_HANDLE_INHERIT)
        wprintf(L"  WSA_FLAG_NO_HANDLE_INHERIT");
#endif
    wprintf(L" (0x%x)\n" , dwFlags);

    sock = WSASocket(iFamily, iType, iProtocol, NULL, 0, dwFlags);
    if (sock == INVALID_SOCKET) 
        wprintf(L"WSASocket function failed with error = %d\n", WSAGetLastError() );
    else {
        wprintf(L"WSASocket function succeeded\n");

        // Close the socket to release the resources associated
        // Normally an application calls shutdown() before closesocket 
        //   to  disables sends or receives on a socket first
        // This isn't needed in this simple sample
        iResult = closesocket(sock);
        if (iResult == SOCKET_ERROR) {
            wprintf(L"closesocket function zfailed with error = %d\n", WSAGetLastError() );
            WSACleanup();
            return 1;
        }    
    }
    WSACleanup();

    return 0;
}

Windows Phone 8: WSASocketW 関数は、Windows Phone 8 以降の Windows Phone Store アプリでサポートされます。

Windows 8.1 および Windows Server 2012 R2: WSASocketW 関数は、Windows 8.1、Windows Server 2012 R2 以降の Windows Store アプリでサポートされます。

メモ

winsock2.h ヘッダーは、UNICODE プリプロセッサ定数の定義に基づいて、この関数の ANSI 版または Unicode 版を自動的に選択するエイリアスとして WSASocket を定義しています。エンコーディング中立のエイリアスの使用を、エンコーディング中立でないコードと混在させると、コンパイルエラーや実行時エラーを引き起こす不一致につながる可能性があります。詳細については、Conventions for Function Prototypes を参照してください。

出典・ライセンス: 上記「公式ドキュメント」の内容は Microsoft の Win32 API ドキュメント(MicrosoftDocs/sdk-api)を日本語に翻訳・改変したものです。© Microsoft Corporation. CC BY 4.0 で提供。
Microsoft 公式リファレンス: 英語 (en-us) · 日本語 (ja-jp) · 原文ソース (GitHub)

各言語での呼び出し定義

// WS2_32.dll  (Unicode / -W)
#include <windows.h>

SOCKET WSASocketW(
    INT af,
    INT type,
    INT protocol,
    WSAPROTOCOL_INFOW* lpProtocolInfo,   // optional
    DWORD g,
    DWORD dwFlags
);
[DllImport("WS2_32.dll", CharSet = CharSet.Unicode, SetLastError = true, ExactSpelling = true)]
static extern UIntPtr WSASocketW(
    int af,   // INT
    int type,   // INT
    int protocol,   // INT
    IntPtr lpProtocolInfo,   // WSAPROTOCOL_INFOW* optional
    uint g,   // DWORD
    uint dwFlags   // DWORD
);
<DllImport("WS2_32.dll", CharSet:=CharSet.Unicode, SetLastError:=True, ExactSpelling:=True)>
Public Shared Function WSASocketW(
    af As Integer,   ' INT
    type As Integer,   ' INT
    protocol As Integer,   ' INT
    lpProtocolInfo As IntPtr,   ' WSAPROTOCOL_INFOW* optional
    g As UInteger,   ' DWORD
    dwFlags As UInteger   ' DWORD
) As UIntPtr
End Function
' af : INT
' type : INT
' protocol : INT
' lpProtocolInfo : WSAPROTOCOL_INFOW* optional
' g : DWORD
' dwFlags : DWORD
Declare PtrSafe Function WSASocketW Lib "ws2_32" ( _
    ByVal af As Long, _
    ByVal type As Long, _
    ByVal protocol As Long, _
    ByVal lpProtocolInfo As LongPtr, _
    ByVal g As Long, _
    ByVal dwFlags As Long) As LongPtr
' Unicode(W): 文字列は ByVal As LongPtr とし StrPtr(unicodeStr) を渡す
' VBA7前提(PtrSafe)。32bit Office では LongPtr→Long。Integer=16bit / Long=32bit / LongLong=64bit。
import ctypes
from ctypes import wintypes

WSASocketW = ctypes.windll.ws2_32.WSASocketW
WSASocketW.restype = ctypes.c_size_t
WSASocketW.argtypes = [
    ctypes.c_int,  # af : INT
    ctypes.c_int,  # type : INT
    ctypes.c_int,  # protocol : INT
    ctypes.c_void_p,  # lpProtocolInfo : WSAPROTOCOL_INFOW* optional
    wintypes.DWORD,  # g : DWORD
    wintypes.DWORD,  # dwFlags : DWORD
]
# GetLastError: use ctypes.GetLastError() (or ctypes.WinDLL(use_last_error=True))
require 'fiddle'
require 'fiddle/import'

lib = Fiddle.dlopen('WS2_32.dll')
WSASocketW = Fiddle::Function.new(
  lib['WSASocketW'],
  [
    Fiddle::TYPE_INT,  # af : INT
    Fiddle::TYPE_INT,  # type : INT
    Fiddle::TYPE_INT,  # protocol : INT
    Fiddle::TYPE_VOIDP,  # lpProtocolInfo : WSAPROTOCOL_INFOW* optional
    -Fiddle::TYPE_INT,  # g : DWORD
    -Fiddle::TYPE_INT,  # dwFlags : DWORD
  ],
  Fiddle::TYPE_UINTPTR_T)
# Wide strings: pass str.encode("UTF-16LE") + "\x00\x00"
#[link(name = "ws2_32")]
extern "system" {
    fn WSASocketW(
        af: i32,  // INT
        type: i32,  // INT
        protocol: i32,  // INT
        lpProtocolInfo: *mut WSAPROTOCOL_INFOW,  // WSAPROTOCOL_INFOW* optional
        g: u32,  // DWORD
        dwFlags: u32  // DWORD
    ) -> usize;
}
// crates: windows-sys provides ready-made bindings for this API.
$sig = @"
[DllImport("WS2_32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern UIntPtr WSASocketW(int af, int type, int protocol, IntPtr lpProtocolInfo, uint g, uint dwFlags);
"@
$api = Add-Type -MemberDefinition $sig -Name 'WS2_32_WSASocketW' -Namespace Win32 -PassThru
# $api::WSASocketW(af, type, protocol, lpProtocolInfo, g, dwFlags)
#uselib "WS2_32.dll"
#func global WSASocketW "WSASocketW" wptr, wptr, wptr, wptr, wptr, wptr
; WSASocketW af, type, protocol, varptr(lpProtocolInfo), g, dwFlags   ; 戻り値は stat
; af : INT -> "wptr"
; type : INT -> "wptr"
; protocol : INT -> "wptr"
; lpProtocolInfo : WSAPROTOCOL_INFOW* optional -> "wptr"
; g : DWORD -> "wptr"
; dwFlags : DWORD -> "wptr"
; ※HSP3.7は #func のため戻り値はシステム変数 stat に格納されます。
出力引数:
#uselib "WS2_32.dll"
#cfunc global WSASocketW "WSASocketW" int, int, int, var, int, int
; res = WSASocketW(af, type, protocol, lpProtocolInfo, g, dwFlags)
; af : INT -> "int"
; type : INT -> "int"
; protocol : INT -> "int"
; lpProtocolInfo : WSAPROTOCOL_INFOW* optional -> "var"
; g : DWORD -> "int"
; dwFlags : DWORD -> "int"
; ※出力/バッファ引数は var 方式(変数を直接渡す)。varptr 方式にも切替可。
出力引数:
; SOCKET WSASocketW(INT af, INT type, INT protocol, WSAPROTOCOL_INFOW* lpProtocolInfo, DWORD g, DWORD dwFlags)
#uselib "WS2_32.dll"
#cfunc global WSASocketW "WSASocketW" int, int, int, var, int, int
; res = WSASocketW(af, type, protocol, lpProtocolInfo, g, dwFlags)
; af : INT -> "int"
; type : INT -> "int"
; protocol : INT -> "int"
; lpProtocolInfo : WSAPROTOCOL_INFOW* optional -> "var"
; g : DWORD -> "int"
; dwFlags : DWORD -> "int"
; ※出力/バッファ引数は var 方式(変数を直接渡す)。varptr 方式にも切替可。
import (
	"golang.org/x/sys/windows"
	"unsafe"
)

var (
	ws2_32 = windows.NewLazySystemDLL("WS2_32.dll")
	procWSASocketW = ws2_32.NewProc("WSASocketW")
)

// af (INT), type (INT), protocol (INT), lpProtocolInfo (WSAPROTOCOL_INFOW* optional), g (DWORD), dwFlags (DWORD)
r1, _, err := procWSASocketW.Call(
	uintptr(af),
	uintptr(type),
	uintptr(protocol),
	uintptr(lpProtocolInfo),
	uintptr(g),
	uintptr(dwFlags),
)
_ = err  // syscall.Errno (valid when the call sets last-error)
_ = r1   // SOCKET
function WSASocketW(
  af: Integer;   // INT
  type: Integer;   // INT
  protocol: Integer;   // INT
  lpProtocolInfo: Pointer;   // WSAPROTOCOL_INFOW* optional
  g: DWORD;   // DWORD
  dwFlags: DWORD   // DWORD
): NativeUInt; stdcall;
  external 'WS2_32.dll' name 'WSASocketW';
result := DllCall("WS2_32\WSASocketW"
    , "Int", af   ; INT
    , "Int", type   ; INT
    , "Int", protocol   ; INT
    , "Ptr", lpProtocolInfo   ; WSAPROTOCOL_INFOW* optional
    , "UInt", g   ; DWORD
    , "UInt", dwFlags   ; DWORD
    , "UPtr")   ; return: SOCKET
●WSASocketW(af, type, protocol, lpProtocolInfo, g, dwFlags) = DLL("WS2_32.dll", "int WSASocketW(int, int, int, void*, dword, dword)")
# 呼び出し: WSASocketW(af, type, protocol, lpProtocolInfo, g, dwFlags)
# af : INT -> "int"
# type : INT -> "int"
# protocol : INT -> "int"
# lpProtocolInfo : WSAPROTOCOL_INFOW* optional -> "void*"
# g : DWORD -> "dword"
# dwFlags : DWORD -> "dword"
# なでしこ1は32bit・ANSI(Shift_JIS)。文字列=char*(ANSI)、ポインタ/ハンドル=void*(4byte)。
# ※-W(Unicode)関数。なでしこ1はANSIのため -A 版の利用を推奨。
const std = @import("std");

extern "ws2_32" fn WSASocketW(
    af: i32, // INT
    type: i32, // INT
    protocol: i32, // INT
    lpProtocolInfo: [*c]WSAPROTOCOL_INFOW, // WSAPROTOCOL_INFOW* optional
    g: u32, // DWORD
    dwFlags: u32 // DWORD
) callconv(std.os.windows.WINAPI) usize;
// Unicode(-W): UTF-16LE のヌル終端バッファ([*c]const u16)を渡す。
proc WSASocketW(
    af: int32,  # INT
    `type`: int32,  # INT
    protocol: int32,  # INT
    lpProtocolInfo: ptr WSAPROTOCOL_INFOW,  # WSAPROTOCOL_INFOW* optional
    g: uint32,  # DWORD
    dwFlags: uint32  # DWORD
): uint {.importc: "WSASocketW", stdcall, dynlib: "WS2_32.dll".}
# Unicode(-W): WideCString は newWideCString("...") で生成。
pragma(lib, "ws2_32");
extern(Windows)
size_t WSASocketW(
    int af,   // INT
    int type,   // INT
    int protocol,   // INT
    WSAPROTOCOL_INFOW* lpProtocolInfo,   // WSAPROTOCOL_INFOW* optional
    uint g,   // DWORD
    uint dwFlags   // DWORD
);
ccall((:WSASocketW, "WS2_32.dll"), stdcall, Csize_t,
      (Int32, Int32, Int32, Ptr{WSAPROTOCOL_INFOW}, UInt32, UInt32),
      af, type, protocol, lpProtocolInfo, g, dwFlags)
# af : INT -> Int32
# type : INT -> Int32
# protocol : INT -> Int32
# lpProtocolInfo : WSAPROTOCOL_INFOW* optional -> Ptr{WSAPROTOCOL_INFOW}
# g : DWORD -> UInt32
# dwFlags : DWORD -> UInt32
# stdcall は 32bit のみ意味を持つ(x64 では無視)。
# Unicode(-W): Cwstring には transcode(UInt16, "...") 等で UTF-16 を渡す。
local ffi = require("ffi")
ffi.cdef[[
uintptr_t WSASocketW(
    int32_t af,
    int32_t type,
    int32_t protocol,
    void* lpProtocolInfo,
    uint32_t g,
    uint32_t dwFlags);
]]
local ws2_32 = ffi.load("ws2_32")
-- ws2_32.WSASocketW(af, type, protocol, lpProtocolInfo, g, dwFlags)
-- af : INT
-- type : INT
-- protocol : INT
-- lpProtocolInfo : WSAPROTOCOL_INFOW* optional
-- g : DWORD
-- dwFlags : DWORD
-- 構造体/GUIDへのポインタは cdef が通るよう void* で表記(実型は各引数コメント参照)。値渡し構造体・enum は対応する typedef を cdef に追加すること。
-- Unicode(-W): uint16_t* には UTF-16LE のバッファ(ffi.new("uint16_t[?]", ...))を渡す。
const koffi = require('koffi');
const lib = koffi.load('WS2_32.dll');
const WSASocketW = lib.func('__stdcall', 'WSASocketW', 'uintptr_t', ['int32_t', 'int32_t', 'int32_t', 'void *', 'uint32_t', 'uint32_t']);
// WSASocketW(af, type, protocol, lpProtocolInfo, g, dwFlags)
// af : INT -> 'int32_t'
// type : INT -> 'int32_t'
// protocol : INT -> 'int32_t'
// lpProtocolInfo : WSAPROTOCOL_INFOW* optional -> 'void *'
// g : DWORD -> 'uint32_t'
// dwFlags : DWORD -> 'uint32_t'
// 出力ポインタは koffi.out(...) で包む。構造体は koffi.struct で定義。
const lib = Deno.dlopen("WS2_32.dll", {
  WSASocketW: { parameters: ["i32", "i32", "i32", "pointer", "u32", "u32"], result: "usize" },
});
// lib.symbols.WSASocketW(af, type, protocol, lpProtocolInfo, g, dwFlags)
// af : INT -> "i32"
// type : INT -> "i32"
// protocol : INT -> "i32"
// lpProtocolInfo : WSAPROTOCOL_INFOW* optional -> "pointer"
// g : DWORD -> "u32"
// dwFlags : DWORD -> "u32"
// 文字列は "buffer"。Unicode(-W) は new TextEncoder() ではなく UTF-16LE のバイト列(末尾に \x00\x00)を Uint8Array で渡す。
// 値渡し構造体は { struct: [ ...field types... ] } を使用。
<?php
$ffi = FFI::cdef(<<<C
size_t WSASocketW(
    int32_t af,
    int32_t type,
    int32_t protocol,
    void* lpProtocolInfo,
    uint32_t g,
    uint32_t dwFlags);
C, "WS2_32.dll");
// $ffi->WSASocketW(af, type, protocol, lpProtocolInfo, g, dwFlags);
// af : INT
// type : INT
// protocol : INT
// lpProtocolInfo : WSAPROTOCOL_INFOW* optional
// g : DWORD
// dwFlags : DWORD
// 構造体/GUIDへのポインタは cdef が通るよう void* で表記(実型は各引数コメント参照)。値渡し構造体・enum は対応する typedef を cdef に追加すること。
// WINAPI(stdcall): x64 では呼出規約が統一されるため問題なし。x86 では __stdcall 対応のラッパが必要な場合あり。
import com.sun.jna.*;
import com.sun.jna.ptr.*;
import com.sun.jna.win32.StdCallLibrary;
import com.sun.jna.win32.W32APIOptions;

public interface Ws2_32 extends StdCallLibrary {
    Ws2_32 INSTANCE = Native.load("ws2_32", Ws2_32.class, W32APIOptions.UNICODE_OPTIONS);
    long WSASocketW(
        int af,   // INT
        int type,   // INT
        int protocol,   // INT
        Pointer lpProtocolInfo,   // WSAPROTOCOL_INFOW* optional
        int g,   // DWORD
        int dwFlags   // DWORD
    );
}
// Unicode(-W): WString(入力)/char[](出力)で UTF-16 をマーシャリング。
@[Link("ws2_32")]
lib LibWS2_32
  fun WSASocketW = WSASocketW(
    af : Int32,   # INT
    type_ : Int32,   # INT
    protocol : Int32,   # INT
    lpProtocolInfo : WSAPROTOCOL_INFOW*,   # WSAPROTOCOL_INFOW* optional
    g : UInt32,   # DWORD
    dwFlags : UInt32   # DWORD
  ) : LibC::SizeT
end
# 構造体/GUID/enum は lib 内に対応する型定義が必要。
# 呼出規約: x64 は規約統一のため OK。x86(32bit)は WINAPI=stdcall だが Crystal の fun に stdcall 付与構文がなく非対応。
import 'dart:ffi';
import 'package:ffi/ffi.dart';

typedef WSASocketWNative = UintPtr Function(Int32, Int32, Int32, Pointer<Void>, Uint32, Uint32);
typedef WSASocketWDart = int Function(int, int, int, Pointer<Void>, int, int);
final WSASocketW = DynamicLibrary.open('WS2_32.dll')
    .lookupFunction<WSASocketWNative, WSASocketWDart>('WSASocketW');
// af : INT -> Int32
// type : INT -> Int32
// protocol : INT -> Int32
// lpProtocolInfo : WSAPROTOCOL_INFOW* optional -> Pointer<Void>
// g : DWORD -> Uint32
// dwFlags : DWORD -> Uint32
// 文字列は package:ffi の "...".toNativeUtf16()/toNativeUtf8() で変換。
{$mode objfpc}{$H+}
function WSASocketW(
  af: Integer;   // INT
  type: Integer;   // INT
  protocol: Integer;   // INT
  lpProtocolInfo: Pointer;   // WSAPROTOCOL_INFOW* optional
  g: DWORD;   // DWORD
  dwFlags: DWORD   // DWORD
): NativeUInt; stdcall;
  external 'WS2_32.dll' name 'WSASocketW';
import Foreign
import Foreign.C.Types
import Foreign.C.String

foreign import stdcall safe "WSASocketW"
  c_WSASocketW :: Int32 -> Int32 -> Int32 -> Ptr () -> Word32 -> Word32 -> IO CUIntPtr
-- af : INT -> Int32
-- type : INT -> Int32
-- protocol : INT -> Int32
-- lpProtocolInfo : WSAPROTOCOL_INFOW* optional -> Ptr ()
-- g : DWORD -> Word32
-- dwFlags : DWORD -> Word32
-- 要 GHC(Windows)。stdcall は x64 では ccall として扱われる。ブロックする API は safe 呼び出し推奨。
open Ctypes
open Foreign

let wsasocketw =
  foreign "WSASocketW"
    (int32_t @-> int32_t @-> int32_t @-> (ptr void) @-> uint32_t @-> uint32_t @-> returning size_t)
(* af : INT -> int32_t *)
(* type : INT -> int32_t *)
(* protocol : INT -> int32_t *)
(* lpProtocolInfo : WSAPROTOCOL_INFOW* optional -> (ptr void) *)
(* g : DWORD -> uint32_t *)
(* dwFlags : DWORD -> uint32_t *)
(* foreign は cdecl 前提。x64 Windows では WINAPI と一致。構造体は ctypes structure を定義のこと。 *)
(cffi:define-foreign-library ws2_32 (t "WS2_32.dll"))
(cffi:use-foreign-library ws2_32)

(cffi:defcfun ("WSASocketW" wsasocket-w :convention :stdcall) :uint64
  (af :int32)   ; INT
  (type :int32)   ; INT
  (protocol :int32)   ; INT
  (lp-protocol-info :pointer)   ; WSAPROTOCOL_INFOW* optional
  (g :uint32)   ; DWORD
  (dw-flags :uint32))   ; DWORD
; isize/usize(INT_PTR/SIZE_T)は x64 前提で :int64/:uint64。x86 では :int32/:uint32。
use Win32::API;
my $WSASocketW = Win32::API::More->new('WS2_32',
    'WPARAM WSASocketW(int af, int type, int protocol, LPVOID lpProtocolInfo, DWORD g, DWORD dwFlags)');
# my $ret = $WSASocketW->Call($af, $type, $protocol, $lpProtocolInfo, $g, $dwFlags);
# af : INT -> int
# type : INT -> int
# protocol : INT -> int
# lpProtocolInfo : WSAPROTOCOL_INFOW* optional -> LPVOID
# g : DWORD -> DWORD
# dwFlags : DWORD -> DWORD
# 値渡し構造体は pack() した文字列、または Win32::API::Struct を使用。
# Unicode(-W): LPCWSTR/LPWSTR は Win32::API が UTF-16 変換を行う。

関連項目

文字セット違い
公式の関連項目
使用する型