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

GetEffectiveRightsFromAclA

関数
ACLから指定トラスティの実効アクセス権を取得する(ANSI版)。
DLLADVAPI32.dll文字セットANSI (-A)呼出規約winapi対応OSWindows XP 以降

シグネチャ

// ADVAPI32.dll  (ANSI / -A)
#include <windows.h>

WIN32_ERROR GetEffectiveRightsFromAclA(
    ACL* pacl,
    TRUSTEE_A* pTrustee,
    DWORD* pAccessRights
);

パラメーター

名前方向説明
paclACL*inトラスティの実効アクセス権を取得する元となる ACL 構造体へのポインターです。
pTrusteeTRUSTEE_A*inトラスティを識別する TRUSTEE 構造体へのポインターです。トラスティには、ユーザー、グループ、またはプログラム(Windows サービスなど)を指定できます。トラスティの識別には、名前またはセキュリティ識別子(SID)を使用できます。
pAccessRightsDWORD*outトラスティの実効アクセス権を受け取る ACCESS_MASK 変数へのポインターです。

戻り値の型: WIN32_ERROR

公式ドキュメント

ACL 構造体が指定したトラスティに付与する実効アクセス権を取得します。トラスティの実効アクセス権とは、ACL がそのトラスティ、またはトラスティが属する任意のグループに付与するアクセス権です。(ANSI)

戻り値

関数が成功した場合、ERROR_SUCCESS を返します。

関数が失敗した場合、WinError.h で定義されている 0 以外のエラーコードを返します。

解説(Remarks)

GetEffectiveRightsFromAcl 関数は、アクセス制御リスト(ACL)内のすべてのアクセス許可およびアクセス拒否のアクセス制御エントリ(ACE)を調べ、トラスティの実効アクセス権を判定します。グループに対して権限を許可または拒否するすべての ACE について、GetEffectiveRightsFromAcl はそのグループのメンバーを列挙し、トラスティがメンバーであるかどうかを判定します。グループのメンバーを列挙できない場合、この関数はエラーを返します。

トラスティが属するグループの権限は、トラスティがリモートコンピューター上のオブジェクトにアクセスする場合であっても、ローカルコンピューター上で GetEffectiveRightsFromAcl によって列挙されます。この関数は、リモートコンピューター上のグループ権限を評価しません。

GetEffectiveRightsFromAcl 関数は、次のものを考慮しません。

指定された ACL に継承されたアクセス拒否 ACE が含まれている場合、GetEffectiveRightsFromAcl 関数は失敗し、ERROR_INVALID_ACL を返します。

Examples

次の例は、Authz API を使用して ACL から実効アクセス権を取得する方法を示しています。


//  Copyright (C) Microsoft. All rights reserved.

#include <windows.h>
#include <stdio.h>
#include <aclapi.h>
#include <tchar.h>
#include <strsafe.h> // for proper buffer handling
#include <authz.h>

#pragma comment(lib, "advapi32.lib")
#pragma comment(lib, "authz.lib")

LPTSTR lpServerName = NULL;


