Win32 API 日本語リファレンス
ホームSecurity › CreateRestrictedToken

CreateRestrictedToken

関数
既存トークンから制限付きアクセストークンを作成する。
DLLADVAPI32.dll呼出規約winapiSetLastErrorあり対応OSWindows XP 以降

シグネチャ

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

BOOL CreateRestrictedToken(
    HANDLE ExistingTokenHandle,
    CREATE_RESTRICTED_TOKEN_FLAGS Flags,
    DWORD DisableSidCount,
    SID_AND_ATTRIBUTES* SidsToDisable,   // optional
    DWORD DeletePrivilegeCount,
    LUID_AND_ATTRIBUTES* PrivilegesToDelete,   // optional
    DWORD RestrictedSidCount,
    SID_AND_ATTRIBUTES* SidsToRestrict,   // optional
    HANDLE* NewTokenHandle
);

パラメーター

名前方向説明
ExistingTokenHandleHANDLEinプライマリトークンまたは偽装トークンへのハンドル。このトークンは制限付きトークンであってもかまいません。ハンドルにはトークンに対する TOKEN_DUPLICATE アクセス権が必要です。
FlagsCREATE_RESTRICTED_TOKEN_FLAGSin

追加の特権オプションを指定します。このパラメーターには 0、または次の値の組み合わせを指定できます。

意味
DISABLE_MAX_PRIVILEGE
0x1
新しいトークン内の SeChangeNotifyPrivilege 特権を除くすべての特権を無効化します。この値が指定された場合、DeletePrivilegeCount および PrivilegesToDelete パラメーターは無視されます。
SANDBOX_INERT
0x2
この値を使用すると、システムは AppLocker ルールのチェックやソフトウェアの制限のポリシーの適用を行いません。AppLocker については、このフラグにより、実行可能ファイル、Windows インストーラー、スクリプト、DLL の 4 種類すべてのルールコレクションに対するチェックが無効化されます。

インストール中に展開された DLL を実行する必要があるセットアッププログラムを作成する場合は、SaferComputeTokenFromLevel 関数で SAFER_TOKEN_MAKE_INERT フラグを使用してください。

このフラグの有無は、GetTokenInformation を使用してトークンに対して照会できます。

Windows Server 2008 R2、Windows 7、Windows Server 2008、Windows Vista、Windows Server 2003、Windows XP: KB2532445 がインストールされているシステムでは、呼び出し元が LocalSystem または TrustedInstaller として実行されている必要があり、そうでない場合システムはこのフラグを無視します。詳細については、You can circumvent AppLocker rules by using an Office macro on a computer that is running Windows 7 or Windows Server 2008 R2 を参照してください。

Windows Server 2008、Windows Vista、Windows Server 2003、Windows XP: AppLocker はサポートされていません。AppLocker は Windows 7 および Windows Server 2008 R2 で導入されました。
LUA_TOKEN
0x4
新しいトークンは LUA トークンになります。

Windows Server 2003 および Windows XP: この値はサポートされていません。
WRITE_RESTRICTED
0x8
新しいトークンには、書き込みアクセスの評価時にのみ考慮される制限 SID が含まれます。

Windows XP with SP2 以降: この定数の値は 0x4 です。アプリケーションを Windows XP with SP2 以降のオペレーティングシステムと互換性を持たせるには、GetVersionEx 関数を呼び出してオペレーティングシステムを照会し、どの値を使用すべきかを判断する必要があります。

Windows Server 2003 および Windows XP with SP1 以前: この値はサポートされていません。
DisableSidCountDWORDinSidsToDisable 配列内のエントリ数を指定します。
SidsToDisableSID_AND_ATTRIBUTES*inoptional

制限付きトークン内の拒否専用 SID を指定する SID_AND_ATTRIBUTES 構造体の配列へのポインター。システムは拒否専用 SID を使用して、セキュリティ保護可能なオブジェクトへのアクセスを拒否します。拒否専用 SID が存在しないからといってアクセスが許可されるわけではありません。

