| 100 | } |
| 101 | |
| 102 | Result<FileInfo> StatFile(const std::wstring& path) { |
| 103 | HANDLE h; |
| 104 | std::string bytes_path = NativeToString(path); |
| 105 | FileInfo info; |
| 106 | |
| 107 | /* Inspired by CPython, see Modules/posixmodule.c */ |
| 108 | h = CreateFileW(path.c_str(), FILE_READ_ATTRIBUTES, /* desired access */ |
| 109 | 0, /* share mode */ |
| 110 | NULL, /* security attributes */ |
| 111 | OPEN_EXISTING, |
| 112 | /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */ |
| 113 | FILE_ATTRIBUTE_NORMAL | FILE_FLAG_BACKUP_SEMANTICS, NULL); |
| 114 | |
| 115 | if (h == INVALID_HANDLE_VALUE) { |
| 116 | DWORD err = GetLastError(); |
| 117 | if (err == ERROR_FILE_NOT_FOUND || err == ERROR_PATH_NOT_FOUND) { |
| 118 | info.set_path(bytes_path); |
| 119 | info.set_type(FileType::NotFound); |
| 120 | info.set_mtime(kNoTime); |
| 121 | info.set_size(kNoSize); |
| 122 | return info; |
| 123 | } else { |
| 124 | return IOErrorFromWinError(GetLastError(), "Failed querying information for path '", |
| 125 | bytes_path, "'"); |
| 126 | } |
| 127 | } |
| 128 | BY_HANDLE_FILE_INFORMATION information; |
| 129 | if (!GetFileInformationByHandle(h, &information)) { |
| 130 | CloseHandle(h); |
| 131 | return IOErrorFromWinError(GetLastError(), "Failed querying information for path '", |
| 132 | bytes_path, "'"); |
| 133 | } |
| 134 | CloseHandle(h); |
| 135 | info = FileInformationToFileInfo(information); |
| 136 | info.set_path(bytes_path); |
| 137 | return info; |
| 138 | } |
| 139 | |
| 140 | #else // POSIX systems |
| 141 |
no test coverage detected