From c5fe3670eff8ac030702959099505522aa7c0caa Mon Sep 17 00:00:00 2001 From: wwqgtxx Date: Wed, 15 Oct 2025 01:35:29 +0800 Subject: [PATCH] action: fix build --- .github/patch/go1.21.patch | 182 ++++++++++ .github/patch/go1.22.patch | 645 +++++++++++++++++++++++++++++++++++ .github/patch/go1.23.patch | 643 +++++++++++++++++++++++++++++++++++ .github/patch/go1.24.patch | 657 ++++++++++++++++++++++++++++++++++++ .github/patch/go1.25.patch | 657 ++++++++++++++++++++++++++++++++++++ .github/workflows/build.yml | 27 +- .github/workflows/test.yml | 84 +---- 7 files changed, 2792 insertions(+), 103 deletions(-) create mode 100644 .github/patch/go1.21.patch create mode 100644 .github/patch/go1.22.patch create mode 100644 .github/patch/go1.23.patch create mode 100644 .github/patch/go1.24.patch create mode 100644 .github/patch/go1.25.patch diff --git a/.github/patch/go1.21.patch b/.github/patch/go1.21.patch new file mode 100644 index 00000000..2ada7781 --- /dev/null +++ b/.github/patch/go1.21.patch @@ -0,0 +1,182 @@ +Subject: [PATCH] Revert "[release-branch.go1.21] crypto/rand,runtime: switch RtlGenRandom for ProcessPrng" +--- +Index: src/crypto/rand/rand.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/crypto/rand/rand.go b/src/crypto/rand/rand.go +--- a/src/crypto/rand/rand.go (revision 8bba868de983dd7bf55fcd121495ba8d6e2734e7) ++++ b/src/crypto/rand/rand.go (revision 7e6c963d81e14ee394402671d4044b2940c8d2c1) +@@ -15,7 +15,7 @@ + // available, /dev/urandom otherwise. + // On OpenBSD and macOS, Reader uses getentropy(2). + // On other Unix-like systems, Reader reads from /dev/urandom. +-// On Windows systems, Reader uses the ProcessPrng API. ++// On Windows systems, Reader uses the RtlGenRandom API. + // On JS/Wasm, Reader uses the Web Crypto API. + // On WASIP1/Wasm, Reader uses random_get from wasi_snapshot_preview1. + var Reader io.Reader +Index: src/crypto/rand/rand_windows.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/crypto/rand/rand_windows.go b/src/crypto/rand/rand_windows.go +--- a/src/crypto/rand/rand_windows.go (revision 8bba868de983dd7bf55fcd121495ba8d6e2734e7) ++++ b/src/crypto/rand/rand_windows.go (revision 7e6c963d81e14ee394402671d4044b2940c8d2c1) +@@ -15,8 +15,11 @@ + + type rngReader struct{} + +-func (r *rngReader) Read(b []byte) (int, error) { +- if err := windows.ProcessPrng(b); err != nil { ++func (r *rngReader) Read(b []byte) (n int, err error) { ++ // RtlGenRandom only returns 1<<32-1 bytes at a time. We only read at ++ // most 1<<31-1 bytes at a time so that this works the same on 32-bit ++ // and 64-bit systems. ++ if err := batched(windows.RtlGenRandom, 1<<31-1)(b); err != nil { + return 0, err + } + return len(b), nil +Index: src/internal/syscall/windows/syscall_windows.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/internal/syscall/windows/syscall_windows.go b/src/internal/syscall/windows/syscall_windows.go +--- a/src/internal/syscall/windows/syscall_windows.go (revision 8bba868de983dd7bf55fcd121495ba8d6e2734e7) ++++ b/src/internal/syscall/windows/syscall_windows.go (revision 7e6c963d81e14ee394402671d4044b2940c8d2c1) +@@ -384,7 +384,7 @@ + //sys DestroyEnvironmentBlock(block *uint16) (err error) = userenv.DestroyEnvironmentBlock + //sys CreateEvent(eventAttrs *SecurityAttributes, manualReset uint32, initialState uint32, name *uint16) (handle syscall.Handle, err error) = kernel32.CreateEventW + +-//sys ProcessPrng(buf []byte) (err error) = bcryptprimitives.ProcessPrng ++//sys RtlGenRandom(buf []byte) (err error) = advapi32.SystemFunction036 + + //sys RtlLookupFunctionEntry(pc uintptr, baseAddress *uintptr, table *byte) (ret uintptr) = kernel32.RtlLookupFunctionEntry + //sys RtlVirtualUnwind(handlerType uint32, baseAddress uintptr, pc uintptr, entry uintptr, ctxt uintptr, data *uintptr, frame *uintptr, ctxptrs *byte) (ret uintptr) = kernel32.RtlVirtualUnwind +Index: src/internal/syscall/windows/zsyscall_windows.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/internal/syscall/windows/zsyscall_windows.go b/src/internal/syscall/windows/zsyscall_windows.go +--- a/src/internal/syscall/windows/zsyscall_windows.go (revision 8bba868de983dd7bf55fcd121495ba8d6e2734e7) ++++ b/src/internal/syscall/windows/zsyscall_windows.go (revision 7e6c963d81e14ee394402671d4044b2940c8d2c1) +@@ -37,14 +37,13 @@ + } + + var ( +- modadvapi32 = syscall.NewLazyDLL(sysdll.Add("advapi32.dll")) +- modbcryptprimitives = syscall.NewLazyDLL(sysdll.Add("bcryptprimitives.dll")) +- modiphlpapi = syscall.NewLazyDLL(sysdll.Add("iphlpapi.dll")) +- modkernel32 = syscall.NewLazyDLL(sysdll.Add("kernel32.dll")) +- modnetapi32 = syscall.NewLazyDLL(sysdll.Add("netapi32.dll")) +- modpsapi = syscall.NewLazyDLL(sysdll.Add("psapi.dll")) +- moduserenv = syscall.NewLazyDLL(sysdll.Add("userenv.dll")) +- modws2_32 = syscall.NewLazyDLL(sysdll.Add("ws2_32.dll")) ++ modadvapi32 = syscall.NewLazyDLL(sysdll.Add("advapi32.dll")) ++ modiphlpapi = syscall.NewLazyDLL(sysdll.Add("iphlpapi.dll")) ++ modkernel32 = syscall.NewLazyDLL(sysdll.Add("kernel32.dll")) ++ modnetapi32 = syscall.NewLazyDLL(sysdll.Add("netapi32.dll")) ++ modpsapi = syscall.NewLazyDLL(sysdll.Add("psapi.dll")) ++ moduserenv = syscall.NewLazyDLL(sysdll.Add("userenv.dll")) ++ modws2_32 = syscall.NewLazyDLL(sysdll.Add("ws2_32.dll")) + + procAdjustTokenPrivileges = modadvapi32.NewProc("AdjustTokenPrivileges") + procDuplicateTokenEx = modadvapi32.NewProc("DuplicateTokenEx") +@@ -53,7 +52,7 @@ + procOpenThreadToken = modadvapi32.NewProc("OpenThreadToken") + procRevertToSelf = modadvapi32.NewProc("RevertToSelf") + procSetTokenInformation = modadvapi32.NewProc("SetTokenInformation") +- procProcessPrng = modbcryptprimitives.NewProc("ProcessPrng") ++ procSystemFunction036 = modadvapi32.NewProc("SystemFunction036") + procGetAdaptersAddresses = modiphlpapi.NewProc("GetAdaptersAddresses") + procCreateEventW = modkernel32.NewProc("CreateEventW") + procGetACP = modkernel32.NewProc("GetACP") +@@ -149,12 +148,12 @@ + return + } + +-func ProcessPrng(buf []byte) (err error) { ++func RtlGenRandom(buf []byte) (err error) { + var _p0 *byte + if len(buf) > 0 { + _p0 = &buf[0] + } +- r1, _, e1 := syscall.Syscall(procProcessPrng.Addr(), 2, uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), 0) ++ r1, _, e1 := syscall.Syscall(procSystemFunction036.Addr(), 2, uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), 0) + if r1 == 0 { + err = errnoErr(e1) + } +Index: src/runtime/os_windows.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/runtime/os_windows.go b/src/runtime/os_windows.go +--- a/src/runtime/os_windows.go (revision 8bba868de983dd7bf55fcd121495ba8d6e2734e7) ++++ b/src/runtime/os_windows.go (revision 7e6c963d81e14ee394402671d4044b2940c8d2c1) +@@ -127,8 +127,15 @@ + _AddVectoredContinueHandler, + _ stdFunction + +- // Use ProcessPrng to generate cryptographically random data. +- _ProcessPrng stdFunction ++ // Use RtlGenRandom to generate cryptographically random data. ++ // This approach has been recommended by Microsoft (see issue ++ // 15589 for details). ++ // The RtlGenRandom is not listed in advapi32.dll, instead ++ // RtlGenRandom function can be found by searching for SystemFunction036. ++ // Also some versions of Mingw cannot link to SystemFunction036 ++ // when building executable as Cgo. So load SystemFunction036 ++ // manually during runtime startup. ++ _RtlGenRandom stdFunction + + // Load ntdll.dll manually during startup, otherwise Mingw + // links wrong printf function to cgo executable (see issue +@@ -145,12 +152,12 @@ + ) + + var ( +- bcryptprimitivesdll = [...]uint16{'b', 'c', 'r', 'y', 'p', 't', 'p', 'r', 'i', 'm', 'i', 't', 'i', 'v', 'e', 's', '.', 'd', 'l', 'l', 0} +- kernel32dll = [...]uint16{'k', 'e', 'r', 'n', 'e', 'l', '3', '2', '.', 'd', 'l', 'l', 0} +- ntdlldll = [...]uint16{'n', 't', 'd', 'l', 'l', '.', 'd', 'l', 'l', 0} +- powrprofdll = [...]uint16{'p', 'o', 'w', 'r', 'p', 'r', 'o', 'f', '.', 'd', 'l', 'l', 0} +- winmmdll = [...]uint16{'w', 'i', 'n', 'm', 'm', '.', 'd', 'l', 'l', 0} +- ws2_32dll = [...]uint16{'w', 's', '2', '_', '3', '2', '.', 'd', 'l', 'l', 0} ++ advapi32dll = [...]uint16{'a', 'd', 'v', 'a', 'p', 'i', '3', '2', '.', 'd', 'l', 'l', 0} ++ kernel32dll = [...]uint16{'k', 'e', 'r', 'n', 'e', 'l', '3', '2', '.', 'd', 'l', 'l', 0} ++ ntdlldll = [...]uint16{'n', 't', 'd', 'l', 'l', '.', 'd', 'l', 'l', 0} ++ powrprofdll = [...]uint16{'p', 'o', 'w', 'r', 'p', 'r', 'o', 'f', '.', 'd', 'l', 'l', 0} ++ winmmdll = [...]uint16{'w', 'i', 'n', 'm', 'm', '.', 'd', 'l', 'l', 0} ++ ws2_32dll = [...]uint16{'w', 's', '2', '_', '3', '2', '.', 'd', 'l', 'l', 0} + ) + + // Function to be called by windows CreateThread +@@ -249,11 +256,11 @@ + } + _AddVectoredContinueHandler = windowsFindfunc(k32, []byte("AddVectoredContinueHandler\000")) + +- bcryptPrimitives := windowsLoadSystemLib(bcryptprimitivesdll[:]) +- if bcryptPrimitives == 0 { +- throw("bcryptprimitives.dll not found") ++ a32 := windowsLoadSystemLib(advapi32dll[:]) ++ if a32 == 0 { ++ throw("advapi32.dll not found") + } +- _ProcessPrng = windowsFindfunc(bcryptPrimitives, []byte("ProcessPrng\000")) ++ _RtlGenRandom = windowsFindfunc(a32, []byte("SystemFunction036\000")) + + n32 := windowsLoadSystemLib(ntdlldll[:]) + if n32 == 0 { +@@ -610,7 +617,7 @@ + //go:nosplit + func getRandomData(r []byte) { + n := 0 +- if stdcall2(_ProcessPrng, uintptr(unsafe.Pointer(&r[0])), uintptr(len(r)))&0xff != 0 { ++ if stdcall2(_RtlGenRandom, uintptr(unsafe.Pointer(&r[0])), uintptr(len(r)))&0xff != 0 { + n = len(r) + } + extendRandom(r, n) diff --git a/.github/patch/go1.22.patch b/.github/patch/go1.22.patch new file mode 100644 index 00000000..3c0c66e3 --- /dev/null +++ b/.github/patch/go1.22.patch @@ -0,0 +1,645 @@ +Subject: [PATCH] Revert "runtime: always use LoadLibraryEx to load system libraries" +Revert "syscall: remove Windows 7 console handle workaround" +Revert "net: remove sysSocket fallback for Windows 7" +Revert "crypto/rand,runtime: switch RtlGenRandom for ProcessPrng" +--- +Index: src/crypto/rand/rand.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/crypto/rand/rand.go b/src/crypto/rand/rand.go +--- a/src/crypto/rand/rand.go (revision cb4eee693c382bea4222f20837e26501d40ed892) ++++ b/src/crypto/rand/rand.go (revision 9779155f18b6556a034f7bb79fb7fb2aad1e26a9) +@@ -15,7 +15,7 @@ + // available, /dev/urandom otherwise. + // On OpenBSD and macOS, Reader uses getentropy(2). + // On other Unix-like systems, Reader reads from /dev/urandom. +-// On Windows systems, Reader uses the ProcessPrng API. ++// On Windows systems, Reader uses the RtlGenRandom API. + // On JS/Wasm, Reader uses the Web Crypto API. + // On WASIP1/Wasm, Reader uses random_get from wasi_snapshot_preview1. + var Reader io.Reader +Index: src/crypto/rand/rand_windows.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/crypto/rand/rand_windows.go b/src/crypto/rand/rand_windows.go +--- a/src/crypto/rand/rand_windows.go (revision cb4eee693c382bea4222f20837e26501d40ed892) ++++ b/src/crypto/rand/rand_windows.go (revision 9779155f18b6556a034f7bb79fb7fb2aad1e26a9) +@@ -15,8 +15,11 @@ + + type rngReader struct{} + +-func (r *rngReader) Read(b []byte) (int, error) { +- if err := windows.ProcessPrng(b); err != nil { ++func (r *rngReader) Read(b []byte) (n int, err error) { ++ // RtlGenRandom only returns 1<<32-1 bytes at a time. We only read at ++ // most 1<<31-1 bytes at a time so that this works the same on 32-bit ++ // and 64-bit systems. ++ if err := batched(windows.RtlGenRandom, 1<<31-1)(b); err != nil { + return 0, err + } + return len(b), nil +Index: src/internal/syscall/windows/syscall_windows.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/internal/syscall/windows/syscall_windows.go b/src/internal/syscall/windows/syscall_windows.go +--- a/src/internal/syscall/windows/syscall_windows.go (revision cb4eee693c382bea4222f20837e26501d40ed892) ++++ b/src/internal/syscall/windows/syscall_windows.go (revision 9779155f18b6556a034f7bb79fb7fb2aad1e26a9) +@@ -384,7 +384,7 @@ + //sys DestroyEnvironmentBlock(block *uint16) (err error) = userenv.DestroyEnvironmentBlock + //sys CreateEvent(eventAttrs *SecurityAttributes, manualReset uint32, initialState uint32, name *uint16) (handle syscall.Handle, err error) = kernel32.CreateEventW + +-//sys ProcessPrng(buf []byte) (err error) = bcryptprimitives.ProcessPrng ++//sys RtlGenRandom(buf []byte) (err error) = advapi32.SystemFunction036 + + type FILE_ID_BOTH_DIR_INFO struct { + NextEntryOffset uint32 +Index: src/internal/syscall/windows/zsyscall_windows.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/internal/syscall/windows/zsyscall_windows.go b/src/internal/syscall/windows/zsyscall_windows.go +--- a/src/internal/syscall/windows/zsyscall_windows.go (revision cb4eee693c382bea4222f20837e26501d40ed892) ++++ b/src/internal/syscall/windows/zsyscall_windows.go (revision 9779155f18b6556a034f7bb79fb7fb2aad1e26a9) +@@ -37,14 +37,13 @@ + } + + var ( +- modadvapi32 = syscall.NewLazyDLL(sysdll.Add("advapi32.dll")) +- modbcryptprimitives = syscall.NewLazyDLL(sysdll.Add("bcryptprimitives.dll")) +- modiphlpapi = syscall.NewLazyDLL(sysdll.Add("iphlpapi.dll")) +- modkernel32 = syscall.NewLazyDLL(sysdll.Add("kernel32.dll")) +- modnetapi32 = syscall.NewLazyDLL(sysdll.Add("netapi32.dll")) +- modpsapi = syscall.NewLazyDLL(sysdll.Add("psapi.dll")) +- moduserenv = syscall.NewLazyDLL(sysdll.Add("userenv.dll")) +- modws2_32 = syscall.NewLazyDLL(sysdll.Add("ws2_32.dll")) ++ modadvapi32 = syscall.NewLazyDLL(sysdll.Add("advapi32.dll")) ++ modiphlpapi = syscall.NewLazyDLL(sysdll.Add("iphlpapi.dll")) ++ modkernel32 = syscall.NewLazyDLL(sysdll.Add("kernel32.dll")) ++ modnetapi32 = syscall.NewLazyDLL(sysdll.Add("netapi32.dll")) ++ modpsapi = syscall.NewLazyDLL(sysdll.Add("psapi.dll")) ++ moduserenv = syscall.NewLazyDLL(sysdll.Add("userenv.dll")) ++ modws2_32 = syscall.NewLazyDLL(sysdll.Add("ws2_32.dll")) + + procAdjustTokenPrivileges = modadvapi32.NewProc("AdjustTokenPrivileges") + procDuplicateTokenEx = modadvapi32.NewProc("DuplicateTokenEx") +@@ -56,7 +55,7 @@ + procQueryServiceStatus = modadvapi32.NewProc("QueryServiceStatus") + procRevertToSelf = modadvapi32.NewProc("RevertToSelf") + procSetTokenInformation = modadvapi32.NewProc("SetTokenInformation") +- procProcessPrng = modbcryptprimitives.NewProc("ProcessPrng") ++ procSystemFunction036 = modadvapi32.NewProc("SystemFunction036") + procGetAdaptersAddresses = modiphlpapi.NewProc("GetAdaptersAddresses") + procCreateEventW = modkernel32.NewProc("CreateEventW") + procGetACP = modkernel32.NewProc("GetACP") +@@ -180,12 +179,12 @@ + return + } + +-func ProcessPrng(buf []byte) (err error) { ++func RtlGenRandom(buf []byte) (err error) { + var _p0 *byte + if len(buf) > 0 { + _p0 = &buf[0] + } +- r1, _, e1 := syscall.Syscall(procProcessPrng.Addr(), 2, uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), 0) ++ r1, _, e1 := syscall.Syscall(procSystemFunction036.Addr(), 2, uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), 0) + if r1 == 0 { + err = errnoErr(e1) + } +Index: src/runtime/os_windows.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/runtime/os_windows.go b/src/runtime/os_windows.go +--- a/src/runtime/os_windows.go (revision cb4eee693c382bea4222f20837e26501d40ed892) ++++ b/src/runtime/os_windows.go (revision 83ff9782e024cb328b690cbf0da4e7848a327f4f) +@@ -40,8 +40,8 @@ + //go:cgo_import_dynamic runtime._GetSystemInfo GetSystemInfo%1 "kernel32.dll" + //go:cgo_import_dynamic runtime._GetThreadContext GetThreadContext%2 "kernel32.dll" + //go:cgo_import_dynamic runtime._SetThreadContext SetThreadContext%2 "kernel32.dll" +-//go:cgo_import_dynamic runtime._LoadLibraryExW LoadLibraryExW%3 "kernel32.dll" + //go:cgo_import_dynamic runtime._LoadLibraryW LoadLibraryW%1 "kernel32.dll" ++//go:cgo_import_dynamic runtime._LoadLibraryA LoadLibraryA%1 "kernel32.dll" + //go:cgo_import_dynamic runtime._PostQueuedCompletionStatus PostQueuedCompletionStatus%4 "kernel32.dll" + //go:cgo_import_dynamic runtime._QueryPerformanceCounter QueryPerformanceCounter%1 "kernel32.dll" + //go:cgo_import_dynamic runtime._RaiseFailFastException RaiseFailFastException%3 "kernel32.dll" +@@ -74,7 +74,6 @@ + // Following syscalls are available on every Windows PC. + // All these variables are set by the Windows executable + // loader before the Go program starts. +- _AddVectoredContinueHandler, + _AddVectoredExceptionHandler, + _CloseHandle, + _CreateEventA, +@@ -98,8 +97,8 @@ + _GetSystemInfo, + _GetThreadContext, + _SetThreadContext, +- _LoadLibraryExW, + _LoadLibraryW, ++ _LoadLibraryA, + _PostQueuedCompletionStatus, + _QueryPerformanceCounter, + _RaiseFailFastException, +@@ -127,8 +126,23 @@ + _WriteFile, + _ stdFunction + +- // Use ProcessPrng to generate cryptographically random data. +- _ProcessPrng stdFunction ++ // Following syscalls are only available on some Windows PCs. ++ // We will load syscalls, if available, before using them. ++ _AddDllDirectory, ++ _AddVectoredContinueHandler, ++ _LoadLibraryExA, ++ _LoadLibraryExW, ++ _ stdFunction ++ ++ // Use RtlGenRandom to generate cryptographically random data. ++ // This approach has been recommended by Microsoft (see issue ++ // 15589 for details). ++ // The RtlGenRandom is not listed in advapi32.dll, instead ++ // RtlGenRandom function can be found by searching for SystemFunction036. ++ // Also some versions of Mingw cannot link to SystemFunction036 ++ // when building executable as Cgo. So load SystemFunction036 ++ // manually during runtime startup. ++ _RtlGenRandom stdFunction + + // Load ntdll.dll manually during startup, otherwise Mingw + // links wrong printf function to cgo executable (see issue +@@ -143,14 +157,6 @@ + _ stdFunction + ) + +-var ( +- bcryptprimitivesdll = [...]uint16{'b', 'c', 'r', 'y', 'p', 't', 'p', 'r', 'i', 'm', 'i', 't', 'i', 'v', 'e', 's', '.', 'd', 'l', 'l', 0} +- ntdlldll = [...]uint16{'n', 't', 'd', 'l', 'l', '.', 'd', 'l', 'l', 0} +- powrprofdll = [...]uint16{'p', 'o', 'w', 'r', 'p', 'r', 'o', 'f', '.', 'd', 'l', 'l', 0} +- winmmdll = [...]uint16{'w', 'i', 'n', 'm', 'm', '.', 'd', 'l', 'l', 0} +- ws2_32dll = [...]uint16{'w', 's', '2', '_', '3', '2', '.', 'd', 'l', 'l', 0} +-) +- + // Function to be called by windows CreateThread + // to start new os thread. + func tstart_stdcall(newm *m) +@@ -239,25 +245,51 @@ + return unsafe.String(&sysDirectory[0], sysDirectoryLen) + } + +-func windowsLoadSystemLib(name []uint16) uintptr { +- return stdcall3(_LoadLibraryExW, uintptr(unsafe.Pointer(&name[0])), 0, _LOAD_LIBRARY_SEARCH_SYSTEM32) ++//go:linkname syscall_getSystemDirectory syscall.getSystemDirectory ++func syscall_getSystemDirectory() string { ++ return unsafe.String(&sysDirectory[0], sysDirectoryLen) ++} ++ ++func windowsLoadSystemLib(name []byte) uintptr { ++ if useLoadLibraryEx { ++ return stdcall3(_LoadLibraryExA, uintptr(unsafe.Pointer(&name[0])), 0, _LOAD_LIBRARY_SEARCH_SYSTEM32) ++ } else { ++ absName := append(sysDirectory[:sysDirectoryLen], name...) ++ return stdcall1(_LoadLibraryA, uintptr(unsafe.Pointer(&absName[0]))) ++ } + } + + func loadOptionalSyscalls() { +- bcryptPrimitives := windowsLoadSystemLib(bcryptprimitivesdll[:]) +- if bcryptPrimitives == 0 { +- throw("bcryptprimitives.dll not found") ++ var kernel32dll = []byte("kernel32.dll\000") ++ k32 := stdcall1(_LoadLibraryA, uintptr(unsafe.Pointer(&kernel32dll[0]))) ++ if k32 == 0 { ++ throw("kernel32.dll not found") + } +- _ProcessPrng = windowsFindfunc(bcryptPrimitives, []byte("ProcessPrng\000")) ++ _AddDllDirectory = windowsFindfunc(k32, []byte("AddDllDirectory\000")) ++ _AddVectoredContinueHandler = windowsFindfunc(k32, []byte("AddVectoredContinueHandler\000")) ++ _LoadLibraryExA = windowsFindfunc(k32, []byte("LoadLibraryExA\000")) ++ _LoadLibraryExW = windowsFindfunc(k32, []byte("LoadLibraryExW\000")) ++ useLoadLibraryEx = (_LoadLibraryExW != nil && _LoadLibraryExA != nil && _AddDllDirectory != nil) ++ ++ initSysDirectory() + +- n32 := windowsLoadSystemLib(ntdlldll[:]) ++ var advapi32dll = []byte("advapi32.dll\000") ++ a32 := windowsLoadSystemLib(advapi32dll) ++ if a32 == 0 { ++ throw("advapi32.dll not found") ++ } ++ _RtlGenRandom = windowsFindfunc(a32, []byte("SystemFunction036\000")) ++ ++ var ntdll = []byte("ntdll.dll\000") ++ n32 := windowsLoadSystemLib(ntdll) + if n32 == 0 { + throw("ntdll.dll not found") + } + _RtlGetCurrentPeb = windowsFindfunc(n32, []byte("RtlGetCurrentPeb\000")) + _RtlGetNtVersionNumbers = windowsFindfunc(n32, []byte("RtlGetNtVersionNumbers\000")) + +- m32 := windowsLoadSystemLib(winmmdll[:]) ++ var winmmdll = []byte("winmm.dll\000") ++ m32 := windowsLoadSystemLib(winmmdll) + if m32 == 0 { + throw("winmm.dll not found") + } +@@ -267,7 +299,8 @@ + throw("timeBegin/EndPeriod not found") + } + +- ws232 := windowsLoadSystemLib(ws2_32dll[:]) ++ var ws232dll = []byte("ws2_32.dll\000") ++ ws232 := windowsLoadSystemLib(ws232dll) + if ws232 == 0 { + throw("ws2_32.dll not found") + } +@@ -286,7 +319,7 @@ + context uintptr + } + +- powrprof := windowsLoadSystemLib(powrprofdll[:]) ++ powrprof := windowsLoadSystemLib([]byte("powrprof.dll\000")) + if powrprof == 0 { + return // Running on Windows 7, where we don't need it anyway. + } +@@ -360,6 +393,22 @@ + // in sys_windows_386.s and sys_windows_amd64.s: + func getlasterror() uint32 + ++// When loading DLLs, we prefer to use LoadLibraryEx with ++// LOAD_LIBRARY_SEARCH_* flags, if available. LoadLibraryEx is not ++// available on old Windows, though, and the LOAD_LIBRARY_SEARCH_* ++// flags are not available on some versions of Windows without a ++// security patch. ++// ++// https://msdn.microsoft.com/en-us/library/ms684179(v=vs.85).aspx says: ++// "Windows 7, Windows Server 2008 R2, Windows Vista, and Windows ++// Server 2008: The LOAD_LIBRARY_SEARCH_* flags are available on ++// systems that have KB2533623 installed. To determine whether the ++// flags are available, use GetProcAddress to get the address of the ++// AddDllDirectory, RemoveDllDirectory, or SetDefaultDllDirectories ++// function. If GetProcAddress succeeds, the LOAD_LIBRARY_SEARCH_* ++// flags can be used with LoadLibraryEx." ++var useLoadLibraryEx bool ++ + var timeBeginPeriodRetValue uint32 + + // osRelaxMinNS indicates that sysmon shouldn't osRelax if the next +@@ -507,7 +556,6 @@ + initHighResTimer() + timeBeginPeriodRetValue = osRelax(false) + +- initSysDirectory() + initLongPathSupport() + + ncpu = getproccount() +@@ -524,7 +572,7 @@ + //go:nosplit + func readRandom(r []byte) int { + n := 0 +- if stdcall2(_ProcessPrng, uintptr(unsafe.Pointer(&r[0])), uintptr(len(r)))&0xff != 0 { ++ if stdcall2(_RtlGenRandom, uintptr(unsafe.Pointer(&r[0])), uintptr(len(r)))&0xff != 0 { + n = len(r) + } + return n +Index: src/net/hook_windows.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/net/hook_windows.go b/src/net/hook_windows.go +--- a/src/net/hook_windows.go (revision 9779155f18b6556a034f7bb79fb7fb2aad1e26a9) ++++ b/src/net/hook_windows.go (revision ef0606261340e608017860b423ffae5c1ce78239) +@@ -13,6 +13,7 @@ + hostsFilePath = windows.GetSystemDirectory() + "/Drivers/etc/hosts" + + // Placeholders for socket system calls. ++ socketFunc func(int, int, int) (syscall.Handle, error) = syscall.Socket + wsaSocketFunc func(int32, int32, int32, *syscall.WSAProtocolInfo, uint32, uint32) (syscall.Handle, error) = windows.WSASocket + connectFunc func(syscall.Handle, syscall.Sockaddr) error = syscall.Connect + listenFunc func(syscall.Handle, int) error = syscall.Listen +Index: src/net/internal/socktest/main_test.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/net/internal/socktest/main_test.go b/src/net/internal/socktest/main_test.go +--- a/src/net/internal/socktest/main_test.go (revision 9779155f18b6556a034f7bb79fb7fb2aad1e26a9) ++++ b/src/net/internal/socktest/main_test.go (revision ef0606261340e608017860b423ffae5c1ce78239) +@@ -2,7 +2,7 @@ + // Use of this source code is governed by a BSD-style + // license that can be found in the LICENSE file. + +-//go:build !js && !plan9 && !wasip1 && !windows ++//go:build !js && !plan9 && !wasip1 + + package socktest_test + +Index: src/net/internal/socktest/main_windows_test.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/net/internal/socktest/main_windows_test.go b/src/net/internal/socktest/main_windows_test.go +new file mode 100644 +--- /dev/null (revision ef0606261340e608017860b423ffae5c1ce78239) ++++ b/src/net/internal/socktest/main_windows_test.go (revision ef0606261340e608017860b423ffae5c1ce78239) +@@ -0,0 +1,22 @@ ++// Copyright 2015 The Go Authors. All rights reserved. ++// Use of this source code is governed by a BSD-style ++// license that can be found in the LICENSE file. ++ ++package socktest_test ++ ++import "syscall" ++ ++var ( ++ socketFunc func(int, int, int) (syscall.Handle, error) ++ closeFunc func(syscall.Handle) error ++) ++ ++func installTestHooks() { ++ socketFunc = sw.Socket ++ closeFunc = sw.Closesocket ++} ++ ++func uninstallTestHooks() { ++ socketFunc = syscall.Socket ++ closeFunc = syscall.Closesocket ++} +Index: src/net/internal/socktest/sys_windows.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/net/internal/socktest/sys_windows.go b/src/net/internal/socktest/sys_windows.go +--- a/src/net/internal/socktest/sys_windows.go (revision 9779155f18b6556a034f7bb79fb7fb2aad1e26a9) ++++ b/src/net/internal/socktest/sys_windows.go (revision ef0606261340e608017860b423ffae5c1ce78239) +@@ -9,6 +9,38 @@ + "syscall" + ) + ++// Socket wraps [syscall.Socket]. ++func (sw *Switch) Socket(family, sotype, proto int) (s syscall.Handle, err error) { ++ sw.once.Do(sw.init) ++ ++ so := &Status{Cookie: cookie(family, sotype, proto)} ++ sw.fmu.RLock() ++ f, _ := sw.fltab[FilterSocket] ++ sw.fmu.RUnlock() ++ ++ af, err := f.apply(so) ++ if err != nil { ++ return syscall.InvalidHandle, err ++ } ++ s, so.Err = syscall.Socket(family, sotype, proto) ++ if err = af.apply(so); err != nil { ++ if so.Err == nil { ++ syscall.Closesocket(s) ++ } ++ return syscall.InvalidHandle, err ++ } ++ ++ sw.smu.Lock() ++ defer sw.smu.Unlock() ++ if so.Err != nil { ++ sw.stats.getLocked(so.Cookie).OpenFailed++ ++ return syscall.InvalidHandle, so.Err ++ } ++ nso := sw.addLocked(s, family, sotype, proto) ++ sw.stats.getLocked(nso.Cookie).Opened++ ++ return s, nil ++} ++ + // WSASocket wraps [syscall.WSASocket]. + func (sw *Switch) WSASocket(family, sotype, proto int32, protinfo *syscall.WSAProtocolInfo, group uint32, flags uint32) (s syscall.Handle, err error) { + sw.once.Do(sw.init) +Index: src/net/main_windows_test.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/net/main_windows_test.go b/src/net/main_windows_test.go +--- a/src/net/main_windows_test.go (revision 9779155f18b6556a034f7bb79fb7fb2aad1e26a9) ++++ b/src/net/main_windows_test.go (revision ef0606261340e608017860b423ffae5c1ce78239) +@@ -8,6 +8,7 @@ + + var ( + // Placeholders for saving original socket system calls. ++ origSocket = socketFunc + origWSASocket = wsaSocketFunc + origClosesocket = poll.CloseFunc + origConnect = connectFunc +@@ -17,6 +18,7 @@ + ) + + func installTestHooks() { ++ socketFunc = sw.Socket + wsaSocketFunc = sw.WSASocket + poll.CloseFunc = sw.Closesocket + connectFunc = sw.Connect +@@ -26,6 +28,7 @@ + } + + func uninstallTestHooks() { ++ socketFunc = origSocket + wsaSocketFunc = origWSASocket + poll.CloseFunc = origClosesocket + connectFunc = origConnect +Index: src/net/sock_windows.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/net/sock_windows.go b/src/net/sock_windows.go +--- a/src/net/sock_windows.go (revision 9779155f18b6556a034f7bb79fb7fb2aad1e26a9) ++++ b/src/net/sock_windows.go (revision ef0606261340e608017860b423ffae5c1ce78239) +@@ -20,6 +20,21 @@ + func sysSocket(family, sotype, proto int) (syscall.Handle, error) { + s, err := wsaSocketFunc(int32(family), int32(sotype), int32(proto), + nil, 0, windows.WSA_FLAG_OVERLAPPED|windows.WSA_FLAG_NO_HANDLE_INHERIT) ++ if err == nil { ++ return s, nil ++ } ++ // WSA_FLAG_NO_HANDLE_INHERIT flag is not supported on some ++ // old versions of Windows, see ++ // https://msdn.microsoft.com/en-us/library/windows/desktop/ms742212(v=vs.85).aspx ++ // for details. Just use syscall.Socket, if windows.WSASocket failed. ++ ++ // See ../syscall/exec_unix.go for description of ForkLock. ++ syscall.ForkLock.RLock() ++ s, err = socketFunc(family, sotype, proto) ++ if err == nil { ++ syscall.CloseOnExec(s) ++ } ++ syscall.ForkLock.RUnlock() + if err != nil { + return syscall.InvalidHandle, os.NewSyscallError("socket", err) + } +Index: src/syscall/exec_windows.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/syscall/exec_windows.go b/src/syscall/exec_windows.go +--- a/src/syscall/exec_windows.go (revision 9779155f18b6556a034f7bb79fb7fb2aad1e26a9) ++++ b/src/syscall/exec_windows.go (revision 7f83badcb925a7e743188041cb6e561fc9b5b642) +@@ -14,7 +14,6 @@ + "unsafe" + ) + +-// ForkLock is not used on Windows. + var ForkLock sync.RWMutex + + // EscapeArg rewrites command line argument s as prescribed +@@ -317,6 +316,17 @@ + } + } + ++ var maj, min, build uint32 ++ rtlGetNtVersionNumbers(&maj, &min, &build) ++ isWin7 := maj < 6 || (maj == 6 && min <= 1) ++ // NT kernel handles are divisible by 4, with the bottom 3 bits left as ++ // a tag. The fully set tag correlates with the types of handles we're ++ // concerned about here. Except, the kernel will interpret some ++ // special handle values, like -1, -2, and so forth, so kernelbase.dll ++ // checks to see that those bottom three bits are checked, but that top ++ // bit is not checked. ++ isLegacyWin7ConsoleHandle := func(handle Handle) bool { return isWin7 && handle&0x10000003 == 3 } ++ + p, _ := GetCurrentProcess() + parentProcess := p + if sys.ParentProcess != 0 { +@@ -325,7 +335,15 @@ + fd := make([]Handle, len(attr.Files)) + for i := range attr.Files { + if attr.Files[i] > 0 { +- err := DuplicateHandle(p, Handle(attr.Files[i]), parentProcess, &fd[i], 0, true, DUPLICATE_SAME_ACCESS) ++ destinationProcessHandle := parentProcess ++ ++ // On Windows 7, console handles aren't real handles, and can only be duplicated ++ // into the current process, not a parent one, which amounts to the same thing. ++ if parentProcess != p && isLegacyWin7ConsoleHandle(Handle(attr.Files[i])) { ++ destinationProcessHandle = p ++ } ++ ++ err := DuplicateHandle(p, Handle(attr.Files[i]), destinationProcessHandle, &fd[i], 0, true, DUPLICATE_SAME_ACCESS) + if err != nil { + return 0, 0, err + } +@@ -356,6 +374,14 @@ + + fd = append(fd, sys.AdditionalInheritedHandles...) + ++ // On Windows 7, console handles aren't real handles, so don't pass them ++ // through to PROC_THREAD_ATTRIBUTE_HANDLE_LIST. ++ for i := range fd { ++ if isLegacyWin7ConsoleHandle(fd[i]) { ++ fd[i] = 0 ++ } ++ } ++ + // The presence of a NULL handle in the list is enough to cause PROC_THREAD_ATTRIBUTE_HANDLE_LIST + // to treat the entire list as empty, so remove NULL handles. + j := 0 +Index: src/runtime/syscall_windows.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/runtime/syscall_windows.go b/src/runtime/syscall_windows.go +--- a/src/runtime/syscall_windows.go (revision 7f83badcb925a7e743188041cb6e561fc9b5b642) ++++ b/src/runtime/syscall_windows.go (revision 83ff9782e024cb328b690cbf0da4e7848a327f4f) +@@ -413,23 +413,36 @@ + + const _LOAD_LIBRARY_SEARCH_SYSTEM32 = 0x00000800 + ++// When available, this function will use LoadLibraryEx with the filename ++// parameter and the important SEARCH_SYSTEM32 argument. But on systems that ++// do not have that option, absoluteFilepath should contain a fallback ++// to the full path inside of system32 for use with vanilla LoadLibrary. ++// + //go:linkname syscall_loadsystemlibrary syscall.loadsystemlibrary + //go:nosplit + //go:cgo_unsafe_args +-func syscall_loadsystemlibrary(filename *uint16) (handle, err uintptr) { ++func syscall_loadsystemlibrary(filename *uint16, absoluteFilepath *uint16) (handle, err uintptr) { + lockOSThread() + c := &getg().m.syscall +- c.fn = getLoadLibraryEx() +- c.n = 3 +- args := struct { +- lpFileName *uint16 +- hFile uintptr // always 0 +- flags uint32 +- }{filename, 0, _LOAD_LIBRARY_SEARCH_SYSTEM32} +- c.args = uintptr(noescape(unsafe.Pointer(&args))) ++ ++ if useLoadLibraryEx { ++ c.fn = getLoadLibraryEx() ++ c.n = 3 ++ args := struct { ++ lpFileName *uint16 ++ hFile uintptr // always 0 ++ flags uint32 ++ }{filename, 0, _LOAD_LIBRARY_SEARCH_SYSTEM32} ++ c.args = uintptr(noescape(unsafe.Pointer(&args))) ++ } else { ++ c.fn = getLoadLibrary() ++ c.n = 1 ++ c.args = uintptr(noescape(unsafe.Pointer(&absoluteFilepath))) ++ } + + cgocall(asmstdcallAddr, unsafe.Pointer(c)) + KeepAlive(filename) ++ KeepAlive(absoluteFilepath) + handle = c.r1 + if handle == 0 { + err = c.err +Index: src/syscall/dll_windows.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/syscall/dll_windows.go b/src/syscall/dll_windows.go +--- a/src/syscall/dll_windows.go (revision 7f83badcb925a7e743188041cb6e561fc9b5b642) ++++ b/src/syscall/dll_windows.go (revision 83ff9782e024cb328b690cbf0da4e7848a327f4f) +@@ -44,7 +44,7 @@ + + func SyscallN(trap uintptr, args ...uintptr) (r1, r2 uintptr, err Errno) + func loadlibrary(filename *uint16) (handle uintptr, err Errno) +-func loadsystemlibrary(filename *uint16) (handle uintptr, err Errno) ++func loadsystemlibrary(filename *uint16, absoluteFilepath *uint16) (handle uintptr, err Errno) + func getprocaddress(handle uintptr, procname *uint8) (proc uintptr, err Errno) + + // A DLL implements access to a single DLL. +@@ -53,6 +53,9 @@ + Handle Handle + } + ++//go:linkname getSystemDirectory ++func getSystemDirectory() string // Implemented in runtime package. ++ + // LoadDLL loads the named DLL file into memory. + // + // If name is not an absolute path and is not a known system DLL used by +@@ -69,7 +72,11 @@ + var h uintptr + var e Errno + if sysdll.IsSystemDLL[name] { +- h, e = loadsystemlibrary(namep) ++ absoluteFilepathp, err := UTF16PtrFromString(getSystemDirectory() + name) ++ if err != nil { ++ return nil, err ++ } ++ h, e = loadsystemlibrary(namep, absoluteFilepathp) + } else { + h, e = loadlibrary(namep) + } diff --git a/.github/patch/go1.23.patch b/.github/patch/go1.23.patch new file mode 100644 index 00000000..e8597548 --- /dev/null +++ b/.github/patch/go1.23.patch @@ -0,0 +1,643 @@ +Subject: [PATCH] Revert "runtime: always use LoadLibraryEx to load system libraries" +Revert "syscall: remove Windows 7 console handle workaround" +Revert "net: remove sysSocket fallback for Windows 7" +Revert "crypto/rand,runtime: switch RtlGenRandom for ProcessPrng" +--- +Index: src/crypto/rand/rand.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/crypto/rand/rand.go b/src/crypto/rand/rand.go +--- a/src/crypto/rand/rand.go (revision 6885bad7dd86880be6929c02085e5c7a67ff2887) ++++ b/src/crypto/rand/rand.go (revision 9ac42137ef6730e8b7daca016ece831297a1d75b) +@@ -16,7 +16,7 @@ + // - On macOS and iOS, Reader uses arc4random_buf(3). + // - On OpenBSD and NetBSD, Reader uses getentropy(2). + // - On other Unix-like systems, Reader reads from /dev/urandom. +-// - On Windows, Reader uses the ProcessPrng API. ++// - On Windows systems, Reader uses the RtlGenRandom API. + // - On js/wasm, Reader uses the Web Crypto API. + // - On wasip1/wasm, Reader uses random_get from wasi_snapshot_preview1. + var Reader io.Reader +Index: src/crypto/rand/rand_windows.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/crypto/rand/rand_windows.go b/src/crypto/rand/rand_windows.go +--- a/src/crypto/rand/rand_windows.go (revision 6885bad7dd86880be6929c02085e5c7a67ff2887) ++++ b/src/crypto/rand/rand_windows.go (revision 9ac42137ef6730e8b7daca016ece831297a1d75b) +@@ -15,8 +15,11 @@ + + type rngReader struct{} + +-func (r *rngReader) Read(b []byte) (int, error) { +- if err := windows.ProcessPrng(b); err != nil { ++func (r *rngReader) Read(b []byte) (n int, err error) { ++ // RtlGenRandom only returns 1<<32-1 bytes at a time. We only read at ++ // most 1<<31-1 bytes at a time so that this works the same on 32-bit ++ // and 64-bit systems. ++ if err := batched(windows.RtlGenRandom, 1<<31-1)(b); err != nil { + return 0, err + } + return len(b), nil +Index: src/internal/syscall/windows/syscall_windows.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/internal/syscall/windows/syscall_windows.go b/src/internal/syscall/windows/syscall_windows.go +--- a/src/internal/syscall/windows/syscall_windows.go (revision 6885bad7dd86880be6929c02085e5c7a67ff2887) ++++ b/src/internal/syscall/windows/syscall_windows.go (revision 9ac42137ef6730e8b7daca016ece831297a1d75b) +@@ -414,7 +414,7 @@ + //sys DestroyEnvironmentBlock(block *uint16) (err error) = userenv.DestroyEnvironmentBlock + //sys CreateEvent(eventAttrs *SecurityAttributes, manualReset uint32, initialState uint32, name *uint16) (handle syscall.Handle, err error) = kernel32.CreateEventW + +-//sys ProcessPrng(buf []byte) (err error) = bcryptprimitives.ProcessPrng ++//sys RtlGenRandom(buf []byte) (err error) = advapi32.SystemFunction036 + + type FILE_ID_BOTH_DIR_INFO struct { + NextEntryOffset uint32 +Index: src/internal/syscall/windows/zsyscall_windows.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/internal/syscall/windows/zsyscall_windows.go b/src/internal/syscall/windows/zsyscall_windows.go +--- a/src/internal/syscall/windows/zsyscall_windows.go (revision 6885bad7dd86880be6929c02085e5c7a67ff2887) ++++ b/src/internal/syscall/windows/zsyscall_windows.go (revision 9ac42137ef6730e8b7daca016ece831297a1d75b) +@@ -38,7 +38,6 @@ + + var ( + modadvapi32 = syscall.NewLazyDLL(sysdll.Add("advapi32.dll")) +- modbcryptprimitives = syscall.NewLazyDLL(sysdll.Add("bcryptprimitives.dll")) + modiphlpapi = syscall.NewLazyDLL(sysdll.Add("iphlpapi.dll")) + modkernel32 = syscall.NewLazyDLL(sysdll.Add("kernel32.dll")) + modnetapi32 = syscall.NewLazyDLL(sysdll.Add("netapi32.dll")) +@@ -57,7 +56,7 @@ + procQueryServiceStatus = modadvapi32.NewProc("QueryServiceStatus") + procRevertToSelf = modadvapi32.NewProc("RevertToSelf") + procSetTokenInformation = modadvapi32.NewProc("SetTokenInformation") +- procProcessPrng = modbcryptprimitives.NewProc("ProcessPrng") ++ procSystemFunction036 = modadvapi32.NewProc("SystemFunction036") + procGetAdaptersAddresses = modiphlpapi.NewProc("GetAdaptersAddresses") + procCreateEventW = modkernel32.NewProc("CreateEventW") + procGetACP = modkernel32.NewProc("GetACP") +@@ -183,12 +182,12 @@ + return + } + +-func ProcessPrng(buf []byte) (err error) { ++func RtlGenRandom(buf []byte) (err error) { + var _p0 *byte + if len(buf) > 0 { + _p0 = &buf[0] + } +- r1, _, e1 := syscall.Syscall(procProcessPrng.Addr(), 2, uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), 0) ++ r1, _, e1 := syscall.Syscall(procSystemFunction036.Addr(), 2, uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), 0) + if r1 == 0 { + err = errnoErr(e1) + } +Index: src/runtime/os_windows.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/runtime/os_windows.go b/src/runtime/os_windows.go +--- a/src/runtime/os_windows.go (revision 6885bad7dd86880be6929c02085e5c7a67ff2887) ++++ b/src/runtime/os_windows.go (revision 69e2eed6dd0f6d815ebf15797761c13f31213dd6) +@@ -39,8 +39,8 @@ + //go:cgo_import_dynamic runtime._GetSystemInfo GetSystemInfo%1 "kernel32.dll" + //go:cgo_import_dynamic runtime._GetThreadContext GetThreadContext%2 "kernel32.dll" + //go:cgo_import_dynamic runtime._SetThreadContext SetThreadContext%2 "kernel32.dll" +-//go:cgo_import_dynamic runtime._LoadLibraryExW LoadLibraryExW%3 "kernel32.dll" + //go:cgo_import_dynamic runtime._LoadLibraryW LoadLibraryW%1 "kernel32.dll" ++//go:cgo_import_dynamic runtime._LoadLibraryA LoadLibraryA%1 "kernel32.dll" + //go:cgo_import_dynamic runtime._PostQueuedCompletionStatus PostQueuedCompletionStatus%4 "kernel32.dll" + //go:cgo_import_dynamic runtime._QueryPerformanceCounter QueryPerformanceCounter%1 "kernel32.dll" + //go:cgo_import_dynamic runtime._QueryPerformanceFrequency QueryPerformanceFrequency%1 "kernel32.dll" +@@ -74,7 +74,6 @@ + // Following syscalls are available on every Windows PC. + // All these variables are set by the Windows executable + // loader before the Go program starts. +- _AddVectoredContinueHandler, + _AddVectoredExceptionHandler, + _CloseHandle, + _CreateEventA, +@@ -97,8 +96,8 @@ + _GetSystemInfo, + _GetThreadContext, + _SetThreadContext, +- _LoadLibraryExW, + _LoadLibraryW, ++ _LoadLibraryA, + _PostQueuedCompletionStatus, + _QueryPerformanceCounter, + _QueryPerformanceFrequency, +@@ -127,8 +126,23 @@ + _WriteFile, + _ stdFunction + +- // Use ProcessPrng to generate cryptographically random data. +- _ProcessPrng stdFunction ++ // Following syscalls are only available on some Windows PCs. ++ // We will load syscalls, if available, before using them. ++ _AddDllDirectory, ++ _AddVectoredContinueHandler, ++ _LoadLibraryExA, ++ _LoadLibraryExW, ++ _ stdFunction ++ ++ // Use RtlGenRandom to generate cryptographically random data. ++ // This approach has been recommended by Microsoft (see issue ++ // 15589 for details). ++ // The RtlGenRandom is not listed in advapi32.dll, instead ++ // RtlGenRandom function can be found by searching for SystemFunction036. ++ // Also some versions of Mingw cannot link to SystemFunction036 ++ // when building executable as Cgo. So load SystemFunction036 ++ // manually during runtime startup. ++ _RtlGenRandom stdFunction + + // Load ntdll.dll manually during startup, otherwise Mingw + // links wrong printf function to cgo executable (see issue +@@ -145,13 +159,6 @@ + _ stdFunction + ) + +-var ( +- bcryptprimitivesdll = [...]uint16{'b', 'c', 'r', 'y', 'p', 't', 'p', 'r', 'i', 'm', 'i', 't', 'i', 'v', 'e', 's', '.', 'd', 'l', 'l', 0} +- ntdlldll = [...]uint16{'n', 't', 'd', 'l', 'l', '.', 'd', 'l', 'l', 0} +- powrprofdll = [...]uint16{'p', 'o', 'w', 'r', 'p', 'r', 'o', 'f', '.', 'd', 'l', 'l', 0} +- winmmdll = [...]uint16{'w', 'i', 'n', 'm', 'm', '.', 'd', 'l', 'l', 0} +-) +- + // Function to be called by windows CreateThread + // to start new os thread. + func tstart_stdcall(newm *m) +@@ -244,8 +251,18 @@ + return unsafe.String(&sysDirectory[0], sysDirectoryLen) + } + +-func windowsLoadSystemLib(name []uint16) uintptr { +- return stdcall3(_LoadLibraryExW, uintptr(unsafe.Pointer(&name[0])), 0, _LOAD_LIBRARY_SEARCH_SYSTEM32) ++//go:linkname syscall_getSystemDirectory syscall.getSystemDirectory ++func syscall_getSystemDirectory() string { ++ return unsafe.String(&sysDirectory[0], sysDirectoryLen) ++} ++ ++func windowsLoadSystemLib(name []byte) uintptr { ++ if useLoadLibraryEx { ++ return stdcall3(_LoadLibraryExA, uintptr(unsafe.Pointer(&name[0])), 0, _LOAD_LIBRARY_SEARCH_SYSTEM32) ++ } else { ++ absName := append(sysDirectory[:sysDirectoryLen], name...) ++ return stdcall1(_LoadLibraryA, uintptr(unsafe.Pointer(&absName[0]))) ++ } + } + + //go:linkname windows_QueryPerformanceCounter internal/syscall/windows.QueryPerformanceCounter +@@ -263,13 +280,28 @@ + } + + func loadOptionalSyscalls() { +- bcryptPrimitives := windowsLoadSystemLib(bcryptprimitivesdll[:]) +- if bcryptPrimitives == 0 { +- throw("bcryptprimitives.dll not found") ++ var kernel32dll = []byte("kernel32.dll\000") ++ k32 := stdcall1(_LoadLibraryA, uintptr(unsafe.Pointer(&kernel32dll[0]))) ++ if k32 == 0 { ++ throw("kernel32.dll not found") + } +- _ProcessPrng = windowsFindfunc(bcryptPrimitives, []byte("ProcessPrng\000")) ++ _AddDllDirectory = windowsFindfunc(k32, []byte("AddDllDirectory\000")) ++ _AddVectoredContinueHandler = windowsFindfunc(k32, []byte("AddVectoredContinueHandler\000")) ++ _LoadLibraryExA = windowsFindfunc(k32, []byte("LoadLibraryExA\000")) ++ _LoadLibraryExW = windowsFindfunc(k32, []byte("LoadLibraryExW\000")) ++ useLoadLibraryEx = (_LoadLibraryExW != nil && _LoadLibraryExA != nil && _AddDllDirectory != nil) ++ ++ initSysDirectory() + +- n32 := windowsLoadSystemLib(ntdlldll[:]) ++ var advapi32dll = []byte("advapi32.dll\000") ++ a32 := windowsLoadSystemLib(advapi32dll) ++ if a32 == 0 { ++ throw("advapi32.dll not found") ++ } ++ _RtlGenRandom = windowsFindfunc(a32, []byte("SystemFunction036\000")) ++ ++ var ntdll = []byte("ntdll.dll\000") ++ n32 := windowsLoadSystemLib(ntdll) + if n32 == 0 { + throw("ntdll.dll not found") + } +@@ -298,7 +330,7 @@ + context uintptr + } + +- powrprof := windowsLoadSystemLib(powrprofdll[:]) ++ powrprof := windowsLoadSystemLib([]byte("powrprof.dll\000")) + if powrprof == 0 { + return // Running on Windows 7, where we don't need it anyway. + } +@@ -357,6 +389,22 @@ + // in sys_windows_386.s and sys_windows_amd64.s: + func getlasterror() uint32 + ++// When loading DLLs, we prefer to use LoadLibraryEx with ++// LOAD_LIBRARY_SEARCH_* flags, if available. LoadLibraryEx is not ++// available on old Windows, though, and the LOAD_LIBRARY_SEARCH_* ++// flags are not available on some versions of Windows without a ++// security patch. ++// ++// https://msdn.microsoft.com/en-us/library/ms684179(v=vs.85).aspx says: ++// "Windows 7, Windows Server 2008 R2, Windows Vista, and Windows ++// Server 2008: The LOAD_LIBRARY_SEARCH_* flags are available on ++// systems that have KB2533623 installed. To determine whether the ++// flags are available, use GetProcAddress to get the address of the ++// AddDllDirectory, RemoveDllDirectory, or SetDefaultDllDirectories ++// function. If GetProcAddress succeeds, the LOAD_LIBRARY_SEARCH_* ++// flags can be used with LoadLibraryEx." ++var useLoadLibraryEx bool ++ + var timeBeginPeriodRetValue uint32 + + // osRelaxMinNS indicates that sysmon shouldn't osRelax if the next +@@ -430,7 +478,8 @@ + // Only load winmm.dll if we need it. + // This avoids a dependency on winmm.dll for Go programs + // that run on new Windows versions. +- m32 := windowsLoadSystemLib(winmmdll[:]) ++ var winmmdll = []byte("winmm.dll\000") ++ m32 := windowsLoadSystemLib(winmmdll) + if m32 == 0 { + print("runtime: LoadLibraryExW failed; errno=", getlasterror(), "\n") + throw("winmm.dll not found") +@@ -471,6 +520,28 @@ + canUseLongPaths = true + } + ++var osVersionInfo struct { ++ majorVersion uint32 ++ minorVersion uint32 ++ buildNumber uint32 ++} ++ ++func initOsVersionInfo() { ++ info := _OSVERSIONINFOW{} ++ info.osVersionInfoSize = uint32(unsafe.Sizeof(info)) ++ stdcall1(_RtlGetVersion, uintptr(unsafe.Pointer(&info))) ++ osVersionInfo.majorVersion = info.majorVersion ++ osVersionInfo.minorVersion = info.minorVersion ++ osVersionInfo.buildNumber = info.buildNumber ++} ++ ++//go:linkname rtlGetNtVersionNumbers syscall.rtlGetNtVersionNumbers ++func rtlGetNtVersionNumbers(majorVersion *uint32, minorVersion *uint32, buildNumber *uint32) { ++ *majorVersion = osVersionInfo.majorVersion ++ *minorVersion = osVersionInfo.minorVersion ++ *buildNumber = osVersionInfo.buildNumber ++} ++ + func osinit() { + asmstdcallAddr = unsafe.Pointer(abi.FuncPCABI0(asmstdcall)) + +@@ -483,8 +554,8 @@ + initHighResTimer() + timeBeginPeriodRetValue = osRelax(false) + +- initSysDirectory() + initLongPathSupport() ++ initOsVersionInfo() + + ncpu = getproccount() + +@@ -500,7 +571,7 @@ + //go:nosplit + func readRandom(r []byte) int { + n := 0 +- if stdcall2(_ProcessPrng, uintptr(unsafe.Pointer(&r[0])), uintptr(len(r)))&0xff != 0 { ++ if stdcall2(_RtlGenRandom, uintptr(unsafe.Pointer(&r[0])), uintptr(len(r)))&0xff != 0 { + n = len(r) + } + return n +Index: src/net/hook_windows.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/net/hook_windows.go b/src/net/hook_windows.go +--- a/src/net/hook_windows.go (revision 9ac42137ef6730e8b7daca016ece831297a1d75b) ++++ b/src/net/hook_windows.go (revision 21290de8a4c91408de7c2b5b68757b1e90af49dd) +@@ -13,6 +13,7 @@ + hostsFilePath = windows.GetSystemDirectory() + "/Drivers/etc/hosts" + + // Placeholders for socket system calls. ++ socketFunc func(int, int, int) (syscall.Handle, error) = syscall.Socket + wsaSocketFunc func(int32, int32, int32, *syscall.WSAProtocolInfo, uint32, uint32) (syscall.Handle, error) = windows.WSASocket + connectFunc func(syscall.Handle, syscall.Sockaddr) error = syscall.Connect + listenFunc func(syscall.Handle, int) error = syscall.Listen +Index: src/net/internal/socktest/main_test.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/net/internal/socktest/main_test.go b/src/net/internal/socktest/main_test.go +--- a/src/net/internal/socktest/main_test.go (revision 9ac42137ef6730e8b7daca016ece831297a1d75b) ++++ b/src/net/internal/socktest/main_test.go (revision 21290de8a4c91408de7c2b5b68757b1e90af49dd) +@@ -2,7 +2,7 @@ + // Use of this source code is governed by a BSD-style + // license that can be found in the LICENSE file. + +-//go:build !js && !plan9 && !wasip1 && !windows ++//go:build !js && !plan9 && !wasip1 + + package socktest_test + +Index: src/net/internal/socktest/main_windows_test.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/net/internal/socktest/main_windows_test.go b/src/net/internal/socktest/main_windows_test.go +new file mode 100644 +--- /dev/null (revision 21290de8a4c91408de7c2b5b68757b1e90af49dd) ++++ b/src/net/internal/socktest/main_windows_test.go (revision 21290de8a4c91408de7c2b5b68757b1e90af49dd) +@@ -0,0 +1,22 @@ ++// Copyright 2015 The Go Authors. All rights reserved. ++// Use of this source code is governed by a BSD-style ++// license that can be found in the LICENSE file. ++ ++package socktest_test ++ ++import "syscall" ++ ++var ( ++ socketFunc func(int, int, int) (syscall.Handle, error) ++ closeFunc func(syscall.Handle) error ++) ++ ++func installTestHooks() { ++ socketFunc = sw.Socket ++ closeFunc = sw.Closesocket ++} ++ ++func uninstallTestHooks() { ++ socketFunc = syscall.Socket ++ closeFunc = syscall.Closesocket ++} +Index: src/net/internal/socktest/sys_windows.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/net/internal/socktest/sys_windows.go b/src/net/internal/socktest/sys_windows.go +--- a/src/net/internal/socktest/sys_windows.go (revision 9ac42137ef6730e8b7daca016ece831297a1d75b) ++++ b/src/net/internal/socktest/sys_windows.go (revision 21290de8a4c91408de7c2b5b68757b1e90af49dd) +@@ -9,6 +9,38 @@ + "syscall" + ) + ++// Socket wraps [syscall.Socket]. ++func (sw *Switch) Socket(family, sotype, proto int) (s syscall.Handle, err error) { ++ sw.once.Do(sw.init) ++ ++ so := &Status{Cookie: cookie(family, sotype, proto)} ++ sw.fmu.RLock() ++ f, _ := sw.fltab[FilterSocket] ++ sw.fmu.RUnlock() ++ ++ af, err := f.apply(so) ++ if err != nil { ++ return syscall.InvalidHandle, err ++ } ++ s, so.Err = syscall.Socket(family, sotype, proto) ++ if err = af.apply(so); err != nil { ++ if so.Err == nil { ++ syscall.Closesocket(s) ++ } ++ return syscall.InvalidHandle, err ++ } ++ ++ sw.smu.Lock() ++ defer sw.smu.Unlock() ++ if so.Err != nil { ++ sw.stats.getLocked(so.Cookie).OpenFailed++ ++ return syscall.InvalidHandle, so.Err ++ } ++ nso := sw.addLocked(s, family, sotype, proto) ++ sw.stats.getLocked(nso.Cookie).Opened++ ++ return s, nil ++} ++ + // WSASocket wraps [syscall.WSASocket]. + func (sw *Switch) WSASocket(family, sotype, proto int32, protinfo *syscall.WSAProtocolInfo, group uint32, flags uint32) (s syscall.Handle, err error) { + sw.once.Do(sw.init) +Index: src/net/main_windows_test.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/net/main_windows_test.go b/src/net/main_windows_test.go +--- a/src/net/main_windows_test.go (revision 9ac42137ef6730e8b7daca016ece831297a1d75b) ++++ b/src/net/main_windows_test.go (revision 21290de8a4c91408de7c2b5b68757b1e90af49dd) +@@ -8,6 +8,7 @@ + + var ( + // Placeholders for saving original socket system calls. ++ origSocket = socketFunc + origWSASocket = wsaSocketFunc + origClosesocket = poll.CloseFunc + origConnect = connectFunc +@@ -17,6 +18,7 @@ + ) + + func installTestHooks() { ++ socketFunc = sw.Socket + wsaSocketFunc = sw.WSASocket + poll.CloseFunc = sw.Closesocket + connectFunc = sw.Connect +@@ -26,6 +28,7 @@ + } + + func uninstallTestHooks() { ++ socketFunc = origSocket + wsaSocketFunc = origWSASocket + poll.CloseFunc = origClosesocket + connectFunc = origConnect +Index: src/net/sock_windows.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/net/sock_windows.go b/src/net/sock_windows.go +--- a/src/net/sock_windows.go (revision 9ac42137ef6730e8b7daca016ece831297a1d75b) ++++ b/src/net/sock_windows.go (revision 21290de8a4c91408de7c2b5b68757b1e90af49dd) +@@ -20,6 +20,21 @@ + func sysSocket(family, sotype, proto int) (syscall.Handle, error) { + s, err := wsaSocketFunc(int32(family), int32(sotype), int32(proto), + nil, 0, windows.WSA_FLAG_OVERLAPPED|windows.WSA_FLAG_NO_HANDLE_INHERIT) ++ if err == nil { ++ return s, nil ++ } ++ // WSA_FLAG_NO_HANDLE_INHERIT flag is not supported on some ++ // old versions of Windows, see ++ // https://msdn.microsoft.com/en-us/library/windows/desktop/ms742212(v=vs.85).aspx ++ // for details. Just use syscall.Socket, if windows.WSASocket failed. ++ ++ // See ../syscall/exec_unix.go for description of ForkLock. ++ syscall.ForkLock.RLock() ++ s, err = socketFunc(family, sotype, proto) ++ if err == nil { ++ syscall.CloseOnExec(s) ++ } ++ syscall.ForkLock.RUnlock() + if err != nil { + return syscall.InvalidHandle, os.NewSyscallError("socket", err) + } +Index: src/syscall/exec_windows.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/syscall/exec_windows.go b/src/syscall/exec_windows.go +--- a/src/syscall/exec_windows.go (revision 9ac42137ef6730e8b7daca016ece831297a1d75b) ++++ b/src/syscall/exec_windows.go (revision 6a31d3fa8e47ddabc10bd97bff10d9a85f4cfb76) +@@ -14,7 +14,6 @@ + "unsafe" + ) + +-// ForkLock is not used on Windows. + var ForkLock sync.RWMutex + + // EscapeArg rewrites command line argument s as prescribed +@@ -254,6 +253,9 @@ + var zeroProcAttr ProcAttr + var zeroSysProcAttr SysProcAttr + ++//go:linkname rtlGetNtVersionNumbers ++func rtlGetNtVersionNumbers(majorVersion *uint32, minorVersion *uint32, buildNumber *uint32) ++ + func StartProcess(argv0 string, argv []string, attr *ProcAttr) (pid int, handle uintptr, err error) { + if len(argv0) == 0 { + return 0, 0, EWINDOWS +@@ -317,6 +319,17 @@ + } + } + ++ var maj, min, build uint32 ++ rtlGetNtVersionNumbers(&maj, &min, &build) ++ isWin7 := maj < 6 || (maj == 6 && min <= 1) ++ // NT kernel handles are divisible by 4, with the bottom 3 bits left as ++ // a tag. The fully set tag correlates with the types of handles we're ++ // concerned about here. Except, the kernel will interpret some ++ // special handle values, like -1, -2, and so forth, so kernelbase.dll ++ // checks to see that those bottom three bits are checked, but that top ++ // bit is not checked. ++ isLegacyWin7ConsoleHandle := func(handle Handle) bool { return isWin7 && handle&0x10000003 == 3 } ++ + p, _ := GetCurrentProcess() + parentProcess := p + if sys.ParentProcess != 0 { +@@ -325,7 +338,15 @@ + fd := make([]Handle, len(attr.Files)) + for i := range attr.Files { + if attr.Files[i] > 0 { +- err := DuplicateHandle(p, Handle(attr.Files[i]), parentProcess, &fd[i], 0, true, DUPLICATE_SAME_ACCESS) ++ destinationProcessHandle := parentProcess ++ ++ // On Windows 7, console handles aren't real handles, and can only be duplicated ++ // into the current process, not a parent one, which amounts to the same thing. ++ if parentProcess != p && isLegacyWin7ConsoleHandle(Handle(attr.Files[i])) { ++ destinationProcessHandle = p ++ } ++ ++ err := DuplicateHandle(p, Handle(attr.Files[i]), destinationProcessHandle, &fd[i], 0, true, DUPLICATE_SAME_ACCESS) + if err != nil { + return 0, 0, err + } +@@ -356,6 +377,14 @@ + + fd = append(fd, sys.AdditionalInheritedHandles...) + ++ // On Windows 7, console handles aren't real handles, so don't pass them ++ // through to PROC_THREAD_ATTRIBUTE_HANDLE_LIST. ++ for i := range fd { ++ if isLegacyWin7ConsoleHandle(fd[i]) { ++ fd[i] = 0 ++ } ++ } ++ + // The presence of a NULL handle in the list is enough to cause PROC_THREAD_ATTRIBUTE_HANDLE_LIST + // to treat the entire list as empty, so remove NULL handles. + j := 0 +Index: src/runtime/syscall_windows.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/runtime/syscall_windows.go b/src/runtime/syscall_windows.go +--- a/src/runtime/syscall_windows.go (revision 6a31d3fa8e47ddabc10bd97bff10d9a85f4cfb76) ++++ b/src/runtime/syscall_windows.go (revision 69e2eed6dd0f6d815ebf15797761c13f31213dd6) +@@ -413,10 +413,20 @@ + + const _LOAD_LIBRARY_SEARCH_SYSTEM32 = 0x00000800 + ++// When available, this function will use LoadLibraryEx with the filename ++// parameter and the important SEARCH_SYSTEM32 argument. But on systems that ++// do not have that option, absoluteFilepath should contain a fallback ++// to the full path inside of system32 for use with vanilla LoadLibrary. ++// + //go:linkname syscall_loadsystemlibrary syscall.loadsystemlibrary +-func syscall_loadsystemlibrary(filename *uint16) (handle, err uintptr) { +- handle, _, err = syscall_SyscallN(uintptr(unsafe.Pointer(_LoadLibraryExW)), uintptr(unsafe.Pointer(filename)), 0, _LOAD_LIBRARY_SEARCH_SYSTEM32) ++func syscall_loadsystemlibrary(filename *uint16, absoluteFilepath *uint16) (handle, err uintptr) { ++ if useLoadLibraryEx { ++ handle, _, err = syscall_SyscallN(uintptr(unsafe.Pointer(_LoadLibraryExW)), uintptr(unsafe.Pointer(filename)), 0, _LOAD_LIBRARY_SEARCH_SYSTEM32) ++ } else { ++ handle, _, err = syscall_SyscallN(uintptr(unsafe.Pointer(_LoadLibraryW)), uintptr(unsafe.Pointer(absoluteFilepath))) ++ } + KeepAlive(filename) ++ KeepAlive(absoluteFilepath) + if handle != 0 { + err = 0 + } +Index: src/syscall/dll_windows.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/syscall/dll_windows.go b/src/syscall/dll_windows.go +--- a/src/syscall/dll_windows.go (revision 6a31d3fa8e47ddabc10bd97bff10d9a85f4cfb76) ++++ b/src/syscall/dll_windows.go (revision 69e2eed6dd0f6d815ebf15797761c13f31213dd6) +@@ -44,7 +44,7 @@ + + func SyscallN(trap uintptr, args ...uintptr) (r1, r2 uintptr, err Errno) + func loadlibrary(filename *uint16) (handle uintptr, err Errno) +-func loadsystemlibrary(filename *uint16) (handle uintptr, err Errno) ++func loadsystemlibrary(filename *uint16, absoluteFilepath *uint16) (handle uintptr, err Errno) + func getprocaddress(handle uintptr, procname *uint8) (proc uintptr, err Errno) + + // A DLL implements access to a single DLL. +@@ -53,6 +53,9 @@ + Handle Handle + } + ++//go:linkname getSystemDirectory ++func getSystemDirectory() string // Implemented in runtime package. ++ + // LoadDLL loads the named DLL file into memory. + // + // If name is not an absolute path and is not a known system DLL used by +@@ -69,7 +72,11 @@ + var h uintptr + var e Errno + if sysdll.IsSystemDLL[name] { +- h, e = loadsystemlibrary(namep) ++ absoluteFilepathp, err := UTF16PtrFromString(getSystemDirectory() + name) ++ if err != nil { ++ return nil, err ++ } ++ h, e = loadsystemlibrary(namep, absoluteFilepathp) + } else { + h, e = loadlibrary(namep) + } diff --git a/.github/patch/go1.24.patch b/.github/patch/go1.24.patch new file mode 100644 index 00000000..ecfc99ff --- /dev/null +++ b/.github/patch/go1.24.patch @@ -0,0 +1,657 @@ +Subject: [PATCH] Revert "runtime: always use LoadLibraryEx to load system libraries" +Revert "syscall: remove Windows 7 console handle workaround" +Revert "net: remove sysSocket fallback for Windows 7" +Revert "crypto/rand,runtime: switch RtlGenRandom for ProcessPrng" +--- +Index: src/crypto/internal/sysrand/rand_windows.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/crypto/internal/sysrand/rand_windows.go b/src/crypto/internal/sysrand/rand_windows.go +--- a/src/crypto/internal/sysrand/rand_windows.go (revision 3901409b5d0fb7c85a3e6730a59943cc93b2835c) ++++ b/src/crypto/internal/sysrand/rand_windows.go (revision 2a406dc9f1ea7323d6ca9fccb2fe9ddebb6b1cc8) +@@ -7,5 +7,26 @@ + import "internal/syscall/windows" + + func read(b []byte) error { +- return windows.ProcessPrng(b) ++ // RtlGenRandom only returns 1<<32-1 bytes at a time. We only read at ++ // most 1<<31-1 bytes at a time so that this works the same on 32-bit ++ // and 64-bit systems. ++ return batched(windows.RtlGenRandom, 1<<31-1)(b) ++} ++ ++// batched returns a function that calls f to populate a []byte by chunking it ++// into subslices of, at most, readMax bytes. ++func batched(f func([]byte) error, readMax int) func([]byte) error { ++ return func(out []byte) error { ++ for len(out) > 0 { ++ read := len(out) ++ if read > readMax { ++ read = readMax ++ } ++ if err := f(out[:read]); err != nil { ++ return err ++ } ++ out = out[read:] ++ } ++ return nil ++ } + } +Index: src/crypto/rand/rand.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/crypto/rand/rand.go b/src/crypto/rand/rand.go +--- a/src/crypto/rand/rand.go (revision 3901409b5d0fb7c85a3e6730a59943cc93b2835c) ++++ b/src/crypto/rand/rand.go (revision 2a406dc9f1ea7323d6ca9fccb2fe9ddebb6b1cc8) +@@ -22,7 +22,7 @@ + // - On legacy Linux (< 3.17), Reader opens /dev/urandom on first use. + // - On macOS, iOS, and OpenBSD Reader, uses arc4random_buf(3). + // - On NetBSD, Reader uses the kern.arandom sysctl. +-// - On Windows, Reader uses the ProcessPrng API. ++// - On Windows systems, Reader uses the RtlGenRandom API. + // - On js/wasm, Reader uses the Web Crypto API. + // - On wasip1/wasm, Reader uses random_get. + // +Index: src/internal/syscall/windows/syscall_windows.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/internal/syscall/windows/syscall_windows.go b/src/internal/syscall/windows/syscall_windows.go +--- a/src/internal/syscall/windows/syscall_windows.go (revision 3901409b5d0fb7c85a3e6730a59943cc93b2835c) ++++ b/src/internal/syscall/windows/syscall_windows.go (revision 2a406dc9f1ea7323d6ca9fccb2fe9ddebb6b1cc8) +@@ -416,7 +416,7 @@ + //sys DestroyEnvironmentBlock(block *uint16) (err error) = userenv.DestroyEnvironmentBlock + //sys CreateEvent(eventAttrs *SecurityAttributes, manualReset uint32, initialState uint32, name *uint16) (handle syscall.Handle, err error) = kernel32.CreateEventW + +-//sys ProcessPrng(buf []byte) (err error) = bcryptprimitives.ProcessPrng ++//sys RtlGenRandom(buf []byte) (err error) = advapi32.SystemFunction036 + + type FILE_ID_BOTH_DIR_INFO struct { + NextEntryOffset uint32 +Index: src/internal/syscall/windows/zsyscall_windows.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/internal/syscall/windows/zsyscall_windows.go b/src/internal/syscall/windows/zsyscall_windows.go +--- a/src/internal/syscall/windows/zsyscall_windows.go (revision 3901409b5d0fb7c85a3e6730a59943cc93b2835c) ++++ b/src/internal/syscall/windows/zsyscall_windows.go (revision 2a406dc9f1ea7323d6ca9fccb2fe9ddebb6b1cc8) +@@ -38,7 +38,6 @@ + + var ( + modadvapi32 = syscall.NewLazyDLL(sysdll.Add("advapi32.dll")) +- modbcryptprimitives = syscall.NewLazyDLL(sysdll.Add("bcryptprimitives.dll")) + modiphlpapi = syscall.NewLazyDLL(sysdll.Add("iphlpapi.dll")) + modkernel32 = syscall.NewLazyDLL(sysdll.Add("kernel32.dll")) + modnetapi32 = syscall.NewLazyDLL(sysdll.Add("netapi32.dll")) +@@ -63,7 +62,7 @@ + procQueryServiceStatus = modadvapi32.NewProc("QueryServiceStatus") + procRevertToSelf = modadvapi32.NewProc("RevertToSelf") + procSetTokenInformation = modadvapi32.NewProc("SetTokenInformation") +- procProcessPrng = modbcryptprimitives.NewProc("ProcessPrng") ++ procSystemFunction036 = modadvapi32.NewProc("SystemFunction036") + procGetAdaptersAddresses = modiphlpapi.NewProc("GetAdaptersAddresses") + procCreateEventW = modkernel32.NewProc("CreateEventW") + procGetACP = modkernel32.NewProc("GetACP") +@@ -236,12 +235,12 @@ + return + } + +-func ProcessPrng(buf []byte) (err error) { ++func RtlGenRandom(buf []byte) (err error) { + var _p0 *byte + if len(buf) > 0 { + _p0 = &buf[0] + } +- r1, _, e1 := syscall.Syscall(procProcessPrng.Addr(), 2, uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), 0) ++ r1, _, e1 := syscall.Syscall(procSystemFunction036.Addr(), 2, uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), 0) + if r1 == 0 { + err = errnoErr(e1) + } +Index: src/runtime/os_windows.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/runtime/os_windows.go b/src/runtime/os_windows.go +--- a/src/runtime/os_windows.go (revision 3901409b5d0fb7c85a3e6730a59943cc93b2835c) ++++ b/src/runtime/os_windows.go (revision ac3e93c061779dfefc0dd13a5b6e6f764a25621e) +@@ -40,8 +40,8 @@ + //go:cgo_import_dynamic runtime._GetSystemInfo GetSystemInfo%1 "kernel32.dll" + //go:cgo_import_dynamic runtime._GetThreadContext GetThreadContext%2 "kernel32.dll" + //go:cgo_import_dynamic runtime._SetThreadContext SetThreadContext%2 "kernel32.dll" +-//go:cgo_import_dynamic runtime._LoadLibraryExW LoadLibraryExW%3 "kernel32.dll" + //go:cgo_import_dynamic runtime._LoadLibraryW LoadLibraryW%1 "kernel32.dll" ++//go:cgo_import_dynamic runtime._LoadLibraryA LoadLibraryA%1 "kernel32.dll" + //go:cgo_import_dynamic runtime._PostQueuedCompletionStatus PostQueuedCompletionStatus%4 "kernel32.dll" + //go:cgo_import_dynamic runtime._QueryPerformanceCounter QueryPerformanceCounter%1 "kernel32.dll" + //go:cgo_import_dynamic runtime._QueryPerformanceFrequency QueryPerformanceFrequency%1 "kernel32.dll" +@@ -75,7 +75,6 @@ + // Following syscalls are available on every Windows PC. + // All these variables are set by the Windows executable + // loader before the Go program starts. +- _AddVectoredContinueHandler, + _AddVectoredExceptionHandler, + _CloseHandle, + _CreateEventA, +@@ -98,8 +97,8 @@ + _GetSystemInfo, + _GetThreadContext, + _SetThreadContext, +- _LoadLibraryExW, + _LoadLibraryW, ++ _LoadLibraryA, + _PostQueuedCompletionStatus, + _QueryPerformanceCounter, + _QueryPerformanceFrequency, +@@ -128,8 +127,23 @@ + _WriteFile, + _ stdFunction + +- // Use ProcessPrng to generate cryptographically random data. +- _ProcessPrng stdFunction ++ // Following syscalls are only available on some Windows PCs. ++ // We will load syscalls, if available, before using them. ++ _AddDllDirectory, ++ _AddVectoredContinueHandler, ++ _LoadLibraryExA, ++ _LoadLibraryExW, ++ _ stdFunction ++ ++ // Use RtlGenRandom to generate cryptographically random data. ++ // This approach has been recommended by Microsoft (see issue ++ // 15589 for details). ++ // The RtlGenRandom is not listed in advapi32.dll, instead ++ // RtlGenRandom function can be found by searching for SystemFunction036. ++ // Also some versions of Mingw cannot link to SystemFunction036 ++ // when building executable as Cgo. So load SystemFunction036 ++ // manually during runtime startup. ++ _RtlGenRandom stdFunction + + // Load ntdll.dll manually during startup, otherwise Mingw + // links wrong printf function to cgo executable (see issue +@@ -146,13 +160,6 @@ + _ stdFunction + ) + +-var ( +- bcryptprimitivesdll = [...]uint16{'b', 'c', 'r', 'y', 'p', 't', 'p', 'r', 'i', 'm', 'i', 't', 'i', 'v', 'e', 's', '.', 'd', 'l', 'l', 0} +- ntdlldll = [...]uint16{'n', 't', 'd', 'l', 'l', '.', 'd', 'l', 'l', 0} +- powrprofdll = [...]uint16{'p', 'o', 'w', 'r', 'p', 'r', 'o', 'f', '.', 'd', 'l', 'l', 0} +- winmmdll = [...]uint16{'w', 'i', 'n', 'm', 'm', '.', 'd', 'l', 'l', 0} +-) +- + // Function to be called by windows CreateThread + // to start new os thread. + func tstart_stdcall(newm *m) +@@ -245,8 +252,18 @@ + return unsafe.String(&sysDirectory[0], sysDirectoryLen) + } + +-func windowsLoadSystemLib(name []uint16) uintptr { +- return stdcall3(_LoadLibraryExW, uintptr(unsafe.Pointer(&name[0])), 0, _LOAD_LIBRARY_SEARCH_SYSTEM32) ++//go:linkname syscall_getSystemDirectory syscall.getSystemDirectory ++func syscall_getSystemDirectory() string { ++ return unsafe.String(&sysDirectory[0], sysDirectoryLen) ++} ++ ++func windowsLoadSystemLib(name []byte) uintptr { ++ if useLoadLibraryEx { ++ return stdcall3(_LoadLibraryExA, uintptr(unsafe.Pointer(&name[0])), 0, _LOAD_LIBRARY_SEARCH_SYSTEM32) ++ } else { ++ absName := append(sysDirectory[:sysDirectoryLen], name...) ++ return stdcall1(_LoadLibraryA, uintptr(unsafe.Pointer(&absName[0]))) ++ } + } + + //go:linkname windows_QueryPerformanceCounter internal/syscall/windows.QueryPerformanceCounter +@@ -264,13 +281,28 @@ + } + + func loadOptionalSyscalls() { +- bcryptPrimitives := windowsLoadSystemLib(bcryptprimitivesdll[:]) +- if bcryptPrimitives == 0 { +- throw("bcryptprimitives.dll not found") ++ var kernel32dll = []byte("kernel32.dll\000") ++ k32 := stdcall1(_LoadLibraryA, uintptr(unsafe.Pointer(&kernel32dll[0]))) ++ if k32 == 0 { ++ throw("kernel32.dll not found") + } +- _ProcessPrng = windowsFindfunc(bcryptPrimitives, []byte("ProcessPrng\000")) ++ _AddDllDirectory = windowsFindfunc(k32, []byte("AddDllDirectory\000")) ++ _AddVectoredContinueHandler = windowsFindfunc(k32, []byte("AddVectoredContinueHandler\000")) ++ _LoadLibraryExA = windowsFindfunc(k32, []byte("LoadLibraryExA\000")) ++ _LoadLibraryExW = windowsFindfunc(k32, []byte("LoadLibraryExW\000")) ++ useLoadLibraryEx = (_LoadLibraryExW != nil && _LoadLibraryExA != nil && _AddDllDirectory != nil) ++ ++ initSysDirectory() + +- n32 := windowsLoadSystemLib(ntdlldll[:]) ++ var advapi32dll = []byte("advapi32.dll\000") ++ a32 := windowsLoadSystemLib(advapi32dll) ++ if a32 == 0 { ++ throw("advapi32.dll not found") ++ } ++ _RtlGenRandom = windowsFindfunc(a32, []byte("SystemFunction036\000")) ++ ++ var ntdll = []byte("ntdll.dll\000") ++ n32 := windowsLoadSystemLib(ntdll) + if n32 == 0 { + throw("ntdll.dll not found") + } +@@ -299,7 +331,7 @@ + context uintptr + } + +- powrprof := windowsLoadSystemLib(powrprofdll[:]) ++ powrprof := windowsLoadSystemLib([]byte("powrprof.dll\000")) + if powrprof == 0 { + return // Running on Windows 7, where we don't need it anyway. + } +@@ -358,6 +390,22 @@ + // in sys_windows_386.s and sys_windows_amd64.s: + func getlasterror() uint32 + ++// When loading DLLs, we prefer to use LoadLibraryEx with ++// LOAD_LIBRARY_SEARCH_* flags, if available. LoadLibraryEx is not ++// available on old Windows, though, and the LOAD_LIBRARY_SEARCH_* ++// flags are not available on some versions of Windows without a ++// security patch. ++// ++// https://msdn.microsoft.com/en-us/library/ms684179(v=vs.85).aspx says: ++// "Windows 7, Windows Server 2008 R2, Windows Vista, and Windows ++// Server 2008: The LOAD_LIBRARY_SEARCH_* flags are available on ++// systems that have KB2533623 installed. To determine whether the ++// flags are available, use GetProcAddress to get the address of the ++// AddDllDirectory, RemoveDllDirectory, or SetDefaultDllDirectories ++// function. If GetProcAddress succeeds, the LOAD_LIBRARY_SEARCH_* ++// flags can be used with LoadLibraryEx." ++var useLoadLibraryEx bool ++ + var timeBeginPeriodRetValue uint32 + + // osRelaxMinNS indicates that sysmon shouldn't osRelax if the next +@@ -431,7 +479,8 @@ + // Only load winmm.dll if we need it. + // This avoids a dependency on winmm.dll for Go programs + // that run on new Windows versions. +- m32 := windowsLoadSystemLib(winmmdll[:]) ++ var winmmdll = []byte("winmm.dll\000") ++ m32 := windowsLoadSystemLib(winmmdll) + if m32 == 0 { + print("runtime: LoadLibraryExW failed; errno=", getlasterror(), "\n") + throw("winmm.dll not found") +@@ -472,6 +521,28 @@ + canUseLongPaths = true + } + ++var osVersionInfo struct { ++ majorVersion uint32 ++ minorVersion uint32 ++ buildNumber uint32 ++} ++ ++func initOsVersionInfo() { ++ info := _OSVERSIONINFOW{} ++ info.osVersionInfoSize = uint32(unsafe.Sizeof(info)) ++ stdcall1(_RtlGetVersion, uintptr(unsafe.Pointer(&info))) ++ osVersionInfo.majorVersion = info.majorVersion ++ osVersionInfo.minorVersion = info.minorVersion ++ osVersionInfo.buildNumber = info.buildNumber ++} ++ ++//go:linkname rtlGetNtVersionNumbers syscall.rtlGetNtVersionNumbers ++func rtlGetNtVersionNumbers(majorVersion *uint32, minorVersion *uint32, buildNumber *uint32) { ++ *majorVersion = osVersionInfo.majorVersion ++ *minorVersion = osVersionInfo.minorVersion ++ *buildNumber = osVersionInfo.buildNumber ++} ++ + func osinit() { + asmstdcallAddr = unsafe.Pointer(abi.FuncPCABI0(asmstdcall)) + +@@ -484,8 +555,8 @@ + initHighResTimer() + timeBeginPeriodRetValue = osRelax(false) + +- initSysDirectory() + initLongPathSupport() ++ initOsVersionInfo() + + ncpu = getproccount() + +@@ -501,7 +572,7 @@ + //go:nosplit + func readRandom(r []byte) int { + n := 0 +- if stdcall2(_ProcessPrng, uintptr(unsafe.Pointer(&r[0])), uintptr(len(r)))&0xff != 0 { ++ if stdcall2(_RtlGenRandom, uintptr(unsafe.Pointer(&r[0])), uintptr(len(r)))&0xff != 0 { + n = len(r) + } + return n +Index: src/net/hook_windows.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/net/hook_windows.go b/src/net/hook_windows.go +--- a/src/net/hook_windows.go (revision 2a406dc9f1ea7323d6ca9fccb2fe9ddebb6b1cc8) ++++ b/src/net/hook_windows.go (revision 7b1fd7d39c6be0185fbe1d929578ab372ac5c632) +@@ -13,6 +13,7 @@ + hostsFilePath = windows.GetSystemDirectory() + "/Drivers/etc/hosts" + + // Placeholders for socket system calls. ++ socketFunc func(int, int, int) (syscall.Handle, error) = syscall.Socket + wsaSocketFunc func(int32, int32, int32, *syscall.WSAProtocolInfo, uint32, uint32) (syscall.Handle, error) = windows.WSASocket + connectFunc func(syscall.Handle, syscall.Sockaddr) error = syscall.Connect + listenFunc func(syscall.Handle, int) error = syscall.Listen +Index: src/net/internal/socktest/main_test.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/net/internal/socktest/main_test.go b/src/net/internal/socktest/main_test.go +--- a/src/net/internal/socktest/main_test.go (revision 2a406dc9f1ea7323d6ca9fccb2fe9ddebb6b1cc8) ++++ b/src/net/internal/socktest/main_test.go (revision 7b1fd7d39c6be0185fbe1d929578ab372ac5c632) +@@ -2,7 +2,7 @@ + // Use of this source code is governed by a BSD-style + // license that can be found in the LICENSE file. + +-//go:build !js && !plan9 && !wasip1 && !windows ++//go:build !js && !plan9 && !wasip1 + + package socktest_test + +Index: src/net/internal/socktest/main_windows_test.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/net/internal/socktest/main_windows_test.go b/src/net/internal/socktest/main_windows_test.go +new file mode 100644 +--- /dev/null (revision 7b1fd7d39c6be0185fbe1d929578ab372ac5c632) ++++ b/src/net/internal/socktest/main_windows_test.go (revision 7b1fd7d39c6be0185fbe1d929578ab372ac5c632) +@@ -0,0 +1,22 @@ ++// Copyright 2015 The Go Authors. All rights reserved. ++// Use of this source code is governed by a BSD-style ++// license that can be found in the LICENSE file. ++ ++package socktest_test ++ ++import "syscall" ++ ++var ( ++ socketFunc func(int, int, int) (syscall.Handle, error) ++ closeFunc func(syscall.Handle) error ++) ++ ++func installTestHooks() { ++ socketFunc = sw.Socket ++ closeFunc = sw.Closesocket ++} ++ ++func uninstallTestHooks() { ++ socketFunc = syscall.Socket ++ closeFunc = syscall.Closesocket ++} +Index: src/net/internal/socktest/sys_windows.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/net/internal/socktest/sys_windows.go b/src/net/internal/socktest/sys_windows.go +--- a/src/net/internal/socktest/sys_windows.go (revision 2a406dc9f1ea7323d6ca9fccb2fe9ddebb6b1cc8) ++++ b/src/net/internal/socktest/sys_windows.go (revision 7b1fd7d39c6be0185fbe1d929578ab372ac5c632) +@@ -9,6 +9,38 @@ + "syscall" + ) + ++// Socket wraps [syscall.Socket]. ++func (sw *Switch) Socket(family, sotype, proto int) (s syscall.Handle, err error) { ++ sw.once.Do(sw.init) ++ ++ so := &Status{Cookie: cookie(family, sotype, proto)} ++ sw.fmu.RLock() ++ f, _ := sw.fltab[FilterSocket] ++ sw.fmu.RUnlock() ++ ++ af, err := f.apply(so) ++ if err != nil { ++ return syscall.InvalidHandle, err ++ } ++ s, so.Err = syscall.Socket(family, sotype, proto) ++ if err = af.apply(so); err != nil { ++ if so.Err == nil { ++ syscall.Closesocket(s) ++ } ++ return syscall.InvalidHandle, err ++ } ++ ++ sw.smu.Lock() ++ defer sw.smu.Unlock() ++ if so.Err != nil { ++ sw.stats.getLocked(so.Cookie).OpenFailed++ ++ return syscall.InvalidHandle, so.Err ++ } ++ nso := sw.addLocked(s, family, sotype, proto) ++ sw.stats.getLocked(nso.Cookie).Opened++ ++ return s, nil ++} ++ + // WSASocket wraps [syscall.WSASocket]. + func (sw *Switch) WSASocket(family, sotype, proto int32, protinfo *syscall.WSAProtocolInfo, group uint32, flags uint32) (s syscall.Handle, err error) { + sw.once.Do(sw.init) +Index: src/net/main_windows_test.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/net/main_windows_test.go b/src/net/main_windows_test.go +--- a/src/net/main_windows_test.go (revision 2a406dc9f1ea7323d6ca9fccb2fe9ddebb6b1cc8) ++++ b/src/net/main_windows_test.go (revision 7b1fd7d39c6be0185fbe1d929578ab372ac5c632) +@@ -8,6 +8,7 @@ + + var ( + // Placeholders for saving original socket system calls. ++ origSocket = socketFunc + origWSASocket = wsaSocketFunc + origClosesocket = poll.CloseFunc + origConnect = connectFunc +@@ -17,6 +18,7 @@ + ) + + func installTestHooks() { ++ socketFunc = sw.Socket + wsaSocketFunc = sw.WSASocket + poll.CloseFunc = sw.Closesocket + connectFunc = sw.Connect +@@ -26,6 +28,7 @@ + } + + func uninstallTestHooks() { ++ socketFunc = origSocket + wsaSocketFunc = origWSASocket + poll.CloseFunc = origClosesocket + connectFunc = origConnect +Index: src/net/sock_windows.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/net/sock_windows.go b/src/net/sock_windows.go +--- a/src/net/sock_windows.go (revision 2a406dc9f1ea7323d6ca9fccb2fe9ddebb6b1cc8) ++++ b/src/net/sock_windows.go (revision 7b1fd7d39c6be0185fbe1d929578ab372ac5c632) +@@ -20,6 +20,21 @@ + func sysSocket(family, sotype, proto int) (syscall.Handle, error) { + s, err := wsaSocketFunc(int32(family), int32(sotype), int32(proto), + nil, 0, windows.WSA_FLAG_OVERLAPPED|windows.WSA_FLAG_NO_HANDLE_INHERIT) ++ if err == nil { ++ return s, nil ++ } ++ // WSA_FLAG_NO_HANDLE_INHERIT flag is not supported on some ++ // old versions of Windows, see ++ // https://msdn.microsoft.com/en-us/library/windows/desktop/ms742212(v=vs.85).aspx ++ // for details. Just use syscall.Socket, if windows.WSASocket failed. ++ ++ // See ../syscall/exec_unix.go for description of ForkLock. ++ syscall.ForkLock.RLock() ++ s, err = socketFunc(family, sotype, proto) ++ if err == nil { ++ syscall.CloseOnExec(s) ++ } ++ syscall.ForkLock.RUnlock() + if err != nil { + return syscall.InvalidHandle, os.NewSyscallError("socket", err) + } +Index: src/syscall/exec_windows.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/syscall/exec_windows.go b/src/syscall/exec_windows.go +--- a/src/syscall/exec_windows.go (revision 2a406dc9f1ea7323d6ca9fccb2fe9ddebb6b1cc8) ++++ b/src/syscall/exec_windows.go (revision 979d6d8bab3823ff572ace26767fd2ce3cf351ae) +@@ -14,7 +14,6 @@ + "unsafe" + ) + +-// ForkLock is not used on Windows. + var ForkLock sync.RWMutex + + // EscapeArg rewrites command line argument s as prescribed +@@ -254,6 +253,9 @@ + var zeroProcAttr ProcAttr + var zeroSysProcAttr SysProcAttr + ++//go:linkname rtlGetNtVersionNumbers ++func rtlGetNtVersionNumbers(majorVersion *uint32, minorVersion *uint32, buildNumber *uint32) ++ + func StartProcess(argv0 string, argv []string, attr *ProcAttr) (pid int, handle uintptr, err error) { + if len(argv0) == 0 { + return 0, 0, EWINDOWS +@@ -317,6 +319,17 @@ + } + } + ++ var maj, min, build uint32 ++ rtlGetNtVersionNumbers(&maj, &min, &build) ++ isWin7 := maj < 6 || (maj == 6 && min <= 1) ++ // NT kernel handles are divisible by 4, with the bottom 3 bits left as ++ // a tag. The fully set tag correlates with the types of handles we're ++ // concerned about here. Except, the kernel will interpret some ++ // special handle values, like -1, -2, and so forth, so kernelbase.dll ++ // checks to see that those bottom three bits are checked, but that top ++ // bit is not checked. ++ isLegacyWin7ConsoleHandle := func(handle Handle) bool { return isWin7 && handle&0x10000003 == 3 } ++ + p, _ := GetCurrentProcess() + parentProcess := p + if sys.ParentProcess != 0 { +@@ -325,7 +338,15 @@ + fd := make([]Handle, len(attr.Files)) + for i := range attr.Files { + if attr.Files[i] > 0 { +- err := DuplicateHandle(p, Handle(attr.Files[i]), parentProcess, &fd[i], 0, true, DUPLICATE_SAME_ACCESS) ++ destinationProcessHandle := parentProcess ++ ++ // On Windows 7, console handles aren't real handles, and can only be duplicated ++ // into the current process, not a parent one, which amounts to the same thing. ++ if parentProcess != p && isLegacyWin7ConsoleHandle(Handle(attr.Files[i])) { ++ destinationProcessHandle = p ++ } ++ ++ err := DuplicateHandle(p, Handle(attr.Files[i]), destinationProcessHandle, &fd[i], 0, true, DUPLICATE_SAME_ACCESS) + if err != nil { + return 0, 0, err + } +@@ -356,6 +377,14 @@ + + fd = append(fd, sys.AdditionalInheritedHandles...) + ++ // On Windows 7, console handles aren't real handles, so don't pass them ++ // through to PROC_THREAD_ATTRIBUTE_HANDLE_LIST. ++ for i := range fd { ++ if isLegacyWin7ConsoleHandle(fd[i]) { ++ fd[i] = 0 ++ } ++ } ++ + // The presence of a NULL handle in the list is enough to cause PROC_THREAD_ATTRIBUTE_HANDLE_LIST + // to treat the entire list as empty, so remove NULL handles. + j := 0 +Index: src/runtime/syscall_windows.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/runtime/syscall_windows.go b/src/runtime/syscall_windows.go +--- a/src/runtime/syscall_windows.go (revision 979d6d8bab3823ff572ace26767fd2ce3cf351ae) ++++ b/src/runtime/syscall_windows.go (revision ac3e93c061779dfefc0dd13a5b6e6f764a25621e) +@@ -413,10 +413,20 @@ + + const _LOAD_LIBRARY_SEARCH_SYSTEM32 = 0x00000800 + ++// When available, this function will use LoadLibraryEx with the filename ++// parameter and the important SEARCH_SYSTEM32 argument. But on systems that ++// do not have that option, absoluteFilepath should contain a fallback ++// to the full path inside of system32 for use with vanilla LoadLibrary. ++// + //go:linkname syscall_loadsystemlibrary syscall.loadsystemlibrary +-func syscall_loadsystemlibrary(filename *uint16) (handle, err uintptr) { +- handle, _, err = syscall_SyscallN(uintptr(unsafe.Pointer(_LoadLibraryExW)), uintptr(unsafe.Pointer(filename)), 0, _LOAD_LIBRARY_SEARCH_SYSTEM32) ++func syscall_loadsystemlibrary(filename *uint16, absoluteFilepath *uint16) (handle, err uintptr) { ++ if useLoadLibraryEx { ++ handle, _, err = syscall_SyscallN(uintptr(unsafe.Pointer(_LoadLibraryExW)), uintptr(unsafe.Pointer(filename)), 0, _LOAD_LIBRARY_SEARCH_SYSTEM32) ++ } else { ++ handle, _, err = syscall_SyscallN(uintptr(unsafe.Pointer(_LoadLibraryW)), uintptr(unsafe.Pointer(absoluteFilepath))) ++ } + KeepAlive(filename) ++ KeepAlive(absoluteFilepath) + if handle != 0 { + err = 0 + } +Index: src/syscall/dll_windows.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/syscall/dll_windows.go b/src/syscall/dll_windows.go +--- a/src/syscall/dll_windows.go (revision 979d6d8bab3823ff572ace26767fd2ce3cf351ae) ++++ b/src/syscall/dll_windows.go (revision ac3e93c061779dfefc0dd13a5b6e6f764a25621e) +@@ -45,7 +45,7 @@ + //go:noescape + func SyscallN(trap uintptr, args ...uintptr) (r1, r2 uintptr, err Errno) + func loadlibrary(filename *uint16) (handle uintptr, err Errno) +-func loadsystemlibrary(filename *uint16) (handle uintptr, err Errno) ++func loadsystemlibrary(filename *uint16, absoluteFilepath *uint16) (handle uintptr, err Errno) + func getprocaddress(handle uintptr, procname *uint8) (proc uintptr, err Errno) + + // A DLL implements access to a single DLL. +@@ -54,6 +54,9 @@ + Handle Handle + } + ++//go:linkname getSystemDirectory ++func getSystemDirectory() string // Implemented in runtime package. ++ + // LoadDLL loads the named DLL file into memory. + // + // If name is not an absolute path and is not a known system DLL used by +@@ -70,7 +73,11 @@ + var h uintptr + var e Errno + if sysdll.IsSystemDLL[name] { +- h, e = loadsystemlibrary(namep) ++ absoluteFilepathp, err := UTF16PtrFromString(getSystemDirectory() + name) ++ if err != nil { ++ return nil, err ++ } ++ h, e = loadsystemlibrary(namep, absoluteFilepathp) + } else { + h, e = loadlibrary(namep) + } diff --git a/.github/patch/go1.25.patch b/.github/patch/go1.25.patch new file mode 100644 index 00000000..626779db --- /dev/null +++ b/.github/patch/go1.25.patch @@ -0,0 +1,657 @@ +Subject: [PATCH] Revert "runtime: always use LoadLibraryEx to load system libraries" +Revert "syscall: remove Windows 7 console handle workaround" +Revert "net: remove sysSocket fallback for Windows 7" +Revert "crypto/rand,runtime: switch RtlGenRandom for ProcessPrng" +--- +Index: src/crypto/internal/sysrand/rand_windows.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/crypto/internal/sysrand/rand_windows.go b/src/crypto/internal/sysrand/rand_windows.go +--- a/src/crypto/internal/sysrand/rand_windows.go (revision 6e676ab2b809d46623acb5988248d95d1eb7939c) ++++ b/src/crypto/internal/sysrand/rand_windows.go (revision 8cb5472d94c34b88733a81091bd328e70ee565a4) +@@ -7,5 +7,26 @@ + import "internal/syscall/windows" + + func read(b []byte) error { +- return windows.ProcessPrng(b) ++ // RtlGenRandom only returns 1<<32-1 bytes at a time. We only read at ++ // most 1<<31-1 bytes at a time so that this works the same on 32-bit ++ // and 64-bit systems. ++ return batched(windows.RtlGenRandom, 1<<31-1)(b) ++} ++ ++// batched returns a function that calls f to populate a []byte by chunking it ++// into subslices of, at most, readMax bytes. ++func batched(f func([]byte) error, readMax int) func([]byte) error { ++ return func(out []byte) error { ++ for len(out) > 0 { ++ read := len(out) ++ if read > readMax { ++ read = readMax ++ } ++ if err := f(out[:read]); err != nil { ++ return err ++ } ++ out = out[read:] ++ } ++ return nil ++ } + } +Index: src/crypto/rand/rand.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/crypto/rand/rand.go b/src/crypto/rand/rand.go +--- a/src/crypto/rand/rand.go (revision 6e676ab2b809d46623acb5988248d95d1eb7939c) ++++ b/src/crypto/rand/rand.go (revision 8cb5472d94c34b88733a81091bd328e70ee565a4) +@@ -22,7 +22,7 @@ + // - On legacy Linux (< 3.17), Reader opens /dev/urandom on first use. + // - On macOS, iOS, and OpenBSD Reader, uses arc4random_buf(3). + // - On NetBSD, Reader uses the kern.arandom sysctl. +-// - On Windows, Reader uses the ProcessPrng API. ++// - On Windows systems, Reader uses the RtlGenRandom API. + // - On js/wasm, Reader uses the Web Crypto API. + // - On wasip1/wasm, Reader uses random_get. + // +Index: src/internal/syscall/windows/syscall_windows.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/internal/syscall/windows/syscall_windows.go b/src/internal/syscall/windows/syscall_windows.go +--- a/src/internal/syscall/windows/syscall_windows.go (revision 6e676ab2b809d46623acb5988248d95d1eb7939c) ++++ b/src/internal/syscall/windows/syscall_windows.go (revision 8cb5472d94c34b88733a81091bd328e70ee565a4) +@@ -419,7 +419,7 @@ + //sys DestroyEnvironmentBlock(block *uint16) (err error) = userenv.DestroyEnvironmentBlock + //sys CreateEvent(eventAttrs *SecurityAttributes, manualReset uint32, initialState uint32, name *uint16) (handle syscall.Handle, err error) = kernel32.CreateEventW + +-//sys ProcessPrng(buf []byte) (err error) = bcryptprimitives.ProcessPrng ++//sys RtlGenRandom(buf []byte) (err error) = advapi32.SystemFunction036 + + type FILE_ID_BOTH_DIR_INFO struct { + NextEntryOffset uint32 +Index: src/internal/syscall/windows/zsyscall_windows.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/internal/syscall/windows/zsyscall_windows.go b/src/internal/syscall/windows/zsyscall_windows.go +--- a/src/internal/syscall/windows/zsyscall_windows.go (revision 6e676ab2b809d46623acb5988248d95d1eb7939c) ++++ b/src/internal/syscall/windows/zsyscall_windows.go (revision 8cb5472d94c34b88733a81091bd328e70ee565a4) +@@ -38,7 +38,6 @@ + + var ( + modadvapi32 = syscall.NewLazyDLL(sysdll.Add("advapi32.dll")) +- modbcryptprimitives = syscall.NewLazyDLL(sysdll.Add("bcryptprimitives.dll")) + modiphlpapi = syscall.NewLazyDLL(sysdll.Add("iphlpapi.dll")) + modkernel32 = syscall.NewLazyDLL(sysdll.Add("kernel32.dll")) + modnetapi32 = syscall.NewLazyDLL(sysdll.Add("netapi32.dll")) +@@ -63,7 +62,7 @@ + procQueryServiceStatus = modadvapi32.NewProc("QueryServiceStatus") + procRevertToSelf = modadvapi32.NewProc("RevertToSelf") + procSetTokenInformation = modadvapi32.NewProc("SetTokenInformation") +- procProcessPrng = modbcryptprimitives.NewProc("ProcessPrng") ++ procSystemFunction036 = modadvapi32.NewProc("SystemFunction036") + procGetAdaptersAddresses = modiphlpapi.NewProc("GetAdaptersAddresses") + procCreateEventW = modkernel32.NewProc("CreateEventW") + procCreateIoCompletionPort = modkernel32.NewProc("CreateIoCompletionPort") +@@ -242,12 +241,12 @@ + return + } + +-func ProcessPrng(buf []byte) (err error) { ++func RtlGenRandom(buf []byte) (err error) { + var _p0 *byte + if len(buf) > 0 { + _p0 = &buf[0] + } +- r1, _, e1 := syscall.Syscall(procProcessPrng.Addr(), 2, uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), 0) ++ r1, _, e1 := syscall.Syscall(procSystemFunction036.Addr(), 2, uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), 0) + if r1 == 0 { + err = errnoErr(e1) + } +Index: src/runtime/os_windows.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/runtime/os_windows.go b/src/runtime/os_windows.go +--- a/src/runtime/os_windows.go (revision 6e676ab2b809d46623acb5988248d95d1eb7939c) ++++ b/src/runtime/os_windows.go (revision f56f1e23507e646c85243a71bde7b9629b2f970c) +@@ -39,8 +39,8 @@ + //go:cgo_import_dynamic runtime._GetSystemInfo GetSystemInfo%1 "kernel32.dll" + //go:cgo_import_dynamic runtime._GetThreadContext GetThreadContext%2 "kernel32.dll" + //go:cgo_import_dynamic runtime._SetThreadContext SetThreadContext%2 "kernel32.dll" +-//go:cgo_import_dynamic runtime._LoadLibraryExW LoadLibraryExW%3 "kernel32.dll" + //go:cgo_import_dynamic runtime._LoadLibraryW LoadLibraryW%1 "kernel32.dll" ++//go:cgo_import_dynamic runtime._LoadLibraryA LoadLibraryA%1 "kernel32.dll" + //go:cgo_import_dynamic runtime._PostQueuedCompletionStatus PostQueuedCompletionStatus%4 "kernel32.dll" + //go:cgo_import_dynamic runtime._QueryPerformanceCounter QueryPerformanceCounter%1 "kernel32.dll" + //go:cgo_import_dynamic runtime._QueryPerformanceFrequency QueryPerformanceFrequency%1 "kernel32.dll" +@@ -74,7 +74,6 @@ + // Following syscalls are available on every Windows PC. + // All these variables are set by the Windows executable + // loader before the Go program starts. +- _AddVectoredContinueHandler, + _AddVectoredExceptionHandler, + _CloseHandle, + _CreateEventA, +@@ -97,8 +96,8 @@ + _GetSystemInfo, + _GetThreadContext, + _SetThreadContext, +- _LoadLibraryExW, + _LoadLibraryW, ++ _LoadLibraryA, + _PostQueuedCompletionStatus, + _QueryPerformanceCounter, + _QueryPerformanceFrequency, +@@ -127,8 +126,23 @@ + _WriteFile, + _ stdFunction + +- // Use ProcessPrng to generate cryptographically random data. +- _ProcessPrng stdFunction ++ // Following syscalls are only available on some Windows PCs. ++ // We will load syscalls, if available, before using them. ++ _AddDllDirectory, ++ _AddVectoredContinueHandler, ++ _LoadLibraryExA, ++ _LoadLibraryExW, ++ _ stdFunction ++ ++ // Use RtlGenRandom to generate cryptographically random data. ++ // This approach has been recommended by Microsoft (see issue ++ // 15589 for details). ++ // The RtlGenRandom is not listed in advapi32.dll, instead ++ // RtlGenRandom function can be found by searching for SystemFunction036. ++ // Also some versions of Mingw cannot link to SystemFunction036 ++ // when building executable as Cgo. So load SystemFunction036 ++ // manually during runtime startup. ++ _RtlGenRandom stdFunction + + // Load ntdll.dll manually during startup, otherwise Mingw + // links wrong printf function to cgo executable (see issue +@@ -145,13 +159,6 @@ + _ stdFunction + ) + +-var ( +- bcryptprimitivesdll = [...]uint16{'b', 'c', 'r', 'y', 'p', 't', 'p', 'r', 'i', 'm', 'i', 't', 'i', 'v', 'e', 's', '.', 'd', 'l', 'l', 0} +- ntdlldll = [...]uint16{'n', 't', 'd', 'l', 'l', '.', 'd', 'l', 'l', 0} +- powrprofdll = [...]uint16{'p', 'o', 'w', 'r', 'p', 'r', 'o', 'f', '.', 'd', 'l', 'l', 0} +- winmmdll = [...]uint16{'w', 'i', 'n', 'm', 'm', '.', 'd', 'l', 'l', 0} +-) +- + // Function to be called by windows CreateThread + // to start new os thread. + func tstart_stdcall(newm *m) +@@ -244,8 +251,18 @@ + return unsafe.String(&sysDirectory[0], sysDirectoryLen) + } + +-func windowsLoadSystemLib(name []uint16) uintptr { +- return stdcall3(_LoadLibraryExW, uintptr(unsafe.Pointer(&name[0])), 0, _LOAD_LIBRARY_SEARCH_SYSTEM32) ++//go:linkname syscall_getSystemDirectory syscall.getSystemDirectory ++func syscall_getSystemDirectory() string { ++ return unsafe.String(&sysDirectory[0], sysDirectoryLen) ++} ++ ++func windowsLoadSystemLib(name []byte) uintptr { ++ if useLoadLibraryEx { ++ return stdcall3(_LoadLibraryExA, uintptr(unsafe.Pointer(&name[0])), 0, _LOAD_LIBRARY_SEARCH_SYSTEM32) ++ } else { ++ absName := append(sysDirectory[:sysDirectoryLen], name...) ++ return stdcall1(_LoadLibraryA, uintptr(unsafe.Pointer(&absName[0]))) ++ } + } + + //go:linkname windows_QueryPerformanceCounter internal/syscall/windows.QueryPerformanceCounter +@@ -263,13 +280,28 @@ + } + + func loadOptionalSyscalls() { +- bcryptPrimitives := windowsLoadSystemLib(bcryptprimitivesdll[:]) +- if bcryptPrimitives == 0 { +- throw("bcryptprimitives.dll not found") ++ var kernel32dll = []byte("kernel32.dll\000") ++ k32 := stdcall1(_LoadLibraryA, uintptr(unsafe.Pointer(&kernel32dll[0]))) ++ if k32 == 0 { ++ throw("kernel32.dll not found") + } +- _ProcessPrng = windowsFindfunc(bcryptPrimitives, []byte("ProcessPrng\000")) ++ _AddDllDirectory = windowsFindfunc(k32, []byte("AddDllDirectory\000")) ++ _AddVectoredContinueHandler = windowsFindfunc(k32, []byte("AddVectoredContinueHandler\000")) ++ _LoadLibraryExA = windowsFindfunc(k32, []byte("LoadLibraryExA\000")) ++ _LoadLibraryExW = windowsFindfunc(k32, []byte("LoadLibraryExW\000")) ++ useLoadLibraryEx = (_LoadLibraryExW != nil && _LoadLibraryExA != nil && _AddDllDirectory != nil) ++ ++ initSysDirectory() + +- n32 := windowsLoadSystemLib(ntdlldll[:]) ++ var advapi32dll = []byte("advapi32.dll\000") ++ a32 := windowsLoadSystemLib(advapi32dll) ++ if a32 == 0 { ++ throw("advapi32.dll not found") ++ } ++ _RtlGenRandom = windowsFindfunc(a32, []byte("SystemFunction036\000")) ++ ++ var ntdll = []byte("ntdll.dll\000") ++ n32 := windowsLoadSystemLib(ntdll) + if n32 == 0 { + throw("ntdll.dll not found") + } +@@ -298,7 +330,7 @@ + context uintptr + } + +- powrprof := windowsLoadSystemLib(powrprofdll[:]) ++ powrprof := windowsLoadSystemLib([]byte("powrprof.dll\000")) + if powrprof == 0 { + return // Running on Windows 7, where we don't need it anyway. + } +@@ -357,6 +389,22 @@ + // in sys_windows_386.s and sys_windows_amd64.s: + func getlasterror() uint32 + ++// When loading DLLs, we prefer to use LoadLibraryEx with ++// LOAD_LIBRARY_SEARCH_* flags, if available. LoadLibraryEx is not ++// available on old Windows, though, and the LOAD_LIBRARY_SEARCH_* ++// flags are not available on some versions of Windows without a ++// security patch. ++// ++// https://msdn.microsoft.com/en-us/library/ms684179(v=vs.85).aspx says: ++// "Windows 7, Windows Server 2008 R2, Windows Vista, and Windows ++// Server 2008: The LOAD_LIBRARY_SEARCH_* flags are available on ++// systems that have KB2533623 installed. To determine whether the ++// flags are available, use GetProcAddress to get the address of the ++// AddDllDirectory, RemoveDllDirectory, or SetDefaultDllDirectories ++// function. If GetProcAddress succeeds, the LOAD_LIBRARY_SEARCH_* ++// flags can be used with LoadLibraryEx." ++var useLoadLibraryEx bool ++ + var timeBeginPeriodRetValue uint32 + + // osRelaxMinNS indicates that sysmon shouldn't osRelax if the next +@@ -430,7 +478,8 @@ + // Only load winmm.dll if we need it. + // This avoids a dependency on winmm.dll for Go programs + // that run on new Windows versions. +- m32 := windowsLoadSystemLib(winmmdll[:]) ++ var winmmdll = []byte("winmm.dll\000") ++ m32 := windowsLoadSystemLib(winmmdll) + if m32 == 0 { + print("runtime: LoadLibraryExW failed; errno=", getlasterror(), "\n") + throw("winmm.dll not found") +@@ -471,6 +520,28 @@ + canUseLongPaths = true + } + ++var osVersionInfo struct { ++ majorVersion uint32 ++ minorVersion uint32 ++ buildNumber uint32 ++} ++ ++func initOsVersionInfo() { ++ info := _OSVERSIONINFOW{} ++ info.osVersionInfoSize = uint32(unsafe.Sizeof(info)) ++ stdcall1(_RtlGetVersion, uintptr(unsafe.Pointer(&info))) ++ osVersionInfo.majorVersion = info.majorVersion ++ osVersionInfo.minorVersion = info.minorVersion ++ osVersionInfo.buildNumber = info.buildNumber ++} ++ ++//go:linkname rtlGetNtVersionNumbers syscall.rtlGetNtVersionNumbers ++func rtlGetNtVersionNumbers(majorVersion *uint32, minorVersion *uint32, buildNumber *uint32) { ++ *majorVersion = osVersionInfo.majorVersion ++ *minorVersion = osVersionInfo.minorVersion ++ *buildNumber = osVersionInfo.buildNumber ++} ++ + func osinit() { + asmstdcallAddr = unsafe.Pointer(abi.FuncPCABI0(asmstdcall)) + +@@ -483,8 +554,8 @@ + initHighResTimer() + timeBeginPeriodRetValue = osRelax(false) + +- initSysDirectory() + initLongPathSupport() ++ initOsVersionInfo() + + numCPUStartup = getCPUCount() + +@@ -500,7 +571,7 @@ + //go:nosplit + func readRandom(r []byte) int { + n := 0 +- if stdcall2(_ProcessPrng, uintptr(unsafe.Pointer(&r[0])), uintptr(len(r)))&0xff != 0 { ++ if stdcall2(_RtlGenRandom, uintptr(unsafe.Pointer(&r[0])), uintptr(len(r)))&0xff != 0 { + n = len(r) + } + return n +Index: src/net/hook_windows.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/net/hook_windows.go b/src/net/hook_windows.go +--- a/src/net/hook_windows.go (revision 8cb5472d94c34b88733a81091bd328e70ee565a4) ++++ b/src/net/hook_windows.go (revision 6788c4c6f9fafb56729bad6b660f7ee2272d699f) +@@ -13,6 +13,7 @@ + hostsFilePath = windows.GetSystemDirectory() + "/Drivers/etc/hosts" + + // Placeholders for socket system calls. ++ socketFunc func(int, int, int) (syscall.Handle, error) = syscall.Socket + wsaSocketFunc func(int32, int32, int32, *syscall.WSAProtocolInfo, uint32, uint32) (syscall.Handle, error) = windows.WSASocket + connectFunc func(syscall.Handle, syscall.Sockaddr) error = syscall.Connect + listenFunc func(syscall.Handle, int) error = syscall.Listen +Index: src/net/internal/socktest/main_test.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/net/internal/socktest/main_test.go b/src/net/internal/socktest/main_test.go +--- a/src/net/internal/socktest/main_test.go (revision 8cb5472d94c34b88733a81091bd328e70ee565a4) ++++ b/src/net/internal/socktest/main_test.go (revision 6788c4c6f9fafb56729bad6b660f7ee2272d699f) +@@ -2,7 +2,7 @@ + // Use of this source code is governed by a BSD-style + // license that can be found in the LICENSE file. + +-//go:build !js && !plan9 && !wasip1 && !windows ++//go:build !js && !plan9 && !wasip1 + + package socktest_test + +Index: src/net/internal/socktest/main_windows_test.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/net/internal/socktest/main_windows_test.go b/src/net/internal/socktest/main_windows_test.go +new file mode 100644 +--- /dev/null (revision 6788c4c6f9fafb56729bad6b660f7ee2272d699f) ++++ b/src/net/internal/socktest/main_windows_test.go (revision 6788c4c6f9fafb56729bad6b660f7ee2272d699f) +@@ -0,0 +1,22 @@ ++// Copyright 2015 The Go Authors. All rights reserved. ++// Use of this source code is governed by a BSD-style ++// license that can be found in the LICENSE file. ++ ++package socktest_test ++ ++import "syscall" ++ ++var ( ++ socketFunc func(int, int, int) (syscall.Handle, error) ++ closeFunc func(syscall.Handle) error ++) ++ ++func installTestHooks() { ++ socketFunc = sw.Socket ++ closeFunc = sw.Closesocket ++} ++ ++func uninstallTestHooks() { ++ socketFunc = syscall.Socket ++ closeFunc = syscall.Closesocket ++} +Index: src/net/internal/socktest/sys_windows.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/net/internal/socktest/sys_windows.go b/src/net/internal/socktest/sys_windows.go +--- a/src/net/internal/socktest/sys_windows.go (revision 8cb5472d94c34b88733a81091bd328e70ee565a4) ++++ b/src/net/internal/socktest/sys_windows.go (revision 6788c4c6f9fafb56729bad6b660f7ee2272d699f) +@@ -9,6 +9,38 @@ + "syscall" + ) + ++// Socket wraps [syscall.Socket]. ++func (sw *Switch) Socket(family, sotype, proto int) (s syscall.Handle, err error) { ++ sw.once.Do(sw.init) ++ ++ so := &Status{Cookie: cookie(family, sotype, proto)} ++ sw.fmu.RLock() ++ f, _ := sw.fltab[FilterSocket] ++ sw.fmu.RUnlock() ++ ++ af, err := f.apply(so) ++ if err != nil { ++ return syscall.InvalidHandle, err ++ } ++ s, so.Err = syscall.Socket(family, sotype, proto) ++ if err = af.apply(so); err != nil { ++ if so.Err == nil { ++ syscall.Closesocket(s) ++ } ++ return syscall.InvalidHandle, err ++ } ++ ++ sw.smu.Lock() ++ defer sw.smu.Unlock() ++ if so.Err != nil { ++ sw.stats.getLocked(so.Cookie).OpenFailed++ ++ return syscall.InvalidHandle, so.Err ++ } ++ nso := sw.addLocked(s, family, sotype, proto) ++ sw.stats.getLocked(nso.Cookie).Opened++ ++ return s, nil ++} ++ + // WSASocket wraps [syscall.WSASocket]. + func (sw *Switch) WSASocket(family, sotype, proto int32, protinfo *syscall.WSAProtocolInfo, group uint32, flags uint32) (s syscall.Handle, err error) { + sw.once.Do(sw.init) +Index: src/net/main_windows_test.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/net/main_windows_test.go b/src/net/main_windows_test.go +--- a/src/net/main_windows_test.go (revision 8cb5472d94c34b88733a81091bd328e70ee565a4) ++++ b/src/net/main_windows_test.go (revision 6788c4c6f9fafb56729bad6b660f7ee2272d699f) +@@ -12,6 +12,7 @@ + + var ( + // Placeholders for saving original socket system calls. ++ origSocket = socketFunc + origWSASocket = wsaSocketFunc + origClosesocket = poll.CloseFunc + origConnect = connectFunc +@@ -21,6 +22,7 @@ + ) + + func installTestHooks() { ++ socketFunc = sw.Socket + wsaSocketFunc = sw.WSASocket + poll.CloseFunc = sw.Closesocket + connectFunc = sw.Connect +@@ -30,6 +32,7 @@ + } + + func uninstallTestHooks() { ++ socketFunc = origSocket + wsaSocketFunc = origWSASocket + poll.CloseFunc = origClosesocket + connectFunc = origConnect +Index: src/net/sock_windows.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/net/sock_windows.go b/src/net/sock_windows.go +--- a/src/net/sock_windows.go (revision 8cb5472d94c34b88733a81091bd328e70ee565a4) ++++ b/src/net/sock_windows.go (revision 6788c4c6f9fafb56729bad6b660f7ee2272d699f) +@@ -20,6 +20,21 @@ + func sysSocket(family, sotype, proto int) (syscall.Handle, error) { + s, err := wsaSocketFunc(int32(family), int32(sotype), int32(proto), + nil, 0, windows.WSA_FLAG_OVERLAPPED|windows.WSA_FLAG_NO_HANDLE_INHERIT) ++ if err == nil { ++ return s, nil ++ } ++ // WSA_FLAG_NO_HANDLE_INHERIT flag is not supported on some ++ // old versions of Windows, see ++ // https://msdn.microsoft.com/en-us/library/windows/desktop/ms742212(v=vs.85).aspx ++ // for details. Just use syscall.Socket, if windows.WSASocket failed. ++ ++ // See ../syscall/exec_unix.go for description of ForkLock. ++ syscall.ForkLock.RLock() ++ s, err = socketFunc(family, sotype, proto) ++ if err == nil { ++ syscall.CloseOnExec(s) ++ } ++ syscall.ForkLock.RUnlock() + if err != nil { + return syscall.InvalidHandle, os.NewSyscallError("socket", err) + } +Index: src/syscall/exec_windows.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/syscall/exec_windows.go b/src/syscall/exec_windows.go +--- a/src/syscall/exec_windows.go (revision 8cb5472d94c34b88733a81091bd328e70ee565a4) ++++ b/src/syscall/exec_windows.go (revision a5b2168bb836ed9d6601c626f95e56c07923f906) +@@ -14,7 +14,6 @@ + "unsafe" + ) + +-// ForkLock is not used on Windows. + var ForkLock sync.RWMutex + + // EscapeArg rewrites command line argument s as prescribed +@@ -254,6 +253,9 @@ + var zeroProcAttr ProcAttr + var zeroSysProcAttr SysProcAttr + ++//go:linkname rtlGetNtVersionNumbers ++func rtlGetNtVersionNumbers(majorVersion *uint32, minorVersion *uint32, buildNumber *uint32) ++ + func StartProcess(argv0 string, argv []string, attr *ProcAttr) (pid int, handle uintptr, err error) { + if len(argv0) == 0 { + return 0, 0, EWINDOWS +@@ -317,6 +319,17 @@ + } + } + ++ var maj, min, build uint32 ++ rtlGetNtVersionNumbers(&maj, &min, &build) ++ isWin7 := maj < 6 || (maj == 6 && min <= 1) ++ // NT kernel handles are divisible by 4, with the bottom 3 bits left as ++ // a tag. The fully set tag correlates with the types of handles we're ++ // concerned about here. Except, the kernel will interpret some ++ // special handle values, like -1, -2, and so forth, so kernelbase.dll ++ // checks to see that those bottom three bits are checked, but that top ++ // bit is not checked. ++ isLegacyWin7ConsoleHandle := func(handle Handle) bool { return isWin7 && handle&0x10000003 == 3 } ++ + p, _ := GetCurrentProcess() + parentProcess := p + if sys.ParentProcess != 0 { +@@ -325,7 +338,15 @@ + fd := make([]Handle, len(attr.Files)) + for i := range attr.Files { + if attr.Files[i] > 0 { +- err := DuplicateHandle(p, Handle(attr.Files[i]), parentProcess, &fd[i], 0, true, DUPLICATE_SAME_ACCESS) ++ destinationProcessHandle := parentProcess ++ ++ // On Windows 7, console handles aren't real handles, and can only be duplicated ++ // into the current process, not a parent one, which amounts to the same thing. ++ if parentProcess != p && isLegacyWin7ConsoleHandle(Handle(attr.Files[i])) { ++ destinationProcessHandle = p ++ } ++ ++ err := DuplicateHandle(p, Handle(attr.Files[i]), destinationProcessHandle, &fd[i], 0, true, DUPLICATE_SAME_ACCESS) + if err != nil { + return 0, 0, err + } +@@ -356,6 +377,14 @@ + + fd = append(fd, sys.AdditionalInheritedHandles...) + ++ // On Windows 7, console handles aren't real handles, so don't pass them ++ // through to PROC_THREAD_ATTRIBUTE_HANDLE_LIST. ++ for i := range fd { ++ if isLegacyWin7ConsoleHandle(fd[i]) { ++ fd[i] = 0 ++ } ++ } ++ + // The presence of a NULL handle in the list is enough to cause PROC_THREAD_ATTRIBUTE_HANDLE_LIST + // to treat the entire list as empty, so remove NULL handles. + j := 0 +Index: src/runtime/syscall_windows.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/runtime/syscall_windows.go b/src/runtime/syscall_windows.go +--- a/src/runtime/syscall_windows.go (revision a5b2168bb836ed9d6601c626f95e56c07923f906) ++++ b/src/runtime/syscall_windows.go (revision f56f1e23507e646c85243a71bde7b9629b2f970c) +@@ -413,10 +413,20 @@ + + const _LOAD_LIBRARY_SEARCH_SYSTEM32 = 0x00000800 + ++// When available, this function will use LoadLibraryEx with the filename ++// parameter and the important SEARCH_SYSTEM32 argument. But on systems that ++// do not have that option, absoluteFilepath should contain a fallback ++// to the full path inside of system32 for use with vanilla LoadLibrary. ++// + //go:linkname syscall_loadsystemlibrary syscall.loadsystemlibrary +-func syscall_loadsystemlibrary(filename *uint16) (handle, err uintptr) { +- handle, _, err = syscall_SyscallN(uintptr(unsafe.Pointer(_LoadLibraryExW)), uintptr(unsafe.Pointer(filename)), 0, _LOAD_LIBRARY_SEARCH_SYSTEM32) ++func syscall_loadsystemlibrary(filename *uint16, absoluteFilepath *uint16) (handle, err uintptr) { ++ if useLoadLibraryEx { ++ handle, _, err = syscall_SyscallN(uintptr(unsafe.Pointer(_LoadLibraryExW)), uintptr(unsafe.Pointer(filename)), 0, _LOAD_LIBRARY_SEARCH_SYSTEM32) ++ } else { ++ handle, _, err = syscall_SyscallN(uintptr(unsafe.Pointer(_LoadLibraryW)), uintptr(unsafe.Pointer(absoluteFilepath))) ++ } + KeepAlive(filename) ++ KeepAlive(absoluteFilepath) + if handle != 0 { + err = 0 + } +Index: src/syscall/dll_windows.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/syscall/dll_windows.go b/src/syscall/dll_windows.go +--- a/src/syscall/dll_windows.go (revision a5b2168bb836ed9d6601c626f95e56c07923f906) ++++ b/src/syscall/dll_windows.go (revision f56f1e23507e646c85243a71bde7b9629b2f970c) +@@ -45,7 +45,7 @@ + //go:noescape + func SyscallN(trap uintptr, args ...uintptr) (r1, r2 uintptr, err Errno) + func loadlibrary(filename *uint16) (handle uintptr, err Errno) +-func loadsystemlibrary(filename *uint16) (handle uintptr, err Errno) ++func loadsystemlibrary(filename *uint16, absoluteFilepath *uint16) (handle uintptr, err Errno) + func getprocaddress(handle uintptr, procname *uint8) (proc uintptr, err Errno) + + // A DLL implements access to a single DLL. +@@ -54,6 +54,9 @@ + Handle Handle + } + ++//go:linkname getSystemDirectory ++func getSystemDirectory() string // Implemented in runtime package. ++ + // LoadDLL loads the named DLL file into memory. + // + // If name is not an absolute path and is not a known system DLL used by +@@ -70,7 +73,11 @@ + var h uintptr + var e Errno + if sysdll.IsSystemDLL[name] { +- h, e = loadsystemlibrary(namep) ++ absoluteFilepathp, err := UTF16PtrFromString(getSystemDirectory() + name) ++ if err != nil { ++ return nil, err ++ } ++ h, e = loadsystemlibrary(namep, absoluteFilepathp) + } else { + h, e = loadlibrary(namep) + } diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index a9f99dc8..9ba36ed8 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -179,12 +179,8 @@ jobs: - name: Revert Golang1.25 commit for Windows7/8 if: ${{ matrix.jobs.goos == 'windows' && matrix.jobs.goversion == '' }} run: | - alias curl='curl -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}"' cd $(go env GOROOT) - curl https://github.com/MetaCubeX/go/commit/8cb5472d94c34b88733a81091bd328e70ee565a4.diff | patch --verbose -p 1 - curl https://github.com/MetaCubeX/go/commit/6788c4c6f9fafb56729bad6b660f7ee2272d699f.diff | patch --verbose -p 1 - curl https://github.com/MetaCubeX/go/commit/a5b2168bb836ed9d6601c626f95e56c07923f906.diff | patch --verbose -p 1 - curl https://github.com/MetaCubeX/go/commit/f56f1e23507e646c85243a71bde7b9629b2f970c.diff | patch --verbose -p 1 + patch --verbose -p 1 < $GITHUB_WORKSPACE/.github/patch/go1.25.patch # modify from https://github.com/restic/restic/issues/4636#issuecomment-1896455557 # this patch file only works on golang1.24.x @@ -198,12 +194,8 @@ jobs: - name: Revert Golang1.24 commit for Windows7/8 if: ${{ matrix.jobs.goos == 'windows' && matrix.jobs.goversion == '1.24' }} run: | - alias curl='curl -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}"' cd $(go env GOROOT) - curl https://github.com/MetaCubeX/go/commit/2a406dc9f1ea7323d6ca9fccb2fe9ddebb6b1cc8.diff | patch --verbose -p 1 - curl https://github.com/MetaCubeX/go/commit/7b1fd7d39c6be0185fbe1d929578ab372ac5c632.diff | patch --verbose -p 1 - curl https://github.com/MetaCubeX/go/commit/979d6d8bab3823ff572ace26767fd2ce3cf351ae.diff | patch --verbose -p 1 - curl https://github.com/MetaCubeX/go/commit/ac3e93c061779dfefc0dd13a5b6e6f764a25621e.diff | patch --verbose -p 1 + patch --verbose -p 1 < $GITHUB_WORKSPACE/.github/patch/go1.24.patch # modify from https://github.com/restic/restic/issues/4636#issuecomment-1896455557 # this patch file only works on golang1.23.x @@ -217,12 +209,8 @@ jobs: - name: Revert Golang1.23 commit for Windows7/8 if: ${{ matrix.jobs.goos == 'windows' && matrix.jobs.goversion == '1.23' }} run: | - alias curl='curl -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}"' cd $(go env GOROOT) - curl https://github.com/MetaCubeX/go/commit/9ac42137ef6730e8b7daca016ece831297a1d75b.diff | patch --verbose -p 1 - curl https://github.com/MetaCubeX/go/commit/21290de8a4c91408de7c2b5b68757b1e90af49dd.diff | patch --verbose -p 1 - curl https://github.com/MetaCubeX/go/commit/6a31d3fa8e47ddabc10bd97bff10d9a85f4cfb76.diff | patch --verbose -p 1 - curl https://github.com/MetaCubeX/go/commit/69e2eed6dd0f6d815ebf15797761c13f31213dd6.diff | patch --verbose -p 1 + patch --verbose -p 1 < $GITHUB_WORKSPACE/.github/patch/go1.23.patch # modify from https://github.com/restic/restic/issues/4636#issuecomment-1896455557 # this patch file only works on golang1.22.x @@ -236,20 +224,15 @@ jobs: - name: Revert Golang1.22 commit for Windows7/8 if: ${{ matrix.jobs.goos == 'windows' && matrix.jobs.goversion == '1.22' }} run: | - alias curl='curl -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}"' cd $(go env GOROOT) - curl https://github.com/MetaCubeX/go/commit/9779155f18b6556a034f7bb79fb7fb2aad1e26a9.diff | patch --verbose -p 1 - curl https://github.com/MetaCubeX/go/commit/ef0606261340e608017860b423ffae5c1ce78239.diff | patch --verbose -p 1 - curl https://github.com/MetaCubeX/go/commit/7f83badcb925a7e743188041cb6e561fc9b5b642.diff | patch --verbose -p 1 - curl https://github.com/MetaCubeX/go/commit/83ff9782e024cb328b690cbf0da4e7848a327f4f.diff | patch --verbose -p 1 + patch --verbose -p 1 < $GITHUB_WORKSPACE/.github/patch/go1.22.patch # modify from https://github.com/restic/restic/issues/4636#issuecomment-1896455557 - name: Revert Golang1.21 commit for Windows7/8 if: ${{ matrix.jobs.goos == 'windows' && matrix.jobs.goversion == '1.21' }} run: | - alias curl='curl -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}"' cd $(go env GOROOT) - curl https://github.com/golang/go/commit/9e43850a3298a9b8b1162ba0033d4c53f8637571.diff | patch --verbose -R -p 1 + patch --verbose -p 1 < $GITHUB_WORKSPACE/.github/patch/go1.21.patch - name: Set variables run: | diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 8d7a35c2..c6ac69cd 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -48,89 +48,11 @@ jobs: with: go-version: ${{ matrix.go-version }} - # modify from https://github.com/restic/restic/issues/4636#issuecomment-1896455557 - # this patch file only works on golang1.25.x - # that means after golang1.26 release it must be changed - # see: https://github.com/MetaCubeX/go/commits/release-branch.go1.25/ - # revert: - # 693def151adff1af707d82d28f55dba81ceb08e1: "crypto/rand,runtime: switch RtlGenRandom for ProcessPrng" - # 7c1157f9544922e96945196b47b95664b1e39108: "net: remove sysSocket fallback for Windows 7" - # 48042aa09c2f878c4faa576948b07fe625c4707a: "syscall: remove Windows 7 console handle workaround" - # a17d959debdb04cd550016a3501dd09d50cd62e7: "runtime: always use LoadLibraryEx to load system libraries" - - name: Revert Golang1.25 commit for Windows7/8 - if: ${{ runner.os == 'Windows' && matrix.go-version == '1.25' }} + - name: Revert Golang commit for Windows7/8 + if: ${{ runner.os == 'Windows' && matrix.go-version != '1.20' }} run: | - alias curl='curl -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}"' cd $(go env GOROOT) - curl https://github.com/MetaCubeX/go/commit/8cb5472d94c34b88733a81091bd328e70ee565a4.diff | patch --verbose -p 1 - curl https://github.com/MetaCubeX/go/commit/6788c4c6f9fafb56729bad6b660f7ee2272d699f.diff | patch --verbose -p 1 - curl https://github.com/MetaCubeX/go/commit/a5b2168bb836ed9d6601c626f95e56c07923f906.diff | patch --verbose -p 1 - curl https://github.com/MetaCubeX/go/commit/f56f1e23507e646c85243a71bde7b9629b2f970c.diff | patch --verbose -p 1 - - # modify from https://github.com/restic/restic/issues/4636#issuecomment-1896455557 - # this patch file only works on golang1.24.x - # that means after golang1.25 release it must be changed - # see: https://github.com/MetaCubeX/go/commits/release-branch.go1.24/ - # revert: - # 693def151adff1af707d82d28f55dba81ceb08e1: "crypto/rand,runtime: switch RtlGenRandom for ProcessPrng" - # 7c1157f9544922e96945196b47b95664b1e39108: "net: remove sysSocket fallback for Windows 7" - # 48042aa09c2f878c4faa576948b07fe625c4707a: "syscall: remove Windows 7 console handle workaround" - # a17d959debdb04cd550016a3501dd09d50cd62e7: "runtime: always use LoadLibraryEx to load system libraries" - - name: Revert Golang1.24 commit for Windows7/8 - if: ${{ runner.os == 'Windows' && matrix.go-version == '1.24' }} - run: | - alias curl='curl -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}"' - cd $(go env GOROOT) - curl https://github.com/MetaCubeX/go/commit/2a406dc9f1ea7323d6ca9fccb2fe9ddebb6b1cc8.diff | patch --verbose -p 1 - curl https://github.com/MetaCubeX/go/commit/7b1fd7d39c6be0185fbe1d929578ab372ac5c632.diff | patch --verbose -p 1 - curl https://github.com/MetaCubeX/go/commit/979d6d8bab3823ff572ace26767fd2ce3cf351ae.diff | patch --verbose -p 1 - curl https://github.com/MetaCubeX/go/commit/ac3e93c061779dfefc0dd13a5b6e6f764a25621e.diff | patch --verbose -p 1 - - # modify from https://github.com/restic/restic/issues/4636#issuecomment-1896455557 - # this patch file only works on golang1.23.x - # that means after golang1.24 release it must be changed - # see: https://github.com/MetaCubeX/go/commits/release-branch.go1.23/ - # revert: - # 693def151adff1af707d82d28f55dba81ceb08e1: "crypto/rand,runtime: switch RtlGenRandom for ProcessPrng" - # 7c1157f9544922e96945196b47b95664b1e39108: "net: remove sysSocket fallback for Windows 7" - # 48042aa09c2f878c4faa576948b07fe625c4707a: "syscall: remove Windows 7 console handle workaround" - # a17d959debdb04cd550016a3501dd09d50cd62e7: "runtime: always use LoadLibraryEx to load system libraries" - - name: Revert Golang1.23 commit for Windows7/8 - if: ${{ runner.os == 'Windows' && matrix.go-version == '1.23' }} - run: | - alias curl='curl -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}"' - cd $(go env GOROOT) - curl https://github.com/MetaCubeX/go/commit/9ac42137ef6730e8b7daca016ece831297a1d75b.diff | patch --verbose -p 1 - curl https://github.com/MetaCubeX/go/commit/21290de8a4c91408de7c2b5b68757b1e90af49dd.diff | patch --verbose -p 1 - curl https://github.com/MetaCubeX/go/commit/6a31d3fa8e47ddabc10bd97bff10d9a85f4cfb76.diff | patch --verbose -p 1 - curl https://github.com/MetaCubeX/go/commit/69e2eed6dd0f6d815ebf15797761c13f31213dd6.diff | patch --verbose -p 1 - - # modify from https://github.com/restic/restic/issues/4636#issuecomment-1896455557 - # this patch file only works on golang1.22.x - # that means after golang1.23 release it must be changed - # see: https://github.com/MetaCubeX/go/commits/release-branch.go1.22/ - # revert: - # 693def151adff1af707d82d28f55dba81ceb08e1: "crypto/rand,runtime: switch RtlGenRandom for ProcessPrng" - # 7c1157f9544922e96945196b47b95664b1e39108: "net: remove sysSocket fallback for Windows 7" - # 48042aa09c2f878c4faa576948b07fe625c4707a: "syscall: remove Windows 7 console handle workaround" - # a17d959debdb04cd550016a3501dd09d50cd62e7: "runtime: always use LoadLibraryEx to load system libraries" - - name: Revert Golang1.22 commit for Windows7/8 - if: ${{ runner.os == 'Windows' && matrix.go-version == '1.22' }} - run: | - alias curl='curl -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}"' - cd $(go env GOROOT) - curl https://github.com/MetaCubeX/go/commit/9779155f18b6556a034f7bb79fb7fb2aad1e26a9.diff | patch --verbose -p 1 - curl https://github.com/MetaCubeX/go/commit/ef0606261340e608017860b423ffae5c1ce78239.diff | patch --verbose -p 1 - curl https://github.com/MetaCubeX/go/commit/7f83badcb925a7e743188041cb6e561fc9b5b642.diff | patch --verbose -p 1 - curl https://github.com/MetaCubeX/go/commit/83ff9782e024cb328b690cbf0da4e7848a327f4f.diff | patch --verbose -p 1 - - # modify from https://github.com/restic/restic/issues/4636#issuecomment-1896455557 - - name: Revert Golang1.21 commit for Windows7/8 - if: ${{ runner.os == 'Windows' && matrix.go-version == '1.21' }} - run: | - alias curl='curl -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}"' - cd $(go env GOROOT) - curl https://github.com/golang/go/commit/9e43850a3298a9b8b1162ba0033d4c53f8637571.diff | patch --verbose -R -p 1 + patch --verbose -p 1 < $GITHUB_WORKSPACE/.github/patch/go${{matrix.go-version}}.patch - name: Test run: go test ./... -v -count=1