internal static T GetAccessControlHandleCore <T>(bool internalCall, bool isFolder, SafeFileHandle handle, AccessControlSections includeSections, SECURITY_INFORMATION securityInfo)
        {
            if (!internalCall)
            {
                securityInfo = CreateSecurityInformation(includeSections);
            }


            // We need the SE_SECURITY_NAME privilege enabled to be able to get the SACL descriptor.
            // So we enable it here for the remainder of this function.

            PrivilegeEnabler privilege = null;

            if (!internalCall && (includeSections & AccessControlSections.Audit) != 0)
            {
                privilege = new PrivilegeEnabler(Privilege.Security);
            }

            using (privilege)
            {
                IntPtr pSidOwner, pSidGroup, pDacl, pSacl;
                SafeGlobalMemoryBufferHandle pSecurityDescriptor;

                var lastError = Security.NativeMethods.GetSecurityInfo(handle, SE_OBJECT_TYPE.SE_FILE_OBJECT, securityInfo, out pSidOwner, out pSidGroup, out pDacl, out pSacl, out pSecurityDescriptor);

                return(GetSecurityDescriptor <T>(lastError, isFolder, null, pSecurityDescriptor));
            }
        }
Exemple #2
0
 internal void Grant()
 {
     if (!Utilities.PlatForm.IsUnixClient())
     {
         priv = new Alphaleonis.Win32.Security.PrivilegeEnabler(Privilege.Backup, Privilege.Restore, Privilege.ManageVolume);
         //see if this proves stable and reliable on all NT platforms
         int sec = Node.Misc.NativeMethods.CoInitializeSecurity(IntPtr.Zero, -1, IntPtr.Zero, IntPtr.Zero, Node.Misc.RpcAuthenticationLevels.None,
                                                                Node.Misc.RpcImpersonationLevels.Impersonate, IntPtr.Zero, Node.Misc.EoAuthenticationCapabilities.None, IntPtr.Zero);
         Logger.Append(Severity.DEBUG, "CoInitializeSecurity() returned " + sec);
     }
 }
        public override void PerformStep()
        {
            logger.LogInformation("Cloning operating system.");
            using (IVssBackupComponents backupComponents = vss.CreateVssBackupComponents())
            {
                this.CreateVssSnapshotOfSystemVolume(backupComponents);

                try
                {
                    logger.LogInformation("Copying system partition data...");
                    using (PrivilegeEnabler privEnabler = new PrivilegeEnabler(Privilege.Backup, Privilege.Restore))
                    {
                        VssSnapshotProperties snapshotInfo = backupComponents.GetSnapshotProperties(this.vssSnapshotId);
                        using (Stream rawVolStream = this.fileSystemHelper.OpenRawDiskStream(snapshotInfo.SnapshotDeviceObject))
                        {
                            string vhdFullName = $"{migrationData.VhdFileTemporaryFolder}\\{migrationData.VhdFileName}";
                            using (VirtualDiskDecorator disk = this.fileSystemHelper.OpenVhdx(vhdFullName))
                            {
                                var partitionTable = disk.Partitions;
                                if (partitionTable != null)
                                {
                                    int partIndex = partitionTable.CreatePrimaryBySector(1, (rawVolStream.Length / disk.Geometry.BytesPerSector), BiosPartitionTypes.Ntfs, false);
                                    PartitionInfoDecorator partition = disk.Partitions[partIndex];

                                    using (var vhdPartitionStream = partition.Open())
                                    {
                                        this.fileSystemHelper.CloneNtfsFileSystem(rawVolStream, vhdPartitionStream, logger);
                                    }
                                }
                                else
                                {
                                    logger.LogError("VHD disk does not contain BIOS partition table. Other partitions tables are not supported.");
                                }
                            }
                        }
                    }
                }
                finally
                {
                    this.RemoveVssSnapshotOfSystemVolume(backupComponents); //always remove the VSS snapshot, either after success or failure
                }
                logger.LogInformation("Cloning operating system completed.");
            }
            return;
        }
