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

LsaLogonUser

関数
指定した認証情報でユーザーをログオンさせアクセストークンを取得する。
DLLSECUR32.dll呼出規約winapi対応OSWindows XP 以降

シグネチャ

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

NTSTATUS LsaLogonUser(
    HANDLE LsaHandle,
    LSA_STRING* OriginName,
    SECURITY_LOGON_TYPE LogonType,
    DWORD AuthenticationPackage,
    void* AuthenticationInformation,
    DWORD AuthenticationInformationLength,
    TOKEN_GROUPS* LocalGroups,   // optional
    TOKEN_SOURCE* SourceContext,
    void** ProfileBuffer,
    DWORD* ProfileBufferLength,
    LUID* LogonId,
    HANDLE* Token,
    QUOTA_LIMITS* Quotas,
    INT* SubStatus
);

パラメーター

名前型方向説明
LsaHandleHANDLEin

以前の LsaRegisterLogonProcess の呼び出しで取得したハンドル。

次のいずれかに該当する場合に限り、呼び出し元は SeTcbPrivilege を保持している必要があります。

  • サブ認証パッケージを使用する。
  • KERB_S4U_LOGON を使用し、呼び出し元が偽装トークンを要求する。
  • LocalGroups パラメーターが NULL でない。
SeTcbPrivilege が不要な場合は、LsaConnectUntrusted を呼び出してハンドルを取得します。
OriginNameLSA_STRING*inログオン試行の発生元を示す文字列。詳細については「解説」を参照してください。
LogonTypeSECURITY_LOGON_TYPEin要求するログオンの種類を指定する SECURITY_LOGON_TYPE 列挙型の値。LogonType が Interactive または Batch の場合、新しいユーザーを表すプライマリ トークンが生成されます。LogonType が Network の場合は、偽装トークンが生成されます。
AuthenticationPackageDWORDin認証に使用する認証パッケージの識別子。この値は LsaLookupAuthenticationPackage を呼び出して取得できます。
AuthenticationInformationvoid*in

ユーザー名やパスワードなどの認証情報を含む入力バッファーへのポインター。このバッファーの形式と内容は、認証パッケージによって決まります。

このパラメーターには、MSV1_0 および Kerberos 認証パッケージ向けの次の入力バッファー構造体のいずれかを指定できます。

値 意味
MSV1_0_INTERACTIVE_LOGON
MSV1_0
対話型ユーザー ログオンを認証します。

MSV1_0_INTERACTIVE_LOGON 構造体の LogonDomainName、UserName、Password の各メンバーは、構造体自体と連続するメモリ上のバッファーを指している必要があります。AuthenticationInformationLength パラメーターの値には、これらのバッファーの長さを含める必要があります。

KERB_INTERACTIVE_LOGON
Kerberos
対話型ユーザー ログオンを認証します。
KERB_TICKET_LOGON
Kerberos
初回のネットワーク ログオン時または切断時にユーザーを認証します。
KERB_TICKET_UNLOCK_LOGON
Kerberos
チケットの更新時にユーザーを認証します。通常のワークステーションのロック解除ログオンの一種です。
KERB_CERTIFICATE_LOGON
Kerberos
対話型のスマート カード ログオンを使用してユーザーを認証します。
KERB_CERTIFICATE_S4U_LOGON
Kerberos
サービス フォー ユーザー (S4U) ログオンを使用してユーザーを認証します。
KERB_CERTIFICATE_UNLOCK_LOGON
Kerberos
対話型のスマート カード ログオン セッション中にロックされたワークステーションのロックを解除するために、ユーザーを認証します。
KERB_SMARTCARD_LOGON
Kerberos
LOGON32_PROVIDER_WINNT50 または LOGON32_PROVIDER_DEFAULT を使用したユーザーのスマート カード ログオンを認証します。
KERB_SMARTCARD_UNLOCK_LOGON
Kerberos
スマート カード ログオン セッション中にロックされたワークステーションのロックを解除するために、ユーザーを認証します。
KERB_S4U_LOGON
Kerberos
S4U クライアント要求を使用してユーザーを認証します。制約付き委任の場合、クライアントが LSA モードの認証パッケージを使用してログオンしていれば、LsaLogonUser を呼び出す必要はありません。Windows オペレーティング システムでは、これには Kerberos、NTLM、Secure Channel、Digest が含まれます。この呼び出しが成功するには、次の条件を満たしている必要があります。
  • 呼び出し元がドメイン アカウントであること (コンピューターがドメインのメンバーである場合は LOCAL_SYSTEM も含まれます)。
  • サービス アカウントを使用する場合、偽装トークンを取得するには、そのアカウントにローカル コンピューター上で SeTcbPrivilege が設定されている必要があります。設定されていない場合は、ID トークンが使用されます。
  • 呼び出し元は Pre-Windows 2000 Compatible Access のメンバーであるか、クライアントのグループ メンバーシップに対する読み取りアクセス権を持っている必要があります。Windows Authorization Access グループのメンバーであれば、クライアントのグループ メンバーシップへの読み取りアクセスが保証されます。Windows Authorization Access グループの構成方法については、Microsoft サポート技術情報 (Knowledge Base) を参照してください。
