From ea4c425e90c70928be951f4eba8763495297e0a6 Mon Sep 17 00:00:00 2001 From: "Jason A. Donenfeld" Date: Sat, 25 May 2019 15:27:23 +0200 Subject: [PATCH] windows: allow Windows-style printf debugging via MessageBox I realize that at this time, x/sys/windows is most certainly not aiming to be some sort of UI library or anything remotely close to that. However, MessageBox is sort of the one universal Windows API that's used even for console programs. It's *the* classic debugging helper. It's even pretty customary for console programs to display their usage message in a message box rather than stdout. I realize this might be somewhat disturbing to consider if you're in the blissful Unix utopia, but on Windows, this is just sort of how things roll. Easy access to MessageBox() is important. Change-Id: I16183b69e8a27a5ddaf73d1d4e106bb7b201a6f0 Reviewed-on: https://go-review.googlesource.com/c/sys/+/178899 Run-TryBot: Jason Donenfeld TryBot-Result: Gobot Gobot Reviewed-by: Alex Brainman Reviewed-by: Brad Fitzpatrick --- windows/syscall_windows.go | 1 + windows/types_windows.go | 35 +++++++++++++++++++++++++++++++++++ windows/zsyscall_windows.go | 15 +++++++++++++++ 3 files changed, 51 insertions(+) diff --git a/windows/syscall_windows.go b/windows/syscall_windows.go index bba1e9e1..108760e4 100644 --- a/windows/syscall_windows.go +++ b/windows/syscall_windows.go @@ -278,6 +278,7 @@ func NewCallbackCDecl(fn interface{}) uintptr { //sys QueryDosDevice(deviceName *uint16, targetPath *uint16, max uint32) (n uint32, err error) [failretval==0] = QueryDosDeviceW //sys SetVolumeLabel(rootPathName *uint16, volumeName *uint16) (err error) = SetVolumeLabelW //sys SetVolumeMountPoint(volumeMountPoint *uint16, volumeName *uint16) (err error) = SetVolumeMountPointW +//sys MessageBox(hwnd Handle, text *uint16, caption *uint16, boxtype uint32) (ret int32, err error) [failretval==0] = user32.MessageBoxW // syscall interface implementation for other packages diff --git a/windows/types_windows.go b/windows/types_windows.go index ca799d5e..0661a493 100644 --- a/windows/types_windows.go +++ b/windows/types_windows.go @@ -1298,6 +1298,41 @@ const ( ComputerNameMax = 8 ) +// For MessageBox() +const ( + MB_OK = 0x00000000 + MB_OKCANCEL = 0x00000001 + MB_ABORTRETRYIGNORE = 0x00000002 + MB_YESNOCANCEL = 0x00000003 + MB_YESNO = 0x00000004 + MB_RETRYCANCEL = 0x00000005 + MB_CANCELTRYCONTINUE = 0x00000006 + MB_ICONHAND = 0x00000010 + MB_ICONQUESTION = 0x00000020 + MB_ICONEXCLAMATION = 0x00000030 + MB_ICONASTERISK = 0x00000040 + MB_USERICON = 0x00000080 + MB_ICONWARNING = MB_ICONEXCLAMATION + MB_ICONERROR = MB_ICONHAND + MB_ICONINFORMATION = MB_ICONASTERISK + MB_ICONSTOP = MB_ICONHAND + MB_DEFBUTTON1 = 0x00000000 + MB_DEFBUTTON2 = 0x00000100 + MB_DEFBUTTON3 = 0x00000200 + MB_DEFBUTTON4 = 0x00000300 + MB_APPLMODAL = 0x00000000 + MB_SYSTEMMODAL = 0x00001000 + MB_TASKMODAL = 0x00002000 + MB_HELP = 0x00004000 + MB_NOFOCUS = 0x00008000 + MB_SETFOREGROUND = 0x00010000 + MB_DEFAULT_DESKTOP_ONLY = 0x00020000 + MB_TOPMOST = 0x00040000 + MB_RIGHT = 0x00080000 + MB_RTLREADING = 0x00100000 + MB_SERVICE_NOTIFICATION = 0x00200000 +) + const ( MOVEFILE_REPLACE_EXISTING = 0x1 MOVEFILE_COPY_ALLOWED = 0x2 diff --git a/windows/zsyscall_windows.go b/windows/zsyscall_windows.go index 4f35a028..0de0de93 100644 --- a/windows/zsyscall_windows.go +++ b/windows/zsyscall_windows.go @@ -41,6 +41,7 @@ var ( moduserenv = NewLazySystemDLL("userenv.dll") modmswsock = NewLazySystemDLL("mswsock.dll") modcrypt32 = NewLazySystemDLL("crypt32.dll") + moduser32 = NewLazySystemDLL("user32.dll") modws2_32 = NewLazySystemDLL("ws2_32.dll") moddnsapi = NewLazySystemDLL("dnsapi.dll") modiphlpapi = NewLazySystemDLL("iphlpapi.dll") @@ -213,6 +214,7 @@ var ( procQueryDosDeviceW = modkernel32.NewProc("QueryDosDeviceW") procSetVolumeLabelW = modkernel32.NewProc("SetVolumeLabelW") procSetVolumeMountPointW = modkernel32.NewProc("SetVolumeMountPointW") + procMessageBoxW = moduser32.NewProc("MessageBoxW") procWSAStartup = modws2_32.NewProc("WSAStartup") procWSACleanup = modws2_32.NewProc("WSACleanup") procWSAIoctl = modws2_32.NewProc("WSAIoctl") @@ -2316,6 +2318,19 @@ func SetVolumeMountPoint(volumeMountPoint *uint16, volumeName *uint16) (err erro return } +func MessageBox(hwnd Handle, text *uint16, caption *uint16, boxtype uint32) (ret int32, err error) { + r0, _, e1 := syscall.Syscall6(procMessageBoxW.Addr(), 4, uintptr(hwnd), uintptr(unsafe.Pointer(text)), uintptr(unsafe.Pointer(caption)), uintptr(boxtype), 0, 0) + ret = int32(r0) + if ret == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + func WSAStartup(verreq uint32, data *WSAData) (sockerr error) { r0, _, _ := syscall.Syscall(procWSAStartup.Addr(), 2, uintptr(verreq), uintptr(unsafe.Pointer(data)), 0) if r0 != 0 {