internal static void CreateDirectory(string path, IsolatedStorageScope scope)
{
if (Directory.Exists(path))
return;
DirectoryInfo info = Directory.CreateDirectory(path);
if (IsMachine(scope) && RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
// Need to emulate COMIsolatedStorage::CreateDirectoryWithDacl(), which gives the following rights:
//
// World / Everyone (S-1-1-0 / SECURITY_WORLD_RID) -> (FILE_GENERIC_WRITE | FILE_GENERIC_READ) & (~WRITE_DAC)
// Creator Owner (S-1-3-0 / SECURITY_CREATOR_OWNER_RID) -> FILE_ALL_ACCESS
// Local Admins (S-1-5-32 / SECURITY_BUILTIN_DOMAIN_RID & DOMAIN_ALIAS_RID_ADMINS) -> FILE_ALL_ACCESS
//
// When looking at rights through the GUI it looks like this:
//
// "Everyone" -> Read, Write
// "Administrators" -> Full control
// "CREATOR OWNER" -> Full control
//
// With rights applying to "This folder, subfolders, and files". No inheritance from the parent folder.
//
// Note that trying to reset the rules for CREATOR OWNER leaves the current directory with the actual creator's SID.
// (But applies CREATOR OWNER as expected for items and subdirectories.) Setting up front when creating the directory
// doesn't exhibit this behavior, but as we can't currently do that we'll take the rough equivalent for now.
DirectorySecurity security = new DirectorySecurity();
// Don't inherit the existing rules
security.SetAccessRuleProtection(isProtected: true, preserveInheritance: false);
security.AddAccessRule(new FileSystemAccessRule(
identity: new SecurityIdentifier(WellKnownSidType.WorldSid, null),
fileSystemRights: FileSystemRights.Read | FileSystemRights.Write,
inheritanceFlags: InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit,
propagationFlags: PropagationFlags.None,
type: AccessControlType.Allow));
security.AddAccessRule(new FileSystemAccessRule(
identity: new SecurityIdentifier(WellKnownSidType.BuiltinAdministratorsSid, null),
fileSystemRights: FileSystemRights.FullControl,
inheritanceFlags: InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit,
propagationFlags: PropagationFlags.None,
type: AccessControlType.Allow));
security.AddAccessRule(new FileSystemAccessRule(
identity: new SecurityIdentifier(WellKnownSidType.CreatorOwnerSid, null),
fileSystemRights: FileSystemRights.FullControl,
inheritanceFlags: InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit,
propagationFlags: PropagationFlags.None,
type: AccessControlType.Allow));
info.SetAccessControl(security);
}
}