views:

606

answers:

1

I've read all related topics and haven't found a full answer to my problem.

I would like to give full permissions to SYSTEM and Read & Execute permissions to Users group to a folder under Program Files. Nothing more, nothing less.

I know there are 3 ways to give permissions to a folder using WIX, none of them are really good for me and I'll explain why:

1) Regular Permission element:

    <CreateFolder Directory="Test">
      <Permission User="SYSTEM" GenericAll="yes"/>
      <Permission User="Users" Domain="[LOCAL_MACHINE_NAME]" GenericRead="yes" Read="yes" GenericExecute="yes" ChangePermission="yes"/>
    </CreateFolder>

Problem: It fails on foreign OS since it doesn't knows the "Users" keyword. I tried it with SID as well. Beside that I need to place the Permission element under each file in the Test directory (but if this was the only case, I would have managed)

2) WixUtilsExtension PermissionEx element:

    <CreateFolder Directory="Test">
      <util:PermissionEx User="SYSTEM" GenericAll="yes"/>
      <util:PermissionEx User="Users" Domain="[LOCAL_MACHINE_NAME]" GenericRead="yes" Read="yes" GenericExecute="yes" ChangePermission="yes"/>
    </CreateFolder>

Problem: The folder also keeps the default permissions of the Program Files folder. I can not allow that.

3) PermissionEx with Sddl:

Problem: This element is only available when installing with MSI 5.0. I'm using installer 3.01.

I'll be happy to get any solution, including solutions with custom actions...

+1  A: 

you need to implement deferred custom action for changing permissions. c# custom action example:

[CustomAction]
public static ActionResult SetFolderPermission(Session session)
{
     string folder = session.CustomActionData["Folder"].Trim('\"');
     string sid = session.CustomActionData["SID"].Trim('\"');
     System.Security.Principal.SecurityIdentifier sidID =  new System.Security.Principal.SecurityIdentifier(sid);

     System.Security.AccessControl.DirectorySecurity ds = System.IO.Directory.GetAccessControl(folder);
     ds.AddAccessRule(new System.Security.AccessControl.FileSystemAccessRule(sidID 
                , System.Security.AccessControl.FileSystemRights.Write
                , System.Security.AccessControl.InheritanceFlags.ObjectInherit
                , System.Security.AccessControl.PropagationFlags.NoPropagateInherit
                , System.Security.AccessControl.AccessControlType.Allow));
     System.IO.Directory.SetAccessControl(folder , ds);

     return ActionResult.Success;
}

you may port that on C++, custom action must be deferred - than you must access your session properties by CustomActionData

necrostaz

related questions