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 =
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_ERR(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);
295DWORD GetModuleFileNameA(HMODULE hModule, LPSTR lpFilename, DWORD nSize)
299 WLog_ERR(TAG,
"is not implemented");
300 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
304#if defined(__linux__)
305 return module_from_proc(
"/proc/self/exe", lpFilename, nSize);
306#elif defined(__FreeBSD__)
307 int mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1 };
311 const int rc = sysctl(mib, ARRAYSIZE(mib),
nullptr, &cb,
nullptr, 0);
314 SetLastError(ERROR_INTERNAL_ERROR);
319 char* fullname = calloc(cb + 1,
sizeof(
char));
322 SetLastError(ERROR_INTERNAL_ERROR);
328 const int rc = sysctl(mib, ARRAYSIZE(mib), fullname, &cb2,
nullptr, 0);
329 if ((rc != 0) || (cb2 != cb))
331 SetLastError(ERROR_INTERNAL_ERROR);
339 strncpy(lpFilename, fullname, nSize - 1);
340 lpFilename[nSize - 1] =
'\0';
345 SetLastError(ERROR_INSUFFICIENT_BUFFER);
347 return (DWORD)MIN(nSize, cb);
348#elif defined(__NetBSD__)
349 return module_from_proc(
"/proc/curproc/exe", lpFilename, nSize);
350#elif defined(__DragonFly__)
351 return module_from_proc(
"/proc/curproc/file", lpFilename, nSize);
352#elif defined(__MACOSX__)
353 char path[4096] = WINPR_C_ARRAY_INIT;
354 char buffer[4096] = WINPR_C_ARRAY_INIT;
355 uint32_t size =
sizeof(path);
356 const int status = _NSGetExecutablePath(path, &size);
361 SetLastError(ERROR_INTERNAL_ERROR);
369 realpath(path, buffer);
370 const size_t length = strnlen(buffer,
sizeof(buffer));
374 CopyMemory(lpFilename, buffer, length);
375 lpFilename[length] =
'\0';
376 return (DWORD)length;
379 CopyMemory(lpFilename, buffer, nSize - 1);
380 lpFilename[nSize - 1] =
'\0';
381 SetLastError(ERROR_INSUFFICIENT_BUFFER);
384 WLog_ERR(TAG,
"is not implemented");
385 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
392HMODULE LoadLibraryX(LPCSTR lpLibFileName)
395 HMODULE hm =
nullptr;
396 WCHAR* wstr =
nullptr;
399 wstr = ConvertUtf8ToWCharAlloc(lpLibFileName,
nullptr);
401 hm = LoadLibraryW(wstr);
405 return LoadLibraryA(lpLibFileName);
409HMODULE LoadLibraryExX(LPCSTR lpLibFileName, HANDLE hFile, DWORD dwFlags)
414 HMODULE hm =
nullptr;
415 WCHAR* wstr = ConvertUtf8ToWCharAlloc(lpLibFileName,
nullptr);
417 hm = LoadLibraryExW(wstr, hFile, dwFlags);
421 return LoadLibraryExA(lpLibFileName, hFile, dwFlags);