KERB_S4U_LOGON 構造体の ClientUpn メンバーと ClientRealm メンバーは、構造体自体と連続するメモリ上のバッファーを指している必要があります。AuthenticationInformationLength パラメーターの値には、これらのバッファーの長さを含める必要があります。
MSV1_0_LM20_LOGON
MSV1_0
NTLM 2.0 プロトコル ログオンの後半を処理します。この種類のログオンの前半は、MsV1_0Lm20ChallengeRequest メッセージを指定して LsaCallAuthenticationPackage を呼び出すことで実行します。詳細については、 MSV1_0_PROTOCOL_MESSAGE_TYPE の MsV1_0Lm20ChallengeRequest の説明を参照してください。

この種類のログオンではサブ認証パッケージを使用できます。

MSV1_0_SUBAUTH_LOGON
MSV1_0
サブ認証を使用してユーザーを認証します。

他の認証パッケージが使用するバッファーについては、それらの認証パッケージのドキュメントを参照してください。

AuthenticationInformationLengthDWORDinAuthenticationInformation バッファーの長さ (バイト単位)。
LocalGroupsTOKEN_GROUPS*inoptional認証されたユーザーのトークンに追加する、追加のグループ識別子のリスト。これらのグループ識別子は、すべてのユーザー トークンに自動的に含まれる既定のグループ WORLD およびログオン種別のグループ (Interactive、Batch、Network) とともに追加されます。
SourceContextTOKEN_SOURCE*inソース モジュール (たとえばセッション マネージャー) と、そのモジュールにとって有用なコンテキストを識別する TOKEN_SOURCE 構造体。この情報はユーザー トークンに含まれ、 GetTokenInformation を呼び出して取得できます。
ProfileBuffervoid**out

ログオン シェルやホーム ディレクトリなどの認証情報を含む出力バッファーのアドレスを受け取る、void ポインターへのポインター。

このパラメーターには、MSV1_0 および Kerberos 認証パッケージ向けの次の出力バッファー構造体のいずれかを指定できます。

値 意味
MSV1_0_INTERACTIVE_PROFILE
MSV1_0
対話型ユーザーのログオン プロファイル。
KERB_TICKET_PROFILE
Kerberos
ログオン、切断、およびチケット更新の認証出力。
MSV1_0_LM20_LOGON
MSV1_0
NTLM 2.0 プロトコル ログオンの後半を処理するときの出力。
MSV1_0_LM20_LOGON_PROFILE
MSV1_0
サブ認証を伴う認証を使用したときの出力。

他の認証パッケージが使用するバッファーについては、その認証パッケージのドキュメントを参照してください。

このバッファーが不要になったら、呼び出し側のアプリケーションは LsaFreeReturnBuffer 関数を呼び出してこのバッファーを解放する必要があります。

ProfileBufferLengthDWORD*out返されるプロファイル バッファーの長さ (バイト単位) を受け取る ULONG へのポインター。
LogonIdLUID*inoutログオン セッションを一意に識別する LUID を受け取るバッファーへのポインター。この LUID は、ログオン情報を認証したドメイン コントローラーによって割り当てられます。
TokenHANDLE*outこのセッション用に作成された新しいユーザー トークンを受け取るハンドルへのポインター。トークンの使用を終えたら、CloseHandle 関数を呼び出して解放してください。
QuotasQUOTA_LIMITS*outプライマリ トークンが返される場合、このパラメーターは、新しくログオンしたユーザーの初期プロセスに割り当てられたプロセスのクォータ制限を含む QUOTA_LIMITS 構造体を受け取ります。
SubStatusINT*out

アカウントの制限によってログオンが失敗した場合、このパラメーターはログオンが失敗した理由に関する情報を受け取ります。この値は、ユーザーのアカウント情報が有効で、かつログオンが拒否された場合にのみ設定されます。

このパラメーターには、MSV1_0 認証パッケージ向けの次の SubStatus 値のいずれかが返されます。

値 意味
STATUS_INVALID_LOGON_HOURS
ユーザー アカウントに時間帯の制限があり、現在の時刻ではログオンに使用できません。
STATUS_INVALID_WORKSTATION
ユーザー アカウントにワークステーションの制限があり、現在のワークステーションからはログオンに使用できません。
STATUS_PASSWORD_EXPIRED
ユーザー アカウントのパスワードの有効期限が切れています。
STATUS_ACCOUNT_DISABLED
ユーザー アカウントは現在無効になっており、ログオンに使用できません。

戻り値の型: NTSTATUS

公式ドキュメント

格納されている資格情報を使用して、セキュリティ プリンシパルのログオン データを認証します。

戻り値

関数が成功した場合は STATUS_SUCCESS を返します。

関数が失敗した場合は NTSTATUS コードを返します。次のいずれかの値になります。

