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,
215215 }
216216}
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(
219223 h: HANDLE,
220 ioControlCode: DWORD,
224 fsControlCode: ULONG,
221225 in: ?[]const u8,
222226 out: ?[]u8,
223 overlapped: ?*OVERLAPPED,
224) !DWORD {
225 var bytes: DWORD = undefined;
226 if (kernel32.DeviceIoControl(
227) FsControlFileError!void {
228 var io: IO_STATUS_BLOCK = undefined;
229 const rc = ntdll.NtFsControlFile(
227230 h,
228 ioControlCode,
231 null,
232 null,
233 null,
234 &io,
235 fsControlCode,
229236 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,
231238 if (out) |o| o.ptr else null,
232 if (out) |o| @intCast(u32, o.len) else 0,
233 &bytes,
234 overlapped,
235 ) == 0) {
236 switch (kernel32.GetLastError()) {
237 .IO_PENDING => if (overlapped == null) unreachable,
238 else => |err| return unexpectedError(err),
239 }
239 if (out) |o| @intCast(ULONG, o.len) else 0,
240 );
241 switch (rc) {
242 .SUCCESS => {},
243 .INVALID_PARAMETER => unreachable,
244 else => return unexpectedStatus(rc),
240245 }
241 return bytes;
242246}
243247
244248pub fn GetOverlappedResult(h: HANDLE, overlapped: *OVERLAPPED, wait: bool) !DWORD {
......@@ -727,8 +731,7 @@ pub fn CreateSymbolicLinkW(
727731 @memcpy(buffer[@sizeOf(SYMLINK_DATA)..], @ptrCast([*]const u8, target_path), target_path.len * 2);
728732 const paths_start = @sizeOf(SYMLINK_DATA) + target_path.len * 2;
729733 @memcpy(buffer[paths_start..].ptr, @ptrCast([*]const u8, target_path), target_path.len * 2);
730 // TODO replace with NtDeviceIoControl
731 _ = try DeviceIoControl(symlink_handle, FSCTL_SET_REPARSE_POINT, buffer[0..buf_len], null, null);
734 _ = try FsControlFile(symlink_handle, FSCTL_SET_REPARSE_POINT, buffer[0..buf_len], null);
732735}
733736
734737pub const ReadLinkError = error{
......@@ -806,7 +809,7 @@ pub fn ReadLinkW(dir: ?HANDLE, sub_path_w: [*:0]const u16, out_buffer: []u8) Rea
806809 defer CloseHandle(result_handle);
807810
808811 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
811814 const reparse_struct = @ptrCast(*const REPARSE_DATA_BUFFER, @alignCast(@alignOf(REPARSE_DATA_BUFFER), &reparse_buf[0]));
812815 switch (reparse_struct.ReparseTag) {
lib/std/os/windows/ntdll.zig+12
......@@ -54,6 +54,18 @@ pub extern "NtDll" fn NtDeviceIoControlFile(
5454 OutputBuffer: ?PVOID,
5555 OutputBufferLength: ULONG,
5656) 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;
5769pub extern "NtDll" fn NtClose(Handle: HANDLE) callconv(.Stdcall) NTSTATUS;
5870pub extern "NtDll" fn RtlDosPathNameToNtPathName_U(
5971 DosPathName: [*:0]const u16,