From afaa3650a925703d407034b604030335ebe39632 Mon Sep 17 00:00:00 2001 From: "Jason A. Donenfeld" Date: Wed, 3 Mar 2021 12:07:20 +0100 Subject: [PATCH] windows: do not write LastStatus parameter of TEB when converting errors The prior function updated the TEB's LastStatus member, which is not what we want to be doing here. It's also not consistent with Microsoft's own Go code for their pipe library, which properly uses the "NoTeb" variant like this commit. For good measure, we add a simple test case to make sure these paths are being exercised. Change-Id: I4080898f704bdc93a6048001b06ffce516fb412d Reviewed-on: https://go-review.googlesource.com/c/sys/+/298169 Trust: Jason A. Donenfeld Run-TryBot: Jason A. Donenfeld TryBot-Result: Go Bot Reviewed-by: Brad Fitzpatrick --- windows/syscall_windows.go | 4 ++-- windows/syscall_windows_test.go | 8 ++++++++ windows/zsyscall_windows.go | 6 +++--- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/windows/syscall_windows.go b/windows/syscall_windows.go index 944750b8..38d7d58b 100644 --- a/windows/syscall_windows.go +++ b/windows/syscall_windows.go @@ -375,7 +375,7 @@ func NewCallbackCDecl(fn interface{}) uintptr { //sys stringFromGUID2(rguid *GUID, lpsz *uint16, cchMax int32) (chars int32) = ole32.StringFromGUID2 //sys coCreateGuid(pguid *GUID) (ret error) = ole32.CoCreateGuid //sys CoTaskMemFree(address unsafe.Pointer) = ole32.CoTaskMemFree -//sys rtlNtStatusToDosError(ntstatus NTStatus) (ret syscall.Errno) = ntdll.RtlNtStatusToDosError +//sys rtlNtStatusToDosErrorNoTeb(ntstatus NTStatus) (ret syscall.Errno) = ntdll.RtlNtStatusToDosErrorNoTeb //sys rtlGetVersion(info *OsVersionInfoEx) (ntstatus error) = ntdll.RtlGetVersion //sys rtlGetNtVersionNumbers(majorVersion *uint32, minorVersion *uint32, buildNumber *uint32) = ntdll.RtlGetNtVersionNumbers //sys getProcessPreferredUILanguages(flags uint32, numLanguages *uint32, buf *uint16, bufSize *uint32) (err error) = kernel32.GetProcessPreferredUILanguages @@ -1517,7 +1517,7 @@ func SetConsoleCursorPosition(console Handle, position Coord) error { } func (s NTStatus) Errno() syscall.Errno { - return rtlNtStatusToDosError(s) + return rtlNtStatusToDosErrorNoTeb(s) } func langID(pri, sub uint16) uint32 { return uint32(sub)<<10 | uint32(pri) } diff --git a/windows/syscall_windows_test.go b/windows/syscall_windows_test.go index 39a72fe8..a3d5a873 100644 --- a/windows/syscall_windows_test.go +++ b/windows/syscall_windows_test.go @@ -494,3 +494,11 @@ func TestNTStatusString(t *testing.T) { t.Errorf("NTStatus.Error did not return an expected error string - want %q; got %q", want, got) } } + +func TestNTStatusConversion(t *testing.T) { + want := windows.ERROR_TOO_MANY_NAMES + got := windows.STATUS_TOO_MANY_NAMES.Errno() + if want != got { + t.Errorf("NTStatus.Errno = %q (0x%x); want %q (0x%x)", got.Error(), got, want.Error(), want) + } +} diff --git a/windows/zsyscall_windows.go b/windows/zsyscall_windows.go index def5b56f..8b16cb35 100644 --- a/windows/zsyscall_windows.go +++ b/windows/zsyscall_windows.go @@ -346,7 +346,7 @@ var ( procNetUserGetInfo = modnetapi32.NewProc("NetUserGetInfo") procRtlGetNtVersionNumbers = modntdll.NewProc("RtlGetNtVersionNumbers") procRtlGetVersion = modntdll.NewProc("RtlGetVersion") - procRtlNtStatusToDosError = modntdll.NewProc("RtlNtStatusToDosError") + procRtlNtStatusToDosErrorNoTeb = modntdll.NewProc("RtlNtStatusToDosErrorNoTeb") procCLSIDFromString = modole32.NewProc("CLSIDFromString") procCoCreateGuid = modole32.NewProc("CoCreateGuid") procCoTaskMemFree = modole32.NewProc("CoTaskMemFree") @@ -2960,8 +2960,8 @@ func rtlGetVersion(info *OsVersionInfoEx) (ntstatus error) { return } -func rtlNtStatusToDosError(ntstatus NTStatus) (ret syscall.Errno) { - r0, _, _ := syscall.Syscall(procRtlNtStatusToDosError.Addr(), 1, uintptr(ntstatus), 0, 0) +func rtlNtStatusToDosErrorNoTeb(ntstatus NTStatus) (ret syscall.Errno) { + r0, _, _ := syscall.Syscall(procRtlNtStatusToDosErrorNoTeb.Addr(), 1, uintptr(ntstatus), 0, 0) ret = syscall.Errno(r0) return }