Skip to content

Commit

Permalink
#166: Fix registry restoration
Browse files Browse the repository at this point in the history
  • Loading branch information
mtkennerly committed Dec 21, 2022
1 parent 28bb874 commit 284c0a9
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 27 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
## Unreleased

* Fixed:
* Native registry saves on Windows were not restored.
* When switching between dropdowns, they would briefly flicker with incorrect content.
* Game titles starting with a lowercase letter were listed after all titles starting with an uppercase letter.
* When using the folder picker for roots and custom game files, glob special characters were not escaped.
Expand Down
21 changes: 11 additions & 10 deletions src/layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -894,7 +894,7 @@ impl GameLayout {
#[cfg(target_os = "windows")]
{
use crate::registry::Hives;
let hives = Hives::from(&scan.found_registry_keys);
let hives = Hives::incorporated(&scan.found_registry_keys);
if !hives.is_empty() {
registry.hash = Some(crate::prelude::sha1(hives.serialize()));
}
Expand Down Expand Up @@ -932,7 +932,7 @@ impl GameLayout {
#[cfg(target_os = "windows")]
{
use crate::registry::Hives;
let hives = Hives::from(&scan.found_registry_keys);
let hives = Hives::incorporated(&scan.found_registry_keys);
if !hives.is_empty() {
registry = Some(IndividualMappingRegistry {
hash: Some(crate::prelude::sha1(hives.serialize())),
Expand Down Expand Up @@ -1005,7 +1005,7 @@ impl GameLayout {
let target_registry_file = self.registry_file_in(backup.name());

if backup.includes_registry() {
let hives = Hives::from(&scan.found_registry_keys);
let hives = Hives::incorporated(&scan.found_registry_keys);
hives.save(&target_registry_file);
} else {
let _ = target_registry_file.remove();
Expand Down Expand Up @@ -1156,7 +1156,7 @@ impl GameLayout {
use crate::registry::Hives;

if backup.includes_registry() {
let hives = Hives::from(&scan.found_registry_keys);
let hives = Hives::incorporated(&scan.found_registry_keys);
if zip.start_file("registry.yaml", options).is_ok() {
let _ = zip.write_all(hives.serialize().as_bytes());
}
Expand Down Expand Up @@ -1299,12 +1299,13 @@ impl GameLayout {
{
use crate::registry::Hives;

let mut hives = Hives::default();
let (found, _) = hives.incorporate(&scan.found_registry_keys);

if found {
// TODO: Track failed keys.
let _ = hives.restore();
if let Some(backup) = scan.backup.as_ref() {
if let Some(registry_content) = self.registry_content(&backup.id()) {
if let Some(hives) = Hives::deserialize(&registry_content) {
// TODO: Track failed keys.
let _ = hives.restore();
}
}
}
}

Expand Down
27 changes: 10 additions & 17 deletions src/registry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use std::collections::HashSet;

use crate::{
config::{BackupFilter, ToggledRegistry},
prelude::{Error, RegistryItem, ScanChange, ScanInfo, ScannedRegistry, StrictPath},
prelude::{Error, RegistryItem, ScanChange, ScannedRegistry, StrictPath},
};
use winreg::types::{FromRegValue, ToRegValue};

Expand Down Expand Up @@ -154,6 +154,9 @@ impl Hives {
serde_yaml::from_str(content).ok()
}

/// This only incorporates the keys, not the values.
/// It can be used during backup since we know the keys exist, so we can look up the values when needed.
/// It should not be used during restore since the keys may not exist.
pub fn incorporate(&mut self, scan: &HashSet<ScannedRegistry>) -> (bool, HashSet<RegistryItem>) {
let mut failed = HashSet::new();
let mut found = false;
Expand All @@ -176,6 +179,12 @@ impl Hives {
(found, failed)
}

pub fn incorporated(scan: &HashSet<ScannedRegistry>) -> Self {
let mut hives = Hives::default();
hives.incorporate(scan);
hives
}

pub fn store_key_from_full_path(&mut self, path: &str) -> Result<(), Error> {
let path = RegistryItem::new(path.to_string()).interpreted();

Expand Down Expand Up @@ -265,22 +274,6 @@ impl Hives {
}
}

impl From<&HashSet<ScannedRegistry>> for Hives {
fn from(source: &HashSet<ScannedRegistry>) -> Self {
let mut hives = Self::default();
hives.incorporate(source);
hives
}
}

impl From<&ScanInfo> for Hives {
fn from(scan: &ScanInfo) -> Self {
let mut hives = Self::default();
hives.incorporate(&scan.found_registry_keys);
hives
}
}

impl Entry {
pub fn is_set(&self) -> bool {
self.sz.is_some()
Expand Down

0 comments on commit 284c0a9

Please sign in to comment.