2013-02-18 6 views
6

Come controllo a livello di codice la creazione dell'autorizzazione file per la cartella? Modifica autorizzazione file? Elimina il permesso di file?
GetNamedSecurityInfo restituisce che posso scrivere in C:\Program Files ma UAC dice Access Denied (5)
Come posso determinare in modo efficace le autorizzazioni di accesso?Come controllo a livello di programmazione le autorizzazioni di modifica?

Il mio codice:

function GetAccessRights(const FileName: String; ObjectType: SE_OBJECT_TYPE; 
    var Access: Cardinal): Cardinal; 
var 
    SecDesc: PSECURITY_DESCRIPTOR; 
    pDacl: PACL; 
    Trusteee: TRUSTEE_; 
begin 
    result := GetNamedSecurityInfo(PChar(FileName), ObjectType, 
    DACL_SECURITY_INFORMATION, nil, nil, @pDacl, nil, SecDesc); 
    if ERROR_SUCCESS = result then 
    begin 
    // the pDacl may be NULL if the object has unrestricted access 
    if pDacl <> nil then 
    begin 
     with Trusteee do 
     begin 
     pMultipleTrustee := nil; 
     MultipleTrusteeOperation := NO_MULTIPLE_TRUSTEE; 
     TrusteeForm := TRUSTEE_IS_NAME; 
     TrusteeType := TRUSTEE_IS_UNKNOWN; 
     ptstrName := 'CURRENT_USER'; 
     end; 
     result := GetEffectiveRightsFromAcl(pDacl^, Trusteee, Access); 
    end 
    else 
    begin 
     Access := $FFFFFFFF; 
     result := ERROR_SUCCESS; 
    end; 
    if SecDesc <> nil then 
     LocalFree(Cardinal(SecDesc)); 
    end; 
end; 
+7

* È più facile chiedere perdono che non ottenere l'autorizzazione * –

+1

Il perdono non è richiesto per 'Programmi '. Windows scrive il file in Virtual Store. – barbaris

+1

Per cosa? Se hai una GUI in cui desideri visualizzare queste informazioni, devi sapere se hai i permessi, non hai scelta; Se è necessario effettivamente * scrivere * qualcosa, non c'è niente di meglio da provare: creare un file temporaneo e quindi cancellarlo. Dubito che qualcos'altro sia veramente affidabile, suggerimento: chi può dire in modo affidabile se si ha accesso in scrittura su un drive di rete mappato, quando il software server è Samba? Anche con l'accesso completo ai file di configurazione potrebbe essere complicato! –

risposta

9

Ho utilizzato NT Utilities per questo. Ha lavorato molto bene per me con Win2K/XP/Vista/7

Esempio dal mio progetto di installazione:

uses unitNTSecurity; 

function CheckAccessToFile(DesiredAccess: DWORD; const FileOrDirName: string; ObjectName: string): Boolean; 
var 
    fo: TNTFileObject; 
    acl: TAccessControlList; 
    ace: TAccessControlElement; 
    name: string; 
    i: integer; 
begin 
    Result := False; 
    if FileExists(FileOrDirName) or DirectoryExists(FileOrDirName) then 
    begin 
    fo := TNTFileObject.Create(FileOrDirName); 
    acl := TAccessControlList.Create; 
    try 
     fo.GetDiscretionaryAccessList(acl); 
     for i := 0 to acl.ElementCount - 1 do 
     begin 
     ace := acl.Element[i]; 
     name := ace.Name; // format is: BUILTIN\Users 
     if (CompareText(ObjectName, name) = 0) and 
      (ace.Type_ = aeAccessAllowed) and 
      (DesiredAccess = ace.Mask) then 
     begin 
      Result := True; 
      Break; 
     end; 
     end; 
    finally 
     fo.Free; 
     acl.Free; 
    end; 
    end; 
end; 

Controllare modify permesso:

Result := CheckAccessToFile($001301BF, 'C:\foo', 'BUILTIN\Users'); 

Una nota sulla mia risposta: Il codice di cui sopra risponde al OP domanda:

Come faccio a livello di codice controllare modificare le autorizzazioni

Ma, se tutto quello che dovete fare, è controllo che l'applicazione è in grado di scrivere in una directory, vorrei non andare per questo tipo di soluzione ACL, e in realtà tenta di scrivere un file temporaneo ad esso, in modo che io sono sicuro al 100% che posso scrivere su di esso.

Uso questo codice come parte del processo di installazione in cui è necessario concedere le autorizzazioni modify per alcune directory, quindi questo codice viene utilizzato per verificare se tale directory non dispone già di tali autorizzazioni. Potrebbe essere uno scenario molto diverso rispetto a il tuo.

ci sono un paio di discussioni su questo problema:

Quindi è necessario selezionare la soluzione secondo lo scenario attuale.