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