値 説明
STATUS_QUOTA_EXCEEDED
呼び出し元のメモリ クォータが不足しているため、認証パッケージが返す出力バッファーを割り当てられません。
STATUS_ACCOUNT_RESTRICTION
ユーザー アカウントとパスワードは正当ですが、ユーザー アカウントに現時点でのログオンを妨げる制限があります。詳細については、SubStatus パラメーターに格納される値を参照してください。
STATUS_BAD_VALIDATION_CLASS
指定された認証情報を認証パッケージが認識できません。
STATUS_LOGON_FAILURE
ログオン試行が失敗しました。失敗の理由は示されませんが、ユーザー名やパスワードの入力間違いが典型的な原因です。
STATUS_NO_LOGON_SERVERS
認証要求を処理できるドメイン コントローラーがありません。
STATUS_NO_SUCH_PACKAGE
指定された認証パッケージを LSA が認識できません。
STATUS_PKINIT_FAILURE
Kerberos クライアントが無効な KDC 証明書を受け取りました。デバイス ログオンでは厳密な KDC の検証が必要なため、KDC は「Kerberos Authentication」テンプレートまたは同等のテンプレートを使用した証明書を持っている必要があります。また、KDC 証明書の有効期限切れや失効、あるいはクライアントが誤ったサーバーに要求を送信させられる攻撃を受けている可能性もあります。
STATUS_PKINIT_CLIENT_FAILURE
Kerberos クライアントが無効なシステム証明書を使用しています。デバイス ログオンでは DNS 名が必要です。また、システム証明書の有効期限が切れているか、誤った証明書が選択されている可能性があります。

詳細については、 LSA ポリシー関数の戻り値を参照してください。

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

解説(Remarks)

OriginName パラメーターには意味のある情報を指定してください。たとえば、端末 1 を示す "TTY1" や、"JAZZ" というリモート ノード経由で NTLM を使用するネットワーク ログオンを示す "NTLM - remote node JAZZ" などを指定します。

LOCAL_SYSTEM と NETWORK_SERVICE の PKINIT デバイス資格情報を更新するには、LsaLogonUser を個別に呼び出す必要があります。PKINIT デバイス資格情報が存在しない場合、呼び出しが成功しても何も行われません。PKINIT デバイス資格情報が存在する場合、呼び出しが成功すると PKINIT デバイス資格情報がクリーンアップされ、パスワード資格情報だけが残ります。

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

各言語での呼び出し定義

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

NTSTATUS LsaLogonUser(
    HANDLE LsaHandle,
    LSA_STRING* OriginName,
    SECURITY_LOGON_TYPE LogonType,
    DWORD AuthenticationPackage,
    void* AuthenticationInformation,
    DWORD AuthenticationInformationLength,
    TOKEN_GROUPS* LocalGroups,   // optional
    TOKEN_SOURCE* SourceContext,
    void** ProfileBuffer,
    DWORD* ProfileBufferLength,
    LUID* LogonId,
    HANDLE* Token,
    QUOTA_LIMITS* Quotas,
    INT* SubStatus
);
[DllImport("SECUR32.dll", ExactSpelling = true)]
static extern int LsaLogonUser(
    IntPtr LsaHandle,   // HANDLE
    IntPtr OriginName,   // LSA_STRING*
    int LogonType,   // SECURITY_LOGON_TYPE
    uint AuthenticationPackage,   // DWORD
    IntPtr AuthenticationInformation,   // void*
    uint AuthenticationInformationLength,   // DWORD
    IntPtr LocalGroups,   // TOKEN_GROUPS* optional
    IntPtr SourceContext,   // TOKEN_SOURCE*
    IntPtr ProfileBuffer,   // void** out
    out uint ProfileBufferLength,   // DWORD* out
    IntPtr LogonId,   // LUID* in/out
    IntPtr Token,   // HANDLE* out
    IntPtr Quotas,   // QUOTA_LIMITS* out
    out int SubStatus   // INT* out
);
<DllImport("SECUR32.dll", ExactSpelling:=True)>
Public Shared Function LsaLogonUser(
    LsaHandle As IntPtr,   ' HANDLE
    OriginName As IntPtr,   ' LSA_STRING*
    LogonType As Integer,   ' SECURITY_LOGON_TYPE
    AuthenticationPackage As UInteger,   ' DWORD
    AuthenticationInformation As IntPtr,   ' void*
    AuthenticationInformationLength As UInteger,   ' DWORD
    LocalGroups As IntPtr,   ' TOKEN_GROUPS* optional
    SourceContext As IntPtr,   ' TOKEN_SOURCE*
    ProfileBuffer As IntPtr,   ' void** out
    <Out> ByRef ProfileBufferLength As UInteger,   ' DWORD* out
    LogonId As IntPtr,   ' LUID* in/out
    Token As IntPtr,   ' HANDLE* out
    Quotas As IntPtr,   ' QUOTA_LIMITS* out
    <Out> ByRef SubStatus As Integer   ' INT* out
) As Integer
End Function
' LsaHandle : HANDLE
' OriginName : LSA_STRING*
' LogonType : SECURITY_LOGON_TYPE
' AuthenticationPackage : DWORD
' AuthenticationInformation : void*
' AuthenticationInformationLength : DWORD
' LocalGroups : TOKEN_GROUPS* optional
' SourceContext : TOKEN_SOURCE*
' ProfileBuffer : void** out
' ProfileBufferLength : DWORD* out
' LogonId : LUID* in/out
' Token : HANDLE* out
' Quotas : QUOTA_LIMITS* out
' SubStatus : INT* out
Declare PtrSafe Function LsaLogonUser Lib "secur32" ( _
    ByVal LsaHandle As LongPtr, _
    ByVal OriginName As LongPtr, _
    ByVal LogonType As Long, _
    ByVal AuthenticationPackage As Long, _
    ByVal AuthenticationInformation As LongPtr, _
    ByVal AuthenticationInformationLength As Long, _
    ByVal LocalGroups As LongPtr, _
    ByVal SourceContext As LongPtr, _
    ByVal ProfileBuffer As LongPtr, _
    ByRef ProfileBufferLength As Long, _
    ByVal LogonId As LongPtr, _
    ByVal Token As LongPtr, _
    ByVal Quotas As LongPtr, _
    ByRef SubStatus As Long) As Long