SID を無効化すると、SE_GROUP_USE_FOR_DENY_ONLY が有効になり、SE_GROUP_ENABLED および SE_GROUP_ENABLED_BY_DEFAULT が無効になります。それ以外の属性は無視されます。

拒否専用属性は、ユーザー SID や SE_GROUP_MANDATORY 属性を持つグループ SID を含む、既存トークンの SID の任意の組み合わせに適用されます。既存トークンに関連付けられた SID を取得するには、GetTokenInformation 関数を TokenUser および TokenGroups フラグとともに使用します。この関数は、配列内に存在しても既存トークンに含まれていない SID をすべて無視します。

この関数は SID_AND_ATTRIBUTES 構造体の Attributes メンバーを無視します。

無効化する SID がない場合、このパラメーターは NULL にできます。

DeletePrivilegeCountDWORDinPrivilegesToDelete 配列内のエントリ数を指定します。
PrivilegesToDeleteLUID_AND_ATTRIBUTES*inoptional

制限付きトークン内で削除する特権を指定する LUID_AND_ATTRIBUTES 構造体の配列へのポインター。

GetTokenInformation 関数を TokenPrivileges フラグとともに使用すると、既存トークンが保持する特権を取得できます。この関数は、配列内にあっても既存トークンが保持していない特権をすべて無視します。

この関数は LUID_AND_ATTRIBUTES 構造体の Attributes メンバーを無視します。

特権を削除しない場合、このパラメーターは NULL にできます。

呼び出し元プログラムがこの配列に過剰な数の特権を渡した場合、CreateRestrictedTokenERROR_INVALID_PARAMETER を返します。

RestrictedSidCountDWORDinSidsToRestrict 配列内のエントリ数を指定します。
SidsToRestrictSID_AND_ATTRIBUTES*inoptional

新しいトークンの制限 SID のリストを指定する SID_AND_ATTRIBUTES 構造体の配列へのポインター。既存トークンが制限付きトークンである場合、新しいトークンの制限 SID リストは、この配列と既存トークンの制限 SID リストの積集合になります。SidsToRestrict パラメーターに指定された重複 SID を削除するためのチェックは行われません。重複 SID により、制限付きトークンは制限 SID リスト内に冗長な情報を持つことができます。

SID_AND_ATTRIBUTES 構造体の Attributes メンバーは 0 でなければなりません。制限 SID はアクセスチェックに対して常に有効です。

制限 SID を指定しない場合、このパラメーターは NULL にできます。

NewTokenHandleHANDLE*out新しい制限付きトークンへのハンドルを受け取る変数へのポインター。このハンドルは ExistingTokenHandle と同じアクセス権を持ちます。新しいトークンは、既存トークンと同じ種類 (プライマリまたは偽装) になります。NewTokenHandle で返されるハンドルは複製できます。

戻り値の型: BOOL

公式ドキュメント

既存のアクセストークンの制限付きバージョンとなる新しいアクセストークンを作成します。制限付きトークンには、無効化されたセキュリティ識別子 (SID)、削除された特権、および制限 SID のリストを含めることができます。

戻り値

関数が成功した場合、戻り値は 0 以外になります。

関数が失敗した場合、戻り値は 0 になります。拡張エラー情報を取得するには、GetLastError を呼び出します。

解説(Remarks)

CreateRestrictedToken 関数は、次の方法でトークンを制限できます。

制限付きトークンを CreateProcessAsUser 関数で使用すると、制限されたアクセス権と特権を持つプロセスを作成できます。プロセスが自身のトークンの制限付きバージョンを使用して CreateProcessAsUser を呼び出す場合、呼び出し元プロセスは SE_ASSIGNPRIMARYTOKEN_NAME 特権を持つ必要はありません。

制限付きトークンは ImpersonateLoggedOnUser 関数でも使用できます。

警告

制限付きトークンを使用するアプリケーションは、制限されたアプリケーションを既定のデスクトップ以外のデスクトップで実行する必要があります。これは、制限されたアプリケーションが SendMessage または PostMessage を使用して、既定のデスクトップ上の制限されていないアプリケーションを攻撃するのを防ぐために必要です。必要に応じて、アプリケーションの目的に合わせてデスクトップを切り替えてください。

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

