![]() |
Re: TreeResetNamedSecurityInfoW-Aufrufproblem
:wall:
Da ich absolut keine Plan mehr habe, was noch falsch sein könnte, poste ich mal die komplette Routine
Delphi-Quellcode:
Die Progress-Routine hab ich, wie Robert es gesagt hat, angepasst
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;
Delphi-Quellcode:
ffilename ist natürlich vom Typ Widestringprocedure 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; 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. |
Re: TreeResetNamedSecurityInfoW-Aufrufproblem
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? |
Re: TreeResetNamedSecurityInfoW-Aufrufproblem
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. |
Re: TreeResetNamedSecurityInfoW-Aufrufproblem
@NewSi, I meant the first time, NewSi is either nil or 0, 0 and PROTECTED_DACL_SECURITY_INFORMATION = PROTECTED_DACL_SECURITY_INFORMATION :gruebel:
Yes Jedi conversion seems correct (my version is v1.10 2006/01/27 21:48:11) |
Re: TreeResetNamedSecurityInfoW-Aufrufproblem
@NewSI
Yes, but only, if the given SecurityInformation contains DACL_SECURITY_INFORMATION :) It's senseless to protect something that is never given :) |
Re: TreeResetNamedSecurityInfoW-Aufrufproblem
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:
Zur Optimierung hab ich NewSI noch rausgeschmissen und dafür SecurityInformation vor dem Aufruf
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; noch korregiert:
Delphi-Quellcode:
Jetzt funktioniert das ganze. Sogar die Callback-Routine wird aufgerufen.
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); Danke an alle die hier mitgeholfen haben. Thanks to all they helped here :) |
Alle Zeitangaben in WEZ +1. Es ist jetzt 19:14 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz