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