' VBA7前提(PtrSafe)。32bit Office では LongPtr→Long。Integer=16bit / Long=32bit / LongLong=64bit。
import ctypes
from ctypes import wintypes

LsaLogonUser = ctypes.windll.secur32.LsaLogonUser
LsaLogonUser.restype = ctypes.c_int
LsaLogonUser.argtypes = [
    wintypes.HANDLE,  # LsaHandle : HANDLE
    ctypes.c_void_p,  # OriginName : LSA_STRING*
    ctypes.c_int,  # LogonType : SECURITY_LOGON_TYPE
    wintypes.DWORD,  # AuthenticationPackage : DWORD
    ctypes.POINTER(None),  # AuthenticationInformation : void*
    wintypes.DWORD,  # AuthenticationInformationLength : DWORD
    ctypes.c_void_p,  # LocalGroups : TOKEN_GROUPS* optional
    ctypes.c_void_p,  # SourceContext : TOKEN_SOURCE*
    ctypes.c_void_p,  # ProfileBuffer : void** out
    ctypes.POINTER(wintypes.DWORD),  # ProfileBufferLength : DWORD* out
    ctypes.c_void_p,  # LogonId : LUID* in/out
    ctypes.c_void_p,  # Token : HANDLE* out
    ctypes.c_void_p,  # Quotas : QUOTA_LIMITS* out
    ctypes.POINTER(ctypes.c_int),  # SubStatus : INT* out
]
require 'fiddle'
require 'fiddle/import'

lib = Fiddle.dlopen('SECUR32.dll')
LsaLogonUser = Fiddle::Function.new(
  lib['LsaLogonUser'],
  [
    Fiddle::TYPE_VOIDP,  # LsaHandle : HANDLE
    Fiddle::TYPE_VOIDP,  # OriginName : LSA_STRING*
    Fiddle::TYPE_INT,  # LogonType : SECURITY_LOGON_TYPE
    -Fiddle::TYPE_INT,  # AuthenticationPackage : DWORD
    Fiddle::TYPE_VOIDP,  # AuthenticationInformation : void*
    -Fiddle::TYPE_INT,  # AuthenticationInformationLength : DWORD
    Fiddle::TYPE_VOIDP,  # LocalGroups : TOKEN_GROUPS* optional
    Fiddle::TYPE_VOIDP,  # SourceContext : TOKEN_SOURCE*
    Fiddle::TYPE_VOIDP,  # ProfileBuffer : void** out
    Fiddle::TYPE_VOIDP,  # ProfileBufferLength : DWORD* out
    Fiddle::TYPE_VOIDP,  # LogonId : LUID* in/out
    Fiddle::TYPE_VOIDP,  # Token : HANDLE* out
    Fiddle::TYPE_VOIDP,  # Quotas : QUOTA_LIMITS* out
    Fiddle::TYPE_VOIDP,  # SubStatus : INT* out
  ],
  Fiddle::TYPE_INT)
