Win32 API 日本語リファレンス
ホームSystem.ApplicationInstallationAndServicing › QueryActCtxW

QueryActCtxW

関数
アクティベーションコンテキストの情報を問い合わせて取得する。
DLLKERNEL32.dll呼出規約winapiSetLastErrorあり対応OSWindows XP 以降

シグネチャ

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

BOOL QueryActCtxW(
    DWORD dwFlags,
    HANDLE hActCtx,
    void* pvSubInstance,   // optional
    DWORD ulInfoClass,
    void* pvBuffer,   // optional
    UINT_PTR cbBuffer,
    UINT_PTR* pcbWrittenOrRequired   // optional
);

パラメーター

名前方向説明
dwFlagsDWORDin

このパラメーターには、次のフラグビットのいずれかを設定する必要があります。

フラグ 意味
QUERY_ACTCTX_FLAG_USE_ACTIVE_ACTCTX
QueryActCtxW は、hActCtx で指定されたコンテキストではなく、スレッド上でアクティブなアクティベーションコンテキストを照会します。これは通常、ActivateActCtx に最後に渡されたアクティベーションコンテキストです。ActivateActCtx が呼び出されていない場合、アクティブなアクティベーションコンテキストは現在のプロセスの実行可能ファイルが使用するアクティベーションコンテキストになることがあります。その他の場合は、オペレーティングシステムがアクティブなアクティベーションコンテキストを決定します。たとえば、新しいスレッドのコールバック関数が呼び出されたとき、アクティブなアクティベーションコンテキストは、CreateThread を呼び出してスレッドを作成した時点でアクティブだったコンテキストになることがあります。
QUERY_ACTCTX_FLAG_ACTCTX_IS_HMODULE
QueryActCtxWhActCtxHMODULE データ型として解釈し、DLL または EXE に関連付けられたアクティベーションコンテキストを照会します。

DLL または EXE が読み込まれると、ローダーはリソースに格納されたマニフェストを確認します。ローダーが、リソース識別子が ISOLATIONAWARE_MANIFEST_ RESOURCE_ID に設定された RT_MANIFEST リソースを見つけると、ローダーは生成されたアクティベーションコンテキストを DLL または EXE に関連付けます。これは、QUERY_ACTCTX_FLAG_ACTCTX_IS_HMODULE フラグが設定されている場合に QueryActCtxW が照会するアクティベーションコンテキストです。

QUERY_ACTCTX_FLAG_ACTCTX_IS_ADDRESS
QueryActCtxWhActCtx を DLL または EXE 内のアドレスとして解釈し、その DLL または EXE に関連付けられたアクティベーションコンテキストを照会します。これは DLL または EXE 内の任意のアドレスを指定できます。たとえば、DLL または EXE 内の任意の関数のアドレスや、定数文字列などの任意の静的データのアドレスです。

DLL または EXE が読み込まれると、ローダーは QUERY_ACTCTX_FLAG_ACTCTX_IS_HMODULE と同じ方法で、リソースに格納されたマニフェストを確認します。

hActCtxHANDLEin照会対象のアクティベーションコンテキストへのハンドルです。
pvSubInstancevoid*inoptional

アクティベーションコンテキスト内のアセンブリ、またはアセンブリとファイルの組み合わせのインデックスです。pvSubInstance の意味は、ulInfoClass パラメーターの値で指定されるオプションによって異なります。

このパラメーターは null にできます。

ulInfoClass オプション 意味
AssemblyDetailedInformationInActivationContext
アクティベーションコンテキスト内のアセンブリのインデックスを指定する DWORD へのポインターです。これは QueryActCtxW が照会するアクティベーションコンテキストです。
FileInformationInAssemblyOfAssemblyInActivationContext
ACTIVATION_CONTEXT_QUERY_INDEX 構造体へのポインターです。このオプションを指定して QueryActCtxW を呼び出し、関数が成功した場合、返されたバッファーにはアセンブリ内のファイルに関する情報が格納されます。この情報は ASSEMBLY_FILE_DETAILED_INFORMATION 構造体の形式です。
ulInfoClassDWORDin

このパラメーターには、次の表に示す値のみを指定できます。

