-
-
Notifications
You must be signed in to change notification settings - Fork 14.4k
Win: Add GetHostNameW fallback for win7 using gethostname #150909
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -227,6 +227,18 @@ compat_fn_with_fallback! { | |
| } | ||
| } | ||
|
|
||
| #[cfg(target_vendor = "win7")] | ||
| compat_fn_with_fallback! { | ||
| pub static WS2_32: &CStr = c"ws2_32"; | ||
|
|
||
| #[cfg(target_vendor = "win7")] | ||
| pub fn GetHostNameW(name: PWSTR, namelen: i32) -> i32 { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I guess it could be nice to link the original issue somewhere around here. |
||
| unsafe { | ||
| crate::sys::winsock::hostname_fallback(name, namelen) | ||
| } | ||
| } | ||
| } | ||
|
|
||
| cfg_select! { | ||
| target_vendor = "uwp" => { | ||
| windows_targets::link_raw_dylib!("ntdll.dll" "system" fn NtCreateFile(filehandle : *mut HANDLE, desiredaccess : FILE_ACCESS_RIGHTS, objectattributes : *const OBJECT_ATTRIBUTES, iostatusblock : *mut IO_STATUS_BLOCK, allocationsize : *const i64, fileattributes : FILE_FLAGS_AND_ATTRIBUTES, shareaccess : FILE_SHARE_MODE, createdisposition : NTCREATEFILE_CREATE_DISPOSITION, createoptions : NTCREATEFILE_CREATE_OPTIONS, eabuffer : *const core::ffi::c_void, ealength : u32) -> NTSTATUS); | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -78,3 +78,46 @@ where | |||||
| { | ||||||
| cvt(f()) | ||||||
| } | ||||||
|
|
||||||
| #[cfg(target_vendor = "win7")] | ||||||
| pub unsafe fn hostname_fallback(name: c::PWSTR, namelen: i32) -> i32 { | ||||||
| assert!(namelen >= 1); | ||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this should return |
||||||
|
|
||||||
| // The documentation of gethostname says that a buffer size of 256 is | ||||||
| // always enough. | ||||||
| let mut buffer = [const { mem::MaybeUninit::<u8>::uninit() }; 256]; | ||||||
|
|
||||||
| // SAFETY: these parameters specify a valid, writable region of memory. | ||||||
| unsafe { | ||||||
| if c::gethostname(buffer.as_mut_ptr().cast(), buffer.len() as i32) == c::SOCKET_ERROR { | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It may be worth documenting that we're using this function in the "Underlying system calls" section of
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think we document syscalls for the win7 target anywhere(?).
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's technically not a syscall either.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The rust documentation has a habit of using the term "syscall" when it means OS API (technically they're not even syscalls on Linux since we go through |
||||||
| return c::SOCKET_ERROR; | ||||||
| } | ||||||
|
Comment on lines
+90
to
+94
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The safety comment seems to suffice for these lines, but the unsafe block continues. I think it would be better if each unsafe call had its own unsafe block with its own safety comments. |
||||||
|
|
||||||
| // Subtract one to leave space for the null terminator, as MultiByteToWideChar doesn't terminate the output buffer | ||||||
| // if the number of output characters is equal to the buffer length. | ||||||
| let len = c::MultiByteToWideChar( | ||||||
| c::CP_ACP, | ||||||
| c::MB_ERR_INVALID_CHARS, | ||||||
| buffer.as_mut_ptr().cast(), | ||||||
| -1, | ||||||
| name, | ||||||
| namelen - 1, | ||||||
| ); | ||||||
|
|
||||||
| if len <= 0 { | ||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
| // GetHostNameW reports WSAEFAULT if the buffer is too small | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
if it indeed still applies here.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That was intentional - if |
||||||
| if c::GetLastError() == c::ERROR_INSUFFICIENT_BUFFER { | ||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If the error is not |
||||||
| c::SetLastError(c::WSAEFAULT as _); | ||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This should call
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Technically unnecessary, as |
||||||
| } | ||||||
| return c::SOCKET_ERROR; | ||||||
| } | ||||||
|
|
||||||
| // Ensure the output is always null terminated. | ||||||
| // If MultiByteToWideChar has already written a null terminator, that null terminator will be included in len | ||||||
| // and this will add a second one, but writing a zero is cheap enough to omit the length comparison. | ||||||
| name.add(len as _).write(0); | ||||||
| } | ||||||
|
|
||||||
| // Success | ||||||
| 0 | ||||||
| } | ||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this seems redundant with the outer cfg attr...