mirror of
https://github.com/MetaCubeX/mihomo.git
synced 2025-12-19 16:30:07 +08:00
Some checks failed
Test / test (1.20, macos-15-intel) (push) Has been cancelled
Test / test (1.20, macos-latest) (push) Has been cancelled
Test / test (1.20, ubuntu-24.04-arm) (push) Has been cancelled
Test / test (1.20, ubuntu-latest) (push) Has been cancelled
Test / test (1.20, windows-latest) (push) Has been cancelled
Test / test (1.21, macos-15-intel) (push) Has been cancelled
Test / test (1.21, macos-latest) (push) Has been cancelled
Test / test (1.21, ubuntu-24.04-arm) (push) Has been cancelled
Test / test (1.21, ubuntu-latest) (push) Has been cancelled
Test / test (1.21, windows-latest) (push) Has been cancelled
Test / test (1.22, macos-15-intel) (push) Has been cancelled
Test / test (1.22, macos-latest) (push) Has been cancelled
Test / test (1.22, ubuntu-24.04-arm) (push) Has been cancelled
Test / test (1.22, ubuntu-latest) (push) Has been cancelled
Test / test (1.22, windows-latest) (push) Has been cancelled
Test / test (1.23, macos-15-intel) (push) Has been cancelled
Test / test (1.23, macos-latest) (push) Has been cancelled
Test / test (1.23, ubuntu-24.04-arm) (push) Has been cancelled
Test / test (1.23, ubuntu-latest) (push) Has been cancelled
Test / test (1.23, windows-latest) (push) Has been cancelled
Test / test (1.24, macos-15-intel) (push) Has been cancelled
Test / test (1.24, macos-latest) (push) Has been cancelled
Test / test (1.24, ubuntu-24.04-arm) (push) Has been cancelled
Test / test (1.24, ubuntu-latest) (push) Has been cancelled
Test / test (1.24, windows-latest) (push) Has been cancelled
Test / test (1.25, macos-15-intel) (push) Has been cancelled
Test / test (1.25, macos-latest) (push) Has been cancelled
Test / test (1.25, ubuntu-24.04-arm) (push) Has been cancelled
Test / test (1.25, ubuntu-latest) (push) Has been cancelled
Test / test (1.25, windows-latest) (push) Has been cancelled
Trigger CMFA Update / trigger-CMFA-update (push) Has been cancelled
658 lines
26 KiB
Diff
658 lines
26 KiB
Diff
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)
|
|
}
|