channels: properly handle VirtualChannelEntryEx in static virtual channel loading
authorMarc-André Moreau <marcandre.moreau@gmail.com>
Wed, 16 Nov 2016 14:52:24 +0000 (09:52 -0500)
committerMarc-André Moreau <marcandre.moreau@gmail.com>
Wed, 16 Nov 2016 14:52:24 +0000 (09:52 -0500)
channels/client/CMakeLists.txt
channels/client/addin.c
channels/drdynvc/client/CMakeLists.txt
channels/drdynvc/client/drdynvc_main.c
client/common/cmdline.c
include/freerdp/addin.h
libfreerdp/common/addin.c

index 1b20dfe..f27940e 100644 (file)
@@ -25,7 +25,7 @@ set(${MODULE_PREFIX}_SRCS
        ${CMAKE_CURRENT_SOURCE_DIR}/addin.h)
 
 if(CHANNEL_STATIC_CLIENT_ENTRIES)
-list(REMOVE_DUPLICATES CHANNEL_STATIC_CLIENT_ENTRIES)
+       list(REMOVE_DUPLICATES CHANNEL_STATIC_CLIENT_ENTRIES)
 endif()
 
 foreach(STATIC_ENTRY ${CHANNEL_STATIC_CLIENT_ENTRIES})
@@ -38,6 +38,8 @@ foreach(STATIC_ENTRY ${CHANNEL_STATIC_CLIENT_ENTRIES})
                        set(ENTRY_POINT_NAME "${STATIC_MODULE_CHANNEL}_${${STATIC_MODULE}_CLIENT_ENTRY}")
                        if(${${STATIC_MODULE}_CLIENT_ENTRY} STREQUAL "VirtualChannelEntry")
                                set(ENTRY_POINT_IMPORT "extern BOOL VCAPITYPE ${ENTRY_POINT_NAME}(PCHANNEL_ENTRY_POINTS);")
+                       elseif(${${STATIC_MODULE}_CLIENT_ENTRY} STREQUAL "VirtualChannelEntryEx")
+                               set(ENTRY_POINT_IMPORT "extern BOOL VCAPITYPE ${ENTRY_POINT_NAME}(PCHANNEL_ENTRY_POINTS,PVOID);")
                        else()
                                set(ENTRY_POINT_IMPORT "extern UINT ${ENTRY_POINT_NAME}();")
                        endif()
index a2d6880..ba28e2c 100644 (file)
@@ -349,6 +349,24 @@ void freerdp_channels_addin_list_free(FREERDP_ADDIN** ppAddins)
        free(ppAddins);
 }
 
+extern const STATIC_ENTRY CLIENT_VirtualChannelEntryEx_TABLE[];
+
+BOOL freerdp_channels_is_virtual_channel_entry_ex(LPCSTR pszName)
+{
+       int i;
+       STATIC_ENTRY* entry;
+
+       for (i = 0; CLIENT_VirtualChannelEntryEx_TABLE[i].name != NULL; i++)
+       {
+               entry = (STATIC_ENTRY*) &CLIENT_VirtualChannelEntryEx_TABLE[i];
+
+               if (!strcmp(entry->name, pszName))
+                       return TRUE;
+       }
+
+       return FALSE;
+}
+
 void* freerdp_channels_load_static_addin_entry(LPCSTR pszName, LPSTR pszSubsystem, LPSTR pszType, DWORD dwFlags)
 {
        int i, j;
@@ -380,6 +398,12 @@ void* freerdp_channels_load_static_addin_entry(LPCSTR pszName, LPSTR pszSubsyste
                        }
                        else
                        {
+                               if (dwFlags & FREERDP_ADDIN_CHANNEL_ENTRYEX)
+                               {
+                                       if (!freerdp_channels_is_virtual_channel_entry_ex(pszName))
+                                               return NULL;
+                               }
+                       
                                return (void*) CLIENT_STATIC_ADDIN_TABLE[i].entry;
                        }
                }
