authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2020-07-27 17:08:25+02:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-07-27 19:45:23+00:00
logf0ed2ed67f8ea53991e0077e3b5b43a94708c3b7
tree5c62d41d808b7d59cd4c85625888035e46450b78
parentd1755e7f16879d678b0accb6a1ccfbe56654c3ab

Replace DeviceIoControl with FsControlFile

This commit replaces `windows.DeviceIoControl` with `windows.FsControlFile` which is a wrapper around the NT-based syscall `ntdll.NtFsControlFile`.

2 files changed, 35 insertions(+), 20 deletions(-)

lib/std/os/windows.zig+23-20
...@@ -215,30 +215,34 @@ pub fn CreateEventExW(attributes: ?*SECURITY_ATTRIBUTES, nameW: [*:0]const u16,...@@ -215,30 +215,34 @@ pub fn CreateEventExW(attributes: ?*SECURITY_ATTRIBUTES, nameW: [*:0]const u16,
215 }215 }
216}216}
217217
218pub fn DeviceIoControl(218pub const FsControlFileError = error{Unexpected};
219
220// TODO work out if we need to expose other arguments to the underlying
221// NtFsControlFile syscall
222pub fn FsControlFile(
219 h: HANDLE,223 h: HANDLE,
220 ioControlCode: DWORD,224 fsControlCode: ULONG,
221 in: ?[]const u8,225 in: ?[]const u8,
222 out: ?[]u8,226 out: ?[]u8,
223 overlapped: ?*OVERLAPPED,227) FsControlFileError!void {
224) !DWORD {228 var io: IO_STATUS_BLOCK = undefined;
225 var bytes: DWORD = undefined;229 const rc = ntdll.NtFsControlFile(
226 if (kernel32.DeviceIoControl(
227 h,230 h,
228 ioControlCode,231 null,
232 null,
233 null,
234 &io,
235 fsControlCode,
229 if (in) |i| i.ptr else null,236 if (in) |i| i.ptr else null,
230 if (in) |i| @intCast(u32, i.len) else 0,237 if (in) |i| @intCast(ULONG, i.len) else 0,
231 if (out) |o| o.ptr else null,238 if (out) |o| o.ptr else null,
232 if (out) |o| @intCast(u32, o.len) else 0,239 if (out) |o| @intCast(ULONG, o.len) else 0,
233 &bytes,240 );
234 overlapped,241 switch (rc) {
235 ) == 0) {242 .SUCCESS => {},
236 switch (kernel32.GetLastError()) {243 .INVALID_PARAMETER => unreachable,
237 .IO_PENDING => if (overlapped == null) unreachable,244 else => return unexpectedStatus(rc),
238 else => |err| return unexpectedError(err),
239 }
240 }245 }
241 return bytes;
242}246}
243247
244pub fn GetOverlappedResult(h: HANDLE, overlapped: *OVERLAPPED, wait: bool) !DWORD {248pub fn GetOverlappedResult(h: HANDLE, overlapped: *OVERLAPPED, wait: bool) !DWORD {
...@@ -727,8 +731,7 @@ pub fn CreateSymbolicLinkW(...@@ -727,8 +731,7 @@ pub fn CreateSymbolicLinkW(
727 @memcpy(buffer[@sizeOf(SYMLINK_DATA)..], @ptrCast([*]const u8, target_path), target_path.len * 2);731 @memcpy(buffer[@sizeOf(SYMLINK_DATA)..], @ptrCast([*]const u8, target_path), target_path.len * 2);
728 const paths_start = @sizeOf(SYMLINK_DATA) + target_path.len * 2;732 const paths_start = @sizeOf(SYMLINK_DATA) + target_path.len * 2;
729 @memcpy(buffer[paths_start..].ptr, @ptrCast([*]const u8, target_path), target_path.len * 2);733 @memcpy(buffer[paths_start..].ptr, @ptrCast([*]const u8, target_path), target_path.len * 2);
730 // TODO replace with NtDeviceIoControl734 _ = try FsControlFile(symlink_handle, FSCTL_SET_REPARSE_POINT, buffer[0..buf_len], null);
731 _ = try DeviceIoControl(symlink_handle, FSCTL_SET_REPARSE_POINT, buffer[0..buf_len], null, null);
732}735}
733736
734pub const ReadLinkError = error{737pub const ReadLinkError = error{
...@@ -806,7 +809,7 @@ pub fn ReadLinkW(dir: ?HANDLE, sub_path_w: [*:0]const u16, out_buffer: []u8) Rea...@@ -806,7 +809,7 @@ pub fn ReadLinkW(dir: ?HANDLE, sub_path_w: [*:0]const u16, out_buffer: []u8) Rea
806 defer CloseHandle(result_handle);809 defer CloseHandle(result_handle);
807810
808 var reparse_buf: [MAXIMUM_REPARSE_DATA_BUFFER_SIZE]u8 = undefined;811 var reparse_buf: [MAXIMUM_REPARSE_DATA_BUFFER_SIZE]u8 = undefined;
809 _ = try DeviceIoControl(result_handle, FSCTL_GET_REPARSE_POINT, null, reparse_buf[0..], null);812 _ = try FsControlFile(result_handle, FSCTL_GET_REPARSE_POINT, null, reparse_buf[0..]);
810813
811 const reparse_struct = @ptrCast(*const REPARSE_DATA_BUFFER, @alignCast(@alignOf(REPARSE_DATA_BUFFER), &reparse_buf[0]));814 const reparse_struct = @ptrCast(*const REPARSE_DATA_BUFFER, @alignCast(@alignOf(REPARSE_DATA_BUFFER), &reparse_buf[0]));
812 switch (reparse_struct.ReparseTag) {815 switch (reparse_struct.ReparseTag) {
lib/std/os/windows/ntdll.zig+12
...@@ -54,6 +54,18 @@ pub extern "NtDll" fn NtDeviceIoControlFile(...@@ -54,6 +54,18 @@ pub extern "NtDll" fn NtDeviceIoControlFile(
54 OutputBuffer: ?PVOID,54 OutputBuffer: ?PVOID,
55 OutputBufferLength: ULONG,55 OutputBufferLength: ULONG,
56) callconv(.Stdcall) NTSTATUS;56) callconv(.Stdcall) NTSTATUS;
57pub extern "NtDll" fn NtFsControlFile(
58 FileHandle: HANDLE,
59 Event: ?HANDLE,
60 ApcRoutine: ?IO_APC_ROUTINE,
61 ApcContext: ?*c_void,
62 IoStatusBlock: *IO_STATUS_BLOCK,
63 FsControlCode: ULONG,
64 InputBuffer: ?*const c_void,
65 InputBufferLength: ULONG,
66 OutputBuffer: ?PVOID,
67 OutputBufferLength: ULONG,
68) callconv(.Stdcall) NTSTATUS;
57pub extern "NtDll" fn NtClose(Handle: HANDLE) callconv(.Stdcall) NTSTATUS;69pub extern "NtDll" fn NtClose(Handle: HANDLE) callconv(.Stdcall) NTSTATUS;
58pub extern "NtDll" fn RtlDosPathNameToNtPathName_U(70pub extern "NtDll" fn RtlDosPathNameToNtPathName_U(
59 DosPathName: [*:0]const u16,71 DosPathName: [*:0]const u16,