Skip to content

Commit e883d00

Browse files
zx2c4bradfitz
authored andcommitted
cmd/link: do not generate NT 4 compatibility binaries
Incredibly, the subsystem version numbers in the PE header influence how win32k handles various syscalls. The first time a win32k syscall is invoked and the kernel upgrades the thread object to a tagTHREADINFO with all of the lovely undocumented UI members and such, it sets the dwExpWinVer member (offset 624 in Windows 10 build 1809) to the result of RtlGetExpWinVer(PsGetProcessSectionBaseAddress(proc)). RtlGetExpWinVer, also undocumented, then calls into the undocumented RtlImageNtHeader function, which returns a fortunately documented IMAGE_NT_HEADERS structure. It uses the subsystem members in there to set the dwExpWinVer member of our newly minted tagTHREADINFO object. Later, functions like SendInput consult this to vary their behaviors and return values. In fact, littered through out win32k are checks like `if (gsti->dwExpWinVer >= 0x501) { ... }`. I don't think Go ever supported NT 4.0. These days the minimum version is Windows 7, which is 6.1. So, let's set the version numbers in the PE header at that, which should give us the behavior that MSDN advertises for various functions, as opposed to bizarre archeological remnants. Interestingly, I suspect that most people never noticed the brokenness, because most people trying to do serious Win32 UI stuff wind up linking in cgo, if not for actually using C, then just to have a larger system stack so that the stack doesn't get corrupted by various UI functions. When MingW is used, the PE header gets a later version. But recently there's been a bug report of some people trying to do more modest UI manipulation using SendInput in a setting where this cgo hack probably isn't required, so they ran into the weird historical compatibility stuff. Fixes #31685 Change-Id: I54461ce820f6e9df349e37be5ecc5a44c04a3e26 Reviewed-on: https://go-review.googlesource.com/c/go/+/178977 Run-TryBot: Jason Donenfeld <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Alex Brainman <[email protected]> Reviewed-by: Brad Fitzpatrick <[email protected]>
1 parent e12efec commit e883d00

File tree

1 file changed

+8
-8
lines changed
  • src/cmd/link/internal/ld

1 file changed

+8
-8
lines changed

src/cmd/link/internal/ld/pe.go

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -833,18 +833,18 @@ func (f *peFile) writeOptionalHeader(ctxt *Link) {
833833
oh.SectionAlignment = uint32(PESECTALIGN)
834834
oh64.FileAlignment = uint32(PEFILEALIGN)
835835
oh.FileAlignment = uint32(PEFILEALIGN)
836-
oh64.MajorOperatingSystemVersion = 4
837-
oh.MajorOperatingSystemVersion = 4
838-
oh64.MinorOperatingSystemVersion = 0
839-
oh.MinorOperatingSystemVersion = 0
836+
oh64.MajorOperatingSystemVersion = 6
837+
oh.MajorOperatingSystemVersion = 6
838+
oh64.MinorOperatingSystemVersion = 1
839+
oh.MinorOperatingSystemVersion = 1
840840
oh64.MajorImageVersion = 1
841841
oh.MajorImageVersion = 1
842842
oh64.MinorImageVersion = 0
843843
oh.MinorImageVersion = 0
844-
oh64.MajorSubsystemVersion = 4
845-
oh.MajorSubsystemVersion = 4
846-
oh64.MinorSubsystemVersion = 0
847-
oh.MinorSubsystemVersion = 0
844+
oh64.MajorSubsystemVersion = 6
845+
oh.MajorSubsystemVersion = 6
846+
oh64.MinorSubsystemVersion = 1
847+
oh.MinorSubsystemVersion = 1
848848
oh64.SizeOfImage = f.nextSectOffset
849849
oh.SizeOfImage = f.nextSectOffset
850850
oh64.SizeOfHeaders = uint32(PEFILEHEADR)

0 commit comments

Comments
 (0)