Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
qbx2 committed Feb 9, 2021
0 parents commit e4f26ec
Show file tree
Hide file tree
Showing 7 changed files with 317 additions and 0 deletions.
5 changes: 5 additions & 0 deletions .cargo/config
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[build]
target = "x86_64-pc-windows-gnu"

[target.x86_64-pc-windows-gnu]
linker = "x86_64-w64-mingw32-gcc"
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
.idea
target
162 changes: 162 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 12 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
[package]
name = "hide-remote-desktop"
version = "0.1.0"
authors = ["qbx2 <[email protected]>"]
edition = "2018"

[lib]
crate-type = ["cdylib"]

[dependencies]
detour = "0.7.1"
winapi = { version = "0.3.9", features = ["libloaderapi", "shlobj", "minwindef", "ntdef", "errhandlingapi", "winerror"] }
18 changes: 18 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -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
```
72 changes: 72 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -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<bool, Box<dyn std::error::Error>> = (|| {
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;
}
46 changes: 46 additions & 0 deletions src/log.rs
Original file line number Diff line number Diff line change
@@ -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<LineWriter<File>> = None;

pub(crate) unsafe fn open_log_file() -> Result<LineWriter<File>, Box<dyn std::error::Error>> {
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<File> {
unsafe {
return if let Some(ref mut log) = LOG {
log
} else {
LOG = Some(open_log_file().unwrap());
LOG.as_mut().unwrap()
}
}
}

0 comments on commit e4f26ec

Please sign in to comment.