Skip to content

Commit 97893d0

Browse files
committed
Use RtlGetVersion to get OS version on Windows
1 parent aec0d6f commit 97893d0

File tree

1 file changed

+19
-5
lines changed

1 file changed

+19
-5
lines changed

Foundation/ProcessInfo.swift

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -104,12 +104,26 @@ open class ProcessInfo: NSObject {
104104
}
105105
versionString = productVersion._swiftObject
106106
#elseif os(Windows)
107-
var siVersionInfo: OSVERSIONINFOW = OSVERSIONINFOW()
108-
siVersionInfo.dwOSVersionInfoSize = DWORD(MemoryLayout<OSVERSIONINFOEXW>.size)
109-
if GetVersionExW(&siVersionInfo) == FALSE {
110-
return OperatingSystemVersion(majorVersion: fallbackMajor, minorVersion: fallbackMinor, patchVersion: fallbackPatch)
107+
guard let ntdll = ("ntdll.dll".withCString(encodedAs: UTF16.self) {
108+
LoadLibraryExW($0, nil, DWORD(LOAD_LIBRARY_SEARCH_SYSTEM32))
109+
}) else {
110+
return OperatingSystemVersion(majorVersion: fallbackMajor, minorVersion: fallbackMinor, patchVersion: fallbackPatch)
111+
}
112+
defer { FreeLibrary(ntdll) }
113+
typealias RTLGetVersionTy = @convention(c) (UnsafeMutablePointer<RTL_OSVERSIONINFOW>) -> NTSTATUS
114+
guard let pfnRTLGetVersion = unsafeBitCast(GetProcAddress(ntdll, "RtlGetVersion"), to: Optional<RTLGetVersionTy>.self) else {
115+
return OperatingSystemVersion(majorVersion: fallbackMajor, minorVersion: fallbackMinor, patchVersion: fallbackPatch)
116+
}
117+
var osVersionInfo = RTL_OSVERSIONINFOW()
118+
osVersionInfo.dwOSVersionInfoSize = DWORD(MemoryLayout<RTL_OSVERSIONINFOW>.size)
119+
guard pfnRTLGetVersion(&osVersionInfo) == 0 else {
120+
return OperatingSystemVersion(majorVersion: fallbackMajor, minorVersion: fallbackMinor, patchVersion: fallbackPatch)
111121
}
112-
return OperatingSystemVersion(majorVersion: Int(siVersionInfo.dwMajorVersion), minorVersion: Int(siVersionInfo.dwMinorVersion), patchVersion: Int(siVersionInfo.dwBuildNumber))
122+
return OperatingSystemVersion(
123+
majorVersion: Int(osVersionInfo.dwMajorVersion),
124+
minorVersion: Int(osVersionInfo.dwMinorVersion),
125+
patchVersion: Int(osVersionInfo.dwBuildNumber)
126+
)
113127
#else
114128
var utsNameBuffer = utsname()
115129
guard uname(&utsNameBuffer) == 0 else {

0 commit comments

Comments
 (0)