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

WSAAsyncGetProtoByName

関数
プロトコル名のプロトコル情報を非同期で取得する。
DLLWS2_32.dll呼出規約winapiSetLastErrorあり対応OSWindows 2000 以降

シグネチャ

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

HANDLE WSAAsyncGetProtoByName(
    HWND hWnd,
    DWORD wMsg,
    LPCSTR name,
    LPSTR buf,
    INT buflen
);

パラメーター

名前方向説明
hWndHWNDin非同期要求が完了したときにメッセージを受信するウィンドウのハンドル。
wMsgDWORDin非同期要求が完了したときに受信するメッセージ。
nameLPCSTRin解決する、null 終端のプロトコル名へのポインター。
bufLPSTRoutprotoent データを受け取るデータ領域へのポインター。データ領域は protoent 構造体のサイズよりも大きくなければなりません。これは、このデータ領域が Windows Sockets によって protoent 構造体と、その protoent 構造体のメンバーから参照されるすべてのデータを格納するために使用されるためです。MAXGETHOSTSTRUCT バイトのバッファーを推奨します。
buflenINTinbuf パラメーターのデータ領域のサイズ (バイト単位)。

戻り値の型: HANDLE

公式ドキュメント

WSAAsyncGetProtoByName 関数 (winsock.h) は、プロトコル名に対応するプロトコル情報を非同期に取得します。

戻り値

戻り値は、非同期操作が正常に開始されたかどうかを示します。操作自体の成否を示すものではありません。

エラーが発生しなかった場合、 WSAAsyncGetProtoByName は、その要求の非同期タスクハンドルである HANDLE 型の 0 以外の値を返します (Windows の HTASK と混同しないでください)。この値は 2 通りの方法で使用できます。 WSACancelAsyncRequest を使用して操作をキャンセルするために使用できるほか、wParam メッセージパラメーターを調べることで、非同期操作と完了メッセージを対応付けるために使用できます。

非同期操作を開始できなかった場合、 WSAAsyncGetProtoByName は 0 の値を返します。具体的なエラー番号は WSAGetLastError を呼び出すことで取得できます。

アプリケーションウィンドウがメッセージを受信したときに、次のエラーコードが設定される場合があります。前述のとおり、これらは応答メッセージの lParam から WSAGETASYNCERROR マクロを使用して抽出できます。

エラーコード 意味
WSAENETDOWN
ネットワークサブシステムに障害が発生しました。
WSAENOBUFS
利用可能なバッファー領域が不足しています。
WSAEFAULT
name パラメーターまたは buf パラメーターが、プロセスアドレス空間の有効な部分にありません。
WSAHOST_NOT_FOUND
権威のある応答でプロトコルが見つかりませんでした。
WSATRY_AGAIN
非権威の応答でプロトコルが見つからなかったか、サーバー障害です。
WSANO_RECOVERY
回復不能なエラーです。プロトコルデータベースにアクセスできません。
WSANO_DATA
名前は有効ですが、要求された種類のデータレコードがありません。

次のエラーは関数呼び出し時に発生する可能性があり、非同期操作を開始できなかったことを示します。

エラーコード 意味
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 の Win32 API ドキュメント(MicrosoftDocs/sdk-api)を日本語に翻訳・改変したものです。© Microsoft Corporation. CC BY 4.0 で提供。
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 方式にも切替可。
出力引数:
; 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 方式にも切替可。
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   // HANDLE
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';
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 を使用。

関連項目

公式の関連項目