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)
148 return LoadPackagedLibrary(lpLibFileName, 0);
150 HMODULE
module = NULL;
151 char* name = ConvertWCharToUtf8Alloc(lpLibFileName, NULL);
155 module = LoadLibraryA(name);
161HMODULE LoadLibraryExA(LPCSTR lpLibFileName, HANDLE hFile, DWORD dwFlags)
164 WLog_WARN(TAG,
"does not support dwFlags 0x%08" PRIx32, dwFlags);
167 WLog_WARN(TAG,
"does not support hFile != NULL");
169 return LoadLibraryA(lpLibFileName);
172HMODULE LoadLibraryExW(LPCWSTR lpLibFileName, HANDLE hFile, DWORD dwFlags)
175 WLog_WARN(TAG,
"does not support dwFlags 0x%08" PRIx32, dwFlags);
178 WLog_WARN(TAG,
"does not support hFile != NULL");
180 return LoadLibraryW(lpLibFileName);
185#if !defined(_WIN32) && !defined(__CYGWIN__)
187FARPROC GetProcAddress(HMODULE hModule, LPCSTR lpProcName)
190 proc = dlsym(hModule, lpProcName);
195 WLog_ERR(TAG,
"GetProcAddress: could not find procedure %s: %s", lpProcName, dlerror());
196 return (FARPROC)NULL;
202BOOL FreeLibrary(HMODULE hLibModule)
205 status = dlclose(hLibModule);
213HMODULE GetModuleHandleA(WINPR_ATTR_UNUSED LPCSTR lpModuleName)
216 WLog_ERR(TAG,
"not implemented");
217 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
221HMODULE GetModuleHandleW(WINPR_ATTR_UNUSED LPCWSTR lpModuleName)
224 WLog_ERR(TAG,
"not implemented");
225 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
237DWORD GetModuleFileNameW(HMODULE hModule, LPWSTR lpFilename, DWORD nSize)
242 SetLastError(ERROR_INTERNAL_ERROR);
246 char* name = calloc(nSize,
sizeof(
char));
249 SetLastError(ERROR_INTERNAL_ERROR);
252 status = GetModuleFileNameA(hModule, name, nSize);
254 if ((status > INT_MAX) || (nSize > INT_MAX))
256 SetLastError(ERROR_INTERNAL_ERROR);
262 if (ConvertUtf8NToWChar(name, status, lpFilename, nSize) < 0)
265 SetLastError(ERROR_INTERNAL_ERROR);
274#if defined(__linux__) || defined(__NetBSD__) || defined(__DragonFly__)
275static DWORD module_from_proc(
const char* proc, LPSTR lpFilename, DWORD nSize)
277 char buffer[8192] = { 0 };
278 ssize_t status = readlink(proc, buffer, ARRAYSIZE(buffer) - 1);
280 if ((status < 0) || ((
size_t)status >= ARRAYSIZE(buffer)))
282 SetLastError(ERROR_INTERNAL_ERROR);
286 const size_t length = strnlen(buffer, ARRAYSIZE(buffer));
290 CopyMemory(lpFilename, buffer, length);
291 lpFilename[length] =
'\0';
292 return (DWORD)length;
295 CopyMemory(lpFilename, buffer, nSize - 1);
296 lpFilename[nSize - 1] =
'\0';
297 SetLastError(ERROR_INSUFFICIENT_BUFFER);
302DWORD GetModuleFileNameA(HMODULE hModule, LPSTR lpFilename, DWORD nSize)
306 WLog_ERR(TAG,
"is not implemented");
307 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
311#if defined(__linux__)
312 return module_from_proc(
"/proc/self/exe", lpFilename, nSize);
313#elif defined(__FreeBSD__)
314 int mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1 };
318 const int rc = sysctl(mib, ARRAYSIZE(mib), NULL, &cb, NULL, 0);
321 SetLastError(ERROR_INTERNAL_ERROR);
326 char* fullname = calloc(cb + 1,
sizeof(
char));
329 SetLastError(ERROR_INTERNAL_ERROR);
335 const int rc = sysctl(mib, ARRAYSIZE(mib), fullname, &cb2, NULL, 0);
336 if ((rc != 0) || (cb2 != cb))
338 SetLastError(ERROR_INTERNAL_ERROR);
346 strncpy(lpFilename, fullname, nSize - 1);
347 lpFilename[nSize - 1] =
'\0';
352 SetLastError(ERROR_INSUFFICIENT_BUFFER);
354 return (DWORD)MIN(nSize, cb);
355#elif defined(__NetBSD__)
356 return module_from_proc(
"/proc/curproc/exe", lpFilename, nSize);
357#elif defined(__DragonFly__)
358 return module_from_proc(
"/proc/curproc/file", lpFilename, nSize);
359#elif defined(__MACOSX__)
360 char path[4096] = { 0 };
361 char buffer[4096] = { 0 };
362 uint32_t size =
sizeof(path);
363 const int status = _NSGetExecutablePath(path, &size);
368 SetLastError(ERROR_INTERNAL_ERROR);
376 realpath(path, buffer);
377 const size_t length = strnlen(buffer,
sizeof(buffer));
381 CopyMemory(lpFilename, buffer, length);
382 lpFilename[length] =
'\0';
383 return (DWORD)length;
386 CopyMemory(lpFilename, buffer, nSize - 1);
387 lpFilename[nSize - 1] =
'\0';
388 SetLastError(ERROR_INSUFFICIENT_BUFFER);
391 WLog_ERR(TAG,
"is not implemented");
392 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
399HMODULE LoadLibraryX(LPCSTR lpLibFileName)
406 WCHAR* wstr = ConvertUtf8ToWCharAlloc(lpLibFileName, NULL);
409 hm = LoadLibraryW(wstr);
413 return LoadLibraryA(lpLibFileName);
417HMODULE LoadLibraryExX(LPCSTR lpLibFileName, HANDLE hFile, DWORD dwFlags)
423 WCHAR* wstr = ConvertUtf8ToWCharAlloc(lpLibFileName, NULL);
425 hm = LoadLibraryExW(wstr, hFile, dwFlags);
429 return LoadLibraryExA(lpLibFileName, hFile, dwFlags);