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

WSANSPIoctl

関数
名前空間プロバイダーに対する制御操作を実行する。
DLLWS2_32.dll呼出規約winapiSetLastErrorあり対応OSWindows 8.1 以降

シグネチャ

// WS2_32.dll
#include <windows.h>

INT WSANSPIoctl(
    HANDLE hLookup,
    DWORD dwControlCode,
    void* lpvInBuffer,   // optional
    DWORD cbInBuffer,
    void* lpvOutBuffer,   // optional
    DWORD cbOutBuffer,
    DWORD* lpcbBytesReturned,
    WSACOMPLETION* lpCompletion   // optional
);

パラメーター

名前方向説明
hLookupHANDLEin以前の WSALookupServiceBegin 関数の呼び出しから返されたルックアップ ハンドル。
dwControlCodeDWORDin

実行する操作の制御コード。

dwControlCode パラメーターに使用できる値は、ネームスペース プロバイダーによって決まります。

次の値は、Network Location Awareness (NS_NLA) ネームスペース プロバイダーを含む複数の Microsoft ネームスペース プロバイダーでサポートされています。この IOCTL は Winsock2.h ヘッダー ファイルで定義されています。

意味
SIO_NSP_NOTIFY_CHANGE
この操作は、hLookup パラメーターを使用した以前の呼び出しで返された結果がまだ有効かどうかを確認します。これらの以前の呼び出しには、hLookup パラメーターを取得するための最初の WSALookupServiceBegin 関数の呼び出しが含まれます。また、hLookup パラメーターを使用した WSALookupServiceNext 関数の呼び出しも含まれる場合があります。
lpvInBuffervoid*inoptional入力バッファーへのポインター。
cbInBufferDWORDin入力バッファーのサイズ (バイト単位)。
lpvOutBuffervoid*outoptional出力バッファーへのポインター。
cbOutBufferDWORDin出力バッファーのサイズ (バイト単位)。
lpcbBytesReturnedDWORD*out返されたバイト数へのポインター。
lpCompletionWSACOMPLETION*inoptional非同期処理に使用される WSACOMPLETION 構造体へのポインター。ブロッキング (同期) 実行を強制するには、lpCompletionNULL に設定します。

戻り値の型: INT

公式ドキュメント

登録済みのネームスペースに対して I/O 制御呼び出しを行えるようにします。

戻り値

成功した場合は NO_ERROR を返します。失敗した場合は SOCKET_ERROR を返し、特定のエラー コードは WSAGetLastError 関数を呼び出すことで取得できます。次の表にエラー コードを示します。

エラー コード 説明
WSA_INVALID_HANDLE
hLookup パラメーターが、 WSALookupServiceBegin によって返された有効なクエリ ハンドルではありませんでした。
WSA_IO_PENDING
オーバーラップ操作が正常に開始され、完了は後で通知されます。
WSAEFAULT
lpvInBuffercbInBufferlpvOutBuffercbOutBuffer、または lpCompletion 引数が、ユーザー アドレス空間の有効な部分に完全には含まれていません。あるいは、cbInBuffer または cbOutBuffer 引数が小さすぎるため、必要な割り当てサイズを反映するように引数が変更されます。
WSAEINVAL
指定されたパラメーターが受け入れられないか、指定された操作にとって意味をなさないにもかかわらず、操作が複数のネームスペースから不適切に結果を返しています。
WSAENETDOWN
ネットワーク サブシステムが失敗しました。
WSAEOPNOTSUPP
操作はサポートされていません。このエラーは、ネームスペース プロバイダーがこの関数を実装していない場合に返されます。また、指定された dwControlCode が認識されないコマンドである場合にも返されることがあります。
WSAEWOULDBLOCK
ソケットがオーバーラップ I/O (非同期処理) を使用していないにもかかわらず、lpCompletion パラメーターが非 NULL です。

このエラーは、lpCompletion パラメーターが NULL (ポーリング) の場合に SIO_NSP_NOTIFY_CHANGE IOCTL の特別な通知として使用され、クエリ セットが依然として有効であることを示します。

解説(Remarks)

WSANSPIoctl 関数は、ネームスペース プロバイダーへのクエリ ハンドルに関連付けられた動作パラメーターの設定または取得に使用されます。hLookup パラメーターは、以前に WSALookupServiceBegin 関数によって返されたネームスペース プロバイダー クエリへのハンドルです (ソケット ハンドルではありません)。