PSID ConvertNameToBinarySid(LPTSTR pAccountName)
{
   LPTSTR pDomainName = NULL;
   DWORD dwDomainNameSize = 0;
   PSID pSid = NULL;
   DWORD dwSidSize = 0;
   SID_NAME_USE sidType;
   BOOL fSuccess = FALSE;
   HRESULT hr = S_OK;

   __try
   {
      LookupAccountName(
            lpServerName,      // look up on local system
            pAccountName,
            pSid,              // buffer to receive name
            &dwSidSize,
            pDomainName,
            &dwDomainNameSize,
            &sidType);
      
      //  If the Name cannot be resolved, LookupAccountName will fail with
      //  ERROR_NONE_MAPPED.
      if (GetLastError() == ERROR_NONE_MAPPED)
      {
         wprintf_s(_T("LookupAccountName failed with %d\n"), GetLastError());
         __leave;
      }
      else if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
      {
         pSid = (LPTSTR)LocalAlloc(LPTR, dwSidSize * sizeof(TCHAR));
         if (pSid == NULL)
         {
            wprintf_s(_T("LocalAlloc failed with %d\n"), GetLastError());
            __leave;
         }

         pDomainName = (LPTSTR)LocalAlloc(LPTR, dwDomainNameSize * sizeof(TCHAR));
         if (pDomainName == NULL)
         {
            wprintf_s(_T("LocalAlloc failed with %d\n"), GetLastError());
            __leave;
         }

         if (!LookupAccountName(
               lpServerName,      // look up on local system
               pAccountName,
               pSid,              // buffer to receive name
               &dwSidSize,
               pDomainName,
               &dwDomainNameSize,
               &sidType))
         {
            wprintf_s(_T("LookupAccountName failed with %d\n"), GetLastError());
            __leave;
         }
      }
      
      //  Any other error code
      else
      {
         wprintf_s(_T("LookupAccountName failed with %d\n"), GetLastError());
         __leave;
      }

      fSuccess = TRUE;
   }
   __finally
   {
      if(pDomainName != NULL)
      {
          LocalFree(pDomainName);
          pDomainName = NULL;
      }
      
      //  Free pSid only if failed;
      //  otherwise, the caller has to free it after use.
      if (fSuccess == FALSE)
      {
         if(pSid != NULL)
      {
          LocalFree(pSid);
          pSid = NULL;
      }
      }
   }

   return pSid;
}


void DisplayError(char* pszAPI, DWORD dwError)
{
   LPVOID lpvMessageBuffer;

   if (!FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_HMODULE | FORMAT_MESSAGE_FROM_SYSTEM,
              GetModuleHandle(L"Kernel32.dll"), dwError, 
              MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),  // the user default language
              (LPTSTR)&lpvMessageBuffer, 0, NULL))
   {
      wprintf_s(L"FormatMessage failed with %d\n", GetLastError());
      ExitProcess(GetLastError());
   }

   //  ...now display this string.
   wprintf_s(L"ERROR: API        = %s.\n", (char *)pszAPI);
   wprintf_s(L"       error code = %08X.\n", dwError);
   wprintf_s(L"       message    = %s.\n", (char *)lpvMessageBuffer);

   //  Free the buffer allocated by the system.
   LocalFree(lpvMessageBuffer);

   ExitProcess(GetLastError());
}

void DisplayAccessMask(ACCESS_MASK Mask)
{
      // This evaluation of the ACCESS_MASK is an example. 
      // Applications should evaluate the ACCESS_MASK as necessary.

   wprintf_s(L"Effective Allowed Access Mask : %8X\n", Mask);
   if (((Mask & GENERIC_ALL) == GENERIC_ALL)
      || ((Mask & FILE_ALL_ACCESS) == FILE_ALL_ACCESS))
   {
         wprintf_s(L"Full Control\n");
         return;
   }
   if (((Mask & GENERIC_READ) == GENERIC_READ)
      || ((Mask & FILE_GENERIC_READ) == FILE_GENERIC_READ))
         wprintf_s(L"Read\n");
   if (((Mask & GENERIC_WRITE) == GENERIC_WRITE)
      || ((Mask & FILE_GENERIC_WRITE) == FILE_GENERIC_WRITE))
         wprintf_s(L"Write\n");
   if (((Mask & GENERIC_EXECUTE) == GENERIC_EXECUTE)
      || ((Mask & FILE_GENERIC_EXECUTE) == FILE_GENERIC_EXECUTE))
         wprintf_s(L"Execute\n");

}

