AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Win32/Win64 API (native code) Delphi TreeResetNamedSecurityInfoW-Aufrufproblem
Thema durchsuchen
Ansicht
Themen-Optionen

TreeResetNamedSecurityInfoW-Aufrufproblem

Ein Thema von Ghostwalker · begonnen am 27. Feb 2007 · letzter Beitrag vom 9. Mär 2007
Antwort Antwort
Seite 2 von 2     12   
Ghostwalker

Registriert seit: 16. Jun 2003
Ort: Schönwald
1.299 Beiträge
 
Delphi 10.3 Rio
 
#11

Re: TreeResetNamedSecurityInfoW-Aufrufproblem

  Alt 8. Mär 2007, 09:43


Da ich absolut keine Plan mehr habe, was noch falsch sein könnte, poste ich mal die komplette Routine

Delphi-Quellcode:
function TFileSecurityInformation.SetSecurity(
  SecurityInformation: SECURITY_INFORMATION;
  pSecurityDescriptor: PSECURITY_DESCRIPTOR): HRESULT;
var
  dErr : DWORD;
  aclPresent : BOOL;
  aclDefault : BOOL;
  SDRevision : DWORD;
  psd : SECURITY_DESCRIPTOR_CONTROL;
  NewSecurityDescriptor : PSECURITY_DESCRIPTOR;
  os : TOsVersion;
  AbsDACL,AbsSACL,NewDACL,NewSACL : PACL;
  AbsGroup,AbsOwner,NewGroup,NewOwner :PSID;
  dwSizes : array[0..4] of DWORD;
  nsdRel : PSECURITY_DESCRIPTOR;
  NewSI : SECURITY_INFORMATION;


  procedure MakeControlBits;
  begin
    aclPresent := FALSE;
    aclDefault := FALSE;
    SDRevision := 0;
    psd := 0;
    if not (GetSecurityDescriptorControl(pSecurityDescriptor,psd,SDRevision)) then
       DoError(GetLastError);
    if ((Securityinformation and DACL_SECURITY_INFORMATION) = DACL_SECURITY_INFORMATION) then
    begin
      if ((psd and SE_DACL_PROTECTED) = SE_DACL_PROTECTED) then
      begin
        SecurityInformation := SecurityInformation or PROTECTED_DACL_SECURITY_INFORMATION;
        NewSI := NewSI or PROTECTED_DACL_SECURITY_INFORMATION;
        if not (SetSecurityDescriptorControl(NewSecurityDescriptor,SE_DACL_PROTECTED,SE_DACL_PROTECTED)) then
          DoError(GetLastError);
      end;
      if ((psd and SE_DACL_AUTO_INHERIT_REQ) = SE_DACL_AUTO_INHERIT_REQ) then
      begin
        SecurityInformation := SecurityInformation or UNPROTECTED_DACL_SECURITY_INFORMATION;
        NewSI := NewSI or UNPROTECTED_DACL_SECURITY_INFORMATION;
        if not (SetSecurityDescriptorControl(NewSecurityDescriptor,SE_DACL_AUTO_INHERIT_REQ,SE_DACL_AUTO_INHERIT_REQ)) then
          DoError(GetLastError);
      end;
    end;
    if ((SecurityInformation and SACL_SECURITY_INFORMATION) = SACL_SECURITY_INFORMATION) then
    begin
      if ((psd and SE_SACL_PROTECTED) = SE_SACL_PROTECTED) then
      begin
        SecurityInformation := SecurityInformation or PROTECTED_SACL_SECURITY_INFORMATION;
        NewSI := NewSI or PROTECTED_SACL_SECURITY_INFORMATION;
        if not (SetSecurityDescriptorControl(NewSecurityDescriptor,SE_SACL_PROTECTED,SE_SACL_PROTECTED)) then
          DoError(GetLastError);
      end;
      if ((psd and SE_SACL_AUTO_INHERIT_REQ) = SE_SACL_AUTO_INHERIT_REQ) then
      begin
        SecurityInformation := SecurityInformation or UNPROTECTED_SACL_SECURITY_INFORMATION;
        NewSI := NewSI or UNPROTECTED_SACL_SECURITY_INFORMATION;
        if not (SetSecurityDescriptorControl(NewSecurityDescriptor,SE_SACL_AUTO_INHERIT_REQ,SE_SACL_AUTO_INHERIT_REQ)) then
          DoError(GetLastError);
      end;
    end;
  end;

