Skip to content

Commit

Permalink
Merge pull request #7 from lunaryorn/use-windows-rs
Browse files Browse the repository at this point in the history
Use windows-rs instead of winapi
  • Loading branch information
swsnr committed Oct 27, 2022
2 parents bdd5096 + 08b6da7 commit 3a3b7c5
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 20 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Expand Up @@ -26,7 +26,7 @@ jobs:
os: [ubuntu-latest, windows-latest, macOS-latest]
rust:
# Our minimal supported version
- '1.56.0'
- '1.64.0'
# The standard Rust version
- stable
steps:
Expand Down
6 changes: 6 additions & 0 deletions CHANGELOG.md
Expand Up @@ -6,6 +6,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Changed
- Replace `winapi` with windows-rs, see [GH-7].
- Bump MSRV to 1.64 as required by windows-rs, see [GH-7].

[GH-7]: https://github.com/lunaryorn/gethostname.rs/pull/7

## [0.3.0] – 2022-10-09

### Changed
Expand Down
6 changes: 5 additions & 1 deletion Cargo.toml
Expand Up @@ -11,9 +11,13 @@ edition = "2021"
license = "Apache-2.0"
keywords = ["gethostname", "DNS", "hostname"]
categories = ["os", "api-bindings"]
rust-version = "1.64"

[target.'cfg(not(windows))'.dependencies]
libc = "^0.2"

[target.'cfg(windows)'.dependencies]
winapi = { version = "^0.3", features = ["sysinfoapi"] }
windows = { version = "0.43.0", features = [
"Win32_System_SystemInformation",
"Win32_Foundation",
] }
47 changes: 29 additions & 18 deletions src/lib.rs
Expand Up @@ -25,7 +25,6 @@
#![deny(warnings, missing_docs, clippy::all)]

use std::ffi::OsString;
use std::io::Error;

/// Get the standard host name for the current machine.
///
Expand Down Expand Up @@ -73,7 +72,7 @@ fn gethostname_impl() -> OsString {
panic!(
"gethostname failed: {}
Please report an issue to <https://github.com/lunaryorn/gethostname.rs/issues>!",
Error::last_os_error()
std::io::Error::last_os_error()
);
}
// We explicitly search for the trailing NUL byte and cap at the buffer
Expand All @@ -90,37 +89,45 @@ fn gethostname_impl() -> OsString {
#[inline]
fn gethostname_impl() -> OsString {
use std::os::windows::ffi::OsStringExt;
use winapi::ctypes::{c_ulong, wchar_t};
use winapi::um::sysinfoapi::{ComputerNamePhysicalDnsHostname, GetComputerNameExW};
use windows::core::PWSTR;
use windows::Win32::System::SystemInformation::{
ComputerNamePhysicalDnsHostname, GetComputerNameExW,
};

let mut buffer_size: c_ulong = 0;
let mut buffer_size: u32 = 0;

unsafe {
// This call always fails with ERROR_MORE_DATA, because we pass NULL to
// get the required buffer size.
// get the required buffer size. GetComputerNameExW then fills buffer_size with the size
// of the host name string plus a trailing zero byte.
GetComputerNameExW(
ComputerNamePhysicalDnsHostname,
std::ptr::null_mut(),
PWSTR::null(),
&mut buffer_size,
)
};
assert!(
0 < buffer_size,
"GetComputerNameExW did not provide buffer size"
);

let mut buffer = vec![0 as wchar_t; buffer_size as usize];
let returncode = unsafe {
let mut buffer = vec![0_u16; buffer_size as usize];
unsafe {
GetComputerNameExW(
ComputerNamePhysicalDnsHostname,
buffer.as_mut_ptr() as *mut wchar_t,
PWSTR::from_raw(buffer.as_mut_ptr()),
&mut buffer_size,
)
};
// GetComputerNameExW returns a non-zero value on success!
if returncode == 0 {
panic!(
"GetComputerNameExW failed to read hostname: {}
Please report this issue to <https://github.com/lunaryorn/gethostname.rs/issues>!",
Error::last_os_error()
);
.expect(
"GetComputerNameExW failed to read hostname.
Please report this issue to <https://github.com/lunaryorn/gethostname.rs/issues>!",
)
}
assert!(
// GetComputerNameExW returns the size _without_ the trailing zero byte on the second call
buffer_size as usize == buffer.len() - 1,
"GetComputerNameExW changed the buffer size unexpectedly"
);

let end = buffer.iter().position(|&b| b == 0).unwrap_or(buffer.len());
OsString::from_wide(&buffer[0..end])
Expand All @@ -137,6 +144,10 @@ mod tests {
.expect("failed to get hostname");
if output.status.success() {
let hostname = String::from_utf8_lossy(&output.stdout);
assert!(
!hostname.is_empty(),
"Failed to get hostname: hostname empty?"
);
// Convert both sides to lowercase; hostnames are case-insensitive
// anyway.
assert_eq!(
Expand Down

0 comments on commit 3a3b7c5

Please sign in to comment.