Exemple #4
0
        internal static T GetAccessControlCore <T>(bool isFolder, string path, AccessControlSections includeSections, PathFormat pathFormat)
        {
            SecurityInformation securityInfo = CreateSecurityInformation(includeSections);


            // We need the SE_SECURITY_NAME privilege enabled to be able to get the SACL descriptor.
            // So we enable it here for the remainder of this function.

            PrivilegeEnabler privilege = null;

            if ((includeSections & AccessControlSections.Audit) != 0)
            {
                privilege = new PrivilegeEnabler(Privilege.Security);
            }

            using (privilege)
            {
                IntPtr pSidOwner, pSidGroup, pDacl, pSacl;
                SafeGlobalMemoryBufferHandle pSecurityDescriptor;

                string pathLp = Path.GetExtendedLengthPathCore(null, path, pathFormat, GetFullPathOptions.RemoveTrailingDirectorySeparator | GetFullPathOptions.FullCheck);


                // Get/SetNamedSecurityInfo does not work with a handle but with a path, hence does not honor the privileges.
                // It magically does since Windows Server 2012 / 8 but not in previous OS versions.

                uint lastError = Security.NativeMethods.GetNamedSecurityInfo(pathLp, ObjectType.FileObject, securityInfo,
                                                                             out pSidOwner, out pSidGroup, out pDacl, out pSacl, out pSecurityDescriptor);


                // When GetNamedSecurityInfo() fails with ACCESS_DENIED, try again using GetSecurityInfo().

                if (lastError == Win32Errors.ERROR_ACCESS_DENIED)
                {
                    using (SafeFileHandle handle = CreateFileCore(null, pathLp, ExtendedFileAttributes.BackupSemantics, null,
                                                                  FileMode.Open, FileSystemRights.Read, FileShare.Read, false, PathFormat.LongFullPath))
                    {
                        return(GetAccessControlHandleCore <T>(true, isFolder, handle, includeSections, securityInfo));
                    }
                }

                return(GetSecurityDescriptor <T>(lastError, isFolder, pathLp, pSecurityDescriptor));
            }
        }
        public override void PerformStep()
        {
            if (this.migrationData.TemporaryVhdFileIsTheFinalOne)
            {
                return;
            }

            logger.LogInformation("Copying partition data...");
            this.sourceVhdFile      = $"{migrationData.VhdFileTemporaryFolder}\\{migrationData.VhdFileName}";
            this.destinationVhdFile = $"{migrationData.VhdFileDestinationFolder}\\{migrationData.VhdFileName}";

            using (PrivilegeEnabler privEnabler = new PrivilegeEnabler(Privilege.Backup, Privilege.Restore))
            {
                using (VirtualDiskDecorator sourceVhd = this.fileSystemHelper.OpenVhdx(this.sourceVhdFile))
                {
                    using (Stream inpuStream = sourceVhd.Partitions[0].Open())
                    {
                        using (VirtualDiskDecorator destinationVhd = this.fileSystemHelper.OpenVhdx(this.destinationVhdFile))
                        {
                            var partitionTable = destinationVhd.Partitions;
                            int partIndex      = partitionTable.CreatePrimaryBySector(1, (inpuStream.Length / destinationVhd.Geometry.BytesPerSector), BiosPartitionTypes.Ntfs, false);
                            PartitionInfoDecorator partition = destinationVhd.Partitions[partIndex];
                            using (var outputStream = partition.Open())
                            {
                                this.fileSystemHelper.CloneNtfsFileSystem(inpuStream, outputStream, logger);
                            }
                        }
                    }
                }
            }

            if (migrationData.DeleteTemporaryVhdFile)
            {
                this.fileSystem.File.Delete(this.sourceVhdFile);
            }

            logger.LogInformation("Cloning temporary vhd to destination vhd completed.");
        }
        public static PrivilegeEnabler EnableAllPrivileges()
        {
            var privileges       = (Privilege[])Enum.GetValues(typeof(Privilege));
            var process          = Process.GetCurrentProcess();
            var privilegeEnabler = new PrivilegeEnabler(process);

            foreach (var priv in privileges)
            {
                try
                {
                    var result = privilegeEnabler.EnablePrivilege(priv);

                    /* if (process.GetPrivilegeState(Privilege.TakeOwnership) != PrivilegeState.Enabled)
                     *  Logger.Error("Failed to grant privilege {0}", priv.ToString()); */
                }
                catch (Win32Exception /* ex */)
                {
                    /* Logger.Error("Failed to grant privilege {0}: {1}", priv.ToString(), ex.Message); */
                }
            }

            return(privilegeEnabler);
        }