index 244d198..abf9185 100644 (file)
@@ -21,7 +21,7 @@ set(${MODULE_PREFIX}_SRCS
        drdynvc_main.c
        drdynvc_main.h)
 
-add_channel_client_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} FALSE "VirtualChannelEntry")
-
+add_channel_client_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} FALSE "VirtualChannelEntryEx")
 
 set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "Channels/${CHANNEL_NAME}/Client")
+
index db31757..c4290f0 100644 (file)
@@ -1422,9 +1422,9 @@ static int drdynvc_get_version(DrdynvcClientContext* context)
 }
 
 /* drdynvc is always built-in */
-#define VirtualChannelEntry    drdynvc_VirtualChannelEntry
+#define VirtualChannelEntryEx  drdynvc_VirtualChannelEntryEx
 
-BOOL VCAPITYPE VirtualChannelEntry(PCHANNEL_ENTRY_POINTS_EX pEntryPoints, PVOID pInitHandle)
+BOOL VCAPITYPE VirtualChannelEntryEx(PCHANNEL_ENTRY_POINTS_EX pEntryPoints, PVOID pInitHandle)
 {
        UINT rc;
        drdynvcPlugin* drdynvc;
index fb5d0c0..3490d37 100644 (file)
@@ -2524,10 +2524,11 @@ static BOOL freerdp_client_load_static_channel_addin(rdpChannels* channels,
        PVIRTUALCHANNELENTRY entry = NULL;
        PVIRTUALCHANNELENTRYEX entryEx = NULL;
 
-       entry = freerdp_load_channel_addin_entry(name, NULL, NULL, FREERDP_ADDIN_CHANNEL_STATIC);
+       entryEx = (PVIRTUALCHANNELENTRYEX) freerdp_load_channel_addin_entry(name, NULL, NULL,
+                                               FREERDP_ADDIN_CHANNEL_STATIC | FREERDP_ADDIN_CHANNEL_ENTRYEX);
 
-       if (!strcmp(name, "drdynvc"))
-               entryEx = (PVIRTUALCHANNELENTRYEX) entry;
+       if (!entryEx)
+               entry = freerdp_load_channel_addin_entry(name, NULL, NULL, FREERDP_ADDIN_CHANNEL_STATIC);
 
        if (entryEx)
        {
index 076e296..d861d86 100644 (file)
@@ -36,6 +36,7 @@
 #define FREERDP_ADDIN_CHANNEL_STATIC           0x00001000
 #define FREERDP_ADDIN_CHANNEL_DYNAMIC          0x00002000
 #define FREERDP_ADDIN_CHANNEL_DEVICE           0x00004000
+#define FREERDP_ADDIN_CHANNEL_ENTRYEX          0x00008000
 
 struct _FREERDP_ADDIN
 {
index d787b07..555c100 100644 (file)
@@ -288,12 +288,13 @@ PVIRTUALCHANNELENTRY freerdp_load_channel_addin_entry(LPCSTR pszName,
        PVIRTUALCHANNELENTRY entry = NULL;
 
        if (freerdp_load_static_channel_addin_entry)
-               entry = freerdp_load_static_channel_addin_entry(pszName, pszSubsystem, pszType,
-                       dwFlags);
+               entry = freerdp_load_static_channel_addin_entry(pszName, pszSubsystem, pszType, dwFlags);
+
+       if (dwFlags & FREERDP_ADDIN_CHANNEL_ENTRYEX)
+               return entry; /* don't warn, don't try dynamic entries for VirtualChannelEntryEx */
 
        if (!entry)
-               entry = freerdp_load_dynamic_channel_addin_entry(pszName, pszSubsystem, pszType,
-                       dwFlags);
+               entry = freerdp_load_dynamic_channel_addin_entry(pszName, pszSubsystem, pszType, dwFlags);
 
        if (!entry)
                WLog_WARN(TAG, "Failed to load channel %s [%s]", pszName, pszSubsystem);