begin
  //some checks if user can change anything
  os := GetWindowsVersion;
  if (pSecurityDescriptor = NIL) then
  begin
    RESULT := E_POINTER;
    EXIT;
  end;
  if (do_SI_READONLY in foptions) then
  begin
    RESULT := E_ACCESSDENIED;
    EXIT;
  end;
  NewSI := 0;
  nsdRel := NIL;
  //ok..user can
  //We first get the "old" Descriptor for merging the new values to it
  dERR := GetNamedSecurityInfow(pwidechar(ffilename),
            SE_FILE_OBJECT,
            SecurityInformation,
            NIL,
            NIL,
            NIL,
            NIL,
            nsdRel);
  //Make a absolut Descriptor
  AbsDACL := NIL;
  AbsSACL := NIL;
  AbsOwner := NIL;
  AbsGroup := NIL;
  NewDACL := NIL;
  NewSACL := NIL;
  NewOwner := NIL;
  NewGroup := NIL;
  NewSecurityDescriptor := NIL;
  fillchar(dwsizes,sizeof(dwsizes),0);
  //First we need the sizes for allocations
  MakeAbsoluteSD(nsdREL,
                 NIL,
                 dwSizes[0],
                 NIL,
                 dwSizes[1],
                 nil,
                 dwSizes[2],
                 nil,
                 dwSizes[3],
                 nil,
                 dwSizes[4]);
  GetMem(NewSecurityDescriptor,dwSizes[0]);
  GetMem(AbsDACL,dwSizes[1]);
  GetMem(AbsSACL,dwSizes[2]);
  GetMem(AbsOwner,dwSizes[3]);
  GetMem(AbsGroup,dwSizes[4]);
  //Now translate from self realtiv to absolute
  if not (MakeAbsoluteSD(nsdRel,
          NewSecurityDescriptor,
          dwSizes[0],
          AbsDACL,
          dwSizes[1],
          AbsSACL,
          dwSizes[2],
          AbsOwner,
          dwSizes[3],
          AbsGroup,
          dwSizes[4])) then
    DoError(GetLastError);
  LocalFree(Cardinal(nsdrel));
  //Make a new SD
  //Set the corresponding Controlbits
  MakeControlBits;
  //Get the new information from the given SD and merge them
  if ((SecurityInformation and DACL_SECURITY_INFORMATION)=DACL_SECURITY_INFORMATION) then
  begin
    if not (GetSecurityDescriptorDACL(pSecurityDescriptor,aclPresent,NewDacl,aclDefault)) then
      DoError(GetLastError);
    if not (SetSecurityDescriptorDACL(NewSecurityDescriptor,aclPresent,NewDACL,acldefault)) then
      DoError(GetLastError);
    newSI := NewSI or DACL_SECURITY_INFORMATION;
  end;
  if ((SecurityInformation and SACL_SECURITY_INFORMATION)=SACL_SECURITY_INFORMATION) then
  begin
    if not (GetSecurityDescriptorSACL(pSecurityDescriptor,aclPresent,NewSacl,aclDefault)) then
      DoError(GetLastError);
    if not (SetSecurityDescriptorSACL(NewSecurityDescriptor,aclPresent,NewSACL,acldefault)) then
      DoError(GetLastError);
    newSI := NewSI or SACL_SECURITY_INFORMATION;
  end;
  if ((SecurityInformation and GROUP_SECURITY_INFORMATION) = GROUP_SECURITY_INFORMATION) then
  begin
    if not (GetSecurityDescriptorGroup(pSecurityDescriptor,NewGroup,@aclDefault)) then
      DoError(GetLastError);
    if not (SetSecurityDescriptorGroup(NewSecurityDescriptor,NewGroup,aclDefault)) then
      DoError(GetLastError);
    newSI := NewSI or GROUP_SECURITY_INFORMATION;
  end;
  if ((SecurityInformation and OWNER_SECURITY_INFORMATION) = OWNER_SECURITY_INFORMATION) then
  begin
    if not (GetSecurityDescriptorOwner(pSecurityDescriptor,NewOwner,@aclDefault)) then
      DoError(GetLastError);
    if not (SetSecurityDescriptorOwner(NewSecurityDescriptor,NewOwner,aclDefault)) then
      DoError(GetLastError);
    newSI := NewSI or OWNER_SECURITY_INFORMATION;
  end;
  //Check if we need to recurse throug a tree
  if (((SecurityInformation AND SI_OWNER_RECURSE) = SI_OWNER_RECURSE) or
     ((SecurityInformation AND SI_RESET_DACL_TREE) = SI_RESET_DACL_TREE) or
     ((SecurityInformation AND SI_RESET_SACL_TREE) = SI_RESET_SACL_TREE)) AND
     fIsDir then
  begin
    //For new Systems use the appropriated API-Calls
    if (os = ovXP) or (os = ov2003) or (os = ovVista) then
    begin
      dErr := TreeResetNamedSecurityInfoW(Pwidechar(ffilename),
              SE_FILE_OBJECT,
              NewSI,
              NewOwner,
              NewGroup,
              NewDACL,
              NewSACL,
              FALSE,
              @DoTreeProgress,
              ProgressInvokeEveryObject,
              SELF);
      if (dErr <> ERROR_SUCCESS) then
        DoError(dErr);
    end
    else
    begin
      //Use alternativ Method for 2000, because no API available
    end;

  end
  else
  begin
    dErr := SetNamedSecurityInfoW(Pwidechar(ffilename),SE_FILE_OBJECT,SecurityInformation,NewOwner,NewGroup,NewDACL,NewSACL);
  end;
  FreeMem(NewSecurityDescriptor,dwSizes[0]);
  FreeMem(AbsDACL,dwSizes[1]);
  FreeMem(AbsSACL,dwSizes[2]);
  FreeMem(AbsOwner,dwSizes[3]);
  FreeMem(AbsOwner,dwSizes[4]);
  if (dErr = ERROR_SUCCESS) then
  begin
    result := S_OK;
    fchanges := TRUE;
  end
  else
    result := E_FAIL;
