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 defined(_UWP)
146 return LoadPackagedLibrary(lpLibFileName, 0);
147#else
148 char* name = NULL;
149
150 if (lpLibFileName)
151 name = ConvertWCharToUtf8Alloc(lpLibFileName, NULL);
152
153 HMODULE module = LoadLibraryA(name);
154 free(name);
155 return module;
156#endif
157}
158
159HMODULE LoadLibraryExA(LPCSTR lpLibFileName, HANDLE hFile, DWORD dwFlags)
160{
161 if (dwFlags != 0)
162 WLog_WARN(TAG, "does not support dwFlags 0x%08" PRIx32, dwFlags);
163
164 if (hFile)
165 WLog_WARN(TAG, "does not support hFile != NULL");
166
167 return LoadLibraryA(lpLibFileName);
168}
169
170HMODULE LoadLibraryExW(LPCWSTR lpLibFileName, HANDLE hFile, DWORD dwFlags)
171{
172 if (dwFlags != 0)
173 WLog_WARN(TAG, "does not support dwFlags 0x%08" PRIx32, dwFlags);
174
175 if (hFile)
176 WLog_WARN(TAG, "does not support hFile != NULL");
177
178 return LoadLibraryW(lpLibFileName);
179}
180
181#endif
182
183#if !defined(_WIN32) && !defined(__CYGWIN__)
184
185FARPROC GetProcAddress(HMODULE hModule, LPCSTR lpProcName)
186{
187 FARPROC proc = NULL;
188 proc = dlsym(hModule, lpProcName);
189
190 if (proc == NULL)
191 {
192 // NOLINTNEXTLINE(concurrency-mt-unsafe)
193 WLog_ERR(TAG, "GetProcAddress: could not find procedure %s: %s", lpProcName, dlerror());
194 return (FARPROC)NULL;
195 }
196
197 return proc;
198}
199
200BOOL FreeLibrary(HMODULE hLibModule)
201{
202 int status = 0;
203 status = dlclose(hLibModule);
204
205 if (status != 0)
206 return FALSE;
207
208 return TRUE;
209}
210
211HMODULE GetModuleHandleA(WINPR_ATTR_UNUSED LPCSTR lpModuleName)
212{
213 /* TODO: Implement */
214 WLog_ERR(TAG, "not implemented");
215 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
216 return NULL;
217}
218
219HMODULE GetModuleHandleW(WINPR_ATTR_UNUSED LPCWSTR lpModuleName)
220{
221 /* TODO: Implement */
222 WLog_ERR(TAG, "not implemented");
223 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
224 return NULL;
225}
226
235DWORD GetModuleFileNameW(HMODULE hModule, LPWSTR lpFilename, DWORD nSize)
236{
237 DWORD status = 0;
238 if (!lpFilename)
239 {
240 SetLastError(ERROR_INTERNAL_ERROR);
241 return 0;
242 }
243
244 char* name = calloc(nSize, sizeof(char));
245 if (!name)
246 {
247 SetLastError(ERROR_INTERNAL_ERROR);
248 return 0;
249 }
250 status = GetModuleFileNameA(hModule, name, nSize);
251
252 if ((status > INT_MAX) || (nSize > INT_MAX))
253 {
254 SetLastError(ERROR_INTERNAL_ERROR);
255 status = 0;
256 }
257
258 if (status > 0)
259 {
260 if (ConvertUtf8NToWChar(name, status, lpFilename, nSize) < 0)
261 {
262 free(name);
263 SetLastError(ERROR_INTERNAL_ERROR);
264 return 0;
265 }
266 }
267
268 free(name);
269 return status;
270}
271
272#if defined(__linux__) || defined(__NetBSD__) || defined(__DragonFly__)
273static DWORD module_from_proc(const char* proc, LPSTR lpFilename, DWORD nSize)
274{
275 char buffer[8192] = { 0 };
276 ssize_t status = readlink(proc, buffer, ARRAYSIZE(buffer) - 1);
277
278 if ((status < 0) || ((size_t)status >= ARRAYSIZE(buffer)))
279 {
280 SetLastError(ERROR_INTERNAL_ERROR);
281 return 0;
282 }
283
284 const size_t length = strnlen(buffer, ARRAYSIZE(buffer));
285
286 if (length < nSize)
287 {
288 CopyMemory(lpFilename, buffer, length);
289 lpFilename[length] = '\0';
290 return (DWORD)length;
291 }
292
293 CopyMemory(lpFilename, buffer, nSize - 1);
294 lpFilename[nSize - 1] = '\0';
295 SetLastError(ERROR_INSUFFICIENT_BUFFER);
296 return nSize;
297}
298#endif
299
300DWORD GetModuleFileNameA(HMODULE hModule, LPSTR lpFilename, DWORD nSize)
301{
302 if (hModule)
303 {
304 WLog_ERR(TAG, "is not implemented");
305 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
306 return 0;
307 }
308
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 };
313 size_t cb = nSize;
314
315 {
316 const int rc = sysctl(mib, ARRAYSIZE(mib), NULL, &cb, NULL, 0);
317 if (rc != 0)
318 {
319 SetLastError(ERROR_INTERNAL_ERROR);
320 return 0;
321 }
322 }
323
324 char* fullname = calloc(cb + 1, sizeof(char));
325 if (!fullname)
326 {
327 SetLastError(ERROR_INTERNAL_ERROR);
328 return 0;
329 }
330
331 {
332 size_t cb2 = cb;
333 const int rc = sysctl(mib, ARRAYSIZE(mib), fullname, &cb2, NULL, 0);
334 if ((rc != 0) || (cb2 != cb))
335 {
336 SetLastError(ERROR_INTERNAL_ERROR);
337 free(fullname);
338 return 0;
339 }
340 }
341
342 if (nSize > 0)
343 {
344 strncpy(lpFilename, fullname, nSize - 1);
345 lpFilename[nSize - 1] = '\0';
346 }
347 free(fullname);
348
349 if (nSize < cb)
350 SetLastError(ERROR_INSUFFICIENT_BUFFER);
351
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);
362
363 if (status != 0)
364 {
365 /* path too small */
366 SetLastError(ERROR_INTERNAL_ERROR);
367 return 0;
368 }
369
370 /*
371 * _NSGetExecutablePath may not return the canonical path,
372 * so use realpath to find the absolute, canonical path.
373 */
374 realpath(path, buffer);
375 const size_t length = strnlen(buffer, sizeof(buffer));
376
377 if (length < nSize)
378 {
379 CopyMemory(lpFilename, buffer, length);
380 lpFilename[length] = '\0';
381 return (DWORD)length;
382 }
383
384 CopyMemory(lpFilename, buffer, nSize - 1);
385 lpFilename[nSize - 1] = '\0';
386 SetLastError(ERROR_INSUFFICIENT_BUFFER);
387 return nSize;
388#else
389 WLog_ERR(TAG, "is not implemented");
390 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
391 return 0;
392#endif
393}
394
395#endif
396
397HMODULE LoadLibraryX(LPCSTR lpLibFileName)
398{
399#if defined(_WIN32)
400 HMODULE hm = NULL;
401 WCHAR* wstr = NULL;
402
403 if (lpLibFileName)
404 wstr = ConvertUtf8ToWCharAlloc(lpLibFileName, NULL);
405
406 hm = LoadLibraryW(wstr);
407 free(wstr);
408 return hm;
409#else
410 return LoadLibraryA(lpLibFileName);
411#endif
412}
413
414HMODULE LoadLibraryExX(LPCSTR lpLibFileName, HANDLE hFile, DWORD dwFlags)
415{
416 if (!lpLibFileName)
417 return NULL;
418#if defined(_WIN32)
419 HMODULE hm = NULL;
420 WCHAR* wstr = ConvertUtf8ToWCharAlloc(lpLibFileName, NULL);
421 if (wstr)
422 hm = LoadLibraryExW(wstr, hFile, dwFlags);
423 free(wstr);
424 return hm;
425#else
426 return LoadLibraryExA(lpLibFileName, hFile, dwFlags);
427#endif
428}