Esempio n. 1
0
        private RegistryValue AddRegistryValue(string name)
        {
            byte[] valueList = _hive.RawCellData(_cell.ValueListIndex, _cell.NumValues * 4);
            if (valueList == null)
            {
                valueList = new byte[0];
            }

            int insertIdx = 0;

            while (insertIdx < _cell.NumValues)
            {
                int       valueCellIndex = EndianUtilities.ToInt32LittleEndian(valueList, insertIdx * 4);
                ValueCell cell           = _hive.GetCell <ValueCell>(valueCellIndex);
                if (string.Compare(name, cell.Name, StringComparison.OrdinalIgnoreCase) < 0)
                {
                    break;
                }

                ++insertIdx;
            }

            // Allocate a new value cell (note _hive.UpdateCell does actual allocation).
            ValueCell valueCell = new ValueCell(name);

            _hive.UpdateCell(valueCell, true);

            // Update the value list, re-allocating if necessary
            byte[] newValueList = new byte[_cell.NumValues * 4 + 4];
            Array.Copy(valueList, 0, newValueList, 0, insertIdx * 4);
            EndianUtilities.WriteBytesLittleEndian(valueCell.Index, newValueList, insertIdx * 4);
            Array.Copy(valueList, insertIdx * 4, newValueList, insertIdx * 4 + 4, (_cell.NumValues - insertIdx) * 4);
            if (_cell.ValueListIndex == -1 ||
                !_hive.WriteRawCellData(_cell.ValueListIndex, newValueList, 0, newValueList.Length))
            {
                int newListCellIndex = _hive.AllocateRawCell(MathUtilities.RoundUp(newValueList.Length, 8));
                _hive.WriteRawCellData(newListCellIndex, newValueList, 0, newValueList.Length);

                if (_cell.ValueListIndex != -1)
                {
                    _hive.FreeCell(_cell.ValueListIndex);
                }

                _cell.ValueListIndex = newListCellIndex;
            }

            // Record the new value and save this cell
            _cell.NumValues++;
            _hive.UpdateCell(_cell, false);

            // Finally, set the data in the value cell
            return(new RegistryValue(_hive, valueCell));
        }
Esempio n. 2
0
        /// <summary>
        /// Deletes a named value stored within this key.
        /// </summary>
        /// <param name="name">The name of the value to delete.</param>
        /// <param name="throwOnMissingValue">Throws ArgumentException if <c>name</c> doesn't exist.</param>
        public void DeleteValue(string name, bool throwOnMissingValue)
        {
            bool foundValue = false;

            if (_cell.NumValues != 0)
            {
                byte[] valueList = _hive.RawCellData(_cell.ValueListIndex, _cell.NumValues * 4);

                int i = 0;
                while (i < _cell.NumValues)
                {
                    int       valueIndex = EndianUtilities.ToInt32LittleEndian(valueList, i * 4);
                    ValueCell valueCell  = _hive.GetCell <ValueCell>(valueIndex);
                    if (string.Compare(valueCell.Name, name, StringComparison.OrdinalIgnoreCase) == 0)
                    {
                        foundValue = true;
                        _hive.FreeCell(valueIndex);
                        _cell.NumValues--;
                        _hive.UpdateCell(_cell, false);
                        break;
                    }

                    ++i;
                }

                // Move following value's to fill gap
                if (i < _cell.NumValues)
                {
                    while (i < _cell.NumValues)
                    {
                        int valueIndex = EndianUtilities.ToInt32LittleEndian(valueList, (i + 1) * 4);
                        EndianUtilities.WriteBytesLittleEndian(valueIndex, valueList, i * 4);

                        ++i;
                    }

                    _hive.WriteRawCellData(_cell.ValueListIndex, valueList, 0, _cell.NumValues * 4);
                }

                // TODO: Update maxbytes for value name and value content if this was the largest value for either.
                // Windows seems to repair this info, if not accurate, though.
            }

            if (throwOnMissingValue && !foundValue)
            {
                throw new ArgumentException("No such value: " + name, nameof(name));
            }
        }
Esempio n. 3
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);
        }
Esempio n. 4
0
        private RegistryValue GetRegistryValue(string name)
        {
            if (name != null && name.Length == 0)
            {
                name = null;
            }

            if (_cell.NumValues != 0)
            {
                byte[] valueList = _hive.RawCellData(_cell.ValueListIndex, _cell.NumValues * 4);

                for (int i = 0; i < _cell.NumValues; ++i)
                {
                    int       valueIndex = EndianUtilities.ToInt32LittleEndian(valueList, i * 4);
                    ValueCell cell       = _hive.GetCell <ValueCell>(valueIndex);
                    if (string.Compare(cell.Name, name, StringComparison.OrdinalIgnoreCase) == 0)
                    {
                        return(new RegistryValue(_hive, cell));
                    }
                }
            }

            return(null);
        }
Esempio n. 5
0
        private RegistryValue AddRegistryValue(string name)
        {
            byte[] valueList = _hive.RawCellData(_cell.ValueListIndex, _cell.NumValues * 4);
            if (valueList == null)
            {
                valueList = new byte[0];
            }

            int insertIdx = 0;
            while(insertIdx < _cell.NumValues)
            {
                int valueCellIndex = Utilities.ToInt32LittleEndian(valueList, insertIdx * 4);
                ValueCell cell = _hive.GetCell<ValueCell>(valueCellIndex);
                if (string.Compare(name, cell.Name, StringComparison.OrdinalIgnoreCase) < 0)
                {
                    break;
                }

                ++insertIdx;
            }

            // Allocate a new value cell (note _hive.UpdateCell does actual allocation).
            ValueCell valueCell = new ValueCell(name);
            _hive.UpdateCell(valueCell, true);

            // Update the value list, re-allocating if necessary
            byte[] newValueList = new byte[_cell.NumValues * 4 + 4];
            Array.Copy(valueList, 0, newValueList, 0, insertIdx * 4);
            Utilities.WriteBytesLittleEndian(valueCell.Index, newValueList, insertIdx * 4);
            Array.Copy(valueList, insertIdx * 4, newValueList, insertIdx * 4 + 4, (_cell.NumValues - insertIdx) * 4);
            if (_cell.ValueListIndex == -1 || !_hive.WriteRawCellData(_cell.ValueListIndex, newValueList, 0, newValueList.Length))
            {
                int newListCellIndex = _hive.AllocateRawCell(Utilities.RoundUp(newValueList.Length, 8));
                _hive.WriteRawCellData(newListCellIndex, newValueList, 0, newValueList.Length);

                if (_cell.ValueListIndex != -1)
                {
                    _hive.FreeCell(_cell.ValueListIndex);
                }

                _cell.ValueListIndex = newListCellIndex;
            }

            // Record the new value and save this cell
            _cell.NumValues++;
            _hive.UpdateCell(_cell, false);

            // Finally, set the data in the value cell
            return new RegistryValue(_hive, valueCell);
        }
Esempio n. 6
0
 internal RegistryValue(RegistryHive hive, ValueCell cell)
 {
     _hive = hive;
     _cell = cell;
 }
Esempio n. 7
0
 internal RegistryValue(RegistryHive hive, ValueCell cell)
 {
     _hive = hive;
     _cell = cell;
 }