WSANSPIoctl
関数シグネチャ
// 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
);パラメーター
| 名前 | 型 | 方向 | 説明 | ||||
|---|---|---|---|---|---|---|---|
| hLookup | HANDLE | in | 以前の WSALookupServiceBegin 関数の呼び出しから返されたルックアップ ハンドル。 | ||||
| dwControlCode | DWORD | in | 実行する操作の制御コード。 dwControlCode パラメーターに使用できる値は、ネームスペース プロバイダーによって決まります。 次の値は、Network Location Awareness (NS_NLA) ネームスペース プロバイダーを含む複数の Microsoft ネームスペース プロバイダーでサポートされています。この IOCTL は Winsock2.h ヘッダー ファイルで定義されています。
| ||||
| lpvInBuffer | void* | inoptional | 入力バッファーへのポインター。 | ||||
| cbInBuffer | DWORD | in | 入力バッファーのサイズ (バイト単位)。 | ||||
| lpvOutBuffer | void* | outoptional | 出力バッファーへのポインター。 | ||||
| cbOutBuffer | DWORD | in | 出力バッファーのサイズ (バイト単位)。 | ||||
| lpcbBytesReturned | DWORD* | out | 返されたバイト数へのポインター。 | ||||
| lpCompletion | WSACOMPLETION* | inoptional | 非同期処理に使用される WSACOMPLETION 構造体へのポインター。ブロッキング (同期) 実行を強制するには、lpCompletion を NULL に設定します。 |
戻り値の型: INT
公式ドキュメント
登録済みのネームスペースに対して I/O 制御呼び出しを行えるようにします。
戻り値
成功した場合は NO_ERROR を返します。失敗した場合は SOCKET_ERROR を返し、特定のエラー コードは WSAGetLastError 関数を呼び出すことで取得できます。次の表にエラー コードを示します。
| エラー コード | 説明 |
|---|---|
| hLookup パラメーターが、 WSALookupServiceBegin によって返された有効なクエリ ハンドルではありませんでした。 | |
| オーバーラップ操作が正常に開始され、完了は後で通知されます。 | |
| lpvInBuffer、cbInBuffer、lpvOutBuffer、cbOutBuffer、または lpCompletion 引数が、ユーザー アドレス空間の有効な部分に完全には含まれていません。あるいは、cbInBuffer または cbOutBuffer 引数が小さすぎるため、必要な割り当てサイズを反映するように引数が変更されます。 | |
| 指定されたパラメーターが受け入れられないか、指定された操作にとって意味をなさないにもかかわらず、操作が複数のネームスペースから不適切に結果を返しています。 | |
| ネットワーク サブシステムが失敗しました。 | |
| 操作はサポートされていません。このエラーは、ネームスペース プロバイダーがこの関数を実装していない場合に返されます。また、指定された dwControlCode が認識されないコマンドである場合にも返されることがあります。 | |
|
ソケットがオーバーラップ 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 に設定します。
lpCompletion が NULL の場合、 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 を返します。
lpvInBuffer、cbInBuffer、lpvOutBuffer、および 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 とともに通知が配信されます。
Windows 8.1 および Windows Server 2012 R2: この関数は、Windows 8.1、Windows Server 2012 R2 以降の Windows ストア アプリでサポートされています。
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 方式にも切替可。#uselib "WS2_32.dll" #cfunc global WSANSPIoctl "WSANSPIoctl" sptr, int, sptr, int, sptr, int, sptr, sptr ; res = WSANSPIoctl(hLookup, dwControlCode, lpvInBuffer, cbInBuffer, lpvOutBuffer, cbOutBuffer, varptr(lpcbBytesReturned), varptr(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 -> "sptr" ; lpCompletion : WSACOMPLETION* optional -> "sptr" ; ※出力/バッファ引数はポインタ方式(token=sptr / 呼び出しは 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 方式にも切替可。; 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, intptr, intptr ; res = WSANSPIoctl(hLookup, dwControlCode, lpvInBuffer, cbInBuffer, lpvOutBuffer, cbOutBuffer, varptr(lpcbBytesReturned), varptr(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 -> "intptr" ; lpCompletion : WSACOMPLETION* optional -> "intptr" ; ※出力/バッファ引数はポインタ方式(token=intptr / 呼び出しは 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 // INTfunction 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 を使用。関連項目
- f ExitThread — 呼び出し元スレッドを指定した終了コードで終了する。
- f WSAGetLastError — 直前のソケット操作のエラーコードを取得する。
- f WSALookupServiceBeginW — サービス問い合わせを開始しクエリハンドルを取得する。
- f WSALookupServiceEnd — サービス問い合わせを終了しハンドルを解放する。
- f WSALookupServiceNextW — サービス問い合わせの次の結果を取得する。