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

WinHttpQueryAuthSchemes

関数
サーバーが提示する認証方式を問い合わせる。
DLLWINHTTP.dll呼出規約winapiSetLastErrorあり対応OSWindows XP 以降

シグネチャ

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

BOOL WinHttpQueryAuthSchemes(
    void* hRequest,
    DWORD* lpdwSupportedSchemes,
    DWORD* lpdwFirstScheme,
    DWORD* pdwAuthTarget
);

パラメーター

名前方向説明
hRequestvoid*inoutWinHttpOpenRequest が返した有効な HINTERNET ハンドル。
lpdwSupportedSchemesDWORD*inout

サポートされている認証スキームを格納するフラグを指定する符号なし整数。このパラメーターは、次の表に示すフラグを 1 つ以上返すことがあります。

意味
WINHTTP_AUTH_SCHEME_BASIC
Basic 認証が利用可能であることを示します。
WINHTTP_AUTH_SCHEME_NTLM
NTLM 認証が利用可能であることを示します。
WINHTTP_AUTH_SCHEME_PASSPORT
Passport 認証が利用可能であることを示します。
WINHTTP_AUTH_SCHEME_DIGEST
Digest 認証が利用可能であることを示します。
WINHTTP_AUTH_SCHEME_NEGOTIATE
NTLM 認証と Kerberos 認証のいずれかを選択します。
lpdwFirstSchemeDWORD*inout

サーバーが最初に列挙した認証スキームを格納するフラグを指定する符号なし整数。このパラメーターは、次の表に示すフラグを 1 つ以上返すことがあります。

意味
WINHTTP_AUTH_SCHEME_BASIC
Basic 認証が最初であることを示します。
WINHTTP_AUTH_SCHEME_NTLM
NTLM 認証が最初であることを示します。
WINHTTP_AUTH_SCHEME_PASSPORT
Passport 認証が最初であることを示します。
WINHTTP_AUTH_SCHEME_DIGEST
Digest 認証が最初であることを示します。
WINHTTP_AUTH_SCHEME_NEGOTIATE
NTLM 認証と Kerberos 認証のいずれかを選択します。
pdwAuthTargetDWORD*inout

認証ターゲットを格納するフラグを指定する符号なし整数。このパラメーターは、次の表に示すフラグを 1 つ以上返すことがあります。

意味
WINHTTP_AUTH_TARGET_SERVER
認証ターゲットはサーバーです。401 ステータスコードを受信したことを示します。
WINHTTP_AUTH_TARGET_PROXY
認証ターゲットはプロキシです。407 ステータスコードを受信したことを示します。

戻り値の型: BOOL

公式ドキュメント

WinHttpQueryAuthSchemes 関数は、サーバーがサポートしている認可スキームを返します。

戻り値

成功した場合は TRUE を、失敗した場合は FALSE を返します。拡張エラー情報を取得するには、 GetLastError を呼び出します。返されるエラーコードを次の表に示します。

エラーコード 説明
ERROR_WINHTTP_INCORRECT_HANDLE_TYPE
指定されたハンドルの種類が、この操作には適切ではありません。
ERROR_WINHTTP_INTERNAL_ERROR
内部エラーが発生しました。
ERROR_NOT_ENOUGH_MEMORY
要求された操作を完了するために十分なメモリがありませんでした。(Windows エラーコード)

解説(Remarks)

WinHTTP を非同期モードで使用している場合(つまり、WinHttpOpenWINHTTP_FLAG_ASYNC を設定している場合)でも、この関数は同期的に動作します。戻り値が成功または失敗を示します。拡張エラー情報を取得するには、 GetLastError を呼び出します。

WinHttpQueryAuthSchemes は、 WinHttpQueryHeaders を呼び出す前に使用することはできません。

注意 Windows XP および Windows 2000 については、WinHttp スタートページの Run-Time Requirements セクションを参照してください。

次の例では、認証が必要な場合に、HTTP サーバーから指定したドキュメントを取得する方法を示します。サーバーまたはプロキシが認証を要求しているかどうかを判断するために、応答からステータスコードを取得します。200 のステータスコードが見つかった場合、そのドキュメントは利用可能です。401 または 407 のステータスコードが見つかった場合、ドキュメントを取得する前に認証が必要です。その他のステータスコードの場合は、エラーメッセージが表示されます。