オプション 意味
ActivationContextBasicInformation
1
利用できません。
ActivationContextDetailedInformation
2
このオプションを指定して QueryActCtxW を呼び出し、関数が成功した場合、返されたバッファーにはアクティベーションコンテキストに関する詳細情報が格納されます。この情報は ACTIVATION_CONTEXT_DETAILED_INFORMATION 構造体の形式です。
AssemblyDetailedInformationInActivationContext
3
このオプションを指定して QueryActCtxW を呼び出し、関数が成功した場合、バッファーには pvSubInstance で指定されたインデックスを持つアセンブリに関する情報が格納されます。この情報は ACTIVATION_CONTEXT_ASSEMBLY_DETAILED_INFORMATION 構造体の形式です。
FileInformationInAssemblyOfAssemblyInActivationContext
4
アクティベーションコンテキスト内のいずれかのアセンブリに含まれるファイルに関する情報です。pvSubInstance パラメーターは ACTIVATION_CONTEXT_QUERY_INDEX 構造体を指している必要があります。このオプションを指定して QueryActCtxW を呼び出し、関数が成功した場合、返されたバッファーにはアセンブリ内のファイルに関する情報が格納されます。この情報は ASSEMBLY_FILE_DETAILED_INFORMATION 構造体の形式です。
RunlevelInformationInActivationContext
5
このオプションを指定して QueryActCtxW を呼び出し、関数が成功した場合、バッファーにはアクティベーションコンテキストの要求された実行レベルに関する情報が格納されます。この情報は ACTIVATION_CONTEXT_RUN_LEVEL_INFORMATION 構造体の形式です。

Windows Server 2003 および Windows XP: この値は利用できません。

CompatibilityInformationInActivationContext
6
このオプションを指定して QueryActCtxW を呼び出し、関数が成功した場合、バッファーには要求された互換性コンテキストに関する情報が格納されます。この情報は ACTIVATION_CONTEXT_COMPATIBILITY_INFORMATION 構造体の形式です。

Windows Server 2008 以前、および Windows Vista 以前: この値は利用できません。このオプションは Windows Server 2008 R2 および Windows 7 以降で利用できます。

pvBuffervoid*outoptional返される情報を格納するバッファーへのポインターです。このパラメーターは省略可能です。pvBuffernull の場合、cbBuffer は 0 でなければなりません。pvBuffer が指すバッファーのサイズが小さすぎる場合、QueryActCtxWERROR_INSUFFICIENT_BUFFER を返し、バッファーにはデータが書き込まれません。必要なバッファーのサイズを判定する方法については、「解説」セクションを参照してください。
cbBufferUINT_PTRinpvBuffer が指すバッファーのサイズ(バイト単位)です。このパラメーターは省略可能です。
pcbWrittenOrRequiredUINT_PTR*outoptional書き込まれた、または必要なバイト数です。pcbWrittenOrRequired パラメーターは、pvBufferNULL の場合にのみ NULL にできます。pcbWrittenOrRequiredNULL 以外の場合、返されるバッファーを格納するために必要なバイト数が設定されます。

戻り値の型: BOOL

公式ドキュメント

QueryActCtxW 関数はアクティベーションコンテキストを照会します。

戻り値

関数が成功した場合は TRUE を返します。それ以外の場合は FALSE を返します。

この関数は、GetLastError を呼び出すことで取得できるエラーを設定します。例については、最後のエラーコードの取得を参照してください。エラーコードの完全な一覧については、システムエラーコードを参照してください。

解説(Remarks)

cbBuffer パラメーターは、pvBuffer が指すバッファーのサイズをバイト単位で指定します。pvBufferNULL の場合、cbBuffer は 0 でなければなりません。pcbWrittenOrRequired パラメーターは、pvBufferNULL の場合にのみ NULL にできます。pcbWrittenOrRequired が戻り時に NULL 以外の場合、返される情報を格納するために必要なバイト数が設定されます。返される情報データが指定されたバッファーよりも大きい場合、QueryActCtxWERROR_INSUFFICIENT_BUFFER を返し、pvBuffer が指すバッファーにはデータが書き込まれません。

次の例は、最初に小さなバッファーで呼び出し、バッファーが小さすぎる場合に再度呼び出す方法を示しています。

SIZE_T cbRequired;
PVOID pvData = NULL;
SIZE_T cbAvailable = 0;

if (!QueryActCtxW(..., pvData, cbAvailable, &cbRequired) && (GetLastError()== ERROR_INSUFFICIENT_BUFFER))
{
    // Allocate enough space to store the returned buffer, fail if too small
    if (NULL == (pvData = HeapAlloc(GetProcessHeap(), 0, cbRequired)))
    {
        SetLastError(ERROR_NOT_ENOUGH_MEMORY);
        return FALSE;
    }
    cbAvailable = cbRequired;
    // Try again, this should succeed.
    if (QueryActCtxW(..., pvData, cbAvailable, &cbRequired))
    {
        // Use the returned data in pvData
    }
    HeapFree(GetProcessHeap(), 0, pvData);
    pvData = NULL;
}
出典・ライセンス: 上記「公式ドキュメント」の内容は Microsoft の Win32 API ドキュメント(MicrosoftDocs/sdk-api)を日本語に翻訳・改変したものです。© Microsoft Corporation. CC BY 4.0 で提供。
Microsoft 公式リファレンス: 英語 (en-us) · 日本語 (ja-jp) · 原文ソース (GitHub)

各言語での呼び出し定義

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

BOOL QueryActCtxW(
    DWORD dwFlags,
    HANDLE hActCtx,
    void* pvSubInstance,   // optional
    DWORD ulInfoClass,
    void* pvBuffer,   // optional
    UINT_PTR cbBuffer,
    UINT_PTR* pcbWrittenOrRequired   // optional
);
[return: MarshalAs(UnmanagedType.Bool)]
[DllImport("KERNEL32.dll", SetLastError = true, ExactSpelling = true)]
static extern bool QueryActCtxW(
    uint dwFlags,   // DWORD
    IntPtr hActCtx,   // HANDLE
    IntPtr pvSubInstance,   // void* optional
    uint ulInfoClass,   // DWORD
    IntPtr pvBuffer,   // void* optional, out
    UIntPtr cbBuffer,   // UINT_PTR
    IntPtr pcbWrittenOrRequired   // UINT_PTR* optional, out
);
<DllImport("KERNEL32.dll", SetLastError:=True, ExactSpelling:=True)>
Public Shared Function QueryActCtxW(
    dwFlags As UInteger,   ' DWORD
    hActCtx As IntPtr,   ' HANDLE
    pvSubInstance As IntPtr,   ' void* optional
    ulInfoClass As UInteger,   ' DWORD
    pvBuffer As IntPtr,   ' void* optional, out
    cbBuffer As UIntPtr,   ' UINT_PTR
    pcbWrittenOrRequired As IntPtr   ' UINT_PTR* optional, out
) As <MarshalAs(UnmanagedType.Bool)> Boolean
End Function
' dwFlags : DWORD
' hActCtx : HANDLE
' pvSubInstance : void* optional
' ulInfoClass : DWORD
' pvBuffer : void* optional, out
' cbBuffer : UINT_PTR
' pcbWrittenOrRequired : UINT_PTR* optional, out
Declare PtrSafe Function QueryActCtxW Lib "kernel32" ( _
    ByVal dwFlags As Long, _
    ByVal hActCtx As LongPtr, _
    ByVal pvSubInstance As LongPtr, _
    ByVal ulInfoClass As Long, _
    ByVal pvBuffer As LongPtr, _
    ByVal cbBuffer As LongPtr, _
    ByVal pcbWrittenOrRequired As LongPtr) As Long
' VBA7前提(PtrSafe)。32bit Office では LongPtr→Long。Integer=16bit / Long=32bit / LongLong=64bit。
import ctypes
from ctypes import wintypes

QueryActCtxW = ctypes.windll.kernel32.QueryActCtxW
QueryActCtxW.restype = wintypes.BOOL
QueryActCtxW.argtypes = [
    wintypes.DWORD,  # dwFlags : DWORD
    wintypes.HANDLE,  # hActCtx : HANDLE
    ctypes.POINTER(None),  # pvSubInstance : void* optional
    wintypes.DWORD,  # ulInfoClass : DWORD
    ctypes.POINTER(None),  # pvBuffer : void* optional, out
    ctypes.c_size_t,  # cbBuffer : UINT_PTR
    ctypes.POINTER(ctypes.c_size_t),  # pcbWrittenOrRequired : UINT_PTR* optional, out
]
# GetLastError: use ctypes.GetLastError() (or ctypes.WinDLL(use_last_error=True))
require 'fiddle'
require 'fiddle/import'

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

var (
	kernel32 = windows.NewLazySystemDLL("KERNEL32.dll")
	procQueryActCtxW = kernel32.NewProc("QueryActCtxW")
)

// dwFlags (DWORD), hActCtx (HANDLE), pvSubInstance (void* optional), ulInfoClass (DWORD), pvBuffer (void* optional, out), cbBuffer (UINT_PTR), pcbWrittenOrRequired (UINT_PTR* optional, out)
r1, _, err := procQueryActCtxW.Call(
	uintptr(dwFlags),
	uintptr(hActCtx),
	uintptr(pvSubInstance),
	uintptr(ulInfoClass),
	uintptr(pvBuffer),
	uintptr(cbBuffer),
	uintptr(pcbWrittenOrRequired),
)
_ = err  // syscall.Errno (valid when the call sets last-error)
_ = r1   // BOOL
function QueryActCtxW(
  dwFlags: DWORD;   // DWORD
  hActCtx: THandle;   // HANDLE
  pvSubInstance: Pointer;   // void* optional
  ulInfoClass: DWORD;   // DWORD
  pvBuffer: Pointer;   // void* optional, out
  cbBuffer: NativeUInt;   // UINT_PTR
  pcbWrittenOrRequired: Pointer   // UINT_PTR* optional, out
): BOOL; stdcall;
  external 'KERNEL32.dll' name 'QueryActCtxW';
result := DllCall("KERNEL32\QueryActCtxW"
    , "UInt", dwFlags   ; DWORD
    , "Ptr", hActCtx   ; HANDLE
    , "Ptr", pvSubInstance   ; void* optional
    , "UInt", ulInfoClass   ; DWORD
    , "Ptr", pvBuffer   ; void* optional, out
    , "UPtr", cbBuffer   ; UINT_PTR
    , "Ptr", pcbWrittenOrRequired   ; UINT_PTR* optional, out
    , "Int")   ; return: BOOL
●QueryActCtxW(dwFlags, hActCtx, pvSubInstance, ulInfoClass, pvBuffer, cbBuffer, pcbWrittenOrRequired) = DLL("KERNEL32.dll", "bool QueryActCtxW(dword, void*, void*, dword, void*, int, void*)")
# 呼び出し: QueryActCtxW(dwFlags, hActCtx, pvSubInstance, ulInfoClass, pvBuffer, cbBuffer, pcbWrittenOrRequired)
# dwFlags : DWORD -> "dword"
# hActCtx : HANDLE -> "void*"
# pvSubInstance : void* optional -> "void*"
# ulInfoClass : DWORD -> "dword"
# pvBuffer : void* optional, out -> "void*"
# cbBuffer : UINT_PTR -> "int"
# pcbWrittenOrRequired : UINT_PTR* optional, out -> "void*"
# なでしこ1は32bit・ANSI(Shift_JIS)。文字列=char*(ANSI)、ポインタ/ハンドル=void*(4byte)。
const std = @import("std");

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

typedef QueryActCtxWNative = Int32 Function(Uint32, Pointer<Void>, Pointer<Void>, Uint32, Pointer<Void>, UintPtr, Pointer<UintPtr>);
typedef QueryActCtxWDart = int Function(int, Pointer<Void>, Pointer<Void>, int, Pointer<Void>, int, Pointer<UintPtr>);
final QueryActCtxW = DynamicLibrary.open('KERNEL32.dll')
    .lookupFunction<QueryActCtxWNative, QueryActCtxWDart>('QueryActCtxW');
// dwFlags : DWORD -> Uint32
// hActCtx : HANDLE -> Pointer<Void>
// pvSubInstance : void* optional -> Pointer<Void>
// ulInfoClass : DWORD -> Uint32
// pvBuffer : void* optional, out -> Pointer<Void>
// cbBuffer : UINT_PTR -> UintPtr
// pcbWrittenOrRequired : UINT_PTR* optional, out -> Pointer<UintPtr>
// 文字列は package:ffi の "...".toNativeUtf16()/toNativeUtf8() で変換。
{$mode objfpc}{$H+}
function QueryActCtxW(
  dwFlags: DWORD;   // DWORD
  hActCtx: THandle;   // HANDLE
  pvSubInstance: Pointer;   // void* optional
  ulInfoClass: DWORD;   // DWORD
  pvBuffer: Pointer;   // void* optional, out
  cbBuffer: NativeUInt;   // UINT_PTR
  pcbWrittenOrRequired: Pointer   // UINT_PTR* optional, out
): BOOL; stdcall;
  external 'KERNEL32.dll' name 'QueryActCtxW';
import Foreign
import Foreign.C.Types
import Foreign.C.String

foreign import stdcall safe "QueryActCtxW"
  c_QueryActCtxW :: Word32 -> Ptr () -> Ptr () -> Word32 -> Ptr () -> CUIntPtr -> Ptr CUIntPtr -> IO CInt
-- dwFlags : DWORD -> Word32
-- hActCtx : HANDLE -> Ptr ()
-- pvSubInstance : void* optional -> Ptr ()
-- ulInfoClass : DWORD -> Word32
-- pvBuffer : void* optional, out -> Ptr ()
-- cbBuffer : UINT_PTR -> CUIntPtr
-- pcbWrittenOrRequired : UINT_PTR* optional, out -> Ptr CUIntPtr
-- 要 GHC(Windows)。stdcall は x64 では ccall として扱われる。ブロックする API は safe 呼び出し推奨。
open Ctypes
open Foreign

let queryactctxw =
  foreign "QueryActCtxW"
    (uint32_t @-> (ptr void) @-> (ptr void) @-> uint32_t @-> (ptr void) @-> size_t @-> (ptr size_t) @-> returning int32_t)
(* dwFlags : DWORD -> uint32_t *)
(* hActCtx : HANDLE -> (ptr void) *)
(* pvSubInstance : void* optional -> (ptr void) *)
(* ulInfoClass : DWORD -> uint32_t *)
(* pvBuffer : void* optional, out -> (ptr void) *)
(* cbBuffer : UINT_PTR -> size_t *)
(* pcbWrittenOrRequired : UINT_PTR* optional, out -> (ptr size_t) *)
(* foreign は cdecl 前提。x64 Windows では WINAPI と一致。構造体は ctypes structure を定義のこと。 *)
(cffi:define-foreign-library kernel32 (t "KERNEL32.dll"))
(cffi:use-foreign-library kernel32)

(cffi:defcfun ("QueryActCtxW" query-act-ctx-w :convention :stdcall) :int32
  (dw-flags :uint32)   ; DWORD
  (h-act-ctx :pointer)   ; HANDLE
  (pv-sub-instance :pointer)   ; void* optional
  (ul-info-class :uint32)   ; DWORD
  (pv-buffer :pointer)   ; void* optional, out
  (cb-buffer :uint64)   ; UINT_PTR
  (pcb-written-or-required :pointer))   ; UINT_PTR* optional, out
; isize/usize(INT_PTR/SIZE_T)は x64 前提で :int64/:uint64。x86 では :int32/:uint32。
use Win32::API;
my $QueryActCtxW = Win32::API::More->new('KERNEL32',
    'BOOL QueryActCtxW(DWORD dwFlags, HANDLE hActCtx, LPVOID pvSubInstance, DWORD ulInfoClass, LPVOID pvBuffer, WPARAM cbBuffer, LPVOID pcbWrittenOrRequired)');
# my $ret = $QueryActCtxW->Call($dwFlags, $hActCtx, $pvSubInstance, $ulInfoClass, $pvBuffer, $cbBuffer, $pcbWrittenOrRequired);
# dwFlags : DWORD -> DWORD
# hActCtx : HANDLE -> HANDLE
# pvSubInstance : void* optional -> LPVOID
# ulInfoClass : DWORD -> DWORD
# pvBuffer : void* optional, out -> LPVOID
# cbBuffer : UINT_PTR -> WPARAM
# pcbWrittenOrRequired : UINT_PTR* optional, out -> LPVOID
# 値渡し構造体は pack() した文字列、または Win32::API::Struct を使用。