nick_name/windows/
nick_name.rs1use std::ffi::{CStr, OsStr};
2use std::os::windows::ffi::{OsStrExt, OsStringExt};
3use std::{
4 ffi::OsString,
5 fmt::{Debug, Formatter},
6};
7use winapi::shared::minwindef::DWORD;
8use winapi::shared::minwindef::MAKEWORD;
9use winapi::um::iptypes::MAX_HOSTNAME_LEN;
10use winapi::um::l2cmn::L2_PROFILE_MAX_NAME_LENGTH;
11#[cfg(not(miri))]
12use winapi::um::sysinfoapi::GetComputerNameExW;
13#[cfg(not(miri))]
14use winapi::um::sysinfoapi::{ComputerNamePhysicalDnsHostname, SetComputerNameExW};
15use winapi::um::winnt;
16pub struct NickName {}
17
18impl Debug for NickName {
19 fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
20 f.debug_struct("NickName").finish()
21 }
22}
23
24impl NickName {
25 pub fn new() -> crate::Result<Self> {
26 Ok(Self {})
27 }
28
29 pub fn get_w(&self) -> crate::Result<String> {
35 unsafe {
36 let mut buffer: [winnt::WCHAR; L2_PROFILE_MAX_NAME_LENGTH + 1] =
38 [0; L2_PROFILE_MAX_NAME_LENGTH + 1];
39 let mut size: DWORD = buffer.len() as DWORD;
40
41 if winapi::um::winbase::GetComputerNameW(buffer.as_mut_ptr(), &mut size) != 0 {
43 let os_string = OsString::from_wide(&buffer[..(size as usize)]);
45
46 let computer_name = os_string.to_string_lossy();
48
49 Ok(computer_name.into())
50 } else {
51 Err(std::io::Error::last_os_error().into())
52 }
53 }
54 }
55
56 pub fn get_a(&self) -> crate::Result<String> {
62 unsafe {
63 let mut buffer: [winnt::CHAR; L2_PROFILE_MAX_NAME_LENGTH + 1] =
65 [0; L2_PROFILE_MAX_NAME_LENGTH + 1];
66 let mut size: DWORD = buffer.len() as DWORD;
67
68 if winapi::um::winbase::GetComputerNameA(buffer.as_mut_ptr(), &mut size) != 0 {
70 let computer_name = String::from_utf8_lossy(std::slice::from_raw_parts(
72 buffer.as_ptr() as *const u8,
73 size as usize,
74 ));
75 Ok(computer_name.into())
76 } else {
77 Err(std::io::Error::last_os_error().into())
78 }
79 }
80 }
81
82 pub fn get_hostname(&self) -> crate::Result<String> {
87 unsafe {
88 #[cfg_attr(miri, allow(unused_assignments))]
89 let mut size: DWORD = 0;
90
91 #[cfg(not(miri))]
95 let result = GetComputerNameExW(
96 ComputerNamePhysicalDnsHostname,
97 std::ptr::null_mut(),
98 &mut size,
99 );
100 #[cfg(miri)]
101 let result = 0;
102 #[cfg(miri)]
103 {
104 size = 8;
105 }
106 if result != 0 {
107 return Err(crate::Error::RuntimeError("unreachable".into()));
108 }
109
110 let mut buffer = Vec::with_capacity(size as usize);
112 let _remaining = buffer.spare_capacity_mut();
113 buffer.set_len(size as usize);
114
115 #[cfg(not(miri))]
117 let ret = GetComputerNameExW(
118 ComputerNamePhysicalDnsHostname,
119 buffer.as_mut_ptr(),
120 &mut size,
121 );
122 #[cfg(miri)]
123 let ret = 1;
124 #[cfg(miri)]
125 {
126 buffer = vec![104, 111, 115, 116, 110, 97, 109, 101];
127 size = 8;
128 }
129 if ret != 0 {
130 let os_string = OsString::from_wide(&buffer[..(size as usize)]);
132
133 let computer_name = os_string.to_string_lossy();
135
136 Ok(computer_name.into())
137 } else {
138 Err(std::io::Error::last_os_error().into())
139 }
140 }
141 }
142
143 pub fn get_hostname_non_official(&self) -> crate::Result<String> {
148 unsafe {
149 let mut wsadata: winapi::um::winsock2::WSADATA = std::mem::zeroed();
151 if winapi::um::winsock2::WSAStartup(MAKEWORD(2, 2), &mut wsadata) != 0 {
152 return Err(std::io::Error::last_os_error().into());
153 }
154
155 let mut buffer: [i8; MAX_HOSTNAME_LEN] = std::mem::zeroed();
157 if winapi::um::winsock2::gethostname(buffer.as_mut_ptr(), buffer.len() as i32) != 0 {
158 winapi::um::winsock2::WSACleanup();
159 return Err(std::io::Error::last_os_error().into());
160 }
161
162 winapi::um::winsock2::WSACleanup();
164
165 let c_str = CStr::from_ptr(buffer.as_ptr());
167 let hostname = c_str.to_string_lossy().into_owned();
168 Ok(hostname)
169 }
170 }
171
172 pub fn get(&self) -> crate::Result<String> {
174 self.get_hostname()
175 }
176
177 pub fn set_w<S: Into<String>>(&self, nickname: S) -> crate::Result<()> {
183 let nickname: String = nickname.into();
184 unsafe {
185 let mut buffer = OsStr::new(&nickname).encode_wide().collect::<Vec<_>>();
186 buffer.push(0);
187
188 if winapi::um::sysinfoapi::SetComputerNameW(buffer.as_ptr()) != 0 {
190 Ok(())
191 } else {
192 Err(std::io::Error::last_os_error().into())
193 }
194 }
195 }
196
197 pub fn set_a<S: Into<String>>(&self, nickname: S) -> crate::Result<()> {
203 let nickname: String = nickname.into();
204 unsafe {
205 let cow = OsStr::new(&nickname).to_string_lossy();
207 let mut buffer = cow.encode_utf16().map(|u| u as i8).collect::<Vec<i8>>();
208 buffer.push(0);
209
210 if winapi::um::sysinfoapi::SetComputerNameA(buffer.as_ptr()) != 0 {
212 Ok(())
213 } else {
214 Err(std::io::Error::last_os_error().into())
215 }
216 }
217 }
218
219 pub fn set_hostname<S: Into<String>>(&self, nickname: S) -> crate::Result<()> {
224 let nickname: String = nickname.into();
225
226 let mut buffer = OsStr::new(&nickname).encode_wide().collect::<Vec<_>>();
227 buffer.push(0);
228
229 #[cfg(not(miri))]
231 if unsafe { SetComputerNameExW(ComputerNamePhysicalDnsHostname, buffer.as_ptr()) } != 0 {
232 Ok(())
233 } else {
234 Err(std::io::Error::last_os_error().into())
235 }
236
237 #[cfg(miri)]
238 Ok(())
239 }
240
241 pub fn set<S: Into<String>>(&self, nickname: S) -> crate::Result<()> {
244 self.set_hostname(nickname)
245 }
246}