Use Get/FreeEnvironmentStringsW instead of Get/FreeEnvironmentStringsA

Changed libstd to use Get/FreeEnvironmentStringsW instead of
Get/FreeEnvironmentStringsA to support Unicode environment variables.
This commit is contained in:
Phil Ruffwind 2014-05-04 21:14:55 -04:00
parent b6cce7ea54
commit d9eca56c06
2 changed files with 34 additions and 12 deletions

View File

@ -4195,7 +4195,7 @@ pub mod funcs {
use types::os::arch::c95::{c_uint};
use types::os::arch::extra::{BOOL, DWORD, SIZE_T, HMODULE,
LPCWSTR, LPWSTR,
LPCH, LPDWORD, LPVOID,
LPWCH, LPDWORD, LPVOID,
LPCVOID, LPOVERLAPPED,
LPSECURITY_ATTRIBUTES,
LPSTARTUPINFO,
@ -4212,8 +4212,8 @@ pub mod funcs {
-> DWORD;
pub fn SetEnvironmentVariableW(n: LPCWSTR, v: LPCWSTR)
-> BOOL;
pub fn GetEnvironmentStringsA() -> LPCH;
pub fn FreeEnvironmentStringsA(env_ptr: LPCH) -> BOOL;
pub fn GetEnvironmentStringsW() -> LPWCH;
pub fn FreeEnvironmentStringsW(env_ptr: LPWCH) -> BOOL;
pub fn GetModuleFileNameW(hModule: HMODULE,
lpFilename: LPWSTR,
nSize: DWORD)

View File

@ -31,7 +31,7 @@
use clone::Clone;
use container::Container;
use libc;
use libc::{c_char, c_void, c_int};
use libc::{c_void, c_int};
use option::{Some, None, Option};
use os;
use ops::Drop;
@ -49,6 +49,8 @@ use vec::Vec;
#[cfg(unix)]
use c_str::ToCStr;
#[cfg(unix)]
use libc::c_char;
#[cfg(windows)]
use str::OwnedStr;
@ -186,22 +188,42 @@ pub fn env_as_bytes() -> Vec<(~[u8],~[u8])> {
unsafe {
#[cfg(windows)]
unsafe fn get_env_pairs() -> Vec<~[u8]> {
use c_str;
use slice::raw;
use libc::funcs::extra::kernel32::{
GetEnvironmentStringsA,
FreeEnvironmentStringsA
GetEnvironmentStringsW,
FreeEnvironmentStringsW
};
let ch = GetEnvironmentStringsA();
let ch = GetEnvironmentStringsW();
if ch as uint == 0 {
fail!("os::env() failure getting env string from OS: {}",
os::last_os_error());
}
// Here, we lossily decode the string as UTF16.
//
// The docs suggest that the result should be in Unicode, but
// Windows doesn't guarantee it's actually UTF16 -- it doesn't
// validate the environment string passed to CreateProcess nor
// SetEnvironmentVariable. Yet, it's unlikely that returning a
// raw u16 buffer would be of practical use since the result would
// be inherently platform-dependent and introduce additional
// complexity to this code.
//
// Using the non-Unicode version of GetEnvironmentStrings is even
// worse since the result is in an OEM code page. Characters that
// can't be encoded in the code page would be turned into question
// marks.
let mut result = Vec::new();
c_str::from_c_multistring(ch as *c_char, None, |cstr| {
result.push(cstr.as_bytes_no_nul().to_owned());
});
FreeEnvironmentStringsA(ch);
let mut i = 0;
while *ch.offset(i) != 0 {
let p = &*ch.offset(i);
let len = ptr::position(p, |c| *c == 0);
raw::buf_as_slice(p, len, |s| {
result.push(str::from_utf16_lossy(s).into_bytes());
});
i += len as int + 1;
}
FreeEnvironmentStringsW(ch);
result
}
#[cfg(unix)]