Example #1
0
        /// <summary>
        /// Sets the value as raw bytes, with no validation that enough data is specified for the given value type.
        /// </summary>
        /// <param name="data">The data to store</param>
        /// <param name="offset">The offset within <c>data</c> of the first byte to store</param>
        /// <param name="count">The number of bytes to store</param>
        /// <param name="valueType">The type of the data</param>
        public void SetData(byte[] data, int offset, int count, RegistryValueType valueType)
        {
            // If we can place the data in the DataIndex field, do that to save space / allocation
            if ((valueType == RegistryValueType.Dword || valueType == RegistryValueType.DwordBigEndian) && count <= 4)
            {
                if (_cell.DataLength >= 0)
                {
                    _hive.FreeCell(_cell.DataIndex);
                }

                _cell.DataLength = (int)((uint)count | 0x80000000);
                _cell.DataIndex  = Utilities.ToInt32LittleEndian(data, offset);
                _cell.DataType   = valueType;
            }
            else
            {
                if (_cell.DataIndex == -1 || _cell.DataLength < 0)
                {
                    _cell.DataIndex = _hive.AllocateRawCell(count);
                }

                if (!_hive.WriteRawCellData(_cell.DataIndex, data, offset, count))
                {
                    int newDataIndex = _hive.AllocateRawCell(count);
                    _hive.WriteRawCellData(newDataIndex, data, offset, count);
                    _hive.FreeCell(_cell.DataIndex);
                    _cell.DataIndex = newDataIndex;
                }

                _cell.DataLength = count;
                _cell.DataType   = valueType;
            }

            _hive.UpdateCell(_cell, false);
        }
Example #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 = Utilities.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 = Utilities.ToInt32LittleEndian(valueList, (i + 1) * 4);
                        Utilities.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, "name");
            }
        }