#include <windows.h>
#include <winhttp.h>
#include <stdio.h>

#pragma comment(lib, "winhttp.lib")

DWORD ChooseAuthScheme( DWORD dwSupportedSchemes )
{
  //  It is the server's responsibility only to accept 
  //  authentication schemes that provide a sufficient level
  //  of security to protect the server's resources.
  //
  //  The client is also obligated only to use an authentication
  //  scheme that adequately protects its username and password.
  //
  //  Thus, this sample code does not use Basic authentication  
  //  because Basic authentication exposes the client's username 
  //  and password to anyone monitoring the connection.
  
  if( dwSupportedSchemes & WINHTTP_AUTH_SCHEME_NEGOTIATE )
    return WINHTTP_AUTH_SCHEME_NEGOTIATE;
  else if( dwSupportedSchemes & WINHTTP_AUTH_SCHEME_NTLM )
    return WINHTTP_AUTH_SCHEME_NTLM;
  else if( dwSupportedSchemes & WINHTTP_AUTH_SCHEME_PASSPORT )
    return WINHTTP_AUTH_SCHEME_PASSPORT;
  else if( dwSupportedSchemes & WINHTTP_AUTH_SCHEME_DIGEST )
    return WINHTTP_AUTH_SCHEME_DIGEST;
  else
    return 0;
}

struct SWinHttpSampleGet
{
  LPCWSTR szServer;
  LPCWSTR szPath;
  BOOL fUseSSL;
  LPCWSTR szServerUsername;
  LPCWSTR szServerPassword;
  LPCWSTR szProxyUsername;
  LPCWSTR szProxyPassword;
};

void WinHttpAuthSample( IN SWinHttpSampleGet *pGetRequest )
{
  DWORD dwStatusCode = 0;
  DWORD dwSupportedSchemes;
  DWORD dwFirstScheme;
  DWORD dwSelectedScheme;
  DWORD dwTarget;
  DWORD dwLastStatus = 0;
  DWORD dwSize = sizeof(DWORD);
  BOOL  bResults = FALSE;
  BOOL  bDone = FALSE;

  DWORD dwProxyAuthScheme = 0;
  HINTERNET  hSession = NULL, 
             hConnect = NULL,
             hRequest = NULL;

  // Use WinHttpOpen to obtain a session handle.
  hSession = WinHttpOpen( L"WinHTTP Example/1.0",  
                          WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
                          WINHTTP_NO_PROXY_NAME, 
                          WINHTTP_NO_PROXY_BYPASS, 0 );

  INTERNET_PORT nPort = ( pGetRequest->fUseSSL ) ? 
                        INTERNET_DEFAULT_HTTPS_PORT  :
                        INTERNET_DEFAULT_HTTP_PORT;

  // Specify an HTTP server.
  if( hSession )
    hConnect = WinHttpConnect( hSession, 
                               pGetRequest->szServer, 
                               nPort, 0 );

  // Create an HTTP request handle.
  if( hConnect )
    hRequest = WinHttpOpenRequest( hConnect, 
                                   L"GET", 
                                   pGetRequest->szPath,
                                   NULL, 
                                   WINHTTP_NO_REFERER, 
                                   WINHTTP_DEFAULT_ACCEPT_TYPES,
                                   ( pGetRequest->fUseSSL ) ? 
                                       WINHTTP_FLAG_SECURE : 0 );

  // Continue to send a request until status code is not 401 or 407.
  if( hRequest == NULL )
    bDone = TRUE;

  while( !bDone )
  {
    //  If a proxy authentication challenge was responded to, reset 
    //  those credentials before each SendRequest, because the proxy  
    //  may require re-authentication after responding to a 401 or to 
    //  a redirect. If you don't, you can get into a 407-401-407-401
    //  loop.
    if( dwProxyAuthScheme != 0 )
      bResults = WinHttpSetCredentials( hRequest, 
                                        WINHTTP_AUTH_TARGET_PROXY, 
                                        dwProxyAuthScheme, 
                                        pGetRequest->szProxyUsername,
                                        pGetRequest->szProxyPassword,
                                        NULL );
    // Send a request.
    bResults = WinHttpSendRequest( hRequest,
                                   WINHTTP_NO_ADDITIONAL_HEADERS,
                                   0,
                                   WINHTTP_NO_REQUEST_DATA,
                                   0, 
                                   0, 
                                   0 );

    // End the request.
    if( bResults )
      bResults = WinHttpReceiveResponse( hRequest, NULL );

    // Resend the request in case of 
    // ERROR_WINHTTP_RESEND_REQUEST error.
    if( !bResults && GetLastError( ) == ERROR_WINHTTP_RESEND_REQUEST)
        continue;

    // Check the status code.
    if( bResults ) 
      bResults = WinHttpQueryHeaders( hRequest, 
                                      WINHTTP_QUERY_STATUS_CODE | 
                                          WINHTTP_QUERY_FLAG_NUMBER,
                                      NULL, 
                                      &dwStatusCode, 
                                      &dwSize, 
                                      NULL );

    if( bResults )
    {
      switch( dwStatusCode )
      {
        case 200: 
          // The resource was successfully retrieved.
          // You can use WinHttpReadData to read the contents 
          // of the server's response.
          printf( "The resource was successfully retrieved.\n" );
          bDone = TRUE;
          break;

        case 401:
          // The server requires authentication.
          printf(
           "The server requires authentication. Sending credentials\n");

          // Obtain the supported and preferred schemes.
          bResults = WinHttpQueryAuthSchemes( hRequest, 
                                              &dwSupportedSchemes, 
                                              &dwFirstScheme, 
                                              &dwTarget );

          // Set the credentials before re-sending the request.
          if( bResults )
          {
            dwSelectedScheme = ChooseAuthScheme( dwSupportedSchemes );

            if( dwSelectedScheme == 0 )
              bDone = TRUE;
            else
              bResults = WinHttpSetCredentials( 
                                        hRequest, dwTarget, 
                                        dwSelectedScheme,
                                        pGetRequest->szServerUsername,
                                        pGetRequest->szServerPassword,
                                        NULL );
          }

          // If the same credentials are requested twice, abort the
          // request.  For simplicity, this sample does not check for
          // a repeated sequence of status codes.
          if( dwLastStatus == 401 )
            bDone = TRUE;

          break;

        case 407:
          // The proxy requires authentication.
          printf( 
           "The proxy requires authentication. Sending credentials\n");

          // Obtain the supported and preferred schemes.
          bResults = WinHttpQueryAuthSchemes( hRequest, 
                                              &dwSupportedSchemes, 
                                              &dwFirstScheme, 
                                              &dwTarget );

          // Set the credentials before re-sending the request.
          if( bResults )
            dwProxyAuthScheme = ChooseAuthScheme(dwSupportedSchemes);

          // If the same credentials are requested twice, abort the
          // request.  For simplicity, this sample does not check for
          // a repeated sequence of status codes.
          if( dwLastStatus == 407 )
            bDone = TRUE;
          break;

        default:
          // The status code does not indicate success.
          printf( "Error. Status code %d returned.\n", dwStatusCode );
          bDone = TRUE;
      }
    }

    // Keep track of the last status code.
    dwLastStatus = dwStatusCode;

    // If there are any errors, break out of the loop.
    if( !bResults ) 
        bDone = TRUE;
  }

  // Report any errors.
  if( !bResults )
  {
    DWORD dwLastError = GetLastError( );
    printf( "Error %d has occurred.\n", dwLastError );
  }

  // Close any open handles.
  if( hRequest ) WinHttpCloseHandle( hRequest );
  if( hConnect ) WinHttpCloseHandle( hConnect );
  if( hSession ) WinHttpCloseHandle( hSession );
}

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

各言語での呼び出し定義

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

BOOL WinHttpQueryAuthSchemes(
    void* hRequest,
    DWORD* lpdwSupportedSchemes,
    DWORD* lpdwFirstScheme,
    DWORD* pdwAuthTarget
);
[return: MarshalAs(UnmanagedType.Bool)]
[DllImport("WINHTTP.dll", SetLastError = true, ExactSpelling = true)]
static extern bool WinHttpQueryAuthSchemes(
    IntPtr hRequest,   // void* in/out
    ref uint lpdwSupportedSchemes,   // DWORD* in/out
    ref uint lpdwFirstScheme,   // DWORD* in/out
    ref uint pdwAuthTarget   // DWORD* in/out
);
<DllImport("WINHTTP.dll", SetLastError:=True, ExactSpelling:=True)>
Public Shared Function WinHttpQueryAuthSchemes(
    hRequest As IntPtr,   ' void* in/out
    ByRef lpdwSupportedSchemes As UInteger,   ' DWORD* in/out
    ByRef lpdwFirstScheme As UInteger,   ' DWORD* in/out
    ByRef pdwAuthTarget As UInteger   ' DWORD* in/out
) As <MarshalAs(UnmanagedType.Bool)> Boolean
End Function
' hRequest : void* in/out
' lpdwSupportedSchemes : DWORD* in/out
' lpdwFirstScheme : DWORD* in/out
' pdwAuthTarget : DWORD* in/out
Declare PtrSafe Function WinHttpQueryAuthSchemes Lib "winhttp" ( _
    ByVal hRequest As LongPtr, _
    ByRef lpdwSupportedSchemes As Long, _
    ByRef lpdwFirstScheme As Long, _
    ByRef pdwAuthTarget As Long) As Long
' VBA7前提(PtrSafe)。32bit Office では LongPtr→Long。Integer=16bit / Long=32bit / LongLong=64bit。
import ctypes
from ctypes import wintypes

WinHttpQueryAuthSchemes = ctypes.windll.winhttp.WinHttpQueryAuthSchemes
WinHttpQueryAuthSchemes.restype = wintypes.BOOL
WinHttpQueryAuthSchemes.argtypes = [
    ctypes.POINTER(None),  # hRequest : void* in/out
    ctypes.POINTER(wintypes.DWORD),  # lpdwSupportedSchemes : DWORD* in/out
    ctypes.POINTER(wintypes.DWORD),  # lpdwFirstScheme : DWORD* in/out
    ctypes.POINTER(wintypes.DWORD),  # pdwAuthTarget : DWORD* in/out
]
# GetLastError: use ctypes.GetLastError() (or ctypes.WinDLL(use_last_error=True))
require 'fiddle'
require 'fiddle/import'

lib = Fiddle.dlopen('WINHTTP.dll')
WinHttpQueryAuthSchemes = Fiddle::Function.new(
  lib['WinHttpQueryAuthSchemes'],
  [
    Fiddle::TYPE_VOIDP,  # hRequest : void* in/out
    Fiddle::TYPE_VOIDP,  # lpdwSupportedSchemes : DWORD* in/out
    Fiddle::TYPE_VOIDP,  # lpdwFirstScheme : DWORD* in/out
    Fiddle::TYPE_VOIDP,  # pdwAuthTarget : DWORD* in/out
  ],
  Fiddle::TYPE_INT)
#[link(name = "winhttp")]
extern "system" {
    fn WinHttpQueryAuthSchemes(
        hRequest: *mut (),  // void* in/out
        lpdwSupportedSchemes: *mut u32,  // DWORD* in/out
        lpdwFirstScheme: *mut u32,  // DWORD* in/out
        pdwAuthTarget: *mut u32  // DWORD* in/out
    ) -> i32;
}
// crates: windows-sys provides ready-made bindings for this API.
$sig = @"
[return: MarshalAs(UnmanagedType.Bool)]
[DllImport("WINHTTP.dll", SetLastError = true)]
public static extern bool WinHttpQueryAuthSchemes(IntPtr hRequest, ref uint lpdwSupportedSchemes, ref uint lpdwFirstScheme, ref uint pdwAuthTarget);
"@
$api = Add-Type -MemberDefinition $sig -Name 'WINHTTP_WinHttpQueryAuthSchemes' -Namespace Win32 -PassThru
# $api::WinHttpQueryAuthSchemes(hRequest, lpdwSupportedSchemes, lpdwFirstScheme, pdwAuthTarget)
#uselib "WINHTTP.dll"
#func global WinHttpQueryAuthSchemes "WinHttpQueryAuthSchemes" sptr, sptr, sptr, sptr
; WinHttpQueryAuthSchemes hRequest, varptr(lpdwSupportedSchemes), varptr(lpdwFirstScheme), varptr(pdwAuthTarget)   ; 戻り値は stat
; hRequest : void* in/out -> "sptr"
; lpdwSupportedSchemes : DWORD* in/out -> "sptr"
; lpdwFirstScheme : DWORD* in/out -> "sptr"
; pdwAuthTarget : DWORD* in/out -> "sptr"
; ※HSP3.7は #func のため戻り値はシステム変数 stat に格納されます。
出力引数:
#uselib "WINHTTP.dll"
#cfunc global WinHttpQueryAuthSchemes "WinHttpQueryAuthSchemes" sptr, var, var, var
; res = WinHttpQueryAuthSchemes(hRequest, lpdwSupportedSchemes, lpdwFirstScheme, pdwAuthTarget)
; hRequest : void* in/out -> "sptr"
; lpdwSupportedSchemes : DWORD* in/out -> "var"
; lpdwFirstScheme : DWORD* in/out -> "var"
; pdwAuthTarget : DWORD* in/out -> "var"
; ※出力/バッファ引数は var 方式(変数を直接渡す)。varptr 方式にも切替可。
出力引数:
; BOOL WinHttpQueryAuthSchemes(void* hRequest, DWORD* lpdwSupportedSchemes, DWORD* lpdwFirstScheme, DWORD* pdwAuthTarget)
#uselib "WINHTTP.dll"
#cfunc global WinHttpQueryAuthSchemes "WinHttpQueryAuthSchemes" intptr, var, var, var
; res = WinHttpQueryAuthSchemes(hRequest, lpdwSupportedSchemes, lpdwFirstScheme, pdwAuthTarget)
; hRequest : void* in/out -> "intptr"
; lpdwSupportedSchemes : DWORD* in/out -> "var"
; lpdwFirstScheme : DWORD* in/out -> "var"
; pdwAuthTarget : DWORD* in/out -> "var"
; ※出力/バッファ引数は var 方式(変数を直接渡す)。varptr 方式にも切替可。
import (
	"golang.org/x/sys/windows"
	"unsafe"
)

var (
	winhttp = windows.NewLazySystemDLL("WINHTTP.dll")
	procWinHttpQueryAuthSchemes = winhttp.NewProc("WinHttpQueryAuthSchemes")
)

// hRequest (void* in/out), lpdwSupportedSchemes (DWORD* in/out), lpdwFirstScheme (DWORD* in/out), pdwAuthTarget (DWORD* in/out)
r1, _, err := procWinHttpQueryAuthSchemes.Call(
	uintptr(hRequest),
	uintptr(lpdwSupportedSchemes),
	uintptr(lpdwFirstScheme),
	uintptr(pdwAuthTarget),
)
_ = err  // syscall.Errno (valid when the call sets last-error)
_ = r1   // BOOL
function WinHttpQueryAuthSchemes(
  hRequest: Pointer;   // void* in/out
  lpdwSupportedSchemes: Pointer;   // DWORD* in/out
  lpdwFirstScheme: Pointer;   // DWORD* in/out
  pdwAuthTarget: Pointer   // DWORD* in/out
): BOOL; stdcall;
  external 'WINHTTP.dll' name 'WinHttpQueryAuthSchemes';
result := DllCall("WINHTTP\WinHttpQueryAuthSchemes"
    , "Ptr", hRequest   ; void* in/out
    , "Ptr", lpdwSupportedSchemes   ; DWORD* in/out
    , "Ptr", lpdwFirstScheme   ; DWORD* in/out
    , "Ptr", pdwAuthTarget   ; DWORD* in/out
    , "Int")   ; return: BOOL
●WinHttpQueryAuthSchemes(hRequest, lpdwSupportedSchemes, lpdwFirstScheme, pdwAuthTarget) = DLL("WINHTTP.dll", "bool WinHttpQueryAuthSchemes(void*, void*, void*, void*)")
# 呼び出し: WinHttpQueryAuthSchemes(hRequest, lpdwSupportedSchemes, lpdwFirstScheme, pdwAuthTarget)
# hRequest : void* in/out -> "void*"
# lpdwSupportedSchemes : DWORD* in/out -> "void*"
# lpdwFirstScheme : DWORD* in/out -> "void*"
# pdwAuthTarget : DWORD* in/out -> "void*"
# なでしこ1は32bit・ANSI(Shift_JIS)。文字列=char*(ANSI)、ポインタ/ハンドル=void*(4byte)。
const std = @import("std");

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

