diff --git a/library/std/src/sys/windows/c.rs b/library/std/src/sys/windows/c.rs index 0906edb0d85e3..2eb95b4bed9e8 100644 --- a/library/std/src/sys/windows/c.rs +++ b/library/std/src/sys/windows/c.rs @@ -551,6 +551,18 @@ compat_fn_with_fallback! { SetLastError(ERROR_CALL_NOT_IMPLEMENTED as DWORD); FALSE } + + // >= Vista / Server 2008 + // https://docs.microsoft.com/en-us/windows/win32/api/stringapiset/nf-stringapiset-comparestringordinal + pub fn CompareStringOrdinal( + lpString1: PCWSTR, + cchCount1: i32, + lpString2: PCWSTR, + cchCount2: i32, + bIgnoreCase: BOOL + ) -> COMPARESTRING_RESULT { + rtabort!("unavailable") + } } compat_fn_optional! { diff --git a/library/std/src/sys/windows/c/windows_sys.lst b/library/std/src/sys/windows/c/windows_sys.lst index 7e83e7143fcc6..97579d0c7748b 100644 --- a/library/std/src/sys/windows/c/windows_sys.lst +++ b/library/std/src/sys/windows/c/windows_sys.lst @@ -1941,7 +1941,6 @@ Windows.Win32.Foundation.WAIT_OBJECT_0 Windows.Win32.Foundation.WAIT_TIMEOUT Windows.Win32.Foundation.WIN32_ERROR Windows.Win32.Globalization.COMPARESTRING_RESULT -Windows.Win32.Globalization.CompareStringOrdinal Windows.Win32.Globalization.CP_UTF8 Windows.Win32.Globalization.CSTR_EQUAL Windows.Win32.Globalization.CSTR_GREATER_THAN diff --git a/library/std/src/sys/windows/c/windows_sys.rs b/library/std/src/sys/windows/c/windows_sys.rs index 7b07fe3467cdb..3bacae1c9714b 100644 --- a/library/std/src/sys/windows/c/windows_sys.rs +++ b/library/std/src/sys/windows/c/windows_sys.rs @@ -16,16 +16,6 @@ extern "system" { pub fn CloseHandle(hobject: HANDLE) -> BOOL; } #[link(name = "kernel32")] -extern "system" { - pub fn CompareStringOrdinal( - lpstring1: PCWSTR, - cchcount1: i32, - lpstring2: PCWSTR, - cchcount2: i32, - bignorecase: BOOL, - ) -> COMPARESTRING_RESULT; -} -#[link(name = "kernel32")] extern "system" { pub fn CreateDirectoryW( lppathname: PCWSTR, diff --git a/library/std/src/sys/windows/process.rs b/library/std/src/sys/windows/process.rs index e8f82c8f44587..63b0cc646f3b1 100644 --- a/library/std/src/sys/windows/process.rs +++ b/library/std/src/sys/windows/process.rs @@ -74,6 +74,10 @@ impl EnvKey { // [4] https://docs.microsoft.com/en-us/windows/win32/api/stringapiset/nf-stringapiset-comparestringordinal impl Ord for EnvKey { fn cmp(&self, other: &Self) -> cmp::Ordering { + if !c::CompareStringOrdinal::available() { + return self.os_string.cmp(&other.os_string); + } + unsafe { let result = c::CompareStringOrdinal( self.utf16.as_ptr(), @@ -99,6 +103,10 @@ impl PartialOrd for EnvKey { } impl PartialEq for EnvKey { fn eq(&self, other: &Self) -> bool { + if !c::CompareStringOrdinal::available() { + return self.os_string == other.os_string; + } + if self.utf16.len() != other.utf16.len() { false } else { @@ -124,7 +132,12 @@ impl PartialEq for EnvKey { // Environment variable keys should preserve their original case even though // they are compared using a caseless string mapping. impl From for EnvKey { - fn from(k: OsString) -> Self { + fn from(mut k: OsString) -> Self { + if !c::CompareStringOrdinal::available() { + k.make_ascii_uppercase(); + return EnvKey { utf16: Vec::new(), os_string: k }; + } + EnvKey { utf16: k.encode_wide().collect(), os_string: k } } } @@ -818,8 +831,12 @@ fn make_envp(maybe_env: Option>) -> io::Result<(*mut } for (k, v) in env { - ensure_no_nuls(k.os_string)?; - blk.extend(k.utf16); + if !c::CompareStringOrdinal::available() { + blk.extend(ensure_no_nuls(k.os_string)?.encode_wide()); + } else { + ensure_no_nuls(k.os_string)?; + blk.extend(k.utf16); + } blk.push('=' as u16); blk.extend(ensure_no_nuls(v)?.encode_wide()); blk.push(0);