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)
114 HMODULE hModule = NULL;
115 WCHAR* filenameW = NULL;
120 filenameW = ConvertUtf8ToWCharAlloc(lpLibFileName, NULL);
124 hModule = LoadLibraryW(filenameW);
128 HMODULE library = NULL;
129 library = dlopen(lpLibFileName, RTLD_LOCAL | RTLD_LAZY);
134 const char* err = dlerror();
135 WLog_ERR(TAG,
"failed with %s", err);
143HMODULE LoadLibraryW(LPCWSTR lpLibFileName)
146 return LoadPackagedLibrary(lpLibFileName, 0);
151 name = ConvertWCharToUtf8Alloc(lpLibFileName, NULL);
153 HMODULE
module = LoadLibraryA(name);
159HMODULE LoadLibraryExA(LPCSTR lpLibFileName, HANDLE hFile, DWORD dwFlags)
162 WLog_WARN(TAG,
"does not support dwFlags 0x%08" PRIx32, dwFlags);
165 WLog_WARN(TAG,
"does not support hFile != NULL");
167 return LoadLibraryA(lpLibFileName);
170HMODULE LoadLibraryExW(LPCWSTR lpLibFileName, HANDLE hFile, DWORD dwFlags)
173 WLog_WARN(TAG,
"does not support dwFlags 0x%08" PRIx32, dwFlags);
176 WLog_WARN(TAG,
"does not support hFile != NULL");
178 return LoadLibraryW(lpLibFileName);
183#if !defined(_WIN32) && !defined(__CYGWIN__)
185FARPROC GetProcAddress(HMODULE hModule, LPCSTR lpProcName)
188 proc = dlsym(hModule, lpProcName);
193 WLog_ERR(TAG,
"GetProcAddress: could not find procedure %s: %s", lpProcName, dlerror());
194 return (FARPROC)NULL;
200BOOL FreeLibrary(HMODULE hLibModule)
203 status = dlclose(hLibModule);
211HMODULE GetModuleHandleA(WINPR_ATTR_UNUSED LPCSTR lpModuleName)
214 WLog_ERR(TAG,
"not implemented");
215 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
219HMODULE GetModuleHandleW(WINPR_ATTR_UNUSED LPCWSTR lpModuleName)
222 WLog_ERR(TAG,
"not implemented");
223 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
235DWORD GetModuleFileNameW(HMODULE hModule, LPWSTR lpFilename, DWORD nSize)
240 SetLastError(ERROR_INTERNAL_ERROR);
244 char* name = calloc(nSize,
sizeof(
char));
247 SetLastError(ERROR_INTERNAL_ERROR);
250 status = GetModuleFileNameA(hModule, name, nSize);
252 if ((status > INT_MAX) || (nSize > INT_MAX))
254 SetLastError(ERROR_INTERNAL_ERROR);
260 if (ConvertUtf8NToWChar(name, status, lpFilename, nSize) < 0)
263 SetLastError(ERROR_INTERNAL_ERROR);
272#if defined(__linux__) || defined(__NetBSD__) || defined(__DragonFly__)
273static DWORD module_from_proc(
const char* proc, LPSTR lpFilename, DWORD nSize)
275 char buffer[8192] = { 0 };
276 ssize_t status = readlink(proc, buffer, ARRAYSIZE(buffer) - 1);
278 if ((status < 0) || ((
size_t)status >= ARRAYSIZE(buffer)))
280 SetLastError(ERROR_INTERNAL_ERROR);
284 const size_t length = strnlen(buffer, ARRAYSIZE(buffer));
288 CopyMemory(lpFilename, buffer, length);
289 lpFilename[length] =
'\0';
290 return (DWORD)length;
293 CopyMemory(lpFilename, buffer, nSize - 1);
294 lpFilename[nSize - 1] =
'\0';
295 SetLastError(ERROR_INSUFFICIENT_BUFFER);
300DWORD GetModuleFileNameA(HMODULE hModule, LPSTR lpFilename, DWORD nSize)
304 WLog_ERR(TAG,
"is not implemented");
305 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
309#if defined(__linux__)
310 return module_from_proc(
"/proc/self/exe", lpFilename, nSize);
311#elif defined(__FreeBSD__)
312 int mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1 };
316 const int rc = sysctl(mib, ARRAYSIZE(mib), NULL, &cb, NULL, 0);
319 SetLastError(ERROR_INTERNAL_ERROR);
324 char* fullname = calloc(cb + 1,
sizeof(
char));
327 SetLastError(ERROR_INTERNAL_ERROR);
333 const int rc = sysctl(mib, ARRAYSIZE(mib), fullname, &cb2, NULL, 0);
334 if ((rc != 0) || (cb2 != cb))
336 SetLastError(ERROR_INTERNAL_ERROR);
344 strncpy(lpFilename, fullname, nSize - 1);
345 lpFilename[nSize - 1] =
'\0';
350 SetLastError(ERROR_INSUFFICIENT_BUFFER);
352 return (DWORD)MIN(nSize, cb);
353#elif defined(__NetBSD__)
354 return module_from_proc(
"/proc/curproc/exe", lpFilename, nSize);
355#elif defined(__DragonFly__)
356 return module_from_proc(
"/proc/curproc/file", lpFilename, nSize);
357#elif defined(__MACOSX__)
358 char path[4096] = { 0 };
359 char buffer[4096] = { 0 };
360 uint32_t size =
sizeof(path);
361 const int status = _NSGetExecutablePath(path, &size);
366 SetLastError(ERROR_INTERNAL_ERROR);
374 realpath(path, buffer);
375 const size_t length = strnlen(buffer,
sizeof(buffer));
379 CopyMemory(lpFilename, buffer, length);
380 lpFilename[length] =
'\0';
381 return (DWORD)length;
384 CopyMemory(lpFilename, buffer, nSize - 1);
385 lpFilename[nSize - 1] =
'\0';
386 SetLastError(ERROR_INSUFFICIENT_BUFFER);
389 WLog_ERR(TAG,
"is not implemented");
390 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
397HMODULE LoadLibraryX(LPCSTR lpLibFileName)
404 wstr = ConvertUtf8ToWCharAlloc(lpLibFileName, NULL);
406 hm = LoadLibraryW(wstr);
410 return LoadLibraryA(lpLibFileName);
414HMODULE LoadLibraryExX(LPCSTR lpLibFileName, HANDLE hFile, DWORD dwFlags)
420 WCHAR* wstr = ConvertUtf8ToWCharAlloc(lpLibFileName, NULL);
422 hm = LoadLibraryExW(wstr, hFile, dwFlags);
426 return LoadLibraryExA(lpLibFileName, hFile, dwFlags);