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
This commit is contained in:
Jay Satiro 2018-11-01 02:50:40 -04:00
parent 28429fb175
commit 397664a065
3 changed files with 70 additions and 0 deletions

View 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 */