我认为这不是一个Delphi但WinAPI的问题。德尔福没有任何特殊的设施来使这个更容易的AFAIK。
Getting information from an ACL说你需要在打开的句柄上做GetSecurityInfo,然后在你得到的ACL上使用GetEffectiveRightsFromACL。
您指定一个trustee,它可以是名字,但更好地使用SID。 “每个人”的名称都可以更改,但是有一个特殊的SID可以在任何PC上使用,请在Google上查看。好的,这里是:“(S-1-1-0)”。或者你可以使用CreateWellKnownSid并给它WinWorldSid以获得相同的SID(更正确但更长的方式)。
所有这些从五分钟的谷歌搜索,所以要小心错误。
好的,这里有一些代码。
function ConvertStringSidToSid(StringSid: PWideChar; var Sid: PSID): boolean; stdcall; external advapi32 name 'ConvertStringSidToSidW';
function AclGetEffectiveRights(const path, sid: string): cardinal;
var h: THandle; //handle to our directory
err: integer;
dacl: PACL; //access control list for the object
secdesc: pointer;
tr: TRUSTEE;
bsid: PSid;
begin
Result := 0;
//Open directory
h := CreateFile(PChar(path), GENERIC_READ, FILE_SHARE_READ, nil,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL or FILE_FLAG_BACKUP_SEMANTICS, 0);
//we need FILE_FLAG_BACKUP_SEMANTICS to open a directory
if h=INVALID_HANDLE_VALUE then RaiseLastOsError();
try
bsid := nil;
//Query access control list for a directory -- the list you see in the properties box
err := GetSecurityInfo(h, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION,
nil, nil, @dacl, nil, secdesc);
//GetSecurityInfo can return many things but we only need DACL,
//and we are required to also get a security descriptor
if err<>ERROR_SUCCESS then
raise Exception.CreateFmt('Cannot retrieve DACL: error %d',[err]);
try
//Convert string sid to binary sid
if not ConvertStringSidToSid(PChar(sid), bsid) then
RaiseLastOsError();
//Query effective rights for a trustee
BuildTrusteeWithSid(@tr, bsid);
err := GetEffectiveRightsFromAcl(dacl^, tr, Result);
if err<>ERROR_SUCCESS then
raise Exception.CreateFmt('Cannot calculate effective rights: error %d',[err]);
finally
//Documentation says to free some resources this way when we're done with it.
LocalFree(NativeUint(bsid));
LocalFree(NativeUint(secdesc));
end;
finally
CloseHandle(h);
end;
end;
它这样使用:
var rights,test: cardinal;
rights := AclGetEffectiveRights('C:\My\Folder','S-1-1-0');
//List rights you want tested
test := FILE_LIST_DIRECTORY + FILE_ADD_FILE + FILE_ADD_SUBDIRECTORY
+ FILE_READ_EA + FILE_WRITE_EA + FILE_TRAVERSE + FILE_DELETE_CHILD;
Result := (rights and test) = test;
可能无法正常工作;给我的电脑ACCESS_DENIED,但这可能是因为我的complicated domain situation。无论如何,这是一个开始。
点击链接Alexey Dynnikov的[网页](http://www.aldyn.ru/demos/0008/1.html)。它可能会给你一些提示。 – 2013-03-27 13:19:48
你实际上想做什么。推荐的做法是让安装人员在应用程序的ProgramData子文件夹中设置ACL。您不检查安装程序中的任何内容。您只需创建一个新文件夹并使用适当的权限应用ACL。 – 2013-03-27 13:23:39
@david:目录已经存在 - 服务/服务器基本上是现有安装的插件。安装程序不会创建任何数据目录。 – mrabat 2013-03-27 14:37:36