typedef WinHttpQueryAuthSchemesNative = Int32 Function(Pointer<Void>, Pointer<Uint32>, Pointer<Uint32>, Pointer<Uint32>);
typedef WinHttpQueryAuthSchemesDart = int Function(Pointer<Void>, Pointer<Uint32>, Pointer<Uint32>, Pointer<Uint32>);
final WinHttpQueryAuthSchemes = DynamicLibrary.open('WINHTTP.dll')
    .lookupFunction<WinHttpQueryAuthSchemesNative, WinHttpQueryAuthSchemesDart>('WinHttpQueryAuthSchemes');
// hRequest : void* in/out -> Pointer<Void>
// lpdwSupportedSchemes : DWORD* in/out -> Pointer<Uint32>
// lpdwFirstScheme : DWORD* in/out -> Pointer<Uint32>
// pdwAuthTarget : DWORD* in/out -> Pointer<Uint32>
// 文字列は package:ffi の "...".toNativeUtf16()/toNativeUtf8() で変換。
{$mode objfpc}{$H+}
function WinHttpQueryAuthSchemes(
  hRequest: Pointer;   // void* in/out
  lpdwSupportedSchemes: Pointer;   // DWORD* in/out
  lpdwFirstScheme: Pointer;   // DWORD* in/out
  pdwAuthTarget: Pointer   // DWORD* in/out
): BOOL; stdcall;
  external 'WINHTTP.dll' name 'WinHttpQueryAuthSchemes';
import Foreign
import Foreign.C.Types
import Foreign.C.String

foreign import stdcall safe "WinHttpQueryAuthSchemes"
  c_WinHttpQueryAuthSchemes :: Ptr () -> Ptr Word32 -> Ptr Word32 -> Ptr Word32 -> IO CInt
-- hRequest : void* in/out -> Ptr ()
-- lpdwSupportedSchemes : DWORD* in/out -> Ptr Word32
-- lpdwFirstScheme : DWORD* in/out -> Ptr Word32
-- pdwAuthTarget : DWORD* in/out -> Ptr Word32
-- 要 GHC(Windows)。stdcall は x64 では ccall として扱われる。ブロックする API は safe 呼び出し推奨。
open Ctypes
open Foreign

let winhttpqueryauthschemes =
  foreign "WinHttpQueryAuthSchemes"
    ((ptr void) @-> (ptr uint32_t) @-> (ptr uint32_t) @-> (ptr uint32_t) @-> returning int32_t)
(* hRequest : void* in/out -> (ptr void) *)
(* lpdwSupportedSchemes : DWORD* in/out -> (ptr uint32_t) *)
(* lpdwFirstScheme : DWORD* in/out -> (ptr uint32_t) *)
(* pdwAuthTarget : DWORD* in/out -> (ptr uint32_t) *)
(* foreign は cdecl 前提。x64 Windows では WINAPI と一致。構造体は ctypes structure を定義のこと。 *)
(cffi:define-foreign-library winhttp (t "WINHTTP.dll"))
(cffi:use-foreign-library winhttp)

(cffi:defcfun ("WinHttpQueryAuthSchemes" win-http-query-auth-schemes :convention :stdcall) :int32
  (h-request :pointer)   ; void* in/out
  (lpdw-supported-schemes :pointer)   ; DWORD* in/out
  (lpdw-first-scheme :pointer)   ; DWORD* in/out
  (pdw-auth-target :pointer))   ; DWORD* in/out
; isize/usize(INT_PTR/SIZE_T)は x64 前提で :int64/:uint64。x86 では :int32/:uint32。
use Win32::API;
my $WinHttpQueryAuthSchemes = Win32::API::More->new('WINHTTP',
    'BOOL WinHttpQueryAuthSchemes(LPVOID hRequest, LPVOID lpdwSupportedSchemes, LPVOID lpdwFirstScheme, LPVOID pdwAuthTarget)');
# my $ret = $WinHttpQueryAuthSchemes->Call($hRequest, $lpdwSupportedSchemes, $lpdwFirstScheme, $pdwAuthTarget);
# hRequest : void* in/out -> LPVOID
# lpdwSupportedSchemes : DWORD* in/out -> LPVOID
# lpdwFirstScheme : DWORD* in/out -> LPVOID
# pdwAuthTarget : DWORD* in/out -> LPVOID
# 値渡し構造体は pack() した文字列、または Win32::API::Struct を使用。

関連項目

公式の関連項目