From e4f26ec2f09028a42593b59c27d763ddd4f2ee49 Mon Sep 17 00:00:00 2001 From: Yop Date: Tue, 9 Feb 2021 20:58:08 +0900 Subject: [PATCH] Initial commit --- .cargo/config | 5 ++ .gitignore | 2 + Cargo.lock | 162 ++++++++++++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 12 ++++ README.md | 18 ++++++ src/lib.rs | 72 ++++++++++++++++++++++ src/log.rs | 46 ++++++++++++++ 7 files changed, 317 insertions(+) create mode 100644 .cargo/config create mode 100644 .gitignore create mode 100644 Cargo.lock create mode 100644 Cargo.toml create mode 100644 README.md create mode 100644 src/lib.rs create mode 100644 src/log.rs diff --git a/.cargo/config b/.cargo/config new file mode 100644 index 0000000..17f9a19 --- /dev/null +++ b/.cargo/config @@ -0,0 +1,5 @@ +[build] +target = "x86_64-pc-windows-gnu" + +[target.x86_64-pc-windows-gnu] +linker = "x86_64-w64-mingw32-gcc" diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ee44a96 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +.idea +target diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..96cafd4 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,162 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "bitflags" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" + +[[package]] +name = "cc" +version = "1.0.66" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c0496836a84f8d0495758516b8621a622beb77c0fed418570e50764093ced48" + +[[package]] +name = "cfg-if" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" + +[[package]] +name = "detour" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "078595bac2ff1822ae53ae3ca1c1ffca97897ecc959adf0137152bfdc278d0d3" +dependencies = [ + "cfg-if", + "generic-array", + "lazy_static", + "libc", + "libudis86-sys", + "mmap-fixed", + "region", + "slice-pool", +] + +[[package]] +name = "generic-array" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ed1e761351b56f54eb9dcd0cfaca9fd0daecf93918e1cfc01c8a3d26ee7adcd" +dependencies = [ + "typenum", +] + +[[package]] +name = "hide-remote-desktop" +version = "0.1.0" +dependencies = [ + "detour", + "winapi 0.3.9", +] + +[[package]] +name = "kernel32-sys" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" +dependencies = [ + "winapi 0.2.8", + "winapi-build", +] + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "libc" +version = "0.2.86" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7282d924be3275cec7f6756ff4121987bc6481325397dde6ba3e7802b1a8b1c" + +[[package]] +name = "libudis86-sys" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "139bbf9ddb1bfc90c1ac64dd2923d9c957cd433cee7315c018125d72ab08a6b0" +dependencies = [ + "cc", + "libc", +] + +[[package]] +name = "mach" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b823e83b2affd8f40a9ee8c29dbc56404c1e34cd2710921f2801e2cf29527afa" +dependencies = [ + "libc", +] + +[[package]] +name = "mmap-fixed" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27c1ae264d6343d3b4079549f6bc9e6d074dc4106cb1324c7753c6ce11d07b21" +dependencies = [ + "kernel32-sys", + "libc", + "winapi 0.2.8", +] + +[[package]] +name = "region" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877e54ea2adcd70d80e9179344c97f93ef0dffd6b03e1f4529e6e83ab2fa9ae0" +dependencies = [ + "bitflags", + "libc", + "mach", + "winapi 0.3.9", +] + +[[package]] +name = "slice-pool" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "733fc6e5f1bd3a8136f842c9bdea4e5f17c910c2fcc98c90c3aa7604ef5e2e7a" + +[[package]] +name = "typenum" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "373c8a200f9e67a0c95e62a4f52fbf80c23b4381c05a17845531982fa99e6b33" + +[[package]] +name = "winapi" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-build" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..33dd339 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "hide-remote-desktop" +version = "0.1.0" +authors = ["qbx2 "] +edition = "2018" + +[lib] +crate-type = ["cdylib"] + +[dependencies] +detour = "0.7.1" +winapi = { version = "0.3.9", features = ["libloaderapi", "shlobj", "minwindef", "ntdef", "errhandlingapi", "winerror"] } diff --git a/README.md b/README.md new file mode 100644 index 0000000..3e7bc26 --- /dev/null +++ b/README.md @@ -0,0 +1,18 @@ +# HideRemoteDesktop SKSE Plugin for Skyrim SE +Removes "This application cannot be run from remote desktop." message. + +## Requirements +- Rust nightly compiler +- SKSE64 +- SkyrimSE + +## Build +``` +cargo build +``` + +## Cross Compilation? +``` +rustup target add x86_64-pc-windows-gnu +rustup toolchain install stable-x86_64-pc-windows-gnu +``` diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..e559b4e --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,72 @@ +mod log; + +use detour::static_detour; +use std::ffi::c_void; +use std::intrinsics::transmute; +use std::io::Write; +use std::os::raw::c_char; +use winapi::um::libloaderapi::{GetModuleHandleA, GetProcAddress}; +use crate::log::get_log; + +enum InfoVersion { + KInfoVersion = 1, +} + +#[repr(C)] +pub struct PluginInfo { + info_version: u32, + name: *const c_char, + version: u32, +} + +#[allow(non_snake_case)] +#[no_mangle] +pub extern fn SKSEPlugin_Query(_: *const c_void, info: *mut PluginInfo) -> bool { + let mut info = unsafe { &mut *info }; + info.info_version = InfoVersion::KInfoVersion as u32; + info.name = "hide-remote-desktop\0".as_ptr() as *const c_char; + info.version = 1; + return true; +} + +static_detour! { + static GetSystemMetrics: fn(i64) -> i64; +} + +fn new_get_system_metrics(n_index: i64) -> i64 { + // is remote desktop? no ;) + let result = if n_index == 0x1000 { + 0 + } else { + GetSystemMetrics.call(n_index) + }; + + get_log().write_all( + format!("GetSystemMetrics({:#x}) -> {}", n_index, result).as_bytes(), + ).ok(); + return result; +} + +#[allow(non_snake_case)] +#[no_mangle] +pub unsafe fn SKSEPlugin_Load(_: *const c_void) -> bool { + let log = log::get_log(); + + let result: Result> = (|| { + let user32 = GetModuleHandleA("User32.dll\0".as_ptr() as *const c_char); + GetSystemMetrics.initialize( + transmute(GetProcAddress(user32, "GetSystemMetrics\0".as_ptr() as *const c_char)), + new_get_system_metrics, + )?; + GetSystemMetrics.enable()?; + + Ok(true) + })(); + + if let Err(err) = result { + log.write_all(format!("error SKSEPlugin_Load: {}\n", err).as_bytes()).unwrap(); + return false; + } + + return true; +} diff --git a/src/log.rs b/src/log.rs new file mode 100644 index 0000000..f7a7bc7 --- /dev/null +++ b/src/log.rs @@ -0,0 +1,46 @@ +use std::io::LineWriter; +use std::ffi::CStr; +use std::fs::File; +use winapi::shared::minwindef::MAX_PATH; +use winapi::shared::ntdef::NULL; +use winapi::shared::windef::HWND; +use winapi::shared::winerror::S_OK; +use winapi::um::errhandlingapi::GetLastError; +use winapi::um::shlobj::{CSIDL_MYDOCUMENTS, CSIDL_FLAG_CREATE, SHGFP_TYPE_CURRENT, SHGetFolderPathA}; + +const LOG_PATH: &str = "\\My Games\\Skyrim Special Edition\\SKSE\\hide-remote-desktop.log"; + +static mut LOG: Option> = None; + +pub(crate) unsafe fn open_log_file() -> Result, Box> { + let mut path = Vec::with_capacity(MAX_PATH); + let result = SHGetFolderPathA( + NULL as HWND, + CSIDL_MYDOCUMENTS | CSIDL_FLAG_CREATE, + NULL, + SHGFP_TYPE_CURRENT, + path.as_mut_ptr(), + ); + if result != S_OK { + return Err(std::io::Error::new( + std::io::ErrorKind::Other, + format!("failed to SHGetFolderPathA, ret = {}, err = {}", result, GetLastError()), + ).into()); + } + + let path = String::from(CStr::from_ptr(path.as_ptr()).to_str()?) + LOG_PATH; + + let file = File::create(&path)?; + Ok(LineWriter::new(file)) +} + +pub(crate) fn get_log() -> &'static mut LineWriter { + unsafe { + return if let Some(ref mut log) = LOG { + log + } else { + LOG = Some(open_log_file().unwrap()); + LOG.as_mut().unwrap() + } + } +}