diff options
Diffstat (limited to 'src/runtime/os_windows.go')
-rw-r--r-- | src/runtime/os_windows.go | 64 |
1 files changed, 54 insertions, 10 deletions
diff --git a/src/runtime/os_windows.go b/src/runtime/os_windows.go index 5607bf95c1..a3d0bcc596 100644 --- a/src/runtime/os_windows.go +++ b/src/runtime/os_windows.go @@ -29,6 +29,7 @@ const ( //go:cgo_import_dynamic runtime._GetProcessAffinityMask GetProcessAffinityMask%3 "kernel32.dll" //go:cgo_import_dynamic runtime._GetQueuedCompletionStatus GetQueuedCompletionStatus%5 "kernel32.dll" //go:cgo_import_dynamic runtime._GetStdHandle GetStdHandle%1 "kernel32.dll" +//go:cgo_import_dynamic runtime._GetSystemDirectoryA GetSystemDirectoryA%2 "kernel32.dll" //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._LoadLibraryW LoadLibraryW%1 "kernel32.dll" @@ -46,12 +47,9 @@ const ( //go:cgo_import_dynamic runtime._VirtualAlloc VirtualAlloc%4 "kernel32.dll" //go:cgo_import_dynamic runtime._VirtualFree VirtualFree%3 "kernel32.dll" //go:cgo_import_dynamic runtime._VirtualQuery VirtualQuery%3 "kernel32.dll" -//go:cgo_import_dynamic runtime._WSAGetOverlappedResult WSAGetOverlappedResult%5 "ws2_32.dll" //go:cgo_import_dynamic runtime._WaitForSingleObject WaitForSingleObject%2 "kernel32.dll" //go:cgo_import_dynamic runtime._WriteConsoleW WriteConsoleW%5 "kernel32.dll" //go:cgo_import_dynamic runtime._WriteFile WriteFile%5 "kernel32.dll" -//go:cgo_import_dynamic runtime._timeBeginPeriod timeBeginPeriod%1 "winmm.dll" -//go:cgo_import_dynamic runtime._timeEndPeriod timeEndPeriod%1 "winmm.dll" type stdFunction unsafe.Pointer @@ -74,6 +72,7 @@ var ( _GetProcessAffinityMask, _GetQueuedCompletionStatus, _GetStdHandle, + _GetSystemDirectoryA, _GetSystemInfo, _GetSystemTimeAsFileTime, _GetThreadContext, @@ -94,12 +93,9 @@ var ( _VirtualAlloc, _VirtualFree, _VirtualQuery, - _WSAGetOverlappedResult, _WaitForSingleObject, _WriteConsoleW, _WriteFile, - _timeBeginPeriod, - _timeEndPeriod, _ stdFunction // Following syscalls are only available on some Windows PCs. @@ -107,6 +103,7 @@ var ( _AddDllDirectory, _AddVectoredContinueHandler, _GetQueuedCompletionStatusEx, + _LoadLibraryExA, _LoadLibraryExW, _ stdFunction @@ -124,6 +121,12 @@ var ( // links wrong printf function to cgo executable (see issue // 12030 for details). _NtWaitForSingleObject stdFunction + + // These are from non-kernel32.dll, so we prefer to LoadLibraryEx them. + _timeBeginPeriod, + _timeEndPeriod, + _WSAGetOverlappedResult, + _ stdFunction ) // Function to be called by windows CreateThread @@ -171,6 +174,26 @@ func windowsFindfunc(lib uintptr, name []byte) stdFunction { return stdFunction(unsafe.Pointer(f)) } +var sysDirectory [521]byte +var sysDirectoryLen uintptr + +func windowsLoadSystemLib(name []byte) uintptr { + if useLoadLibraryEx { + return stdcall3(_LoadLibraryExA, uintptr(unsafe.Pointer(&name[0])), 0, _LOAD_LIBRARY_SEARCH_SYSTEM32) + } else { + if sysDirectoryLen == 0 { + l := stdcall2(_GetSystemDirectoryA, uintptr(unsafe.Pointer(&sysDirectory[0])), uintptr(len(sysDirectory)-1)) + if l == 0 || l > uintptr(len(sysDirectory)-1) { + throw("Unable to determine system directory") + } + sysDirectory[l] = '\\' + sysDirectoryLen = l + 1 + } + absName := append(sysDirectory[:sysDirectoryLen], name...) + return stdcall1(_LoadLibraryA, uintptr(unsafe.Pointer(&absName[0]))) + } +} + func loadOptionalSyscalls() { var kernel32dll = []byte("kernel32.dll\000") k32 := stdcall1(_LoadLibraryA, uintptr(unsafe.Pointer(&kernel32dll[0]))) @@ -180,22 +203,45 @@ func loadOptionalSyscalls() { _AddDllDirectory = windowsFindfunc(k32, []byte("AddDllDirectory\000")) _AddVectoredContinueHandler = windowsFindfunc(k32, []byte("AddVectoredContinueHandler\000")) _GetQueuedCompletionStatusEx = windowsFindfunc(k32, []byte("GetQueuedCompletionStatusEx\000")) + _LoadLibraryExA = windowsFindfunc(k32, []byte("LoadLibraryExA\000")) _LoadLibraryExW = windowsFindfunc(k32, []byte("LoadLibraryExW\000")) + useLoadLibraryEx = (_LoadLibraryExW != nil && _LoadLibraryExA != nil && _AddDllDirectory != nil) var advapi32dll = []byte("advapi32.dll\000") - a32 := stdcall1(_LoadLibraryA, uintptr(unsafe.Pointer(&advapi32dll[0]))) + a32 := windowsLoadSystemLib(advapi32dll) if a32 == 0 { throw("advapi32.dll not found") } _RtlGenRandom = windowsFindfunc(a32, []byte("SystemFunction036\000")) var ntdll = []byte("ntdll.dll\000") - n32 := stdcall1(_LoadLibraryA, uintptr(unsafe.Pointer(&ntdll[0]))) + n32 := windowsLoadSystemLib(ntdll) if n32 == 0 { throw("ntdll.dll not found") } _NtWaitForSingleObject = windowsFindfunc(n32, []byte("NtWaitForSingleObject\000")) + var winmmdll = []byte("winmm.dll\000") + m32 := windowsLoadSystemLib(winmmdll) + if m32 == 0 { + throw("winmm.dll not found") + } + _timeBeginPeriod = windowsFindfunc(m32, []byte("timeBeginPeriod\000")) + _timeEndPeriod = windowsFindfunc(m32, []byte("timeEndPeriod\000")) + if _timeBeginPeriod == nil || _timeEndPeriod == nil { + throw("timeBegin/EndPeriod not found") + } + + var ws232dll = []byte("ws2_32.dll\000") + ws232 := windowsLoadSystemLib(ws232dll) + if ws232 == 0 { + throw("ws2_32.dll not found") + } + _WSAGetOverlappedResult = windowsFindfunc(ws232, []byte("WSAGetOverlappedResult\000")) + if _WSAGetOverlappedResult == nil { + throw("WSAGetOverlappedResult not found") + } + if windowsFindfunc(n32, []byte("wine_get_version\000")) != nil { // running on Wine initWine(k32) @@ -302,8 +348,6 @@ func osinit() { loadOptionalSyscalls() - useLoadLibraryEx = (_LoadLibraryExW != nil && _AddDllDirectory != nil) - disableWER() initExceptionHandler() |