#include "../mongocrypt-dll-private.h" #ifdef _WIN32 #include #include #include #include #include #include mcr_dll mcr_dll_open(const char *filepath_) { // Convert all slashes to the native Windows separator mstr filepath = mpath_to_format(MPATH_WIN32, mstrv_view_cstr(filepath_), MPATH_WIN32); // Check if the path is just a filename. bool is_just_filename = mstr_eq(mpath_filename(filepath.view, MPATH_WIN32), filepath.view); if (!is_just_filename) { // If the path is only a filename, we'll allow LoadLibrary() to do a // proper full DLL search. If the path is NOT just a filename, resolve the // given path to a single unambiguous absolute path to suppress // LoadLibrary()'s DLL search behavior. mstr_assign(&filepath, mpath_absolute(filepath.view, MPATH_WIN32)); } mstr_widen_result wide = mstr_win32_widen(filepath.view); mstr_free(filepath); if (wide.error) { return (mcr_dll){._native_handle = NULL, .error_string = merror_system_error_string(wide.error)}; } HMODULE lib = LoadLibraryW(wide.wstring); if (lib == NULL) { return (mcr_dll){._native_handle = NULL, .error_string = merror_system_error_string(GetLastError())}; } free(wide.wstring); return (mcr_dll){.error_string = NULL, ._native_handle = lib}; } void mcr_dll_close_handle(mcr_dll dll) { if (dll._native_handle) { FreeLibrary(dll._native_handle); } } void *mcr_dll_sym(mcr_dll dll, const char *sym) { return GetProcAddress(dll._native_handle, sym); } mcr_dll_path_result mcr_dll_path(mcr_dll dll) { mstr ret_str = MSTR_NULL; int ret_error = 0; DWORD acc_size = 512; while (!ret_str.data && !ret_error) { // Loop until we allocate a large enough buffer or get an error wchar_t *path = calloc((size_t)acc_size + 1u, sizeof(wchar_t)); SetLastError(0); GetModuleFileNameW(dll._native_handle, path, acc_size); if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) { // Try again with more buffer /* DWORD is a 32-bit unsigned integer */ assert(acc_size <= UINT32_MAX / 2u); acc_size *= 2; } else if (GetLastError() != 0) { ret_error = GetLastError(); } else { mstr_narrow_result narrow = mstr_win32_narrow(path); // GetModuleFileNameW should never return invalid Unicode: assert(narrow.error == 0); ret_str = narrow.string; } free(path); } return (mcr_dll_path_result){ .path = ret_str, .error_string = merror_system_error_string(ret_error), }; } #endif