pleriche / FastMM5

FastMM is a fast replacement memory manager for Embarcadero Delphi applications that scales well across multiple threads and CPU cores, is not prone to memory fragmentation, and supports shared memory without the use of external .DLL files.
283 stars 73 forks source link

SetEntriesInACL fails with FastMM4 & 5 but fine in XE6 & Rio with default manager #7

Closed rshuck closed 4 years ago

rshuck commented 4 years ago

I have attached a simple bit of code which will show the problem. If call SetEveryoneFullPermissions({file or folder path}) when calling setentriesinacl you receive the error no entries were set

` unit SecurityUtils;

interface

uses SysUtils, Windows, OleDB, AclApi, AccCtrl, IOUtils;

type TPermissionsGroup = (sgEveryone);

procedure SetEveryoneFullPermissions(const Paths: Array of String);

implementation

function ConvertStringSidToSid(StringSid: PWideChar; var Sid: PSID): Boolean; stdcall; external 'advapi32.dll' name 'ConvertStringSidToSidW';

function GetSid(Group: TPermissionsGroup): PSID; const SecuritySIDs: Array[TPermissionsGroup] of String = ('S-1-1-0'); begin Result:=nil; ConvertStringSIDToSID(PChar(SecuritySIDs[Group]),Result); end;

function BuildAccess(Sid: PSID): EXPLICIT_ACCESS; var cchDomain: DWORD; cchName: DWORD; Name: array of Char; Domain: array of Char; peUse: DWORD; begin 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); end;

if not LookupAccountSid(nil, Sid, @Name[0], cchName, @Domain[0], cchDomain, peUse) then RaiseLastOSError;

ZeroMemory(@Result,SizeOf(Result)); BuildExplicitAccessWithName(@Result, PChar(Name), GENERIC_ALL,GRANT_ACCESS, SUB_CONTAINERS_AND_OBJECTS_INHERIT); end;

function GetAcl(const Access: EXPLICIT_ACCESS): PACL; var R: DWORD; begin R := SetEntriesInAcl(1, @Access, nil, Result); if R<>ERROR_SUCCESS then raise Exception.Create('Failed To SetEntriesInAcl '+SysErrorMessage(R)); end;

procedure SetPermissions(Path: String; ACL: PACL); begin SetNamedSecurityInfo(PChar(Path), SE_FILE_OBJECT,DACL_SECURITY_INFORMATION, nil, nil, ACL, nil); end;

procedure SetEveryoneFullPermissions(const Paths: Array of String); var Path: String; Sid: PSID; Access: EXPLICIT_ACCESS; Acl: PACL; begin Sid:=GetSid(sgEveryone); try Access:=BuildAccess(Sid); Acl:=GetAcl(Access); try for Path in Paths do if not Path.IsEmpty then SetPermissions(Path,Acl); finally LocalFree(HLOCAL(Acl)); end; finally LocalFree(HLOCAL(Sid)); end; end;

end. `

pleriche commented 4 years ago

I have tried your test case in Delphi 10.3.3 with both FastMM4 and FastMM5 and cannot reproduce the issue.

Looking at the code it is not obvious to me how the memory manager could be a factor here, it being mostly Windows API calls.

rshuck commented 4 years ago

Many thanks for looking into this. As you couldn't find a problem I had another dig. I was reading the paths from a json file with SuperObject and when I changed the code to use Rio built-in Json the problem disappeared. I have read that SuperObject does not work 64bit so although I am not using 64 atm was intending to switch at some point anyway.