各言語での呼び出し定義

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

BOOL CreateRestrictedToken(
    HANDLE ExistingTokenHandle,
    CREATE_RESTRICTED_TOKEN_FLAGS Flags,
    DWORD DisableSidCount,
    SID_AND_ATTRIBUTES* SidsToDisable,   // optional
    DWORD DeletePrivilegeCount,
    LUID_AND_ATTRIBUTES* PrivilegesToDelete,   // optional
    DWORD RestrictedSidCount,
    SID_AND_ATTRIBUTES* SidsToRestrict,   // optional
    HANDLE* NewTokenHandle
);
[return: MarshalAs(UnmanagedType.Bool)]
[DllImport("ADVAPI32.dll", SetLastError = true, ExactSpelling = true)]
static extern bool CreateRestrictedToken(
    IntPtr ExistingTokenHandle,   // HANDLE
    uint Flags,   // CREATE_RESTRICTED_TOKEN_FLAGS
    uint DisableSidCount,   // DWORD
    IntPtr SidsToDisable,   // SID_AND_ATTRIBUTES* optional
    uint DeletePrivilegeCount,   // DWORD
    IntPtr PrivilegesToDelete,   // LUID_AND_ATTRIBUTES* optional
    uint RestrictedSidCount,   // DWORD
    IntPtr SidsToRestrict,   // SID_AND_ATTRIBUTES* optional
    IntPtr NewTokenHandle   // HANDLE* out
);
<DllImport("ADVAPI32.dll", SetLastError:=True, ExactSpelling:=True)>
Public Shared Function CreateRestrictedToken(
    ExistingTokenHandle As IntPtr,   ' HANDLE
    Flags As UInteger,   ' CREATE_RESTRICTED_TOKEN_FLAGS
    DisableSidCount As UInteger,   ' DWORD
    SidsToDisable As IntPtr,   ' SID_AND_ATTRIBUTES* optional
    DeletePrivilegeCount As UInteger,   ' DWORD
    PrivilegesToDelete As IntPtr,   ' LUID_AND_ATTRIBUTES* optional
    RestrictedSidCount As UInteger,   ' DWORD
    SidsToRestrict As IntPtr,   ' SID_AND_ATTRIBUTES* optional
    NewTokenHandle As IntPtr   ' HANDLE* out
) As <MarshalAs(UnmanagedType.Bool)> Boolean
End Function
' ExistingTokenHandle : HANDLE
' Flags : CREATE_RESTRICTED_TOKEN_FLAGS
' DisableSidCount : DWORD
' SidsToDisable : SID_AND_ATTRIBUTES* optional
' DeletePrivilegeCount : DWORD
' PrivilegesToDelete : LUID_AND_ATTRIBUTES* optional
' RestrictedSidCount : DWORD
' SidsToRestrict : SID_AND_ATTRIBUTES* optional
' NewTokenHandle : HANDLE* out
Declare PtrSafe Function CreateRestrictedToken Lib "advapi32" ( _
    ByVal ExistingTokenHandle As LongPtr, _
    ByVal Flags As Long, _
    ByVal DisableSidCount As Long, _
    ByVal SidsToDisable As LongPtr, _
    ByVal DeletePrivilegeCount As Long, _
    ByVal PrivilegesToDelete As LongPtr, _
    ByVal RestrictedSidCount As Long, _
    ByVal SidsToRestrict As LongPtr, _
    ByVal NewTokenHandle As LongPtr) As Long
' VBA7前提(PtrSafe)。32bit Office では LongPtr→Long。Integer=16bit / Long=32bit / LongLong=64bit。
import ctypes
from ctypes import wintypes

CreateRestrictedToken = ctypes.windll.advapi32.CreateRestrictedToken
CreateRestrictedToken.restype = wintypes.BOOL
CreateRestrictedToken.argtypes = [
    wintypes.HANDLE,  # ExistingTokenHandle : HANDLE
    wintypes.DWORD,  # Flags : CREATE_RESTRICTED_TOKEN_FLAGS
    wintypes.DWORD,  # DisableSidCount : DWORD
    ctypes.c_void_p,  # SidsToDisable : SID_AND_ATTRIBUTES* optional
    wintypes.DWORD,  # DeletePrivilegeCount : DWORD
    ctypes.c_void_p,  # PrivilegesToDelete : LUID_AND_ATTRIBUTES* optional
    wintypes.DWORD,  # RestrictedSidCount : DWORD
    ctypes.c_void_p,  # SidsToRestrict : SID_AND_ATTRIBUTES* optional
    ctypes.c_void_p,  # NewTokenHandle : HANDLE* out
]
# GetLastError: use ctypes.GetLastError() (or ctypes.WinDLL(use_last_error=True))
require 'fiddle'
require 'fiddle/import'

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

var (
	advapi32 = windows.NewLazySystemDLL("ADVAPI32.dll")
	procCreateRestrictedToken = advapi32.NewProc("CreateRestrictedToken")
)

// ExistingTokenHandle (HANDLE), Flags (CREATE_RESTRICTED_TOKEN_FLAGS), DisableSidCount (DWORD), SidsToDisable (SID_AND_ATTRIBUTES* optional), DeletePrivilegeCount (DWORD), PrivilegesToDelete (LUID_AND_ATTRIBUTES* optional), RestrictedSidCount (DWORD), SidsToRestrict (SID_AND_ATTRIBUTES* optional), NewTokenHandle (HANDLE* out)
r1, _, err := procCreateRestrictedToken.Call(
	uintptr(ExistingTokenHandle),
	uintptr(Flags),
	uintptr(DisableSidCount),
	uintptr(SidsToDisable),
	uintptr(DeletePrivilegeCount),
	uintptr(PrivilegesToDelete),
	uintptr(RestrictedSidCount),
	uintptr(SidsToRestrict),
	uintptr(NewTokenHandle),
)
_ = err  // syscall.Errno (valid when the call sets last-error)
_ = r1   // BOOL
function CreateRestrictedToken(
  ExistingTokenHandle: THandle;   // HANDLE
  Flags: DWORD;   // CREATE_RESTRICTED_TOKEN_FLAGS
  DisableSidCount: DWORD;   // DWORD
  SidsToDisable: Pointer;   // SID_AND_ATTRIBUTES* optional
  DeletePrivilegeCount: DWORD;   // DWORD
  PrivilegesToDelete: Pointer;   // LUID_AND_ATTRIBUTES* optional
  RestrictedSidCount: DWORD;   // DWORD
  SidsToRestrict: Pointer;   // SID_AND_ATTRIBUTES* optional
  NewTokenHandle: Pointer   // HANDLE* out
): BOOL; stdcall;
  external 'ADVAPI32.dll' name 'CreateRestrictedToken';
result := DllCall("ADVAPI32\CreateRestrictedToken"
    , "Ptr", ExistingTokenHandle   ; HANDLE
    , "UInt", Flags   ; CREATE_RESTRICTED_TOKEN_FLAGS
    , "UInt", DisableSidCount   ; DWORD
    , "Ptr", SidsToDisable   ; SID_AND_ATTRIBUTES* optional
    , "UInt", DeletePrivilegeCount   ; DWORD
    , "Ptr", PrivilegesToDelete   ; LUID_AND_ATTRIBUTES* optional
    , "UInt", RestrictedSidCount   ; DWORD
    , "Ptr", SidsToRestrict   ; SID_AND_ATTRIBUTES* optional
    , "Ptr", NewTokenHandle   ; HANDLE* out
    , "Int")   ; return: BOOL
●CreateRestrictedToken(ExistingTokenHandle, Flags, DisableSidCount, SidsToDisable, DeletePrivilegeCount, PrivilegesToDelete, RestrictedSidCount, SidsToRestrict, NewTokenHandle) = DLL("ADVAPI32.dll", "bool CreateRestrictedToken(void*, dword, dword, void*, dword, void*, dword, void*, void*)")
# 呼び出し: CreateRestrictedToken(ExistingTokenHandle, Flags, DisableSidCount, SidsToDisable, DeletePrivilegeCount, PrivilegesToDelete, RestrictedSidCount, SidsToRestrict, NewTokenHandle)
# ExistingTokenHandle : HANDLE -> "void*"
# Flags : CREATE_RESTRICTED_TOKEN_FLAGS -> "dword"
# DisableSidCount : DWORD -> "dword"
# SidsToDisable : SID_AND_ATTRIBUTES* optional -> "void*"
# DeletePrivilegeCount : DWORD -> "dword"
# PrivilegesToDelete : LUID_AND_ATTRIBUTES* optional -> "void*"
# RestrictedSidCount : DWORD -> "dword"
# SidsToRestrict : SID_AND_ATTRIBUTES* optional -> "void*"
# NewTokenHandle : HANDLE* out -> "void*"
# なでしこ1は32bit・ANSI(Shift_JIS)。文字列=char*(ANSI)、ポインタ/ハンドル=void*(4byte)。
const std = @import("std");

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

typedef CreateRestrictedTokenNative = Int32 Function(Pointer<Void>, Uint32, Uint32, Pointer<Void>, Uint32, Pointer<Void>, Uint32, Pointer<Void>, Pointer<Void>);
typedef CreateRestrictedTokenDart = int Function(Pointer<Void>, int, int, Pointer<Void>, int, Pointer<Void>, int, Pointer<Void>, Pointer<Void>);
final CreateRestrictedToken = DynamicLibrary.open('ADVAPI32.dll')
    .lookupFunction<CreateRestrictedTokenNative, CreateRestrictedTokenDart>('CreateRestrictedToken');
// ExistingTokenHandle : HANDLE -> Pointer<Void>
// Flags : CREATE_RESTRICTED_TOKEN_FLAGS -> Uint32
// DisableSidCount : DWORD -> Uint32
// SidsToDisable : SID_AND_ATTRIBUTES* optional -> Pointer<Void>
// DeletePrivilegeCount : DWORD -> Uint32
// PrivilegesToDelete : LUID_AND_ATTRIBUTES* optional -> Pointer<Void>
// RestrictedSidCount : DWORD -> Uint32
// SidsToRestrict : SID_AND_ATTRIBUTES* optional -> Pointer<Void>
// NewTokenHandle : HANDLE* out -> Pointer<Void>
// 文字列は package:ffi の "...".toNativeUtf16()/toNativeUtf8() で変換。
{$mode objfpc}{$H+}
function CreateRestrictedToken(
  ExistingTokenHandle: THandle;   // HANDLE
  Flags: DWORD;   // CREATE_RESTRICTED_TOKEN_FLAGS
  DisableSidCount: DWORD;   // DWORD
  SidsToDisable: Pointer;   // SID_AND_ATTRIBUTES* optional
  DeletePrivilegeCount: DWORD;   // DWORD
  PrivilegesToDelete: Pointer;   // LUID_AND_ATTRIBUTES* optional
  RestrictedSidCount: DWORD;   // DWORD
  SidsToRestrict: Pointer;   // SID_AND_ATTRIBUTES* optional
  NewTokenHandle: Pointer   // HANDLE* out
): BOOL; stdcall;
  external 'ADVAPI32.dll' name 'CreateRestrictedToken';
import Foreign
import Foreign.C.Types
import Foreign.C.String

foreign import stdcall safe "CreateRestrictedToken"
  c_CreateRestrictedToken :: Ptr () -> Word32 -> Word32 -> Ptr () -> Word32 -> Ptr () -> Word32 -> Ptr () -> Ptr () -> IO CInt
-- ExistingTokenHandle : HANDLE -> Ptr ()
-- Flags : CREATE_RESTRICTED_TOKEN_FLAGS -> Word32
-- DisableSidCount : DWORD -> Word32
-- SidsToDisable : SID_AND_ATTRIBUTES* optional -> Ptr ()
-- DeletePrivilegeCount : DWORD -> Word32
-- PrivilegesToDelete : LUID_AND_ATTRIBUTES* optional -> Ptr ()
-- RestrictedSidCount : DWORD -> Word32
-- SidsToRestrict : SID_AND_ATTRIBUTES* optional -> Ptr ()
-- NewTokenHandle : HANDLE* out -> Ptr ()
-- 要 GHC(Windows)。stdcall は x64 では ccall として扱われる。ブロックする API は safe 呼び出し推奨。
open Ctypes
open Foreign

let createrestrictedtoken =
  foreign "CreateRestrictedToken"
    ((ptr void) @-> uint32_t @-> uint32_t @-> (ptr void) @-> uint32_t @-> (ptr void) @-> uint32_t @-> (ptr void) @-> (ptr void) @-> returning int32_t)
(* ExistingTokenHandle : HANDLE -> (ptr void) *)
(* Flags : CREATE_RESTRICTED_TOKEN_FLAGS -> uint32_t *)
(* DisableSidCount : DWORD -> uint32_t *)
(* SidsToDisable : SID_AND_ATTRIBUTES* optional -> (ptr void) *)
(* DeletePrivilegeCount : DWORD -> uint32_t *)
(* PrivilegesToDelete : LUID_AND_ATTRIBUTES* optional -> (ptr void) *)
(* RestrictedSidCount : DWORD -> uint32_t *)
(* SidsToRestrict : SID_AND_ATTRIBUTES* optional -> (ptr void) *)
(* NewTokenHandle : HANDLE* 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 ("CreateRestrictedToken" create-restricted-token :convention :stdcall) :int32
  (existing-token-handle :pointer)   ; HANDLE
  (flags :uint32)   ; CREATE_RESTRICTED_TOKEN_FLAGS
  (disable-sid-count :uint32)   ; DWORD
  (sids-to-disable :pointer)   ; SID_AND_ATTRIBUTES* optional
  (delete-privilege-count :uint32)   ; DWORD
  (privileges-to-delete :pointer)   ; LUID_AND_ATTRIBUTES* optional
  (restricted-sid-count :uint32)   ; DWORD
  (sids-to-restrict :pointer)   ; SID_AND_ATTRIBUTES* optional
  (new-token-handle :pointer))   ; HANDLE* out
; isize/usize(INT_PTR/SIZE_T)は x64 前提で :int64/:uint64。x86 では :int32/:uint32。
use Win32::API;
my $CreateRestrictedToken = Win32::API::More->new('ADVAPI32',
    'BOOL CreateRestrictedToken(HANDLE ExistingTokenHandle, DWORD Flags, DWORD DisableSidCount, LPVOID SidsToDisable, DWORD DeletePrivilegeCount, LPVOID PrivilegesToDelete, DWORD RestrictedSidCount, LPVOID SidsToRestrict, HANDLE NewTokenHandle)');
# my $ret = $CreateRestrictedToken->Call($ExistingTokenHandle, $Flags, $DisableSidCount, $SidsToDisable, $DeletePrivilegeCount, $PrivilegesToDelete, $RestrictedSidCount, $SidsToRestrict, $NewTokenHandle);
# ExistingTokenHandle : HANDLE -> HANDLE
# Flags : CREATE_RESTRICTED_TOKEN_FLAGS -> DWORD
# DisableSidCount : DWORD -> DWORD
# SidsToDisable : SID_AND_ATTRIBUTES* optional -> LPVOID
# DeletePrivilegeCount : DWORD -> DWORD
# PrivilegesToDelete : LUID_AND_ATTRIBUTES* optional -> LPVOID
# RestrictedSidCount : DWORD -> DWORD
# SidsToRestrict : SID_AND_ATTRIBUTES* optional -> LPVOID
# NewTokenHandle : HANDLE* out -> HANDLE
# 値渡し構造体は pack() した文字列、または Win32::API::Struct を使用。

関連項目

使用する型