Home > Software design >  Windows, add user by Rust
Windows, add user by Rust

Time:12-20

I use winapi NetUserAdd to add a user,account added succsess,execute command net user,shows as below picture and cannot find users by control panel.

enter image description here

What wrong with LPSWTR or USER_INFO_1 struct to LPBYTE?


use winapi::um::lmaccess::{USER_INFO_1,NetUserAdd,UF_SCRIPT};
use std::iter::{once};
use std::os::windows::ffi::OsStrExt;
use std::ffi::OsStr;

pub fn winstr(value: &str) -> Vec<u16> {
    OsStr::new(value).encode_wide().chain(once(0)).collect()
}

fn main() {

        let username:String =  "Test".to_string();
        let password:String = "Test******".to_string();
        let mut user = USER_INFO_1{
            usri1_name:winstr(&username).as_mut_ptr(),
            usri1_password:winstr(&password).as_mut_ptr(),
            usri1_priv:1,
            usri1_password_age: 0,
            usri1_home_dir: std::ptr::null_mut(),
            usri1_comment: std::ptr::null_mut(),
            usri1_flags:UF_SCRIPT,
            usri1_script_path: std::ptr::null_mut(),
        };
        
        let mut error = 0 ;
        unsafe{
            NetUserAdd(std::ptr::null_mut(),1,&mut user as *mut _ as _,&mut error);
        }
        
        println!("{}",error);//result is 0,means success.

}

CodePudding user response:

You're sending dangling pointers.

Your winstr(...).as_mut_ptr() calls create a Vec<u16>, gets a pointer to its data, and drops the Vec<u16> since it was a temporary value. You need to keep those values at least until the call to NetUserAdd has finished:

let mut username = winstr("Test");
let mut password = winstr("Test******");
let mut user = USER_INFO_1{
    usri1_name: username.as_mut_ptr(),
    usri1_password: password.as_mut_ptr(),
    usri1_priv: 1,
    usri1_password_age: 0,
    usri1_home_dir: std::ptr::null_mut(),
    usri1_comment: std::ptr::null_mut(),
    usri1_flags: UF_SCRIPT,
    usri1_script_path: std::ptr::null_mut(),
};
  • Related