예제 #1
0
        /// <summary>
        /// Creates or opens a subkey.
        /// </summary>
        /// <param name="subkey">The relative path the the subkey.</param>
        /// <returns>The subkey.</returns>
        public RegistryKey CreateSubKey(string subkey)
        {
            if (string.IsNullOrEmpty(subkey))
            {
                return(this);
            }

            string[] split     = subkey.Split(new[] { '\\' }, 2);
            int      cellIndex = FindSubKeyCell(split[0]);

            if (cellIndex < 0)
            {
                KeyNodeCell newKeyCell = new KeyNodeCell(split[0], _cell.Index);
                newKeyCell.SecurityIndex = _cell.SecurityIndex;
                ReferenceSecurityCell(newKeyCell.SecurityIndex);
                _hive.UpdateCell(newKeyCell, true);

                LinkSubKey(split[0], newKeyCell.Index);

                if (split.Length == 1)
                {
                    return(new RegistryKey(_hive, newKeyCell));
                }
                return(new RegistryKey(_hive, newKeyCell).CreateSubKey(split[1]));
            }
            KeyNodeCell cell = _hive.GetCell <KeyNodeCell>(cellIndex);

            if (split.Length == 1)
            {
                return(new RegistryKey(_hive, cell));
            }
            return(new RegistryKey(_hive, cell).CreateSubKey(split[1]));
        }
예제 #2
0
        /// <summary>
        /// Opens a sub key.
        /// </summary>
        /// <param name="path">The relative path to the sub key.</param>
        /// <returns>The sub key, or <c>null</c> if not found.</returns>
        public RegistryKey OpenSubKey(string path)
        {
            if (string.IsNullOrEmpty(path))
            {
                return(this);
            }

            string[] split     = path.Split(new char[] { '\\' }, 2);
            int      cellIndex = FindSubKeyCell(split[0]);

            if (cellIndex < 0)
            {
                return(null);
            }
            else
            {
                KeyNodeCell cell = _hive.GetCell <KeyNodeCell>(cellIndex);
                if (split.Length == 1)
                {
                    return(new RegistryKey(_hive, cell));
                }
                else
                {
                    return(new RegistryKey(_hive, cell).OpenSubKey(split[1]));
                }
            }
        }
예제 #3
0
        /// <summary>
        /// Finds a subkey cell, returning it's index in this list.
        /// </summary>
        /// <param name="name">The name of the key to find.</param>
        /// <returns>The index of the found key, or <c>-1</c>.</returns>
        internal int IndexOf(string name)
        {
            foreach (var index in Find(name, 0))
            {
                KeyNodeCell cell = _hive.GetCell <KeyNodeCell>(_subKeyIndexes[index]);
                if (cell.Name.ToUpperInvariant() == name.ToUpperInvariant())
                {
                    return(index);
                }
            }

            return(-1);
        }
예제 #4
0
            public int Compare(int x, int y)
            {
                // TODO: Be more efficient at ruling out no-hopes by using the hash values
                KeyNodeCell cell   = _hive.GetCell <KeyNodeCell>(x);
                int         result = string.Compare(((KeyNodeCell)cell).Name, _searchName, StringComparison.OrdinalIgnoreCase);

                if (result == 0)
                {
                    CellIndex = x;
                }

                return(result);
            }
예제 #5
0
        /// <summary>
        /// Adds a new entry.
        /// </summary>
        /// <param name="name">The name of the subkey.</param>
        /// <param name="cellIndex">The cell index of the subkey.</param>
        /// <returns>The index of the new entry.</returns>
        internal int Add(string name, int cellIndex)
        {
            for (int i = 0; i < _numElements; ++i)
            {
                KeyNodeCell cell = _hive.GetCell <KeyNodeCell>(_subKeyIndexes[i]);
                if (string.Compare(cell.Name, name, StringComparison.OrdinalIgnoreCase) > 0)
                {
                    _subKeyIndexes.Insert(i, cellIndex);
                    _nameHashes.Insert(i, CalcHash(name));
                    _numElements++;
                    return(i);
                }
            }

            _subKeyIndexes.Add(cellIndex);
            _nameHashes.Add(CalcHash(name));
            return(_numElements++);
        }
