Win32 API 日本語リファレンス
ホーム › Security.Authentication.Identity › LsaLookupSids2

LsaLookupSids2

関数
SIDの配列を対応するアカウント名へ変換する拡張版である。
DLLADVAPI32.dll呼出規約winapi対応OSwindows8.0

シグネチャ

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

NTSTATUS LsaLookupSids2(
    LSA_HANDLE PolicyHandle,
    DWORD LookupOptions,
    DWORD Count,
    PSID* Sids,
    LSA_REFERENCED_DOMAIN_LIST** ReferencedDomains,
    LSA_TRANSLATED_NAME** Names
);

パラメーター

名前型方向説明
PolicyHandleLSA_HANDLEinPolicy オブジェクトへのハンドル。このハンドルには POLICY_LOOKUP_NAMES アクセス権が必要です。詳細については、 Opening a Policy Object Handle を参照してください。
LookupOptionsDWORDin

検索の動作を変更するフラグ。

値 意味
LSA_LOOKUP_DISALLOW_CONNECTED_ACCOUNT_INTERNET_SID
接続されたアカウントの ID プロバイダーによるインターネット SID を許可しません。接続されたアカウントとは、オンライン ID プロバイダーに接続された、ローカル SAM データベース内の対応するシャドウ アカウントを持つアカウントです。たとえば、MicrosoftAccount は接続されたアカウントです。
LSA_LOOKUP_PREFER_INTERNET_NAMES
インターネット名を返します。それ以外の場合は、NT4 形式の名前 (domain\username) が返されます。ただし、Microsoft アカウントのインターネット SID が指定された場合は例外で、LSA_LOOKUP_DISALLOW_NON_WINDOWS_INTERNET_SID が指定されていない限りインターネット名が返されます。
LSA_LOOKUP_RETURN_LOCAL_NAMES
インターネット プロバイダー ID の場合でも、常にローカル SAM アカウント名を返します。
CountDWORDinSids 配列内の SID の数を指定します。これは Names 配列で返されるエントリの数でもあります。この値は 20480 以下である必要があります。
SidsPSID*in検索対象の SID ポインターの配列へのポインター。SID には、well-known SID、ユーザー、グループ、ローカル グループのアカウント SID、またはドメイン SID を指定できます。
ReferencedDomainsLSA_REFERENCED_DOMAIN_LIST**out

LSA_REFERENCED_DOMAIN_LIST 構造体へのポインターのポインターを受け取ります。この構造体の Domains メンバーは、SID が見つかったドメインごとのエントリを含む配列です。各ドメインのエントリには、そのドメインの SID とフラット名が格納されます。Windows ドメインの場合、フラット名は NetBIOS 名です。Windows 以外のドメインとのリンクの場合、フラット名はそのドメインを識別する名前であるか、NULL です。

この情報が不要になったら、返されたポインターを LsaFreeMemory に渡してください。このメモリは、関数がエラー コード STATUS_NONE_MAPPED または STATUS_SOME_NOT_MAPPED のいずれかで失敗した場合でも解放する必要があります

NamesLSA_TRANSLATED_NAME**out

LSA_TRANSLATED_NAME 構造体の配列へのポインターを受け取ります。Names 配列の各エントリには、Sids 配列内の対応するエントリの名前情報が格納されます。アカウント SID の場合、各構造体の Name メンバーにはアカウントの分離名 (isolated name) が格納されます。ドメイン SID の場合、Name メンバーは有効ではありません。

Names 配列の各エントリの DomainIndex メンバーは、ReferencedDomains パラメーターで返される Domains 配列内のエントリのインデックスです。このインデックスは、SID が見つかったドメインに対応する Domains 配列のエントリを示します。

この情報が不要になったら、返されたポインターを LsaFreeMemory に渡してください。このメモリは、関数がエラー コード STATUS_NONE_MAPPED または STATUS_SOME_NOT_MAPPED のいずれかで失敗した場合でも解放する必要があります

戻り値の型: NTSTATUS

公式ドキュメント

セキュリティ識別子 (SID) の配列に対応する名前を検索します。インターネット プロバイダー ID もサポートします。LsaLookupSids2 が SID に対応する名前を見つけられない場合、この関数は SID を文字形式で返します。

戻り値

関数が成功した場合、戻り値は次のいずれかの NTSTATUS 値です。

戻り値 説明
STATUS_SOME_NOT_MAPPED
一部の SID を変換できませんでした。これは情報レベルの戻り値です。
STATUS_SUCCESS
すべての SID が見つかり、正常に変換されました。

