| ... | @@ -215,24 +215,28 @@ pub fn CreateEventExW(attributes: ?*SECURITY_ATTRIBUTES, nameW: [*:0]const u16, | ... | @@ -215,24 +215,28 @@ pub fn CreateEventExW(attributes: ?*SECURITY_ATTRIBUTES, nameW: [*:0]const u16, |
| 215 | } | 215 | } |
| 216 | } | 216 | } |
| 217 | | 217 | |
| 218 | pub const FsControlFileError = error{Unexpected}; | 218 | pub const DeviceIoControlError = error{Unexpected}; |
| 219 | | 219 | |
| 220 | // TODO work out if we need to expose other arguments to the underlying | 220 | /// A Zig wrapper around `NtDeviceIoControlFile` and `NtFsControlFile` syscalls. |
| 221 | // NtFsControlFile syscall | 221 | /// It implements similar behavior to `DeviceIoControl` and is meant to serve |
| 222 | pub fn FsControlFile( | 222 | /// as a direct substitute for that call. |
| | 223 | /// TODO work out if we need to expose other arguments to the underlying syscalls. |
| | 224 | pub fn DeviceIoControl( |
| 223 | h: HANDLE, | 225 | h: HANDLE, |
| 224 | fsControlCode: ULONG, | 226 | ioControlCode: ULONG, |
| 225 | in: ?[]const u8, | 227 | in: ?[]const u8, |
| 226 | out: ?[]u8, | 228 | out: ?[]u8, |
| 227 | ) FsControlFileError!void { | 229 | ) DeviceIoControlError!void { |
| | 230 | // Logic from: https://doxygen.reactos.org/d3/d74/deviceio_8c.html |
| | 231 | const syscall = if ((ioControlCode >> 16) == FILE_DEVICE_FILE_SYSTEM) ntdll.NtFsControlFile else ntdll.NtDeviceIoControlFile; |
| 228 | var io: IO_STATUS_BLOCK = undefined; | 232 | var io: IO_STATUS_BLOCK = undefined; |
| 229 | const rc = ntdll.NtFsControlFile( | 233 | const rc = syscall( |
| 230 | h, | 234 | h, |
| 231 | null, | 235 | null, |
| 232 | null, | 236 | null, |
| 233 | null, | 237 | null, |
| 234 | &io, | 238 | &io, |
| 235 | fsControlCode, | 239 | ioControlCode, |
| 236 | if (in) |i| i.ptr else null, | 240 | if (in) |i| i.ptr else null, |
| 237 | if (in) |i| @intCast(ULONG, i.len) else 0, | 241 | if (in) |i| @intCast(ULONG, i.len) else 0, |
| 238 | if (out) |o| o.ptr else null, | 242 | if (out) |o| o.ptr else null, |
| ... | @@ -731,7 +735,7 @@ pub fn CreateSymbolicLinkW( | ... | @@ -731,7 +735,7 @@ pub fn CreateSymbolicLinkW( |
| 731 | @memcpy(buffer[@sizeOf(SYMLINK_DATA)..], @ptrCast([*]const u8, target_path), target_path.len * 2); | 735 | @memcpy(buffer[@sizeOf(SYMLINK_DATA)..], @ptrCast([*]const u8, target_path), target_path.len * 2); |
| 732 | const paths_start = @sizeOf(SYMLINK_DATA) + target_path.len * 2; | 736 | const paths_start = @sizeOf(SYMLINK_DATA) + target_path.len * 2; |
| 733 | @memcpy(buffer[paths_start..].ptr, @ptrCast([*]const u8, target_path), target_path.len * 2); | 737 | @memcpy(buffer[paths_start..].ptr, @ptrCast([*]const u8, target_path), target_path.len * 2); |
| 734 | _ = try FsControlFile(symlink_handle, FSCTL_SET_REPARSE_POINT, buffer[0..buf_len], null); | 738 | _ = try DeviceIoControl(symlink_handle, FSCTL_SET_REPARSE_POINT, buffer[0..buf_len], null); |
| 735 | } | 739 | } |
| 736 | | 740 | |
| 737 | pub const ReadLinkError = error{ | 741 | pub const ReadLinkError = error{ |
| ... | @@ -809,7 +813,7 @@ pub fn ReadLinkW(dir: ?HANDLE, sub_path_w: [*:0]const u16, out_buffer: []u8) Rea | ... | @@ -809,7 +813,7 @@ pub fn ReadLinkW(dir: ?HANDLE, sub_path_w: [*:0]const u16, out_buffer: []u8) Rea |
| 809 | defer CloseHandle(result_handle); | 813 | defer CloseHandle(result_handle); |
| 810 | | 814 | |
| 811 | var reparse_buf: [MAXIMUM_REPARSE_DATA_BUFFER_SIZE]u8 = undefined; | 815 | var reparse_buf: [MAXIMUM_REPARSE_DATA_BUFFER_SIZE]u8 = undefined; |
| 812 | _ = try FsControlFile(result_handle, FSCTL_GET_REPARSE_POINT, null, reparse_buf[0..]); | 816 | _ = try DeviceIoControl(result_handle, FSCTL_GET_REPARSE_POINT, null, reparse_buf[0..]); |
| 813 | | 817 | |
| 814 | const reparse_struct = @ptrCast(*const REPARSE_DATA_BUFFER, @alignCast(@alignOf(REPARSE_DATA_BUFFER), &reparse_buf[0])); | 818 | const reparse_struct = @ptrCast(*const REPARSE_DATA_BUFFER, @alignCast(@alignOf(REPARSE_DATA_BUFFER), &reparse_buf[0])); |
| 815 | switch (reparse_struct.ReparseTag) { | 819 | switch (reparse_struct.ReparseTag) { |