예제 #6
0
        private void FreeValues(KeyNodeCell cell)
        {
            if (cell.NumValues != 0 && cell.ValueListIndex != -1)
            {
                byte[] valueList = _hive.RawCellData(cell.ValueListIndex, cell.NumValues * 4);

                for (int i = 0; i < cell.NumValues; ++i)
                {
                    int valueIndex = EndianUtilities.ToInt32LittleEndian(valueList, i * 4);
                    _hive.FreeCell(valueIndex);
                }

                _hive.FreeCell(cell.ValueListIndex);
                cell.ValueListIndex  = -1;
                cell.NumValues       = 0;
                cell.MaxValDataBytes = 0;
                cell.MaxValNameBytes = 0;
            }
        }
        internal override int UnlinkSubKey(string name)
        {
            if (ListType == "ri")
            {
                if (_listIndexes.Count == 0)
                {
                    throw new NotImplementedException("Empty indirect list");
                }

                for (int i = 0; i < _listIndexes.Count; ++i)
                {
                    int      tempIndex;
                    ListCell cell = _hive.GetCell <ListCell>(_listIndexes[i]);
                    if (cell.FindKey(name, out tempIndex) <= 0)
                    {
                        _listIndexes[i] = cell.UnlinkSubKey(name);
                        if (cell.Count == 0)
                        {
                            _hive.FreeCell(_listIndexes[i]);
                            _listIndexes.RemoveAt(i);
                        }

                        return(_hive.UpdateCell(this, false));
                    }
                }
            }
            else
            {
                for (int i = 0; i < _listIndexes.Count; ++i)
                {
                    KeyNodeCell cell = _hive.GetCell <KeyNodeCell>(_listIndexes[i]);
                    if (string.Compare(name, cell.Name, StringComparison.OrdinalIgnoreCase) == 0)
                    {
                        _listIndexes.RemoveAt(i);
                        return(_hive.UpdateCell(this, true));
                    }
                }
            }

            return(Index);
        }
        internal override int LinkSubKey(string name, int cellIndex)
        {
            // Look for the first sublist that has a subkey name greater than name
            if (ListType == "ri")
            {
                if (_listIndexes.Count == 0)
                {
                    throw new NotImplementedException("Empty indirect list");
                }

                for (int i = 0; i < _listIndexes.Count - 1; ++i)
                {
                    int      tempIndex;
                    ListCell cell = _hive.GetCell <ListCell>(_listIndexes[i]);
                    if (cell.FindKey(name, out tempIndex) <= 0)
                    {
                        _listIndexes[i] = cell.LinkSubKey(name, cellIndex);
                        return(_hive.UpdateCell(this, false));
                    }
                }

                ListCell lastCell = _hive.GetCell <ListCell>(_listIndexes[_listIndexes.Count - 1]);
                _listIndexes[_listIndexes.Count - 1] = lastCell.LinkSubKey(name, cellIndex);
                return(_hive.UpdateCell(this, false));
            }
            else
            {
                for (int i = 0; i < _listIndexes.Count; ++i)
                {
                    KeyNodeCell cell = _hive.GetCell <KeyNodeCell>(_listIndexes[i]);
                    if (string.Compare(name, cell.Name, StringComparison.OrdinalIgnoreCase) < 0)
                    {
                        _listIndexes.Insert(i, cellIndex);
                        return(_hive.UpdateCell(this, true));
                    }
                }

                _listIndexes.Add(cellIndex);
                return(_hive.UpdateCell(this, true));
            }
        }
예제 #9
0
        private void FreeSubKeys(KeyNodeCell subkeyCell)
        {
            if (subkeyCell.SubKeysIndex == -1)
            {
                throw new InvalidOperationException("No subkey list");
            }

            Cell list = _hive.GetCell <Cell>(subkeyCell.SubKeysIndex);

            SubKeyIndirectListCell indirectList = list as SubKeyIndirectListCell;

            if (indirectList != null)
            {
                ////foreach (int listIndex in indirectList.CellIndexes)
                for (int i = 0; i < indirectList.CellIndexes.Count; ++i)
                {
                    int listIndex = indirectList.CellIndexes[i];
                    _hive.FreeCell(listIndex);
                }
            }

            _hive.FreeCell(list.Index);
        }
