windows: basic support for GetUserProfileDirectoryW
This commit is contained in:
parent
26faaa3047
commit
342943bc77
5 changed files with 114 additions and 2 deletions
|
|
@ -299,6 +299,27 @@ dependencies = [
|
|||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "directories"
|
||||
version = "5.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9a49173b84e034382284f27f1af4dcbbd231ffa358c0fe316541a7337f376a35"
|
||||
dependencies = [
|
||||
"dirs-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dirs-sys"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"option-ext",
|
||||
"redox_users",
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "encode_unicode"
|
||||
version = "0.3.6"
|
||||
|
|
@ -490,6 +511,16 @@ dependencies = [
|
|||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libredox"
|
||||
version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d"
|
||||
dependencies = [
|
||||
"bitflags 2.4.2",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "linux-raw-sys"
|
||||
version = "0.4.13"
|
||||
|
|
@ -558,6 +589,7 @@ dependencies = [
|
|||
"chrono",
|
||||
"colored",
|
||||
"ctrlc",
|
||||
"directories",
|
||||
"getrandom",
|
||||
"jemalloc-sys",
|
||||
"lazy_static",
|
||||
|
|
@ -614,6 +646,12 @@ version = "1.19.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
|
||||
|
||||
[[package]]
|
||||
name = "option-ext"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d"
|
||||
|
||||
[[package]]
|
||||
name = "owo-colors"
|
||||
version = "3.5.0"
|
||||
|
|
@ -746,6 +784,17 @@ dependencies = [
|
|||
"bitflags 1.3.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_users"
|
||||
version = "0.4.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bd283d9651eeda4b2a83a43c1c91b266c40fd76ecd39a50a8c630ae69dc72891"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
"libredox",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.10.3"
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ aes = { version = "0.8.3", features = ["hazmat"] }
|
|||
measureme = "11"
|
||||
ctrlc = "3.2.5"
|
||||
chrono = { version = "0.4.38", default-features = false, features = ["clock"] }
|
||||
directories = "5"
|
||||
|
||||
# Copied from `compiler/rustc/Cargo.toml`.
|
||||
# But only for some targets, it fails for others. Rustc configures this in its CI, but we can't
|
||||
|
|
|
|||
|
|
@ -494,9 +494,65 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
|||
fn GetCurrentProcessId(&mut self) -> InterpResult<'tcx, u32> {
|
||||
let this = self.eval_context_mut();
|
||||
this.assert_target_os("windows", "GetCurrentProcessId");
|
||||
|
||||
this.check_no_isolation("`GetCurrentProcessId`")?;
|
||||
|
||||
Ok(std::process::id())
|
||||
}
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
fn GetUserProfileDirectoryW(
|
||||
&mut self,
|
||||
token: &OpTy<'tcx, Provenance>, // HANDLE
|
||||
buf: &OpTy<'tcx, Provenance>, // LPWSTR
|
||||
size: &OpTy<'tcx, Provenance>, // LPDWORD
|
||||
) -> InterpResult<'tcx, Scalar<Provenance>> // returns BOOL
|
||||
{
|
||||
let this = self.eval_context_mut();
|
||||
this.assert_target_os("windows", "GetUserProfileDirectoryW");
|
||||
this.check_no_isolation("`GetUserProfileDirectoryW`")?;
|
||||
|
||||
let token = this.read_target_isize(token)?;
|
||||
let buf = this.read_pointer(buf)?;
|
||||
let size = this.deref_pointer(size)?;
|
||||
|
||||
if token != -4 {
|
||||
throw_unsup_format!(
|
||||
"GetUserProfileDirectoryW: only CURRENT_PROCESS_TOKEN is supported"
|
||||
);
|
||||
}
|
||||
|
||||
// See <https://learn.microsoft.com/en-us/windows/win32/api/userenv/nf-userenv-getuserprofiledirectoryw> for docs.
|
||||
Ok(match directories::UserDirs::new() {
|
||||
Some(dirs) => {
|
||||
let home = dirs.home_dir();
|
||||
let size_avail = if this.ptr_is_null(size.ptr())? {
|
||||
0 // if the buf pointer is null, we can't write to it; `size` will be updated to the required length
|
||||
} else {
|
||||
this.read_scalar(&size)?.to_u32()?
|
||||
};
|
||||
// Of course we cannot use `windows_check_buffer_size` here since this uses
|
||||
// a different method for dealing with a too-small buffer than the other functions...
|
||||
let (success, len) = this.write_path_to_wide_str(
|
||||
home,
|
||||
buf,
|
||||
size_avail.into(),
|
||||
/*truncate*/ false,
|
||||
)?;
|
||||
// The Windows docs just say that this is written on failure. But std
|
||||
// seems to rely on it always being written.
|
||||
this.write_scalar(Scalar::from_u32(len.try_into().unwrap()), &size)?;
|
||||
if success {
|
||||
Scalar::from_i32(1) // return TRUE
|
||||
} else {
|
||||
this.set_last_error(this.eval_windows("c", "ERROR_INSUFFICIENT_BUFFER"))?;
|
||||
Scalar::from_i32(0) // return FALSE
|
||||
}
|
||||
}
|
||||
None => {
|
||||
// We have to pick some error code.
|
||||
this.set_last_error(this.eval_windows("c", "ERROR_BAD_USER_PROFILE"))?;
|
||||
Scalar::from_i32(0) // return FALSE
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -135,6 +135,12 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
|||
let result = this.SetCurrentDirectoryW(path)?;
|
||||
this.write_scalar(result, dest)?;
|
||||
}
|
||||
"GetUserProfileDirectoryW" => {
|
||||
let [token, buf, size] =
|
||||
this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
|
||||
let result = this.GetUserProfileDirectoryW(token, buf, size)?;
|
||||
this.write_scalar(result, dest)?;
|
||||
}
|
||||
|
||||
// File related shims
|
||||
"NtWriteFile" => {
|
||||
|
|
|
|||
2
src/tools/miri/tests/pass/shims/env/home.rs
vendored
2
src/tools/miri/tests/pass/shims/env/home.rs
vendored
|
|
@ -1,9 +1,9 @@
|
|||
//@ignore-target-windows: home_dir is not supported on Windows
|
||||
//@compile-flags: -Zmiri-disable-isolation
|
||||
use std::env;
|
||||
|
||||
fn main() {
|
||||
env::remove_var("HOME"); // make sure we enter the interesting codepath
|
||||
env::remove_var("USERPROFILE"); // Windows also looks as this env var
|
||||
#[allow(deprecated)]
|
||||
env::home_dir().unwrap();
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue