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(_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 = NULL;
118 WCHAR* filenameW = NULL;
120 filenameW = ConvertUtf8ToWCharAlloc(lpLibFileName, NULL);
124 hModule = LoadLibraryW(filenameW);
128 HMODULE library = dlopen(lpLibFileName, RTLD_LOCAL | RTLD_LAZY);
133 const char* err = dlerror();
134 WLog_ERR(TAG,
"failed with %s", err);
142HMODULE LoadLibraryW(LPCWSTR lpLibFileName)
145 return LoadPackagedLibrary(lpLibFileName, 0);
150 name = ConvertWCharToUtf8Alloc(lpLibFileName, NULL);
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 != NULL");
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 != NULL");
177 return LoadLibraryW(lpLibFileName);
182#if !defined(_WIN32) && !defined(__CYGWIN__)
184FARPROC GetProcAddress(HMODULE hModule, LPCSTR lpProcName)
187 proc = dlsym(hModule, lpProcName);
192 WLog_ERR(TAG,
"GetProcAddress: could not find procedure %s: %s", lpProcName, dlerror());
193 return (FARPROC)NULL;
199BOOL FreeLibrary(HMODULE hLibModule)
202 status = dlclose(hLibModule);
210HMODULE GetModuleHandleA(LPCSTR lpModuleName)
212 return dlopen(lpModuleName, RTLD_NOLOAD | RTLD_LOCAL | RTLD_LAZY);
215HMODULE GetModuleHandleW(LPCWSTR lpModuleName)
219 name = ConvertWCharToUtf8Alloc(lpModuleName, NULL);
220 HANDLE hdl = GetModuleHandleA(name);
233DWORD GetModuleFileNameW(HMODULE hModule, LPWSTR lpFilename, DWORD nSize)
238 SetLastError(ERROR_INTERNAL_ERROR);
242 char* name = calloc(nSize,
sizeof(
char));
245 SetLastError(ERROR_INTERNAL_ERROR);
248 status = GetModuleFileNameA(hModule, name, nSize);
250 if ((status > INT_MAX) || (nSize > INT_MAX))
252 SetLastError(ERROR_INTERNAL_ERROR);
258 if (ConvertUtf8NToWChar(name, status, lpFilename, nSize) < 0)
261 SetLastError(ERROR_INTERNAL_ERROR);
270#if defined(__linux__) || defined(__NetBSD__) || defined(__DragonFly__)
271static DWORD module_from_proc(
const char* proc, LPSTR lpFilename, DWORD nSize)
273 char buffer[8192] = { 0 };
274 ssize_t status = readlink(proc, buffer, ARRAYSIZE(buffer) - 1);
276 if ((status < 0) || ((
size_t)status >= ARRAYSIZE(buffer)))
278 SetLastError(ERROR_INTERNAL_ERROR);
282 const size_t length = strnlen(buffer, ARRAYSIZE(buffer));
286 CopyMemory(lpFilename, buffer, length);
287 lpFilename[length] =
'\0';
288 return (DWORD)length;
291 CopyMemory(lpFilename, buffer, nSize - 1);
292 lpFilename[nSize - 1] =
'\0';
293 SetLastError(ERROR_INSUFFICIENT_BUFFER);
298DWORD GetModuleFileNameA(HMODULE hModule, LPSTR lpFilename, DWORD nSize)
302 WLog_ERR(TAG,
"is not implemented");
303 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
307#if defined(__linux__)
308 return module_from_proc(
"/proc/self/exe", lpFilename, nSize);
309#elif defined(__FreeBSD__)
310 int mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1 };
314 const int rc = sysctl(mib, ARRAYSIZE(mib), NULL, &cb, NULL, 0);
317 SetLastError(ERROR_INTERNAL_ERROR);
322 char* fullname = calloc(cb + 1,
sizeof(
char));
325 SetLastError(ERROR_INTERNAL_ERROR);
331 const int rc = sysctl(mib, ARRAYSIZE(mib), fullname, &cb2, NULL, 0);
332 if ((rc != 0) || (cb2 != cb))
334 SetLastError(ERROR_INTERNAL_ERROR);
342 strncpy(lpFilename, fullname, nSize - 1);
343 lpFilename[nSize - 1] =
'\0';
348 SetLastError(ERROR_INSUFFICIENT_BUFFER);
350 return (DWORD)MIN(nSize, cb);
351#elif defined(__NetBSD__)
352 return module_from_proc(
"/proc/curproc/exe", lpFilename, nSize);
353#elif defined(__DragonFly__)
354 return module_from_proc(
"/proc/curproc/file", lpFilename, nSize);
355#elif defined(__MACOSX__)
356 char path[4096] = { 0 };
357 char buffer[4096] = { 0 };
358 uint32_t size =
sizeof(path);
359 const int status = _NSGetExecutablePath(path, &size);
364 SetLastError(ERROR_INTERNAL_ERROR);
372 realpath(path, buffer);
373 const size_t length = strnlen(buffer,
sizeof(buffer));
377 CopyMemory(lpFilename, buffer, length);
378 lpFilename[length] =
'\0';
379 return (DWORD)length;
382 CopyMemory(lpFilename, buffer, nSize - 1);
383 lpFilename[nSize - 1] =
'\0';
384 SetLastError(ERROR_INSUFFICIENT_BUFFER);
387 WLog_ERR(TAG,
"is not implemented");
388 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
395HMODULE LoadLibraryX(LPCSTR lpLibFileName)
402 wstr = ConvertUtf8ToWCharAlloc(lpLibFileName, NULL);
404 hm = LoadLibraryW(wstr);
408 return LoadLibraryA(lpLibFileName);
412HMODULE LoadLibraryExX(LPCSTR lpLibFileName, HANDLE hFile, DWORD dwFlags)
418 WCHAR* wstr = ConvertUtf8ToWCharAlloc(lpLibFileName, NULL);
420 hm = LoadLibraryExW(wstr, hFile, dwFlags);
424 return LoadLibraryExA(lpLibFileName, hFile, dwFlags);