ネームスペース プロバイダーに送信された IOCTL は、ネームスペースの実装によっては無期限にブロックされる可能性があります。アプリケーションが WSANSPIoctl 関数呼び出しでのブロッキングを許容できない場合は、オーバーラップ I/O を使用し、lpCompletion パラメーターが WSACOMPLETION 構造体を指すようにする必要があります。 WSANSPIoctl 関数呼び出しを非ブロッキングにしてすぐに戻すには、WSACOMPLETION 構造体の Type メンバーを NSP_NOTIFY_IMMEDIATELY に設定します。

lpCompletionNULL の場合、 WSANSPIoctl 関数はブロッキング呼び出しとして実行されます。ネームスペース プロバイダーはすぐに戻り、ブロックすべきではありません。ただし、この動作の強制は各ネームスペースの責任です。

次の IOCTL コードは、複数の Microsoft ネームスペース プロバイダーでサポートされています。

SIO_NSP_NOTIFY_CHANGE
この操作は、hLookup パラメーターを使用した以前の呼び出しで返された結果がまだ有効かどうかを確認します。これらの以前の呼び出しには、hLookup パラメーターを取得するための最初の WSALookupServiceBegin 関数の呼び出しが含まれます。また、hLookup パラメーターを使用した WSALookupServiceNext 関数の呼び出しも含まれる場合があります。

この IOCTL をサポートする Microsoft ネームスペース プロバイダーには次のものが含まれます。

  • NS_NLA - Network Location Awareness (NLA) ネームスペース プロバイダー。
  • NS_PNRPNAME - Peer Name Resolution Protocol (PNRP) ネームスペース プロバイダー。
  • NS_PNRPCLOUD - Peer Name Resolution Protocol (PNRP) クラウド ネームスペース プロバイダー。

この IOCTL をサポートする Microsoft 以外のネームスペース プロバイダーがインストールされている場合もあります。

lpCompletion パラメーターが NULL の場合、この IOCTL は特別な動作を実装します。この IOCTL で lpCompletion パラメーターが NULL の場合、この操作はポーリングであり、すぐに戻ります。クエリ セットが依然として有効な場合は、 WSAEWOULDBLOCK が、クエリ セットが依然として有効であることを示す通知として返されます。クエリ セットが変更されて無効になった場合は、NO_ERROR が返され、クエリ セットの無効化のポーリングが成功したことを示します。

lpCompletion パラメーターが NULL ではなく、WSACOMPLETION 構造体を指している場合、WSANSPIoctl 関数は、オーバーラップ操作が正常に開始され完了が後で通知されるときに WSA_IO_PENDING を返します。WSACOMPLETION 構造体で指定されたメソッドは、クエリ セットがまだ有効かどうかをアプリケーションに通知するために使用されます。

すべての名前解決プロトコルがこの機能をサポートできるわけではないため、この関数呼び出しは WSAEOPNOTSUPP で失敗する場合があります。複数のプロバイダーからのデータを含むクエリはこの IOCTL を呼び出すことができず、 WSAEINVAL を返します。

lpvInBuffercbInBufferlpvOutBuffer、および cbOutBuffer パラメーターは、現在 Microsoft ネームスペース プロバイダーによって無視されます。

シングルスレッド アプリケーションの場合、WSANSPIoctl 関数を使用する一般的な方法は次のとおりです。クエリ データがまだ有効であることを確認するため、各 WSALookupServiceNext 関数呼び出しの後に、dwControlCode パラメーターを SIO_NSP_NOTIFY_CHANGE に設定し、完了ルーチンを指定せずに (lpCompletion パラメーターを NULL に設定して) WSANSPIoctl 関数を呼び出します。データが無効になった場合は、WSALookupServiceEnd 関数を呼び出してクエリ ハンドルを閉じます。WSALookupServiceBegin 関数を呼び出して新しいクエリ ハンドルを取得し、クエリを再度開始します。

マルチスレッド アプリケーションの場合、WSANSPIoctl 関数を使用する一般的な方法は次のとおりです。最初の WSALookupServiceBegin 関数呼び出しの後に、dwControlCode パラメーターを SIO_NSP_NOTIFY_CHANGE に設定し、完了ルーチンを指定して WSANSPIoctl 関数を呼び出します。アプリケーションは、データが有効でなくなったときに通知を受け取るために、完了ルーチンで指定された通知メカニズムを使用します。一般的なメカニズムの 1 つは、完了ルーチンで指定されたイベントを使用することです。データが無効になった場合は、WSALookupServiceEnd 関数を呼び出してクエリ ハンドルを閉じます。WSALookupServiceBegin 関数と WSANSPIoctl 関数を呼び出して新しいクエリ ハンドルを取得し、クエリを再度開始します。

プロトコルによっては、単に情報をローカルにキャッシュし、一定時間後に無効化するものもあります。この場合、ローカル キャッシュが無効化されたことを示す通知が発行されることがあります。

変更が頻繁でない名前解決プロトコルの場合、ネームスペース プロバイダーが、変更通知が要求および発行されたクエリには適用されない可能性のあるグローバルな変更イベントを示すことがあります。

即時ポーリング操作は通常、通知オブジェクトを必要としないため、はるかにコストが低くなります。ほとんどの場合、これは単純なブール変数のチェックとして実装されます。一方、非同期通知では、ネームスペース プロバイダー サービスの実装によっては専用のワーカー スレッドやプロセス間通信チャネルの作成が必要になることがあり、変更イベントの通知に関わる通知オブジェクトに関連する処理オーバーヘッドが発生します。

非同期通知要求をキャンセルするには、対象のクエリ ハンドルに対して WSALookupServiceEnd 関数呼び出しで元のクエリを終了します。LUP_NOTIFY_HWND の非同期通知をキャンセルしてもメッセージは送信されませんが、オーバーラップ操作は完了し、エラー WSA_OPERATION_ABORTED とともに通知が配信されます。

注意 特定のスレッドによって開始されたすべての I/O は、そのスレッドが終了するときにキャンセルされます。オーバーラップ ソケットの場合、操作が完了する前にスレッドが閉じられると、保留中の非同期操作が失敗することがあります。詳細については、ExitThread を参照してください。
Windows Phone 8: この関数は、Windows Phone 8 以降の Windows Phone ストア アプリでサポートされています。

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

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

各言語での呼び出し定義

// WS2_32.dll
#include <windows.h>

INT WSANSPIoctl(
    HANDLE hLookup,
    DWORD dwControlCode,
    void* lpvInBuffer,   // optional
    DWORD cbInBuffer,
    void* lpvOutBuffer,   // optional
    DWORD cbOutBuffer,
    DWORD* lpcbBytesReturned,
    WSACOMPLETION* lpCompletion   // optional
);
[DllImport("WS2_32.dll", SetLastError = true, ExactSpelling = true)]
static extern int WSANSPIoctl(
    IntPtr hLookup,   // HANDLE
    uint dwControlCode,   // DWORD
    IntPtr lpvInBuffer,   // void* optional
    uint cbInBuffer,   // DWORD
    IntPtr lpvOutBuffer,   // void* optional, out
    uint cbOutBuffer,   // DWORD
    out uint lpcbBytesReturned,   // DWORD* out
    IntPtr lpCompletion   // WSACOMPLETION* optional
);
<DllImport("WS2_32.dll", SetLastError:=True, ExactSpelling:=True)>
Public Shared Function WSANSPIoctl(
    hLookup As IntPtr,   ' HANDLE
    dwControlCode As UInteger,   ' DWORD
    lpvInBuffer As IntPtr,   ' void* optional
    cbInBuffer As UInteger,   ' DWORD
    lpvOutBuffer As IntPtr,   ' void* optional, out
    cbOutBuffer As UInteger,   ' DWORD
    <Out> ByRef lpcbBytesReturned As UInteger,   ' DWORD* out
    lpCompletion As IntPtr   ' WSACOMPLETION* optional
) As Integer
End Function
' hLookup : HANDLE
' dwControlCode : DWORD
' lpvInBuffer : void* optional
' cbInBuffer : DWORD
' lpvOutBuffer : void* optional, out
' cbOutBuffer : DWORD
' lpcbBytesReturned : DWORD* out
' lpCompletion : WSACOMPLETION* optional
Declare PtrSafe Function WSANSPIoctl Lib "ws2_32" ( _
    ByVal hLookup As LongPtr, _
    ByVal dwControlCode As Long, _
    ByVal lpvInBuffer As LongPtr, _
    ByVal cbInBuffer As Long, _
    ByVal lpvOutBuffer As LongPtr, _
    ByVal cbOutBuffer As Long, _
    ByRef lpcbBytesReturned As Long, _
    ByVal lpCompletion As LongPtr) As Long
' VBA7前提(PtrSafe)。32bit Office では LongPtr→Long。Integer=16bit / Long=32bit / LongLong=64bit。
import ctypes
from ctypes import wintypes

WSANSPIoctl = ctypes.windll.ws2_32.WSANSPIoctl
WSANSPIoctl.restype = ctypes.c_int
WSANSPIoctl.argtypes = [
    wintypes.HANDLE,  # hLookup : HANDLE
    wintypes.DWORD,  # dwControlCode : DWORD
    ctypes.POINTER(None),  # lpvInBuffer : void* optional
    wintypes.DWORD,  # cbInBuffer : DWORD
    ctypes.POINTER(None),  # lpvOutBuffer : void* optional, out
    wintypes.DWORD,  # cbOutBuffer : DWORD
    ctypes.POINTER(wintypes.DWORD),  # lpcbBytesReturned : DWORD* out
    ctypes.c_void_p,  # lpCompletion : WSACOMPLETION* optional
]
# GetLastError: use ctypes.GetLastError() (or ctypes.WinDLL(use_last_error=True))
require 'fiddle'
require 'fiddle/import'

lib = Fiddle.dlopen('WS2_32.dll')
WSANSPIoctl = Fiddle::Function.new(
  lib['WSANSPIoctl'],
  [
    Fiddle::TYPE_VOIDP,  # hLookup : HANDLE
    -Fiddle::TYPE_INT,  # dwControlCode : DWORD
    Fiddle::TYPE_VOIDP,  # lpvInBuffer : void* optional
    -Fiddle::TYPE_INT,  # cbInBuffer : DWORD
    Fiddle::TYPE_VOIDP,  # lpvOutBuffer : void* optional, out
    -Fiddle::TYPE_INT,  # cbOutBuffer : DWORD
    Fiddle::TYPE_VOIDP,  # lpcbBytesReturned : DWORD* out
    Fiddle::TYPE_VOIDP,  # lpCompletion : WSACOMPLETION* optional
  ],
  Fiddle::TYPE_INT)
#[link(name = "ws2_32")]
extern "system" {
    fn WSANSPIoctl(
        hLookup: *mut core::ffi::c_void,  // HANDLE
        dwControlCode: u32,  // DWORD
        lpvInBuffer: *mut (),  // void* optional
        cbInBuffer: u32,  // DWORD
        lpvOutBuffer: *mut (),  // void* optional, out
        cbOutBuffer: u32,  // DWORD
        lpcbBytesReturned: *mut u32,  // DWORD* out
        lpCompletion: *mut WSACOMPLETION  // WSACOMPLETION* optional
    ) -> i32;
}
// crates: windows-sys provides ready-made bindings for this API.
$sig = @"
[DllImport("WS2_32.dll", SetLastError = true)]
public static extern int WSANSPIoctl(IntPtr hLookup, uint dwControlCode, IntPtr lpvInBuffer, uint cbInBuffer, IntPtr lpvOutBuffer, uint cbOutBuffer, out uint lpcbBytesReturned, IntPtr lpCompletion);
"@
$api = Add-Type -MemberDefinition $sig -Name 'WS2_32_WSANSPIoctl' -Namespace Win32 -PassThru
# $api::WSANSPIoctl(hLookup, dwControlCode, lpvInBuffer, cbInBuffer, lpvOutBuffer, cbOutBuffer, lpcbBytesReturned, lpCompletion)
#uselib "WS2_32.dll"
#func global WSANSPIoctl "WSANSPIoctl" sptr, sptr, sptr, sptr, sptr, sptr, sptr, sptr
; WSANSPIoctl hLookup, dwControlCode, lpvInBuffer, cbInBuffer, lpvOutBuffer, cbOutBuffer, varptr(lpcbBytesReturned), varptr(lpCompletion)   ; 戻り値は stat
; hLookup : HANDLE -> "sptr"
; dwControlCode : DWORD -> "sptr"
; lpvInBuffer : void* optional -> "sptr"
; cbInBuffer : DWORD -> "sptr"
; lpvOutBuffer : void* optional, out -> "sptr"
; cbOutBuffer : DWORD -> "sptr"
; lpcbBytesReturned : DWORD* out -> "sptr"
; lpCompletion : WSACOMPLETION* optional -> "sptr"
; ※HSP3.7は #func のため戻り値はシステム変数 stat に格納されます。
出力引数:
#uselib "WS2_32.dll"
#cfunc global WSANSPIoctl "WSANSPIoctl" sptr, int, sptr, int, sptr, int, var, var
; res = WSANSPIoctl(hLookup, dwControlCode, lpvInBuffer, cbInBuffer, lpvOutBuffer, cbOutBuffer, lpcbBytesReturned, lpCompletion)
; hLookup : HANDLE -> "sptr"
; dwControlCode : DWORD -> "int"
; lpvInBuffer : void* optional -> "sptr"
; cbInBuffer : DWORD -> "int"
; lpvOutBuffer : void* optional, out -> "sptr"
; cbOutBuffer : DWORD -> "int"
; lpcbBytesReturned : DWORD* out -> "var"
; lpCompletion : WSACOMPLETION* optional -> "var"
; ※出力/バッファ引数は var 方式(変数を直接渡す)。varptr 方式にも切替可。
出力引数:
; INT WSANSPIoctl(HANDLE hLookup, DWORD dwControlCode, void* lpvInBuffer, DWORD cbInBuffer, void* lpvOutBuffer, DWORD cbOutBuffer, DWORD* lpcbBytesReturned, WSACOMPLETION* lpCompletion)
#uselib "WS2_32.dll"
#cfunc global WSANSPIoctl "WSANSPIoctl" intptr, int, intptr, int, intptr, int, var, var
; res = WSANSPIoctl(hLookup, dwControlCode, lpvInBuffer, cbInBuffer, lpvOutBuffer, cbOutBuffer, lpcbBytesReturned, lpCompletion)
; hLookup : HANDLE -> "intptr"
; dwControlCode : DWORD -> "int"
; lpvInBuffer : void* optional -> "intptr"
; cbInBuffer : DWORD -> "int"
; lpvOutBuffer : void* optional, out -> "intptr"
; cbOutBuffer : DWORD -> "int"
; lpcbBytesReturned : DWORD* out -> "var"
; lpCompletion : WSACOMPLETION* optional -> "var"
; ※出力/バッファ引数は var 方式(変数を直接渡す)。varptr 方式にも切替可。
import (
	"golang.org/x/sys/windows"
	"unsafe"
)

