FreeRDP
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 
86 DLL_DIRECTORY_COOKIE AddDllDirectory(PCWSTR NewDirectory)
87 {
88  /* TODO: Implement */
89  WLog_ERR(TAG, "not implemented");
90  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
91  return NULL;
92 }
93 
94 BOOL RemoveDllDirectory(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 
102 BOOL SetDefaultDllDirectories(DWORD DirectoryFlags)
103 {
104  /* TODO: Implement */
105  WLog_ERR(TAG, "not implemented");
106  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
107  return FALSE;
108 }
109 
110 HMODULE 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  const char* err = dlerror();
134  WLog_ERR(TAG, "failed with %s", err);
135  return NULL;
136  }
137 
138  return library;
139 #endif
140 }
141 
142 HMODULE LoadLibraryW(LPCWSTR lpLibFileName)
143 {
144  if (!lpLibFileName)
145  return NULL;
146 #if defined(_UWP)
147  return LoadPackagedLibrary(lpLibFileName, 0);
148 #else
149  HMODULE module = NULL;
150  char* name = ConvertWCharToUtf8Alloc(lpLibFileName, NULL);
151  if (!name)
152  return NULL;
153 
154  module = LoadLibraryA(name);
155  free(name);
156  return module;
157 #endif
158 }
159 
160 HMODULE LoadLibraryExA(LPCSTR lpLibFileName, HANDLE hFile, DWORD dwFlags)
161 {
162  if (dwFlags != 0)
163  WLog_WARN(TAG, "does not support dwFlags 0x%08" PRIx32, dwFlags);
164 
165  if (hFile)
166  WLog_WARN(TAG, "does not support hFile != NULL");
167 
168  return LoadLibraryA(lpLibFileName);
169 }
170 
171 HMODULE LoadLibraryExW(LPCWSTR lpLibFileName, HANDLE hFile, DWORD dwFlags)
172 {
173  if (dwFlags != 0)
174  WLog_WARN(TAG, "does not support dwFlags 0x%08" PRIx32, dwFlags);
175 
176  if (hFile)
177  WLog_WARN(TAG, "does not support hFile != NULL");
178 
179  return LoadLibraryW(lpLibFileName);
180 }
181 
182 #endif
183 
184 #if !defined(_WIN32) && !defined(__CYGWIN__)
185 
186 FARPROC GetProcAddress(HMODULE hModule, LPCSTR lpProcName)
187 {
188  FARPROC proc = NULL;
189  proc = dlsym(hModule, lpProcName);
190 
191  if (proc == NULL)
192  {
193  WLog_ERR(TAG, "GetProcAddress: could not find procedure %s: %s", lpProcName, dlerror());
194  return (FARPROC)NULL;
195  }
196 
197  return proc;
198 }
199 
200 BOOL 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 
211 HMODULE GetModuleHandleA(LPCSTR lpModuleName)
212 {
213  /* TODO: Implement */
214  WLog_ERR(TAG, "not implemented");
215  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
216  return NULL;
217 }
218 
219 HMODULE GetModuleHandleW(LPCWSTR lpModuleName)
220 {
221  /* TODO: Implement */
222  WLog_ERR(TAG, "not implemented");
223  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
224  return NULL;
225 }
226 
235 DWORD 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__)
273 static 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 
300 DWORD GetModuleFileNameA(HMODULE hModule, LPSTR lpFilename, DWORD nSize)
301 {
302 #if defined(__linux__)
303  if (!hModule)
304  return module_from_proc("/proc/self/exe", lpFilename, nSize);
305 #elif defined(__FreeBSD__)
306  int mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1 };
307  size_t cb = nSize;
308 
309  const int rc = sysctl(mib, ARRAYSIZE(mib), lpFilename, &cb, NULL, 0);
310  if ((rc != 0) || (cb > nSize))
311  {
312  SetLastError(ERROR_INTERNAL_ERROR);
313  return 0;
314  }
315 
316  return (DWORD)cb;
317 #elif defined(__NetBSD__)
318  if (!hModule)
319  return module_from_proc("/proc/curproc/exe", lpFilename, nSize);
320 #elif defined(__DragonFly__)
321  if (!hModule)
322  return module_from_proc("/proc/curproc/file", lpFilename, nSize);
323 #elif defined(__MACOSX__)
324  int status;
325  size_t length;
326 
327  if (!hModule)
328  {
329  char path[4096];
330  char buffer[4096];
331  uint32_t size = sizeof(path);
332  status = _NSGetExecutablePath(path, &size);
333 
334  if (status != 0)
335  {
336  /* path too small */
337  SetLastError(ERROR_INTERNAL_ERROR);
338  return 0;
339  }
340 
341  /*
342  * _NSGetExecutablePath may not return the canonical path,
343  * so use realpath to find the absolute, canonical path.
344  */
345  realpath(path, buffer);
346  length = strnlen(buffer, sizeof(buffer));
347 
348  if (length < nSize)
349  {
350  CopyMemory(lpFilename, buffer, length);
351  lpFilename[length] = '\0';
352  return (DWORD)length;
353  }
354 
355  CopyMemory(lpFilename, buffer, nSize - 1);
356  lpFilename[nSize - 1] = '\0';
357  SetLastError(ERROR_INSUFFICIENT_BUFFER);
358  return nSize;
359  }
360 
361 #endif
362  WLog_ERR(TAG, "is not implemented");
363  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
364  return 0;
365 }
366 
367 #endif
368 
369 HMODULE LoadLibraryX(LPCSTR lpLibFileName)
370 {
371  if (!lpLibFileName)
372  return NULL;
373 
374 #if defined(_WIN32)
375  HMODULE hm = NULL;
376  WCHAR* wstr = ConvertUtf8ToWCharAlloc(lpLibFileName, NULL);
377 
378  if (wstr)
379  hm = LoadLibraryW(wstr);
380  free(wstr);
381  return hm;
382 #else
383  return LoadLibraryA(lpLibFileName);
384 #endif
385 }
386 
387 HMODULE LoadLibraryExX(LPCSTR lpLibFileName, HANDLE hFile, DWORD dwFlags)
388 {
389  if (!lpLibFileName)
390  return NULL;
391 #if defined(_WIN32)
392  HMODULE hm = NULL;
393  WCHAR* wstr = ConvertUtf8ToWCharAlloc(lpLibFileName, NULL);
394  if (wstr)
395  hm = LoadLibraryExW(wstr, hFile, dwFlags);
396  free(wstr);
397  return hm;
398 #else
399  return LoadLibraryExA(lpLibFileName, hFile, dwFlags);
400 #endif
401 }