void GetAccess(AUTHZ_CLIENT_CONTEXT_HANDLE hAuthzClient, PSECURITY_DESCRIPTOR psd)
{
   AUTHZ_ACCESS_REQUEST AccessRequest = {0};
   AUTHZ_ACCESS_REPLY AccessReply = {0};
   BYTE     Buffer[1024];
   BOOL bRes = FALSE;  // assume error

   //  Do AccessCheck.
   AccessRequest.DesiredAccess = MAXIMUM_ALLOWED;
   AccessRequest.PrincipalSelfSid = NULL;
   AccessRequest.ObjectTypeList = NULL;
   AccessRequest.ObjectTypeListLength = 0;
   AccessRequest.OptionalArguments = NULL; 

   RtlZeroMemory(Buffer, sizeof(Buffer));
   AccessReply.ResultListLength = 1;
   AccessReply.GrantedAccessMask = (PACCESS_MASK) (Buffer);
   AccessReply.Error = (PDWORD) (Buffer + sizeof(ACCESS_MASK));


   if (!AuthzAccessCheck( 0,
                          hAuthzClient,
                          &AccessRequest,
                          NULL,
                          psd,
                          NULL,
                          0,
                          &AccessReply,
                          NULL) ) {
      wprintf_s(_T("AuthzAccessCheck failed with %d\n"), GetLastError());
   }
   else 
      DisplayAccessMask(*(PACCESS_MASK)(AccessReply.GrantedAccessMask));

   return;
}

BOOL GetEffectiveRightsForUser(AUTHZ_RESOURCE_MANAGER_HANDLE hManager,
                               PSECURITY_DESCRIPTOR psd,
                                      LPTSTR lpszUserName)
{
   PSID pSid = NULL;
   BOOL bResult = FALSE;
   LUID unusedId = { 0 };
   AUTHZ_CLIENT_CONTEXT_HANDLE hAuthzClientContext = NULL;

   pSid = ConvertNameToBinarySid(lpszUserName);
   if (pSid != NULL)
   {
      bResult = AuthzInitializeContextFromSid(0,
         pSid,
         hManager,
         NULL,
         unusedId,
         NULL,
         &hAuthzClientContext);
      if (bResult)
      {
         GetAccess(hAuthzClientContext, psd);
         AuthzFreeContext(hAuthzClientContext);
      }
      else
         wprintf_s(_T("AuthzInitializeContextFromSid failed with %d\n"), GetLastError());
   }
    if(pSid != NULL)
      {
          LocalFree(pSid);
          pSid = NULL;
      }

   return bResult;
}

void UseAuthzSolution(PSECURITY_DESCRIPTOR psd, LPTSTR lpszUserName)
{
   AUTHZ_RESOURCE_MANAGER_HANDLE hManager;
   BOOL bResult = FALSE;

   bResult = AuthzInitializeResourceManager(AUTHZ_RM_FLAG_NO_AUDIT,
      NULL, NULL, NULL, NULL, &hManager);
   if (bResult)
   {
      bResult = GetEffectiveRightsForUser(hManager, psd, lpszUserName);
      AuthzFreeResourceManager(hManager);
   }
   else
      wprintf_s(_T("AuthzInitializeResourceManager failed with %d\n"), GetLastError());
}


void wmain(int argc, wchar_t *argv[])
{
   DWORD                dw;
   PACL                 pacl;
   PSECURITY_DESCRIPTOR psd;
   PSID                 psid = NULL; 

   if (argc != 3)
   {
      wprintf_s(L"Usage: FileOrFolderName UserOrGroupName\n");
      wprintf_s(L"Usage: FileOrFolderName UserOrGroupName\n");
      return;
   }
  

    dw = GetNamedSecurityInfo(argv[1], SE_FILE_OBJECT, DACL_SECURITY_INFORMATION | 
      OWNER_SECURITY_INFORMATION |
      GROUP_SECURITY_INFORMATION, NULL, NULL, &pacl, NULL, &psd);
   if (dw != ERROR_SUCCESS)
   {  printf("couldn't do getnamedsecinfo \n");
      DisplayError("GetNamedSecurityInfo", dw);
   }

   
   UseAuthzSolution(psd, argv[2]);


   if(psid != NULL)
      {
          LocalFree(psid);
          psid = NULL;
      };

   LocalFree(psd);
}
メモ

