diff --git a/Sources/SWBUtil/CMakeLists.txt b/Sources/SWBUtil/CMakeLists.txt index eae57b98..9fa533e0 100644 --- a/Sources/SWBUtil/CMakeLists.txt +++ b/Sources/SWBUtil/CMakeLists.txt @@ -101,6 +101,7 @@ add_library(SWBUtil VFS.swift WaitCondition.swift WeakRef.swift + Win32.swift Win32Error.swift XCBuildDataArchive.swift Xcode.swift) diff --git a/Sources/SWBUtil/Library.swift b/Sources/SWBUtil/Library.swift index c8079482..a0174ad3 100644 --- a/Sources/SWBUtil/Library.swift +++ b/Sources/SWBUtil/Library.swift @@ -117,32 +117,3 @@ public struct LibraryHandle: @unchecked Sendable { self.rawValue = rawValue } } - -#if os(Windows) -@_spi(Testing) public func SWB_GetModuleFileNameW(_ hModule: HMODULE?) throws -> String { -#if DEBUG - var bufferCount = Int(1) // force looping -#else - var bufferCount = Int(MAX_PATH) -#endif - while true { - if let result = try withUnsafeTemporaryAllocation(of: WCHAR.self, capacity: bufferCount, { buffer in - switch (GetModuleFileNameW(hModule, buffer.baseAddress!, DWORD(buffer.count)), GetLastError()) { - case (1.. String? { #if os(Windows) try name.withCString(encodedAs: CInterop.PlatformUnicodeEncoding.self) { wName in - let dwLength: DWORD = GetEnvironmentVariableW(wName, nil, 0) - if dwLength == 0 { - if GetLastError() == ERROR_ENVVAR_NOT_FOUND { - return nil - } - throw POSIXError(errno, context: "GetEnvironmentVariableW", name) - } - return try withUnsafeTemporaryAllocation(of: WCHAR.self, capacity: Int(dwLength)) { - switch GetEnvironmentVariableW(wName, $0.baseAddress!, DWORD($0.count)) { - case 1..) throws -> DWORD) throws -> String { + var bufferCount = max(1, min(initialSize, maxSize)) + while bufferCount <= maxSize { + if let result = try withUnsafeTemporaryAllocation(of: WCHAR.self, capacity: Int(bufferCount), { buffer in + let count = try body(buffer) + switch count { + case 0: + throw Win32Error(GetLastError()) + case 1.. String { + try FillNullTerminatedWideStringBuffer(initialSize: DWORD(MAX_PATH), maxSize: maxPathLength) { + GetModuleFileNameW(hModule, $0.baseAddress!, DWORD($0.count)) + } +} + +public func SWB_GetEnvironmentVariableW(_ wName: LPCWSTR) throws -> String { + try FillNullTerminatedWideStringBuffer(initialSize: 1024, maxSize: maxEnvVarLength) { + GetEnvironmentVariableW(wName, $0.baseAddress!, DWORD($0.count)) + } +} + +public func SWB_GetWindowsDirectoryW() throws -> String { + try FillNullTerminatedWideStringBuffer(initialSize: DWORD(MAX_PATH), maxSize: maxPathLength) { + GetWindowsDirectoryW($0.baseAddress!, DWORD($0.count)) + } +} +#endif diff --git a/Tests/SwiftBuildTests/ConsoleCommands/CLIConnection.swift b/Tests/SwiftBuildTests/ConsoleCommands/CLIConnection.swift index 5624e529..f97d7891 100644 --- a/Tests/SwiftBuildTests/ConsoleCommands/CLIConnection.swift +++ b/Tests/SwiftBuildTests/ConsoleCommands/CLIConnection.swift @@ -328,20 +328,7 @@ fileprivate func swiftRuntimePath() throws -> Path? { fileprivate func systemRoot() throws -> Path? { #if os(Windows) - let dwLength: DWORD = GetWindowsDirectoryW(nil, 0) - if dwLength == 0 { - throw Win32Error(GetLastError()) - } - return try withUnsafeTemporaryAllocation(of: WCHAR.self, capacity: Int(dwLength)) { - switch GetWindowsDirectoryW($0.baseAddress!, DWORD($0.count)) { - case 1..