Skip to content

Commit 9889525

Browse files
authored
fix(uv-platform): adjust windows ostype to match sys-info-rs, fix windows version (#18383)
## Summary In #18324, sys-info-rs was dropped in favor of a more native reimplementation to provide OsType and OsRelease. This PR adjusts two areas for windows to match closely previous behavior: 1. OsType should be `Windows` rather than `Windows_NT` #18324 (comment) as seen in https://github.com/FillZpp/sys-info-rs/blob/60ecf1470a5b7c90242f429934a3bacb6023ec4d/c/windows.c#L12. This also matches the output of `platform.system()` in CPython. 2. OsRelease previously used `GetVersionEx` in sys-info-rs. Looking closely, this was used primarily in `crates/uv-python/src/interpreter.rs` and not in linehaul as linehaul uses `platform.release()`. The problem with `GetVersionEx` is that it returns often the wrong version due to legacy reasons (e.g. may be stuck returning `6.2.9200`). The current implementation only returns the build number from the registry which is prone to problems across windows older variants. The implementation should use `RtlGetVersion` system call which returns the current major, minor, build in the same way as reported by `sys.getwindowsversion()` in CPython. In order to strike balance, this switches the implementation to use four octects `{major}.{minor}.{build}.{revision}` as recent windows versioning relies on major, build and revision where as older versions rely on major, minor and service pack. A windows-version crate by the same author as windows-rs was added as it includes the correct system calls for the windows versions. ## Test Plan Tested manually on both Windows desktop (10, 11) and Windows Server (2016).
1 parent 50d5d89 commit 9889525

4 files changed

Lines changed: 38 additions & 15 deletions

File tree

Cargo.lock

Lines changed: 10 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,7 @@ windows = { version = "0.61.0", features = [
294294
"Win32_UI_WindowsAndMessaging",
295295
] }
296296
windows-registry = { version = "0.5.0" }
297+
windows-version = { version = "0.1.6" }
297298
wiremock = { version = "0.6.4" }
298299
wmi = { version = "0.16.0", default-features = false }
299300
xz2 = { version = "0.1.7", features = ["static"] }

crates/uv-platform/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ rustix = { workspace = true }
3434
procfs = { workspace = true }
3535

3636
[target.'cfg(target_os = "windows")'.dependencies]
37-
windows-registry = { workspace = true }
37+
windows-version = { workspace = true }
3838

3939
[dev-dependencies]
4040
insta = { workspace = true }

crates/uv-platform/src/host.rs

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ pub enum OsType {
1111
Linux(String),
1212
/// macOS / Darwin.
1313
Darwin,
14-
/// Windows NT.
15-
WindowsNt,
14+
/// Windows.
15+
Windows,
1616
}
1717

1818
impl OsType {
@@ -32,7 +32,7 @@ impl OsType {
3232
}
3333
#[cfg(target_os = "windows")]
3434
{
35-
Some(Self::WindowsNt)
35+
Some(Self::Windows)
3636
}
3737
#[cfg(not(any(target_os = "linux", target_os = "macos", target_os = "windows")))]
3838
{
@@ -46,7 +46,7 @@ impl fmt::Display for OsType {
4646
match self {
4747
Self::Linux(os_type) => f.write_str(os_type),
4848
Self::Darwin => f.write_str("Darwin"),
49-
Self::WindowsNt => f.write_str("Windows_NT"),
49+
Self::Windows => f.write_str("Windows"),
5050
}
5151
}
5252
}
@@ -56,8 +56,13 @@ impl fmt::Display for OsType {
5656
pub enum OsRelease {
5757
/// Unix kernel release from `uname -r` (e.g., `"6.8.0-90-generic"`).
5858
Unix(String),
59-
/// Windows build number from the registry (e.g., `"22631"`).
60-
Windows(String),
59+
/// Windows version major.minor.build.revision (e.g., `"10.0.26100.6901"`).
60+
Windows {
61+
major: u32,
62+
minor: u32,
63+
build: u32,
64+
revision: u32,
65+
},
6166
}
6267

6368
impl OsRelease {
@@ -73,10 +78,13 @@ impl OsRelease {
7378
}
7479
#[cfg(windows)]
7580
{
76-
let key = windows_registry::LOCAL_MACHINE
77-
.open(r"SOFTWARE\Microsoft\Windows NT\CurrentVersion")
78-
.ok()?;
79-
Some(Self::Windows(key.get_string("CurrentBuildNumber").ok()?))
81+
let os_version = windows_version::OsVersion::current();
82+
Some(Self::Windows {
83+
major: os_version.major,
84+
minor: os_version.minor,
85+
build: os_version.build,
86+
revision: windows_version::revision(),
87+
})
8088
}
8189
#[cfg(not(any(unix, windows)))]
8290
{
@@ -89,7 +97,12 @@ impl fmt::Display for OsRelease {
8997
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9098
match self {
9199
Self::Unix(release) => f.write_str(release),
92-
Self::Windows(build) => f.write_str(build),
100+
Self::Windows {
101+
major,
102+
minor,
103+
build,
104+
revision,
105+
} => write!(f, "{major}.{minor}.{build}.{revision}"),
93106
}
94107
}
95108
}
@@ -232,7 +245,7 @@ VERSION_ID=40
232245
#[cfg(target_os = "macos")]
233246
assert_eq!(os_type, OsType::Darwin);
234247
#[cfg(target_os = "windows")]
235-
assert_eq!(os_type, OsType::WindowsNt);
248+
assert_eq!(os_type, OsType::Windows);
236249
}
237250

238251
#[test]
@@ -242,6 +255,6 @@ VERSION_ID=40
242255
#[cfg(unix)]
243256
assert!(matches!(os_release, OsRelease::Unix(_)));
244257
#[cfg(windows)]
245-
assert!(matches!(os_release, OsRelease::Windows(_)));
258+
assert!(matches!(os_release, OsRelease::Windows { .. }));
246259
}
247260
}

0 commit comments

Comments
 (0)