예제 #10
0
        internal static Cell Parse(RegistryHive hive, int index, byte[] buffer, int pos)
        {
            string type = Utilities.BytesToString(buffer, pos, 2);

            Cell result = null;

            switch (type)
            {
            case "nk":
                result = new KeyNodeCell(index);
                break;

            case "sk":
                result = new SecurityCell(index);
                break;

            case "vk":
                result = new ValueCell(index);
                break;

            case "lh":
            case "lf":
                result = new SubKeyHashedListCell(hive, index);
                break;

            case "li":
            case "ri":
                result = new SubKeyIndirectListCell(hive, index);
                break;

            default:
                throw new RegistryCorruptException("Unknown cell type '" + type + "'");
            }

            result.ReadFrom(buffer, pos);
            return(result);
        }
예제 #11
0
        /// <summary>
        /// Creates a new (empty) registry hive.
        /// </summary>
        /// <param name="stream">The stream to contain the new hive.</param>
        /// <param name="ownership">Whether the returned object owns the stream.</param>
        /// <returns>The new hive.</returns>
        public static RegistryHive Create(Stream stream, Ownership ownership)
        {
            if (stream == null)
            {
                throw new ArgumentNullException(nameof(stream), "Attempt to create registry hive in null stream");
            }

            // Construct a file with minimal structure - hive header, plus one (empty) bin
            BinHeader binHeader = new BinHeader();

            binHeader.FileOffset = 0;
            binHeader.BinSize    = (int)(4 * Sizes.OneKiB);

            HiveHeader hiveHeader = new HiveHeader();

            hiveHeader.Length = binHeader.BinSize;

            stream.Position = 0;

            byte[] buffer = new byte[hiveHeader.Size];
            hiveHeader.WriteTo(buffer, 0);
            stream.Write(buffer, 0, buffer.Length);

            buffer = new byte[binHeader.Size];
            binHeader.WriteTo(buffer, 0);
            stream.Position = BinStart;
            stream.Write(buffer, 0, buffer.Length);

            buffer = new byte[4];
            EndianUtilities.WriteBytesLittleEndian(binHeader.BinSize - binHeader.Size, buffer, 0);
            stream.Write(buffer, 0, buffer.Length);

            // Make sure the file is initialized out to the end of the firs bin
            stream.Position = BinStart + binHeader.BinSize - 1;
            stream.WriteByte(0);

            // Temporary hive to perform construction of higher-level structures
            RegistryHive newHive  = new RegistryHive(stream);
            KeyNodeCell  rootCell = new KeyNodeCell("root", -1);

            rootCell.Flags = RegistryKeyFlags.Normal | RegistryKeyFlags.Root;
            newHive.UpdateCell(rootCell, true);

            RegistrySecurity sd = new RegistrySecurity();

            sd.SetSecurityDescriptorSddlForm("O:BAG:BAD:PAI(A;;KA;;;SY)(A;CI;KA;;;BA)", AccessControlSections.All);
            SecurityCell secCell = new SecurityCell(sd);

            newHive.UpdateCell(secCell, true);
            secCell.NextIndex     = secCell.Index;
            secCell.PreviousIndex = secCell.Index;
            newHive.UpdateCell(secCell, false);

            rootCell.SecurityIndex = secCell.Index;
            newHive.UpdateCell(rootCell, false);

            // Ref the root cell from the hive header
            hiveHeader.RootCell = rootCell.Index;
            buffer = new byte[hiveHeader.Size];
            hiveHeader.WriteTo(buffer, 0);
            stream.Position = 0;
            stream.Write(buffer, 0, buffer.Length);

            // Finally, return the new hive
            return(new RegistryHive(stream, ownership));
        }
예제 #12
0
 internal RegistryKey(RegistryHive hive, KeyNodeCell cell)
 {
     _hive = hive;
     _cell = cell;
 }
