summaryrefslogtreecommitdiffstats
path: root/winpr/libwinpr/library/library.c
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-04 01:24:41 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-04 01:24:41 +0000
commita9bcc81f821d7c66f623779fa5147e728eb3c388 (patch)
tree98676963bcdd537ae5908a067a8eb110b93486a6 /winpr/libwinpr/library/library.c
parentInitial commit. (diff)
downloadfreerdp3-a9bcc81f821d7c66f623779fa5147e728eb3c388.tar.xz
freerdp3-a9bcc81f821d7c66f623779fa5147e728eb3c388.zip
Adding upstream version 3.3.0+dfsg1.upstream/3.3.0+dfsg1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'winpr/libwinpr/library/library.c')
-rw-r--r--winpr/libwinpr/library/library.c381
1 files changed, 381 insertions, 0 deletions
diff --git a/winpr/libwinpr/library/library.c b/winpr/libwinpr/library/library.c
new file mode 100644
index 0000000..307dc20
--- /dev/null
+++ b/winpr/libwinpr/library/library.c
@@ -0,0 +1,381 @@
+/**
+ * WinPR: Windows Portable Runtime
+ * Library Loader
+ *
+ * Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <winpr/config.h>
+
+#include <winpr/crt.h>
+#include <winpr/platform.h>
+
+#include <winpr/library.h>
+
+#include "../log.h"
+#define TAG WINPR_TAG("library")
+
+/**
+ * api-ms-win-core-libraryloader-l1-1-1.dll:
+ *
+ * AddDllDirectory
+ * RemoveDllDirectory
+ * SetDefaultDllDirectories
+ * DisableThreadLibraryCalls
+ * EnumResourceLanguagesExA
+ * EnumResourceLanguagesExW
+ * EnumResourceNamesExA
+ * EnumResourceNamesExW
+ * EnumResourceTypesExA
+ * EnumResourceTypesExW
+ * FindResourceExW
+ * FindStringOrdinal
+ * FreeLibrary
+ * FreeLibraryAndExitThread
+ * FreeResource
+ * GetModuleFileNameA
+ * GetModuleFileNameW
+ * GetModuleHandleA
+ * GetModuleHandleExA
+ * GetModuleHandleExW
+ * GetModuleHandleW
+ * GetProcAddress
+ * LoadLibraryExA
+ * LoadLibraryExW
+ * LoadResource
+ * LoadStringA
+ * LoadStringW
+ * LockResource
+ * QueryOptionalDelayLoadedAPI
+ * SizeofResource
+ */
+
+#if !defined(_WIN32) || defined(_UWP)
+
+#ifndef _WIN32
+
+#include <dlfcn.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#ifdef __MACOSX__
+#include <mach-o/dyld.h>
+#endif
+
+#endif
+
+DLL_DIRECTORY_COOKIE AddDllDirectory(PCWSTR NewDirectory)
+{
+ /* TODO: Implement */
+ WLog_ERR(TAG, "not implemented");
+ SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ return NULL;
+}
+
+BOOL RemoveDllDirectory(DLL_DIRECTORY_COOKIE Cookie)
+{
+ /* TODO: Implement */
+ WLog_ERR(TAG, "not implemented");
+ SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ return FALSE;
+}
+
+BOOL SetDefaultDllDirectories(DWORD DirectoryFlags)
+{
+ /* TODO: Implement */
+ WLog_ERR(TAG, "not implemented");
+ SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ return FALSE;
+}
+
+HMODULE LoadLibraryA(LPCSTR lpLibFileName)
+{
+#if defined(_UWP)
+ int status;
+ HMODULE hModule = NULL;
+ WCHAR* filenameW = NULL;
+
+ if (!lpLibFileName)
+ return NULL;
+
+ filenameW = ConvertUtf8ToWCharAlloc(lpLibFileName, NULL);
+ if (filenameW)
+ return NULL;
+
+ hModule = LoadLibraryW(filenameW);
+ free(filenameW);
+ return hModule;
+#else
+ HMODULE library = NULL;
+ library = dlopen(lpLibFileName, RTLD_LOCAL | RTLD_LAZY);
+
+ if (!library)
+ {
+ const char* err = dlerror();
+ WLog_ERR(TAG, "failed with %s", err);
+ return NULL;
+ }
+
+ return library;
+#endif
+}
+
+HMODULE LoadLibraryW(LPCWSTR lpLibFileName)
+{
+ if (!lpLibFileName)
+ return NULL;
+#if defined(_UWP)
+ return LoadPackagedLibrary(lpLibFileName, 0);
+#else
+ HMODULE module = NULL;
+ char* name = ConvertWCharToUtf8Alloc(lpLibFileName, NULL);
+ if (!name)
+ return NULL;
+
+ module = LoadLibraryA(name);
+ free(name);
+ return module;
+#endif
+}
+
+HMODULE LoadLibraryExA(LPCSTR lpLibFileName, HANDLE hFile, DWORD dwFlags)
+{
+ if (dwFlags != 0)
+ WLog_WARN(TAG, "does not support dwFlags 0x%08" PRIx32, dwFlags);
+
+ if (hFile)
+ WLog_WARN(TAG, "does not support hFile != NULL");
+
+ return LoadLibraryA(lpLibFileName);
+}
+
+HMODULE LoadLibraryExW(LPCWSTR lpLibFileName, HANDLE hFile, DWORD dwFlags)
+{
+ if (dwFlags != 0)
+ WLog_WARN(TAG, "does not support dwFlags 0x%08" PRIx32, dwFlags);
+
+ if (hFile)
+ WLog_WARN(TAG, "does not support hFile != NULL");
+
+ return LoadLibraryW(lpLibFileName);
+}
+
+#endif
+
+#if !defined(_WIN32) && !defined(__CYGWIN__)
+
+FARPROC GetProcAddress(HMODULE hModule, LPCSTR lpProcName)
+{
+ FARPROC proc = NULL;
+ proc = dlsym(hModule, lpProcName);
+
+ if (proc == NULL)
+ {
+ WLog_ERR(TAG, "GetProcAddress: could not find procedure %s: %s", lpProcName, dlerror());
+ return (FARPROC)NULL;
+ }
+
+ return proc;
+}
+
+BOOL FreeLibrary(HMODULE hLibModule)
+{
+ int status = 0;
+ status = dlclose(hLibModule);
+
+ if (status != 0)
+ return FALSE;
+
+ return TRUE;
+}
+
+HMODULE GetModuleHandleA(LPCSTR lpModuleName)
+{
+ /* TODO: Implement */
+ WLog_ERR(TAG, "not implemented");
+ SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ return NULL;
+}
+
+HMODULE GetModuleHandleW(LPCWSTR lpModuleName)
+{
+ /* TODO: Implement */
+ WLog_ERR(TAG, "not implemented");
+ SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ return NULL;
+}
+
+/**
+ * GetModuleFileName:
+ * http://msdn.microsoft.com/en-us/library/windows/desktop/ms683197/
+ *
+ * Finding current executable's path without /proc/self/exe:
+ * http://stackoverflow.com/questions/1023306/finding-current-executables-path-without-proc-self-exe
+ */
+
+DWORD GetModuleFileNameW(HMODULE hModule, LPWSTR lpFilename, DWORD nSize)
+{
+ DWORD status = 0;
+ if (!lpFilename)
+ {
+ SetLastError(ERROR_INTERNAL_ERROR);
+ return 0;
+ }
+
+ char* name = calloc(nSize, sizeof(char));
+ if (!name)
+ {
+ SetLastError(ERROR_INTERNAL_ERROR);
+ return 0;
+ }
+ status = GetModuleFileNameA(hModule, name, nSize);
+
+ if ((status > INT_MAX) || (nSize > INT_MAX))
+ {
+ SetLastError(ERROR_INTERNAL_ERROR);
+ status = 0;
+ }
+
+ if (status > 0)
+ {
+ if (ConvertUtf8NToWChar(name, status, lpFilename, nSize) < 0)
+ {
+ free(name);
+ SetLastError(ERROR_INTERNAL_ERROR);
+ return 0;
+ }
+ }
+
+ free(name);
+ return status;
+}
+
+DWORD GetModuleFileNameA(HMODULE hModule, LPSTR lpFilename, DWORD nSize)
+{
+#if defined(__linux__)
+ SSIZE_T status = 0;
+ size_t length = 0;
+ char path[64];
+
+ if (!hModule)
+ {
+ char buffer[4096];
+ sprintf_s(path, ARRAYSIZE(path), "/proc/%d/exe", getpid());
+ status = readlink(path, buffer, sizeof(buffer));
+
+ if (status < 0)
+ {
+ SetLastError(ERROR_INTERNAL_ERROR);
+ return 0;
+ }
+
+ buffer[status] = '\0';
+ length = strnlen(buffer, sizeof(buffer));
+
+ if (length < nSize)
+ {
+ CopyMemory(lpFilename, buffer, length);
+ lpFilename[length] = '\0';
+ return (DWORD)length;
+ }
+
+ CopyMemory(lpFilename, buffer, nSize - 1);
+ lpFilename[nSize - 1] = '\0';
+ SetLastError(ERROR_INSUFFICIENT_BUFFER);
+ return nSize;
+ }
+
+#elif defined(__MACOSX__)
+ int status;
+ size_t length;
+
+ if (!hModule)
+ {
+ char path[4096];
+ char buffer[4096];
+ uint32_t size = sizeof(path);
+ status = _NSGetExecutablePath(path, &size);
+
+ if (status != 0)
+ {
+ /* path too small */
+ SetLastError(ERROR_INTERNAL_ERROR);
+ return 0;
+ }
+
+ /*
+ * _NSGetExecutablePath may not return the canonical path,
+ * so use realpath to find the absolute, canonical path.
+ */
+ realpath(path, buffer);
+ length = strnlen(buffer, sizeof(buffer));
+
+ if (length < nSize)
+ {
+ CopyMemory(lpFilename, buffer, length);
+ lpFilename[length] = '\0';
+ return (DWORD)length;
+ }
+
+ CopyMemory(lpFilename, buffer, nSize - 1);
+ lpFilename[nSize - 1] = '\0';
+ SetLastError(ERROR_INSUFFICIENT_BUFFER);
+ return nSize;
+ }
+
+#endif
+ WLog_ERR(TAG, "is not implemented");
+ SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ return 0;
+}
+
+#endif
+
+HMODULE LoadLibraryX(LPCSTR lpLibFileName)
+{
+ if (!lpLibFileName)
+ return NULL;
+
+#if defined(_WIN32)
+ HMODULE hm = NULL;
+ WCHAR* wstr = ConvertUtf8ToWCharAlloc(lpLibFileName, NULL);
+
+ if (wstr)
+ hm = LoadLibraryW(wstr);
+ free(wstr);
+ return hm;
+#else
+ return LoadLibraryA(lpLibFileName);
+#endif
+}
+
+HMODULE LoadLibraryExX(LPCSTR lpLibFileName, HANDLE hFile, DWORD dwFlags)
+{
+ if (!lpLibFileName)
+ return NULL;
+#if defined(_WIN32)
+ HMODULE hm = NULL;
+ WCHAR* wstr = ConvertUtf8ToWCharAlloc(lpLibFileName, NULL);
+ if (wstr)
+ hm = LoadLibraryExW(wstr, hFile, dwFlags);
+ free(wstr);
+ return hm;
+#else
+ return LoadLibraryExA(lpLibFileName, hFile, dwFlags);
+#endif
+}