char* GetCombinedPath(const char* basePath, const char* subPath) { int length; HRESULT status; char* path = NULL; char* subPathCpy; int basePathLength = 0; int subPathLength = 0; if (basePath) basePathLength = strlen(basePath); if (subPath) subPathLength = strlen(subPath); length = basePathLength + subPathLength + 1; path = (char*) malloc(length + 1); if (!path) return NULL; if (basePath) CopyMemory(path, basePath, basePathLength); path[basePathLength] = '\0'; if (FAILED(PathCchConvertStyleA(path, basePathLength, PATH_STYLE_NATIVE))) { free(path); return NULL; } if (!subPath) return path; subPathCpy = _strdup(subPath); if (!subPathCpy) { free(path); return NULL; } if (FAILED(PathCchConvertStyleA(subPathCpy, subPathLength, PATH_STYLE_NATIVE))) { free(path); free(subPathCpy); return NULL; } status = NativePathCchAppendA(path, length + 1, subPathCpy); free(subPathCpy); if (FAILED(status)) { free(path); return NULL; } else return path; }
int TestLibraryLoadLibrary(int argc, char* argv[]) { HINSTANCE library; LPCSTR SharedLibraryExtension; CHAR LibraryPath[PATHCCH_MAX_CCH]; PCHAR p; if (!GetModuleFileNameA(NULL, LibraryPath, PATHCCH_MAX_CCH)) { printf("%s: GetModuleFilenameA failed: 0x%08"PRIX32"\n", __FUNCTION__, GetLastError()); return -1; } /* PathCchRemoveFileSpec is not implemented in WinPR */ if (!(p = strrchr(LibraryPath, PathGetSeparatorA(PATH_STYLE_NATIVE)))) { printf("%s: Error identifying module directory path\n", __FUNCTION__); return -1; } *p = 0; NativePathCchAppendA(LibraryPath, PATHCCH_MAX_CCH, "TestLibraryA"); SharedLibraryExtension = PathGetSharedLibraryExtensionA(PATH_SHARED_LIB_EXT_WITH_DOT); NativePathCchAddExtensionA(LibraryPath, PATHCCH_MAX_CCH, SharedLibraryExtension); printf("%s: Loading Library: '%s'\n", __FUNCTION__, LibraryPath); if (!(library = LoadLibraryA(LibraryPath))) { printf("%s: LoadLibraryA failure: 0x%08"PRIX32"\n", __FUNCTION__, GetLastError()); return -1; } if (!FreeLibrary(library)) { printf("%s: FreeLibrary failure: 0x%08"PRIX32"\n", __FUNCTION__, GetLastError()); return -1; } return 0; }
LPSTR freerdp_get_dynamic_addin_install_path(void) { LPSTR pszPath; size_t cchPath; size_t cchAddinPath; size_t cchInstallPrefix; BOOL needLibPath, needInstallPath; LPCSTR pszAddinPath = FREERDP_ADDIN_PATH; LPCSTR pszInstallPrefix = FREERDP_INSTALL_PREFIX; cchAddinPath = strlen(pszAddinPath) + 1; cchInstallPrefix = strlen(pszInstallPrefix) + 1; cchPath = cchInstallPrefix + cchAddinPath; needInstallPath = is_path_required(pszInstallPrefix, cchInstallPrefix); needLibPath = is_path_required(pszAddinPath, cchAddinPath); if (!needInstallPath && !needLibPath) return NULL; pszPath = (LPSTR) calloc(cchPath + 1, sizeof(CHAR)); if (!pszPath) return NULL; if (needInstallPath) { CopyMemory(pszPath, pszInstallPrefix, cchInstallPrefix); pszPath[cchInstallPrefix] = '\0'; } if (needLibPath) { if (FAILED(NativePathCchAppendA(pszPath, cchPath + 1, pszAddinPath))) { free(pszPath); return NULL; } } return pszPath; }
LPSTR freerdp_get_library_install_path(void) { LPSTR pszPath; size_t cchPath; size_t cchLibraryPath; size_t cchInstallPrefix; BOOL needLibPath, needInstallPath; LPCSTR pszLibraryPath = FREERDP_LIBRARY_PATH; LPCSTR pszInstallPrefix = FREERDP_INSTALL_PREFIX; cchLibraryPath = strlen(pszLibraryPath) + 1; cchInstallPrefix = strlen(pszInstallPrefix) + 1; cchPath = cchInstallPrefix + cchLibraryPath; needInstallPath = is_path_required(pszInstallPrefix, cchInstallPrefix); needLibPath = is_path_required(pszLibraryPath, cchLibraryPath); if (!needInstallPath && !needLibPath) return NULL; pszPath = (LPSTR) malloc(cchPath + 1); if (!pszPath) return NULL; if (needInstallPath) { CopyMemory(pszPath, pszInstallPrefix, cchInstallPrefix); pszPath[cchInstallPrefix] = '\0'; } if (needLibPath) { if (FAILED(NativePathCchAppendA(pszPath, cchPath + 1, pszLibraryPath))) { free(pszPath); return NULL; } } return pszPath; }
LPSTR freerdp_get_dynamic_addin_install_path() { LPSTR pszPath; size_t cchPath; size_t cchAddinPath; size_t cchInstallPrefix; LPCSTR pszAddinPath = FREERDP_ADDIN_PATH; LPCSTR pszInstallPrefix = FREERDP_INSTALL_PREFIX; cchAddinPath = strlen(pszAddinPath); cchInstallPrefix = strlen(pszInstallPrefix); cchPath = cchInstallPrefix + cchAddinPath + 2; pszPath = (LPSTR) malloc(cchPath + 1); CopyMemory(pszPath, pszInstallPrefix, cchInstallPrefix); pszPath[cchInstallPrefix] = '\0'; NativePathCchAppendA(pszPath, cchPath + 1, pszAddinPath); return pszPath; }
LPSTR freerdp_get_library_install_path() { LPSTR pszPath; size_t cchPath; size_t cchLibraryPath; size_t cchInstallPrefix; LPCSTR pszLibraryPath = FREERDP_LIBRARY_PATH; LPCSTR pszInstallPrefix = FREERDP_INSTALL_PREFIX; cchLibraryPath = strlen(pszLibraryPath); cchInstallPrefix = strlen(pszInstallPrefix); cchPath = cchInstallPrefix + cchLibraryPath + 2; pszPath = (LPSTR) malloc(cchPath + 1); CopyMemory(pszPath, pszInstallPrefix, cchInstallPrefix); pszPath[cchInstallPrefix] = '\0'; NativePathCchAppendA(pszPath, cchPath + 1, pszLibraryPath); return pszPath; }
void* freerdp_load_dynamic_addin(LPCSTR pszFileName, LPCSTR pszPath, LPCSTR pszEntryName) { void* entry; BOOL bHasExt; PCSTR pszExt; size_t cchExt; HINSTANCE library; size_t cchFileName; LPSTR pszFilePath; size_t cchFilePath; LPSTR pszAddinFile; size_t cchAddinFile; LPSTR pszAddinInstallPath; size_t cchAddinInstallPath; entry = NULL; cchExt = 0; bHasExt = TRUE; cchFileName = strlen(pszFileName); if (PathCchFindExtensionA(pszFileName, cchFileName + 1, &pszExt) != S_OK) { pszExt = PathGetSharedLibraryExtensionA(PATH_SHARED_LIB_EXT_WITH_DOT); cchExt = strlen(pszExt); bHasExt = FALSE; } pszAddinInstallPath = freerdp_get_dynamic_addin_install_path(); cchAddinInstallPath = strlen(pszAddinInstallPath); cchFilePath = cchAddinInstallPath + cchFileName + 32; pszFilePath = (LPSTR) malloc(cchFilePath + 1); if (bHasExt) { pszAddinFile = _strdup(pszFileName); cchAddinFile = strlen(pszAddinFile); } else { cchAddinFile = cchFileName + cchExt + 2; pszAddinFile = (LPSTR) malloc(cchAddinFile + 1); sprintf_s(pszAddinFile, cchAddinFile, "%s%s", pszFileName, pszExt); cchAddinFile = strlen(pszAddinFile); } CopyMemory(pszFilePath, pszAddinInstallPath, cchAddinInstallPath); pszFilePath[cchAddinInstallPath] = '\0'; NativePathCchAppendA((LPSTR) pszFilePath, cchFilePath + 1, pszAddinFile); library = LoadLibraryA(pszFilePath); free(pszAddinInstallPath); free(pszAddinFile); free(pszFilePath); if (!library) return NULL; entry = GetProcAddress(library, pszEntryName); if (entry) return entry; FreeLibrary(library); return entry; }
PVIRTUALCHANNELENTRY freerdp_load_dynamic_addin(LPCSTR pszFileName, LPCSTR pszPath, LPCSTR pszEntryName) { LPSTR pszAddinInstallPath = freerdp_get_dynamic_addin_install_path(); PVIRTUALCHANNELENTRY entry = NULL; BOOL bHasExt = TRUE; PCSTR pszExt; size_t cchExt = 0; HINSTANCE library = NULL; size_t cchFileName; size_t cchFilePath; LPSTR pszAddinFile = NULL; LPSTR pszFilePath = NULL; LPSTR pszRelativeFilePath = NULL; size_t cchAddinFile; size_t cchAddinInstallPath; if (!pszFileName || !pszEntryName) goto fail; cchFileName = strlen(pszFileName); /* Get file name with prefix and extension */ if (FAILED(PathCchFindExtensionA(pszFileName, cchFileName + 1, &pszExt))) { pszExt = PathGetSharedLibraryExtensionA(PATH_SHARED_LIB_EXT_WITH_DOT); cchExt = strlen(pszExt); bHasExt = FALSE; } if (bHasExt) { pszAddinFile = _strdup(pszFileName); if (!pszAddinFile) goto fail; } else { cchAddinFile = cchFileName + cchExt + 2 + sizeof(FREERDP_SHARED_LIBRARY_PREFIX); pszAddinFile = (LPSTR) malloc(cchAddinFile + 1); if (!pszAddinFile) goto fail; sprintf_s(pszAddinFile, cchAddinFile, FREERDP_SHARED_LIBRARY_PREFIX"%s%s", pszFileName, pszExt); } cchAddinFile = strlen(pszAddinFile); /* If a path is provided prefix the library name with it. */ if (pszPath) { size_t relPathLen = strlen(pszPath) + cchAddinFile + 1; pszRelativeFilePath = calloc(relPathLen, sizeof(CHAR)); if (!pszRelativeFilePath) goto fail; sprintf_s(pszRelativeFilePath, relPathLen, "%s", pszRelativeFilePath); NativePathCchAppendA(pszRelativeFilePath, relPathLen, pszAddinFile); } else pszRelativeFilePath = _strdup(pszAddinFile); if (!pszRelativeFilePath) goto fail; /* If a system prefix path is provided try these locations too. */ if (pszAddinInstallPath) { cchAddinInstallPath = strlen(pszAddinInstallPath); cchFilePath = cchAddinInstallPath + cchFileName + 32; pszFilePath = (LPSTR) malloc(cchFilePath + 1); if (!pszFilePath) goto fail; CopyMemory(pszFilePath, pszAddinInstallPath, cchAddinInstallPath); pszFilePath[cchAddinInstallPath] = '\0'; NativePathCchAppendA((LPSTR) pszFilePath, cchFilePath + 1, pszRelativeFilePath); } else pszFilePath = _strdup(pszRelativeFilePath); library = LoadLibraryA(pszFilePath); if (!library) goto fail; entry = (PVIRTUALCHANNELENTRY)GetProcAddress(library, pszEntryName); fail: free(pszRelativeFilePath); free(pszAddinFile); free(pszFilePath); free(pszAddinInstallPath); if (!entry && library) FreeLibrary(library); return entry; }