Skip to content

Commit 6fcbd96

Browse files
committed
FileManager: correct symbolic link handling on Windows
When the symbolic link points across a drive, querying the symbolic link will provide a NT style path. The NT style path is not valid for a reparse point destination. Use a hand-rolled canonicalization (removal of the `\??\` prefix) for the path to get a path that we can use in the symbolic link. `NTPathToDosPath` is a possible approach to a more robust solution but relies on undocumented kernel APIs.
1 parent 973afe6 commit 6fcbd96

File tree

1 file changed

+9
-1
lines changed

1 file changed

+9
-1
lines changed

Foundation/FileManager+Win32.swift

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -397,9 +397,17 @@ extension FileManager {
397397
}
398398

399399
let substituteNameBuff = Data(bytes: pathBufferPtr + substituteNameOffset, count: substituteNameBytes)
400-
guard let substitutePath = String(data: substituteNameBuff, encoding: .utf16LittleEndian) else {
400+
guard var substitutePath = String(data: substituteNameBuff, encoding: .utf16LittleEndian) else {
401401
throw _NSErrorWithWindowsError(DWORD(ERROR_INVALID_DATA), reading: false)
402402
}
403+
404+
// Canonicalize the NT Object Manager Path to the DOS style path
405+
// instead. Unfortunately, there is no nice API which can allow us to
406+
// do this in a guranteed way.
407+
let kObjectManagerPrefix = "\\??\\"
408+
if substitutePath.hasPrefix(kObjectManagerPrefix) {
409+
substitutePath = String(substitutePath.dropFirst(kObjectManagerPrefix.count))
410+
}
403411
return substitutePath
404412
}
405413

0 commit comments

Comments
 (0)