var (
	ws2_32 = windows.NewLazySystemDLL("WS2_32.dll")
	procWSANSPIoctl = ws2_32.NewProc("WSANSPIoctl")
)

// hLookup (HANDLE), dwControlCode (DWORD), lpvInBuffer (void* optional), cbInBuffer (DWORD), lpvOutBuffer (void* optional, out), cbOutBuffer (DWORD), lpcbBytesReturned (DWORD* out), lpCompletion (WSACOMPLETION* optional)
r1, _, err := procWSANSPIoctl.Call(
	uintptr(hLookup),
	uintptr(dwControlCode),
	uintptr(lpvInBuffer),
	uintptr(cbInBuffer),
	uintptr(lpvOutBuffer),
	uintptr(cbOutBuffer),
	uintptr(lpcbBytesReturned),
	uintptr(lpCompletion),
)
_ = err  // syscall.Errno (valid when the call sets last-error)
_ = r1   // INT
function WSANSPIoctl(
  hLookup: THandle;   // HANDLE
  dwControlCode: DWORD;   // DWORD
  lpvInBuffer: Pointer;   // void* optional
  cbInBuffer: DWORD;   // DWORD
  lpvOutBuffer: Pointer;   // void* optional, out
  cbOutBuffer: DWORD;   // DWORD
  lpcbBytesReturned: Pointer;   // DWORD* out
  lpCompletion: Pointer   // WSACOMPLETION* optional
): Integer; stdcall;
  external 'WS2_32.dll' name 'WSANSPIoctl';
result := DllCall("WS2_32\WSANSPIoctl"
    , "Ptr", hLookup   ; HANDLE
    , "UInt", dwControlCode   ; DWORD
    , "Ptr", lpvInBuffer   ; void* optional
    , "UInt", cbInBuffer   ; DWORD
    , "Ptr", lpvOutBuffer   ; void* optional, out
    , "UInt", cbOutBuffer   ; DWORD
    , "Ptr", lpcbBytesReturned   ; DWORD* out
    , "Ptr", lpCompletion   ; WSACOMPLETION* optional
    , "Int")   ; return: INT
●WSANSPIoctl(hLookup, dwControlCode, lpvInBuffer, cbInBuffer, lpvOutBuffer, cbOutBuffer, lpcbBytesReturned, lpCompletion) = DLL("WS2_32.dll", "int WSANSPIoctl(void*, dword, void*, dword, void*, dword, void*, void*)")
# 呼び出し: WSANSPIoctl(hLookup, dwControlCode, lpvInBuffer, cbInBuffer, lpvOutBuffer, cbOutBuffer, lpcbBytesReturned, lpCompletion)
# hLookup : HANDLE -> "void*"
# dwControlCode : DWORD -> "dword"
# lpvInBuffer : void* optional -> "void*"
# cbInBuffer : DWORD -> "dword"
# lpvOutBuffer : void* optional, out -> "void*"
# cbOutBuffer : DWORD -> "dword"
# lpcbBytesReturned : DWORD* out -> "void*"
# lpCompletion : WSACOMPLETION* optional -> "void*"
# なでしこ1は32bit・ANSI(Shift_JIS)。文字列=char*(ANSI)、ポインタ/ハンドル=void*(4byte)。
const std = @import("std");