end;
Die Progress-Routine hab ich, wie Robert es gesagt hat, angepasst

Delphi-Quellcode:

procedure DoTreeProgress(
    pObjectName: LPWSTR; // name of object just processed
    Status: DWORD; // status of operation on object
    var pInvokeSetting: PROG_INVOKE_SETTING; // Never, always,
    Args: PVOID; // Caller specific data
    SecuritySet: BOOL );Stdcall;
ffilename ist natürlich vom Typ Widestring

In der Zwischenzeit hab ich so ziemlich alle Varianten des Aufrufs durch. Aber egal was ich bei
Callback und den InvokeSettings und dem letzten Parameter angebe, ich bekomme immer "falscher Parameter" (87) zurück. Ich bin echt am Verzweifeln.
Uwe
e=mc² or energy = milk * coffee²
  Mit Zitat antworten Zitat
Benutzerbild von Remko
Remko

Registriert seit: 10. Okt 2006
Ort: 's-Hertogenbosch, Die Niederlande
222 Beiträge
 
RAD-Studio 2010 Arc
 
#12

Re: TreeResetNamedSecurityInfoW-Aufrufproblem

  Alt 8. Mär 2007, 10:34
Just be to be sure, why not change this line
NewSI := NewSI or PROTECTED_DACL_SECURITY_INFORMATION;
to NewSI := PROTECTED_DACL_SECURITY_INFORMATION;
because NewSi has not been given a value yet...

You're passing SELF as the Args parameter, are you doing something with this in the callback? If not, just pass nil.

Do you get the same error when using nil and ProgressInvokeNever?
  Mit Zitat antworten Zitat
Ghostwalker

Registriert seit: 16. Jun 2003
Ort: Schönwald
1.299 Beiträge
 
Delphi 10.3 Rio
 
#13

Re: TreeResetNamedSecurityInfoW-Aufrufproblem

  Alt 8. Mär 2007, 11:48
I init the NewSI with 0, because i've to check, witch information the user has changed

It makes no sense, to include PROTECTED_DACL_SECURITY_INFORMATION if the user has not changed the DACL


In my test i don't use this last parameter (Self). It makes no difference if i pass nil or self to it.

I tried the NIL/ProgressInvokeNever combination, but the error is the same in this case.

i also checked the conversion of the call in the jwaaclapi-unit, and, comparing to MSDN, it seems to be right.
Uwe
e=mc² or energy = milk * coffee²
  Mit Zitat antworten Zitat
Benutzerbild von Remko
Remko

Registriert seit: 10. Okt 2006
Ort: 's-Hertogenbosch, Die Niederlande
222 Beiträge
 
RAD-Studio 2010 Arc
 
#14

Re: TreeResetNamedSecurityInfoW-Aufrufproblem

  Alt 8. Mär 2007, 14:36
@NewSi, I meant the first time, NewSi is either nil or 0, 0 and PROTECTED_DACL_SECURITY_INFORMATION = PROTECTED_DACL_SECURITY_INFORMATION
Yes Jedi conversion seems correct (my version is v1.10 2006/01/27 21:48:11)
  Mit Zitat antworten Zitat
