aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJay Satiro <raysatiro@yahoo.com>2018-11-01 02:50:40 -0400
committerJay Satiro <raysatiro@yahoo.com>2018-11-06 03:15:44 -0500
commit397664a065abffb7c3445ca9086f917e13719d1f (patch)
tree0767418d916c3c3eee605e36f48ad8233e2672ad
parent28429fb1753d63a659f38577b39e0b5747f28939 (diff)
tool: add undocumented option --dump-module-paths for win32
- 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
-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);