authorgravatar for dev@sgregoratto.meStephen Gregoratto <dev@sgregoratto.me> 2024-03-12 22:21:55+11:00
committergravatar for dev@sgregoratto.meStephen Gregoratto <dev@sgregoratto.me> 2024-03-16 23:37:50+11:00
log69175ad62f531327e9fd693c13890ca1d472a7a3
tree8f6a8b5f626cfca74a6973479bec61b441815db7
parent9532f729371d8142fb65c61794b7bd765cd82396

Windows: Add wrappers for `GetCurrent(Process|Thread)` via NT_TIB

This is how they've been implemented in `kernel32` since NT 3.1.

3 files changed, 46 insertions(+), 5 deletions(-)

lib/std/child_process.zig+1-1
......@@ -1420,7 +1420,7 @@ fn windowsMakeAsyncPipe(rd: *?windows.HANDLE, wr: *?windows.HANDLE, sattr: *cons
14201420 const pipe_path = std.fmt.bufPrintZ(
14211421 &tmp_buf,
14221422 "\\\\.\\pipe\\zig-childprocess-{d}-{d}",
1423 .{ windows.kernel32.GetCurrentProcessId(), pipe_name_counter.fetchAdd(1, .monotonic) },
1423 .{ windows.GetCurrentProcessId(), pipe_name_counter.fetchAdd(1, .monotonic) },
14241424 ) catch unreachable;
14251425 const len = std.unicode.wtf8ToWtf16Le(&tmp_bufw, pipe_path) catch unreachable;
14261426 tmp_bufw[len] = 0;
lib/std/debug.zig+1-1
......@@ -814,7 +814,7 @@ pub noinline fn walkStackWindows(addresses: []usize, existing_context: ?*const w
814814 return windows.ntdll.RtlCaptureStackBackTrace(0, addresses.len, @as(**anyopaque, @ptrCast(addresses.ptr)), null);
815815 }
816816
817 const tib = @as(*const windows.NT_TIB, @ptrCast(&windows.teb().Reserved1));
817 const tib = &windows.teb().NtTib;
818818
819819 var context: windows.CONTEXT = undefined;
820820 if (existing_context) |context_ptr| {
lib/std/os/windows.zig+44-3
......@@ -153,6 +153,24 @@ pub fn OpenFile(sub_path_w: []const u16, options: OpenFileOptions) OpenError!HAN
153153 }
154154}
155155
156pub fn GetCurrentProcess() HANDLE {
157 const process_pseudo_handle: usize = @bitCast(@as(isize, -1));
158 return @ptrFromInt(process_pseudo_handle);
159}
160
161pub fn GetCurrentProcessId() DWORD {
162 return @truncate(@intFromPtr(teb().ClientId.UniqueProcess));
163}
164
165pub fn GetCurrentThread() HANDLE {
166 const thread_pseudo_handle: usize = @bitCast(@as(isize, -2));
167 return @ptrFromInt(thread_pseudo_handle);
168}
169
170pub fn GetCurrentThreadId() DWORD {
171 return @truncate(@intFromPtr(teb().ClientId.UniqueThread));
172}
173
156174pub const CreatePipeError = error{ Unexpected, SystemResources };
157175
158176var npfs: ?HANDLE = null;
......@@ -259,12 +277,12 @@ pub fn CreatePipe(rd: *HANDLE, wr: *HANDLE, sattr: *const SECURITY_ATTRIBUTES) C
259277 var write: HANDLE = undefined;
260278 switch (ntdll.NtCreateFile(
261279 &write,
262 FILE_GENERIC_WRITE,
280 GENERIC_WRITE | SYNCHRONIZE | FILE_READ_ATTRIBUTES,
263281 &attrs,
264282 &iosb,
265283 null,
266284 0,
267 FILE_SHARE_READ,
285 FILE_SHARE_READ | FILE_SHARE_WRITE,
268286 FILE_OPEN,
269287 FILE_SYNCHRONOUS_IO_NONALERT | FILE_NON_DIRECTORY_FILE,
270288 null,
......@@ -4309,7 +4327,11 @@ pub const THREAD_BASIC_INFORMATION = extern struct {
43094327};
43104328
43114329pub const TEB = extern struct {
4312 Reserved1: [12]PVOID,
4330 NtTib: NT_TIB,
4331 EnvironmentPointer: PVOID,
4332 ClientId: CLIENT_ID,
4333 ActiveRpcHandle: PVOID,
4334 ThreadLocalStoragePointer: PVOID,
43134335 ProcessEnvironmentBlock: *PEB,
43144336 Reserved2: [399]PVOID,
43154337 Reserved3: [1952]u8,
......@@ -4321,6 +4343,25 @@ pub const TEB = extern struct {
43214343 TlsExpansionSlots: PVOID,
43224344};
43234345
4346comptime {
4347 // Offsets taken from WinDbg info and Geoff Chappell[1] (RIP)
4348 // [1]: https://www.geoffchappell.com/studies/windows/km/ntoskrnl/inc/api/pebteb/teb/index.htm
4349 assert(@offsetOf(TEB, "NtTib") == 0x00);
4350 if (@sizeOf(usize) == 4) {
4351 assert(@offsetOf(TEB, "EnvironmentPointer") == 0x1C);
4352 assert(@offsetOf(TEB, "ClientId") == 0x20);
4353 assert(@offsetOf(TEB, "ActiveRpcHandle") == 0x28);
4354 assert(@offsetOf(TEB, "ThreadLocalStoragePointer") == 0x2C);
4355 assert(@offsetOf(TEB, "ProcessEnvironmentBlock") == 0x30);
4356 } else if (@sizeOf(usize) == 8) {
4357 assert(@offsetOf(TEB, "EnvironmentPointer") == 0x38);
4358 assert(@offsetOf(TEB, "ClientId") == 0x40);
4359 assert(@offsetOf(TEB, "ActiveRpcHandle") == 0x50);
4360 assert(@offsetOf(TEB, "ThreadLocalStoragePointer") == 0x58);
4361 assert(@offsetOf(TEB, "ProcessEnvironmentBlock") == 0x60);
4362 }
4363}
4364
43244365pub const EXCEPTION_REGISTRATION_RECORD = extern struct {
43254366 Next: ?*EXCEPTION_REGISTRATION_RECORD,
43264367 Handler: ?*EXCEPTION_DISPOSITION,