scmanager_windows_rs/
common.rs1use defer_lite::defer;
2use widestring::U16CString;
3use windows_sys::Win32::{
4 Foundation::{CloseHandle, GetLastError, LUID},
5 Security::{
6 AdjustTokenPrivileges, LookupPrivilegeValueW, SE_PRIVILEGE_ENABLED,
7 TOKEN_ADJUST_PRIVILEGES, TOKEN_PRIVILEGES, TOKEN_QUERY,
8 },
9 System::Threading::{GetCurrentProcess, OpenProcessToken},
10};
11
12#[inline(always)]
13pub fn get_last_error() -> u32 {
14 unsafe { GetLastError() }
15}
16pub fn set_privilege(name: String) -> Result<(), String> {
17 unsafe {
18 let mut token_handle = 0;
19
20 if OpenProcessToken(
21 GetCurrentProcess(),
22 TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
23 &mut token_handle,
24 ) == 0
25 {
26 return Err("OpenProcessToken failed".to_string());
27 }
28
29 defer! {CloseHandle(token_handle);}
30
31 let mut lookup_id = std::mem::MaybeUninit::<LUID>::zeroed();
32
33 let name = U16CString::from_str(name).unwrap();
34
35 if LookupPrivilegeValueW(std::ptr::null(), name.as_ptr(), lookup_id.as_mut_ptr()) == 0 {
36 return Err("LookupPrivilegeValueA failed".to_string());
37 }
38
39 let mut token_priv = std::mem::MaybeUninit::<TOKEN_PRIVILEGES>::zeroed();
40 let token_priv_ptr = token_priv.as_mut_ptr();
41
42 (*token_priv_ptr).PrivilegeCount = 1;
43 (*token_priv_ptr).Privileges[0].Luid = lookup_id.assume_init();
44 (*token_priv_ptr).Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
45
46 if AdjustTokenPrivileges(
47 token_handle,
48 0,
49 token_priv.as_ptr(),
50 std::mem::size_of::<TOKEN_PRIVILEGES>() as u32,
51 std::ptr::null_mut(),
52 std::ptr::null_mut(),
53 ) == 0
54 {
55 return Err("AdjustTokenPrivileges failed".to_string());
56 }
57 }
58
59 Ok(())
60}