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>
86DLL_DIRECTORY_COOKIE AddDllDirectory(WINPR_ATTR_UNUSED PCWSTR NewDirectory)
89 WLog_ERR(TAG,
"not implemented");
90 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
94BOOL RemoveDllDirectory(WINPR_ATTR_UNUSED DLL_DIRECTORY_COOKIE Cookie)
97 WLog_ERR(TAG,
"not implemented");
98 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
102BOOL SetDefaultDllDirectories(WINPR_ATTR_UNUSED DWORD DirectoryFlags)
105 WLog_ERR(TAG,
"not implemented");
106 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
110HMODULE LoadLibraryA(LPCSTR lpLibFileName)
117 HMODULE hModule =
nullptr;
118 WCHAR* filenameW =
nullptr;
120 filenameW = ConvertUtf8ToWCharAlloc(lpLibFileName,
nullptr);
124 hModule = LoadLibraryW(filenameW);
128 HMODULE library = dlopen(lpLibFileName, RTLD_LOCAL | RTLD_LAZY);
133 const char* err = dlerror();
134 WLog_VRB(TAG,
"failed with %s", err);
142HMODULE LoadLibraryW(LPCWSTR lpLibFileName)
145 return LoadPackagedLibrary(lpLibFileName, 0);
147 char* name =
nullptr;
150 name = ConvertWCharToUtf8Alloc(lpLibFileName,
nullptr);
152 HMODULE
module = LoadLibraryA(name);
158HMODULE LoadLibraryExA(LPCSTR lpLibFileName, HANDLE hFile, DWORD dwFlags)
161 WLog_WARN(TAG,
"does not support dwFlags 0x%08" PRIx32, dwFlags);
164 WLog_WARN(TAG,
"does not support hFile != nullptr");
166 return LoadLibraryA(lpLibFileName);
169HMODULE LoadLibraryExW(LPCWSTR lpLibFileName, HANDLE hFile, DWORD dwFlags)
172 WLog_WARN(TAG,
"does not support dwFlags 0x%08" PRIx32, dwFlags);
175 WLog_WARN(TAG,
"does not support hFile != nullptr");
177 return LoadLibraryW(lpLibFileName);
182#if !defined(_WIN32) && !defined(__CYGWIN__)
184FARPROC GetProcAddress(HMODULE hModule, LPCSTR lpProcName)
186 FARPROC proc =
nullptr;
187 proc = dlsym(hModule, lpProcName);
192 WLog_ERR(TAG,
"GetProcAddress: could not find procedure %s: %s", lpProcName, dlerror());
193 return (FARPROC)
nullptr;
199BOOL FreeLibrary(HMODULE hLibModule)
202 status = dlclose(hLibModule);
204 return (status == 0);
207HMODULE GetModuleHandleA(LPCSTR lpModuleName)
209 return dlopen(lpModuleName, RTLD_NOLOAD | RTLD_LOCAL | RTLD_LAZY);
212HMODULE GetModuleHandleW(LPCWSTR lpModuleName)
214 char* name =
nullptr;
216 name = ConvertWCharToUtf8Alloc(lpModuleName,
nullptr);
217 HANDLE hdl = GetModuleHandleA(name);
230DWORD GetModuleFileNameW(HMODULE hModule, LPWSTR lpFilename, DWORD nSize)
235 SetLastError(ERROR_INTERNAL_ERROR);
239 char* name = calloc(nSize,
sizeof(
char));
242 SetLastError(ERROR_INTERNAL_ERROR);
245 status = GetModuleFileNameA(hModule, name, nSize);
247 if ((status > INT_MAX) || (nSize > INT_MAX))
249 SetLastError(ERROR_INTERNAL_ERROR);
255 if (ConvertUtf8NToWChar(name, status, lpFilename, nSize) < 0)
258 SetLastError(ERROR_INTERNAL_ERROR);
267#if defined(__linux__) || defined(__NetBSD__) || defined(__DragonFly__)
268static DWORD module_from_proc(
const char* proc, LPSTR lpFilename, DWORD nSize)
270 char buffer[8192] = WINPR_C_ARRAY_INIT;
271 ssize_t status = readlink(proc, buffer, ARRAYSIZE(buffer) - 1);
273 if ((status < 0) || ((
size_t)status >= ARRAYSIZE(buffer)))
275 SetLastError(ERROR_INTERNAL_ERROR);
279 const size_t length = strnlen(buffer, ARRAYSIZE(buffer));
283 CopyMemory(lpFilename, buffer, length);
284 lpFilename[length] =
'\0';
285 return (DWORD)length;
288 CopyMemory(lpFilename, buffer, nSize - 1);
289 lpFilename[nSize - 1] =
'\0';
290 SetLastError(ERROR_INSUFFICIENT_BUFFER);
295#if defined(__MACOSX__)
297static uint32_t get_required_size(
void)
299 char buffer[1] = WINPR_C_ARRAY_INIT;
300 uint32_t size =
sizeof(buffer);
301 if (_NSGetExecutablePath(buffer, &size) == 0)
302 return sizeof(buffer);
307static DWORD mac_get_module_file_name(
char* lpFilename, uint32_t nSize)
309 const uint32_t required = get_required_size();
313 if (required < nSize)
315 uint32_t size = nSize;
316 if (_NSGetExecutablePath(lpFilename, &size) == 0)
317 return (DWORD)strnlen(lpFilename, nSize);
318 SetLastError(ERROR_INSUFFICIENT_BUFFER);
322 char* buffer = calloc(1ull + required,
sizeof(
char));
325 SetLastError(ERROR_OUTOFMEMORY);
329 uint32_t size = required;
330 const int status = _NSGetExecutablePath(buffer, &size);
335 SetLastError(ERROR_INSUFFICIENT_BUFFER);
344 char* real = realpath(buffer,
nullptr);
348 SetLastError(ERROR_OUTOFMEMORY);
351 const size_t length = strlen(real);
354 strncpy(lpFilename, real, length + 1);
356 return (DWORD)strnlen(lpFilename, nSize);
359 strncpy(lpFilename, real, nSize - 1);
361 lpFilename[nSize - 1] =
'\0';
362 SetLastError(ERROR_INSUFFICIENT_BUFFER);
367DWORD GetModuleFileNameA(HMODULE hModule, LPSTR lpFilename, DWORD nSize)
371 WLog_ERR(TAG,
"is not implemented");
372 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
376#if defined(__linux__)
377 return module_from_proc(
"/proc/self/exe", lpFilename, nSize);
378#elif defined(__FreeBSD__)
379 int mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1 };
383 const int rc = sysctl(mib, ARRAYSIZE(mib),
nullptr, &cb,
nullptr, 0);
386 SetLastError(ERROR_INTERNAL_ERROR);
391 char* fullname = calloc(cb + 1,
sizeof(
char));
394 SetLastError(ERROR_INTERNAL_ERROR);
400 const int rc = sysctl(mib, ARRAYSIZE(mib), fullname, &cb2,
nullptr, 0);
401 if ((rc != 0) || (cb2 != cb))
403 SetLastError(ERROR_INTERNAL_ERROR);
411 strncpy(lpFilename, fullname, nSize - 1);
412 lpFilename[nSize - 1] =
'\0';
417 SetLastError(ERROR_INSUFFICIENT_BUFFER);
419 return (DWORD)MIN(nSize, cb);
420#elif defined(__NetBSD__)
421 return module_from_proc(
"/proc/curproc/exe", lpFilename, nSize);
422#elif defined(__DragonFly__)
423 return module_from_proc(
"/proc/curproc/file", lpFilename, nSize);
424#elif defined(__MACOSX__)
425 return mac_get_module_file_name(lpFilename, nSize);
427 WLog_ERR(TAG,
"is not implemented");
428 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
435HMODULE LoadLibraryX(LPCSTR lpLibFileName)
438 HMODULE hm =
nullptr;
439 WCHAR* wstr =
nullptr;
442 wstr = ConvertUtf8ToWCharAlloc(lpLibFileName,
nullptr);
444 hm = LoadLibraryW(wstr);
448 return LoadLibraryA(lpLibFileName);
452HMODULE LoadLibraryExX(LPCSTR lpLibFileName, HANDLE hFile, DWORD dwFlags)
457 HMODULE hm =
nullptr;
458 WCHAR* wstr = ConvertUtf8ToWCharAlloc(lpLibFileName,
nullptr);
460 hm = LoadLibraryExW(wstr, hFile, dwFlags);
464 return LoadLibraryExA(lpLibFileName, hFile, dwFlags);