2011-08-02 54 views
0

我想檢測一個文件夾,如果需要管理員權限級別(使用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'); 
+2

爲何降票?我的問題有什麼問題嗎?請幫我修復它:) – Kermia

+2

這個問題不能回答。這太不精確。 「需要管理員權限級別」來做什麼?讀書?來寫?刪除?等等。你能否解釋爲什麼你需要檢測這個,因爲可能有更好的解決方案。 –

+0

這個問題被編輯。 – Kermia

回答

6

以下示例從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; 

enter image description here
用Delphi 2007在64位Windows 7企業版SP 1


反正更容易將下載JEDI Windows Security Code Library,並按照像this one的例子(我希望它的工作原理也可用於目錄,但我很確定它會)。

2

上面例子的小改動,對於那些已經轉移到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;