関数が失敗した場合、戻り値は NTSTATUS コードであり、次のいずれかの値、または LSA Policy Function Return Values のいずれかになります。

戻り値 説明
STATUS_NONE_MAPPED
どの SID も変換されませんでした。これはエラー レベルの戻り値です。
STATUS_TOO_MANY_SIDS
Sids 配列パラメーターが大きすぎます。

LsaNtStatusToWinError 関数を使用すると、NTSTATUS コードを Windows エラー コードに変換できます。

解説(Remarks)

LSA_LOOKUP_PREFER_INTERNET_NAMES フラグは、MicrosoftAccount や Azure Active Directory アカウントなどのインターネット アカウントに使用してください。 このフラグを指定すると、SID から名前への検索では、MicrosoftAccount\foo@outlook.com や AzureAD\foo@contoso.com という形式でアカウントの UPN が返されます。 Microsoft アカウントの場合、このフラグを指定すると、ローカル SAM SID とインターネット SID のどちらでも UPN が返されます。 LSA_LOOKUP_PREFER_INTERNET_NAMES を指定しない場合、AAD アカウントについては AzureAD\foo という形式の NT4 形式の名前が返されます。NT4 形式の名前はコンピューター固有であるため、その使用は慎重に検討し、可能であれば避けるべきです。 MicrosoftAccount の場合、LSA_LOOKUP_PREFER_INTERNET_NAMES を指定しないと、アカウントのローカル SID はローカル SAM 名に、インターネット SID は UPN 名に変換されます。

アカウント SID の場合、Name メンバーで返される文字列はアカウントの分離名 (isolated name) です (例: user_name)。アカウントの複合名 (例: Acctg\user_name) が必要な場合は、ReferencedDomains バッファーからドメイン名を取得し、円記号と分離名を追加してください。

LsaLookupSids2 関数が SID を変換できない場合、この関数は次のアルゴリズムを使用します。

  1. SID のドメインが判明している場合、ReferencedDomains バッファーにはそのドメインのエントリが格納され、Names パラメーターで返される文字列は、SID に含まれるアカウントの相対識別子 (RID) の Unicode 表現になります。
  2. SID のドメインが判明していない場合、Names パラメーターで返される文字列は SID 全体の Unicode 表現になり、この SID に対応するドメイン レコードは ReferencedDomains バッファーに含まれません。
LsaLookupSids2 は、ローカル アカウント、ローカル ドメイン アカウント、および明示的に信頼されたドメインのアカウントの SID を検索するだけでなく、Windows フォレスト内の任意のドメインにある任意のアカウントの SID を検索できます。これには、フォレスト内のアカウントの SIDhistory フィールドにのみ存在する SID も含まれます。SIDhistory フィールドには、他のドメインから移動されたアカウントの以前の SID が格納されます。これらの検索を実行するために、この関数はフォレストのグローバル カタログに問い合わせます。
出典・ライセンス: 上記「公式ドキュメント」の内容は Microsoft の Win32 API ドキュメント(MicrosoftDocs/sdk-api)を日本語に翻訳・改変したものです。© Microsoft Corporation. CC BY 4.0 で提供。
Microsoft 公式リファレンス: 英語 (en-us) · 日本語 (ja-jp) · 原文ソース (GitHub)

各言語での呼び出し定義

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

NTSTATUS LsaLookupSids2(
    LSA_HANDLE PolicyHandle,
    DWORD LookupOptions,
    DWORD Count,
    PSID* Sids,
    LSA_REFERENCED_DOMAIN_LIST** ReferencedDomains,
    LSA_TRANSLATED_NAME** Names
);
[DllImport("ADVAPI32.dll", ExactSpelling = true)]
static extern int LsaLookupSids2(
    IntPtr PolicyHandle,   // LSA_HANDLE
    uint LookupOptions,   // DWORD
    uint Count,   // DWORD
    IntPtr Sids,   // PSID*
    IntPtr ReferencedDomains,   // LSA_REFERENCED_DOMAIN_LIST** out
    IntPtr Names   // LSA_TRANSLATED_NAME** out
);
<DllImport("ADVAPI32.dll", ExactSpelling:=True)>
Public Shared Function LsaLookupSids2(
    PolicyHandle As IntPtr,   ' LSA_HANDLE
    LookupOptions As UInteger,   ' DWORD
    Count As UInteger,   ' DWORD
    Sids As IntPtr,   ' PSID*
    ReferencedDomains As IntPtr,   ' LSA_REFERENCED_DOMAIN_LIST** out
    Names As IntPtr   ' LSA_TRANSLATED_NAME** out
) As Integer
End Function
' PolicyHandle : LSA_HANDLE
' LookupOptions : DWORD
' Count : DWORD
' Sids : PSID*
' ReferencedDomains : LSA_REFERENCED_DOMAIN_LIST** out
' Names : LSA_TRANSLATED_NAME** out
Declare PtrSafe Function LsaLookupSids2 Lib "advapi32" ( _
    ByVal PolicyHandle As LongPtr, _
    ByVal LookupOptions As Long, _
    ByVal Count As Long, _
    ByVal Sids As LongPtr, _
    ByVal ReferencedDomains As LongPtr, _
    ByVal Names As LongPtr) As Long
