Instead of looping 8 times to work around the TOCTOU issue with sizing the current directory buffer, instead keep doubling the buffer up until the 32767 character limit until the result fits. This ensures we always get a working directory if GetWorkingDirectoryW didn't return some other error, rather than returning nil in the case of a race condition.
GetBinaryType will return ERROR_BAD_EXE_FORMAT when querying an arm64 executable from an x86 process running on an ARM system. This change switches the implementation to use SHGetFileInfoW, which isn't subject to this quirk.
This also makes isExecutableFile behave more similarly to other platforms -- e.g. isExecutableFile already returns true for any file with the execute bit, even for an arm64 executable on an x86_64 macOS system (which it can't actually run). The spirit of the API is that the file is of an executable type, not necessarily that the running system is capable of executing it.
The practical consequence of fixing this bug is that queries like:
```swift
FileManager.default.isExecutableFile(atPath: "C:\\Windows\\system32\\cmd.exe")
```
will now correctly return true regardless of what architecture the binary is compiled for or what type of system it's running on.
Closes#860
Adjust the Windows path for copying (or linking) files. This adds the
missing recursion in the copy (the documentation for `CopyFile2` was not
clear that the recursive copy is not performed).
We would previously always overwrite the file which would not match the
expectation. Correct the flags to allow us to properly create or
overwrite the file.
clang imported types in WinSDK do not sometimes match the expected
types. Add overloads to shadow the types and match expectations. This
repairs the build after #634.
This adds an initial implementation for file operations on Windows. With
this, `FileManager` should at least build on Windows, which unblocks
future work as well as brings us closer to enabling
`FoundationEssentials` on Windows.
Implement the directory enumeration operations in FileManager on
Windows. The implementation uses the Win32 API surface to ensure that we
can use the full features of the platform.
Adjust the codepaths to improve Windows support in the file. This is
simply blindly trying to match semantics to reduce the errors reported
during building `FoundationEssentials`.
This adjusts the symbolic link paths to be supported on Windows. The
symbolic link destination computation is particularly gnarly as it
requires re-defining the device driver interface in a shim header to
access that and then performing aliasing contortions to gain access to
the trailing VLA to get the value.
This allows for us to use the constants without explicitly casting the
type to `DWORD` on each site of use. By providing the shadowing
overload we can simply use the constants without impacting the
readability of the surrounding code.