From 0382965825caa27deaac3ab6a25145c896b9053b Mon Sep 17 00:00:00 2001 From: =?utf8?q?Pali=20Roh=C3=A1r?= Date: Fri, 18 Nov 2022 21:47:04 +0100 Subject: [PATCH] libpci: windows: Fix usage of GetModuleFileName() Module file name can have arbitrary length despite all MS examples say about MAX_PATH upper limit. This limit does not apply for example when executable is running from network disk with very long UNC paths or when using "\\??\\" prefix for specifying executable binary path. So handle buffer truncatenation by retrying GetModuleFileName() call with larger buffer. Fixes loading of pci.ids file when lspci.exe binary is running from network drive with path longer than 260 bytes. --- lib/init.c | 31 ++++++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/lib/init.c b/lib/init.c index e6efb8b..9cb64f3 100644 --- a/lib/init.c +++ b/lib/init.c @@ -223,12 +223,33 @@ pci_init_name_list_path(struct pci_access *a) else { char *path, *sep; - DWORD len; + size_t len; + size_t size; + + /* + * Module file name can have arbitrary length despite all MS examples say + * about MAX_PATH upper limit. This limit does not apply for example when + * executable is running from network disk with very long UNC paths or + * when using "\\??\\" prefix for specifying executable binary path. + * Function GetModuleFileName() returns passed size argument when passed + * buffer is too small and does not signal any error. In this case retry + * again with larger buffer. + */ + size = 256; /* initial buffer size (more than sizeof(PCI_IDS)) */ +retry: + path = pci_malloc(a, size); + len = GetModuleFileNameA(module, path, size-sizeof(PCI_IDS)); + if (len >= size-sizeof(PCI_IDS)) + { + free(path); + size *= 2; + goto retry; + } + else if (len == 0) + path[0] = '\0'; - path = pci_malloc(a, MAX_PATH+1); - len = GetModuleFileNameA(NULL, path, MAX_PATH+1); - sep = (len > 0) ? strrchr(path, '\\') : NULL; - if (len == 0 || len == MAX_PATH+1 || !sep || MAX_PATH-(size_t)(sep+1-path) < sizeof(PCI_IDS)) + sep = strrchr(path, '\\'); + if (!sep) { free(path); pci_set_name_list_path(a, PCI_IDS, 0); -- 2.39.2