#[link(name = "secur32")]
extern "system" {
    fn LsaLogonUser(
        LsaHandle: *mut core::ffi::c_void,  // HANDLE
        OriginName: *mut LSA_STRING,  // LSA_STRING*
        LogonType: i32,  // SECURITY_LOGON_TYPE
        AuthenticationPackage: u32,  // DWORD
        AuthenticationInformation: *mut (),  // void*
        AuthenticationInformationLength: u32,  // DWORD
        LocalGroups: *mut TOKEN_GROUPS,  // TOKEN_GROUPS* optional
        SourceContext: *mut TOKEN_SOURCE,  // TOKEN_SOURCE*
        ProfileBuffer: *mut *mut (),  // void** out
        ProfileBufferLength: *mut u32,  // DWORD* out
        LogonId: *mut LUID,  // LUID* in/out
        Token: *mut *mut core::ffi::c_void,  // HANDLE* out
        Quotas: *mut QUOTA_LIMITS,  // QUOTA_LIMITS* out
        SubStatus: *mut i32  // INT* out
    ) -> i32;
}
// crates: windows-sys provides ready-made bindings for this API.
$sig = @"
[DllImport("SECUR32.dll")]
public static extern int LsaLogonUser(IntPtr LsaHandle, IntPtr OriginName, int LogonType, uint AuthenticationPackage, IntPtr AuthenticationInformation, uint AuthenticationInformationLength, IntPtr LocalGroups, IntPtr SourceContext, IntPtr ProfileBuffer, out uint ProfileBufferLength, IntPtr LogonId, IntPtr Token, IntPtr Quotas, out int SubStatus);
"@
$api = Add-Type -MemberDefinition $sig -Name 'SECUR32_LsaLogonUser' -Namespace Win32 -PassThru
# $api::LsaLogonUser(LsaHandle, OriginName, LogonType, AuthenticationPackage, AuthenticationInformation, AuthenticationInformationLength, LocalGroups, SourceContext, ProfileBuffer, ProfileBufferLength, LogonId, Token, Quotas, SubStatus)
#uselib "SECUR32.dll"
#func global LsaLogonUser "LsaLogonUser" sptr, sptr, sptr, sptr, sptr, sptr, sptr, sptr, sptr, sptr, sptr, sptr, sptr, sptr
; LsaLogonUser LsaHandle, varptr(OriginName), LogonType, AuthenticationPackage, AuthenticationInformation, AuthenticationInformationLength, varptr(LocalGroups), varptr(SourceContext), ProfileBuffer, varptr(ProfileBufferLength), varptr(LogonId), Token, varptr(Quotas), varptr(SubStatus)   ; 戻り値は stat
; LsaHandle : HANDLE -> "sptr"
; OriginName : LSA_STRING* -> "sptr"
; LogonType : SECURITY_LOGON_TYPE -> "sptr"
; AuthenticationPackage : DWORD -> "sptr"
; AuthenticationInformation : void* -> "sptr"
; AuthenticationInformationLength : DWORD -> "sptr"
; LocalGroups : TOKEN_GROUPS* optional -> "sptr"
; SourceContext : TOKEN_SOURCE* -> "sptr"
; ProfileBuffer : void** out -> "sptr"
; ProfileBufferLength : DWORD* out -> "sptr"
; LogonId : LUID* in/out -> "sptr"
; Token : HANDLE* out -> "sptr"
; Quotas : QUOTA_LIMITS* out -> "sptr"
; SubStatus : INT* out -> "sptr"
; ※HSP3.7は #func のため戻り値はシステム変数 stat に格納されます。
出力引数:
#uselib "SECUR32.dll"
#cfunc global LsaLogonUser "LsaLogonUser" sptr, var, int, int, sptr, int, var, var, sptr, var, var, sptr, var, var
; res = LsaLogonUser(LsaHandle, OriginName, LogonType, AuthenticationPackage, AuthenticationInformation, AuthenticationInformationLength, LocalGroups, SourceContext, ProfileBuffer, ProfileBufferLength, LogonId, Token, Quotas, SubStatus)
; LsaHandle : HANDLE -> "sptr"
; OriginName : LSA_STRING* -> "var"
; LogonType : SECURITY_LOGON_TYPE -> "int"
; AuthenticationPackage : DWORD -> "int"
; AuthenticationInformation : void* -> "sptr"
; AuthenticationInformationLength : DWORD -> "int"
; LocalGroups : TOKEN_GROUPS* optional -> "var"
; SourceContext : TOKEN_SOURCE* -> "var"
; ProfileBuffer : void** out -> "sptr"
; ProfileBufferLength : DWORD* out -> "var"
; LogonId : LUID* in/out -> "var"
; Token : HANDLE* out -> "sptr"
; Quotas : QUOTA_LIMITS* out -> "var"
; SubStatus : INT* out -> "var"
; ※出力/バッファ引数は var 方式(変数を直接渡す)。varptr 方式にも切替可。
出力引数:
; NTSTATUS LsaLogonUser(HANDLE LsaHandle, LSA_STRING* OriginName, SECURITY_LOGON_TYPE LogonType, DWORD AuthenticationPackage, void* AuthenticationInformation, DWORD AuthenticationInformationLength, TOKEN_GROUPS* LocalGroups, TOKEN_SOURCE* SourceContext, void** ProfileBuffer, DWORD* ProfileBufferLength, LUID* LogonId, HANDLE* Token, QUOTA_LIMITS* Quotas, INT* SubStatus)
#uselib "SECUR32.dll"
#cfunc global LsaLogonUser "LsaLogonUser" intptr, var, int, int, intptr, int, var, var, intptr, var, var, intptr, var, var
; res = LsaLogonUser(LsaHandle, OriginName, LogonType, AuthenticationPackage, AuthenticationInformation, AuthenticationInformationLength, LocalGroups, SourceContext, ProfileBuffer, ProfileBufferLength, LogonId, Token, Quotas, SubStatus)
; LsaHandle : HANDLE -> "intptr"
; OriginName : LSA_STRING* -> "var"
; LogonType : SECURITY_LOGON_TYPE -> "int"
; AuthenticationPackage : DWORD -> "int"
; AuthenticationInformation : void* -> "intptr"
; AuthenticationInformationLength : DWORD -> "int"
; LocalGroups : TOKEN_GROUPS* optional -> "var"
; SourceContext : TOKEN_SOURCE* -> "var"
; ProfileBuffer : void** out -> "intptr"
; ProfileBufferLength : DWORD* out -> "var"
; LogonId : LUID* in/out -> "var"
; Token : HANDLE* out -> "intptr"
; Quotas : QUOTA_LIMITS* out -> "var"
; SubStatus : INT* out -> "var"
; ※出力/バッファ引数は var 方式(変数を直接渡す)。varptr 方式にも切替可。
import (
	"golang.org/x/sys/windows"
	"unsafe"
)

