WSAAsyncGetProtoByName
関数シグネチャ
// WS2_32.dll
#include <windows.h>
HANDLE WSAAsyncGetProtoByName(
HWND hWnd,
DWORD wMsg,
LPCSTR name,
LPSTR buf,
INT buflen
);パラメーター
| 名前 | 型 | 方向 | 説明 |
|---|---|---|---|
| hWnd | HWND | in | 非同期要求が完了したときにメッセージを受信するウィンドウのハンドル。 |
| wMsg | DWORD | in | 非同期要求が完了したときに受信するメッセージ。 |
| name | LPCSTR | in | 解決する、null 終端のプロトコル名へのポインター。 |
| buf | LPSTR | out | protoent データを受け取るデータ領域へのポインター。データ領域は protoent 構造体のサイズよりも大きくなければなりません。これは、このデータ領域が Windows Sockets によって protoent 構造体と、その protoent 構造体のメンバーから参照されるすべてのデータを格納するために使用されるためです。MAXGETHOSTSTRUCT バイトのバッファーを推奨します。 |
| buflen | INT | in | buf パラメーターのデータ領域のサイズ (バイト単位)。 |
戻り値の型: HANDLE
公式ドキュメント
WSAAsyncGetProtoByName 関数 (winsock.h) は、プロトコル名に対応するプロトコル情報を非同期に取得します。
戻り値
戻り値は、非同期操作が正常に開始されたかどうかを示します。操作自体の成否を示すものではありません。
エラーが発生しなかった場合、 WSAAsyncGetProtoByName は、その要求の非同期タスクハンドルである HANDLE 型の 0 以外の値を返します (Windows の HTASK と混同しないでください)。この値は 2 通りの方法で使用できます。 WSACancelAsyncRequest を使用して操作をキャンセルするために使用できるほか、wParam メッセージパラメーターを調べることで、非同期操作と完了メッセージを対応付けるために使用できます。
非同期操作を開始できなかった場合、 WSAAsyncGetProtoByName は 0 の値を返します。具体的なエラー番号は WSAGetLastError を呼び出すことで取得できます。
アプリケーションウィンドウがメッセージを受信したときに、次のエラーコードが設定される場合があります。前述のとおり、これらは応答メッセージの lParam から WSAGETASYNCERROR マクロを使用して抽出できます。
| エラーコード | 意味 |
|---|---|
| ネットワークサブシステムに障害が発生しました。 | |
| 利用可能なバッファー領域が不足しています。 | |
| name パラメーターまたは buf パラメーターが、プロセスアドレス空間の有効な部分にありません。 | |
| 権威のある応答でプロトコルが見つかりませんでした。 | |
| 非権威の応答でプロトコルが見つからなかったか、サーバー障害です。 | |
| 回復不能なエラーです。プロトコルデータベースにアクセスできません。 | |
| 名前は有効ですが、要求された種類のデータレコードがありません。 |
次のエラーは関数呼び出し時に発生する可能性があり、非同期操作を開始できなかったことを示します。
| エラーコード | 意味 |
|---|---|
| WSANOTINITIALISED | この関数を使用する前に、 WSAStartup の呼び出しが成功している必要があります。 |
| WSAENETDOWN | ネットワークサブシステムに障害が発生しました。 |
| WSAEINPROGRESS | ブロッキングの Windows Sockets 1.1 呼び出しが進行中であるか、サービスプロバイダーがコールバック関数をまだ処理中です。 |
| WSAEWOULDBLOCK | Windows Sockets 実装内のリソースその他の制約により、現時点では非同期操作をスケジュールできません。 |
解説(Remarks)
WSAAsyncGetProtoByName 関数は、 getprotobyname の非同期版です。指定されたプロトコル名に対応するプロトコル名と番号を、Windows Sockets データベースから取得するために使用します。Windows Sockets は操作を開始してすぐに呼び出し元へ戻り、アプリケーションがその操作を識別するために使用できる不透明な非同期タスクハンドルを返します。操作が完了すると、結果 (もしあれば) は呼び出し元が提供したバッファーにコピーされ、アプリケーションのウィンドウにメッセージが送信されます。
非同期操作が完了すると、hWnd パラメーターで示されたアプリケーションウィンドウは、wMsg パラメーターで指定されたメッセージを受信します。wParam パラメーターには、元の関数呼び出しが返した非同期タスクハンドルが格納されます。lParam の上位 16 ビットにはエラーコードが格納されます。エラーコードは Winsock2.h で定義された任意のエラーになり得ます。エラーコードが 0 の場合は、非同期操作が正常に完了したことを示します。
正常に完了すると、元の関数呼び出しで指定したバッファーに protoent 構造体が格納されます。この構造体のメンバーにアクセスするには、元のバッファーアドレスを protoent 構造体ポインターにキャストし、適切にアクセスする必要があります。
エラーコードが WSAENOBUFS の場合、元の呼び出しで buflen に指定したバッファーのサイズが、結果として得られるすべての情報を格納するには小さすぎたことを意味します。この場合、lParam の下位 16 ビットには、すべての必要な情報を提供するために必要なバッファーサイズが格納されます。アプリケーションが部分的なデータでは不十分と判断した場合は、必要なすべての情報を受け取るのに十分な大きさのバッファー (すなわち lParam の下位 16 ビット以上の大きさ) を指定して、 WSAAsyncGetProtoByName 関数呼び出しを再発行できます。
この関数に指定するバッファーは、 protoent 構造体と、その同じ protoent 構造体のメンバーが参照するデータ領域の内容を Windows Sockets が構築するために使用します。上記の WSAENOBUFS エラーを回避するため、アプリケーションは少なくとも MAXGETHOSTSTRUCT バイト (Winsock2.h で定義) のバッファーを提供する必要があります。
エラーコードとバッファー長は、Winsock2.h で次のように定義されている WSAGETASYNCERROR および WSAGETASYNCBUFLEN マクロを使用して、lParam から抽出する必要があります。
#include <windows.h>
#define WSAGETASYNCBUFLEN(lParam) LOWORD(lParam)
#define WSAGETASYNCERROR(lParam) HIWORD(lParam)
これらのマクロを使用することで、アプリケーションのソースコードの移植性を最大限に高められます。
Microsoft 公式リファレンス: 英語 (en-us) · 日本語 (ja-jp) · 原文ソース (GitHub)
各言語での呼び出し定義
// WS2_32.dll
#include <windows.h>
HANDLE WSAAsyncGetProtoByName(
HWND hWnd,
DWORD wMsg,
LPCSTR name,
LPSTR buf,
INT buflen
);[DllImport("WS2_32.dll", SetLastError = true, ExactSpelling = true)]
static extern IntPtr WSAAsyncGetProtoByName(
IntPtr hWnd, // HWND
uint wMsg, // DWORD
[MarshalAs(UnmanagedType.LPStr)] string name, // LPCSTR
[MarshalAs(UnmanagedType.LPStr)] System.Text.StringBuilder buf, // LPSTR out
int buflen // INT
);<DllImport("WS2_32.dll", SetLastError:=True, ExactSpelling:=True)>
Public Shared Function WSAAsyncGetProtoByName(
hWnd As IntPtr, ' HWND
wMsg As UInteger, ' DWORD
<MarshalAs(UnmanagedType.LPStr)> name As String, ' LPCSTR
<MarshalAs(UnmanagedType.LPStr)> buf As System.Text.StringBuilder, ' LPSTR out
buflen As Integer ' INT
) As IntPtr
End Function' hWnd : HWND
' wMsg : DWORD
' name : LPCSTR
' buf : LPSTR out
' buflen : INT
Declare PtrSafe Function WSAAsyncGetProtoByName Lib "ws2_32" ( _
ByVal hWnd As LongPtr, _
ByVal wMsg As Long, _
ByVal name As String, _
ByVal buf As String, _
ByVal buflen As Long) As LongPtr
' VBA7前提(PtrSafe)。32bit Office では LongPtr→Long。Integer=16bit / Long=32bit / LongLong=64bit。import ctypes
from ctypes import wintypes
WSAAsyncGetProtoByName = ctypes.windll.ws2_32.WSAAsyncGetProtoByName
WSAAsyncGetProtoByName.restype = ctypes.c_void_p
WSAAsyncGetProtoByName.argtypes = [
wintypes.HANDLE, # hWnd : HWND
wintypes.DWORD, # wMsg : DWORD
wintypes.LPCSTR, # name : LPCSTR
wintypes.LPSTR, # buf : LPSTR out
ctypes.c_int, # buflen : INT
]
# GetLastError: use ctypes.GetLastError() (or ctypes.WinDLL(use_last_error=True))require 'fiddle'
require 'fiddle/import'
lib = Fiddle.dlopen('WS2_32.dll')
WSAAsyncGetProtoByName = Fiddle::Function.new(
lib['WSAAsyncGetProtoByName'],
[
Fiddle::TYPE_VOIDP, # hWnd : HWND
-Fiddle::TYPE_INT, # wMsg : DWORD
Fiddle::TYPE_VOIDP, # name : LPCSTR
Fiddle::TYPE_VOIDP, # buf : LPSTR out
Fiddle::TYPE_INT, # buflen : INT
],
Fiddle::TYPE_VOIDP)#[link(name = "ws2_32")]
extern "system" {
fn WSAAsyncGetProtoByName(
hWnd: *mut core::ffi::c_void, // HWND
wMsg: u32, // DWORD
name: *const u8, // LPCSTR
buf: *mut u8, // LPSTR out
buflen: i32 // INT
) -> *mut core::ffi::c_void;
}
// crates: windows-sys provides ready-made bindings for this API.$sig = @"
[DllImport("WS2_32.dll", SetLastError = true)]
public static extern IntPtr WSAAsyncGetProtoByName(IntPtr hWnd, uint wMsg, [MarshalAs(UnmanagedType.LPStr)] string name, [MarshalAs(UnmanagedType.LPStr)] System.Text.StringBuilder buf, int buflen);
"@
$api = Add-Type -MemberDefinition $sig -Name 'WS2_32_WSAAsyncGetProtoByName' -Namespace Win32 -PassThru
# $api::WSAAsyncGetProtoByName(hWnd, wMsg, name, buf, buflen)#uselib "WS2_32.dll"
#func global WSAAsyncGetProtoByName "WSAAsyncGetProtoByName" sptr, sptr, sptr, sptr, sptr
; WSAAsyncGetProtoByName hWnd, wMsg, name, varptr(buf), buflen ; 戻り値は stat
; hWnd : HWND -> "sptr"
; wMsg : DWORD -> "sptr"
; name : LPCSTR -> "sptr"
; buf : LPSTR out -> "sptr"
; buflen : INT -> "sptr"
; ※HSP3.7は #func のため戻り値はシステム変数 stat に格納されます。#uselib "WS2_32.dll" #cfunc global WSAAsyncGetProtoByName "WSAAsyncGetProtoByName" sptr, int, str, var, int ; res = WSAAsyncGetProtoByName(hWnd, wMsg, name, buf, buflen) ; hWnd : HWND -> "sptr" ; wMsg : DWORD -> "int" ; name : LPCSTR -> "str" ; buf : LPSTR out -> "var" ; buflen : INT -> "int" ; ※出力/バッファ引数は var 方式(変数を直接渡す)。varptr 方式にも切替可。#uselib "WS2_32.dll" #cfunc global WSAAsyncGetProtoByName "WSAAsyncGetProtoByName" sptr, int, str, sptr, int ; res = WSAAsyncGetProtoByName(hWnd, wMsg, name, varptr(buf), buflen) ; hWnd : HWND -> "sptr" ; wMsg : DWORD -> "int" ; name : LPCSTR -> "str" ; buf : LPSTR out -> "sptr" ; buflen : INT -> "int" ; ※出力/バッファ引数はポインタ方式(token=sptr / 呼び出しは varptr(変数))。
; HANDLE WSAAsyncGetProtoByName(HWND hWnd, DWORD wMsg, LPCSTR name, LPSTR buf, INT buflen) #uselib "WS2_32.dll" #cfunc global WSAAsyncGetProtoByName "WSAAsyncGetProtoByName" intptr, int, str, var, int ; res = WSAAsyncGetProtoByName(hWnd, wMsg, name, buf, buflen) ; hWnd : HWND -> "intptr" ; wMsg : DWORD -> "int" ; name : LPCSTR -> "str" ; buf : LPSTR out -> "var" ; buflen : INT -> "int" ; ※出力/バッファ引数は var 方式(変数を直接渡す)。varptr 方式にも切替可。; HANDLE WSAAsyncGetProtoByName(HWND hWnd, DWORD wMsg, LPCSTR name, LPSTR buf, INT buflen) #uselib "WS2_32.dll" #cfunc global WSAAsyncGetProtoByName "WSAAsyncGetProtoByName" intptr, int, str, intptr, int ; res = WSAAsyncGetProtoByName(hWnd, wMsg, name, varptr(buf), buflen) ; hWnd : HWND -> "intptr" ; wMsg : DWORD -> "int" ; name : LPCSTR -> "str" ; buf : LPSTR out -> "intptr" ; buflen : INT -> "int" ; ※出力/バッファ引数はポインタ方式(token=intptr / 呼び出しは varptr(変数))。
import (
"golang.org/x/sys/windows"
"unsafe"
)
var (
ws2_32 = windows.NewLazySystemDLL("WS2_32.dll")
procWSAAsyncGetProtoByName = ws2_32.NewProc("WSAAsyncGetProtoByName")
)
// hWnd (HWND), wMsg (DWORD), name (LPCSTR), buf (LPSTR out), buflen (INT)
r1, _, err := procWSAAsyncGetProtoByName.Call(
uintptr(hWnd),
uintptr(wMsg),
uintptr(unsafe.Pointer(windows.BytePtrFromString(name))),
uintptr(buf),
uintptr(buflen),
)
_ = err // syscall.Errno (valid when the call sets last-error)
_ = r1 // HANDLEfunction WSAAsyncGetProtoByName(
hWnd: THandle; // HWND
wMsg: DWORD; // DWORD
name: PAnsiChar; // LPCSTR
buf: PAnsiChar; // LPSTR out
buflen: Integer // INT
): THandle; stdcall;
external 'WS2_32.dll' name 'WSAAsyncGetProtoByName';result := DllCall("WS2_32\WSAAsyncGetProtoByName"
, "Ptr", hWnd ; HWND
, "UInt", wMsg ; DWORD
, "AStr", name ; LPCSTR
, "Ptr", buf ; LPSTR out
, "Int", buflen ; INT
, "Ptr") ; return: HANDLE●WSAAsyncGetProtoByName(hWnd, wMsg, name, buf, buflen) = DLL("WS2_32.dll", "void* WSAAsyncGetProtoByName(void*, dword, char*, char*, int)")
# 呼び出し: WSAAsyncGetProtoByName(hWnd, wMsg, name, buf, buflen)
# hWnd : HWND -> "void*"
# wMsg : DWORD -> "dword"
# name : LPCSTR -> "char*"
# buf : LPSTR out -> "char*"
# buflen : INT -> "int"
# なでしこ1は32bit・ANSI(Shift_JIS)。文字列=char*(ANSI)、ポインタ/ハンドル=void*(4byte)。const std = @import("std");
extern "ws2_32" fn WSAAsyncGetProtoByName(
hWnd: ?*anyopaque, // HWND
wMsg: u32, // DWORD
name: [*c]const u8, // LPCSTR
buf: [*c]u8, // LPSTR out
buflen: i32 // INT
) callconv(std.os.windows.WINAPI) ?*anyopaque;proc WSAAsyncGetProtoByName(
hWnd: pointer, # HWND
wMsg: uint32, # DWORD
name: cstring, # LPCSTR
buf: ptr char, # LPSTR out
buflen: int32 # INT
): pointer {.importc: "WSAAsyncGetProtoByName", stdcall, dynlib: "WS2_32.dll".}pragma(lib, "ws2_32");
extern(Windows)
void* WSAAsyncGetProtoByName(
void* hWnd, // HWND
uint wMsg, // DWORD
const(char)* name, // LPCSTR
char* buf, // LPSTR out
int buflen // INT
);ccall((:WSAAsyncGetProtoByName, "WS2_32.dll"), stdcall, Ptr{Cvoid},
(Ptr{Cvoid}, UInt32, Cstring, Ptr{UInt8}, Int32),
hWnd, wMsg, name, buf, buflen)
# hWnd : HWND -> Ptr{Cvoid}
# wMsg : DWORD -> UInt32
# name : LPCSTR -> Cstring
# buf : LPSTR out -> Ptr{UInt8}
# buflen : INT -> Int32
# stdcall は 32bit のみ意味を持つ(x64 では無視)。local ffi = require("ffi")
ffi.cdef[[
void* WSAAsyncGetProtoByName(
void* hWnd,
uint32_t wMsg,
const char* name,
char* buf,
int32_t buflen);
]]
local ws2_32 = ffi.load("ws2_32")
-- ws2_32.WSAAsyncGetProtoByName(hWnd, wMsg, name, buf, buflen)
-- hWnd : HWND
-- wMsg : DWORD
-- name : LPCSTR
-- buf : LPSTR out
-- buflen : INT
-- 構造体/GUIDへのポインタは cdef が通るよう void* で表記(実型は各引数コメント参照)。値渡し構造体・enum は対応する typedef を cdef に追加すること。const koffi = require('koffi');
const lib = koffi.load('WS2_32.dll');
const WSAAsyncGetProtoByName = lib.func('__stdcall', 'WSAAsyncGetProtoByName', 'void *', ['void *', 'uint32_t', 'str', 'char *', 'int32_t']);
// WSAAsyncGetProtoByName(hWnd, wMsg, name, buf, buflen)
// hWnd : HWND -> 'void *'
// wMsg : DWORD -> 'uint32_t'
// name : LPCSTR -> 'str'
// buf : LPSTR out -> 'char *'
// buflen : INT -> 'int32_t'
// 出力ポインタは koffi.out(...) で包む。構造体は koffi.struct で定義。const lib = Deno.dlopen("WS2_32.dll", {
WSAAsyncGetProtoByName: { parameters: ["pointer", "u32", "buffer", "buffer", "i32"], result: "pointer" },
});
// lib.symbols.WSAAsyncGetProtoByName(hWnd, wMsg, name, buf, buflen)
// hWnd : HWND -> "pointer"
// wMsg : DWORD -> "u32"
// name : LPCSTR -> "buffer"
// buf : LPSTR out -> "buffer"
// buflen : INT -> "i32"
// 文字列引数は "buffer"(NUL 終端のバイト列を Uint8Array で渡す)。
// 値渡し構造体は { struct: [ ...field types... ] } を使用。<?php
$ffi = FFI::cdef(<<<C
void* WSAAsyncGetProtoByName(
void* hWnd,
uint32_t wMsg,
const char* name,
char* buf,
int32_t buflen);
C, "WS2_32.dll");
// $ffi->WSAAsyncGetProtoByName(hWnd, wMsg, name, buf, buflen);
// hWnd : HWND
// wMsg : DWORD
// name : LPCSTR
// buf : LPSTR out
// buflen : INT
// 構造体/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);
Pointer WSAAsyncGetProtoByName(
Pointer hWnd, // HWND
int wMsg, // DWORD
String name, // LPCSTR
byte[] buf, // LPSTR out
int buflen // INT
);
}@[Link("ws2_32")]
lib LibWS2_32
fun WSAAsyncGetProtoByName = WSAAsyncGetProtoByName(
hWnd : Void*, # HWND
wMsg : UInt32, # DWORD
name : UInt8*, # LPCSTR
buf : UInt8*, # LPSTR out
buflen : Int32 # INT
) : Void*
end
# 構造体/GUID/enum は lib 内に対応する型定義が必要。
# 呼出規約: x64 は規約統一のため OK。x86(32bit)は WINAPI=stdcall だが Crystal の fun に stdcall 付与構文がなく非対応。import 'dart:ffi';
import 'package:ffi/ffi.dart';
typedef WSAAsyncGetProtoByNameNative = Pointer<Void> Function(Pointer<Void>, Uint32, Pointer<Utf8>, Pointer<Utf8>, Int32);
typedef WSAAsyncGetProtoByNameDart = Pointer<Void> Function(Pointer<Void>, int, Pointer<Utf8>, Pointer<Utf8>, int);
final WSAAsyncGetProtoByName = DynamicLibrary.open('WS2_32.dll')
.lookupFunction<WSAAsyncGetProtoByNameNative, WSAAsyncGetProtoByNameDart>('WSAAsyncGetProtoByName');
// hWnd : HWND -> Pointer<Void>
// wMsg : DWORD -> Uint32
// name : LPCSTR -> Pointer<Utf8>
// buf : LPSTR out -> Pointer<Utf8>
// buflen : INT -> Int32
// 文字列は package:ffi の "...".toNativeUtf16()/toNativeUtf8() で変換。{$mode objfpc}{$H+}
function WSAAsyncGetProtoByName(
hWnd: THandle; // HWND
wMsg: DWORD; // DWORD
name: PAnsiChar; // LPCSTR
buf: PAnsiChar; // LPSTR out
buflen: Integer // INT
): THandle; stdcall;
external 'WS2_32.dll' name 'WSAAsyncGetProtoByName';import Foreign
import Foreign.C.Types
import Foreign.C.String
foreign import stdcall safe "WSAAsyncGetProtoByName"
c_WSAAsyncGetProtoByName :: Ptr () -> Word32 -> CString -> CString -> Int32 -> IO (Ptr ())
-- hWnd : HWND -> Ptr ()
-- wMsg : DWORD -> Word32
-- name : LPCSTR -> CString
-- buf : LPSTR out -> CString
-- buflen : INT -> Int32
-- 要 GHC(Windows)。stdcall は x64 では ccall として扱われる。ブロックする API は safe 呼び出し推奨。open Ctypes
open Foreign
let wsaasyncgetprotobyname =
foreign "WSAAsyncGetProtoByName"
((ptr void) @-> uint32_t @-> string @-> string @-> int32_t @-> returning (ptr void))
(* hWnd : HWND -> (ptr void) *)
(* wMsg : DWORD -> uint32_t *)
(* name : LPCSTR -> string *)
(* buf : LPSTR out -> string *)
(* buflen : INT -> int32_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 ("WSAAsyncGetProtoByName" wsaasync-get-proto-by-name :convention :stdcall) :pointer
(h-wnd :pointer) ; HWND
(w-msg :uint32) ; DWORD
(name :string) ; LPCSTR
(buf :pointer) ; LPSTR out
(buflen :int32)) ; INT
; isize/usize(INT_PTR/SIZE_T)は x64 前提で :int64/:uint64。x86 では :int32/:uint32。use Win32::API;
my $WSAAsyncGetProtoByName = Win32::API::More->new('WS2_32',
'HANDLE WSAAsyncGetProtoByName(HANDLE hWnd, DWORD wMsg, LPCSTR name, LPSTR buf, int buflen)');
# my $ret = $WSAAsyncGetProtoByName->Call($hWnd, $wMsg, $name, $buf, $buflen);
# hWnd : HWND -> HANDLE
# wMsg : DWORD -> DWORD
# name : LPCSTR -> LPCSTR
# buf : LPSTR out -> LPSTR
# buflen : INT -> int
# 値渡し構造体は pack() した文字列、または Win32::API::Struct を使用。関連項目
- f WSACancelAsyncRequest — 進行中の非同期データベース問い合わせを取り消す。
- f getprotobyname — プロトコル名に対応するプロトコル情報を取得する。