| ... | @@ -110,7 +110,6 @@ pub const OpenFileOptions = struct { | ... | @@ -110,7 +110,6 @@ pub const OpenFileOptions = struct { |
| 110 | share_access: ULONG = FILE_SHARE_WRITE | FILE_SHARE_READ | FILE_SHARE_DELETE, | 110 | share_access: ULONG = FILE_SHARE_WRITE | FILE_SHARE_READ | FILE_SHARE_DELETE, |
| 111 | share_access_nonblocking: bool = false, | 111 | share_access_nonblocking: bool = false, |
| 112 | creation: ULONG, | 112 | creation: ULONG, |
| 113 | options: ?ULONG = null, | | |
| 114 | io_mode: std.io.ModeOverride, | 113 | io_mode: std.io.ModeOverride, |
| 115 | }; | 114 | }; |
| 116 | | 115 | |
| ... | @@ -147,14 +146,7 @@ pub fn OpenFile(sub_path_w: []const u16, options: OpenFileOptions) OpenError!HAN | ... | @@ -147,14 +146,7 @@ pub fn OpenFile(sub_path_w: []const u16, options: OpenFileOptions) OpenError!HAN |
| 147 | var delay: usize = 1; | 146 | var delay: usize = 1; |
| 148 | while (true) { | 147 | while (true) { |
| 149 | var flags: ULONG = undefined; | 148 | var flags: ULONG = undefined; |
| 150 | if (options.options) |opt| { | 149 | const blocking_flag: ULONG = if (options.io_mode == .blocking) FILE_SYNCHRONOUS_IO_NONALERT else 0; |
| 151 | flags = opt; | | |
| 152 | } else { | | |
| 153 | const blocking_flag: ULONG = if (options.io_mode == .blocking) FILE_SYNCHRONOUS_IO_NONALERT else 0; | | |
| 154 | flags = FILE_NON_DIRECTORY_FILE | blocking_flag; | | |
| 155 | } | | |
| 156 | // const blocking_flag: ULONG = if (options.io_mode == .blocking) FILE_SYNCHRONOUS_IO_NONALERT else 0; | | |
| 157 | // const flags = if (options.options) |opt| opt else FILE_NON_DIRECTORY_FILE; | | |
| 158 | const rc = ntdll.NtCreateFile( | 150 | const rc = ntdll.NtCreateFile( |
| 159 | &result, | 151 | &result, |
| 160 | options.access_mask, | 152 | options.access_mask, |
| ... | @@ -164,8 +156,7 @@ pub fn OpenFile(sub_path_w: []const u16, options: OpenFileOptions) OpenError!HAN | ... | @@ -164,8 +156,7 @@ pub fn OpenFile(sub_path_w: []const u16, options: OpenFileOptions) OpenError!HAN |
| 164 | FILE_ATTRIBUTE_NORMAL, | 156 | FILE_ATTRIBUTE_NORMAL, |
| 165 | options.share_access, | 157 | options.share_access, |
| 166 | options.creation, | 158 | options.creation, |
| 167 | // flags | blocking_flag, | 159 | FILE_NON_DIRECTORY_FILE | blocking_flag, |
| 168 | flags, | | |
| 169 | null, | 160 | null, |
| 170 | 0, | 161 | 0, |
| 171 | ); | 162 | ); |
| ... | @@ -1380,3 +1371,53 @@ pub fn unexpectedStatus(status: NTSTATUS) std.os.UnexpectedError { | ... | @@ -1380,3 +1371,53 @@ pub fn unexpectedStatus(status: NTSTATUS) std.os.UnexpectedError { |
| 1380 | } | 1371 | } |
| 1381 | return error.Unexpected; | 1372 | return error.Unexpected; |
| 1382 | } | 1373 | } |
| | 1374 | |
| | 1375 | pub fn ReadLink(path_w: []const u16) OpenError!HANDLE { |
| | 1376 | var result: HANDLE = undefined; |
| | 1377 | |
| | 1378 | const path_len_bytes = math.cast(u16, path_w.len * 2) catch |err| switch (err) { |
| | 1379 | error.Overflow => return error.NameTooLong, |
| | 1380 | }; |
| | 1381 | var nt_name = UNICODE_STRING{ |
| | 1382 | .Length = path_len_bytes, |
| | 1383 | .MaximumLength = path_len_bytes, |
| | 1384 | .Buffer = @intToPtr([*]u16, @ptrToInt(path_w.ptr)), |
| | 1385 | }; |
| | 1386 | var attr = OBJECT_ATTRIBUTES{ |
| | 1387 | .Length = @sizeOf(OBJECT_ATTRIBUTES), |
| | 1388 | .RootDirectory = null, |
| | 1389 | .Attributes = 0, // Note we do not use OBJ_CASE_INSENSITIVE here. |
| | 1390 | .ObjectName = &nt_name, |
| | 1391 | .SecurityDescriptor = null, |
| | 1392 | .SecurityQualityOfService = null, |
| | 1393 | }; |
| | 1394 | var io: IO_STATUS_BLOCK = undefined; |
| | 1395 | const rc = ntdll.NtCreateFile( |
| | 1396 | &result, |
| | 1397 | FILE_LIST_DIRECTORY, |
| | 1398 | &attr, |
| | 1399 | &io, |
| | 1400 | null, |
| | 1401 | FILE_ATTRIBUTE_NORMAL, |
| | 1402 | FILE_SHARE_READ | FILE_SHARE_DELETE, |
| | 1403 | FILE_OPEN, |
| | 1404 | FILE_OPEN_REPARSE_POINT, |
| | 1405 | null, |
| | 1406 | 0, |
| | 1407 | ); |
| | 1408 | switch (rc) { |
| | 1409 | .SUCCESS => return result, |
| | 1410 | .OBJECT_NAME_INVALID => unreachable, |
| | 1411 | .OBJECT_NAME_NOT_FOUND => return error.FileNotFound, |
| | 1412 | .OBJECT_PATH_NOT_FOUND => return error.FileNotFound, |
| | 1413 | .NO_MEDIA_IN_DEVICE => return error.NoDevice, |
| | 1414 | .INVALID_PARAMETER => unreachable, |
| | 1415 | .SHARING_VIOLATION => return error.WouldBlock, |
| | 1416 | .ACCESS_DENIED => return error.AccessDenied, |
| | 1417 | .PIPE_BUSY => return error.PipeBusy, |
| | 1418 | .OBJECT_PATH_SYNTAX_BAD => unreachable, |
| | 1419 | .OBJECT_NAME_COLLISION => return error.PathAlreadyExists, |
| | 1420 | .FILE_IS_A_DIRECTORY => return error.IsDir, |
| | 1421 | else => return unexpectedStatus(rc), |
| | 1422 | } |
| | 1423 | } |
| \ No newline at end of file |