20#include <winpr/config.h>
23#include <winpr/platform.h>
25#include <winpr/library.h>
28#define TAG WINPR_TAG("library")
65#if (!defined(_WIN32) && !defined(__CYGWIN__)) || defined(_UWP)
77#include <mach-o/dyld.h>
80#if defined(__FreeBSD__)
81#include <sys/sysctl.h>
84#if defined(__OpenBSD__)
90DLL_DIRECTORY_COOKIE AddDllDirectory(WINPR_ATTR_UNUSED PCWSTR NewDirectory)
93 WLog_ERR(TAG,
"not implemented");
94 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
98BOOL RemoveDllDirectory(WINPR_ATTR_UNUSED DLL_DIRECTORY_COOKIE Cookie)
101 WLog_ERR(TAG,
"not implemented");
102 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
106BOOL SetDefaultDllDirectories(WINPR_ATTR_UNUSED DWORD DirectoryFlags)
109 WLog_ERR(TAG,
"not implemented");
110 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
114HMODULE LoadLibraryA(LPCSTR lpLibFileName)
121 HMODULE hModule =
nullptr;
122 WCHAR* filenameW =
nullptr;
124 filenameW = ConvertUtf8ToWCharAlloc(lpLibFileName,
nullptr);
128 hModule = LoadLibraryW(filenameW);
132 HMODULE library = dlopen(lpLibFileName, RTLD_LOCAL | RTLD_LAZY);
137 const char* err = dlerror();
138 WLog_VRB(TAG,
"failed with %s", err);
146HMODULE LoadLibraryW(LPCWSTR lpLibFileName)
149 return LoadPackagedLibrary(lpLibFileName, 0);
151 char* name =
nullptr;
154 name = ConvertWCharToUtf8Alloc(lpLibFileName,
nullptr);
156 HMODULE
module = LoadLibraryA(name);
162HMODULE LoadLibraryExA(LPCSTR lpLibFileName, HANDLE hFile, DWORD dwFlags)
165 WLog_WARN(TAG,
"does not support dwFlags 0x%08" PRIx32, dwFlags);
168 WLog_WARN(TAG,
"does not support hFile != nullptr");
170 return LoadLibraryA(lpLibFileName);
173HMODULE LoadLibraryExW(LPCWSTR lpLibFileName, HANDLE hFile, DWORD dwFlags)
176 WLog_WARN(TAG,
"does not support dwFlags 0x%08" PRIx32, dwFlags);
179 WLog_WARN(TAG,
"does not support hFile != nullptr");
181 return LoadLibraryW(lpLibFileName);
186#if !defined(_WIN32) && !defined(__CYGWIN__)
188FARPROC GetProcAddress(HMODULE hModule, LPCSTR lpProcName)
190 FARPROC proc =
nullptr;
191 proc = dlsym(hModule, lpProcName);
196 WLog_ERR(TAG,
"GetProcAddress: could not find procedure %s: %s", lpProcName, dlerror());
197 return (FARPROC)
nullptr;
203BOOL FreeLibrary(HMODULE hLibModule)
206 status = dlclose(hLibModule);
208 return (status == 0);
211HMODULE GetModuleHandleA(LPCSTR lpModuleName)
213 return dlopen(lpModuleName, RTLD_NOLOAD | RTLD_LOCAL | RTLD_LAZY);
216HMODULE GetModuleHandleW(LPCWSTR lpModuleName)
218 char* name =
nullptr;
220 name = ConvertWCharToUtf8Alloc(lpModuleName,
nullptr);
221 HANDLE hdl = GetModuleHandleA(name);
234DWORD GetModuleFileNameW(HMODULE hModule, LPWSTR lpFilename, DWORD nSize)
239 SetLastError(ERROR_INTERNAL_ERROR);
243 char* name = calloc(nSize,
sizeof(
char));
246 SetLastError(ERROR_INTERNAL_ERROR);
249 status = GetModuleFileNameA(hModule, name, nSize);
251 if ((status > INT_MAX) || (nSize > INT_MAX))
253 SetLastError(ERROR_INTERNAL_ERROR);
259 if (ConvertUtf8NToWChar(name, status, lpFilename, nSize) < 0)
262 SetLastError(ERROR_INTERNAL_ERROR);
271#if defined(__linux__) || defined(__NetBSD__) || defined(__DragonFly__)
272static DWORD module_from_proc(
const char* proc, LPSTR lpFilename, DWORD nSize)
274 char buffer[8192] = WINPR_C_ARRAY_INIT;
275 ssize_t status = readlink(proc, buffer, ARRAYSIZE(buffer) - 1);
277 if ((status < 0) || ((
size_t)status >= ARRAYSIZE(buffer)))
279 SetLastError(ERROR_INTERNAL_ERROR);
283 const size_t length = strnlen(buffer, ARRAYSIZE(buffer));
287 CopyMemory(lpFilename, buffer, length);
288 lpFilename[length] =
'\0';
289 return (DWORD)length;
292 CopyMemory(lpFilename, buffer, nSize - 1);
293 lpFilename[nSize - 1] =
'\0';
294 SetLastError(ERROR_INSUFFICIENT_BUFFER);
299#if defined(__FreeBSD__)
301static DWORD freebsd_get_module_file_name(
char* lpFilename, uint32_t nSize)
303 int mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1 };
307 const int rc = sysctl(mib, ARRAYSIZE(mib),
nullptr, &cb,
nullptr, 0);
310 SetLastError(ERROR_INTERNAL_ERROR);
315 char* fullname = calloc(cb + 1,
sizeof(
char));
318 SetLastError(ERROR_INTERNAL_ERROR);
324 const int rc = sysctl(mib, ARRAYSIZE(mib), fullname, &cb2,
nullptr, 0);
325 if ((rc != 0) || (cb2 != cb))
327 SetLastError(ERROR_INTERNAL_ERROR);
335 strncpy(lpFilename, fullname, nSize - 1);
336 lpFilename[nSize - 1] =
'\0';
341 SetLastError(ERROR_INSUFFICIENT_BUFFER);
343 return (DWORD)MIN(nSize, cb);
347#if defined(__MACOSX__)
349static uint32_t get_required_size(
void)
351 char buffer[1] = WINPR_C_ARRAY_INIT;
352 uint32_t size =
sizeof(buffer);
353 if (_NSGetExecutablePath(buffer, &size) == 0)
354 return sizeof(buffer);
359static DWORD mac_get_module_file_name(
char* lpFilename, uint32_t nSize)
361 const uint32_t required = get_required_size();
365 if (required < nSize)
367 uint32_t size = nSize;
368 if (_NSGetExecutablePath(lpFilename, &size) == 0)
369 return (DWORD)strnlen(lpFilename, nSize);
370 SetLastError(ERROR_INSUFFICIENT_BUFFER);
374 char* buffer = calloc(1ull + required,
sizeof(
char));
377 SetLastError(ERROR_OUTOFMEMORY);
381 uint32_t size = required;
382 const int status = _NSGetExecutablePath(buffer, &size);
387 SetLastError(ERROR_INSUFFICIENT_BUFFER);
396 char* real = realpath(buffer,
nullptr);
400 SetLastError(ERROR_OUTOFMEMORY);
403 const size_t length = strlen(real);
406 strncpy(lpFilename, real, length + 1);
408 return (DWORD)strnlen(lpFilename, nSize);
411 strncpy(lpFilename, real, nSize - 1);
413 lpFilename[nSize - 1] =
'\0';
414 SetLastError(ERROR_INSUFFICIENT_BUFFER);
419#if defined(__OpenBSD__)
421static DWORD openbsd_get_module_file_name(
char* lpFilename, uint32_t nSize)
423#ifdef WITH_GETEXECPATH
424 size_t size = nSize + 1ull;
425 char* path = calloc(1, size);
429 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
433 while (getexecpath(path, size) != 0)
438 SetLastError(ERROR_INTERNAL_ERROR);
444 char* tmp = realloc(path, size);
449 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
456 const size_t length = strnlen(path, size);
458 memset(lpFilename, 0, nSize);
459 memcpy(lpFilename, path, MIN(length, nSize));
465 SetLastError(ERROR_INSUFFICIENT_BUFFER);
469 return WINPR_ASSERTING_INT_CAST(DWORD, length);
471 WLog_ERR(TAG,
"is not implemented");
472 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
478DWORD GetModuleFileNameA(HMODULE hModule, LPSTR lpFilename, DWORD nSize)
482 WLog_ERR(TAG,
"is not implemented");
483 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
487#if defined(__linux__)
488 return module_from_proc(
"/proc/self/exe", lpFilename, nSize);
489#elif defined(__FreeBSD__)
490 return freebsd_get_module_file_name(lpFilename, nSize);
491#elif defined(__NetBSD__)
492 return module_from_proc(
"/proc/curproc/exe", lpFilename, nSize);
493#elif defined(__DragonFly__)
494 return module_from_proc(
"/proc/curproc/file", lpFilename, nSize);
495#elif defined(__MACOSX__)
496 return mac_get_module_file_name(lpFilename, nSize);
497#elif defined(__OpenBSD__)
498 return openbsd_get_module_file_name(lpFilename, nSize);
500 WLog_ERR(TAG,
"is not implemented");
501 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
508HMODULE LoadLibraryX(LPCSTR lpLibFileName)
511 HMODULE hm =
nullptr;
512 WCHAR* wstr =
nullptr;
515 wstr = ConvertUtf8ToWCharAlloc(lpLibFileName,
nullptr);
517 hm = LoadLibraryW(wstr);
521 return LoadLibraryA(lpLibFileName);
525HMODULE LoadLibraryExX(LPCSTR lpLibFileName, HANDLE hFile, DWORD dwFlags)
530 HMODULE hm =
nullptr;
531 WCHAR* wstr = ConvertUtf8ToWCharAlloc(lpLibFileName,
nullptr);
533 hm = LoadLibraryExW(wstr, hFile, dwFlags);
537 return LoadLibraryExA(lpLibFileName, hFile, dwFlags);