aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/tool_doswin.c53
-rw-r--r--src/tool_doswin.h1
-rw-r--r--src/tool_main.c16
3 files changed, 70 insertions, 0 deletions
diff --git a/src/tool_doswin.c b/src/tool_doswin.c
index c3a8826ff..012ede5ac 100644
--- a/src/tool_doswin.c
+++ b/src/tool_doswin.c
@@ -28,6 +28,7 @@
#endif
#ifdef WIN32
+# include <tlhelp32.h>
# include "tool_cfgable.h"
# include "tool_libinfo.h"
#endif
@@ -670,6 +671,58 @@ CURLcode FindWin32CACert(struct OperationConfig *config,
return result;
}
+
+/* Get a list of all loaded modules with full paths.
+ * Returns slist on success or NULL on error.
+ */
+struct curl_slist *GetLoadedModulePaths(void)
+{
+ HANDLE hnd = INVALID_HANDLE_VALUE;
+ MODULEENTRY32 mod = { sizeof(mod), };
+ struct curl_slist *slist = NULL;
+
+ do {
+ hnd = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, 0);
+ } while(hnd == INVALID_HANDLE_VALUE && GetLastError() == ERROR_BAD_LENGTH);
+
+ if(hnd == INVALID_HANDLE_VALUE)
+ goto error;
+
+ if(!Module32First(hnd, &mod))
+ goto error;
+
+ do {
+ char *path; /* points to stack allocated buffer */
+ struct curl_slist *temp;
+
+#ifdef UNICODE
+ /* sizeof(mod.szExePath) is the max total bytes of wchars. the max total
+ bytes of multibyte chars won't be more than twice that. */
+ char buffer[sizeof(mod.szExePath) * 2];
+ if(!WideCharToMultiByte(CP_ACP, 0, mod.szExePath, -1,
+ buffer, sizeof(buffer), NULL, NULL))
+ goto error;
+ path = buffer;
+#else
+ path = mod.szExePath;
+#endif
+ temp = curl_slist_append(slist, path);
+ if(!temp)
+ goto error;
+ slist = temp;
+ } while(Module32Next(hnd, &mod));
+
+ goto cleanup;
+
+error:
+ curl_slist_free_all(slist);
+ slist = NULL;
+cleanup:
+ if(hnd != INVALID_HANDLE_VALUE)
+ CloseHandle(hnd);
+ return slist;
+}
+
#endif /* WIN32 */
#endif /* MSDOS || WIN32 */
diff --git a/src/tool_doswin.h b/src/tool_doswin.h
index 6398390f1..415fac27e 100644
--- a/src/tool_doswin.h
+++ b/src/tool_doswin.h
@@ -60,6 +60,7 @@ char **__crt0_glob_function(char *arg);
CURLcode FindWin32CACert(struct OperationConfig *config,
curl_sslbackend backend,
const char *bundle_file);
+struct curl_slist *GetLoadedModulePaths(void);
#endif /* WIN32 */
diff --git a/src/tool_main.c b/src/tool_main.c
index 6dc74d923..3089ee37f 100644
--- a/src/tool_main.c
+++ b/src/tool_main.c
@@ -38,6 +38,7 @@
#include "tool_cfgable.h"
#include "tool_convert.h"
+#include "tool_doswin.h"
#include "tool_msgs.h"
#include "tool_operate.h"
#include "tool_panykey.h"
@@ -305,6 +306,21 @@ int main(int argc, char *argv[])
/* Initialize the curl library - do not call any libcurl functions before
this point */
result = main_init(&global);
+
+#ifdef WIN32
+ /* Undocumented diagnostic option to list the full paths of all loaded
+ modules, regardless of whether or not initialization succeeded. */
+ if(argc == 2 && !strcmp(argv[1], "--dump-module-paths")) {
+ struct curl_slist *item, *head = GetLoadedModulePaths();
+ for(item = head; item; item = item->next) {
+ printf("%s\n", item->data);
+ }
+ curl_slist_free_all(head);
+ if(!result)
+ main_free(&global);
+ }
+ else
+#endif /* WIN32 */
if(!result) {
/* Start our curl operation */
result = operate(&global, argc, argv);