var (
	secur32 = windows.NewLazySystemDLL("SECUR32.dll")
	procLsaLogonUser = secur32.NewProc("LsaLogonUser")
)

// LsaHandle (HANDLE), OriginName (LSA_STRING*), LogonType (SECURITY_LOGON_TYPE), AuthenticationPackage (DWORD), AuthenticationInformation (void*), AuthenticationInformationLength (DWORD), LocalGroups (TOKEN_GROUPS* optional), SourceContext (TOKEN_SOURCE*), ProfileBuffer (void** out), ProfileBufferLength (DWORD* out), LogonId (LUID* in/out), Token (HANDLE* out), Quotas (QUOTA_LIMITS* out), SubStatus (INT* out)
r1, _, err := procLsaLogonUser.Call(
	uintptr(LsaHandle),
	uintptr(OriginName),
	uintptr(LogonType),
	uintptr(AuthenticationPackage),
	uintptr(AuthenticationInformation),
	uintptr(AuthenticationInformationLength),
	uintptr(LocalGroups),
	uintptr(SourceContext),
	uintptr(ProfileBuffer),
	uintptr(ProfileBufferLength),
	uintptr(LogonId),
	uintptr(Token),
	uintptr(Quotas),
	uintptr(SubStatus),
)
_ = err  // syscall.Errno (valid when the call sets last-error)
_ = r1   // NTSTATUS
function LsaLogonUser(
  LsaHandle: THandle;   // HANDLE
  OriginName: Pointer;   // LSA_STRING*
  LogonType: Integer;   // SECURITY_LOGON_TYPE
  AuthenticationPackage: DWORD;   // DWORD
  AuthenticationInformation: Pointer;   // void*
  AuthenticationInformationLength: DWORD;   // DWORD
  LocalGroups: Pointer;   // TOKEN_GROUPS* optional
  SourceContext: Pointer;   // TOKEN_SOURCE*
  ProfileBuffer: Pointer;   // void** out
  ProfileBufferLength: Pointer;   // DWORD* out
  LogonId: Pointer;   // LUID* in/out
  Token: Pointer;   // HANDLE* out
  Quotas: Pointer;   // QUOTA_LIMITS* out
  SubStatus: Pointer   // INT* out
): Integer; stdcall;
  external 'SECUR32.dll' name 'LsaLogonUser';
result := DllCall("SECUR32\LsaLogonUser"
    , "Ptr", LsaHandle   ; HANDLE
    , "Ptr", OriginName   ; LSA_STRING*
    , "Int", LogonType   ; SECURITY_LOGON_TYPE
    , "UInt", AuthenticationPackage   ; DWORD
    , "Ptr", AuthenticationInformation   ; void*
    , "UInt", AuthenticationInformationLength   ; DWORD
    , "Ptr", LocalGroups   ; TOKEN_GROUPS* optional
    , "Ptr", SourceContext   ; TOKEN_SOURCE*
    , "Ptr", ProfileBuffer   ; void** out
    , "Ptr", ProfileBufferLength   ; DWORD* out
    , "Ptr", LogonId   ; LUID* in/out
    , "Ptr", Token   ; HANDLE* out
    , "Ptr", Quotas   ; QUOTA_LIMITS* out
    , "Ptr", SubStatus   ; INT* out
    , "Int")   ; return: NTSTATUS