' VBA7前提(PtrSafe)。32bit Office では LongPtr→Long。Integer=16bit / Long=32bit / LongLong=64bit。
import ctypes
from ctypes import wintypes

LsaLookupSids2 = ctypes.windll.advapi32.LsaLookupSids2
LsaLookupSids2.restype = ctypes.c_int
LsaLookupSids2.argtypes = [
    ctypes.c_ssize_t,  # PolicyHandle : LSA_HANDLE
    wintypes.DWORD,  # LookupOptions : DWORD
    wintypes.DWORD,  # Count : DWORD
    ctypes.c_void_p,  # Sids : PSID*
    ctypes.c_void_p,  # ReferencedDomains : LSA_REFERENCED_DOMAIN_LIST** out
    ctypes.c_void_p,  # Names : LSA_TRANSLATED_NAME** out
]
require 'fiddle'
require 'fiddle/import'

lib = Fiddle.dlopen('ADVAPI32.dll')
LsaLookupSids2 = Fiddle::Function.new(
  lib['LsaLookupSids2'],
  [
    Fiddle::TYPE_INTPTR_T,  # PolicyHandle : LSA_HANDLE
    -Fiddle::TYPE_INT,  # LookupOptions : DWORD
    -Fiddle::TYPE_INT,  # Count : DWORD
    Fiddle::TYPE_VOIDP,  # Sids : PSID*
    Fiddle::TYPE_VOIDP,  # ReferencedDomains : LSA_REFERENCED_DOMAIN_LIST** out
    Fiddle::TYPE_VOIDP,  # Names : LSA_TRANSLATED_NAME** out
  ],
  Fiddle::TYPE_INT)
#[link(name = "advapi32")]
extern "system" {
    fn LsaLookupSids2(
        PolicyHandle: isize,  // LSA_HANDLE
        LookupOptions: u32,  // DWORD
        Count: u32,  // DWORD
        Sids: *mut *mut core::ffi::c_void,  // PSID*
        ReferencedDomains: *mut *mut LSA_REFERENCED_DOMAIN_LIST,  // LSA_REFERENCED_DOMAIN_LIST** out
        Names: *mut *mut LSA_TRANSLATED_NAME  // LSA_TRANSLATED_NAME** out
    ) -> i32;
}
// crates: windows-sys provides ready-made bindings for this API.
$sig = @"
[DllImport("ADVAPI32.dll")]
public static extern int LsaLookupSids2(IntPtr PolicyHandle, uint LookupOptions, uint Count, IntPtr Sids, IntPtr ReferencedDomains, IntPtr Names);
"@
$api = Add-Type -MemberDefinition $sig -Name 'ADVAPI32_LsaLookupSids2' -Namespace Win32 -PassThru
# $api::LsaLookupSids2(PolicyHandle, LookupOptions, Count, Sids, ReferencedDomains, Names)
#uselib "ADVAPI32.dll"
#func global LsaLookupSids2 "LsaLookupSids2" sptr, sptr, sptr, sptr, sptr, sptr
; LsaLookupSids2 PolicyHandle, LookupOptions, Count, Sids, varptr(ReferencedDomains), varptr(Names)   ; 戻り値は stat
; PolicyHandle : LSA_HANDLE -> "sptr"
; LookupOptions : DWORD -> "sptr"
; Count : DWORD -> "sptr"
; Sids : PSID* -> "sptr"
; ReferencedDomains : LSA_REFERENCED_DOMAIN_LIST** out -> "sptr"
; Names : LSA_TRANSLATED_NAME** out -> "sptr"
; ※HSP3.7は #func のため戻り値はシステム変数 stat に格納されます。
出力引数:
#uselib "ADVAPI32.dll"
#cfunc global LsaLookupSids2 "LsaLookupSids2" sptr, int, int, sptr, var, var
; res = LsaLookupSids2(PolicyHandle, LookupOptions, Count, Sids, ReferencedDomains, Names)
; PolicyHandle : LSA_HANDLE -> "sptr"
; LookupOptions : DWORD -> "int"
; Count : DWORD -> "int"
; Sids : PSID* -> "sptr"
; ReferencedDomains : LSA_REFERENCED_DOMAIN_LIST** out -> "var"
; Names : LSA_TRANSLATED_NAME** out -> "var"
; ※出力/バッファ引数は var 方式(変数を直接渡す)。varptr 方式にも切替可。
出力引数:
; NTSTATUS LsaLookupSids2(LSA_HANDLE PolicyHandle, DWORD LookupOptions, DWORD Count, PSID* Sids, LSA_REFERENCED_DOMAIN_LIST** ReferencedDomains, LSA_TRANSLATED_NAME** Names)
#uselib "ADVAPI32.dll"
#cfunc global LsaLookupSids2 "LsaLookupSids2" intptr, int, int, intptr, var, var
; res = LsaLookupSids2(PolicyHandle, LookupOptions, Count, Sids, ReferencedDomains, Names)
; PolicyHandle : LSA_HANDLE -> "intptr"
; LookupOptions : DWORD -> "int"
; Count : DWORD -> "int"
; Sids : PSID* -> "intptr"
; ReferencedDomains : LSA_REFERENCED_DOMAIN_LIST** out -> "var"
; Names : LSA_TRANSLATED_NAME** out -> "var"
; ※出力/バッファ引数は var 方式(変数を直接渡す)。varptr 方式にも切替可。
import (
	"golang.org/x/sys/windows"
	"unsafe"
)

