Newsgroup: it.comp.lang.delphi
Titolo: Permessi file

Ciao a tutti.
 
Per problemi che sarebbe lungo raccontarvi ho la necessitï¿œ, da 
programma, di aggiungere il permesso everyone su alcuni file.
Questo lo riesco a fare correttamente (in fondo ho inserito la routine 
per chi servisse) ma il problema ï¿œ un altro: la carissima Microzoz ha 
pensato bene di usare la dicitura everyone per molte lingue ma non per 
tutte (per esempio su windows in spagnolo ï¿œ todos).
Ora la domanda sorge spontanea... come faccio a sapere che diavolo di 
nome dare quando cambio i permessi?
 
Grazie,
David
 
const
   ACL_REVISION = 2;
 
function AddAccountNameToAcl(ptr_acl : PACL; AccountName : string):boolean;
var
   SidBuffer       : array [1..100] of byte;
   ptr_sid         : PSID;
   SidBufSz        : dword;
   DomainNameBuf   : String;
   DomainNameBufSz : dword;
   SNU             : Sid_Name_Use;
begin
   ptr_sid  := @SidBuffer;
   SidBufSz := SizeOf(SidBuffer);
 
   SetLength(DomainNameBuf, 256);
 
   DomainNameBufSz := 256;
 
   Result := LookupAccountName(nil, PChar(AccountName), ptr_sid, 
SidBufSz, PChar(DomainNameBuf), DomainNameBufSz, SNU);
   if Result then
      Begin
        SetLength(DomainNameBuf, DomainNameBufSz);
        Result := AddAccessAllowedAce(ptr_acl^, ACL_REVISION, 
GENERIC_ALL + GENERIC_READ + GENERIC_WRITE + GENERIC_EXECUTE, ptr_sid);
      End;
end;
 
// ---------------------------------------------------------------------
// Impone al file i privilegi di lettura e scrittura per tutti gli 
utenti su un singolo file
// ---------------------------------------------------------------------
function SetEveryoneAllowedToUseFile(AFileName : string):boolean;
var
   SD      : TSecurityDescriptor;
   SA      : TSecurityAttributes;
   SI      : SECURITY_INFORMATION;
   AclBuf  : array [1..1024] of byte;
   ptr_acl : PACL;
begin
   Result := InitializeSecurityDescriptor(@SD, 
SECURITY_DESCRIPTOR_REVISION);
 
   If Result Then
      Begin
        ptr_acl := @AclBuf;
 
        Result  := InitializeACL(ptr_acl^, SizeOf(AclBuf), ACL_REVISION);
 
        If Result Then
           Begin
             AddAccountNameToAcl(ptr_acl, 'Everyone');
             Result := SetSecurityDescriptorDacl(@SD, true, ptr_acl, false);
 
             If Result Then
                Begin
                  SA.nLength              := SizeOf(SA);
                  SA.bInheritHandle       := false;
                  SA.lpSecurityDescriptor := @SD;
                  SI                      := DACL_SECURITY_INFORMATION;
                  Result                  := 
SetFileSecurity(PChar(AFileName), SI, @SD);
                End;
           End;
      End;
end;
 
// ---------------------------------------------------------------------
// Impone al file i privilegi di lettura e scrittura per tutti gli 
utenti su tutti i file di un direttorio
// ---------------------------------------------------------------------
Procedure SetEveryoneAllowedToUseAllFiles(Dir : String; AlsoSubDir : 
Boolean);
Var
   Fine  : Boolean;
   CC, I : Integer;
   Sr    : TSearchRec;
   MyDir : Array Of String;
Begin
   // ----------------------------------------------------
   // Sblocco file
   // ----------------------------------------------------
  {$WARNINGS OFF}
   If FindFirst(Dir+'*.*', faArchive, SR) = 0 Then
  {$WARNINGS ON}
      Begin
        Fine := False;
        While (Not Fine) Do
              Begin
                Application.ProcessMessages;
 
                SetEveryoneAllowedToUseFile(Dir+SR.Name);
 
                Fine := (FindNext(Sr) <> 0);
 
                Application.ProcessMessages;
              End;
      End;
   FindClose(SR);
 
   If Not AlsoSubDir Then Exit;
 
   // ----------------------------------------------------
   // Ricerca e sblocco directory
   // ----------------------------------------------------
   CC := 0;
  {$WARNINGS OFF}
   If FindFirst(Dir+'*.*', faDirectory, SR) = 0 Then
      Begin
        Fine := False;
        While (Not Fine) Do
              Begin
                If (Copy(Sr.Name, 1, 1) <> '.'               ) And
                   (FileGetAttr(Sr.Name) And faDirectory <> 0) Then
                   Begin
                     Try
                       ChDir(Sr.Name);
                       Inc(CC);
                       SetLength(MyDir, CC);
                       MyDir[CC-1] := Sr.Name;
                       ChDir('..\');
                       Application.ProcessMessages;
                     Except
                     End;
                   End;
                Fine := (FindNext(Sr) <> 0);
              End;
 
        For I := 1 To CC Do
            Begin
              Try
                SetEveryoneAllowedToUseFile(Dir+MyDir[I-1]);
                ChDir(MyDir[I-1]);
                SetEveryoneAllowedToUseAllFiles(Dir+MyDir[I-1]+'\', True);
                ChDir('..\');
              Except
              End;
            End;
      End;
  {$WARNINGS ON}
   FindClose(SR);
 
   If (CC > 0) Then Finalize(MyDir);
End;

 David
 
come fai ad aprire la cartella "Documenti"?
 
msdn.microsoft.com/en-us/library/ms707085(v=vs.85).aspx
 
msdn.microsoft.com/en-us/library/windows/desktop/aa446585(v=vs.85).aspx
 
 
ciao
 
 

Ariciao, sono ancora io...
 
Dunque sono riuscito a trovare una procedurina per la conversione dei 
SID in nomi (allegata alla fine se serve) per cui con everyone dovrei 
stare a posto.
Ora un'altra domandina piccola piccola e ultima, spero...
Ho notato che la funzione che uso sovrascrive i permessi presenti su un 
file e non aggiunge, ovvero cancella quelli presenti sull'oggetto ed 
inserisce solamente quello di everyone. Come potrei fare a mantenere 
quelli del file aggiungendo solamente il permesso in piu?
 
Grazie a tutti,
David
 
Function GetNameFromSid(SSID : String) : String;
var
   Sid       : JwaWinNT.PSID;
   peUse     : DWORD;
   cchDomain : DWORD;
   cchName   : DWORD;
   Name      : array of Char;
   Domain    : array of Char;
begin
   Result := '';
 
   Sid := nil;
   Win32Check(ConvertStringSidToSidA(PChar(SSID), SID));
 
   cchName   := 0;
   cchDomain := 0;
   if (not LookupAccountSid(nil, Sid, nil, cchName, nil, cchDomain, 
peUse)) and (GetLastError = ERROR_INSUFFICIENT_BUFFER) then
      begin
        SetLength(Name, cchName);
        SetLength(Domain, cchDomain);
        if LookupAccountSid(nil, Sid, @Name[0], cchName, @Domain[0], 
cchDomain, peUse)
        then
          Result := PChar(Name);
      end;
 
   if Assigned(Sid) then LocalFree(DWORD(Sid));
end;
 
per trovare il nome di everyone basta chiamarla cosi:
 
Nome := GetNameForSid('S-1-1-0');
 
dimenticavo sono necessarie le unit  JwaSddl, JwaWinBase e JwaWinNT, 
incluse nella suit jedy