我试图在Lazarus中运行一个函数,该函数应该将File-ACL添加到该对象的现有ACL中。显然我做错了一些:当程序到达BuildExplicitAccessWithName时程序与SIGSEGV崩溃。关于调试器,此函数直接调用BuildTrusteeWithObjectsAndName,然后导致SIGSEGV。 我在这做错了什么?这是我的代码:
program acltest;
uses JwaWindows;
function AddFileACL(Filename, TrusteeName: AnsiString; AccessMode: ACCESS_MODE; Inheritance: dWord): Boolean; stdcall;
var
pExplicitAccess : PEXPLICIT_ACCESS;
ExistingDacl : PACL;
pExistingDacl : PPACL;
NewAcl : PACL;
psd : PSECURITY_DESCRIPTOR;
begin
NewAcl := nil;
psd := nil;
pExistingDacl := nil;
Result := false;
try
if ERROR_SUCCESS = GetNamedSecurityInfo(pAnsiChar(Filename), SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, nil, nil, pExistingDacl, nil, psd) then
begin
try
BuildExplicitAccessWithName(pExplicitAccess, PAnsiChar(TrusteeName), GENERIC_ALL, AccessMode, Inheritance);
ExistingDacl := pExistingDacl^;
if ERROR_SUCCESS = SetEntriesInAcl(1, pExplicitAccess, ExistingDacl, NewAcl) then
begin
if ERROR_SUCCESS = SetNamedSecurityInfo(pAnsiChar(Filename), SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, nil, nil, NewAcl, nil) then
begin
Result := true;
end;
end;
finally
end;
end;
finally
end;
end;
begin
if AddFileACL('C:\Users\keckc\Desktop\test.txt', 'Everyone', GRANT_ACCESS, SUB_CONTAINERS_AND_OBJECTS_INHERIT) = true then
begin
writeln('Yep, it works!');
end
else begin
writeln('Nope, try again!');
end;
end.
答案 0 :(得分:2)
您传递pExplicitAccess
,它是PEXPLICIT_ACCESS
类型的未初始化指针变量。相反,您需要分配EXPLICIT_ACCESS
结构,并传递其地址。
var
ExplicitAccess: EXPLICIT_ACCESS;
....
BuildExplicitAccessWithName(@ExplicitAccess, ...);
在致电GetNamedSecurityInfo
时,传递psd
有点毫无意义。由于它的值为nil
,因此您也可以删除传递nil
。此时,您将能够删除psd
变量。
对于pExistingDacl
,再次将其初始化为nil
。所以pExistingDacl^
将成为另一个SIGSEV。相反,您应该删除pExistingDacl
变量,然后传递@ExistingDacl
。
您对SetEntriesInAcl
和SetNamedSecurityInfo
的调用似乎有类似的问题,但希望到现在为止,您可以了解该模式并能够解决问题。
最后,我也想知道你为什么要使用ANSI版本的函数而不是Unicode版本。
答案 1 :(得分:0)
在XE8中,很可能其他版本的Delphi GetNamedSecurityInfo声明错误。
解决这个问题的两种方法:
1)Redeclare as:
function FixedGetNamedSecurityInfo(pObjectName: LPWSTR; ObjectType: SE_OBJECT_TYPE;
SecurityInfo: SECURITY_INFORMATION; ppsidOwner, ppsidGroup: PPSID; ppDacl, ppSacl: PPACL;
var ppSecurityDescriptor: PSECURITY_DESCRIPTOR): DWORD; stdcall;
external 'ADVAPI32.DLL' name 'GetNamedSecurityInfoW';
另一种是对使用的指针进行类型转换:
GetNamedSecurityInfo(FileObject.ToPchar, SE_OBJECT_TYPE.SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, nil, nil, PACL(@pExistingDacl), nil, pSD);