Exemple #7
0
        internal static void SetAccessControlCore(string path, SafeFileHandle handle, ObjectSecurity objectSecurity, AccessControlSections includeSections, PathFormat pathFormat)
        {
            if (pathFormat == PathFormat.RelativePath)
            {
                Path.CheckSupportedPathFormat(path, true, true);
            }

            if (objectSecurity == null)
            {
                throw new ArgumentNullException("objectSecurity");
            }


            var managedDescriptor = objectSecurity.GetSecurityDescriptorBinaryForm();

            using (var safeBuffer = new SafeGlobalMemoryBufferHandle(managedDescriptor.Length))
            {
                var pathLp = Path.GetExtendedLengthPathCore(null, path, pathFormat, GetFullPathOptions.RemoveTrailingDirectorySeparator | GetFullPathOptions.CheckInvalidPathChars);

                safeBuffer.CopyFrom(managedDescriptor, 0, managedDescriptor.Length);

                SECURITY_DESCRIPTOR_CONTROL control;
                uint revision;


                var success = Security.NativeMethods.GetSecurityDescriptorControl(safeBuffer, out control, out revision);

                var lastError = Marshal.GetLastWin32Error();
                if (!success)
                {
                    NativeError.ThrowException(lastError, pathLp);
                }


                PrivilegeEnabler privilegeEnabler = null;

                try
                {
                    var securityInfo = SECURITY_INFORMATION.None;
                    var pDacl        = IntPtr.Zero;

                    if ((includeSections & AccessControlSections.Access) != 0)
                    {
                        bool daclDefaulted, daclPresent;


                        success = Security.NativeMethods.GetSecurityDescriptorDacl(safeBuffer, out daclPresent, out pDacl, out daclDefaulted);

                        lastError = Marshal.GetLastWin32Error();
                        if (!success)
                        {
                            NativeError.ThrowException(lastError, pathLp);
                        }


                        if (daclPresent)
                        {
                            securityInfo |= SECURITY_INFORMATION.DACL_SECURITY_INFORMATION;
                            securityInfo |= (control & SECURITY_DESCRIPTOR_CONTROL.SE_DACL_PROTECTED) != 0 ? SECURITY_INFORMATION.PROTECTED_DACL_SECURITY_INFORMATION : SECURITY_INFORMATION.UNPROTECTED_DACL_SECURITY_INFORMATION;
                        }
                    }


                    var pSacl = IntPtr.Zero;

                    if ((includeSections & AccessControlSections.Audit) != 0)
                    {
                        bool saclDefaulted, saclPresent;


                        success = Security.NativeMethods.GetSecurityDescriptorSacl(safeBuffer, out saclPresent, out pSacl, out saclDefaulted);

                        lastError = Marshal.GetLastWin32Error();
                        if (!success)
                        {
                            NativeError.ThrowException(lastError, pathLp);
                        }


                        if (saclPresent)
                        {
                            securityInfo |= SECURITY_INFORMATION.SACL_SECURITY_INFORMATION;
                            securityInfo |= (control & SECURITY_DESCRIPTOR_CONTROL.SE_SACL_PROTECTED) != 0 ? SECURITY_INFORMATION.PROTECTED_SACL_SECURITY_INFORMATION : SECURITY_INFORMATION.UNPROTECTED_SACL_SECURITY_INFORMATION;

                            privilegeEnabler = new PrivilegeEnabler(Privilege.Security);
                        }
                    }


                    var pOwner = IntPtr.Zero;

                    if ((includeSections & AccessControlSections.Owner) != 0)
                    {
                        bool ownerDefaulted;


                        success = Security.NativeMethods.GetSecurityDescriptorOwner(safeBuffer, out pOwner, out ownerDefaulted);

                        lastError = Marshal.GetLastWin32Error();
                        if (!success)
                        {
                            NativeError.ThrowException(lastError, pathLp);
                        }


                        if (pOwner != IntPtr.Zero)
                        {
                            securityInfo |= SECURITY_INFORMATION.OWNER_SECURITY_INFORMATION;
                        }
                    }


                    var pGroup = IntPtr.Zero;

                    if ((includeSections & AccessControlSections.Group) != 0)
                    {
                        bool groupDefaulted;


                        success = Security.NativeMethods.GetSecurityDescriptorGroup(safeBuffer, out pGroup, out groupDefaulted);

                        lastError = Marshal.GetLastWin32Error();
                        if (!success)
                        {
                            NativeError.ThrowException(lastError, pathLp);
                        }


                        if (pGroup != IntPtr.Zero)
                        {
                            securityInfo |= SECURITY_INFORMATION.GROUP_SECURITY_INFORMATION;
                        }
                    }



                    if (!Utils.IsNullOrWhiteSpace(pathLp))
                    {
                        // SetNamedSecurityInfo()
                        // 2013-01-13: MSDN does not confirm LongPath usage but a Unicode version of this function exists.

                        lastError = (int)Security.NativeMethods.SetNamedSecurityInfo(pathLp, SE_OBJECT_TYPE.SE_FILE_OBJECT, securityInfo, pOwner, pGroup, pDacl, pSacl);

                        if (lastError != Win32Errors.ERROR_SUCCESS)
                        {
                            NativeError.ThrowException(lastError, pathLp);
                        }
                    }

                    else
                    {
                        if (NativeMethods.IsValidHandle(handle))
                        {
                            lastError = (int)Security.NativeMethods.SetSecurityInfo(handle, SE_OBJECT_TYPE.SE_FILE_OBJECT, securityInfo, pOwner, pGroup, pDacl, pSacl);

                            if (lastError != Win32Errors.ERROR_SUCCESS)
                            {
                                NativeError.ThrowException(lastError);
                            }
                        }
                    }
                }
                finally
                {
                    if (null != privilegeEnabler)
                    {
                        privilegeEnabler.Dispose();
                    }
                }
            }
        }
