// Метод загружает базу private bool LoadBase() { // Попытка открытия файла try { FS = new FileStream(BasesSubdirectory + "\\" + baseName + BaseFileExtension, FileMode.Open); } catch { return(false); } SR = new StreamReader(FS, baseFileEncoding); // Чтение файла SR.ReadLine(); // Версия while (!SR.EndOfStream) { string s = SR.ReadLine(); string[] values = s.Split(baseFileSplitters); // Пустые поля не удалять, т.к. они отвечают за значения по умолчанию if (values.Length != 6) { continue; // Если вдруг попадётся битая запись, пропустить её } RegistryValueTypes valueType = RegistryValueTypes.REG_SZ; try { valueType = (RegistryValueTypes)uint.Parse(values[3]); } catch { } RegistryEntry re = new RegistryEntry(values[0], values[1], values[2], valueType, values[4] != "0", values[5] != "0"); if (!re.IsValid) { continue; // Аналогично } // В противном случае добавляем запись entries.Add(re); } // Завершено SR.Close(); FS.Close(); return(true); }
// Метод-инициализатор экземпляра класса private void CreateRegistryEntry(string Path, string Name, string Value, RegistryValueTypes Type, bool DeletePath, bool DeleteName) { // Переменные char[] pathSplitters = new char[] { '\\' }; char[] valuesSplitters = new char[] { '\"', '[', ']' }; // Контроль пути string[] values = Path.Split(valuesSplitters, StringSplitOptions.RemoveEmptyEntries); if (values.Length != 1) // Означает наличие недопустимых символов или пустую строку { return; } pathMustBeDeleted = (values[0].Substring(0, 1) == "-"); // Раздел помечен на удаление string s = values[0]; if (pathMustBeDeleted) { s = values[0].Substring(1); } pathMustBeDeleted |= DeletePath; values = s.Split(pathSplitters, StringSplitOptions.RemoveEmptyEntries); // Убираем лишние слэшы if (values.Length < 1) // Такого не должно случиться, но вдруг там только слэшы и были { return; } if (values[0] == Registry.ClassesRoot.Name) { valueMasterKey = Registry.ClassesRoot; } /*else if (values[0] == Registry.CurrentConfig.Name) * valueMasterKey = Registry.CurrentConfig; * else if (values[0] == Registry.CurrentUser.Name) * valueMasterKey = Registry.CurrentUser; * else if (values[0] == Registry.LocalMachine.Name) * valueMasterKey = Registry.LocalMachine; * else if (values[0] == Registry.Users.Name) * valueMasterKey = Registry.Users;*/// Остальные разделы запрещены областью применения программы else { return; // Если корневой раздел не является допустимым } // Пересобираем путь valuePath = values[0]; for (int i = 1; i < values.Length; i++) { valuePath += (pathSplitters[0].ToString() + values[i]); } // Если путь помечен на удаление, остальные параметры можно (и нужно) проигнорировать if (pathMustBeDeleted) { isValid = true; return; } // Контроль имени values = Name.Split(valuesSplitters, StringSplitOptions.RemoveEmptyEntries); if (values.Length == 0) // Пустая строка здесь допустима - для значения по умолчанию { valueName = ""; } else if (values.Length > 1) { return; // Означает наличие недопустимых символов или пустую строку } else { valueName = values[0]; } if (valueName.Contains(pathSplitters[0].ToString())) { return; } if (valueName == "@") { valueName = ""; } // Контроль значения (может содержать любые символы; предполагается, что кавычки уже удалены) if ((Value == "-") || DeleteName) // Параметр помечен на удаление { nameMustBeDeleted = isValid = true; valueObject = "-"; return; } // Проверка на наличие спецификации типа if (Value.StartsWith("hex:")) { valueType = RegistryValueTypes.REG_BINARY; } if (Value.StartsWith("dword:")) { valueType = RegistryValueTypes.REG_DWORD; } if (Value.StartsWith("hex(2):")) { valueType = RegistryValueTypes.REG_EXPAND_SZ; } if (Value.StartsWith("hex(7):")) { valueType = RegistryValueTypes.REG_MULTI_SZ; } if (Value.StartsWith("hex(0):")) { valueType = RegistryValueTypes.REG_NONE; } if (Value.StartsWith("hex(b):")) { valueType = RegistryValueTypes.REG_QWORD; } // Обработка значения в зависимости от типа данных switch (valueType) { case RegistryValueTypes.REG_SZ: valueObject = Value; break; case RegistryValueTypes.REG_DWORD: try { valueObject = (Int32.Parse(Value.Substring(6), NumberStyles.HexNumber)).ToString(); } catch { return; } break; case RegistryValueTypes.REG_QWORD: try { Int64 a = Int64.Parse(Value.Substring(7).Replace(",", ""), NumberStyles.HexNumber); a = (ExcludeByte(a, 0) << 56) | (ExcludeByte(a, 1) << 48) | (ExcludeByte(a, 2) << 40) | (ExcludeByte(a, 3) << 32) | (ExcludeByte(a, 4) << 24) | (ExcludeByte(a, 5) << 16) | (ExcludeByte(a, 6) << 8) | ExcludeByte(a, 7); valueObject = a.ToString(); } catch { return; } break; default: return; // Остальные типы мы пока обрабатывать не умеем } // Переопределение, если указано (делается позже остального, чтобы не вынуждать значения, // пропущенные через базу, обрабатываться снова) if (Type != RegistryValueTypes.REG_SZ) { // Установка типа valueType = Type; switch (valueType) { case RegistryValueTypes.REG_BINARY: valueTypeAsKind = RegistryValueKind.Binary; break; case RegistryValueTypes.REG_DWORD: valueTypeAsKind = RegistryValueKind.DWord; break; case RegistryValueTypes.REG_EXPAND_SZ: valueTypeAsKind = RegistryValueKind.ExpandString; break; case RegistryValueTypes.REG_MULTI_SZ: valueTypeAsKind = RegistryValueKind.MultiString; break; case RegistryValueTypes.REG_NONE: valueTypeAsKind = RegistryValueKind.None; break; case RegistryValueTypes.REG_QWORD: valueTypeAsKind = RegistryValueKind.QWord; break; } // Постконтроль значения (запрет на подстановку не-чисел в числовые типы) try { if (valueType == RegistryValueTypes.REG_QWORD) { Int64 a = Int64.Parse(valueObject); } if (valueType == RegistryValueTypes.REG_DWORD) { Int32 b = Int32.Parse(valueObject); } } catch { return; } } // Завершено isValid = true; }
/// <summary> /// Конструктор. Создаёт запись реестра Windows /// </summary> /// <param name="Path">Путь к разделу</param> /// <param name="Name">Название параметра</param> /// <param name="Value">Значение параметра (без внешних кавычек)</param> /// <param name="DeleteName">Флаг, указывающий на необходимость удаления указанного параметра реестра; /// при значении true принудительно задаёт признак '-' в параметре Value</param> /// <param name="DeletePath">Флаг, указывающий на необходимость удаления указанного раздела реестра; /// при значении true принудительно задаёт признак '-' в параметре Path</param> /// <param name="Type">Тип значения параметра реестра; при значении, не равном REG_SZ, принудительно /// задаёт тип в обход спецификации в параметре Value</param> public RegistryEntry(string Path, string Name, string Value, RegistryValueTypes Type, bool DeletePath, bool DeleteName) { CreateRegistryEntry(Path, Name, Value, Type, DeletePath, DeleteName); }