var (
	advapi32 = windows.NewLazySystemDLL("ADVAPI32.dll")
	procLsaLookupSids2 = advapi32.NewProc("LsaLookupSids2")
)

// PolicyHandle (LSA_HANDLE), LookupOptions (DWORD), Count (DWORD), Sids (PSID*), ReferencedDomains (LSA_REFERENCED_DOMAIN_LIST** out), Names (LSA_TRANSLATED_NAME** out)
r1, _, err := procLsaLookupSids2.Call(
	uintptr(PolicyHandle),
	uintptr(LookupOptions),
	uintptr(Count),
	uintptr(Sids),
	uintptr(ReferencedDomains),
	uintptr(Names),
)
_ = err  // syscall.Errno (valid when the call sets last-error)
_ = r1   // NTSTATUS
function LsaLookupSids2(
  PolicyHandle: NativeInt;   // LSA_HANDLE
  LookupOptions: DWORD;   // DWORD
  Count: DWORD;   // DWORD
  Sids: Pointer;   // PSID*
  ReferencedDomains: Pointer;   // LSA_REFERENCED_DOMAIN_LIST** out
  Names: Pointer   // LSA_TRANSLATED_NAME** out
): Integer; stdcall;
  external 'ADVAPI32.dll' name 'LsaLookupSids2';
result := DllCall("ADVAPI32\LsaLookupSids2"
    , "Ptr", PolicyHandle   ; LSA_HANDLE
    , "UInt", LookupOptions   ; DWORD
    , "UInt", Count   ; DWORD
    , "Ptr", Sids   ; PSID*
    , "Ptr", ReferencedDomains   ; LSA_REFERENCED_DOMAIN_LIST** out
    , "Ptr", Names   ; LSA_TRANSLATED_NAME** out
    , "Int")   ; return: NTSTATUS
●LsaLookupSids2(PolicyHandle, LookupOptions, Count, Sids, ReferencedDomains, Names) = DLL("ADVAPI32.dll", "int LsaLookupSids2(int, dword, dword, void*, void*, void*)")
# 呼び出し: LsaLookupSids2(PolicyHandle, LookupOptions, Count, Sids, ReferencedDomains, Names)
# PolicyHandle : LSA_HANDLE -> "int"
# LookupOptions : DWORD -> "dword"
# Count : DWORD -> "dword"
# Sids : PSID* -> "void*"
# ReferencedDomains : LSA_REFERENCED_DOMAIN_LIST** out -> "void*"
# Names : LSA_TRANSLATED_NAME** out -> "void*"
# なでしこ1は32bit・ANSI(Shift_JIS)。文字列=char*(ANSI)、ポインタ/ハンドル=void*(4byte)。
const std = @import("std");

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

typedef LsaLookupSids2Native = Int32 Function(IntPtr, Uint32, Uint32, Pointer<Void>, Pointer<Void>, Pointer<Void>);
typedef LsaLookupSids2Dart = int Function(int, int, int, Pointer<Void>, Pointer<Void>, Pointer<Void>);
final LsaLookupSids2 = DynamicLibrary.open('ADVAPI32.dll')
    .lookupFunction<LsaLookupSids2Native, LsaLookupSids2Dart>('LsaLookupSids2');