Exemple #8
0
        internal static SafeFileHandle CreateFileCore(KernelTransaction transaction, string path, ExtendedFileAttributes attributes, FileSecurity fileSecurity, FileMode fileMode, FileSystemRights fileSystemRights, FileShare fileShare, bool checkPath, PathFormat pathFormat)
        {
            if (checkPath && pathFormat == PathFormat.RelativePath)
            {
                Path.CheckSupportedPathFormat(path, true, true);
            }

            // When isFile == null, we're working with a device.
            // When opening a VOLUME or removable media drive (for example, a floppy disk drive or flash memory thumb drive),
            // the path string should be the following form: "\\.\X:"
            // Do not use a trailing backslash (\), which indicates the root.

            var pathLp = Path.GetExtendedLengthPathCore(transaction, path, pathFormat, GetFullPathOptions.TrimEnd | GetFullPathOptions.RemoveTrailingDirectorySeparator);

            PrivilegeEnabler privilegeEnabler = null;


            var isAppend = fileMode == FileMode.Append;


            // CreateFileXxx() does not support FileMode.Append mode.
            if (isAppend)
            {
                fileMode          = FileMode.OpenOrCreate;
                fileSystemRights &= FileSystemRights.AppendData; // Add right.
            }


            if (fileSecurity != null)
            {
                fileSystemRights |= (FileSystemRights)0x1000000; // Set right.
            }
            // AccessSystemSecurity = 0x1000000    AccessSystemAcl access type.
            // MaximumAllowed       = 0x2000000    MaximumAllowed  access type.

            if ((fileSystemRights & (FileSystemRights)0x1000000) != 0 ||
                (fileSystemRights & (FileSystemRights)0x2000000) != 0)
            {
                privilegeEnabler = new PrivilegeEnabler(Privilege.Security);
            }


            using (privilegeEnabler)
                using (var securityAttributes = new Security.NativeMethods.SecurityAttributes(fileSecurity))
                {
                    var handle = transaction == null || !NativeMethods.IsAtLeastWindowsVista

                                 // CreateFile() / CreateFileTransacted()
                                 // In the ANSI version of this function, the name is limited to MAX_PATH characters.
                                 // To extend this limit to 32,767 wide characters, call the Unicode version of the function and prepend "\\?\" to the path.
                                 // 2013-01-13: MSDN confirms LongPath usage.

               ? NativeMethods.CreateFile(pathLp, fileSystemRights, fileShare, securityAttributes, fileMode, attributes, IntPtr.Zero)
               : NativeMethods.CreateFileTransacted(pathLp, fileSystemRights, fileShare, securityAttributes, fileMode, attributes, IntPtr.Zero, transaction.SafeHandle, IntPtr.Zero, IntPtr.Zero);

                    var lastError = Marshal.GetLastWin32Error();

                    if (handle.IsInvalid)
                    {
                        handle.Close();
                        NativeError.ThrowException(lastError, pathLp);
                    }


                    if (isAppend)
                    {
                        var stream = new FileStream(handle, FileAccess.Write, NativeMethods.DefaultFileBufferSize, (attributes & ExtendedFileAttributes.Overlapped) != 0);
                        stream.Seek(0, SeekOrigin.End);
                    }

                    return(handle);
                }
        }
