| ... | ... | @@ -137,32 +137,42 @@ pub fn OpenFileW( |
| 137 | 137 | }; |
| 138 | 138 | var io: IO_STATUS_BLOCK = undefined; |
| 139 | 139 | const share_access = share_access_opt orelse FILE_SHARE_WRITE | FILE_SHARE_READ | FILE_SHARE_DELETE; |
| 140 | | const rc = ntdll.NtCreateFile( |
| 141 | | &result, |
| 142 | | access_mask, |
| 143 | | &attr, |
| 144 | | &io, |
| 145 | | null, |
| 146 | | FILE_ATTRIBUTE_NORMAL, |
| 147 | | share_access, |
| 148 | | creation, |
| 149 | | FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT, |
| 150 | | null, |
| 151 | | 0, |
| 152 | | ); |
| 153 | | switch (rc) { |
| 154 | | .SUCCESS => return result, |
| 155 | | .OBJECT_NAME_INVALID => unreachable, |
| 156 | | .OBJECT_NAME_NOT_FOUND => return error.FileNotFound, |
| 157 | | .OBJECT_PATH_NOT_FOUND => return error.FileNotFound, |
| 158 | | .NO_MEDIA_IN_DEVICE => return error.NoDevice, |
| 159 | | .INVALID_PARAMETER => unreachable, |
| 160 | | .SHARING_VIOLATION => return error.SharingViolation, |
| 161 | | .ACCESS_DENIED => return error.AccessDenied, |
| 162 | | .PIPE_BUSY => return error.PipeBusy, |
| 163 | | .OBJECT_PATH_SYNTAX_BAD => unreachable, |
| 164 | | .OBJECT_NAME_COLLISION => return error.PathAlreadyExists, |
| 165 | | else => return unexpectedStatus(rc), |
| 140 | |
| 141 | var delay: usize = 1; |
| 142 | while (true) { |
| 143 | const rc = ntdll.NtCreateFile( |
| 144 | &result, |
| 145 | access_mask, |
| 146 | &attr, |
| 147 | &io, |
| 148 | null, |
| 149 | FILE_ATTRIBUTE_NORMAL, |
| 150 | share_access, |
| 151 | creation, |
| 152 | FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT, |
| 153 | null, |
| 154 | 0, |
| 155 | ); |
| 156 | switch (rc) { |
| 157 | .SUCCESS => return result, |
| 158 | .OBJECT_NAME_INVALID => unreachable, |
| 159 | .OBJECT_NAME_NOT_FOUND => return error.FileNotFound, |
| 160 | .OBJECT_PATH_NOT_FOUND => return error.FileNotFound, |
| 161 | .NO_MEDIA_IN_DEVICE => return error.NoDevice, |
| 162 | .INVALID_PARAMETER => unreachable, |
| 163 | .SHARING_VIOLATION => { |
| 164 | std.time.sleep(delay); |
| 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 | |