使用本地var的API调用会导致fn返回后的访问错误(CheckTokenMembership)

问题描述:

在下面的示例中使用外部函数CheckTokenMembership从SO中获得访问错误函数IsUserAdmin返回到IsUserAdminStr。使用本地var的API调用会导致fn返回后的访问错误(CheckTokenMembership)

当b是局部var到n时,IsUserAdmin之后会立即出现访问冲突。如果b是全局变量,那么它工作。

删除CheckTokenMembership停止错误。 FreeSid(AdministratorsGroup)没有效果。 Changing to Result := true;已无效

请指出我明显缺少的东西。

//from https://stackoverflow.com/questions/6261865/looking-for-delphi-7-code-to-detect-if-a-program-is-started-with-administrator-r 

//var b:boolean; // <------ Works if b is here 
function IsUserAdminStr(SingleChar:boolean=false):string; 
begin 
    if IsUserAdmin 
     then result:='Admin' 
     else result:='User'; //<----------- throws access error here 
end; 
function CheckTokenMembership(TokenHandle: THandle; SIdToCheck: PSID; var IsMember: Boolean): BOOL; StdCall; External AdvApi32; 
function IsUserAdmin: Boolean; 
var 
    b: boolean;  // <-----------Fails if b is here 
    b: BOOL;  // <------- this works 
    AdministratorsGroup: PSID; 

const 
    SECURITY_NT_AUTHORITY: SID_IDENTIFIER_AUTHORITY = 
    (Value: (0,0,0,0,0,5)); // ntifs 
    SECURITY_BUILTIN_DOMAIN_RID: DWORD = $00000020; 
    DOMAIN_ALIAS_RID_ADMINS: DWORD = $00000220; 
begin 
    b := AllocateAndInitializeSid(
     SECURITY_NT_AUTHORITY, 
     2, //2 sub-authorities 
     SECURITY_BUILTIN_DOMAIN_RID, //sub-authority 0 
     DOMAIN_ALIAS_RID_ADMINS,  //sub-authority 1 
     0, 0, 0, 0, 0, 0,    //sub-authorities 2-7 not passed 
     AdministratorsGroup); 
    if (b) then 
    begin 
    if not CheckTokenMembership(0, AdministratorsGroup, b) then 
     b := False; 
    FreeSid(AdministratorsGroup); 
    end; 
    Result := b; 
end; 
+0

这是一个输出'BOOL'参数。定义它('out IsMember:BOOL')。我不是说这是你报告的问题的根源,因为我手上没有德尔菲(除了一些神秘的力量解释:)做更多的调试是我的建议。 – Victoria

+0

没有。但是var b:BOOL;而不是布尔使它工作。为什么? –

+0

不是吗?看看Windows SDK如何声明'[CheckTokenMembership'(这应该工作)(https://pastebin.com/MvJ9vwJw))。 – Victoria

如果b BOOL不是布尔值,它的工作原理``变种B:BOOL;`

还是不明白为什么,或为什么它显然奏效了原来那么海报。 (使用D10.1)

+0

Win32 API没有Delphi的'Boolean'类型的概念,只有它自己的'BOOL'类型。它们是不同大小的不同类型('Boolean' = 1个字节,'BOOL' = 4个字节)。 'BOOL'等价于Delphi的'LongBool'。当变量是'Boolean'时,API函数正在尝试写入4个字节,其中只分配了1个字节。 –