From 96e5e03e89e346fb1273fec5b711a26be5061833 Mon Sep 17 00:00:00 2001 From: Putta Khunchalee Date: Tue, 10 Dec 2024 00:51:14 +0700 Subject: [PATCH 1/3] Implements read_data_root for Windows --- gui/Cargo.toml | 1 + gui/main.cpp | 5 +- gui/main_window.cpp | 37 +------------- gui/main_window.hpp | 12 +---- gui/src/setup/windows.rs | 101 ++++++++++++++++++++++++++++++++++++++- 5 files changed, 103 insertions(+), 53 deletions(-) diff --git a/gui/Cargo.toml b/gui/Cargo.toml index 5d14ae16b..136d2d94b 100644 --- a/gui/Cargo.toml +++ b/gui/Cargo.toml @@ -60,6 +60,7 @@ features = [ "Win32_System", "Win32_System_Hypervisor", "Win32_System_Memory", + "Win32_System_Registry", "Win32_System_SystemInformation", ] diff --git a/gui/main.cpp b/gui/main.cpp index 578a53b93..2f4d2ef30 100644 --- a/gui/main.cpp +++ b/gui/main.cpp @@ -27,11 +27,8 @@ int main(int argc, char *argv[]) QGuiApplication::setWindowIcon(QIcon(":/resources/obliteration-icon.png")); - // Parse arguments. - QCommandLineParser args; - // Setup main window. - MainWindow win(args); + MainWindow win; // Run main window. return QApplication::exec(); diff --git a/gui/main_window.cpp b/gui/main_window.cpp index 8a5f11c67..557ba7aca 100644 --- a/gui/main_window.cpp +++ b/gui/main_window.cpp @@ -25,13 +25,7 @@ #include #endif -namespace Args { - const QCommandLineOption debug("debug", "Immediate launch the VMM in debug mode.", "addr", "127.0.0.1:1234"); - const QCommandLineOption kernel("kernel", "Use this kernel instead of default one.", "path"); -} - -MainWindow::MainWindow(const QCommandLineParser &args) : - m_args(args), +MainWindow::MainWindow() : m_main(nullptr) { // File menu. @@ -83,17 +77,6 @@ void MainWindow::aboutObliteration() "working in the future."); } -void MainWindow::vmmError(const QString &msg) -{ - QMessageBox::critical(this, "Error", msg); - - if (m_args.isSet(Args::debug)) { - close(); - } else { - m_main->setCurrentIndex(0); - } -} - void MainWindow::waitKernelExit(bool success) { if (!success) { @@ -105,21 +88,3 @@ void MainWindow::waitKernelExit(bool success) m_main->setCurrentIndex(0); } - -void MainWindow::stopDebug() -{ - // We can't free the VMM here because the thread that trigger this method are waiting - // for us to return. - if (m_args.isSet(Args::debug)) { - QMetaObject::invokeMethod( - this, - &MainWindow::close, - Qt::QueuedConnection); - } else { - QMetaObject::invokeMethod( - this, - &MainWindow::waitKernelExit, - Qt::QueuedConnection, - true); - } -} diff --git a/gui/main_window.hpp b/gui/main_window.hpp index d7e98e138..5daaadff0 100644 --- a/gui/main_window.hpp +++ b/gui/main_window.hpp @@ -3,27 +3,17 @@ #include #include -class QCommandLineOption; -class QCommandLineParser; class QStackedWidget; class MainWindow final : public QMainWindow { public: - MainWindow(const QCommandLineParser &args); + MainWindow(); ~MainWindow() override; private slots: void reportIssue(); void aboutObliteration(); private: - void vmmError(const QString &msg); void waitKernelExit(bool success); - void stopDebug(); - const QCommandLineParser &m_args; QStackedWidget *m_main; }; - -namespace Args { - extern const QCommandLineOption debug; - extern const QCommandLineOption kernel; -} diff --git a/gui/src/setup/windows.rs b/gui/src/setup/windows.rs index 9798822be..fe9a4941e 100644 --- a/gui/src/setup/windows.rs +++ b/gui/src/setup/windows.rs @@ -1,13 +1,110 @@ +use std::ptr::{null, null_mut}; use thiserror::Error; +use windows_sys::w; +use windows_sys::Win32::Foundation::{ERROR_FILE_NOT_FOUND, ERROR_SUCCESS}; +use windows_sys::Win32::System::Registry::{ + RegCloseKey, RegCreateKeyExW, RegQueryValueExW, HKEY, HKEY_CURRENT_USER, KEY_ALL_ACCESS, + REG_OPTION_NON_VOLATILE, REG_SZ, +}; pub fn read_data_root() -> Result, DataRootError> { - todo!() + // Open our registry key. + let mut key = null_mut(); + let e = unsafe { + RegCreateKeyExW( + HKEY_CURRENT_USER, + w!("Software\\OBHQ\\Obliteration"), + 0, + null(), + REG_OPTION_NON_VOLATILE, + KEY_ALL_ACCESS, + null(), + &mut key, + null_mut(), + ) + }; + + if e != ERROR_SUCCESS { + let k = "HKEY_CURRENT_USER\\Software\\OBHQ\\Obliteration"; + let e = std::io::Error::from_raw_os_error(e.try_into().unwrap()); + + return Err(DataRootError::CreateRegKey(k, e)); + } + + // Get data size. + let fqvn = "HKEY_CURRENT_USER\\Software\\OBHQ\\Obliteration\\DataRoot"; + let key = Key(key); + let name = w!("DataRoot"); + let mut ty = 0; + let mut len = 0; + let e = unsafe { RegQueryValueExW(key.0, name, null(), &mut ty, null_mut(), &mut len) }; + + if e == ERROR_FILE_NOT_FOUND { + return Ok(None); + } else if e != ERROR_SUCCESS { + let e = std::io::Error::from_raw_os_error(e.try_into().unwrap()); + + return Err(DataRootError::QueryRegKey(fqvn, e)); + } else if ty != REG_SZ { + return Err(DataRootError::InvalidRegValue(fqvn)); + } + + // Read data. + let mut buf = vec![0u16; (len / 2).try_into().unwrap()]; + let e = unsafe { + RegQueryValueExW( + key.0, + name, + null(), + &mut ty, + buf.as_mut_ptr().cast(), + &mut len, + ) + }; + + if e != ERROR_SUCCESS { + let e = std::io::Error::from_raw_os_error(e.try_into().unwrap()); + + return Err(DataRootError::QueryRegKey(fqvn, e)); + } else if ty != REG_SZ { + return Err(DataRootError::InvalidRegValue(fqvn)); + } + + // Remove null-terminators if any. + buf.truncate((len / 2).try_into().unwrap()); + + while buf.last().is_some_and(|&v| v == 0) { + buf.pop(); + } + + // Convert to Rust string. + String::from_utf16(&buf) + .map_err(|_| DataRootError::InvalidRegValue(fqvn)) + .map(Some) } pub fn write_data_root(path: impl AsRef) -> Result<(), DataRootError> { todo!() } +/// RAII struct to close `HKEY` when dropped. +struct Key(HKEY); + +impl Drop for Key { + fn drop(&mut self) { + assert_eq!(unsafe { RegCloseKey(self.0) }, ERROR_SUCCESS); + } +} + /// Represents an error when read or write data root fails. #[derive(Debug, Error)] -pub enum DataRootError {} +pub enum DataRootError { + #[error("couldn't create {0}")] + CreateRegKey(&'static str, #[source] std::io::Error), + + #[error("couldn't read {0}")] + QueryRegKey(&'static str, #[source] std::io::Error), + + #[error("{0} has invalid value")] + InvalidRegValue(&'static str), +} From 3193ee550f2b91d6115add740c00a242e7be2855 Mon Sep 17 00:00:00 2001 From: Putta Khunchalee Date: Tue, 10 Dec 2024 01:03:22 +0700 Subject: [PATCH 2/3] Upgrades windows-sys --- Cargo.lock | 2 +- gui/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 02a6e4fe8..20ec92d0c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1593,7 +1593,7 @@ dependencies = [ "slint-build", "thiserror 2.0.3", "uuid", - "windows-sys 0.52.0", + "windows-sys 0.59.0", "winres", "x86-64", "xdg", diff --git a/gui/Cargo.toml b/gui/Cargo.toml index 136d2d94b..3434a6d7a 100644 --- a/gui/Cargo.toml +++ b/gui/Cargo.toml @@ -53,7 +53,7 @@ features = ["linked", "std"] default-features = false [target.'cfg(windows)'.dependencies.windows-sys] -version = "0.52.0" +version = "0.59.0" features = [ "Win32", "Win32_Foundation", From 342910096b33334198019b40e73015cd078b7fd8 Mon Sep 17 00:00:00 2001 From: Putta Khunchalee Date: Tue, 10 Dec 2024 01:11:34 +0700 Subject: [PATCH 3/3] Enables Win32_Security --- gui/Cargo.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/gui/Cargo.toml b/gui/Cargo.toml index 3434a6d7a..45d1a0572 100644 --- a/gui/Cargo.toml +++ b/gui/Cargo.toml @@ -57,6 +57,7 @@ version = "0.59.0" features = [ "Win32", "Win32_Foundation", + "Win32_Security", "Win32_System", "Win32_System_Hypervisor", "Win32_System_Memory",