Exemple #9
0
    public AppCompatCache(string filename, int controlSet, bool noLogs)
    {
        byte[] rawBytes = null;
        Caches = new List <IAppCompatCache>();

        var controlSetIds = new List <int>();

        RegistryKey subKey = null;

        var isLiveRegistry = string.IsNullOrEmpty(filename);

        if (isLiveRegistry)
        {
            if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                throw new NotSupportedException("Live Registry support is not supported on non-Windows platforms.");
            }

            var keyCurrUser = Microsoft.Win32.Registry.LocalMachine;
            var subKey2     =
                keyCurrUser.OpenSubKey(@"SYSTEM\CurrentControlSet\Control\Session Manager\AppCompatCache");

            if (subKey2 == null)
            {
                subKey2 =
                    keyCurrUser.OpenSubKey(@"SYSTEM\CurrentControlSet\Control\Session Manager\AppCompatibility");

                if (subKey2 == null)
                {
                    Console.WriteLine(
                        @"'CurrentControlSet\Control\Session Manager\AppCompatCache' key not found! Exiting");
                    return;
                }
            }

            rawBytes = (byte[])subKey2.GetValue("AppCompatCache", null);

            subKey2    = keyCurrUser.OpenSubKey(@"SYSTEM\Select");
            ControlSet = (int)subKey2.GetValue("Current");

            var is32Bit = Is32Bit(filename, null);

            var cache = Init(rawBytes, is32Bit, ControlSet);

            Caches.Add(cache);

            return;
        }

        RegistryHive reg;

        if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
        {
            Privilege[] privileges = { Privilege.EnableDelegation, Privilege.Impersonate, Privilege.Tcb };
            using var enabler = new PrivilegeEnabler(Privilege.Backup, privileges);
        }

        ControlSet = controlSet;

        if (File.Exists(filename) == false && Helper.RawFileExists(filename) == false)
        {
            throw new FileNotFoundException($"File not found ({filename})!");
        }

        var dirname  = Path.GetDirectoryName(Path.GetFullPath(filename));
        var hiveBase = Path.GetFileName(filename);



        List <RawCopyReturn> rawFiles = null;

        try
        {
            reg = new RegistryHive(filename)
            {
                RecoverDeleted = true
            };
        }
        catch (IOException)
        {
            //file is in use

            if (Helper.IsAdministrator() == false)
            {
                throw new UnauthorizedAccessException("Administrator privileges not found!");
            }

            Log.Warning("'{Filename}' is in use. Rerouting...", filename);

            var files = new List <string>();
            files.Add(filename);

            var logFiles = Directory.GetFiles(dirname, $"{hiveBase}.LOG?").ToList();

            var log1 = $"{dirname}\\{hiveBase}.LOG1";
            var log2 = $"{dirname}\\{hiveBase}.LOG2";

            if (logFiles.Count == 0)
            {
                if (Helper.RawFileExists(log1))
                {
                    logFiles.Add(log1);
                }

                if (Helper.RawFileExists(log2))
                {
                    logFiles.Add(log2);
                }
            }

            foreach (var logFile in logFiles)
            {
                files.Add(logFile);
            }

            rawFiles = Helper.GetRawFiles(files);
            var b = new byte[rawFiles.First().FileStream.Length];

            rawFiles.First().FileStream.Read(b, 0, (int)rawFiles.First().FileStream.Length);


            reg = new RegistryHive(b, rawFiles.First().InputFilename);
        }

        if (reg.Header.PrimarySequenceNumber != reg.Header.SecondarySequenceNumber)
        {
            if (string.IsNullOrEmpty(dirname))
            {
                dirname = ".";
            }

            var logFiles = Directory.GetFiles(dirname, $"{hiveBase}.LOG?").ToList();

            var log1 = $"{dirname}\\{hiveBase}.LOG1";
            var log2 = $"{dirname}\\{hiveBase}.LOG2";

            if (logFiles.Count == 0)
            {
                if (File.Exists(log1))
                {
                    logFiles.Add(log1);
                }

                if (File.Exists(log2))
                {
                    logFiles.Add(log2);
                }
            }

            if (logFiles.Count == 0)
            {
                if (Helper.IsAdministrator())
                {
                    if (Helper.RawFileExists(log1))
                    {
                        logFiles.Add(log1);
                    }

                    if (Helper.RawFileExists(log2))
                    {
                        logFiles.Add(log2);
                    }
                }
                else
                {
                    Log.Fatal("Log files not found and no administrator access to look for them!");
                }
            }


            if (logFiles.Count == 0)
            {
                if (noLogs == false)
                {
                    Log.Warning(
                        "Registry hive is dirty and no transaction logs were found in the same directory! LOGs should have same base name as the hive. Aborting!!");
                    throw new Exception(
                              "Sequence numbers do not match and transaction logs were not found in the same directory as the hive. Aborting");
                }

                Log.Warning(
                    "Registry hive is dirty and no transaction logs were found in the same directory. Data may be missing! Continuing anyways...");
            }
            else
            {
                if (noLogs == false)
                {
                    if (rawFiles != null)
                    {
                        var lt = new List <TransactionLogFileInfo>();
                        foreach (var rawCopyReturn in rawFiles.Skip(1).ToList())
                        {
                            var b = new byte[rawCopyReturn.FileStream.Length];

                            var tt = new TransactionLogFileInfo(rawCopyReturn.InputFilename,
                                                                b);
                            lt.Add(tt);
                        }

                        reg.ProcessTransactionLogs(lt, true);
                    }
                    else
                    {
                        reg.ProcessTransactionLogs(logFiles.ToList(), true);
                    }
                }
                else
                {
                    Log.Warning(
                        "Registry hive is dirty and transaction logs were found in the same directory, but --nl was provided. Data may be missing! Continuing anyways...");
                }
            }
        }


        reg.ParseHive();

        if (controlSet == -1)
        {
            for (var i = 0; i < 10; i++)
            {
                subKey = reg.GetKey($@"ControlSet00{i}\Control\Session Manager\AppCompatCache");

                if (subKey == null)
                {
                    subKey = reg.GetKey($@"ControlSet00{i}\Control\Session Manager\AppCompatibility");
                }

                if (subKey != null)
                {
                    controlSetIds.Add(i);
                }
            }

            if (controlSetIds.Count > 1)
            {
                Log.Warning(
                    "***The following ControlSet00x keys will be exported: {Cs}. Use -c to process keys individually", string.Join(",", controlSetIds));
            }
        }
        else
        {
            //a control set was passed in
            subKey = reg.GetKey($@"ControlSet00{ControlSet}\Control\Session Manager\AppCompatCache");

            if (subKey == null)
            {
                subKey = reg.GetKey($@"ControlSet00{ControlSet}\Control\Session Manager\AppCompatibility");
            }

            if (subKey == null)
            {
                throw new Exception($"Could not find ControlSet00{ControlSet}. Exiting");
            }

            controlSetIds.Add(ControlSet);
        }


        var is32 = Is32Bit(filename, reg);


        Log.Debug("**** Found {Count} ids to process", controlSetIds.Count);


        foreach (var id in controlSetIds)
        {
            Log.Debug("**** Processing id {Id}", id);

            //  var hive2 = new RegistryHiveOnDemand(filename);

            subKey = reg.GetKey($@"ControlSet00{id}\Control\Session Manager\AppCompatCache");

            if (subKey == null)
            {
                Log.Debug("**** Initial subkey null, getting appCompatability key");
                subKey = reg.GetKey($@"ControlSet00{id}\Control\Session Manager\AppCompatibility");
            }

            Log.Debug("**** Looking for AppCompatcache value");

            var val = subKey?.Values.SingleOrDefault(c => c.ValueName == "AppCompatCache");

            if (val != null)
            {
                Log.Debug("**** Found AppCompatcache value");
                rawBytes = val.ValueDataRaw;
            }

            if (rawBytes == null)
            {
                Log.Error("'AppCompatCache' value not found for 'ControlSet00{Id}'! Exiting", id);
            }

            var cache = Init(rawBytes, is32, id);

            Caches.Add(cache);
        }
    }
