From b3f6dea39055dcd07ae4cb3ebac0325aede712b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Sat, 3 Nov 2012 23:04:04 -0400 Subject: [PATCH] libfreerdp-client: started addin enumerator --- CMakeLists.txt | 3 +- channels/client/CMakeLists.txt | 2 +- channels/client/channels.c | 149 +++++++++++++++++++++++- client/common/test/CMakeLists.txt | 3 +- client/common/test/TestClientChannels.c | 59 ++++++++++ config.h.in | 6 +- include/freerdp/client/channels.h | 21 ++++ winpr/include/winpr/synch.h | 7 +- winpr/libwinpr/file/file.c | 8 +- 9 files changed, 249 insertions(+), 9 deletions(-) create mode 100644 client/common/test/TestClientChannels.c diff --git a/CMakeLists.txt b/CMakeLists.txt index d328ba1ab..777bbfeff 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -294,8 +294,7 @@ else() set(FREERDP_PLUGIN_PATH "${CMAKE_INSTALL_LIBDIR}/freerdp") endif() -set(FREERDP_CLIENT_PLUGIN_PATH "${FREERDP_PLUGIN_PATH}/client") -set(FREERDP_SERVER_PLUGIN_PATH "${FREERDP_PLUGIN_PATH}/server") +set(FREERDP_ADDIN_PATH "${FREERDP_PLUGIN_PATH}") # Path to put extensions set(FREERDP_EXTENSION_PATH "${CMAKE_INSTALL_FULL_LIBDIR}/freerdp/extensions") diff --git a/channels/client/CMakeLists.txt b/channels/client/CMakeLists.txt index 4f8bd6a47..111022928 100644 --- a/channels/client/CMakeLists.txt +++ b/channels/client/CMakeLists.txt @@ -69,7 +69,7 @@ set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS MONOLITHIC ${MONOLITHIC_BUILD} MODULE winpr - MODULES winpr-crt winpr-synch winpr-interlocked) + MODULES winpr-crt winpr-path winpr-file winpr-synch winpr-interlocked) set(${MODULE_PREFIX}_SRCS ${${MODULE_PREFIX}_SRCS} PARENT_SCOPE) set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} PARENT_SCOPE) diff --git a/channels/client/channels.c b/channels/client/channels.c index b5e0a5abf..e01fde3a0 100644 --- a/channels/client/channels.c +++ b/channels/client/channels.c @@ -42,6 +42,8 @@ #include #include +#include +#include #include #include @@ -116,7 +118,7 @@ void* freerdp_channels_client_find_dynamic_entry(const char* name, const char* i char* module; module = freerdp_append_shared_library_suffix((char*) identifier); - path = freerdp_construct_path(FREERDP_CLIENT_PLUGIN_PATH, module); + path = freerdp_construct_path(FREERDP_PLUGIN_PATH, module); entry = freerdp_load_library_symbol(path, module); @@ -140,6 +142,151 @@ void* freerdp_channels_client_find_entry(const char* name, const char* identifie return pChannelEntry; } +LPCSTR gAddinPath = FREERDP_ADDIN_PATH; +LPCSTR gInstallPrefix = FREERDP_INSTALL_PREFIX; + +FREERDP_ADDIN** freerdp_channels_list_client_addins(LPSTR lpName, LPSTR lpSubsystem, LPSTR lpType, DWORD dwFlags) +{ + int index; + int nDashes; + HANDLE hFind; + DWORD nAddins; + LPSTR lpPattern; + size_t cchPattern; + LPCSTR lpExtension; + LPSTR lpSearchPath; + size_t cchSearchPath; + size_t cchAddinPath; + size_t cchInstallPrefix; + FREERDP_ADDIN** ppAddins; + WIN32_FIND_DATAA FindData; + + cchAddinPath = strlen(gAddinPath); + cchInstallPrefix = strlen(gInstallPrefix); + + lpExtension = PathGetSharedLibraryExtensionA(0); + + cchPattern = 128 + strlen(lpExtension) + 2; + lpPattern = (LPSTR) malloc(cchPattern + 1); + + if (lpName && lpSubsystem && lpType) + { + sprintf_s(lpPattern, cchPattern, "%s-client-%s-%s.%s", lpName, lpSubsystem, lpType, lpExtension); + } + else if (lpName && lpType) + { + sprintf_s(lpPattern, cchPattern, "%s-client-?-%s.%s", lpName, lpType, lpExtension); + } + else if (lpName) + { + sprintf_s(lpPattern, cchPattern, "%s-client*.%s", lpName, lpExtension); + } + else + { + sprintf_s(lpPattern, cchPattern, "?-client*.%s", lpExtension); + } + + cchPattern = strlen(lpPattern); + + cchSearchPath = cchInstallPrefix + cchAddinPath + cchPattern + 3; + lpSearchPath = (LPSTR) malloc(cchSearchPath + 1); + + CopyMemory(lpSearchPath, gInstallPrefix, cchInstallPrefix); + lpSearchPath[cchInstallPrefix] = '\0'; + + NativePathCchAppendA(lpSearchPath, cchSearchPath + 1, gAddinPath); + NativePathCchAppendA(lpSearchPath, cchSearchPath + 1, lpPattern); + + cchSearchPath = strlen(lpSearchPath); + + hFind = FindFirstFileA(lpSearchPath, &FindData); + + nAddins = 0; + ppAddins = (FREERDP_ADDIN**) malloc(sizeof(FREERDP_ADDIN*) * 128); + ppAddins[nAddins] = NULL; + + if (hFind == INVALID_HANDLE_VALUE) + return ppAddins; + + do + { + char* p[5]; + nDashes = 0; + FREERDP_ADDIN* pAddin; + + pAddin = (FREERDP_ADDIN*) malloc(sizeof(FREERDP_ADDIN)); + ZeroMemory(pAddin, sizeof(FREERDP_ADDIN)); + + for (index = 0; FindData.cFileName[index]; index++) + nDashes += (FindData.cFileName[index] == '-') ? 1 : 0; + + if (nDashes == 1) + { + /* -client. */ + + p[0] = FindData.cFileName; + p[1] = strchr(p[0], '-') + 1; + + strncpy(pAddin->cName, p[0], p[1] - p[0] - 1); + + pAddin->dwFlags = FREERDP_ADDIN_DYNAMIC; + pAddin->dwFlags |= FREERDP_ADDIN_NAME; + + ppAddins[nAddins++] = pAddin; + } + else if (nDashes == 2) + { + /* -client-. */ + + p[0] = FindData.cFileName; + p[1] = strchr(p[0], '-') + 1; + p[2] = strchr(p[1], '-') + 1; + p[3] = strchr(p[2], '.') + 1; + + strncpy(pAddin->cName, p[0], p[1] - p[0] - 1); + strncpy(pAddin->cSubsystem, p[2], p[3] - p[2] - 1); + + pAddin->dwFlags = FREERDP_ADDIN_DYNAMIC; + pAddin->dwFlags |= FREERDP_ADDIN_NAME; + pAddin->dwFlags |= FREERDP_ADDIN_SUBSYSTEM; + + ppAddins[nAddins++] = pAddin; + } + else if (nDashes == 3) + { + /* -client--. */ + + p[0] = FindData.cFileName; + p[1] = strchr(p[0], '-') + 1; + p[2] = strchr(p[1], '-') + 1; + p[3] = strchr(p[2], '-') + 1; + p[4] = strchr(p[3], '.') + 1; + + strncpy(pAddin->cName, p[0], p[1] - p[0] - 1); + strncpy(pAddin->cSubsystem, p[2], p[3] - p[2] - 1); + strncpy(pAddin->cType, p[3], p[4] - p[3] - 1); + + pAddin->dwFlags = FREERDP_ADDIN_DYNAMIC; + pAddin->dwFlags |= FREERDP_ADDIN_NAME; + pAddin->dwFlags |= FREERDP_ADDIN_SUBSYSTEM; + pAddin->dwFlags |= FREERDP_ADDIN_TYPE; + + ppAddins[nAddins++] = pAddin; + } + else + { + free(pAddin); + } + } + while (FindNextFileA(hFind, &FindData)); + + FindClose(hFind); + + ppAddins[nAddins] = NULL; + + return ppAddins; +} + struct lib_data { PVIRTUALCHANNELENTRY entry; /* the one and only exported function */ diff --git a/client/common/test/CMakeLists.txt b/client/common/test/CMakeLists.txt index dcdeab17e..b68ac11e7 100644 --- a/client/common/test/CMakeLists.txt +++ b/client/common/test/CMakeLists.txt @@ -5,7 +5,8 @@ set(MODULE_PREFIX "TEST_CLIENT") set(${MODULE_PREFIX}_DRIVER ${MODULE_NAME}.c) set(${MODULE_PREFIX}_TESTS - TestClientRdpFile.c) + TestClientRdpFile.c + TestClientChannels.c) create_test_sourcelist(${MODULE_PREFIX}_SRCS ${${MODULE_PREFIX}_DRIVER} diff --git a/client/common/test/TestClientChannels.c b/client/common/test/TestClientChannels.c new file mode 100644 index 000000000..3a6e59d8d --- /dev/null +++ b/client/common/test/TestClientChannels.c @@ -0,0 +1,59 @@ + +#include +#include +#include + +#include + +int TestClientChannels(int argc, char* argv[]) +{ + int index; + FREERDP_ADDIN* pAddin; + FREERDP_ADDIN** ppAddins; + + printf("Enumerate all\n"); + ppAddins = freerdp_channels_list_client_addins(NULL, NULL, NULL, 0); + + for (index = 0; ppAddins[index] != NULL; index++) + { + pAddin = ppAddins[index]; + + printf("Addin: Name: %s Subsystem: %s Type: %s\n", + pAddin->cName, pAddin->cSubsystem, pAddin->cType); + } + + printf("Enumerate rdpsnd\n"); + ppAddins = freerdp_channels_list_client_addins("rdpsnd", NULL, NULL, 0); + + for (index = 0; ppAddins[index] != NULL; index++) + { + pAddin = ppAddins[index]; + + printf("Addin: Name: %s Subsystem: %s Type: %s\n", + pAddin->cName, pAddin->cSubsystem, pAddin->cType); + } + + printf("Enumerate tsmf video\n"); + ppAddins = freerdp_channels_list_client_addins("tsmf", NULL, "video", 0); + + for (index = 0; ppAddins[index] != NULL; index++) + { + pAddin = ppAddins[index]; + + printf("Addin: Name: %s Subsystem: %s Type: %s\n", + pAddin->cName, pAddin->cSubsystem, pAddin->cType); + } + + printf("Enumerate unknown\n"); + ppAddins = freerdp_channels_list_client_addins("unknown", NULL, NULL, 0); + + for (index = 0; ppAddins[index] != NULL; index++) + { + pAddin = ppAddins[index]; + + printf("Addin: Name: %s Subsystem: %s Type: %s\n", + pAddin->cName, pAddin->cSubsystem, pAddin->cType); + } + + return 0; +} diff --git a/config.h.in b/config.h.in index e89aec95c..9ce8dada3 100644 --- a/config.h.in +++ b/config.h.in @@ -11,8 +11,10 @@ #define FREERDP_DATA_PATH "${FREERDP_DATA_PATH}" #define FREERDP_KEYMAP_PATH "${FREERDP_KEYMAP_PATH}" #define FREERDP_PLUGIN_PATH "${FREERDP_PLUGIN_PATH}" -#define FREERDP_CLIENT_PLUGIN_PATH "${FREERDP_CLIENT_PLUGIN_PATH}" -#define FREERDP_SERVER_PLUGIN_PATH "${FREERDP_SERVER_PLUGIN_PATH}" + +#define FREERDP_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}" + +#define FREERDP_ADDIN_PATH "${FREERDP_ADDIN_PATH}" /* Include files */ #cmakedefine HAVE_FCNTL_H diff --git a/include/freerdp/client/channels.h b/include/freerdp/client/channels.h index f2dbc9d20..11aa4443f 100644 --- a/include/freerdp/client/channels.h +++ b/include/freerdp/client/channels.h @@ -23,9 +23,30 @@ #include #include +#define FREERDP_ADDIN_CLIENT 0x00000001 +#define FREERDP_ADDIN_SERVER 0x00000002 + +#define FREERDP_ADDIN_STATIC 0x00000010 +#define FREERDP_ADDIN_DYNAMIC 0x00000020 + +#define FREERDP_ADDIN_NAME 0x00000100 +#define FREERDP_ADDIN_SUBSYSTEM 0x00000200 +#define FREERDP_ADDIN_TYPE 0x00000400 + +struct _FREERDP_ADDIN +{ + DWORD dwFlags; + CHAR cName[16]; + CHAR cType[16]; + CHAR cSubsystem[16]; +}; +typedef struct _FREERDP_ADDIN FREERDP_ADDIN; + FREERDP_API void* freerdp_channels_client_find_static_entry(const char* name, const char* identifier); FREERDP_API void* freerdp_channels_client_find_dynamic_entry(const char* name, const char* identifier); FREERDP_API void* freerdp_channels_client_find_entry(const char* name, const char* identifier); +FREERDP_API FREERDP_ADDIN** freerdp_channels_list_client_addins(LPSTR lpName, LPSTR lpSubsystem, LPSTR lpType, DWORD dwFlags); + #endif /* FREERDP_CHANNELS_CLIENT */ diff --git a/winpr/include/winpr/synch.h b/winpr/include/winpr/synch.h index 5665c52c1..6d9759a8e 100644 --- a/winpr/include/winpr/synch.h +++ b/winpr/include/winpr/synch.h @@ -23,9 +23,10 @@ #include #include #include + #include #include - +#include #include #ifndef _WIN32 @@ -187,7 +188,11 @@ WINPR_API BOOL WaitOnAddress(VOID volatile *Address, PVOID CompareAddress, SIZE_ #define WAIT_OBJECT_0 0x00000000L #define WAIT_ABANDONED 0x00000080L + +#ifndef WAIT_TIMEOUT #define WAIT_TIMEOUT 0x00000102L +#endif + #define WAIT_FAILED ((DWORD) 0xFFFFFFFF) WINPR_API DWORD WaitForSingleObject(HANDLE hHandle, DWORD dwMilliseconds); diff --git a/winpr/libwinpr/file/file.c b/winpr/libwinpr/file/file.c index 9d60fc48f..2bcf6df0d 100644 --- a/winpr/libwinpr/file/file.c +++ b/winpr/libwinpr/file/file.c @@ -709,7 +709,7 @@ HANDLE FindFirstFileA(LPCSTR lpFileName, LPWIN32_FIND_DATAA lpFindFileData) } } - return NULL; + return INVALID_HANDLE_VALUE; } HANDLE FindFirstFileW(LPCWSTR lpFileName, LPWIN32_FIND_DATAW lpFindFileData) @@ -733,6 +733,12 @@ BOOL FindNextFileA(HANDLE hFindFile, LPWIN32_FIND_DATAA lpFindFileData) { WIN32_FILE_SEARCH* pFileSearch; + if (!hFindFile) + return FALSE; + + if (hFindFile == INVALID_HANDLE_VALUE) + return FALSE; + pFileSearch = (WIN32_FILE_SEARCH*) hFindFile; while ((pFileSearch->pDirent = readdir(pFileSearch->pDir)) != NULL)