●LsaLogonUser(LsaHandle, OriginName, LogonType, AuthenticationPackage, AuthenticationInformation, AuthenticationInformationLength, LocalGroups, SourceContext, ProfileBuffer, ProfileBufferLength, LogonId, Token, Quotas, SubStatus) = DLL("SECUR32.dll", "int LsaLogonUser(void*, void*, int, dword, void*, dword, void*, void*, void*, void*, void*, void*, void*, void*)")
# 呼び出し: LsaLogonUser(LsaHandle, OriginName, LogonType, AuthenticationPackage, AuthenticationInformation, AuthenticationInformationLength, LocalGroups, SourceContext, ProfileBuffer, ProfileBufferLength, LogonId, Token, Quotas, SubStatus)
# LsaHandle : HANDLE -> "void*"
# OriginName : LSA_STRING* -> "void*"
# LogonType : SECURITY_LOGON_TYPE -> "int"
# AuthenticationPackage : DWORD -> "dword"
# AuthenticationInformation : void* -> "void*"
# AuthenticationInformationLength : DWORD -> "dword"
# LocalGroups : TOKEN_GROUPS* optional -> "void*"
# SourceContext : TOKEN_SOURCE* -> "void*"
# ProfileBuffer : void** out -> "void*"
# ProfileBufferLength : DWORD* out -> "void*"
# LogonId : LUID* in/out -> "void*"
# Token : HANDLE* out -> "void*"
# Quotas : QUOTA_LIMITS* out -> "void*"
# SubStatus : INT* out -> "void*"
# なでしこ1は32bit・ANSI(Shift_JIS)。文字列=char*(ANSI)、ポインタ/ハンドル=void*(4byte)。
const std = @import("std");

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

typedef LsaLogonUserNative = Int32 Function(Pointer<Void>, Pointer<Void>, Int32, Uint32, Pointer<Void>, Uint32, Pointer<Void>, Pointer<Void>, Pointer<Void>, Pointer<Uint32>, Pointer<Void>, Pointer<Void>, Pointer<Void>, Pointer<Int32>);
typedef LsaLogonUserDart = int Function(Pointer<Void>, Pointer<Void>, int, int, Pointer<Void>, int, Pointer<Void>, Pointer<Void>, Pointer<Void>, Pointer<Uint32>, Pointer<Void>, Pointer<Void>, Pointer<Void>, Pointer<Int32>);
final LsaLogonUser = DynamicLibrary.open('SECUR32.dll')
    .lookupFunction<LsaLogonUserNative, LsaLogonUserDart>('LsaLogonUser');
// LsaHandle : HANDLE -> Pointer<Void>
// OriginName : LSA_STRING* -> Pointer<Void>
// LogonType : SECURITY_LOGON_TYPE -> Int32
// AuthenticationPackage : DWORD -> Uint32
// AuthenticationInformation : void* -> Pointer<Void>
// AuthenticationInformationLength : DWORD -> Uint32
// LocalGroups : TOKEN_GROUPS* optional -> Pointer<Void>
// SourceContext : TOKEN_SOURCE* -> Pointer<Void>
// ProfileBuffer : void** out -> Pointer<Void>
// ProfileBufferLength : DWORD* out -> Pointer<Uint32>
// LogonId : LUID* in/out -> Pointer<Void>
// Token : HANDLE* out -> Pointer<Void>
// Quotas : QUOTA_LIMITS* out -> Pointer<Void>
// SubStatus : INT* out -> Pointer<Int32>
// 文字列は package:ffi の "...".toNativeUtf16()/toNativeUtf8() で変換。
{$mode objfpc}{$H+}
function LsaLogonUser(
  LsaHandle: THandle;   // HANDLE
  OriginName: Pointer;   // LSA_STRING*
  LogonType: Integer;   // SECURITY_LOGON_TYPE
  AuthenticationPackage: DWORD;   // DWORD
  AuthenticationInformation: Pointer;   // void*
  AuthenticationInformationLength: DWORD;   // DWORD
  LocalGroups: Pointer;   // TOKEN_GROUPS* optional
  SourceContext: Pointer;   // TOKEN_SOURCE*
  ProfileBuffer: Pointer;   // void** out
  ProfileBufferLength: Pointer;   // DWORD* out
  LogonId: Pointer;   // LUID* in/out
  Token: Pointer;   // HANDLE* out
  Quotas: Pointer;   // QUOTA_LIMITS* out
  SubStatus: Pointer   // INT* out
): Integer; stdcall;
  external 'SECUR32.dll' name 'LsaLogonUser';
import Foreign
import Foreign.C.Types
import Foreign.C.String

foreign import stdcall safe "LsaLogonUser"
  c_LsaLogonUser :: Ptr () -> Ptr () -> Int32 -> Word32 -> Ptr () -> Word32 -> Ptr () -> Ptr () -> Ptr () -> Ptr Word32 -> Ptr () -> Ptr () -> Ptr () -> Ptr Int32 -> IO Int32
