| ... | @@ -137,32 +137,42 @@ pub fn OpenFileW( | ... | @@ -137,32 +137,42 @@ pub fn OpenFileW( |
| 137 | }; | 137 | }; |
| 138 | var io: IO_STATUS_BLOCK = undefined; | 138 | var io: IO_STATUS_BLOCK = undefined; |
| 139 | const share_access = share_access_opt orelse FILE_SHARE_WRITE | FILE_SHARE_READ | FILE_SHARE_DELETE; | 139 | const share_access = share_access_opt orelse FILE_SHARE_WRITE | FILE_SHARE_READ | FILE_SHARE_DELETE; |
| 140 | const rc = ntdll.NtCreateFile( | 140 | |
| 141 | &result, | 141 | var delay: usize = 1; |
| 142 | access_mask, | 142 | while (true) { |
| 143 | &attr, | 143 | const rc = ntdll.NtCreateFile( |
| 144 | &io, | 144 | &result, |
| 145 | null, | 145 | access_mask, |
| 146 | FILE_ATTRIBUTE_NORMAL, | 146 | &attr, |
| 147 | share_access, | 147 | &io, |
| 148 | creation, | 148 | null, |
| 149 | FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT, | 149 | FILE_ATTRIBUTE_NORMAL, |
| 150 | null, | 150 | share_access, |
| 151 | 0, | 151 | creation, |
| 152 | ); | 152 | FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT, |
| 153 | switch (rc) { | 153 | null, |
| 154 | .SUCCESS => return result, | 154 | 0, |
| 155 | .OBJECT_NAME_INVALID => unreachable, | 155 | ); |
| 156 | .OBJECT_NAME_NOT_FOUND => return error.FileNotFound, | 156 | switch (rc) { |
| 157 | .OBJECT_PATH_NOT_FOUND => return error.FileNotFound, | 157 | .SUCCESS => return result, |
| 158 | .NO_MEDIA_IN_DEVICE => return error.NoDevice, | 158 | .OBJECT_NAME_INVALID => unreachable, |
| 159 | .INVALID_PARAMETER => unreachable, | 159 | .OBJECT_NAME_NOT_FOUND => return error.FileNotFound, |
| 160 | .SHARING_VIOLATION => return error.SharingViolation, | 160 | .OBJECT_PATH_NOT_FOUND => return error.FileNotFound, |
| 161 | .ACCESS_DENIED => return error.AccessDenied, | 161 | .NO_MEDIA_IN_DEVICE => return error.NoDevice, |
| 162 | .PIPE_BUSY => return error.PipeBusy, | 162 | .INVALID_PARAMETER => unreachable, |
| 163 | .OBJECT_PATH_SYNTAX_BAD => unreachable, | 163 | .SHARING_VIOLATION => { |
| 164 | .OBJECT_NAME_COLLISION => return error.PathAlreadyExists, | 164 | std.time.sleep(delay); |
| 165 | else => return unexpectedStatus(rc), | 165 | if (delay < 1 * std.time.ns_per_s) { |
| | 166 | delay *= 2; |
| | 167 | } |
| | 168 | continue; // TODO: don't loop for async |
| | 169 | }, |
| | 170 | .ACCESS_DENIED => return error.AccessDenied, |
| | 171 | .PIPE_BUSY => return error.PipeBusy, |
| | 172 | .OBJECT_PATH_SYNTAX_BAD => unreachable, |
| | 173 | .OBJECT_NAME_COLLISION => return error.PathAlreadyExists, |
| | 174 | else => return unexpectedStatus(rc), |
| | 175 | } |
| 166 | } | 176 | } |
| 167 | } | 177 | } |
| 168 | | 178 | |