aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPali Rohár <pali@kernel.org>2023-08-17 21:15:02 +0200
committerMartin Mares <mj@ucw.cz>2023-12-29 14:30:02 +0100
commit8c22b2c473815c6b19c4b6cfa32229e405b9c367 (patch)
tree3329253769d733ddb9687d3bd12dc9453ee9d26c
parent6e50724345522dce3f74f076dc2a0662956ba933 (diff)
downloadpciutils-8c22b2c473815c6b19c4b6cfa32229e405b9c367.tar.gz
libpci: win32-kldbg: Fix driver constructing path
Get*Directory() functions have strange API. When called with zero buffer they return length of the required buffer for storing path including nul-term in TCHAR units (which is 1 for ANSI builds and 2 for UNICODE builds). When called with non-zero buffer which can store full path they return length of the path without nul-term (again in TCHAR units). GetWindowsDirectory() function returns HOME user folder if application is running on the Terminal Server. So this function is not suitable. Fix calculation of path buffer for UNICODE builds and instead of usage GetWindowsDirectory() function with concatenating "\\system32" string, use function GetSystemDirectory() which returns path directly to system32 folder and which works correctly also on Terminal Server (per KB281316).
-rw-r--r--lib/win32-kldbg.c58
1 files changed, 17 insertions, 41 deletions
diff --git a/lib/win32-kldbg.c b/lib/win32-kldbg.c
index 9593a05..c051f1a 100644
--- a/lib/win32-kldbg.c
+++ b/lib/win32-kldbg.c
@@ -213,7 +213,7 @@ win32_check_driver(BYTE *driver_data)
}
static int
-win32_kldbg_unpack_driver(struct pci_access *a, void *driver_path)
+win32_kldbg_unpack_driver(struct pci_access *a, LPTSTR driver_path)
{
BOOL use_kd_exe = FALSE;
HMODULE exe_with_driver = NULL;
@@ -323,58 +323,34 @@ out:
static int
win32_kldbg_register_driver(struct pci_access *a, SC_HANDLE manager, SC_HANDLE *service)
{
- UINT (WINAPI *get_system_root_path)(void *buffer, UINT size) = NULL;
- UINT systemroot_len;
- void *driver_path;
+ UINT system32_len;
+ LPTSTR driver_path;
HANDLE driver_handle;
- HMODULE kernel32;
/*
- * COM library dbgeng.dll unpacks kldbg driver to file \\system32\\kldbgdrv.sys
+ * COM library dbgeng.dll unpacks kldbg driver to file "\\system32\\kldbgdrv.sys"
* and register this driver with service name kldbgdrv. Implement same behavior.
+ * GetSystemDirectory() returns path to "\\system32" directory on all Windows versions.
*/
- /*
- * Old Windows versions return path to NT SystemRoot namespace via
- * GetWindowsDirectory() function. New Windows versions via
- * GetSystemWindowsDirectory(). GetSystemWindowsDirectory() is not
- * provided in old Windows versions, so use GetProcAddress() for
- * compatibility with all Windows versions.
- */
-
- kernel32 = GetModuleHandle(TEXT("kernel32.dll"));
- if (kernel32)
- get_system_root_path = (void *)GetProcAddress(kernel32, "GetSystemWindowsDirectory"
-#ifdef UNICODE
- "W"
-#else
- "A"
-#endif
- );
-
- if (!get_system_root_path)
- get_system_root_path = (void *)&GetWindowsDirectory;
-
- systemroot_len = get_system_root_path(NULL, 0);
- if (!systemroot_len)
- systemroot_len = sizeof(TEXT("C:\\Windows\\"));
+ system32_len = GetSystemDirectory(NULL, 0); /* Returns number of TCHARs plus 1 for nul-term. */
+ if (!system32_len)
+ system32_len = sizeof("C:\\Windows\\System32");
- driver_path = pci_malloc(a, systemroot_len + sizeof(TEXT("\\system32\\kldbgdrv.sys")));
+ driver_path = pci_malloc(a, (system32_len + sizeof("\\kldbgdrv.sys")-1) * sizeof(TCHAR));
- systemroot_len = get_system_root_path(driver_path, systemroot_len + sizeof(TEXT("")));
- if (!systemroot_len)
+ system32_len = GetSystemDirectory(driver_path, system32_len); /* Now it returns number of TCHARs without nul-term. */
+ if (!system32_len)
{
- systemroot_len = sizeof(TEXT("C:\\Windows\\"));
- memcpy(driver_path, TEXT("C:\\Windows\\"), systemroot_len);
+ system32_len = sizeof("C:\\Windows\\System32")-1;
+ memcpy(driver_path, TEXT("C:\\Windows\\System32"), system32_len);
}
- if (((char *)driver_path)[systemroot_len-sizeof(TEXT(""))+1] != '\\')
- {
- ((char *)driver_path)[systemroot_len-sizeof(TEXT(""))+1] = '\\';
- systemroot_len += sizeof(TEXT(""));
- }
+ /* GetSystemDirectory returns path without backslash unless the system directory is the root directory. */
+ if (driver_path[system32_len-1] != '\\')
+ driver_path[system32_len++] = '\\';
- memcpy((char *)driver_path + systemroot_len, TEXT("system32\\kldbgdrv.sys"), sizeof(TEXT("system32\\kldbgdrv.sys")));
+ memcpy(driver_path + system32_len, TEXT("kldbgdrv.sys"), sizeof(TEXT("kldbgdrv.sys")));
driver_handle = CreateFile(driver_path, 0, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (driver_handle != INVALID_HANDLE_VALUE)