#1
  1. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Sep 2015
    Posts
    5
    Rep Power
    0

    Access Violation Trying to modify folder's permissions


    Hello guys,
    I'm trying to make a little bit of code to create a folder and allow everyone modify access to the folder and its sub-directories. So far I have this code here :

    Code:
    unit ModifyPerms;
    
    interface
    
    uses
      Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
      StdCtrls, AccCtrl, perms;
    
    type
      TForm1 = class(TForm)
        Button1: TButton;
        procedure Button1Click(Sender: TObject);
    
      private
        { Private declarations }
      public
        { Public declarations }
      end;
    
    var
      Form1: TForm1;
    
    implementation
    {$R *.DFM}
    
    procedure TForm1.Button1Click(Sender: TObject);
    var
      NewDacl, OldDacl: PACl;
      SD: PSECURITY_DESCRIPTOR;
      EA: PEXPLICIT_ACCESS_A;
    begin
      GetNamedSecurityInfo(PChar('c:\test'), SE_FILE_OBJECT,
    DACL_SECURITY_INFORMATION, nil, nil, @OldDacl, nil, SD);
    
      BuildExplicitAccessWithName(@EA, PChar('Everyone'), GENERIC_ALL,
    GRANT_ACCESS, SUB_CONTAINERS_AND_OBJECTS_INHERIT);
    
      SetEntriesInAcl(1, @EA, OldDacl, NewDacl);
    
      SetNamedSecurityInfo(PChar('c:\test'), SE_FILE_OBJECT,
    DACL_SECURITY_INFORMATION, nil, nil, NewDacl, nil);
    end;
    
    end.
    I'm using Delphi 5 (I know it's old as crap, no I can't just upgrade to a newer Delphi). When I run it tells me "Project ModifyPermissions.exe raised exception class EAccessViolation with message 'Access violation at address 00000001. Read of address 00000001'. Process stopped. Use Step or Run to continue.

    I tried running the program in admin mode, it doesn't change anything. I'm confused since I got this code from someone who's program was working... Any help would be appreciated, thanks in advance!
  2. #2
  3. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Sep 2015
    Posts
    5
    Rep Power
    0
    EDIT : I realized I'm *kind of* doing what I want, but not really, in the sense that I'm deleting all the groups from the security tab which means the folder can be modified by any user but has no protection left whatsoever which is not good...
  4. #3
  5. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jun 2008
    Posts
    397
    Rep Power
    0
    looking at msdn (https://msdn.microsoft.com/en-us/lib...=vs.85%29.aspx) it states that several of the parameters that you expect GetNamedSecurityInfo to populate for you (those marked _Out_opt_) may actually return null, your code doesn't seem to check if null values were in fact returned, so that may be the cause of your access violation.
  6. #4
  7. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Sep 2015
    Posts
    5
    Rep Power
    0
    majlumbo,

    Thanks for replying!

    I singled out every function and realized the one causing the error was :
    Code:
    BuildExplicitAccessWithName(@EA, PChar('Everyone'), GENERIC_ALL, GRANT_ACCESS, SUB_CONTAINERS_AND_OBJECTS_INHERIT);
    Now I saw on another forum that :
    1. The article above helped to use Pack '0' instead of '4' (see below).
    "Pack=4 may work incorrectly (access violation) when used on 64-bit OS. Use '0' (works as per the platform)".
    2. The 2nd required change was changing Integer to Long for 64-bit OS for TRUSTEE and EXPLICIT_ACCESS.
    A 64 bit OS is what I'm using.

    The mentioned article is this
    Do you have any idea how to change the structure "header" like they do in C# and VB to change the pack?
    Code:
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto, Pack = 0)]
  8. #5
  9. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jun 2008
    Posts
    397
    Rep Power
    0
    I'm certainly not the expert on Windows Security so I can only go by what the documentation states. Again from MSDN on BuildExplicitAccessWithName (https://msdn.microsoft.com/en-us/lib...=vs.85%29.aspx) for the first parameter:

    pExplicitAccess [in, out]

    A pointer to an EXPLICIT_ACCESS structure to initialize. The BuildExplicitAccessWithName function does not allocate any memory. This parameter cannot be NULL.

    Emphasis mine on what I think may be the issue...

    Code:
    begin
      GetNamedSecurityInfo(PChar('c:\test'), SE_FILE_OBJECT,
      DACL_SECURITY_INFORMATION, nil, nil, @OldDacl, nil, SD);
    
      //add this to actually allocate the memory
      EA := AllocMem(SizeOf(EXPLICIT_ACCESS));
    
      BuildExplicitAccessWithName(@EA, PChar('Everyone'), GENERIC_ALL, GRANT_ACCESS, SUB_CONTAINERS_AND_OBJECTS_INHERIT);
    Last edited by majlumbo; September 15th, 2015 at 01:42 PM.
  10. #6
  11. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Sep 2015
    Posts
    5
    Rep Power
    0
    majlumbo,

    I just wanted to drop in and tell you that it's working fine now! I had to tweak a few things based on what you told me. Thanks good sir!
  12. #7
  13. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jun 2008
    Posts
    397
    Rep Power
    0
    Glad I could help, you may still want to post the working code in case someone else comes upon the same issue.

    Comments on this post

    • Will-O-The-Wisp agrees : Thank you for helping out here!
  14. #8
  15. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Sep 2015
    Posts
    5
    Rep Power
    0
    Good call!

    Code:
    procedure TForm1.Button1Click(Sender: TObject);
    begin
        GetLocalSecurityIdentifierName();
    end;
    
    procedure TForm1.ChangeFolderPermissions(ipcSIDLocalName: PChar; ipcPathDirectory: PChar);
    const
      FULL_CONTROL           = $001F01FF;
      READ_EXEC_CONTROL      = $001200A9;
      LIMIT_CONTROL          = $001000A9;
      MODIFY_CONTROL         = $001301BF;
      MODIFY_SPECIAL_CONTROL = $001301FF;
      WRITE                  = $00120116;
    var
        NewDACL: PACL;
        RequiredExplicitAccess: array[0..1] of EXPLICIT_ACCESS;
    begin
        //Fills a block of memory with zeros
        ZeroMemory(@RequiredExplicitAccess, 2* Sizeof(EXPLICIT_ACCESS));
    
        //Initializes an EXPLICIT_ACCESS structure with the required data
        BuildExplicitAccessWithName(@RequiredExplicitAccess[0], ipcSIDLocalName, WRITE,
            SET_ACCESS, SUB_CONTAINERS_AND_OBJECTS_INHERIT);
    
        //Creates a new Access Control List by merging the new access with the existing one
        SetEntriesInAcl(1, @RequiredExplicitAccess[0], nil, NewDACL);
    
        //Sets specified security information in the security descriptor of the folder
        SetNamedSecurityInfo(ipcPathDirectory, SE_FILE_OBJECT,
            DACL_SECURITY_INFORMATION, nil, nil, NewDACL, nil);
    
        //Frees the memory
        LocalFree(Cardinal(NewDACL));
    end;
    
    procedure TForm1.GetLocalSecurityIdentifierName();
    const
        USERS_SID = 'S-1-5-32-545';
        EVERYONE_SID = 'S-1-1-0';
        ADMIN_SID = 'S-1-5-32-544';
    var
        SIDCode: PSID;
        SIDType: DWORD;
        SIDNameSize: DWORD;
        DomainSize: DWORD;
        SIDName: array of Char;
        DomainName: array of Char;
        LocalSIDName: PChar;
        DirectoryPath: string;
    begin
        SIDCode := nil;
        SIDNameSize := 0;
        DomainSize := 0;
    
        //Converts a string to a working SID
        Win32Check(ConvertStringSidToSidA(PChar(EVERYONE_SID), SIDCode));
    
        //Checks the length of the SID's name
        LookupAccountSid(nil, SIDCode, nil, SIDNameSize, nil, DomainSize, SIDType);
    
        //Set the appropriate length
        SetLength(SIDName, SIDNameSize);
        SetLength(DomainName, DomainSize);
    
        //Get the SID's name and assign it to the array
        LookupAccountSid(nil, SIDCode, @SIDName[0], SIDNameSize, @DomainName[0], DomainSize, SIDType);
    
        //Assign the name to a PChar
        LocalSIDName := PChar(SIDName);
    
        //Get Program files path
        DirectoryPath:= GetProgramFilesPath();
    
        //Creates directory using path
        CreateDir(DirectoryPath);
    
        //Change permissions
        ChangeFolderPermissions(LocalSIDName, PChar(DirectoryPath));
    
    end;
    
    function TForm1.GetProgramFilesPath(): string;
    const
        PROGRAM_FILES = 'ProgramFiles';
    var
        ProgramFilesPath: string;
        BufferSize: Integer;
    begin
    
        //Get the buffer size
        BufferSize := GetEnvironmentVariable(PChar(PROGRAM_FILES), nil, 0);
        if BufferSize > 0 then
        begin
            //Set the appropriate length
            SetLength(ProgramFilesPath, BufferSize - 1);
    
            //Gets the path from the string
            GetEnvironmentVariable(PChar(PROGRAM_FILES),
                PChar(ProgramFilesPath), BufferSize);
        end;
    
        //Returns the path with the additional folder
        Result:= ProgramFilesPath + '\Test';
    
    end;

    Comments on this post

    • Will-O-The-Wisp agrees : Thank you for sharing your solution!

IMN logo majestic logo threadwatch logo seochat tools logo