// PolicyHandle : LSA_HANDLE -> IntPtr
// LookupOptions : DWORD -> Uint32
// Count : DWORD -> Uint32
// Sids : PSID* -> Pointer<Void>
// ReferencedDomains : LSA_REFERENCED_DOMAIN_LIST** out -> Pointer<Void>
// Names : LSA_TRANSLATED_NAME** out -> Pointer<Void>
// 文字列は package:ffi の "...".toNativeUtf16()/toNativeUtf8() で変換。
{$mode objfpc}{$H+}
function LsaLookupSids2(
  PolicyHandle: NativeInt;   // LSA_HANDLE
  LookupOptions: DWORD;   // DWORD
  Count: DWORD;   // DWORD
  Sids: Pointer;   // PSID*
  ReferencedDomains: Pointer;   // LSA_REFERENCED_DOMAIN_LIST** out
  Names: Pointer   // LSA_TRANSLATED_NAME** out
): Integer; stdcall;
  external 'ADVAPI32.dll' name 'LsaLookupSids2';
import Foreign
import Foreign.C.Types
import Foreign.C.String

foreign import stdcall safe "LsaLookupSids2"
  c_LsaLookupSids2 :: CIntPtr -> Word32 -> Word32 -> Ptr () -> Ptr () -> Ptr () -> IO Int32
-- PolicyHandle : LSA_HANDLE -> CIntPtr
-- LookupOptions : DWORD -> Word32
-- Count : DWORD -> Word32
-- Sids : PSID* -> Ptr ()
-- ReferencedDomains : LSA_REFERENCED_DOMAIN_LIST** out -> Ptr ()
-- Names : LSA_TRANSLATED_NAME** out -> Ptr ()
-- 要 GHC(Windows)。stdcall は x64 では ccall として扱われる。ブロックする API は safe 呼び出し推奨。
open Ctypes
open Foreign

let lsalookupsids2 =
  foreign "LsaLookupSids2"
    (intptr_t @-> uint32_t @-> uint32_t @-> (ptr void) @-> (ptr void) @-> (ptr void) @-> returning int32_t)
(* PolicyHandle : LSA_HANDLE -> intptr_t *)
(* LookupOptions : DWORD -> uint32_t *)
(* Count : DWORD -> uint32_t *)
(* Sids : PSID* -> (ptr void) *)
(* ReferencedDomains : LSA_REFERENCED_DOMAIN_LIST** out -> (ptr void) *)
(* Names : LSA_TRANSLATED_NAME** out -> (ptr void) *)
(* foreign は cdecl 前提。x64 Windows では WINAPI と一致。構造体は ctypes structure を定義のこと。 *)
(cffi:define-foreign-library advapi32 (t "ADVAPI32.dll"))
(cffi:use-foreign-library advapi32)

(cffi:defcfun ("LsaLookupSids2" lsa-lookup-sids2 :convention :stdcall) :int32
  (policy-handle :int64)   ; LSA_HANDLE
  (lookup-options :uint32)   ; DWORD
  (count :uint32)   ; DWORD
  (sids :pointer)   ; PSID*
  (referenced-domains :pointer)   ; LSA_REFERENCED_DOMAIN_LIST** out
  (names :pointer))   ; LSA_TRANSLATED_NAME** out
; isize/usize(INT_PTR/SIZE_T)は x64 前提で :int64/:uint64。x86 では :int32/:uint32。
use Win32::API;
my $LsaLookupSids2 = Win32::API::More->new('ADVAPI32',
    'int LsaLookupSids2(LPARAM PolicyHandle, DWORD LookupOptions, DWORD Count, HANDLE Sids, LPVOID ReferencedDomains, LPVOID Names)');
# my $ret = $LsaLookupSids2->Call($PolicyHandle, $LookupOptions, $Count, $Sids, $ReferencedDomains, $Names);
# PolicyHandle : LSA_HANDLE -> LPARAM
# LookupOptions : DWORD -> DWORD
# Count : DWORD -> DWORD
# Sids : PSID* -> HANDLE
# ReferencedDomains : LSA_REFERENCED_DOMAIN_LIST** out -> LPVOID
# Names : LSA_TRANSLATED_NAME** out -> LPVOID
# 値渡し構造体は pack() した文字列、または Win32::API::Struct を使用。

関連項目

類似 API
公式の関連項目
使用する型