Ghostwalker

Registriert seit: 16. Jun 2003
Ort: Schönwald
1.299 Beiträge
 
Delphi 10.3 Rio
 
#15

Re: TreeResetNamedSecurityInfoW-Aufrufproblem

  Alt 8. Mär 2007, 15:45
@NewSI

Yes, but only, if the given SecurityInformation contains DACL_SECURITY_INFORMATION

It's senseless to protect something that is never given
Uwe
e=mc² or energy = milk * coffee²
  Mit Zitat antworten Zitat
Ghostwalker

Registriert seit: 16. Jun 2003
Ort: Schönwald
1.299 Beiträge
 
Delphi 10.3 Rio
 
#16

Re: TreeResetNamedSecurityInfoW-Aufrufproblem

  Alt 9. Mär 2007, 11:03
Strike Problem gelöst.

Ursache war ein falsch gesetztes Flag bei den SecurityInformations. Der Fehler lag genau in der Routine MakeControlBits, und dieser Fehler ist auch in meiner C++-Vorlage.

Jetzt sieht die Routine wie folgt aus:

Delphi-Quellcode:
  procedure MakeControlBits;
  begin
    aclPresent := False;
    aclDefault := False;
    SDRevision := 0;
    psd := 0;
    if not (GetSecurityDescriptorControl(pSecurityDescriptor, psd, SDRevision)) then
      DoError(GetLastError);
    if ((SecurityInformation and DACL_SECURITY_INFORMATION) = DACL_SECURITY_INFORMATION) then
    begin
      if ((psd and SE_DACL_PROTECTED) = SE_DACL_PROTECTED) then
      begin
        SecurityInformation := SecurityInformation or PROTECTED_DACL_SECURITY_INFORMATION;
        if not (SetSecurityDescriptorControl(NewSecurityDescriptor, SE_DACL_PROTECTED, SE_DACL_PROTECTED)) then
          DoError(GetLastError);
      end
      else
      begin
        if ((psd and SE_DACL_AUTO_INHERIT_REQ) = SE_DACL_AUTO_INHERIT_REQ) then
        begin
          SecurityInformation := SecurityInformation or UNPROTECTED_DACL_SECURITY_INFORMATION;
          if not (SetSecurityDescriptorControl(NewSecurityDescriptor, SE_DACL_AUTO_INHERIT_REQ, SE_DACL_AUTO_INHERIT_REQ)) then
            DoError(GetLastError);
        end;
      end;
    end;
    if ((SecurityInformation and SACL_SECURITY_INFORMATION) = SACL_SECURITY_INFORMATION) then
    begin
      if ((psd and SE_SACL_PROTECTED) = SE_SACL_PROTECTED) then
      begin
        SecurityInformation := SecurityInformation or PROTECTED_SACL_SECURITY_INFORMATION;
        if not (SetSecurityDescriptorControl(NewSecurityDescriptor, SE_SACL_PROTECTED, SE_SACL_PROTECTED)) then
          DoError(GetLastError);
      end
      else
      begin
        if ((psd and SE_SACL_AUTO_INHERIT_REQ) = SE_SACL_AUTO_INHERIT_REQ) then
        begin
          SecurityInformation := SecurityInformation or UNPROTECTED_SACL_SECURITY_INFORMATION;
          if not (SetSecurityDescriptorControl(NewSecurityDescriptor, SE_SACL_AUTO_INHERIT_REQ, SE_SACL_AUTO_INHERIT_REQ)) then
            DoError(GetLastError);
        end;
      end;
    end;
  end;
Zur Optimierung hab ich NewSI noch rausgeschmissen und dafür SecurityInformation vor dem Aufruf
noch korregiert:

Delphi-Quellcode:
      SecurityInformation := SecurityInformation and not (SI_OWNER_RECURSE or SI_RESET_DACL_TREE or SI_RESET_SACL_TREE);
      dErr := TreeResetNamedSecurityInfoW(pwidechar(ffilename),
        SE_FILE_OBJECT,
        SecurityInformation,
        NewOwner,
        NewGroup,
        NewDACL,
        NewSACL,
        True,
        @DoTreeProgress,
        ProgressInvokeEveryObject,
        SELF);
Jetzt funktioniert das ganze. Sogar die Callback-Routine wird aufgerufen.

Danke an alle die hier mitgeholfen haben.

Thanks to all they helped here
Uwe
e=mc² or energy = milk * coffee²
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 2 von 2     12   


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 14:27 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz