+ size *= 2;
+ goto retry;
+ }
+ else if (len == 0)
+ path[0] = '\0';
+
+ /*
+ * GetModuleFileName() has bugs. On Windows 10 it prepends current drive
+ * letter if path is just pure NT namespace (with "\\??\\" prefix). Such
+ * extra drive letter makes path fully invalid and unusable. So remove
+ * extra drive letter to make path valid again.
+ * Reproduce: CreateProcessW("\\??\\C:\\lspci.exe", ...)
+ */
+ if (((path[0] >= 'a' && path[0] <= 'z') ||
+ (path[0] >= 'A' && path[0] <= 'Z')) &&
+ strncmp(path+1, ":\\??\\", 5) == 0)
+ {
+ memmove(path, path+2, len-2);
+ len -= 2;
+ path[len] = '\0';
+ }
+
+ /*
+ * GetModuleFileName() has bugs. On Windows 10 it does not add "\\\\?\\"
+ * prefix when path is in native NT UNC namespace. Such path is treated by
+ * WinAPI/DOS functions as standard DOS path relative to the current
+ * directory, hence something completely different. So prepend missing
+ * "\\\\?\\" prefix to make path valid again.
+ * Reproduce: CreateProcessW("\\??\\UNC\\10.0.2.4\\qemu\\lspci.exe", ...)
+ *
+ * If path starts with DOS drive letter and with appended PCI_IDS is
+ * longer than 260 bytes and is without "\\\\?\\" prefix then append it.
+ * This prefix is required for paths and file names with DOS drive letter
+ * longer than 260 bytes.
+ */
+ if (strncmp(path, "\\UNC\\", 5) == 0 ||
+ strncmp(path, "UNC\\", 4) == 0 ||
+ (((path[0] >= 'a' && path[0] <= 'z') || (path[0] >= 'A' && path[0] <= 'Z')) &&
+ len + sizeof(PCI_IDS) >= 260))
+ {
+ memmove(path+4, path, len);
+ memcpy(path, "\\\\?\\", 4);
+ len += 4;
+ path[len] = '\0';
+ }
+
+#elif defined(PCI_OS_DJGPP) || defined(PCI_OS_WINDOWS)
+
+ const char *exe_path;
+
+#ifdef PCI_OS_DJGPP
+ exe_path = __dos_argv0;
+#else
+ exe_path = _pgmptr;
+#endif
+
+ len = strlen(exe_path);
+ path = pci_malloc(a, len+sizeof(PCI_IDS));
+ memcpy(path, exe_path, len+1);
+
+#endif
+
+ sep = strrchr(path, '\\');
+ if (!sep)
+ {
+ /*
+ * If current module path (current executable for static builds or
+ * current DLL library for shared build) cannot be determined then
+ * fallback to the current directory.
+ */
+ free(path);