Use CreateProcessW instead of CreateProcessA
Changed libnative to use CreateProcessW instead of CreateProcessA. In addition, the lpEnvironment parameter now uses Unicode. Added a helper function os::win32::as_mut_utf16_p, which does basically the same thing as os::win32::as_utf16_p except the pointer is mutable.
This commit is contained in:
parent
4537f13a87
commit
e12aeb39bc
@ -208,7 +208,7 @@ pub use funcs::bsd43::{shutdown};
|
||||
#[cfg(windows)] pub use consts::os::extra::{TRUE, FALSE, INFINITE};
|
||||
#[cfg(windows)] pub use consts::os::extra::{PROCESS_TERMINATE, PROCESS_QUERY_INFORMATION};
|
||||
#[cfg(windows)] pub use consts::os::extra::{STILL_ACTIVE, DETACHED_PROCESS};
|
||||
#[cfg(windows)] pub use consts::os::extra::{CREATE_NEW_PROCESS_GROUP};
|
||||
#[cfg(windows)] pub use consts::os::extra::{CREATE_NEW_PROCESS_GROUP, CREATE_UNICODE_ENVIRONMENT};
|
||||
#[cfg(windows)] pub use consts::os::extra::{FILE_BEGIN, FILE_END, FILE_CURRENT};
|
||||
#[cfg(windows)] pub use consts::os::extra::{FILE_GENERIC_READ, FILE_GENERIC_WRITE};
|
||||
#[cfg(windows)] pub use consts::os::extra::{FILE_SHARE_READ, FILE_SHARE_WRITE, FILE_SHARE_DELETE};
|
||||
@ -1937,6 +1937,7 @@ pub mod consts {
|
||||
|
||||
pub static DETACHED_PROCESS: DWORD = 0x00000008;
|
||||
pub static CREATE_NEW_PROCESS_GROUP: DWORD = 0x00000200;
|
||||
pub static CREATE_UNICODE_ENVIRONMENT: DWORD = 0x00000400;
|
||||
|
||||
pub static PIPE_ACCESS_DUPLEX: DWORD = 0x00000003;
|
||||
pub static PIPE_ACCESS_INBOUND: DWORD = 0x00000001;
|
||||
@ -4193,7 +4194,7 @@ pub mod funcs {
|
||||
pub mod kernel32 {
|
||||
use types::os::arch::c95::{c_uint};
|
||||
use types::os::arch::extra::{BOOL, DWORD, SIZE_T, HMODULE,
|
||||
LPCWSTR, LPWSTR, LPCSTR, LPSTR,
|
||||
LPCWSTR, LPWSTR,
|
||||
LPCH, LPDWORD, LPVOID,
|
||||
LPCVOID, LPOVERLAPPED,
|
||||
LPSECURITY_ATTRIBUTES,
|
||||
@ -4251,8 +4252,8 @@ pub mod funcs {
|
||||
dwProcessId: DWORD)
|
||||
-> HANDLE;
|
||||
pub fn GetCurrentProcess() -> HANDLE;
|
||||
pub fn CreateProcessA(lpApplicationName: LPCSTR,
|
||||
lpCommandLine: LPSTR,
|
||||
pub fn CreateProcessW(lpApplicationName: LPCWSTR,
|
||||
lpCommandLine: LPWSTR,
|
||||
lpProcessAttributes:
|
||||
LPSECURITY_ATTRIBUTES,
|
||||
lpThreadAttributes:
|
||||
@ -4260,7 +4261,7 @@ pub mod funcs {
|
||||
bInheritHandles: BOOL,
|
||||
dwCreationFlags: DWORD,
|
||||
lpEnvironment: LPVOID,
|
||||
lpCurrentDirectory: LPCSTR,
|
||||
lpCurrentDirectory: LPCWSTR,
|
||||
lpStartupInfo: LPSTARTUPINFO,
|
||||
lpProcessInformation:
|
||||
LPPROCESS_INFORMATION)
|
||||
|
@ -258,7 +258,7 @@ fn spawn_process_os(config: p::ProcessConfig,
|
||||
GetCurrentProcess,
|
||||
DuplicateHandle,
|
||||
CloseHandle,
|
||||
CreateProcessA
|
||||
CreateProcessW
|
||||
};
|
||||
use libc::funcs::extra::msvcrt::get_osfhandle;
|
||||
|
||||
@ -318,15 +318,15 @@ fn spawn_process_os(config: p::ProcessConfig,
|
||||
let mut create_err = None;
|
||||
|
||||
// stolen from the libuv code.
|
||||
let mut flags = 0;
|
||||
let mut flags = libc::CREATE_UNICODE_ENVIRONMENT;
|
||||
if config.detach {
|
||||
flags |= libc::DETACHED_PROCESS | libc::CREATE_NEW_PROCESS_GROUP;
|
||||
}
|
||||
|
||||
with_envp(env, |envp| {
|
||||
with_dirp(dir, |dirp| {
|
||||
cmd.with_c_str(|cmdp| {
|
||||
let created = CreateProcessA(ptr::null(), mem::transmute(cmdp),
|
||||
os::win32::as_mut_utf16_p(cmd, |cmdp| {
|
||||
let created = CreateProcessW(ptr::null(), cmdp,
|
||||
ptr::mut_null(), ptr::mut_null(), TRUE,
|
||||
flags, envp, dirp, &mut si,
|
||||
&mut pi);
|
||||
@ -691,7 +691,7 @@ fn with_envp<T>(env: Option<~[(~str, ~str)]>, cb: |*mut c_void| -> T) -> T {
|
||||
|
||||
for pair in env.iter() {
|
||||
let kv = format!("{}={}", *pair.ref0(), *pair.ref1());
|
||||
blk.push_all(kv.as_bytes());
|
||||
blk.push_all(kv.to_utf16().as_slice());
|
||||
blk.push(0);
|
||||
}
|
||||
|
||||
@ -704,9 +704,12 @@ fn with_envp<T>(env: Option<~[(~str, ~str)]>, cb: |*mut c_void| -> T) -> T {
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
fn with_dirp<T>(d: Option<&Path>, cb: |*libc::c_char| -> T) -> T {
|
||||
fn with_dirp<T>(d: Option<&Path>, cb: |*u16| -> T) -> T {
|
||||
match d {
|
||||
Some(dir) => dir.with_c_str(|buf| cb(buf)),
|
||||
Some(dir) => match dir.as_str() {
|
||||
Some(dir_str) => os::win32::as_utf16_p(dir_str, cb),
|
||||
None => cb(ptr::null())
|
||||
},
|
||||
None => cb(ptr::null())
|
||||
}
|
||||
}
|
||||
|
@ -141,10 +141,14 @@ pub mod win32 {
|
||||
}
|
||||
|
||||
pub fn as_utf16_p<T>(s: &str, f: |*u16| -> T) -> T {
|
||||
as_mut_utf16_p(s, |t| { f(t as *u16) })
|
||||
}
|
||||
|
||||
pub fn as_mut_utf16_p<T>(s: &str, f: |*mut u16| -> T) -> T {
|
||||
let mut t = s.to_utf16();
|
||||
// Null terminate before passing on.
|
||||
t.push(0u16);
|
||||
f(t.as_ptr())
|
||||
f(t.as_mut_ptr())
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user