extern "ws2_32" fn WSANSPIoctl(
    hLookup: ?*anyopaque, // HANDLE
    dwControlCode: u32, // DWORD
    lpvInBuffer: ?*anyopaque, // void* optional
    cbInBuffer: u32, // DWORD
    lpvOutBuffer: ?*anyopaque, // void* optional, out
    cbOutBuffer: u32, // DWORD
    lpcbBytesReturned: [*c]u32, // DWORD* out
    lpCompletion: [*c]WSACOMPLETION // WSACOMPLETION* optional
) callconv(std.os.windows.WINAPI) i32;
proc WSANSPIoctl(
    hLookup: pointer,  # HANDLE
    dwControlCode: uint32,  # DWORD
    lpvInBuffer: pointer,  # void* optional
    cbInBuffer: uint32,  # DWORD
    lpvOutBuffer: pointer,  # void* optional, out
    cbOutBuffer: uint32,  # DWORD
    lpcbBytesReturned: ptr uint32,  # DWORD* out
    lpCompletion: ptr WSACOMPLETION  # WSACOMPLETION* optional
): int32 {.importc: "WSANSPIoctl", stdcall, dynlib: "WS2_32.dll".}
pragma(lib, "ws2_32");
extern(Windows)
int WSANSPIoctl(
    void* hLookup,   // HANDLE
    uint dwControlCode,   // DWORD
    void* lpvInBuffer,   // void* optional
    uint cbInBuffer,   // DWORD
    void* lpvOutBuffer,   // void* optional, out
    uint cbOutBuffer,   // DWORD
    uint* lpcbBytesReturned,   // DWORD* out
    WSACOMPLETION* lpCompletion   // WSACOMPLETION* optional
);
ccall((:WSANSPIoctl, "WS2_32.dll"), stdcall, Int32,
      (Ptr{Cvoid}, UInt32, Ptr{Cvoid}, UInt32, Ptr{Cvoid}, UInt32, Ptr{UInt32}, Ptr{WSACOMPLETION}),
      hLookup, dwControlCode, lpvInBuffer, cbInBuffer, lpvOutBuffer, cbOutBuffer, lpcbBytesReturned, lpCompletion)
# hLookup : HANDLE -> Ptr{Cvoid}
# dwControlCode : DWORD -> UInt32
# lpvInBuffer : void* optional -> Ptr{Cvoid}
# cbInBuffer : DWORD -> UInt32
# lpvOutBuffer : void* optional, out -> Ptr{Cvoid}
# cbOutBuffer : DWORD -> UInt32
# lpcbBytesReturned : DWORD* out -> Ptr{UInt32}
# lpCompletion : WSACOMPLETION* optional -> Ptr{WSACOMPLETION}
# stdcall は 32bit のみ意味を持つ(x64 では無視)。
local ffi = require("ffi")
ffi.cdef[[
int32_t WSANSPIoctl(
    void* hLookup,
    uint32_t dwControlCode,
    void* lpvInBuffer,
    uint32_t cbInBuffer,
    void* lpvOutBuffer,
    uint32_t cbOutBuffer,
    uint32_t* lpcbBytesReturned,
    void* lpCompletion);
]]
local ws2_32 = ffi.load("ws2_32")
-- ws2_32.WSANSPIoctl(hLookup, dwControlCode, lpvInBuffer, cbInBuffer, lpvOutBuffer, cbOutBuffer, lpcbBytesReturned, lpCompletion)
-- hLookup : HANDLE
-- dwControlCode : DWORD
-- lpvInBuffer : void* optional
-- cbInBuffer : DWORD
-- lpvOutBuffer : void* optional, out
-- cbOutBuffer : DWORD
-- lpcbBytesReturned : DWORD* out
-- lpCompletion : WSACOMPLETION* optional
-- 構造体/GUIDへのポインタは cdef が通るよう void* で表記(実型は各引数コメント参照)。値渡し構造体・enum は対応する typedef を cdef に追加すること。
const koffi = require('koffi');
const lib = koffi.load('WS2_32.dll');
const WSANSPIoctl = lib.func('__stdcall', 'WSANSPIoctl', 'int32_t', ['void *', 'uint32_t', 'void *', 'uint32_t', 'void *', 'uint32_t', 'uint32_t *', 'void *']);
// WSANSPIoctl(hLookup, dwControlCode, lpvInBuffer, cbInBuffer, lpvOutBuffer, cbOutBuffer, lpcbBytesReturned, lpCompletion)
// hLookup : HANDLE -> 'void *'
// dwControlCode : DWORD -> 'uint32_t'
// lpvInBuffer : void* optional -> 'void *'
// cbInBuffer : DWORD -> 'uint32_t'
// lpvOutBuffer : void* optional, out -> 'void *'
// cbOutBuffer : DWORD -> 'uint32_t'
// lpcbBytesReturned : DWORD* out -> 'uint32_t *'
// lpCompletion : WSACOMPLETION* optional -> 'void *'
// 出力ポインタは koffi.out(...) で包む。構造体は koffi.struct で定義。
const lib = Deno.dlopen("WS2_32.dll", {
  WSANSPIoctl: { parameters: ["pointer", "u32", "pointer", "u32", "pointer", "u32", "pointer", "pointer"], result: "i32" },
});
// lib.symbols.WSANSPIoctl(hLookup, dwControlCode, lpvInBuffer, cbInBuffer, lpvOutBuffer, cbOutBuffer, lpcbBytesReturned, lpCompletion)
// hLookup : HANDLE -> "pointer"
// dwControlCode : DWORD -> "u32"
// lpvInBuffer : void* optional -> "pointer"
// cbInBuffer : DWORD -> "u32"
// lpvOutBuffer : void* optional, out -> "pointer"
// cbOutBuffer : DWORD -> "u32"
// lpcbBytesReturned : DWORD* out -> "pointer"
// lpCompletion : WSACOMPLETION* optional -> "pointer"
// 文字列引数は "buffer"(NUL 終端のバイト列を Uint8Array で渡す)。
// 値渡し構造体は { struct: [ ...field types... ] } を使用。
<?php
$ffi = FFI::cdef(<<<C
int32_t WSANSPIoctl(
    void* hLookup,
    uint32_t dwControlCode,
    void* lpvInBuffer,
    uint32_t cbInBuffer,
    void* lpvOutBuffer,
    uint32_t cbOutBuffer,
    uint32_t* lpcbBytesReturned,
    void* lpCompletion);
C, "WS2_32.dll");
// $ffi->WSANSPIoctl(hLookup, dwControlCode, lpvInBuffer, cbInBuffer, lpvOutBuffer, cbOutBuffer, lpcbBytesReturned, lpCompletion);
// hLookup : HANDLE
// dwControlCode : DWORD
// lpvInBuffer : void* optional
// cbInBuffer : DWORD
// lpvOutBuffer : void* optional, out
// cbOutBuffer : DWORD
// lpcbBytesReturned : DWORD* out
// lpCompletion : WSACOMPLETION* optional
// 構造体/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);
    int WSANSPIoctl(
        Pointer hLookup,   // HANDLE
        int dwControlCode,   // DWORD
        Pointer lpvInBuffer,   // void* optional
        int cbInBuffer,   // DWORD
        Pointer lpvOutBuffer,   // void* optional, out
        int cbOutBuffer,   // DWORD
        IntByReference lpcbBytesReturned,   // DWORD* out
        Pointer lpCompletion   // WSACOMPLETION* optional
    );
}
@[Link("ws2_32")]
lib LibWS2_32
  fun WSANSPIoctl = WSANSPIoctl(
    hLookup : Void*,   # HANDLE
    dwControlCode : UInt32,   # DWORD
    lpvInBuffer : Void*,   # void* optional
    cbInBuffer : UInt32,   # DWORD
    lpvOutBuffer : Void*,   # void* optional, out
    cbOutBuffer : UInt32,   # DWORD
    lpcbBytesReturned : UInt32*,   # DWORD* out
    lpCompletion : WSACOMPLETION*   # WSACOMPLETION* optional
  ) : Int32
end
# 構造体/GUID/enum は lib 内に対応する型定義が必要。
# 呼出規約: x64 は規約統一のため OK。x86(32bit)は WINAPI=stdcall だが Crystal の fun に stdcall 付与構文がなく非対応。
import 'dart:ffi';
import 'package:ffi/ffi.dart';

typedef WSANSPIoctlNative = Int32 Function(Pointer<Void>, Uint32, Pointer<Void>, Uint32, Pointer<Void>, Uint32, Pointer<Uint32>, Pointer<Void>);
typedef WSANSPIoctlDart = int Function(Pointer<Void>, int, Pointer<Void>, int, Pointer<Void>, int, Pointer<Uint32>, Pointer<Void>);
final WSANSPIoctl = DynamicLibrary.open('WS2_32.dll')
    .lookupFunction<WSANSPIoctlNative, WSANSPIoctlDart>('WSANSPIoctl');