-- LsaHandle : HANDLE -> Ptr ()
-- OriginName : LSA_STRING* -> Ptr ()
-- LogonType : SECURITY_LOGON_TYPE -> Int32
-- AuthenticationPackage : DWORD -> Word32
-- AuthenticationInformation : void* -> Ptr ()
-- AuthenticationInformationLength : DWORD -> Word32
-- LocalGroups : TOKEN_GROUPS* optional -> Ptr ()
-- SourceContext : TOKEN_SOURCE* -> Ptr ()
-- ProfileBuffer : void** out -> Ptr ()
-- ProfileBufferLength : DWORD* out -> Ptr Word32
-- LogonId : LUID* in/out -> Ptr ()
-- Token : HANDLE* out -> Ptr ()
-- Quotas : QUOTA_LIMITS* out -> Ptr ()
-- SubStatus : INT* out -> Ptr Int32
-- 要 GHC(Windows)。stdcall は x64 では ccall として扱われる。ブロックする API は safe 呼び出し推奨。
open Ctypes
open Foreign

let lsalogonuser =
  foreign "LsaLogonUser"
    ((ptr void) @-> (ptr void) @-> int32_t @-> uint32_t @-> (ptr void) @-> uint32_t @-> (ptr void) @-> (ptr void) @-> (ptr void) @-> (ptr uint32_t) @-> (ptr void) @-> (ptr void) @-> (ptr void) @-> (ptr int32_t) @-> returning int32_t)
(* LsaHandle : HANDLE -> (ptr void) *)
(* OriginName : LSA_STRING* -> (ptr void) *)
(* LogonType : SECURITY_LOGON_TYPE -> int32_t *)
(* AuthenticationPackage : DWORD -> uint32_t *)
(* AuthenticationInformation : void* -> (ptr void) *)
(* AuthenticationInformationLength : DWORD -> uint32_t *)
(* LocalGroups : TOKEN_GROUPS* optional -> (ptr void) *)
(* SourceContext : TOKEN_SOURCE* -> (ptr void) *)
(* ProfileBuffer : void** out -> (ptr void) *)
(* ProfileBufferLength : DWORD* out -> (ptr uint32_t) *)
(* LogonId : LUID* in/out -> (ptr void) *)
(* Token : HANDLE* out -> (ptr void) *)
(* Quotas : QUOTA_LIMITS* out -> (ptr void) *)
(* SubStatus : INT* out -> (ptr int32_t) *)
(* foreign は cdecl 前提。x64 Windows では WINAPI と一致。構造体は ctypes structure を定義のこと。 *)
(cffi:define-foreign-library secur32 (t "SECUR32.dll"))
(cffi:use-foreign-library secur32)

(cffi:defcfun ("LsaLogonUser" lsa-logon-user :convention :stdcall) :int32
  (lsa-handle :pointer)   ; HANDLE
  (origin-name :pointer)   ; LSA_STRING*
  (logon-type :int32)   ; SECURITY_LOGON_TYPE
  (authentication-package :uint32)   ; DWORD
  (authentication-information :pointer)   ; void*
  (authentication-information-length :uint32)   ; DWORD
  (local-groups :pointer)   ; TOKEN_GROUPS* optional
  (source-context :pointer)   ; TOKEN_SOURCE*
  (profile-buffer :pointer)   ; void** out
  (profile-buffer-length :pointer)   ; DWORD* out
  (logon-id :pointer)   ; LUID* in/out
  (token :pointer)   ; HANDLE* out
  (quotas :pointer)   ; QUOTA_LIMITS* out
  (sub-status :pointer))   ; INT* out
; isize/usize(INT_PTR/SIZE_T)は x64 前提で :int64/:uint64。x86 では :int32/:uint32。
use Win32::API;
my $LsaLogonUser = Win32::API::More->new('SECUR32',
    'int LsaLogonUser(HANDLE LsaHandle, LPVOID OriginName, int LogonType, DWORD AuthenticationPackage, LPVOID AuthenticationInformation, DWORD AuthenticationInformationLength, LPVOID LocalGroups, LPVOID SourceContext, LPVOID ProfileBuffer, LPVOID ProfileBufferLength, LPVOID LogonId, HANDLE Token, LPVOID Quotas, LPVOID SubStatus)');
# my $ret = $LsaLogonUser->Call($LsaHandle, $OriginName, $LogonType, $AuthenticationPackage, $AuthenticationInformation, $AuthenticationInformationLength, $LocalGroups, $SourceContext, $ProfileBuffer, $ProfileBufferLength, $LogonId, $Token, $Quotas, $SubStatus);
# LsaHandle : HANDLE -> HANDLE
# OriginName : LSA_STRING* -> LPVOID
# LogonType : SECURITY_LOGON_TYPE -> int
# AuthenticationPackage : DWORD -> DWORD
# AuthenticationInformation : void* -> LPVOID
# AuthenticationInformationLength : DWORD -> DWORD
# LocalGroups : TOKEN_GROUPS* optional -> LPVOID
# SourceContext : TOKEN_SOURCE* -> LPVOID
# ProfileBuffer : void** out -> LPVOID
# ProfileBufferLength : DWORD* out -> LPVOID
# LogonId : LUID* in/out -> LPVOID
# Token : HANDLE* out -> HANDLE
# Quotas : QUOTA_LIMITS* out -> LPVOID
# SubStatus : INT* out -> LPVOID
# 値渡し構造体は pack() した文字列、または Win32::API::Struct を使用。

関連項目

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