我想检测一个文件夹,如果需要管理员权限级别(使用Delphi
)。可能吗?
我写了这段代码。这正是我想要的。但是我想用Windows标准函数来做这件事。
// Check if You need Administrator-level access to create a folder
try
mkdir(SDirectory + '\~TEST');
except
on E: exception do
begin
if E.message = 'File access denied' then
begin
MessageBox(self.Handle,
'You need Administrator-level access to create this folder', '', MB_ICONERROR);
exit;
end;
end;
end;
RmDir(SDirectory + '\~TEST');
以下示例是从this article翻译而来的。它可用于确定文件或目录是否具有that article中为每个用户注意的访问权限,因此如果我要求FILE_ALL_ACCESS,则表示每个人都拥有对所需文件或目录的完全访问权限。请注意,在下面的代码中没有异常处理,我甚至不记得上次使用VB的时候所以它可能是错误的,所以把它当作灵感并随意修改这篇文章。
const
FILE_READ_DATA = $0001;
FILE_WRITE_DATA = $0002;
FILE_APPEND_DATA = $0004;
FILE_READ_EA = $0008;
FILE_WRITE_EA = $0010;
FILE_EXECUTE = $0020;
FILE_READ_ATTRIBUTES = $0080;
FILE_WRITE_ATTRIBUTES = $0100;
FILE_GENERIC_READ = (STANDARD_RIGHTS_READ or FILE_READ_DATA or
FILE_READ_ATTRIBUTES or FILE_READ_EA or SYNCHRONIZE);
FILE_GENERIC_WRITE = (STANDARD_RIGHTS_WRITE or FILE_WRITE_DATA or
FILE_WRITE_ATTRIBUTES or FILE_WRITE_EA or FILE_APPEND_DATA or SYNCHRONIZE);
FILE_GENERIC_EXECUTE = (STANDARD_RIGHTS_EXECUTE or FILE_READ_ATTRIBUTES or
FILE_EXECUTE or SYNCHRONIZE);
FILE_ALL_ACCESS = STANDARD_RIGHTS_REQUIRED or SYNCHRONIZE or $1FF;
function CheckFileAccess(const FileName: string; const CheckedAccess: Cardinal): Cardinal;
var Token: Cardinal;
Status: LongBool;
Access: Cardinal;
SecDescSize: Cardinal;
PrivSetSize: Cardinal;
PrivSet: PRIVILEGE_SET;
Mapping: GENERIC_MAPPING;
SecDesc: PSECURITY_DESCRIPTOR;
begin
Result := 0;
GetFileSecurity(PChar(Filename), OWNER_SECURITY_INFORMATION or GROUP_SECURITY_INFORMATION or DACL_SECURITY_INFORMATION, nil, 0, SecDescSize);
SecDesc := GetMemory(SecDescSize);
if GetFileSecurity(PChar(Filename), OWNER_SECURITY_INFORMATION or GROUP_SECURITY_INFORMATION or DACL_SECURITY_INFORMATION, SecDesc, SecDescSize, SecDescSize) then
begin
ImpersonateSelf(SecurityImpersonation);
OpenThreadToken(GetCurrentThread, TOKEN_QUERY, False, Token);
if Token <> 0 then
begin
Mapping.GenericRead := FILE_GENERIC_READ;
Mapping.GenericWrite := FILE_GENERIC_WRITE;
Mapping.GenericExecute := FILE_GENERIC_EXECUTE;
Mapping.GenericAll := FILE_ALL_ACCESS;
MapGenericMask(Access, Mapping);
PrivSetSize := SizeOf(PrivSet);
AccessCheck(SecDesc, Token, CheckedAccess, Mapping, PrivSet, PrivSetSize, Access, Status);
CloseHandle(Token);
if Status then
Result := Access;
end;
end;
FreeMem(SecDesc, SecDescSize);
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
if CheckFileAccess('C:\Windows', FILE_ALL_ACCESS) = FILE_ALL_ACCESS then
ShowMessage('C:\Windows has full access for everyone')
else
ShowMessage('Someone has no full access to C:\Windows');
end;
使用64位Windows 7 Enterprise SP 1上的Delphi 2007
无论如何更容易下载JEDI Windows Security Code Library并遵循像this one的例子(我希望它也适用于目录,但我很确定它会)。
对于那些已经转移到Delphi XE2及以上版本(Token不再适用于Cardinal,必须是THandle)的上述示例的小改动。
function getFileAccess(...):Cardinal;
var
Token: THandle;//No longer Cardinal
begin
{ ... code ...}
if GetFileSecurity({...params...}) then
begin
//... more stuff
OpenThreadToken(GetCurrentThread,TOKEN_QUERY,false,Token);
if Token<>0 then
begin
//... more stuff
AccessCheck(SecDesc,Token,CheckedAccess,Mapping,PrivSet,PrivSetSize,Access,Status);
CloseHandle(Token);
//... more stuff
end;
end;
//....more stuff
end;