So I am trying to convet this piece of C# code to Rust.
private bool CreateAnonymousPipeEveryoneAccess(ref IntPtr hReadPipe, ref IntPtr hWritePipe)
{
SECURITY_ATTRIBUTES sa = new SECURITY_ATTRIBUTES();
sa.Length = Marshal.SizeOf(sa);
sa.lpSecurityDescriptor = IntPtr.Zero;
sa.bInheritHandle = true;
if (CreatePipe(out hReadPipe, out hWritePipe, ref sa, (uint)BUFFER_SIZE_PIPE))
return true;
return false;
}
private void RunasSetupStdHandlesForProcess(ref STARTUPINFO startupInfo, out IntPtr hOutputWrite, out IntPtr hErrorWrite, out IntPtr hOutputRead) {
IntPtr hOutputReadTmpLocal = IntPtr.Zero;
IntPtr hOutputWriteLocal = IntPtr.Zero;
IntPtr hErrorWriteLocal = IntPtr.Zero;
IntPtr hOutputReadLocal = IntPtr.Zero;
IntPtr socketLocal = IntPtr.Zero;
IntPtr hCurrentProcess = Process.GetCurrentProcess().Handle;
if (!CreateAnonymousPipeEveryoneAccess(ref hOutputReadTmpLocal, ref hOutputWriteLocal))
throw new RunasCsException("CreatePipe", true);
if (!DuplicateHandle(hCurrentProcess, hOutputWriteLocal, hCurrentProcess, out hErrorWriteLocal, 0, true, DUPLICATE_SAME_ACCESS))
throw new RunasCsException("DuplicateHandle stderr write pipe", true);
if (!DuplicateHandle(hCurrentProcess, hOutputReadTmpLocal, hCurrentProcess, out hOutputReadLocal, 0, false, DUPLICATE_SAME_ACCESS))
throw new RunasCsException("DuplicateHandle stdout read pipe", true);
CloseHandle(hOutputReadTmpLocal);
hOutputReadTmpLocal = IntPtr.Zero;
UInt32 PIPE_NOWAIT = 0x00000001;
if (!SetNamedPipeHandleState(hOutputReadLocal, ref PIPE_NOWAIT, IntPtr.Zero, IntPtr.Zero))
throw new RunasCsException("SetNamedPipeHandleState", true);
startupInfo.dwFlags = Startf_UseStdHandles;
startupInfo.hStdOutput = hOutputWriteLocal;
startupInfo.hStdError = hErrorWriteLocal;
hOutputWrite = hOutputWriteLocal;
hErrorWrite = hErrorWriteLocal;
hOutputRead = hOutputReadLocal;
}
I presume the Process.GetCurrentProcess().Handle
returns the Windows handler for the process.
I do know that std::process::id
do have the function id
to return the handler id of current process, so I came up with h_current_process = HANDLE(id() as isize);
.
All in all:
fn create_anonymous_pipe_everyone_access(h_read_pipe: *const u32, h_write_pipe: *const u32) -> bool {
const SA: SECURITY_ATTRIBUTES = SECURITY_ATTRIBUTES{
nLength: size_of::<SECURITY_ATTRIBUTES>() as u32,
lpSecurityDescriptor: ptr::null_mut(),
bInheritHandle: BOOL(1),
};
unsafe {
const BUFFER_SIZE_PIPE: u32 = 1048576;
return CreatePipe(&mut HANDLE(h_read_pipe as isize), &mut HANDLE(h_write_pipe as isize),
Some(&SA), BUFFER_SIZE_PIPE).as_bool();
}
}
fn runas_setup_std_handles_for_process(mut startup_info: STARTUPINFOW, mut h_output_write: *const u32, mut h_error_write: *const u32, mut h_output_read: *const u32) {
let h_output_read_tmp_local0: u32 = 0;
let h_output_read_tmp_local: *const u32 = &h_output_read_tmp_local0;
let h_output_write_local0: u32 = 0;
let h_output_write_local: *const u32 = &h_output_write_local0;
let h_error_write_local0: u32 = 0;
let h_error_write_local: *const u32 = &h_error_write_local0;
let h_output_read_local0: u32 = 0;
let h_output_read_local: *const u32 = &h_output_read_local0;
let mut h_current_process = HANDLE(id() as isize);
println!("Currrent process: {}", id());
if create_anonymous_pipe_everyone_access(h_output_read_tmp_local, h_output_write_local) {
println!("Error Create pipe")
}
unsafe {
if !DuplicateHandle(h_current_process, HANDLE(h_output_write_local as isize),
h_current_process, &mut HANDLE(h_error_write_local as isize),
0, true, DUPLICATE_SAME_ACCESS).as_bool() {
println!("Error DuplicateHandle stderr write pipe")
}
if !DuplicateHandle(h_current_process, HANDLE(h_output_read_tmp_local as isize),
h_current_process, &mut HANDLE(h_output_read_local as isize),
0, true, DUPLICATE_SAME_ACCESS).as_bool() {
println!("Error DuplicateHandle stdout read pipe")
}
CloseHandle(HANDLE(h_output_read_tmp_local as isize));
const LPMODE: NAMED_PIPE_MODE = PIPE_NOWAIT;
if !SetNamedPipeHandleState(HANDLE(h_output_read_local as isize), Some(&LPMODE), None, None ).as_bool(){
println!("Error SetNamedPipeHandleState")
}
}
startup_info.dwFlags = STARTF_USESTDHANDLES;
startup_info.hStdOutput = HANDLE(h_output_write_local as isize);
startup_info.hStdError = HANDLE(h_error_write_local as isize);
h_output_write = h_error_write_local;
h_error_write = h_error_write_local;
h_output_read = h_output_read_local;
}
Problem is mine failed in every state possible, even the reate_anonymous_pipe_everyone_access
return false, i.e. failed. Not compilation failed, but every error got printed out.
Can anyone have a look at it and what did I do wrong? Thank you.
Also, is there anyway to shorten:
let h_output_read_tmp_local0: u32 = 0;
let h_output_read_tmp_local: *const u32 = &h_output_read_tmp_local0;
to something one liner (if I did not do anything wrong at that part)?
Thank you.