aclapi.h ヘッダーは、UNICODE プリプロセッサ定数の定義に基づいて、この関数の ANSI 版または Unicode 版を自動的に選択するエイリアスとして GetEffectiveRightsFromAcl を定義しています。エンコーディング非依存のエイリアスの使用を、エンコーディング非依存でないコードと混在させると、不整合が生じてコンパイルエラーや実行時エラーを引き起こす可能性があります。詳細については、関数プロトタイプの規則を参照してください。

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

各言語での呼び出し定義

// ADVAPI32.dll  (ANSI / -A)
#include <windows.h>

WIN32_ERROR GetEffectiveRightsFromAclA(
    ACL* pacl,
    TRUSTEE_A* pTrustee,
    DWORD* pAccessRights
);
[DllImport("ADVAPI32.dll", CharSet = CharSet.Ansi, ExactSpelling = true)]
static extern uint GetEffectiveRightsFromAclA(
    IntPtr pacl,   // ACL*
    IntPtr pTrustee,   // TRUSTEE_A*
    out uint pAccessRights   // DWORD* out
);
<DllImport("ADVAPI32.dll", CharSet:=CharSet.Ansi, ExactSpelling:=True)>
Public Shared Function GetEffectiveRightsFromAclA(
    pacl As IntPtr,   ' ACL*
    pTrustee As IntPtr,   ' TRUSTEE_A*
    <Out> ByRef pAccessRights As UInteger   ' DWORD* out
) As UInteger
End Function
' pacl : ACL*
' pTrustee : TRUSTEE_A*
' pAccessRights : DWORD* out
Declare PtrSafe Function GetEffectiveRightsFromAclA Lib "advapi32" ( _
    ByVal pacl As LongPtr, _
    ByVal pTrustee As LongPtr, _
    ByRef pAccessRights As Long) As Long
' VBA7前提(PtrSafe)。32bit Office では LongPtr→Long。Integer=16bit / Long=32bit / LongLong=64bit。
import ctypes
from ctypes import wintypes

GetEffectiveRightsFromAclA = ctypes.windll.advapi32.GetEffectiveRightsFromAclA
GetEffectiveRightsFromAclA.restype = wintypes.DWORD
GetEffectiveRightsFromAclA.argtypes = [
    ctypes.c_void_p,  # pacl : ACL*
    ctypes.c_void_p,  # pTrustee : TRUSTEE_A*
    ctypes.POINTER(wintypes.DWORD),  # pAccessRights : DWORD* out
]
require 'fiddle'
require 'fiddle/import'

lib = Fiddle.dlopen('ADVAPI32.dll')
GetEffectiveRightsFromAclA = Fiddle::Function.new(
  lib['GetEffectiveRightsFromAclA'],
  [
    Fiddle::TYPE_VOIDP,  # pacl : ACL*
    Fiddle::TYPE_VOIDP,  # pTrustee : TRUSTEE_A*
    Fiddle::TYPE_VOIDP,  # pAccessRights : DWORD* out
  ],
  -Fiddle::TYPE_INT)