Exemple #10
0
        internal static void SetAccessControlCore(string path, SafeFileHandle handle, ObjectSecurity objectSecurity, AccessControlSections includeSections, PathFormat pathFormat)
        {
            if (pathFormat == PathFormat.RelativePath)
            {
                Path.CheckSupportedPathFormat(path, true, true);
            }

            if (objectSecurity == null)
            {
                throw new ArgumentNullException("objectSecurity");
            }


            byte[] managedDescriptor = objectSecurity.GetSecurityDescriptorBinaryForm();

            using (var safeBuffer = new SafeGlobalMemoryBufferHandle(managedDescriptor.Length))
            {
                string pathLp = Path.GetExtendedLengthPathCore(null, path, pathFormat, GetFullPathOptions.RemoveTrailingDirectorySeparator | GetFullPathOptions.CheckInvalidPathChars);

                safeBuffer.CopyFrom(managedDescriptor, 0, managedDescriptor.Length);

                SecurityDescriptorControl control;
                uint revision;

                if (!Security.NativeMethods.GetSecurityDescriptorControl(safeBuffer, out control, out revision))
                {
                    NativeError.ThrowException(Marshal.GetLastWin32Error(), pathLp);
                }


                PrivilegeEnabler privilegeEnabler = null;

                try
                {
                    var    securityInfo = SecurityInformation.None;
                    IntPtr pDacl        = IntPtr.Zero;

                    if ((includeSections & AccessControlSections.Access) != 0)
                    {
                        bool daclDefaulted, daclPresent;

                        if (!Security.NativeMethods.GetSecurityDescriptorDacl(safeBuffer, out daclPresent, out pDacl, out daclDefaulted))
                        {
                            NativeError.ThrowException(Marshal.GetLastWin32Error(), pathLp);
                        }

                        if (daclPresent)
                        {
                            securityInfo |= SecurityInformation.Dacl;
                            securityInfo |= (control & SecurityDescriptorControl.DaclProtected) != 0
                        ? SecurityInformation.ProtectedDacl
                        : SecurityInformation.UnprotectedDacl;
                        }
                    }


                    IntPtr pSacl = IntPtr.Zero;

                    if ((includeSections & AccessControlSections.Audit) != 0)
                    {
                        bool saclDefaulted, saclPresent;

                        if (!Security.NativeMethods.GetSecurityDescriptorSacl(safeBuffer, out saclPresent, out pSacl, out saclDefaulted))
                        {
                            NativeError.ThrowException(Marshal.GetLastWin32Error(), pathLp);
                        }

                        if (saclPresent)
                        {
                            securityInfo |= SecurityInformation.Sacl;
                            securityInfo |= (control & SecurityDescriptorControl.SaclProtected) != 0
                        ? SecurityInformation.ProtectedSacl
                        : SecurityInformation.UnprotectedSacl;

                            privilegeEnabler = new PrivilegeEnabler(Privilege.Security);
                        }
                    }


                    IntPtr pOwner = IntPtr.Zero;

                    if ((includeSections & AccessControlSections.Owner) != 0)
                    {
                        bool ownerDefaulted;

                        if (!Security.NativeMethods.GetSecurityDescriptorOwner(safeBuffer, out pOwner, out ownerDefaulted))
                        {
                            NativeError.ThrowException(Marshal.GetLastWin32Error(), pathLp);
                        }

                        if (pOwner != IntPtr.Zero)
                        {
                            securityInfo |= SecurityInformation.Owner;
                        }
                    }


                    IntPtr pGroup = IntPtr.Zero;

                    if ((includeSections & AccessControlSections.Group) != 0)
                    {
                        bool groupDefaulted;

                        if (!Security.NativeMethods.GetSecurityDescriptorGroup(safeBuffer, out pGroup, out groupDefaulted))
                        {
                            NativeError.ThrowException(Marshal.GetLastWin32Error(), pathLp);
                        }

                        if (pGroup != IntPtr.Zero)
                        {
                            securityInfo |= SecurityInformation.Group;
                        }
                    }


                    uint lastError;

                    if (!Utils.IsNullOrWhiteSpace(pathLp))
                    {
                        // SetNamedSecurityInfo()
                        // In the ANSI version of this function, the name is limited to MAX_PATH characters.
                        // To extend this limit to 32,767 wide characters, call the Unicode version of the function and prepend "\\?\" to the path.
                        // 2013-01-13: MSDN does not confirm LongPath usage but a Unicode version of this function exists.

                        lastError = Security.NativeMethods.SetNamedSecurityInfo(pathLp, ObjectType.FileObject, securityInfo, pOwner, pGroup, pDacl, pSacl);

                        if (lastError != Win32Errors.ERROR_SUCCESS)
                        {
                            NativeError.ThrowException(lastError, pathLp);
                        }
                    }
                    else
                    {
                        if (NativeMethods.IsValidHandle(handle))
                        {
                            lastError = Security.NativeMethods.SetSecurityInfo(handle, ObjectType.FileObject, securityInfo, pOwner, pGroup, pDacl, pSacl);

                            if (lastError != Win32Errors.ERROR_SUCCESS)
                            {
                                NativeError.ThrowException((int)lastError);
                            }
                        }
                    }
                }
                finally
                {
                    if (privilegeEnabler != null)
                    {
                        privilegeEnabler.Dispose();
                    }
                }
            }
        }
