#include <wchar.h> /* for wcslen(), wcscpy() */
#include "internal.h"
+#include "win32-helpers.h"
/* Unfortunately MinGW32 toolchain does not provide these cfgmgr32 constants. */
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)
{
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)
{
SERVICE_STATUS service_status;
SC_HANDLE service = NULL;
char *driver_path = NULL;
+ int trim_system32 = 0;
UINT systemroot_len;
int driver_path_len;
+ UINT system32_len;
HMODULE kernel32;
+ WCHAR *trim_ptr;
DWORD error;
service = OpenServiceW(manager, service_name, SERVICE_QUERY_CONFIG | SERVICE_QUERY_STATUS);
*/
/*
- * Old Windows versions return path to NT SystemRoot namespace via
- * GetWindowsDirectoryW() function. New Windows versions via
- * GetSystemWindowsDirectoryW(). GetSystemWindowsDirectoryW() is not
- * provided in old Windows versions, so use GetProcAddress() for
- * compatibility with all Windows versions.
+ * GetSystemWindowsDirectoryW() returns path to NT SystemRoot namespace.
+ * Alternativelly path to NT SystemRoot namespace can be constructed by
+ * GetSystemDirectoryW() by trimming "\\system32" from the end of path.
+ * GetSystemWindowsDirectoryW() is not provided in old Windows versions,
+ * so use GetProcAddress() for compatibility with all Windows versions.
*/
kernel32 = GetModuleHandleW(L"kernel32.dll");
if (kernel32)
get_system_root_path = (void *)GetProcAddress(kernel32, "GetSystemWindowsDirectoryW");
- if (!get_system_root_path)
- get_system_root_path = &GetWindowsDirectoryW;
-
- systemroot_len = get_system_root_path(NULL, 0);
+ else
+ {
+ get_system_root_path = &GetSystemDirectoryW;
+ trim_system32 = 1;
+ }
if (!service_config->lpBinaryPathName || !service_config->lpBinaryPathName[0])
{
- /* No ImagePath is specified, NT kernel assumes implicit kernel driver path by service name. */
- service_image_path = pci_malloc(a, sizeof(WCHAR) * (systemroot_len + sizeof("\\System32\\drivers\\")-1 + wcslen(service_name) + sizeof(".sys")-1 + 1));
- systemroot_len = get_system_root_path(service_image_path, systemroot_len+1);
- if (systemroot_len && service_image_path[systemroot_len-1] != L'\\')
- service_image_path[systemroot_len++] = L'\\';
- wcscpy(service_image_path + systemroot_len, L"System32\\drivers\\");
- wcscpy(service_image_path + systemroot_len + sizeof("System32\\drivers\\")-1, service_name);
- wcscpy(service_image_path + systemroot_len + sizeof("System32\\drivers\\")-1 + wcslen(service_name), L".sys");
+ /* No ImagePath is specified, NT kernel assumes implicit kernel driver path by service name, which is relative to "\\system32\\drivers". */
+ /* GetSystemDirectoryW() returns path to "\\system32" directory on all Windows versions. */
+ system32_len = GetSystemDirectoryW(NULL, 0); /* Returns number of WCHARs plus 1 for nul-term. */
+ service_image_path = pci_malloc(a, sizeof(WCHAR) * (system32_len + sizeof("\\drivers\\")-1 + wcslen(service_name) + sizeof(".sys")-1));
+ system32_len = GetSystemDirectoryW(service_image_path, system32_len); /* Now it returns number of WCHARs without nul-term. */
+ if (system32_len && service_image_path[system32_len-1] != L'\\')
+ service_image_path[system32_len++] = L'\\';
+ wcscpy(service_image_path + system32_len, L"drivers\\");
+ wcscpy(service_image_path + system32_len + sizeof("drivers\\")-1, service_name);
+ wcscpy(service_image_path + system32_len + sizeof("drivers\\")-1 + wcslen(service_name), L".sys");
}
else if (wcsncmp(service_config->lpBinaryPathName, L"\\SystemRoot\\", sizeof("\\SystemRoot\\")-1) == 0)
{
- /* ImagePath is in NT SystemRoot namespace, convert to Win32 path via GetSystemWindowsDirectoryW()/GetWindowsDirectoryW(). */
+ /* ImagePath is in NT SystemRoot namespace, convert to Win32 path via GetSystemWindowsDirectoryW()/GetSystemDirectoryW(). */
+ systemroot_len = get_system_root_path(NULL, 0); /* Returns number of WCHARs plus 1 for nul-term. */
service_image_path = pci_malloc(a, sizeof(WCHAR) * (systemroot_len + wcslen(service_config->lpBinaryPathName) - (sizeof("\\SystemRoot")-1)));
- systemroot_len = get_system_root_path(service_image_path, systemroot_len+1);
+ systemroot_len = get_system_root_path(service_image_path, systemroot_len); /* Now it returns number of WCHARs without nul-term. */
+ if (trim_system32 && systemroot_len && (trim_ptr = wcsrchr(service_image_path, L'\\')) != NULL)
+ systemroot_len = trim_ptr - service_image_path;
if (systemroot_len && service_image_path[systemroot_len-1] != L'\\')
service_image_path[systemroot_len++] = L'\\';
wcscpy(service_image_path + systemroot_len, service_config->lpBinaryPathName + sizeof("\\SystemRoot\\")-1);
}
else if (service_config->lpBinaryPathName[0] != L'\\')
{
- /* ImagePath is relative to the NT SystemRoot namespace, convert to Win32 path via GetSystemWindowsDirectoryW()/GetWindowsDirectoryW(). */
- service_image_path = pci_malloc(a, sizeof(WCHAR) * (systemroot_len + sizeof("\\") + wcslen(service_config->lpBinaryPathName)));
- systemroot_len = get_system_root_path(service_image_path, systemroot_len+1);
+ /* ImagePath is relative to the NT SystemRoot namespace, convert to Win32 path via GetSystemWindowsDirectoryW()/GetSystemDirectoryW(). */
+ systemroot_len = get_system_root_path(NULL, 0); /* Returns number of WCHARs plus 1 for nul-term. */
+ service_image_path = pci_malloc(a, sizeof(WCHAR) * (systemroot_len + sizeof("\\")-1 + wcslen(service_config->lpBinaryPathName)));
+ systemroot_len = get_system_root_path(service_image_path, systemroot_len); /* Now it returns number of WCHARs without nul-term. */
+ if (trim_system32 && systemroot_len && (trim_ptr = wcsrchr(service_image_path, L'\\')) != NULL)
+ systemroot_len = trim_ptr - service_image_path;
if (systemroot_len && service_image_path[systemroot_len-1] != L'\\')
service_image_path[systemroot_len++] = L'\\';
wcscpy(service_image_path + systemroot_len, service_config->lpBinaryPathName);
{
error = GetLastError();
if (error == 0)
- a->warning("Cannot read driver %s key for PCI device %s: DevLoader key is stored as unknown type 0x%lx.", subname, devinst_id, unkn_reg_type);
+ a->warning("Cannot read driver %s key for PCI device %s: %s key is stored as unknown type 0x%lx.", subname, devinst_id, subname, unkn_reg_type);
else if (error != ERROR_FILE_NOT_FOUND)
a->warning("Cannot read driver %s key for PCI device %s: %s.", subname, devinst_id, win32_strerror(error));
else if (strcmp(subname, "minivdd") == 0)
LPWSTR service_name = NULL;
ULONG devinst_id_len = 0;
char *driver_path = NULL;
- DEVINST devinst = (DEVINST)d->aux;
+ DEVINST devinst = (DEVINST)d->backend_data;
ULONG problem = 0;
ULONG status = 0;
HKEY key = NULL;
* 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)
}
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)
d = pci_get_dev(a, domain, bus, dev, func);
pci_link_dev(a, d);
- if (!d->access->aux)
+ if (!d->access->backend_data)
d->no_config_access = 1;
- d->aux = (void *)devinst;
+ d->backend_data = (void *)devinst;
/* Parse device id part of devinst id and fill details into pci_dev. */
if (!a->buscentric)
fill_resources(d, devinst, devinst_id);
/*
- * Set parent field to cfgmgr32 parent devinst handle and aux field to current
+ * Set parent field to cfgmgr32 parent devinst handle and backend_data field to current
* devinst handle. At later stage in win32_cfgmgr32_scan() when all pci_dev
* devices are linked, change every devinst handle by pci_dev.
*/
for (d1 = a->devices; d1; d1 = d1->next)
{
for (d2 = a->devices; d2; d2 = d2->next)
- if ((DEVINST)d1->parent == (DEVINST)d2->aux)
+ if ((DEVINST)d1->parent == (DEVINST)d2->backend_data)
break;
d1->parent = d2;
if (d1->parent)
}
}
- /* devinst stored in ->aux is not needed anymore, clear it. */
+ /* devinst stored in ->backend_data is not needed anymore, clear it. */
for (d = a->devices; d; d = d->next)
- d->aux = NULL;
+ d->backend_data = NULL;
pci_mfree(devinst_id_list);
}
* All available flags were filled by win32_cfgmgr32_scan().
* Filling more flags is possible only from config space.
*/
- if (!d->access->aux)
+ if (!d->access->backend_data)
return;
pci_generic_fill_info(d, flags);
win32_cfgmgr32_read(struct pci_dev *d, int pos, byte *buf, int len)
{
struct pci_access *a = d->access;
- struct pci_access *acfg = a->aux;
- struct pci_dev *dcfg = d->aux;
+ struct pci_access *acfg = a->backend_data;
+ struct pci_dev *dcfg = d->backend_data;
if (!acfg)
return pci_emulated_read(d, pos, buf, len);
if (!dcfg)
- d->aux = dcfg = pci_get_dev(acfg, d->domain, d->bus, d->dev, d->func);
+ d->backend_data = dcfg = pci_get_dev(acfg, d->domain, d->bus, d->dev, d->func);
return pci_read_block(dcfg, pos, buf, len);
}
win32_cfgmgr32_write(struct pci_dev *d, int pos, byte *buf, int len)
{
struct pci_access *a = d->access;
- struct pci_access *acfg = a->aux;
- struct pci_dev *dcfg = d->aux;
+ struct pci_access *acfg = a->backend_data;
+ struct pci_dev *dcfg = d->backend_data;
if (!acfg)
return 0;
if (!dcfg)
- d->aux = dcfg = pci_get_dev(acfg, d->domain, d->bus, d->dev, d->func);
+ d->backend_data = dcfg = pci_get_dev(acfg, d->domain, d->bus, d->dev, d->func);
return pci_write_block(dcfg, pos, buf, len);
}
static void
win32_cfgmgr32_cleanup_dev(struct pci_dev *d)
{
- struct pci_dev *dcfg = d->aux;
+ struct pci_dev *dcfg = d->backend_data;
if (dcfg)
pci_free_dev(dcfg);
return;
}
- a->aux = acfg;
+ a->backend_data = acfg;
}
static void
win32_cfgmgr32_cleanup(struct pci_access *a)
{
- struct pci_access *acfg = a->aux;
+ struct pci_access *acfg = a->backend_data;
if (acfg)
pci_cleanup(acfg);