FreeRDP
Loading...
Searching...
No Matches
library.c
1
20#include <winpr/config.h>
21
22#include <winpr/crt.h>
23#include <winpr/platform.h>
24
25#include <winpr/library.h>
26
27#include "../log.h"
28#define TAG WINPR_TAG("library")
29
65#if !defined(_WIN32) || defined(_UWP)
66
67#ifndef _WIN32
68
69#include <dlfcn.h>
70#include <stdio.h>
71#include <stdlib.h>
72#include <unistd.h>
73#include <sys/types.h>
74#include <sys/stat.h>
75
76#ifdef __MACOSX__
77#include <mach-o/dyld.h>
78#endif
79
80#if defined(__FreeBSD__)
81#include <sys/sysctl.h>
82#endif
83
84#endif
85
86DLL_DIRECTORY_COOKIE AddDllDirectory(WINPR_ATTR_UNUSED PCWSTR NewDirectory)
87{
88 /* TODO: Implement */
89 WLog_ERR(TAG, "not implemented");
90 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
91 return NULL;
92}
93
94BOOL RemoveDllDirectory(WINPR_ATTR_UNUSED DLL_DIRECTORY_COOKIE Cookie)
95{
96 /* TODO: Implement */
97 WLog_ERR(TAG, "not implemented");
98 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
99 return FALSE;
100}
101
102BOOL SetDefaultDllDirectories(WINPR_ATTR_UNUSED DWORD DirectoryFlags)
103{
104 /* TODO: Implement */
105 WLog_ERR(TAG, "not implemented");
106 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
107 return FALSE;
108}
109
110HMODULE LoadLibraryA(LPCSTR lpLibFileName)
111{
112#if defined(_UWP)
113 int status;
114 HMODULE hModule = NULL;
115 WCHAR* filenameW = NULL;
116
117 if (!lpLibFileName)
118 return NULL;
119
120 filenameW = ConvertUtf8ToWCharAlloc(lpLibFileName, NULL);
121 if (filenameW)
122 return NULL;
123
124 hModule = LoadLibraryW(filenameW);
125 free(filenameW);
126 return hModule;
127#else
128 HMODULE library = NULL;
129 library = dlopen(lpLibFileName, RTLD_LOCAL | RTLD_LAZY);
130
131 if (!library)
132 {
133 // NOLINTNEXTLINE(concurrency-mt-unsafe)
134 const char* err = dlerror();
135 WLog_ERR(TAG, "failed with %s", err);
136 return NULL;
137 }
138
139 return library;
140#endif
141}
142
143HMODULE LoadLibraryW(LPCWSTR lpLibFileName)
144{
145 if (!lpLibFileName)
146 return NULL;
147#if defined(_UWP)
148 return LoadPackagedLibrary(lpLibFileName, 0);
149#else
150 HMODULE module = NULL;
151 char* name = ConvertWCharToUtf8Alloc(lpLibFileName, NULL);
152 if (!name)
153 return NULL;
154
155 module = LoadLibraryA(name);
156 free(name);
157 return module;
158#endif
159}
160
161HMODULE LoadLibraryExA(LPCSTR lpLibFileName, HANDLE hFile, DWORD dwFlags)
162{
163 if (dwFlags != 0)
164 WLog_WARN(TAG, "does not support dwFlags 0x%08" PRIx32, dwFlags);
165
166 if (hFile)
167 WLog_WARN(TAG, "does not support hFile != NULL");
168
169 return LoadLibraryA(lpLibFileName);
170}
171
172HMODULE LoadLibraryExW(LPCWSTR lpLibFileName, HANDLE hFile, DWORD dwFlags)
173{
174 if (dwFlags != 0)
175 WLog_WARN(TAG, "does not support dwFlags 0x%08" PRIx32, dwFlags);
176
177 if (hFile)
178 WLog_WARN(TAG, "does not support hFile != NULL");
179
180 return LoadLibraryW(lpLibFileName);
181}
182
183#endif
184
185#if !defined(_WIN32) && !defined(__CYGWIN__)
186
187FARPROC GetProcAddress(HMODULE hModule, LPCSTR lpProcName)
188{
189 FARPROC proc = NULL;
190 proc = dlsym(hModule, lpProcName);
191
192 if (proc == NULL)
193 {
194 // NOLINTNEXTLINE(concurrency-mt-unsafe)
195 WLog_ERR(TAG, "GetProcAddress: could not find procedure %s: %s", lpProcName, dlerror());
196 return (FARPROC)NULL;
197 }
198
199 return proc;
200}
201
202BOOL FreeLibrary(HMODULE hLibModule)
203{
204 int status = 0;
205 status = dlclose(hLibModule);
206
207 if (status != 0)
208 return FALSE;
209
210 return TRUE;
211}
212
213HMODULE GetModuleHandleA(WINPR_ATTR_UNUSED LPCSTR lpModuleName)
214{
215 /* TODO: Implement */
216 WLog_ERR(TAG, "not implemented");
217 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
218 return NULL;
219}
220
221HMODULE GetModuleHandleW(WINPR_ATTR_UNUSED LPCWSTR lpModuleName)
222{
223 /* TODO: Implement */
224 WLog_ERR(TAG, "not implemented");
225 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
226 return NULL;
227}
228
237DWORD GetModuleFileNameW(HMODULE hModule, LPWSTR lpFilename, DWORD nSize)
238{
239 DWORD status = 0;
240 if (!lpFilename)
241 {
242 SetLastError(ERROR_INTERNAL_ERROR);
243 return 0;
244 }
245
246 char* name = calloc(nSize, sizeof(char));
247 if (!name)
248 {
249 SetLastError(ERROR_INTERNAL_ERROR);
250 return 0;
251 }
252 status = GetModuleFileNameA(hModule, name, nSize);
253
254 if ((status > INT_MAX) || (nSize > INT_MAX))
255 {
256 SetLastError(ERROR_INTERNAL_ERROR);
257 status = 0;
258 }
259
260 if (status > 0)
261 {
262 if (ConvertUtf8NToWChar(name, status, lpFilename, nSize) < 0)
263 {
264 free(name);
265 SetLastError(ERROR_INTERNAL_ERROR);
266 return 0;
267 }
268 }
269
270 free(name);
271 return status;
272}
273
274#if defined(__linux__) || defined(__NetBSD__) || defined(__DragonFly__)
275static DWORD module_from_proc(const char* proc, LPSTR lpFilename, DWORD nSize)
276{
277 char buffer[8192] = { 0 };
278 ssize_t status = readlink(proc, buffer, ARRAYSIZE(buffer) - 1);
279
280 if ((status < 0) || ((size_t)status >= ARRAYSIZE(buffer)))
281 {
282 SetLastError(ERROR_INTERNAL_ERROR);
283 return 0;
284 }
285
286 const size_t length = strnlen(buffer, ARRAYSIZE(buffer));
287
288 if (length < nSize)
289 {
290 CopyMemory(lpFilename, buffer, length);
291 lpFilename[length] = '\0';
292 return (DWORD)length;
293 }
294
295 CopyMemory(lpFilename, buffer, nSize - 1);
296 lpFilename[nSize - 1] = '\0';
297 SetLastError(ERROR_INSUFFICIENT_BUFFER);
298 return nSize;
299}
300#endif
301
302DWORD GetModuleFileNameA(HMODULE hModule, LPSTR lpFilename, DWORD nSize)
303{
304 if (hModule)
305 {
306 WLog_ERR(TAG, "is not implemented");
307 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
308 return 0;
309 }
310
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 };
315 size_t cb = nSize;
316
317 {
318 const int rc = sysctl(mib, ARRAYSIZE(mib), NULL, &cb, NULL, 0);
319 if (rc != 0)
320 {
321 SetLastError(ERROR_INTERNAL_ERROR);
322 return 0;
323 }
324 }
325
326 char* fullname = calloc(cb + 1, sizeof(char));
327 if (!fullname)
328 {
329 SetLastError(ERROR_INTERNAL_ERROR);
330 return 0;
331 }
332
333 {
334 size_t cb2 = cb;
335 const int rc = sysctl(mib, ARRAYSIZE(mib), fullname, &cb2, NULL, 0);
336 if ((rc != 0) || (cb2 != cb))
337 {
338 SetLastError(ERROR_INTERNAL_ERROR);
339 free(fullname);
340 return 0;
341 }
342 }
343
344 if (nSize > 0)
345 {
346 strncpy(lpFilename, fullname, nSize - 1);
347 lpFilename[nSize - 1] = '\0';
348 }
349 free(fullname);
350
351 if (nSize < cb)
352 SetLastError(ERROR_INSUFFICIENT_BUFFER);
353
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);
364
365 if (status != 0)
366 {
367 /* path too small */
368 SetLastError(ERROR_INTERNAL_ERROR);
369 return 0;
370 }
371
372 /*
373 * _NSGetExecutablePath may not return the canonical path,
374 * so use realpath to find the absolute, canonical path.
375 */
376 realpath(path, buffer);
377 const size_t length = strnlen(buffer, sizeof(buffer));
378
379 if (length < nSize)
380 {
381 CopyMemory(lpFilename, buffer, length);
382 lpFilename[length] = '\0';
383 return (DWORD)length;
384 }
385
386 CopyMemory(lpFilename, buffer, nSize - 1);
387 lpFilename[nSize - 1] = '\0';
388 SetLastError(ERROR_INSUFFICIENT_BUFFER);
389 return nSize;
390#else
391 WLog_ERR(TAG, "is not implemented");
392 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
393 return 0;
394#endif
395}
396
397#endif
398
399HMODULE LoadLibraryX(LPCSTR lpLibFileName)
400{
401 if (!lpLibFileName)
402 return NULL;
403
404#if defined(_WIN32)
405 HMODULE hm = NULL;
406 WCHAR* wstr = ConvertUtf8ToWCharAlloc(lpLibFileName, NULL);
407
408 if (wstr)
409 hm = LoadLibraryW(wstr);
410 free(wstr);
411 return hm;
412#else
413 return LoadLibraryA(lpLibFileName);
414#endif
415}
416
417HMODULE LoadLibraryExX(LPCSTR lpLibFileName, HANDLE hFile, DWORD dwFlags)
418{
419 if (!lpLibFileName)
420 return NULL;
421#if defined(_WIN32)
422 HMODULE hm = NULL;
423 WCHAR* wstr = ConvertUtf8ToWCharAlloc(lpLibFileName, NULL);
424 if (wstr)
425 hm = LoadLibraryExW(wstr, hFile, dwFlags);
426 free(wstr);
427 return hm;
428#else
429 return LoadLibraryExA(lpLibFileName, hFile, dwFlags);
430#endif
431}