From db5f48e779d7e3599cc3c7595cdf9c37eb71a9d5 Mon Sep 17 00:00:00 2001 From: Pali Rohár Date: Sun, 7 May 2023 16:40:28 +0200 Subject: windows: Deduplicate code and move helper functions to new file win32-helpers.c Function win32_strerror() was duplicated in two different files: win32-cfgmgr32.c and win32-kldbg.c. Now there is only one in win32-helpers.c. --- lib/Makefile | 12 +++++-- lib/i386-io-windows.h | 7 ++-- lib/win32-cfgmgr32.c | 81 ++---------------------------------------- lib/win32-helpers.c | 97 +++++++++++++++++++++++++++++++++++++++++++++++++++ lib/win32-helpers.h | 4 +++ lib/win32-kldbg.c | 48 +------------------------ lib/win32-sysdbg.c | 1 + 7 files changed, 118 insertions(+), 132 deletions(-) create mode 100644 lib/win32-helpers.c create mode 100644 lib/win32-helpers.h diff --git a/lib/Makefile b/lib/Makefile index a89ac14..4110ad3 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -75,6 +75,10 @@ ifdef PCI_HAVE_PM_WIN32_SYSDBG OBJS += win32-sysdbg endif +ifdef PCI_OS_WINDOWS +OBJS += win32-helpers +endif + all: $(PCILIB) $(PCILIBPC) ifeq ($(SHARED),no) @@ -143,9 +147,11 @@ names-hwdb.o: names-hwdb.c $(INCL) names.h filter.o: filter.c $(INCL) nbsd-libpci.o: nbsd-libpci.c $(INCL) hurd.o: hurd.c $(INCL) -win32-cfgmgr32.o: win32-cfgmgr32.c $(INCL) -win32-kldbg.o: win32-kldbg.c $(INCL) -win32-sysdbg.o: win32-sysdbg.c $(INCL) +win32-helpers.o: win32-helpers.c $(INCL) win32-helpers.h +win32-cfgmgr32.o: win32-cfgmgr32.c $(INCL) win32-helpers.h +win32-kldbg.o: win32-kldbg.c $(INCL) win32-helpers.h +win32-sysdbg.o: win32-sysdbg.c $(INCL) win32-helpers.h +i386-io-windows.h: win32-helpers.h # MinGW32 toolchain has some required Win32 header files in /ddk subdirectory. # But these header files include another header files from /ddk subdirectory diff --git a/lib/i386-io-windows.h b/lib/i386-io-windows.h index fa0db58..69ed821 100644 --- a/lib/i386-io-windows.h +++ b/lib/i386-io-windows.h @@ -12,6 +12,7 @@ #include #include +#include "win32-helpers.h" #include "i386-io-access.h" @@ -1276,9 +1277,7 @@ intel_setup_io(struct pci_access *a) { #ifndef _WIN64 /* 16/32-bit non-NT systems allow applications to access PCI I/O ports without any special setup. */ - OSVERSIONINFOA version; - version.dwOSVersionInfoSize = sizeof(version); - if (GetVersionExA(&version) && version.dwPlatformId < VER_PLATFORM_WIN32_NT) + if (win32_is_non_nt_system()) { a->debug("Detected 16/32-bit non-NT system, skipping NT setup..."); return 1; @@ -1296,7 +1295,7 @@ intel_setup_io(struct pci_access *a) if (!SetProcessUserModeIOPL()) { DWORD error = GetLastError(); - a->debug("NT ProcessUserModeIOPL call failed: %s.", error == ERROR_INVALID_FUNCTION ? "Not Implemented" : error == ERROR_PRIVILEGE_NOT_HELD ? "Access Denied" : "Operation Failed"); + a->debug("NT ProcessUserModeIOPL call failed: %s.", error == ERROR_INVALID_FUNCTION ? "Call is not supported" : win32_strerror(error)); return 0; } diff --git a/lib/win32-cfgmgr32.c b/lib/win32-cfgmgr32.c index 4acac2e..a001187 100644 --- a/lib/win32-cfgmgr32.c +++ b/lib/win32-cfgmgr32.c @@ -17,6 +17,7 @@ #include /* for wcslen(), wcscpy() */ #include "internal.h" +#include "win32-helpers.h" /* Unfortunately MinGW32 toolchain does not provide these cfgmgr32 constants. */ @@ -213,32 +214,6 @@ cr_strerror(CONFIGRET cr_error_id) return cr_errors[cr_error_id]; } -static const char * -win32_strerror(DWORD win32_error_id) -{ - /* - * Use static buffer which is large enough. - * Hopefully no Win32 API error message string is longer than 4 kB. - */ - static char buffer[4096]; - DWORD len; - - len = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, win32_error_id, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), buffer, sizeof(buffer), NULL); - - /* FormatMessage() automatically appends ".\r\n" to the error message. */ - if (len && buffer[len-1] == '\n') - buffer[--len] = '\0'; - if (len && buffer[len-1] == '\r') - buffer[--len] = '\0'; - if (len && buffer[len-1] == '.') - buffer[--len] = '\0'; - - if (!len) - sprintf(buffer, "Unknown Win32 error %lu", win32_error_id); - - return buffer; -} - static int fmt_validate(const char *s, int len, const char *fmt) { @@ -267,56 +242,6 @@ seq_xdigit_validate(const char *s, int mult, int min) return 1; } -static BOOL -is_non_nt_system(void) -{ - OSVERSIONINFOA version; - version.dwOSVersionInfoSize = sizeof(version); - return GetVersionExA(&version) && version.dwPlatformId < VER_PLATFORM_WIN32_NT; -} - -static BOOL -is_32bit_on_win8_64bit_system(void) -{ -#ifdef _WIN64 - return FALSE; -#else - BOOL (WINAPI *MyIsWow64Process)(HANDLE, PBOOL); - OSVERSIONINFOA version; - HMODULE kernel32; - BOOL is_wow64; - - /* Check for Windows 8 (NT 6.2). */ - version.dwOSVersionInfoSize = sizeof(version); - if (!GetVersionExA(&version) || - version.dwPlatformId != VER_PLATFORM_WIN32_NT || - version.dwMajorVersion < 6 || - (version.dwMajorVersion == 6 && version.dwMinorVersion < 2)) - return FALSE; - - /* - * Check for 64-bit system via IsWow64Process() function exported - * from 32-bit kernel32.dll library available on the 64-bit systems. - * Resolve pointer to this function at runtime as this code path is - * primary running on 32-bit systems where are not available 64-bit - * functions. - */ - - kernel32 = GetModuleHandleA("kernel32.dll"); - if (!kernel32) - return FALSE; - - MyIsWow64Process = (void *)GetProcAddress(kernel32, "IsWow64Process"); - if (!MyIsWow64Process) - return FALSE; - - if (!MyIsWow64Process(GetCurrentProcess(), &is_wow64)) - return FALSE; - - return is_wow64; -#endif -} - static LPWSTR get_device_service_name(struct pci_access *a, DEVINST devinst, DEVINSTID_A devinst_id, BOOL *supported) { @@ -995,7 +920,7 @@ fill_resources(struct pci_dev *d, DEVINST devinst, DEVINSTID_A devinst_id) * application using the hardware resource APIs. For example: An AMD64 * application for AMD64 systems. */ - if (cr == CR_CALL_NOT_IMPLEMENTED && is_32bit_on_win8_64bit_system()) + if (cr == CR_CALL_NOT_IMPLEMENTED && win32_is_32bit_on_win8_64bit_system()) { static BOOL warn_once = FALSE; if (!warn_once) @@ -1010,7 +935,7 @@ fill_resources(struct pci_dev *d, DEVINST devinst, DEVINSTID_A devinst_id) } bar_res_count = 0; - non_nt_system = is_non_nt_system(); + non_nt_system = win32_is_non_nt_system(); is_bar_res = TRUE; if (non_nt_system) diff --git a/lib/win32-helpers.c b/lib/win32-helpers.c new file mode 100644 index 0000000..dd47865 --- /dev/null +++ b/lib/win32-helpers.c @@ -0,0 +1,97 @@ +/* + * The PCI Library -- Win32 helper functions + * + * Copyright (c) 2023 Pali Rohár + * + * Can be freely distributed and used under the terms of the GNU GPL v2+ + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include +#include /* for sprintf() */ + +#include "win32-helpers.h" + +const char * +win32_strerror(DWORD win32_error_id) +{ + /* + * Use static buffer which is large enough. + * Hopefully no Win32 API error message string is longer than 4 kB. + */ + static char buffer[4096]; + DWORD len; + + len = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, win32_error_id, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), buffer, sizeof(buffer), NULL); + + /* FormatMessage() automatically appends ".\r\n" to the error message. */ + if (len && buffer[len-1] == '\n') + buffer[--len] = '\0'; + if (len && buffer[len-1] == '\r') + buffer[--len] = '\0'; + if (len && buffer[len-1] == '.') + buffer[--len] = '\0'; + + if (!len) + sprintf(buffer, "Unknown Win32 error %lu", win32_error_id); + + return buffer; +} + +BOOL +win32_is_non_nt_system(void) +{ + OSVERSIONINFOA version; + version.dwOSVersionInfoSize = sizeof(version); + return GetVersionExA(&version) && version.dwPlatformId < VER_PLATFORM_WIN32_NT; +} + +BOOL +win32_is_32bit_on_64bit_system(void) +{ + BOOL (WINAPI *MyIsWow64Process)(HANDLE, PBOOL); + HMODULE kernel32; + BOOL is_wow64; + + /* + * Check for 64-bit system via IsWow64Process() function exported + * from 32-bit kernel32.dll library available on the 64-bit systems. + * Resolve pointer to this function at runtime as this code path is + * primary running on 32-bit systems where are not available 64-bit + * functions. + */ + + kernel32 = GetModuleHandle(TEXT("kernel32.dll")); + if (!kernel32) + return FALSE; + + MyIsWow64Process = (void *)GetProcAddress(kernel32, "IsWow64Process"); + if (!MyIsWow64Process) + return FALSE; + + if (!MyIsWow64Process(GetCurrentProcess(), &is_wow64)) + return FALSE; + + return is_wow64; +} + +BOOL +win32_is_32bit_on_win8_64bit_system(void) +{ +#ifdef _WIN64 + return FALSE; +#else + OSVERSIONINFOA version; + + /* Check for Windows 8 (NT 6.2). */ + version.dwOSVersionInfoSize = sizeof(version); + if (!GetVersionExA(&version) || + version.dwPlatformId != VER_PLATFORM_WIN32_NT || + version.dwMajorVersion < 6 || + (version.dwMajorVersion == 6 && version.dwMinorVersion < 2)) + return FALSE; + + return win32_is_32bit_on_64bit_system(); +#endif +} diff --git a/lib/win32-helpers.h b/lib/win32-helpers.h new file mode 100644 index 0000000..18f75de --- /dev/null +++ b/lib/win32-helpers.h @@ -0,0 +1,4 @@ +const char *win32_strerror(DWORD win32_error_id); +BOOL win32_is_non_nt_system(void); +BOOL win32_is_32bit_on_64bit_system(void); +BOOL win32_is_32bit_on_win8_64bit_system(void); diff --git a/lib/win32-kldbg.c b/lib/win32-kldbg.c index c051f1a..bb00508 100644 --- a/lib/win32-kldbg.c +++ b/lib/win32-kldbg.c @@ -16,6 +16,7 @@ #include "internal.h" #include "i386-io-windows.h" +#include "win32-helpers.h" #ifndef ERROR_NOT_FOUND #define ERROR_NOT_FOUND 1168 @@ -108,53 +109,6 @@ static HANDLE kldbg_dev = INVALID_HANDLE_VALUE; static BOOL win32_kldbg_pci_bus_data(BOOL WriteBusData, USHORT SegmentNumber, BYTE BusNumber, BYTE DeviceNumber, BYTE FunctionNumber, USHORT Address, PVOID Buffer, ULONG BufferSize, LPDWORD Length); -static const char * -win32_strerror(DWORD win32_error_id) -{ - /* - * Use static buffer which is large enough. - * Hopefully no Win32 API error message string is longer than 4 kB. - */ - static char buffer[4096]; - DWORD len; - - len = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, win32_error_id, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), buffer, sizeof(buffer), NULL); - - /* FormatMessage() automatically appends ".\r\n" to the error message. */ - if (len && buffer[len-1] == '\n') - buffer[--len] = '\0'; - if (len && buffer[len-1] == '\r') - buffer[--len] = '\0'; - if (len && buffer[len-1] == '.') - buffer[--len] = '\0'; - - if (!len) - sprintf(buffer, "Unknown Win32 error %lu", win32_error_id); - - return buffer; -} - -static BOOL -win32_is_32bit_on_64bit_system(void) -{ - BOOL (WINAPI *MyIsWow64Process)(HANDLE, PBOOL); - HMODULE kernel32; - BOOL is_wow64; - - kernel32 = GetModuleHandle(TEXT("kernel32.dll")); - if (!kernel32) - return FALSE; - - MyIsWow64Process = (void *)GetProcAddress(kernel32, "IsWow64Process"); - if (!MyIsWow64Process) - return FALSE; - - if (!MyIsWow64Process(GetCurrentProcess(), &is_wow64)) - return FALSE; - - return is_wow64; -} - static WORD win32_get_current_process_machine(void) { diff --git a/lib/win32-sysdbg.c b/lib/win32-sysdbg.c index 6b17f37..22ecc60 100644 --- a/lib/win32-sysdbg.c +++ b/lib/win32-sysdbg.c @@ -12,6 +12,7 @@ #include "internal.h" #include "i386-io-windows.h" +#include "win32-helpers.h" #ifndef NTSTATUS #define NTSTATUS LONG -- cgit 1.2.3-korg