我正在尝试使用EXPLICIT_ACCESS_A
从Free Pascal中的SetEntriesInAclA
数组创建一个新的ACL,但是我一直使用以下命令从SetEntriesInAclA
不断得到错误代码87(无效参数)以下代码:
uses
sysutils,
JwaWinNT,
JwaAclApi,
JwaAccCtrl,
JwaSDDL,
jwawinbase,
jwawinsta,
jwawintype,
jwawinerror;
function SetupAccess(owner: jwawinnt.PSID; var acl: jwawinnt.PACL): bool;
const
EA_COUNT = 3;
var
sidAuthWorld: jwawinnt.SID_IDENTIFIER_AUTHORITY;
sidAuthNT: jwawinnt.SID_IDENTIFIER_AUTHORITY;
everyoneSID: jwawinnt.PSID;
adminSID: jwawinnt.PSID;
ea: Array[0..(EA_COUNT-1)] of jwaaccctrl.EXPLICIT_ACCESS_A;
status: jwawintype.DWORD;
begin
try
begin
WriteLn(IntToStr(SizeOf(jwaaccctrl.EXPLICIT_ACCESS_A)));
sidAuthWorld := jwawinnt.SECURITY_WORLD_SID_AUTHORITY;
sidAuthNT := jwawinnt.SECURITY_NT_AUTHORITY;
if not (jwawinbase.AllocateAndInitializeSid(@sidAuthWorld, 1, jwawinnt.SECURITY_WORLD_RID,
0, 0, 0, 0, 0, 0, 0, everyoneSID)
and AllocateAndInitializeSid(@sidAuthNT, 2, jwawinnt.SECURITY_BUILTIN_DOMAIN_RID,
jwawinnt.DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, adminSID)) then
begin
WriteLn('Could not allocate SIDs: ' + SysErrorMessage(getLastError()));
Result := false;
end
else
begin
jwawinbase.ZeroMemory(@ea, EA_COUNT * sizeOf(EXPLICIT_ACCESS_A));
ea[0].grfAccessPermissions := GENERIC_ALL;
ea[0].grfAccessMode := DENY_ACCESS;
ea[0].grfInheritance := NO_INHERITANCE;
ea[0].Trustee.MultipleTrusteeOperation := NO_MULTIPLE_TRUSTEE;
ea[0].Trustee.pMultipleTrustee := nil;
ea[0].Trustee.TrusteeForm := TRUSTEE_IS_SID;
ea[0].Trustee.TrusteeType := TRUSTEE_IS_WELL_KNOWN_GROUP;
ea[0].Trustee.ptstrName := pointer(everyoneSID);
ea[1].grfAccessPermissions := GENERIC_ALL;
ea[1].grfAccessMode := SET_ACCESS;
ea[1].grfInheritance := NO_INHERITANCE;
ea[1].Trustee.MultipleTrusteeOperation := NO_MULTIPLE_TRUSTEE;
ea[1].Trustee.pMultipleTrustee := nil;
ea[1].Trustee.TrusteeForm := TRUSTEE_IS_SID;
ea[1].Trustee.TrusteeType := TRUSTEE_IS_GROUP;
ea[1].Trustee.ptstrName := pointer(adminSID);
ea[2].grfAccessPermissions := GENERIC_ALL;
ea[2].grfAccessMode := SET_ACCESS;
ea[2].grfInheritance := NO_INHERITANCE;
ea[2].Trustee.MultipleTrusteeOperation := NO_MULTIPLE_TRUSTEE;
ea[2].Trustee.pMultipleTrustee := nil;
ea[2].Trustee.TrusteeForm := TRUSTEE_IS_SID;
ea[2].Trustee.TrusteeType := TRUSTEE_IS_USER;
ea[2].Trustee.ptstrName := pointer(owner);
status := jwaaclapi.SetEntriesInAclA(2, @ea, nil, acl);
if status = ERROR_SUCCESS then
Result := true
else
begin
WriteLn('Error in SetEntriesInAcl: ' + IntToStr(status));
Result := false;
end;
end;
end
finally
If Assigned(everyoneSID) then
jwawinbase.FreeSID(everyoneSID);
If Assigned(adminSID) then
jwawinbase.FreeSID(adminSID);
end
end;
[在搜索该问题时,我遇到了this question,这暗示该问题可能与EXPLICIT_ACCESS_A
记录的对齐有关。
并且确定WriteLn(IntToStr(SizeOf(jwaaccctrl.EXPLICIT_ACCESS_A)));
足够大,它的大小为20。这是因为jedi将该结构声明为packed
。从链接的问题中,我认为EXPLICIT_ACCESS_A
应该大小为24,但在C ++中测试后,实际上似乎为32。
我还尝试将EXPLICIT_ACCESS_A
和TRUSTEE_A
结构复制到我的单位并删除packed
关键字。产生大小为24的结构,但仍然是相同的错误。
结论:我可以使用jedi制作上述代码,还是jedi中的错误/疏忽?
还请注意,我正在使用Lazarus 2.0.4和FPC 3.0.4从x64交叉编译为x86。
对于32位,EXPLICIT_ACCESS_A结构应为32字节。该记录可能很挤满,因为它包含一个联合。我在Delphi中使用Jedi ApiLib进行了测试,它返回正确的大小:
program SizeTest;
{$APPTYPE CONSOLE}
{$R *.res}
uses
System.SysUtils,
JwaAccCtrl;
begin
WriteLn(Format('EXPLICIT_ACCESS_A size: %d', [SizeOf(EXPLICIT_ACCESS_A)]));
输出:
在Delphi {$ MINENUMSIZE 4}中用于将枚举强制为4个字节(如C中一样,也许您需要在Lazarus/FPC中设置它?