]> granicus.if.org Git - curl/commitdiff
tool: add undocumented option --dump-module-paths for win32
authorJay Satiro <raysatiro@yahoo.com>
Thu, 1 Nov 2018 06:50:40 +0000 (02:50 -0400)
committerJay Satiro <raysatiro@yahoo.com>
Tue, 6 Nov 2018 08:15:44 +0000 (03:15 -0500)
- Add an undocumented diagnostic option for Windows to show the full
  paths of all loaded modules regardless of whether or not libcurl
  initialization succeeds.

This is needed so that in the CI we can get a list of all DLL
dependencies after initialization (when they're most likely to have
finished loading) and then package them as artifacts so that a
functioning build can be downloaded. Also I imagine it may have some use
as a diagnostic for help requests.

Ref: https://github.com/curl/curl/pull/3103

Closes https://github.com/curl/curl/pull/3208

src/tool_doswin.c
src/tool_doswin.h
src/tool_main.c

index c3a8826ff51e8c3219effe3ed8a4cd616a81e71e..012ede5ace44d8978d112047b23ba867404a4002 100644 (file)
@@ -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 */
index 6398390f143611f3b399a23dda71cada03cfd249..415fac27e0a092ad4e76c7e6eada4b1be74942df 100644 (file)
@@ -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 */
 
index 6dc74d9234bd70ff195db184b2f12d54a662812f..3089ee37f8f5a99b5ca475fcb054d5fbaff593ea 100644 (file)
@@ -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);