From ee5a18167c4f8dd1d701b06c18285eb311cc87bf Mon Sep 17 00:00:00 2001 From: nibon7 Date: Fri, 5 Jan 2024 01:17:19 +0800 Subject: [PATCH] Replace `winapi` with `windows` (#11481) # Description `winapi` is not actively maintained, use the Microsoft blessed `windows` crate instead. # User-Facing Changes N/A --- Cargo.lock | 2 +- crates/nu-system/Cargo.toml | 44 ++--- crates/nu-system/src/windows.rs | 337 +++++++++++++++++--------------- 3 files changed, 191 insertions(+), 192 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 328c14e1a4..43732e9b47 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3061,7 +3061,7 @@ dependencies = [ "once_cell", "procfs", "sysinfo", - "winapi", + "windows 0.52.0", ] [[package]] diff --git a/crates/nu-system/Cargo.toml b/crates/nu-system/Cargo.toml index 336020c8e1..75f1240197 100644 --- a/crates/nu-system/Cargo.toml +++ b/crates/nu-system/Cargo.toml @@ -31,33 +31,17 @@ mach2 = "0.4" chrono = { version = "0.4", default-features = false } ntapi = "0.4" once_cell = "1.18" -winapi = { version = "0.3", features = [ - "tlhelp32", - "fileapi", - "handleapi", - "ifdef", - "ioapiset", - "minwindef", - "pdh", - "psapi", - "synchapi", - "sysinfoapi", - "winbase", - "winerror", - "winioctl", - "winnt", - "oleauto", - "wbemcli", - "rpcdce", - "combaseapi", - "objidl", - "powerbase", - "netioapi", - "lmcons", - "lmaccess", - "lmapibuf", - "memoryapi", - "shellapi", - "std", - "securitybaseapi", - ] } +windows = { version = "0.52", features = [ + "Wdk_System_SystemServices", + "Wdk_System_Threading", + "Win32_Foundation", + "Win32_Security", + "Win32_System_Diagnostics_Debug", + "Win32_System_Diagnostics_ToolHelp", + "Win32_System_Kernel", + "Win32_System_Memory", + "Win32_System_ProcessStatus", + "Win32_System_SystemInformation", + "Win32_System_Threading", + "Win32_UI_Shell", +]} diff --git a/crates/nu-system/src/windows.rs b/crates/nu-system/src/windows.rs index d3ec7fca15..c29afff6b1 100644 --- a/crates/nu-system/src/windows.rs +++ b/crates/nu-system/src/windows.rs @@ -4,13 +4,10 @@ use chrono::offset::TimeZone; use chrono::{Local, NaiveDate}; use libc::c_void; -use ntapi::ntpebteb::PEB; -use ntapi::ntpsapi::{ - NtQueryInformationProcess, ProcessBasicInformation, ProcessCommandLineInformation, - ProcessWow64Information, PROCESSINFOCLASS, PROCESS_BASIC_INFORMATION, -}; -use ntapi::ntrtl::{RtlGetVersion, PRTL_USER_PROCESS_PARAMETERS, RTL_USER_PROCESS_PARAMETERS}; -use ntapi::ntwow64::{PEB32, PRTL_USER_PROCESS_PARAMETERS32, RTL_USER_PROCESS_PARAMETERS32}; + +use ntapi::ntrtl::RTL_USER_PROCESS_PARAMETERS; +use ntapi::ntwow64::{PEB32, RTL_USER_PROCESS_PARAMETERS32}; + use once_cell::sync::Lazy; use std::cell::RefCell; use std::collections::HashMap; @@ -22,33 +19,48 @@ use std::ptr; use std::ptr::null_mut; use std::thread; use std::time::{Duration, Instant}; -use winapi::shared::basetsd::SIZE_T; -use winapi::shared::minwindef::{DWORD, FALSE, FILETIME, LPVOID, MAX_PATH, TRUE, ULONG}; -use winapi::shared::ntdef::{NT_SUCCESS, UNICODE_STRING}; -use winapi::shared::ntstatus::{ - STATUS_BUFFER_OVERFLOW, STATUS_BUFFER_TOO_SMALL, STATUS_INFO_LENGTH_MISMATCH, + +use windows::core::{PCWSTR, PWSTR}; + +use windows::Wdk::System::SystemServices::RtlGetVersion; +use windows::Wdk::System::Threading::{ + NtQueryInformationProcess, ProcessBasicInformation, ProcessCommandLineInformation, + ProcessWow64Information, PROCESSINFOCLASS, }; -use winapi::um::handleapi::CloseHandle; -use winapi::um::memoryapi::{ReadProcessMemory, VirtualQueryEx}; -use winapi::um::processthreadsapi::{ - GetCurrentProcess, GetPriorityClass, GetProcessTimes, OpenProcess, OpenProcessToken, + +use windows::Win32::Foundation::{ + CloseHandle, LocalFree, FALSE, FILETIME, HANDLE, HLOCAL, HMODULE, MAX_PATH, PSID, + STATUS_BUFFER_OVERFLOW, STATUS_BUFFER_TOO_SMALL, STATUS_INFO_LENGTH_MISMATCH, UNICODE_STRING, }; -use winapi::um::psapi::{ + +use windows::Win32::Security::{ + AdjustTokenPrivileges, GetTokenInformation, LookupAccountSidW, LookupPrivilegeValueW, + TokenGroups, TokenUser, SE_DEBUG_NAME, SE_PRIVILEGE_ENABLED, SID, SID_NAME_USE, + TOKEN_ADJUST_PRIVILEGES, TOKEN_GROUPS, TOKEN_PRIVILEGES, TOKEN_QUERY, TOKEN_USER, +}; + +use windows::Win32::System::Diagnostics::Debug::ReadProcessMemory; +use windows::Win32::System::Diagnostics::ToolHelp::{ + CreateToolhelp32Snapshot, Process32First, Process32Next, PROCESSENTRY32, TH32CS_SNAPPROCESS, +}; + +use windows::Win32::System::Memory::{VirtualQueryEx, MEMORY_BASIC_INFORMATION}; + +use windows::Win32::System::ProcessStatus::{ GetModuleBaseNameW, GetProcessMemoryInfo, K32EnumProcesses, PROCESS_MEMORY_COUNTERS, PROCESS_MEMORY_COUNTERS_EX, }; -use winapi::um::securitybaseapi::{AdjustTokenPrivileges, GetTokenInformation}; -use winapi::um::tlhelp32::{ - CreateToolhelp32Snapshot, Process32First, Process32Next, PROCESSENTRY32, TH32CS_SNAPPROCESS, -}; -use winapi::um::winbase::{GetProcessIoCounters, LookupAccountSidW, LookupPrivilegeValueW}; -use winapi::um::winnt::{ - TokenGroups, TokenUser, HANDLE, IO_COUNTERS, MEMORY_BASIC_INFORMATION, - PROCESS_QUERY_INFORMATION, PROCESS_VM_READ, PSID, RTL_OSVERSIONINFOEXW, SE_DEBUG_NAME, - SE_PRIVILEGE_ENABLED, SID, TOKEN_ADJUST_PRIVILEGES, TOKEN_GROUPS, TOKEN_PRIVILEGES, - TOKEN_QUERY, TOKEN_USER, + +use windows::Win32::System::SystemInformation::OSVERSIONINFOEXW; + +use windows::Win32::System::Threading::{ + GetCurrentProcess, GetPriorityClass, GetProcessIoCounters, GetProcessTimes, OpenProcess, + OpenProcessToken, IO_COUNTERS, PEB, PROCESS_BASIC_INFORMATION, PROCESS_QUERY_INFORMATION, + PROCESS_VM_READ, }; +use windows::Win32::UI::Shell::CommandLineToArgvW; + pub struct ProcessInfo { pub pid: i32, pub command: String, @@ -235,7 +247,7 @@ pub fn collect_proc(interval: Duration, _with_thread: bool) -> Vec } unsafe { - CloseHandle(handle); + let _ = CloseHandle(handle); } } } @@ -249,32 +261,20 @@ fn set_privilege() -> bool { let handle = GetCurrentProcess(); let mut token: HANDLE = zeroed(); let ret = OpenProcessToken(handle, TOKEN_ADJUST_PRIVILEGES, &mut token); - if ret == 0 { + if ret.is_err() { return false; } let mut tps: TOKEN_PRIVILEGES = zeroed(); - let se_debug_name: Vec = format!("{}\0", SE_DEBUG_NAME).encode_utf16().collect(); tps.PrivilegeCount = 1; - let ret = LookupPrivilegeValueW( - ptr::null(), - se_debug_name.as_ptr(), - &mut tps.Privileges[0].Luid, - ); - if ret == 0 { + if LookupPrivilegeValueW(PCWSTR::null(), SE_DEBUG_NAME, &mut tps.Privileges[0].Luid) + .is_err() + { return false; } tps.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; - let ret = AdjustTokenPrivileges( - token, - FALSE, - &mut tps, - 0, - ptr::null::() as *mut TOKEN_PRIVILEGES, - ptr::null::() as *mut u32, - ); - if ret == 0 { + if AdjustTokenPrivileges(token, FALSE, Some(&tps), 0, None, None).is_err() { return false; } @@ -284,21 +284,21 @@ fn set_privilege() -> bool { #[cfg_attr(tarpaulin, skip)] fn get_pids() -> Vec { - let dword_size = size_of::(); - let mut pids: Vec = Vec::with_capacity(10192); + let dword_size = size_of::(); + let mut pids: Vec = Vec::with_capacity(10192); let mut cb_needed = 0; unsafe { pids.set_len(10192); let result = K32EnumProcesses( pids.as_mut_ptr(), - (dword_size * pids.len()) as DWORD, + (dword_size * pids.len()) as u32, &mut cb_needed, ); - if result == 0 { + if !result.as_bool() { return Vec::new(); } - let pids_len = cb_needed / dword_size as DWORD; + let pids_len = cb_needed / dword_size as u32; pids.set_len(pids_len as usize); } @@ -311,18 +311,20 @@ fn get_ppid_threads() -> (HashMap, HashMap) { let mut threads = HashMap::new(); unsafe { - let snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); + let Ok(snapshot) = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0) else { + return (ppids, threads); + }; let mut entry: PROCESSENTRY32 = zeroed(); entry.dwSize = size_of::() as u32; let mut not_the_end = Process32First(snapshot, &mut entry); - while not_the_end != 0 { + while not_the_end.is_ok() { ppids.insert(entry.th32ProcessID as i32, entry.th32ParentProcessID as i32); threads.insert(entry.th32ProcessID as i32, entry.cntThreads as i32); not_the_end = Process32Next(snapshot, &mut entry); } - CloseHandle(snapshot); + let _ = CloseHandle(snapshot); } (ppids, threads) @@ -338,14 +340,14 @@ fn get_handle(pid: i32) -> Option { OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, - pid as DWORD, + pid as u32, ) - }; + } + .ok(); - if handle.is_null() { - None - } else { - Some(handle) + match handle { + Some(h) if h.is_invalid() => None, + h => h, } } @@ -370,7 +372,7 @@ fn get_times(handle: HANDLE) -> Option<(u64, u64, u64, u64)> { let sys = u64::from(sys.dwHighDateTime) << 32 | u64::from(sys.dwLowDateTime); let user = u64::from(user.dwHighDateTime) << 32 | u64::from(user.dwLowDateTime); - if ret != 0 { + if ret.is_ok() { Some((start, exit, sys, user)) } else { None @@ -386,10 +388,10 @@ fn get_memory_info(handle: HANDLE) -> Option { handle, &mut pmc as *mut PROCESS_MEMORY_COUNTERS_EX as *mut c_void as *mut PROCESS_MEMORY_COUNTERS, - size_of::() as DWORD, + size_of::() as u32, ); - if ret != 0 { + if ret.is_ok() { let info = MemoryInfo { page_fault_count: u64::from(pmc.PageFaultCount), peak_working_set_size: pmc.PeakWorkingSetSize as u64, @@ -412,15 +414,10 @@ fn get_memory_info(handle: HANDLE) -> Option { #[cfg_attr(tarpaulin, skip)] fn get_command(handle: HANDLE) -> Option { unsafe { - let mut exe_buf = [0u16; MAX_PATH + 1]; - let h_mod = std::ptr::null_mut(); + let mut exe_buf = [0u16; MAX_PATH as usize + 1]; + let h_mod = HMODULE::default(); - let ret = GetModuleBaseNameW( - handle, - h_mod as _, - exe_buf.as_mut_ptr(), - MAX_PATH as DWORD + 1, - ); + let ret = GetModuleBaseNameW(handle, h_mod, exe_buf.as_mut_slice()); let mut pos = 0; for x in exe_buf.iter() { @@ -460,7 +457,7 @@ macro_rules! impl_RtlUserProcessParameters { fn get_environ(&self, handle: HANDLE) -> Result, &'static str> { let ptr = self.Environment; unsafe { - let size = get_region_size(handle, ptr as LPVOID)?; + let size = get_region_size(handle, ptr as _)?; get_process_data(handle, ptr as _, size as _) } } @@ -483,30 +480,41 @@ unsafe fn null_terminated_wchar_to_string(slice: &[u16]) -> String { #[allow(clippy::uninit_vec)] unsafe fn get_process_data( handle: HANDLE, - ptr: LPVOID, + ptr: *const c_void, size: usize, ) -> Result, &'static str> { let mut buffer: Vec = Vec::with_capacity(size / 2 + 1); - buffer.set_len(size / 2); + let mut bytes_read = 0; + if ReadProcessMemory( handle, - ptr as *mut _, - buffer.as_mut_ptr() as *mut _, + ptr, + buffer.as_mut_ptr().cast(), size, - std::ptr::null_mut(), - ) != TRUE + Some(&mut bytes_read), + ) + .is_err() { return Err("Unable to read process data"); } + + // Documentation states that the function fails if not all data is accessible. + if bytes_read != size { + return Err("ReadProcessMemory returned unexpected number of bytes read"); + } + + buffer.set_len(size / 2); + buffer.push(0); + Ok(buffer) } -unsafe fn get_region_size(handle: HANDLE, ptr: LPVOID) -> Result { +unsafe fn get_region_size(handle: HANDLE, ptr: *const c_void) -> Result { let mut meminfo = MaybeUninit::::uninit(); if VirtualQueryEx( handle, - ptr, - meminfo.as_mut_ptr() as *mut _, + Some(ptr), + meminfo.as_mut_ptr().cast(), size_of::(), ) == 0 { @@ -521,46 +529,51 @@ unsafe fn ph_query_process_variable_size( process_handle: HANDLE, process_information_class: PROCESSINFOCLASS, ) -> Option> { - let mut return_length = MaybeUninit::::uninit(); + let mut return_length = MaybeUninit::::uninit(); - let mut status = NtQueryInformationProcess( + if let Err(err) = NtQueryInformationProcess( process_handle, process_information_class, std::ptr::null_mut(), 0, return_length.as_mut_ptr() as *mut _, - ); - - if status != STATUS_BUFFER_OVERFLOW - && status != STATUS_BUFFER_TOO_SMALL - && status != STATUS_INFO_LENGTH_MISMATCH + ) + .ok() { - return None; + if ![ + STATUS_BUFFER_OVERFLOW.into(), + STATUS_BUFFER_TOO_SMALL.into(), + STATUS_INFO_LENGTH_MISMATCH.into(), + ] + .contains(&err.code()) + { + return None; + } } let mut return_length = return_length.assume_init(); let buf_len = (return_length as usize) / 2; let mut buffer: Vec = Vec::with_capacity(buf_len + 1); - buffer.set_len(buf_len); - - status = NtQueryInformationProcess( + if NtQueryInformationProcess( process_handle, process_information_class, buffer.as_mut_ptr() as *mut _, return_length, &mut return_length as *mut _, - ); - if !NT_SUCCESS(status) { + ) + .is_err() + { return None; } + buffer.set_len(buf_len); buffer.push(0); Some(buffer) } -unsafe fn get_cmdline_from_buffer(buffer: *const u16) -> Vec { +unsafe fn get_cmdline_from_buffer(buffer: PCWSTR) -> Vec { // Get argc and argv from the command line let mut argc = MaybeUninit::::uninit(); - let argv_p = winapi::um::shellapi::CommandLineToArgvW(buffer, argc.as_mut_ptr()); + let argv_p = CommandLineToArgvW(buffer, argc.as_mut_ptr()); if argv_p.is_null() { return Vec::new(); } @@ -569,12 +582,10 @@ unsafe fn get_cmdline_from_buffer(buffer: *const u16) -> Vec { let mut res = Vec::new(); for arg in argv { - let len = libc::wcslen(*arg); - let str_slice = std::slice::from_raw_parts(*arg, len); - res.push(String::from_utf16_lossy(str_slice)); + res.push(String::from_utf16_lossy(arg.as_wide())); } - winapi::um::winbase::LocalFree(argv_p as *mut _); + let _err = LocalFree(HLOCAL(argv_p as _)); res } @@ -587,15 +598,16 @@ unsafe fn get_process_params( } // First check if target process is running in wow64 compatibility emulator - let mut pwow32info = MaybeUninit::::uninit(); - let result = NtQueryInformationProcess( + let mut pwow32info = MaybeUninit::<*const c_void>::uninit(); + if NtQueryInformationProcess( handle, ProcessWow64Information, - pwow32info.as_mut_ptr() as *mut _, - size_of::() as u32, + pwow32info.as_mut_ptr().cast(), + size_of::<*const c_void>() as u32, null_mut(), - ); - if !NT_SUCCESS(result) { + ) + .is_err() + { return Err("Unable to check WOW64 information about the process"); } let pwow32info = pwow32info.assume_init(); @@ -604,14 +616,15 @@ unsafe fn get_process_params( // target is a 64 bit process let mut pbasicinfo = MaybeUninit::::uninit(); - let result = NtQueryInformationProcess( + if NtQueryInformationProcess( handle, ProcessBasicInformation, - pbasicinfo.as_mut_ptr() as *mut _, + pbasicinfo.as_mut_ptr().cast(), size_of::() as u32, null_mut(), - ); - if !NT_SUCCESS(result) { + ) + .is_err() + { return Err("Unable to get basic process information"); } let pinfo = pbasicinfo.assume_init(); @@ -619,11 +632,12 @@ unsafe fn get_process_params( let mut peb = MaybeUninit::::uninit(); if ReadProcessMemory( handle, - pinfo.PebBaseAddress as *mut _, - peb.as_mut_ptr() as *mut _, - size_of::() as SIZE_T, - std::ptr::null_mut(), - ) != TRUE + pinfo.PebBaseAddress.cast(), + peb.as_mut_ptr().cast(), + size_of::(), + None, + ) + .is_err() { return Err("Unable to read process PEB"); } @@ -633,11 +647,12 @@ unsafe fn get_process_params( let mut proc_params = MaybeUninit::::uninit(); if ReadProcessMemory( handle, - peb.ProcessParameters as *mut PRTL_USER_PROCESS_PARAMETERS as *mut _, - proc_params.as_mut_ptr() as *mut _, - size_of::() as SIZE_T, - std::ptr::null_mut(), - ) != TRUE + peb.ProcessParameters.cast(), + proc_params.as_mut_ptr().cast(), + size_of::(), + None, + ) + .is_err() { return Err("Unable to read process parameters"); } @@ -655,10 +670,11 @@ unsafe fn get_process_params( if ReadProcessMemory( handle, pwow32info, - peb32.as_mut_ptr() as *mut _, - size_of::() as SIZE_T, - std::ptr::null_mut(), - ) != TRUE + peb32.as_mut_ptr().cast(), + size_of::(), + None, + ) + .is_err() { return Err("Unable to read PEB32"); } @@ -667,11 +683,12 @@ unsafe fn get_process_params( let mut proc_params = MaybeUninit::::uninit(); if ReadProcessMemory( handle, - peb32.ProcessParameters as *mut PRTL_USER_PROCESS_PARAMETERS32 as *mut _, - proc_params.as_mut_ptr() as *mut _, - size_of::() as SIZE_T, - std::ptr::null_mut(), - ) != TRUE + peb32.ProcessParameters as *mut _, + proc_params.as_mut_ptr().cast(), + size_of::(), + None, + ) + .is_err() { return Err("Unable to read 32 bit process parameters"); } @@ -683,13 +700,11 @@ unsafe fn get_process_params( )) } -static WINDOWS_8_1_OR_NEWER: Lazy = Lazy::new(|| { - let mut version_info: RTL_OSVERSIONINFOEXW = unsafe { MaybeUninit::zeroed().assume_init() }; +static WINDOWS_8_1_OR_NEWER: Lazy = Lazy::new(|| unsafe { + let mut version_info: OSVERSIONINFOEXW = MaybeUninit::zeroed().assume_init(); - version_info.dwOSVersionInfoSize = std::mem::size_of::() as u32; - if !NT_SUCCESS(unsafe { - RtlGetVersion(&mut version_info as *mut RTL_OSVERSIONINFOEXW as *mut _) - }) { + version_info.dwOSVersionInfoSize = std::mem::size_of::() as u32; + if RtlGetVersion((&mut version_info as *mut OSVERSIONINFOEXW).cast()).is_err() { return true; } @@ -713,16 +728,16 @@ fn get_cmd_line_new(handle: HANDLE) -> Vec { { let buffer = (*(buffer.as_ptr() as *const UNICODE_STRING)).Buffer; - get_cmdline_from_buffer(buffer) + get_cmdline_from_buffer(PCWSTR::from_raw(buffer.as_ptr())) } else { - vec![] + Vec::new() } } } fn get_cmd_line_old(params: &T, handle: HANDLE) -> Vec { match params.get_cmdline(handle) { - Ok(buffer) => unsafe { get_cmdline_from_buffer(buffer.as_ptr()) }, + Ok(buffer) => unsafe { get_cmdline_from_buffer(PCWSTR::from_raw(buffer.as_ptr())) }, Err(_e) => Vec::new(), } } @@ -769,7 +784,7 @@ fn get_io(handle: HANDLE) -> Option<(u64, u64)> { let mut io: IO_COUNTERS = zeroed(); let ret = GetProcessIoCounters(handle, &mut io); - if ret != 0 { + if ret.is_ok() { Some((io.ReadTransferCount, io.WriteTransferCount)) } else { None @@ -790,7 +805,7 @@ fn get_user(handle: HANDLE) -> Option { let mut token: HANDLE = zeroed(); let ret = OpenProcessToken(handle, TOKEN_QUERY, &mut token); - if ret == 0 { + if ret.is_err() { return None; } @@ -798,7 +813,7 @@ fn get_user(handle: HANDLE) -> Option { let _ = GetTokenInformation( token, TokenUser, - ptr::null::() as *mut c_void, + Some(ptr::null::() as *mut c_void), 0, &mut cb_needed, ); @@ -808,13 +823,13 @@ fn get_user(handle: HANDLE) -> Option { let ret = GetTokenInformation( token, TokenUser, - buf.as_mut_ptr() as *mut c_void, + Some(buf.as_mut_ptr() as *mut c_void), cb_needed, &mut cb_needed, ); buf.set_len(cb_needed as usize); - if ret == 0 { + if ret.is_err() { return None; } @@ -843,7 +858,7 @@ fn get_groups(handle: HANDLE) -> Option> { let mut token: HANDLE = zeroed(); let ret = OpenProcessToken(handle, TOKEN_QUERY, &mut token); - if ret == 0 { + if ret.is_err() { return None; } @@ -851,7 +866,7 @@ fn get_groups(handle: HANDLE) -> Option> { let _ = GetTokenInformation( token, TokenGroups, - ptr::null::() as *mut c_void, + Some(ptr::null::() as *mut c_void), 0, &mut cb_needed, ); @@ -861,13 +876,13 @@ fn get_groups(handle: HANDLE) -> Option> { let ret = GetTokenInformation( token, TokenGroups, - buf.as_mut_ptr() as *mut c_void, + Some(buf.as_mut_ptr() as *mut c_void), cb_needed, &mut cb_needed, ); buf.set_len(cb_needed as usize); - if ret == 0 { + if ret.is_err() { return None; } @@ -901,7 +916,7 @@ fn get_groups(handle: HANDLE) -> Option> { fn get_sid(psid: PSID) -> Vec { unsafe { let mut ret = Vec::new(); - let psid = psid as *const SID; + let psid = psid.0 as *const SID; let mut ia = 0; ia |= u64::from((*psid).IdentifierAuthority.Value[0]) << 40; @@ -924,7 +939,7 @@ fn get_sid(psid: PSID) -> Vec { } thread_local!( - pub static NAME_CACHE: RefCell>> = + pub static NAME_CACHE: RefCell>> = RefCell::new(HashMap::new()); ); @@ -932,11 +947,11 @@ thread_local!( fn get_name_cached(psid: PSID) -> Option<(String, String)> { NAME_CACHE.with(|c| { let mut c = c.borrow_mut(); - if let Some(x) = c.get(&psid) { + if let Some(x) = c.get(&psid.0) { x.clone() } else { let x = get_name(psid); - c.insert(psid, x.clone()); + c.insert(psid.0, x.clone()); x } }) @@ -947,13 +962,13 @@ fn get_name(psid: PSID) -> Option<(String, String)> { unsafe { let mut cc_name = 0; let mut cc_domainname = 0; - let mut pe_use = 0; + let mut pe_use = SID_NAME_USE::default(); let _ = LookupAccountSidW( - ptr::null::() as *mut u16, + PCWSTR::null(), psid, - ptr::null::() as *mut u16, + PWSTR::null(), &mut cc_name, - ptr::null::() as *mut u16, + PWSTR::null(), &mut cc_domainname, &mut pe_use, ); @@ -966,17 +981,17 @@ fn get_name(psid: PSID) -> Option<(String, String)> { let mut domainname: Vec = Vec::with_capacity(cc_domainname as usize); name.set_len(cc_name as usize); domainname.set_len(cc_domainname as usize); - let ret = LookupAccountSidW( - ptr::null::() as *mut u16, + if LookupAccountSidW( + PCWSTR::null(), psid, - name.as_mut_ptr(), + PWSTR::from_raw(name.as_mut_ptr()), &mut cc_name, - domainname.as_mut_ptr(), + PWSTR::from_raw(domainname.as_mut_ptr()), &mut cc_domainname, &mut pe_use, - ); - - if ret == 0 { + ) + .is_err() + { return None; }