GetUserProfileDirectoryW is now documented to always store the size

This commit is contained in:
Ralf Jung 2025-05-22 20:07:16 +02:00
parent e88e854634
commit 587653a2fc
2 changed files with 3 additions and 5 deletions

View File

@ -202,8 +202,6 @@ fn home_dir_crt() -> Option<PathBuf> {
|buf, mut sz| {
// GetUserProfileDirectoryW does not quite use the usual protocol for
// negotiating the buffer size, so we have to translate.
// FIXME(#141254): We rely on the *undocumented* property that this function will
// always set the size, not just on failure.
match c::GetUserProfileDirectoryW(
ptr::without_provenance_mut(CURRENT_PROCESS_TOKEN),
buf,

View File

@ -230,7 +230,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
interp_ok(match directories::UserDirs::new() {
Some(dirs) => {
let home = dirs.home_dir();
let size_avail = if this.ptr_is_null(size.ptr())? {
let size_avail = if this.ptr_is_null(buf)? {
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()?
@ -238,8 +238,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
// 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())?;
// The Windows docs just say that this is written on failure, but std relies on it
// always being written. Also see <https://github.com/rust-lang/rust/issues/141254>.
// As per <https://github.com/MicrosoftDocs/sdk-api/pull/1810>, the size is always
// written, not just on failure.
this.write_scalar(Scalar::from_u32(len.try_into().unwrap()), &size)?;
if success {
Scalar::from_i32(1) // return TRUE