Skip to content

Commit 8e4feed

Browse files
committed
[Windows] Fix Interpretation of Volume Name Array
Taking &wszPathNAmes[...] doesn't properly get the string and leads to garbled data. Instead, compute the pointer address and pass that.
1 parent cfd7974 commit 8e4feed

File tree

2 files changed

+16
-11
lines changed

2 files changed

+16
-11
lines changed

Foundation/FileManager+Win32.swift

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -39,19 +39,19 @@ extension FileManager {
3939

4040
var wszPathNames: [WCHAR] = Array<WCHAR>(repeating: 0, count: Int(dwCChReturnLength + 1))
4141
if !GetVolumePathNamesForVolumeNameW(&wszVolumeName, &wszPathNames, DWORD(wszPathNames.count), &dwCChReturnLength) {
42-
// TODO(compnerd) handle error
43-
continue
42+
return nil
4443
}
4544

46-
var pPath: DWORD = 0
47-
repeat {
48-
let path: String = String(decodingCString: &wszPathNames[Int(pPath)], as: UTF16.self)
49-
if path.length == 0 {
50-
break
51-
}
52-
urls.append(URL(fileURLWithPath: path, isDirectory: true))
53-
pPath += DWORD(path.length + 1)
54-
} while pPath < dwCChReturnLength
45+
var pPath: Int = 0
46+
while wszPathNames[pPath] != 0 {
47+
guard let (url, pathLength): (URL, Int) = wszPathNames.withUnsafeBufferPointer({
48+
guard let pathStart = $0.baseAddress else { return nil }
49+
let path = String(decodingCString: pathStart + pPath, as: UTF16.self)
50+
return (URL(fileURLWithPath: path, isDirectory: true), path.length + 1)
51+
}) else { return nil }
52+
urls.append(url)
53+
pPath += pathLength
54+
}
5555
} while FindNextVolumeW(hVolumes, &wszVolumeName, DWORD(wszVolumeName.count))
5656

5757
return urls

TestFoundation/TestFileManager.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -975,7 +975,12 @@ class TestFileManager : XCTestCase {
975975
return
976976
}
977977
XCTAssertNotEqual(0, volumes.count)
978+
#if os(Windows)
979+
let url = URL(fileURLWithPath: String(NSTemporaryDirectory().prefix(3)))
980+
XCTAssertTrue(volumes.contains(url))
981+
#else
978982
XCTAssertTrue(volumes.contains(URL(fileURLWithPath: "/")))
983+
#endif
979984
#if os(macOS)
980985
// On macOS, .skipHiddenVolumes should hide 'nobrowse' volumes of which there should be at least one
981986
guard let visibleVolumes = FileManager.default.mountedVolumeURLs(includingResourceValuesForKeys: [], options: [.skipHiddenVolumes]) else {

0 commit comments

Comments
 (0)