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
        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));
        }