예제 #13
0
        /// <summary>
        /// Deletes the specified subkey. The string subkey is not case-sensitive.
        /// </summary>
        /// <param name="subkey">The subkey to delete.</param>
        /// <param name="throwOnMissingSubKey"><c>true</c> to throw an argument exception if <c>subkey</c> doesn't exist.</param>
        public void DeleteSubKey(string subkey, bool throwOnMissingSubKey)
        {
            if (string.IsNullOrEmpty(subkey))
            {
                throw new ArgumentException("Invalid SubKey", nameof(subkey));
            }

            string[] split = subkey.Split(new[] { '\\' }, 2);

            int subkeyCellIndex = FindSubKeyCell(split[0]);

            if (subkeyCellIndex < 0)
            {
                if (throwOnMissingSubKey)
                {
                    throw new ArgumentException("No such SubKey", nameof(subkey));
                }
                return;
            }

            KeyNodeCell subkeyCell = _hive.GetCell <KeyNodeCell>(subkeyCellIndex);

            if (split.Length == 1)
            {
                if (subkeyCell.NumSubKeys != 0)
                {
                    throw new InvalidOperationException("The registry key has subkeys");
                }

                if (subkeyCell.ClassNameIndex != -1)
                {
                    _hive.FreeCell(subkeyCell.ClassNameIndex);
                    subkeyCell.ClassNameIndex  = -1;
                    subkeyCell.ClassNameLength = 0;
                }

                if (subkeyCell.SecurityIndex != -1)
                {
                    DereferenceSecurityCell(subkeyCell.SecurityIndex);
                    subkeyCell.SecurityIndex = -1;
                }

                if (subkeyCell.SubKeysIndex != -1)
                {
                    FreeSubKeys(subkeyCell);
                }

                if (subkeyCell.ValueListIndex != -1)
                {
                    FreeValues(subkeyCell);
                }

                UnlinkSubKey(subkey);
                _hive.FreeCell(subkeyCellIndex);
                _hive.UpdateCell(_cell, false);
            }
            else
            {
                new RegistryKey(_hive, subkeyCell).DeleteSubKey(split[1], throwOnMissingSubKey);
            }
        }
예제 #14
0
        private void FreeSubKeys(KeyNodeCell subkeyCell)
        {
            if (subkeyCell.SubKeysIndex == -1)
            {
                throw new InvalidOperationException("No subkey list");
            }

            Cell list = _hive.GetCell<Cell>(subkeyCell.SubKeysIndex);

            SubKeyIndirectListCell indirectList = list as SubKeyIndirectListCell;
            if (indirectList != null)
            {
                //foreach (int listIndex in indirectList.CellIndexes)
                for (int i = 0; i < indirectList.CellIndexes.Count; ++i)
                {
                    int listIndex = indirectList.CellIndexes[i];
                    _hive.FreeCell(listIndex);
                }
            }

            _hive.FreeCell(list.Index);
        }
예제 #15
0
        private void FreeValues(KeyNodeCell cell)
        {
            if (cell.NumValues != 0 && cell.ValueListIndex != -1)
            {
                byte[] valueList = _hive.RawCellData(cell.ValueListIndex, cell.NumValues * 4);

                for (int i = 0; i < cell.NumValues; ++i)
                {
                    int valueIndex = Utilities.ToInt32LittleEndian(valueList, i * 4);
                    _hive.FreeCell(valueIndex);
                }

                _hive.FreeCell(cell.ValueListIndex);
                cell.ValueListIndex = -1;
                cell.NumValues = 0;
                cell.MaxValDataBytes = 0;
                cell.MaxValNameBytes = 0;
            }
        }
예제 #16
0
        /// <summary>
        /// Creates or opens a subkey.
        /// </summary>
        /// <param name="subkey">The relative path the the subkey</param>
        /// <returns>The subkey</returns>
        public RegistryKey CreateSubKey(string subkey)
        {
            if (string.IsNullOrEmpty(subkey))
            {
                return this;
            }

            string[] split = subkey.Split(new char[] { '\\' }, 2);
            int cellIndex = FindSubKeyCell(split[0]);

            if (cellIndex < 0)
            {
                KeyNodeCell newKeyCell = new KeyNodeCell(split[0], _cell.Index);
                newKeyCell.SecurityIndex = _cell.SecurityIndex;
                ReferenceSecurityCell(newKeyCell.SecurityIndex);
                _hive.UpdateCell(newKeyCell, true);

                LinkSubKey(split[0], newKeyCell.Index);

                if (split.Length == 1)
                {
                    return new RegistryKey(_hive, newKeyCell);
                }
                else
                {
                    return new RegistryKey(_hive, newKeyCell).CreateSubKey(split[1]);
                }
            }
            else
            {
                KeyNodeCell cell = _hive.GetCell<KeyNodeCell>(cellIndex);
                if (split.Length == 1)
                {
                    return new RegistryKey(_hive, cell);
                }
                else
                {
                    return new RegistryKey(_hive, cell).CreateSubKey(split[1]);
                }
            }
        }
예제 #17
0
 internal RegistryKey(RegistryHive hive, KeyNodeCell cell)
 {
     _hive = hive;
     _cell = cell;
 }