#[link(name = "advapi32")]
extern "system" {
    fn GetEffectiveRightsFromAclA(
        pacl: *mut ACL,  // ACL*
        pTrustee: *mut TRUSTEE_A,  // TRUSTEE_A*
        pAccessRights: *mut u32  // DWORD* out
    ) -> u32;
}
// crates: windows-sys provides ready-made bindings for this API.
$sig = @"
[DllImport("ADVAPI32.dll", CharSet = CharSet.Ansi)]
public static extern uint GetEffectiveRightsFromAclA(IntPtr pacl, IntPtr pTrustee, out uint pAccessRights);
"@
$api = Add-Type -MemberDefinition $sig -Name 'ADVAPI32_GetEffectiveRightsFromAclA' -Namespace Win32 -PassThru
# $api::GetEffectiveRightsFromAclA(pacl, pTrustee, pAccessRights)
#uselib "ADVAPI32.dll"
#func global GetEffectiveRightsFromAclA "GetEffectiveRightsFromAclA" sptr, sptr, sptr
; GetEffectiveRightsFromAclA varptr(pacl), varptr(pTrustee), varptr(pAccessRights)   ; 戻り値は stat
; pacl : ACL* -> "sptr"
; pTrustee : TRUSTEE_A* -> "sptr"
; pAccessRights : DWORD* out -> "sptr"
; ※HSP3.7は #func のため戻り値はシステム変数 stat に格納されます。
出力引数:
#uselib "ADVAPI32.dll"
#cfunc global GetEffectiveRightsFromAclA "GetEffectiveRightsFromAclA" var, var, var
; res = GetEffectiveRightsFromAclA(pacl, pTrustee, pAccessRights)
; pacl : ACL* -> "var"
; pTrustee : TRUSTEE_A* -> "var"
; pAccessRights : DWORD* out -> "var"
; ※出力/バッファ引数は var 方式(変数を直接渡す)。varptr 方式にも切替可。
出力引数:
; WIN32_ERROR GetEffectiveRightsFromAclA(ACL* pacl, TRUSTEE_A* pTrustee, DWORD* pAccessRights)
#uselib "ADVAPI32.dll"
#cfunc global GetEffectiveRightsFromAclA "GetEffectiveRightsFromAclA" var, var, var
; res = GetEffectiveRightsFromAclA(pacl, pTrustee, pAccessRights)
; pacl : ACL* -> "var"
; pTrustee : TRUSTEE_A* -> "var"
; pAccessRights : DWORD* out -> "var"
; ※出力/バッファ引数は var 方式(変数を直接渡す)。varptr 方式にも切替可。
import (
	"golang.org/x/sys/windows"
	"unsafe"
)

var (
	advapi32 = windows.NewLazySystemDLL("ADVAPI32.dll")
	procGetEffectiveRightsFromAclA = advapi32.NewProc("GetEffectiveRightsFromAclA")
)

// pacl (ACL*), pTrustee (TRUSTEE_A*), pAccessRights (DWORD* out)
r1, _, err := procGetEffectiveRightsFromAclA.Call(
	uintptr(pacl),
	uintptr(pTrustee),
	uintptr(pAccessRights),
)
_ = err  // syscall.Errno (valid when the call sets last-error)
_ = r1   // WIN32_ERROR
function GetEffectiveRightsFromAclA(
  pacl: Pointer;   // ACL*
  pTrustee: Pointer;   // TRUSTEE_A*
  pAccessRights: Pointer   // DWORD* out
): DWORD; stdcall;
  external 'ADVAPI32.dll' name 'GetEffectiveRightsFromAclA';
result := DllCall("ADVAPI32\GetEffectiveRightsFromAclA"
    , "Ptr", pacl   ; ACL*
    , "Ptr", pTrustee   ; TRUSTEE_A*
    , "Ptr", pAccessRights   ; DWORD* out
    , "UInt")   ; return: WIN32_ERROR
●GetEffectiveRightsFromAclA(pacl, pTrustee, pAccessRights) = DLL("ADVAPI32.dll", "dword GetEffectiveRightsFromAclA(void*, void*, void*)")
# 呼び出し: GetEffectiveRightsFromAclA(pacl, pTrustee, pAccessRights)
# pacl : ACL* -> "void*"
# pTrustee : TRUSTEE_A* -> "void*"
# pAccessRights : DWORD* out -> "void*"
# なでしこ1は32bit・ANSI(Shift_JIS)。文字列=char*(ANSI)、ポインタ/ハンドル=void*(4byte)。
const std = @import("std");

