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)); }
/// <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"); } }
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 = Utilities.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); }
internal RegistryValue(RegistryHive hive, ValueCell cell) { _hive = hive; _cell = cell; }