Exemple #11
0
    private static List <string> GetRecycleBinFiles(string dir)
    {
        var files = new List <string>();


#if NET6_0
        var enumerationOptions = new EnumerationOptions
        {
            IgnoreInaccessible    = true,
            MatchCasing           = MatchCasing.CaseSensitive,
            RecurseSubdirectories = true,
            AttributesToSkip      = 0
        };


        var files2 = Directory.EnumerateFileSystemEntries(dir, "$I*", enumerationOptions);


        files.AddRange(files2);


        files2 = Directory.EnumerateFileSystemEntries(dir, "INFO2", enumerationOptions);


        files.AddRange(files2);
#elif NET462
        Privilege[] privs = { Privilege.EnableDelegation, Privilege.Impersonate, Privilege.Tcb };
        using var enabler = new PrivilegeEnabler(Privilege.Backup, privs);
        var filters = new DirectoryEnumerationFilters
        {
            // Used to abort the enumeration.
            // CancellationToken = cancelSource.Token,

            // Filter to decide whether to recurse into subdirectories.
            RecursionFilter = entryInfo =>
            {
                if (!entryInfo.IsMountPoint && !entryInfo.IsSymbolicLink)
                {
                    return(true);
                }

                return(false);
            },

            // Filter to process Exception handling.
            ErrorFilter = delegate(int errorCode, string errorMessage, string pathProcessed)
            {
                Log.Error("Error accessing {PathProcessed}. Error: {ErrorMessage}", pathProcessed, errorCode);

                // Return true to continue, false to throw the Exception.
                return(true);
            },

            // Filter to in-/exclude file system entries during the enumeration.
            InclusionFilter = entryInfo =>
            {
                if (entryInfo.FileName == "INFO2" || entryInfo.FileName.StartsWith("$I"))
                {
                    Log.Debug("Found match: {FullPath}", entryInfo.FullPath);
                    return(true);
                }

                return(false);
            }
        };

        var dirEnumOptions =
            DirectoryEnumerationOptions.Files | DirectoryEnumerationOptions.Recursive | DirectoryEnumerationOptions.ContinueOnException |
            DirectoryEnumerationOptions.SkipReparsePoints;

        files.AddRange(Directory.EnumerateFileSystemEntryInfos <string>(dir, dirEnumOptions, filters).Where(File.Exists));
#endif

        return(files);
    }
      internal static T GetAccessControlInternal<T>(bool isFolder, string path, AccessControlSections includeSections, PathFormat pathFormat)
      {
         SecurityInformation securityInfo = 0;
         PrivilegeEnabler privilegeEnabler = null;

         if ((includeSections & AccessControlSections.Access) != 0)
            securityInfo |= SecurityInformation.Dacl;

         if ((includeSections & AccessControlSections.Group) != 0)
            securityInfo |= SecurityInformation.Group;

         if ((includeSections & AccessControlSections.Owner) != 0)
            securityInfo |= SecurityInformation.Owner;

         if ((includeSections & AccessControlSections.Audit) != 0)
         {
            // We need the SE_SECURITY_NAME privilege enabled to be able to get the
            // SACL descriptor. So we enable it here for the remainder of this function.
            privilegeEnabler = new PrivilegeEnabler(Privilege.Security);
            securityInfo |= SecurityInformation.Sacl;
         }

         using (privilegeEnabler)
         {
            string pathLp = Path.GetExtendedLengthPathInternal(null, path, pathFormat, GetFullPathOptions.RemoveTrailingDirectorySeparator | GetFullPathOptions.FullCheck);

            IntPtr pSidOwner, pSidGroup, pDacl, pSacl;
            SafeGlobalMemoryBufferHandle pSecurityDescriptor;
            ObjectSecurity objectSecurity;

            uint lastError = Security.NativeMethods.GetNamedSecurityInfo(pathLp, ObjectType.FileObject, securityInfo, out pSidOwner, out pSidGroup, out pDacl, out pSacl, out pSecurityDescriptor);

            try
            {
               if (lastError == Win32Errors.ERROR_FILE_NOT_FOUND || lastError == Win32Errors.ERROR_PATH_NOT_FOUND)
                  lastError = (isFolder ? Win32Errors.ERROR_PATH_NOT_FOUND : Win32Errors.ERROR_FILE_NOT_FOUND);

               // If the function fails, the return value is zero.
               if (lastError != Win32Errors.ERROR_SUCCESS)
                  NativeError.ThrowException(lastError, pathLp);

               if (!NativeMethods.IsValidHandle(pSecurityDescriptor, false))
                  throw new IOException(Resources.InvalidSecurityDescriptorReturnedFromSystem);


               uint length = Security.NativeMethods.GetSecurityDescriptorLength(pSecurityDescriptor);

               // Seems not to work: Method .CopyTo: length > Capacity, so an Exception is thrown.
               //byte[] managedBuffer = new byte[length];
               //pSecurityDescriptor.CopyTo(managedBuffer, 0, (int) length);

               byte[] managedBuffer = pSecurityDescriptor.ToByteArray(0, (int)length);

               objectSecurity = (isFolder) ? (ObjectSecurity)new DirectorySecurity() : new FileSecurity();
               objectSecurity.SetSecurityDescriptorBinaryForm(managedBuffer);
            }
            finally
            {
               if (pSecurityDescriptor != null)
                  pSecurityDescriptor.Close();
            }

            return (T)(object)objectSecurity;
         }
      }
        internal static SafeFileHandle CreateFileInternal(KernelTransaction transaction, string path, ExtendedFileAttributes attributes, FileSecurity fileSecurity, FileMode fileMode, FileSystemRights fileSystemRights, FileShare fileShare, bool checkPath, PathFormat pathFormat)
        {
            if (checkPath && pathFormat == PathFormat.RelativePath)
            {
                Path.CheckValidPath(path, true, true);
            }

            // When isFile == null, we're working with a device.
            // When opening a VOLUME or removable media drive (for example, a floppy disk drive or flash memory thumb drive),
            // the path string should be the following form: "\\.\X:"
            // Do not use a trailing backslash (\), which indicates the root.

            string pathLp = Path.GetExtendedLengthPathInternal(transaction, path, pathFormat, GetFullPathOptions.TrimEnd | GetFullPathOptions.RemoveTrailingDirectorySeparator);

            PrivilegeEnabler privilegeEnabler = null;

            try
            {
                if (fileSecurity != null)
                {
                    fileSystemRights |= (FileSystemRights)0x1000000;
                }

                // AccessSystemSecurity = 0x1000000    AccessSystemAcl access type.
                // MaximumAllowed       = 0x2000000    MaximumAllowed access type.
                if ((fileSystemRights & (FileSystemRights)0x1000000) != 0 ||
                    (fileSystemRights & (FileSystemRights)0x2000000) != 0)
                {
                    privilegeEnabler = new PrivilegeEnabler(Privilege.Security);
                }


                using (var securityAttributes = new Security.NativeMethods.SecurityAttributes(fileSecurity))
                {
                    SafeFileHandle handle = transaction == null || !NativeMethods.IsAtLeastWindowsVista

                                            // CreateFile() / CreateFileTransacted()
                                            // In the ANSI version of this function, the name is limited to MAX_PATH characters.
                                            // To extend this limit to 32,767 wide characters, call the Unicode version of the function and prepend "\\?\" to the path.
                                            // 2013-01-13: MSDN confirms LongPath usage.

                  ? NativeMethods.CreateFile(pathLp, fileSystemRights, fileShare, securityAttributes, fileMode, attributes, IntPtr.Zero)
                  : NativeMethods.CreateFileTransacted(pathLp, fileSystemRights, fileShare, securityAttributes, fileMode, attributes, IntPtr.Zero, transaction.SafeHandle, IntPtr.Zero, IntPtr.Zero);

                    int lastError = Marshal.GetLastWin32Error();
                    if (handle.IsInvalid)
                    {
                        handle.Close();
                        NativeError.ThrowException(lastError, pathLp);
                    }

                    return(handle);
                }
            }
            finally
            {
                if (privilegeEnabler != null)
                {
                    privilegeEnabler.Dispose();
                }
            }
        }