extern "advapi32" fn GetEffectiveRightsFromAclA(
    pacl: [*c]ACL, // ACL*
    pTrustee: [*c]TRUSTEE_A, // TRUSTEE_A*
    pAccessRights: [*c]u32 // DWORD* out
) callconv(std.os.windows.WINAPI) u32;
proc GetEffectiveRightsFromAclA(
    pacl: ptr ACL,  # ACL*
    pTrustee: ptr TRUSTEE_A,  # TRUSTEE_A*
    pAccessRights: ptr uint32  # DWORD* out
): uint32 {.importc: "GetEffectiveRightsFromAclA", stdcall, dynlib: "ADVAPI32.dll".}
pragma(lib, "advapi32");
extern(Windows)
uint GetEffectiveRightsFromAclA(
    ACL* pacl,   // ACL*
    TRUSTEE_A* pTrustee,   // TRUSTEE_A*
    uint* pAccessRights   // DWORD* out
);
ccall((:GetEffectiveRightsFromAclA, "ADVAPI32.dll"), stdcall, UInt32,
      (Ptr{ACL}, Ptr{TRUSTEE_A}, Ptr{UInt32}),
      pacl, pTrustee, pAccessRights)
# pacl : ACL* -> Ptr{ACL}
# pTrustee : TRUSTEE_A* -> Ptr{TRUSTEE_A}
# pAccessRights : DWORD* out -> Ptr{UInt32}
# stdcall は 32bit のみ意味を持つ(x64 では無視)。
local ffi = require("ffi")
ffi.cdef[[
uint32_t GetEffectiveRightsFromAclA(
    void* pacl,
    void* pTrustee,
    uint32_t* pAccessRights);
]]
local advapi32 = ffi.load("advapi32")
-- advapi32.GetEffectiveRightsFromAclA(pacl, pTrustee, pAccessRights)
-- pacl : ACL*
-- pTrustee : TRUSTEE_A*
-- pAccessRights : DWORD* out
-- 構造体/GUIDへのポインタは cdef が通るよう void* で表記(実型は各引数コメント参照)。値渡し構造体・enum は対応する typedef を cdef に追加すること。
const koffi = require('koffi');
const lib = koffi.load('ADVAPI32.dll');
const GetEffectiveRightsFromAclA = lib.func('__stdcall', 'GetEffectiveRightsFromAclA', 'uint32_t', ['void *', 'void *', 'uint32_t *']);
// GetEffectiveRightsFromAclA(pacl, pTrustee, pAccessRights)
// pacl : ACL* -> 'void *'
// pTrustee : TRUSTEE_A* -> 'void *'
// pAccessRights : DWORD* out -> 'uint32_t *'
// 出力ポインタは koffi.out(...) で包む。構造体は koffi.struct で定義。
const lib = Deno.dlopen("ADVAPI32.dll", {
  GetEffectiveRightsFromAclA: { parameters: ["pointer", "pointer", "pointer"], result: "u32" },
});
// lib.symbols.GetEffectiveRightsFromAclA(pacl, pTrustee, pAccessRights)
// pacl : ACL* -> "pointer"
// pTrustee : TRUSTEE_A* -> "pointer"
// pAccessRights : DWORD* out -> "pointer"
// 文字列は "buffer"。ANSI(-A) は new TextEncoder() で UTF-8/ANSI バイト列(末尾に \x00)を渡す。
// 値渡し構造体は { struct: [ ...field types... ] } を使用。
<?php
$ffi = FFI::cdef(<<<C
uint32_t GetEffectiveRightsFromAclA(
    void* pacl,
    void* pTrustee,
    uint32_t* pAccessRights);
C, "ADVAPI32.dll");
// $ffi->GetEffectiveRightsFromAclA(pacl, pTrustee, pAccessRights);
// pacl : ACL*
// pTrustee : TRUSTEE_A*
// pAccessRights : DWORD* 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, W32APIOptions.ASCII_OPTIONS);
    int GetEffectiveRightsFromAclA(
        Pointer pacl,   // ACL*
        Pointer pTrustee,   // TRUSTEE_A*
        IntByReference pAccessRights   // DWORD* out
    );
}
@[Link("advapi32")]
lib LibADVAPI32
  fun GetEffectiveRightsFromAclA = GetEffectiveRightsFromAclA(
    pacl : ACL*,   # ACL*
    pTrustee : TRUSTEE_A*,   # TRUSTEE_A*
    pAccessRights : UInt32*   # DWORD* out
  ) : UInt32
end
# 構造体/GUID/enum は lib 内に対応する型定義が必要。
# 呼出規約: x64 は規約統一のため OK。x86(32bit)は WINAPI=stdcall だが Crystal の fun に stdcall 付与構文がなく非対応。
import 'dart:ffi';
import 'package:ffi/ffi.dart';

typedef GetEffectiveRightsFromAclANative = Uint32 Function(Pointer<Void>, Pointer<Void>, Pointer<Uint32>);
typedef GetEffectiveRightsFromAclADart = int Function(Pointer<Void>, Pointer<Void>, Pointer<Uint32>);
final GetEffectiveRightsFromAclA = DynamicLibrary.open('ADVAPI32.dll')
    .lookupFunction<GetEffectiveRightsFromAclANative, GetEffectiveRightsFromAclADart>('GetEffectiveRightsFromAclA');
// pacl : ACL* -> Pointer<Void>
// pTrustee : TRUSTEE_A* -> Pointer<Void>
// pAccessRights : DWORD* out -> Pointer<Uint32>
// 文字列は package:ffi の "...".toNativeUtf16()/toNativeUtf8() で変換。
{$mode objfpc}{$H+}
function GetEffectiveRightsFromAclA(
  pacl: Pointer;   // ACL*
  pTrustee: Pointer;   // TRUSTEE_A*
  pAccessRights: Pointer   // DWORD* out
): DWORD; stdcall;
  external 'ADVAPI32.dll' name 'GetEffectiveRightsFromAclA';
import Foreign
import Foreign.C.Types
import Foreign.C.String

foreign import stdcall safe "GetEffectiveRightsFromAclA"
  c_GetEffectiveRightsFromAclA :: Ptr () -> Ptr () -> Ptr Word32 -> IO Word32
-- pacl : ACL* -> Ptr ()
-- pTrustee : TRUSTEE_A* -> Ptr ()
-- pAccessRights : DWORD* out -> Ptr Word32
-- 要 GHC(Windows)。stdcall は x64 では ccall として扱われる。ブロックする API は safe 呼び出し推奨。
open Ctypes
open Foreign

let geteffectiverightsfromacla =
  foreign "GetEffectiveRightsFromAclA"
    ((ptr void) @-> (ptr void) @-> (ptr uint32_t) @-> returning uint32_t)
(* pacl : ACL* -> (ptr void) *)
(* pTrustee : TRUSTEE_A* -> (ptr void) *)
(* pAccessRights : DWORD* out -> (ptr uint32_t) *)
(* foreign は cdecl 前提。x64 Windows では WINAPI と一致。構造体は ctypes structure を定義のこと。 *)
(cffi:define-foreign-library advapi32 (t "ADVAPI32.dll"))
(cffi:use-foreign-library advapi32)

(cffi:defcfun ("GetEffectiveRightsFromAclA" get-effective-rights-from-acl-a :convention :stdcall) :uint32
  (pacl :pointer)   ; ACL*
  (p-trustee :pointer)   ; TRUSTEE_A*
  (p-access-rights :pointer))   ; DWORD* out
; isize/usize(INT_PTR/SIZE_T)は x64 前提で :int64/:uint64。x86 では :int32/:uint32。
use Win32::API;
my $GetEffectiveRightsFromAclA = Win32::API::More->new('ADVAPI32',
    'DWORD GetEffectiveRightsFromAclA(LPVOID pacl, LPVOID pTrustee, LPVOID pAccessRights)');
# my $ret = $GetEffectiveRightsFromAclA->Call($pacl, $pTrustee, $pAccessRights);
# pacl : ACL* -> LPVOID
# pTrustee : TRUSTEE_A* -> LPVOID
# pAccessRights : DWORD* out -> LPVOID
# 値渡し構造体は pack() した文字列、または Win32::API::Struct を使用。

関連項目

文字セット違い
公式の関連項目
使用する型