OsString and OsStr bridge this gap by simultaneously representing Rust and platform-native string values, and in particular allowing a Rust string to be converted into an “OS” string with no cost if possible. A consequence of this is that OsString instances are not NUL terminated; in order to pass to e.g., Unix system call, you should create a CStr.
However, winreg produces strings that have a NULL terminator:
use std::io;
use std::ffi::OsString;
use winreg::enums::*;
use winreg::RegKey;
fn main() -> io::Result<()> {
println!("Reading some system info...");
let hklm = RegKey::predef(HKEY_LOCAL_MACHINE);
let cur_ver = hklm.open_subkey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion")?;
let pf: OsString = cur_ver.get_value("ProgramFilesDir")?;
println!("Program files dir");
use std::os::windows::ffi::OsStrExt;
for c in pf.encode_wide() {
print!(" {:02x}", c);
}
println!();
Ok(())
}
Running this produces:
❯ cargo run
Compiling winreg-test v0.1.0 (C:\Users\smcro\Code\Ion\winreg-test)
Finished dev [unoptimized + debuginfo] target(s) in 0.45s
Running `target\debug\winreg-test.exe`
Reading some system info...
Program files dir
43 3a 5c 50 72 6f 67 72 61 6d 20 46 69 6c 65 73 00
❯
According to https://doc.rust-lang.org/std/ffi/struct.OsString.html,
OsString
objects should not be NULL terminated:However,
winreg
produces strings that have a NULL terminator:Running this produces: