Fixed addin loader, prefer system library paths.

This commit is contained in:
Armin Novak 2016-11-10 10:18:55 +01:00
parent 0febd9c7cd
commit 3f6bd603e9
3 changed files with 128 additions and 77 deletions

View File

@ -766,15 +766,21 @@ if (TARGET_ARCH MATCHES "sparc")
set(HAVE_ALIGNED_REQUIRED 1) set(HAVE_ALIGNED_REQUIRED 1)
endif() endif()
# Path to put FreeRDP data # Android expects all libraries to be loadable
set(FREERDP_DATA_PATH "${CMAKE_INSTALL_PREFIX}/share/freerdp${FREERDP_VERSION_MAJOR}") # without paths.
if (ANDROID)
# Path to put plugins set(FREERDP_DATA_PATH "share")
set(FREERDP_INSTALL_PREFIX ".")
set(FREERDP_LIBRARY_PATH "${CMAKE_INSTALL_LIBDIR}") set(FREERDP_LIBRARY_PATH ".")
set(FREERDP_PLUGIN_PATH ".")
set(FREERDP_PLUGIN_PATH "${CMAKE_INSTALL_LIBDIR}/freerdp${FREERDP_VERSION_MAJOR}") set(FREERDP_ADDIN_PATH ".")
set(FREERDP_ADDIN_PATH "${FREERDP_PLUGIN_PATH}") else (ANDROID)
set(FREERDP_DATA_PATH "${CMAKE_INSTALL_PREFIX}/share/freerdp${FREERDP_VERSION_MAJOR}")
set(FREERDP_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}")
set(FREERDP_LIBRARY_PATH "${CMAKE_INSTALL_LIBDIR}")
set(FREERDP_PLUGIN_PATH "${CMAKE_INSTALL_LIBDIR}/freerdp${FREERDP_VERSION_MAJOR}")
set(FREERDP_ADDIN_PATH "${FREERDP_PLUGIN_PATH}")
endif(ANDROID)
# Path to put extensions # Path to put extensions
set(FREERDP_EXTENSION_PATH "${CMAKE_INSTALL_FULL_LIBDIR}/freerdp${FREERDP_VERSION_MAJOR}/extensions") set(FREERDP_EXTENSION_PATH "${CMAKE_INSTALL_FULL_LIBDIR}/freerdp${FREERDP_VERSION_MAJOR}/extensions")

View File

@ -5,7 +5,7 @@
#define FREERDP_KEYMAP_PATH "${FREERDP_KEYMAP_PATH}" #define FREERDP_KEYMAP_PATH "${FREERDP_KEYMAP_PATH}"
#define FREERDP_PLUGIN_PATH "${FREERDP_PLUGIN_PATH}" #define FREERDP_PLUGIN_PATH "${FREERDP_PLUGIN_PATH}"
#define FREERDP_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}" #define FREERDP_INSTALL_PREFIX "${FREERDP_INSTALL_PREFIX}"
#define FREERDP_LIBRARY_PATH "${FREERDP_LIBRARY_PATH}" #define FREERDP_LIBRARY_PATH "${FREERDP_LIBRARY_PATH}"

View File

@ -35,29 +35,52 @@
#include <freerdp/log.h> #include <freerdp/log.h>
#define TAG FREERDP_TAG("addin") #define TAG FREERDP_TAG("addin")
static INLINE BOOL is_path_required(LPCSTR path, size_t len)
{
if (!path || (len <= 1))
return FALSE;
if (strcmp(path, ".") == 0)
return FALSE;
return TRUE;
}
LPSTR freerdp_get_library_install_path(void) LPSTR freerdp_get_library_install_path(void)
{ {
LPSTR pszPath; LPSTR pszPath;
size_t cchPath; size_t cchPath;
size_t cchLibraryPath; size_t cchLibraryPath;
size_t cchInstallPrefix; size_t cchInstallPrefix;
BOOL needLibPath, needInstallPath;
LPCSTR pszLibraryPath = FREERDP_LIBRARY_PATH; LPCSTR pszLibraryPath = FREERDP_LIBRARY_PATH;
LPCSTR pszInstallPrefix = FREERDP_INSTALL_PREFIX; LPCSTR pszInstallPrefix = FREERDP_INSTALL_PREFIX;
cchLibraryPath = strlen(pszLibraryPath); cchLibraryPath = strlen(pszLibraryPath) + 1;
cchInstallPrefix = strlen(pszInstallPrefix); cchInstallPrefix = strlen(pszInstallPrefix) + 1;
cchPath = cchInstallPrefix + cchLibraryPath + 2; 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); pszPath = (LPSTR) malloc(cchPath + 1);
if (!pszPath) if (!pszPath)
return NULL; return NULL;
CopyMemory(pszPath, pszInstallPrefix, cchInstallPrefix); if (needInstallPath)
pszPath[cchInstallPrefix] = '\0';
if (FAILED(NativePathCchAppendA(pszPath, cchPath + 1, pszLibraryPath)))
{ {
free(pszPath); CopyMemory(pszPath, pszInstallPrefix, cchInstallPrefix);
return NULL; pszPath[cchInstallPrefix] = '\0';
}
if (needLibPath)
{
if (FAILED(NativePathCchAppendA(pszPath, cchPath + 1, pszLibraryPath)))
{
free(pszPath);
return NULL;
}
} }
return pszPath; return pszPath;
@ -69,23 +92,37 @@ LPSTR freerdp_get_dynamic_addin_install_path(void)
size_t cchPath; size_t cchPath;
size_t cchAddinPath; size_t cchAddinPath;
size_t cchInstallPrefix; size_t cchInstallPrefix;
BOOL needLibPath, needInstallPath;
LPCSTR pszAddinPath = FREERDP_ADDIN_PATH; LPCSTR pszAddinPath = FREERDP_ADDIN_PATH;
LPCSTR pszInstallPrefix = FREERDP_INSTALL_PREFIX; LPCSTR pszInstallPrefix = FREERDP_INSTALL_PREFIX;
cchAddinPath = strlen(pszAddinPath); cchAddinPath = strlen(pszAddinPath) + 1;
cchInstallPrefix = strlen(pszInstallPrefix); cchInstallPrefix = strlen(pszInstallPrefix) + 1;
cchPath = cchInstallPrefix + cchAddinPath + 2; cchPath = cchInstallPrefix + cchAddinPath;
pszPath = (LPSTR) malloc(cchPath + 1);
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) if (!pszPath)
return NULL; return NULL;
CopyMemory(pszPath, pszInstallPrefix, cchInstallPrefix); if (needInstallPath)
pszPath[cchInstallPrefix] = '\0';
if (FAILED(NativePathCchAppendA(pszPath, cchPath + 1, pszAddinPath)))
{ {
free(pszPath); CopyMemory(pszPath, pszInstallPrefix, cchInstallPrefix);
return NULL; pszPath[cchInstallPrefix] = '\0';
}
if (needLibPath)
{
if (FAILED(NativePathCchAppendA(pszPath, cchPath + 1, pszAddinPath)))
{
free(pszPath);
return NULL;
}
} }
return pszPath; return pszPath;
@ -94,23 +131,26 @@ LPSTR freerdp_get_dynamic_addin_install_path(void)
PVIRTUALCHANNELENTRY freerdp_load_dynamic_addin(LPCSTR pszFileName, PVIRTUALCHANNELENTRY freerdp_load_dynamic_addin(LPCSTR pszFileName,
LPCSTR pszPath, LPCSTR pszEntryName) LPCSTR pszPath, LPCSTR pszEntryName)
{ {
PVIRTUALCHANNELENTRY entry; LPSTR pszAddinInstallPath = freerdp_get_dynamic_addin_install_path();
BOOL bHasExt; PVIRTUALCHANNELENTRY entry = NULL;
BOOL bHasExt = TRUE;
PCSTR pszExt; PCSTR pszExt;
size_t cchExt; size_t cchExt = 0;
HINSTANCE library; HINSTANCE library = NULL;
size_t cchFileName; size_t cchFileName;
LPSTR pszFilePath;
size_t cchFilePath; size_t cchFilePath;
LPSTR pszAddinFile; LPSTR pszAddinFile;
LPSTR pszFilePath = NULL;
LPSTR pszRelativeFilePath = NULL;
size_t cchAddinFile; size_t cchAddinFile;
LPSTR pszAddinInstallPath;
size_t cchAddinInstallPath; size_t cchAddinInstallPath;
entry = NULL;
cchExt = 0; if (!pszFileName || !pszEntryName)
bHasExt = TRUE; goto fail;
cchFileName = strlen(pszFileName); cchFileName = strlen(pszFileName);
/* Get file name with prefix and extension */
if (FAILED(PathCchFindExtensionA(pszFileName, cchFileName + 1, &pszExt))) if (FAILED(PathCchFindExtensionA(pszFileName, cchFileName + 1, &pszExt)))
{ {
pszExt = PathGetSharedLibraryExtensionA(PATH_SHARED_LIB_EXT_WITH_DOT); pszExt = PathGetSharedLibraryExtensionA(PATH_SHARED_LIB_EXT_WITH_DOT);
@ -118,33 +158,12 @@ PVIRTUALCHANNELENTRY freerdp_load_dynamic_addin(LPCSTR pszFileName,
bHasExt = FALSE; bHasExt = FALSE;
} }
pszAddinInstallPath = freerdp_get_dynamic_addin_install_path();
if (!pszAddinInstallPath)
return NULL;
cchAddinInstallPath = strlen(pszAddinInstallPath);
cchFilePath = cchAddinInstallPath + cchFileName + 32;
pszFilePath = (LPSTR) malloc(cchFilePath + 1);
if (!pszFilePath)
{
free(pszAddinInstallPath);
return NULL;
}
if (bHasExt) if (bHasExt)
{ {
pszAddinFile = _strdup(pszFileName); pszAddinFile = _strdup(pszFileName);
if (!pszAddinFile) if (!pszAddinFile)
{ goto fail;
free(pszAddinInstallPath);
free(pszFilePath);
return NULL;
}
cchAddinFile = strlen(pszAddinFile);
} }
else else
{ {
@ -152,34 +171,60 @@ PVIRTUALCHANNELENTRY freerdp_load_dynamic_addin(LPCSTR pszFileName,
pszAddinFile = (LPSTR) malloc(cchAddinFile + 1); pszAddinFile = (LPSTR) malloc(cchAddinFile + 1);
if (!pszAddinFile) if (!pszAddinFile)
{ goto fail;
free(pszAddinInstallPath);
free(pszFilePath);
return NULL;
}
sprintf_s(pszAddinFile, cchAddinFile, FREERDP_SHARED_LIBRARY_PREFIX"%s%s", sprintf_s(pszAddinFile, cchAddinFile, FREERDP_SHARED_LIBRARY_PREFIX"%s%s",
pszFileName, pszExt); pszFileName, pszExt);
cchAddinFile = strlen(pszAddinFile);
} }
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);
CopyMemory(pszFilePath, pszAddinInstallPath, cchAddinInstallPath);
pszFilePath[cchAddinInstallPath] = '\0';
NativePathCchAppendA((LPSTR) pszFilePath, cchFilePath + 1, pszAddinFile);
library = LoadLibraryA(pszFilePath); library = LoadLibraryA(pszFilePath);
free(pszAddinInstallPath);
free(pszAddinFile);
free(pszFilePath);
if (!library) if (!library)
return NULL; goto fail;
entry = (PVIRTUALCHANNELENTRY)GetProcAddress(library, pszEntryName); entry = (PVIRTUALCHANNELENTRY)GetProcAddress(library, pszEntryName);
if (entry) fail:
return entry; free(pszRelativeFilePath);
free(pszAddinFile);
FreeLibrary(library); free(pszFilePath);
free(pszAddinInstallPath);
if (!entry && library)
FreeLibrary(library);
return entry; return entry;
} }