我试图在Lazarus中实现一个函数,该函数应该向该对象的现有ACL中添加一个File。显然,我做错了什么:当程序到达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.
发布于 2014-07-30 10:06:14
传递pExplicitAccess
,它是PEXPLICIT_ACCESS
类型的未初始化指针变量。相反,您需要分配一个EXPLICIT_ACCESS
结构,并传递其地址。
var
ExplicitAccess: EXPLICIT_ACCESS;
....
BuildExplicitAccessWithName(@ExplicitAccess, ...);
在对GetNamedSecurityInfo
的调用中,传递psd
有点毫无意义。由于它的值为nil
,所以您还可以删除pass nil
。此时,您将能够删除psd
变量。
至于pExistingDacl
,您再次将其初始化为nil
。因此,pExistingDacl^
将成为另一个SIGSEV。相反,您应该删除pExistingDacl
变量,并传递@ExistingDacl
。
对SetEntriesInAcl
和SetNamedSecurityInfo
的调用似乎存在类似的问题,但希望到现在为止,您可以理解模式,并能够解决这些问题。
最后,我也想知道为什么要使用函数的ANSI版本而不是Unicode版本。
发布于 2015-07-16 20:45:09
在XE8中,很可能还有其他风格的德尔菲,GetNamedSecurityInfo被宣布错了。
解决这一问题的两种方法:
1)重新声明为:
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);
https://stackoverflow.com/questions/25033651
复制相似问题