/// <summary> /// Creates or opens a subkey. /// </summary> /// <param name="subkey">The relative path the the subkey.</param> /// <returns>The subkey.</returns> public RegistryKey CreateSubKey(string subkey) { if (string.IsNullOrEmpty(subkey)) { return(this); } string[] split = subkey.Split(new[] { '\\' }, 2); int cellIndex = FindSubKeyCell(split[0]); if (cellIndex < 0) { KeyNodeCell newKeyCell = new KeyNodeCell(split[0], _cell.Index); newKeyCell.SecurityIndex = _cell.SecurityIndex; ReferenceSecurityCell(newKeyCell.SecurityIndex); _hive.UpdateCell(newKeyCell, true); LinkSubKey(split[0], newKeyCell.Index); if (split.Length == 1) { return(new RegistryKey(_hive, newKeyCell)); } return(new RegistryKey(_hive, newKeyCell).CreateSubKey(split[1])); } KeyNodeCell cell = _hive.GetCell <KeyNodeCell>(cellIndex); if (split.Length == 1) { return(new RegistryKey(_hive, cell)); } return(new RegistryKey(_hive, cell).CreateSubKey(split[1])); }
/// <summary> /// Opens a sub key. /// </summary> /// <param name="path">The relative path to the sub key.</param> /// <returns>The sub key, or <c>null</c> if not found.</returns> public RegistryKey OpenSubKey(string path) { if (string.IsNullOrEmpty(path)) { return(this); } string[] split = path.Split(new char[] { '\\' }, 2); int cellIndex = FindSubKeyCell(split[0]); if (cellIndex < 0) { return(null); } else { KeyNodeCell cell = _hive.GetCell <KeyNodeCell>(cellIndex); if (split.Length == 1) { return(new RegistryKey(_hive, cell)); } else { return(new RegistryKey(_hive, cell).OpenSubKey(split[1])); } } }
/// <summary> /// Finds a subkey cell, returning it's index in this list. /// </summary> /// <param name="name">The name of the key to find.</param> /// <returns>The index of the found key, or <c>-1</c>.</returns> internal int IndexOf(string name) { foreach (var index in Find(name, 0)) { KeyNodeCell cell = _hive.GetCell <KeyNodeCell>(_subKeyIndexes[index]); if (cell.Name.ToUpperInvariant() == name.ToUpperInvariant()) { return(index); } } return(-1); }
public int Compare(int x, int y) { // TODO: Be more efficient at ruling out no-hopes by using the hash values KeyNodeCell cell = _hive.GetCell <KeyNodeCell>(x); int result = string.Compare(((KeyNodeCell)cell).Name, _searchName, StringComparison.OrdinalIgnoreCase); if (result == 0) { CellIndex = x; } return(result); }
/// <summary> /// Adds a new entry. /// </summary> /// <param name="name">The name of the subkey.</param> /// <param name="cellIndex">The cell index of the subkey.</param> /// <returns>The index of the new entry.</returns> internal int Add(string name, int cellIndex) { for (int i = 0; i < _numElements; ++i) { KeyNodeCell cell = _hive.GetCell <KeyNodeCell>(_subKeyIndexes[i]); if (string.Compare(cell.Name, name, StringComparison.OrdinalIgnoreCase) > 0) { _subKeyIndexes.Insert(i, cellIndex); _nameHashes.Insert(i, CalcHash(name)); _numElements++; return(i); } } _subKeyIndexes.Add(cellIndex); _nameHashes.Add(CalcHash(name)); return(_numElements++); }
private void FreeValues(KeyNodeCell cell) { if (cell.NumValues != 0 && cell.ValueListIndex != -1) { byte[] valueList = _hive.RawCellData(cell.ValueListIndex, cell.NumValues * 4); for (int i = 0; i < cell.NumValues; ++i) { int valueIndex = EndianUtilities.ToInt32LittleEndian(valueList, i * 4); _hive.FreeCell(valueIndex); } _hive.FreeCell(cell.ValueListIndex); cell.ValueListIndex = -1; cell.NumValues = 0; cell.MaxValDataBytes = 0; cell.MaxValNameBytes = 0; } }
internal override int UnlinkSubKey(string name) { if (ListType == "ri") { if (_listIndexes.Count == 0) { throw new NotImplementedException("Empty indirect list"); } for (int i = 0; i < _listIndexes.Count; ++i) { int tempIndex; ListCell cell = _hive.GetCell <ListCell>(_listIndexes[i]); if (cell.FindKey(name, out tempIndex) <= 0) { _listIndexes[i] = cell.UnlinkSubKey(name); if (cell.Count == 0) { _hive.FreeCell(_listIndexes[i]); _listIndexes.RemoveAt(i); } return(_hive.UpdateCell(this, false)); } } } else { for (int i = 0; i < _listIndexes.Count; ++i) { KeyNodeCell cell = _hive.GetCell <KeyNodeCell>(_listIndexes[i]); if (string.Compare(name, cell.Name, StringComparison.OrdinalIgnoreCase) == 0) { _listIndexes.RemoveAt(i); return(_hive.UpdateCell(this, true)); } } } return(Index); }
internal override int LinkSubKey(string name, int cellIndex) { // Look for the first sublist that has a subkey name greater than name if (ListType == "ri") { if (_listIndexes.Count == 0) { throw new NotImplementedException("Empty indirect list"); } for (int i = 0; i < _listIndexes.Count - 1; ++i) { int tempIndex; ListCell cell = _hive.GetCell <ListCell>(_listIndexes[i]); if (cell.FindKey(name, out tempIndex) <= 0) { _listIndexes[i] = cell.LinkSubKey(name, cellIndex); return(_hive.UpdateCell(this, false)); } } ListCell lastCell = _hive.GetCell <ListCell>(_listIndexes[_listIndexes.Count - 1]); _listIndexes[_listIndexes.Count - 1] = lastCell.LinkSubKey(name, cellIndex); return(_hive.UpdateCell(this, false)); } else { for (int i = 0; i < _listIndexes.Count; ++i) { KeyNodeCell cell = _hive.GetCell <KeyNodeCell>(_listIndexes[i]); if (string.Compare(name, cell.Name, StringComparison.OrdinalIgnoreCase) < 0) { _listIndexes.Insert(i, cellIndex); return(_hive.UpdateCell(this, true)); } } _listIndexes.Add(cellIndex); return(_hive.UpdateCell(this, true)); } }
private void FreeSubKeys(KeyNodeCell subkeyCell) { if (subkeyCell.SubKeysIndex == -1) { throw new InvalidOperationException("No subkey list"); } Cell list = _hive.GetCell <Cell>(subkeyCell.SubKeysIndex); SubKeyIndirectListCell indirectList = list as SubKeyIndirectListCell; if (indirectList != null) { ////foreach (int listIndex in indirectList.CellIndexes) for (int i = 0; i < indirectList.CellIndexes.Count; ++i) { int listIndex = indirectList.CellIndexes[i]; _hive.FreeCell(listIndex); } } _hive.FreeCell(list.Index); }
internal static Cell Parse(RegistryHive hive, int index, byte[] buffer, int pos) { string type = Utilities.BytesToString(buffer, pos, 2); Cell result = null; switch (type) { case "nk": result = new KeyNodeCell(index); break; case "sk": result = new SecurityCell(index); break; case "vk": result = new ValueCell(index); break; case "lh": case "lf": result = new SubKeyHashedListCell(hive, index); break; case "li": case "ri": result = new SubKeyIndirectListCell(hive, index); break; default: throw new RegistryCorruptException("Unknown cell type '" + type + "'"); } result.ReadFrom(buffer, pos); return(result); }
/// <summary> /// Creates a new (empty) registry hive. /// </summary> /// <param name="stream">The stream to contain the new hive.</param> /// <param name="ownership">Whether the returned object owns the stream.</param> /// <returns>The new hive.</returns> public static RegistryHive Create(Stream stream, Ownership ownership) { if (stream == null) { throw new ArgumentNullException(nameof(stream), "Attempt to create registry hive in null stream"); } // Construct a file with minimal structure - hive header, plus one (empty) bin BinHeader binHeader = new BinHeader(); binHeader.FileOffset = 0; binHeader.BinSize = (int)(4 * Sizes.OneKiB); HiveHeader hiveHeader = new HiveHeader(); hiveHeader.Length = binHeader.BinSize; stream.Position = 0; byte[] buffer = new byte[hiveHeader.Size]; hiveHeader.WriteTo(buffer, 0); stream.Write(buffer, 0, buffer.Length); buffer = new byte[binHeader.Size]; binHeader.WriteTo(buffer, 0); stream.Position = BinStart; stream.Write(buffer, 0, buffer.Length); buffer = new byte[4]; EndianUtilities.WriteBytesLittleEndian(binHeader.BinSize - binHeader.Size, buffer, 0); stream.Write(buffer, 0, buffer.Length); // Make sure the file is initialized out to the end of the firs bin stream.Position = BinStart + binHeader.BinSize - 1; stream.WriteByte(0); // Temporary hive to perform construction of higher-level structures RegistryHive newHive = new RegistryHive(stream); KeyNodeCell rootCell = new KeyNodeCell("root", -1); rootCell.Flags = RegistryKeyFlags.Normal | RegistryKeyFlags.Root; newHive.UpdateCell(rootCell, true); RegistrySecurity sd = new RegistrySecurity(); sd.SetSecurityDescriptorSddlForm("O:BAG:BAD:PAI(A;;KA;;;SY)(A;CI;KA;;;BA)", AccessControlSections.All); SecurityCell secCell = new SecurityCell(sd); newHive.UpdateCell(secCell, true); secCell.NextIndex = secCell.Index; secCell.PreviousIndex = secCell.Index; newHive.UpdateCell(secCell, false); rootCell.SecurityIndex = secCell.Index; newHive.UpdateCell(rootCell, false); // Ref the root cell from the hive header hiveHeader.RootCell = rootCell.Index; buffer = new byte[hiveHeader.Size]; hiveHeader.WriteTo(buffer, 0); stream.Position = 0; stream.Write(buffer, 0, buffer.Length); // Finally, return the new hive return(new RegistryHive(stream, ownership)); }
internal RegistryKey(RegistryHive hive, KeyNodeCell cell) { _hive = hive; _cell = cell; }
/// <summary> /// Deletes the specified subkey. The string subkey is not case-sensitive. /// </summary> /// <param name="subkey">The subkey to delete.</param> /// <param name="throwOnMissingSubKey"><c>true</c> to throw an argument exception if <c>subkey</c> doesn't exist.</param> public void DeleteSubKey(string subkey, bool throwOnMissingSubKey) { if (string.IsNullOrEmpty(subkey)) { throw new ArgumentException("Invalid SubKey", nameof(subkey)); } string[] split = subkey.Split(new[] { '\\' }, 2); int subkeyCellIndex = FindSubKeyCell(split[0]); if (subkeyCellIndex < 0) { if (throwOnMissingSubKey) { throw new ArgumentException("No such SubKey", nameof(subkey)); } return; } KeyNodeCell subkeyCell = _hive.GetCell <KeyNodeCell>(subkeyCellIndex); if (split.Length == 1) { if (subkeyCell.NumSubKeys != 0) { throw new InvalidOperationException("The registry key has subkeys"); } if (subkeyCell.ClassNameIndex != -1) { _hive.FreeCell(subkeyCell.ClassNameIndex); subkeyCell.ClassNameIndex = -1; subkeyCell.ClassNameLength = 0; } if (subkeyCell.SecurityIndex != -1) { DereferenceSecurityCell(subkeyCell.SecurityIndex); subkeyCell.SecurityIndex = -1; } if (subkeyCell.SubKeysIndex != -1) { FreeSubKeys(subkeyCell); } if (subkeyCell.ValueListIndex != -1) { FreeValues(subkeyCell); } UnlinkSubKey(subkey); _hive.FreeCell(subkeyCellIndex); _hive.UpdateCell(_cell, false); } else { new RegistryKey(_hive, subkeyCell).DeleteSubKey(split[1], throwOnMissingSubKey); } }
private void FreeSubKeys(KeyNodeCell subkeyCell) { if (subkeyCell.SubKeysIndex == -1) { throw new InvalidOperationException("No subkey list"); } Cell list = _hive.GetCell<Cell>(subkeyCell.SubKeysIndex); SubKeyIndirectListCell indirectList = list as SubKeyIndirectListCell; if (indirectList != null) { //foreach (int listIndex in indirectList.CellIndexes) for (int i = 0; i < indirectList.CellIndexes.Count; ++i) { int listIndex = indirectList.CellIndexes[i]; _hive.FreeCell(listIndex); } } _hive.FreeCell(list.Index); }
private void FreeValues(KeyNodeCell cell) { if (cell.NumValues != 0 && cell.ValueListIndex != -1) { byte[] valueList = _hive.RawCellData(cell.ValueListIndex, cell.NumValues * 4); for (int i = 0; i < cell.NumValues; ++i) { int valueIndex = Utilities.ToInt32LittleEndian(valueList, i * 4); _hive.FreeCell(valueIndex); } _hive.FreeCell(cell.ValueListIndex); cell.ValueListIndex = -1; cell.NumValues = 0; cell.MaxValDataBytes = 0; cell.MaxValNameBytes = 0; } }
/// <summary> /// Creates or opens a subkey. /// </summary> /// <param name="subkey">The relative path the the subkey</param> /// <returns>The subkey</returns> public RegistryKey CreateSubKey(string subkey) { if (string.IsNullOrEmpty(subkey)) { return this; } string[] split = subkey.Split(new char[] { '\\' }, 2); int cellIndex = FindSubKeyCell(split[0]); if (cellIndex < 0) { KeyNodeCell newKeyCell = new KeyNodeCell(split[0], _cell.Index); newKeyCell.SecurityIndex = _cell.SecurityIndex; ReferenceSecurityCell(newKeyCell.SecurityIndex); _hive.UpdateCell(newKeyCell, true); LinkSubKey(split[0], newKeyCell.Index); if (split.Length == 1) { return new RegistryKey(_hive, newKeyCell); } else { return new RegistryKey(_hive, newKeyCell).CreateSubKey(split[1]); } } else { KeyNodeCell cell = _hive.GetCell<KeyNodeCell>(cellIndex); if (split.Length == 1) { return new RegistryKey(_hive, cell); } else { return new RegistryKey(_hive, cell).CreateSubKey(split[1]); } } }