// hLookup : HANDLE -> Pointer<Void>
// dwControlCode : DWORD -> Uint32
// lpvInBuffer : void* optional -> Pointer<Void>
// cbInBuffer : DWORD -> Uint32
// lpvOutBuffer : void* optional, out -> Pointer<Void>
// cbOutBuffer : DWORD -> Uint32
// lpcbBytesReturned : DWORD* out -> Pointer<Uint32>
// lpCompletion : WSACOMPLETION* optional -> Pointer<Void>
// 文字列は package:ffi の "...".toNativeUtf16()/toNativeUtf8() で変換。
{$mode objfpc}{$H+}
function WSANSPIoctl(
  hLookup: THandle;   // HANDLE
  dwControlCode: DWORD;   // DWORD
  lpvInBuffer: Pointer;   // void* optional
  cbInBuffer: DWORD;   // DWORD
  lpvOutBuffer: Pointer;   // void* optional, out
  cbOutBuffer: DWORD;   // DWORD
  lpcbBytesReturned: Pointer;   // DWORD* out
  lpCompletion: Pointer   // WSACOMPLETION* optional
): Integer; stdcall;
  external 'WS2_32.dll' name 'WSANSPIoctl';
import Foreign
import Foreign.C.Types
import Foreign.C.String

foreign import stdcall safe "WSANSPIoctl"
  c_WSANSPIoctl :: Ptr () -> Word32 -> Ptr () -> Word32 -> Ptr () -> Word32 -> Ptr Word32 -> Ptr () -> IO Int32
-- hLookup : HANDLE -> Ptr ()
-- dwControlCode : DWORD -> Word32
-- lpvInBuffer : void* optional -> Ptr ()
-- cbInBuffer : DWORD -> Word32
-- lpvOutBuffer : void* optional, out -> Ptr ()
-- cbOutBuffer : DWORD -> Word32
-- lpcbBytesReturned : DWORD* out -> Ptr Word32
-- lpCompletion : WSACOMPLETION* optional -> Ptr ()
-- 要 GHC(Windows)。stdcall は x64 では ccall として扱われる。ブロックする API は safe 呼び出し推奨。
open Ctypes
open Foreign

let wsanspioctl =
  foreign "WSANSPIoctl"
    ((ptr void) @-> uint32_t @-> (ptr void) @-> uint32_t @-> (ptr void) @-> uint32_t @-> (ptr uint32_t) @-> (ptr void) @-> returning int32_t)
(* hLookup : HANDLE -> (ptr void) *)
(* dwControlCode : DWORD -> uint32_t *)
(* lpvInBuffer : void* optional -> (ptr void) *)
(* cbInBuffer : DWORD -> uint32_t *)
(* lpvOutBuffer : void* optional, out -> (ptr void) *)
(* cbOutBuffer : DWORD -> uint32_t *)
(* lpcbBytesReturned : DWORD* out -> (ptr uint32_t) *)
(* lpCompletion : WSACOMPLETION* optional -> (ptr void) *)
(* 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 ("WSANSPIoctl" wsanspioctl :convention :stdcall) :int32
  (h-lookup :pointer)   ; HANDLE
  (dw-control-code :uint32)   ; DWORD
  (lpv-in-buffer :pointer)   ; void* optional
  (cb-in-buffer :uint32)   ; DWORD
  (lpv-out-buffer :pointer)   ; void* optional, out
  (cb-out-buffer :uint32)   ; DWORD
  (lpcb-bytes-returned :pointer)   ; DWORD* out
  (lp-completion :pointer))   ; WSACOMPLETION* optional
; isize/usize(INT_PTR/SIZE_T)は x64 前提で :int64/:uint64。x86 では :int32/:uint32。
use Win32::API;
my $WSANSPIoctl = Win32::API::More->new('WS2_32',
    'int WSANSPIoctl(HANDLE hLookup, DWORD dwControlCode, LPVOID lpvInBuffer, DWORD cbInBuffer, LPVOID lpvOutBuffer, DWORD cbOutBuffer, LPVOID lpcbBytesReturned, LPVOID lpCompletion)');
# my $ret = $WSANSPIoctl->Call($hLookup, $dwControlCode, $lpvInBuffer, $cbInBuffer, $lpvOutBuffer, $cbOutBuffer, $lpcbBytesReturned, $lpCompletion);
# hLookup : HANDLE -> HANDLE
# dwControlCode : DWORD -> DWORD
# lpvInBuffer : void* optional -> LPVOID
# cbInBuffer : DWORD -> DWORD
# lpvOutBuffer : void* optional, out -> LPVOID
# cbOutBuffer : DWORD -> DWORD
# lpcbBytesReturned : DWORD* out -> LPVOID
# lpCompletion : WSACOMPLETION* optional -> LPVOID
# 値渡し構造体は pack() した文字列、または Win32::API::Struct を使用。

関連項目

公式の関連項目
使用する型