Merge pull request #3610 from FreeRDP/mh-channels-new-api

Channels - use new VirtualChannelEx api
This commit is contained in:
akallabeth 2016-11-24 09:42:30 +01:00 committed by GitHub
commit aaae190ee1
21 changed files with 233 additions and 329 deletions

View File

@ -23,7 +23,7 @@ set(${MODULE_PREFIX}_SRCS
cliprdr_main.c cliprdr_main.c
cliprdr_main.h) cliprdr_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(${MODULE_PREFIX}_LIBS freerdp winpr) set(${MODULE_PREFIX}_LIBS freerdp winpr)

View File

@ -34,8 +34,6 @@
#include "cliprdr_main.h" #include "cliprdr_main.h"
#include "cliprdr_format.h" #include "cliprdr_format.h"
static rdpChannelHandles g_ChannelHandles = { NULL, NULL };
static const char* const CB_MSG_TYPE_STRINGS[] = static const char* const CB_MSG_TYPE_STRINGS[] =
{ {
"", "",
@ -108,7 +106,8 @@ static UINT cliprdr_packet_send(cliprdrPlugin* cliprdr, wStream* s)
} }
else else
{ {
status = cliprdr->channelEntryPoints.pVirtualChannelWrite(cliprdr->OpenHandle, status = cliprdr->channelEntryPoints.pVirtualChannelWriteEx(cliprdr->InitHandle,
cliprdr->OpenHandle,
Stream_Buffer(s), (UINT32) Stream_GetPosition(s), s); Stream_Buffer(s), (UINT32) Stream_GetPosition(s), s);
} }
@ -1013,24 +1012,26 @@ static UINT cliprdr_virtual_channel_event_data_received(cliprdrPlugin* cliprdr,
return CHANNEL_RC_OK; return CHANNEL_RC_OK;
} }
static VOID VCAPITYPE cliprdr_virtual_channel_open_event(DWORD openHandle, static VOID VCAPITYPE cliprdr_virtual_channel_open_event_ex(LPVOID lpUserParam, DWORD openHandle,
UINT event, UINT event,
LPVOID pData, UINT32 dataLength, UINT32 totalLength, UINT32 dataFlags) LPVOID pData, UINT32 dataLength, UINT32 totalLength, UINT32 dataFlags)
{ {
UINT error = CHANNEL_RC_OK; UINT error = CHANNEL_RC_OK;
cliprdrPlugin* cliprdr = (cliprdrPlugin*) freerdp_channel_get_open_handle_data(&g_ChannelHandles, openHandle); cliprdrPlugin* cliprdr = (cliprdrPlugin*) lpUserParam;
if (!cliprdr || (cliprdr->OpenHandle != openHandle)) if (!cliprdr || (cliprdr->OpenHandle != openHandle))
{ {
WLog_ERR(TAG, "cliprdr_virtual_channel_open_event: error no match"); WLog_ERR(TAG, "error no match");
return; return;
} }
switch (event) switch (event)
{ {
case CHANNEL_EVENT_DATA_RECEIVED: case CHANNEL_EVENT_DATA_RECEIVED:
error = cliprdr_virtual_channel_event_data_received(cliprdr, pData, dataLength, if ((error = cliprdr_virtual_channel_event_data_received(cliprdr, pData, dataLength,
totalLength, dataFlags); totalLength, dataFlags)))
WLog_ERR(TAG, "failed with error %lu", error);
break; break;
case CHANNEL_EVENT_WRITE_COMPLETE: case CHANNEL_EVENT_WRITE_COMPLETE:
@ -1043,7 +1044,7 @@ static VOID VCAPITYPE cliprdr_virtual_channel_open_event(DWORD openHandle,
if (error && cliprdr->context->rdpcontext) if (error && cliprdr->context->rdpcontext)
setChannelError(cliprdr->context->rdpcontext, error, setChannelError(cliprdr->context->rdpcontext, error,
"cliprdr_virtual_channel_open_event reported an error"); "cliprdr_virtual_channel_open_event_ex reported an error");
} }
static void* cliprdr_virtual_channel_client_thread(void* arg) static void* cliprdr_virtual_channel_client_thread(void* arg)
@ -1101,9 +1102,9 @@ static UINT cliprdr_virtual_channel_event_connected(cliprdrPlugin* cliprdr,
LPVOID pData, UINT32 dataLength) LPVOID pData, UINT32 dataLength)
{ {
UINT32 status; UINT32 status;
status = cliprdr->channelEntryPoints.pVirtualChannelOpen(cliprdr->InitHandle, status = cliprdr->channelEntryPoints.pVirtualChannelOpenEx(cliprdr->InitHandle,
&cliprdr->OpenHandle, cliprdr->channelDef.name, &cliprdr->OpenHandle, cliprdr->channelDef.name,
cliprdr_virtual_channel_open_event); cliprdr_virtual_channel_open_event_ex);
if (status != CHANNEL_RC_OK) if (status != CHANNEL_RC_OK)
{ {
@ -1112,8 +1113,6 @@ static UINT cliprdr_virtual_channel_event_connected(cliprdrPlugin* cliprdr,
return status; return status;
} }
freerdp_channel_add_open_handle_data(&g_ChannelHandles, cliprdr->OpenHandle, (void*) cliprdr);
cliprdr->queue = MessageQueue_New(NULL); cliprdr->queue = MessageQueue_New(NULL);
if (!cliprdr->queue) if (!cliprdr->queue)
@ -1154,7 +1153,7 @@ static UINT cliprdr_virtual_channel_event_disconnected(cliprdrPlugin* cliprdr)
MessageQueue_Free(cliprdr->queue); MessageQueue_Free(cliprdr->queue);
CloseHandle(cliprdr->thread); CloseHandle(cliprdr->thread);
rc = cliprdr->channelEntryPoints.pVirtualChannelClose(cliprdr->OpenHandle); rc = cliprdr->channelEntryPoints.pVirtualChannelCloseEx(cliprdr->InitHandle, cliprdr->OpenHandle);
if (CHANNEL_RC_OK != rc) if (CHANNEL_RC_OK != rc)
{ {
@ -1171,8 +1170,6 @@ static UINT cliprdr_virtual_channel_event_disconnected(cliprdrPlugin* cliprdr)
cliprdr->data_in = NULL; cliprdr->data_in = NULL;
} }
freerdp_channel_remove_open_handle_data(&g_ChannelHandles, cliprdr->OpenHandle);
return CHANNEL_RC_OK; return CHANNEL_RC_OK;
} }
@ -1183,17 +1180,16 @@ static UINT cliprdr_virtual_channel_event_disconnected(cliprdrPlugin* cliprdr)
*/ */
static UINT cliprdr_virtual_channel_event_terminated(cliprdrPlugin* cliprdr) static UINT cliprdr_virtual_channel_event_terminated(cliprdrPlugin* cliprdr)
{ {
freerdp_channel_remove_init_handle_data(&g_ChannelHandles, (void*) cliprdr); cliprdr->InitHandle = 0;
free(cliprdr); free(cliprdr);
return CHANNEL_RC_OK; return CHANNEL_RC_OK;
} }
static VOID VCAPITYPE cliprdr_virtual_channel_init_event(LPVOID pInitHandle, static VOID VCAPITYPE cliprdr_virtual_channel_init_event_ex(LPVOID lpUserParam, LPVOID pInitHandle,
UINT event, LPVOID pData, UINT event, LPVOID pData, UINT dataLength)
UINT dataLength)
{ {
UINT error = CHANNEL_RC_OK; UINT error = CHANNEL_RC_OK;
cliprdrPlugin* cliprdr = (cliprdrPlugin*) freerdp_channel_get_init_handle_data(&g_ChannelHandles, pInitHandle); cliprdrPlugin* cliprdr = (cliprdrPlugin*) lpUserParam;
if (!cliprdr || (cliprdr->InitHandle != pInitHandle)) if (!cliprdr || (cliprdr->InitHandle != pInitHandle))
{ {
@ -1232,14 +1228,14 @@ static VOID VCAPITYPE cliprdr_virtual_channel_init_event(LPVOID pInitHandle,
} }
/* cliprdr is always built-in */ /* cliprdr is always built-in */
#define VirtualChannelEntry cliprdr_VirtualChannelEntry #define VirtualChannelEntryEx cliprdr_VirtualChannelEntryEx
BOOL VCAPITYPE VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints) BOOL VCAPITYPE VirtualChannelEntryEx(PCHANNEL_ENTRY_POINTS pEntryPoints, PVOID pInitHandle)
{ {
UINT rc; UINT rc;
cliprdrPlugin* cliprdr; cliprdrPlugin* cliprdr;
CliprdrClientContext* context = NULL; CliprdrClientContext* context = NULL;
CHANNEL_ENTRY_POINTS_FREERDP* pEntryPointsEx; CHANNEL_ENTRY_POINTS_FREERDP_EX* pEntryPointsEx;
cliprdr = (cliprdrPlugin*) calloc(1, sizeof(cliprdrPlugin)); cliprdr = (cliprdrPlugin*) calloc(1, sizeof(cliprdrPlugin));
if (!cliprdr) if (!cliprdr)
@ -1254,9 +1250,9 @@ BOOL VCAPITYPE VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints)
CHANNEL_OPTION_COMPRESS_RDP | CHANNEL_OPTION_COMPRESS_RDP |
CHANNEL_OPTION_SHOW_PROTOCOL; CHANNEL_OPTION_SHOW_PROTOCOL;
strcpy(cliprdr->channelDef.name, "cliprdr"); strcpy(cliprdr->channelDef.name, "cliprdr");
pEntryPointsEx = (CHANNEL_ENTRY_POINTS_FREERDP*) pEntryPoints; pEntryPointsEx = (CHANNEL_ENTRY_POINTS_FREERDP_EX*) pEntryPoints;
if ((pEntryPointsEx->cbSize >= sizeof(CHANNEL_ENTRY_POINTS_FREERDP)) && if ((pEntryPointsEx->cbSize >= sizeof(CHANNEL_ENTRY_POINTS_FREERDP_EX)) &&
(pEntryPointsEx->MagicNumber == FREERDP_CHANNEL_MAGIC_NUMBER)) (pEntryPointsEx->MagicNumber == FREERDP_CHANNEL_MAGIC_NUMBER))
{ {
context = (CliprdrClientContext*) calloc(1, sizeof(CliprdrClientContext)); context = (CliprdrClientContext*) calloc(1, sizeof(CliprdrClientContext));
@ -1280,7 +1276,6 @@ BOOL VCAPITYPE VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints)
context->ClientFormatDataResponse = cliprdr_client_format_data_response; context->ClientFormatDataResponse = cliprdr_client_format_data_response;
context->ClientFileContentsRequest = cliprdr_client_file_contents_request; context->ClientFileContentsRequest = cliprdr_client_file_contents_request;
context->ClientFileContentsResponse = cliprdr_client_file_contents_response; context->ClientFileContentsResponse = cliprdr_client_file_contents_response;
*(pEntryPointsEx->ppInterface) = (void*) context;
cliprdr->context = context; cliprdr->context = context;
context->rdpcontext = pEntryPointsEx->context; context->rdpcontext = pEntryPointsEx->context;
} }
@ -1290,32 +1285,23 @@ BOOL VCAPITYPE VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints)
cliprdr->streamFileClipEnabled = FALSE; cliprdr->streamFileClipEnabled = FALSE;
cliprdr->fileClipNoFilePaths = TRUE; cliprdr->fileClipNoFilePaths = TRUE;
cliprdr->canLockClipData = FALSE; cliprdr->canLockClipData = FALSE;
WLog_Print(cliprdr->log, WLOG_DEBUG, "VirtualChannelEntry"); WLog_Print(cliprdr->log, WLOG_DEBUG, "VirtualChannelEntryEx");
CopyMemory(&(cliprdr->channelEntryPoints), pEntryPoints, CopyMemory(&(cliprdr->channelEntryPoints), pEntryPoints,
sizeof(CHANNEL_ENTRY_POINTS_FREERDP)); sizeof(CHANNEL_ENTRY_POINTS_FREERDP_EX));
rc = cliprdr->channelEntryPoints.pVirtualChannelInit(&cliprdr->InitHandle, cliprdr->InitHandle = pInitHandle;
rc = cliprdr->channelEntryPoints.pVirtualChannelInitEx(cliprdr, context, pInitHandle,
&cliprdr->channelDef, 1, VIRTUAL_CHANNEL_VERSION_WIN2000, &cliprdr->channelDef, 1, VIRTUAL_CHANNEL_VERSION_WIN2000,
cliprdr_virtual_channel_init_event); cliprdr_virtual_channel_init_event_ex);
if (CHANNEL_RC_OK != rc) if (CHANNEL_RC_OK != rc)
{ {
WLog_ERR(TAG, "pVirtualChannelInit failed with %s [%08X]", WLog_ERR(TAG, "pVirtualChannelInit failed with %s [%08X]",
WTSErrorToString(rc), rc); WTSErrorToString(rc), rc);
if (context)
*(pEntryPointsEx->ppInterface) = NULL;
free(cliprdr->context); free(cliprdr->context);
free(cliprdr); free(cliprdr);
return FALSE; return FALSE;
} }
cliprdr->channelEntryPoints.pInterface = * cliprdr->channelEntryPoints.pInterface = context;
(cliprdr->channelEntryPoints.ppInterface);
cliprdr->channelEntryPoints.ppInterface = &
(cliprdr->channelEntryPoints.pInterface);
freerdp_channel_add_init_handle_data(&g_ChannelHandles, cliprdr->InitHandle, (void*) cliprdr);
return TRUE; return TRUE;
} }

View File

@ -33,7 +33,7 @@
struct cliprdr_plugin struct cliprdr_plugin
{ {
CHANNEL_DEF channelDef; CHANNEL_DEF channelDef;
CHANNEL_ENTRY_POINTS_FREERDP channelEntryPoints; CHANNEL_ENTRY_POINTS_FREERDP_EX channelEntryPoints;
CliprdrClientContext* context; CliprdrClientContext* context;

View File

@ -701,13 +701,13 @@ static UINT drdynvc_send(drdynvcPlugin* drdynvc, wStream* s)
else else
{ {
status = drdynvc->channelEntryPoints.pVirtualChannelWriteEx(drdynvc->InitHandle, status = drdynvc->channelEntryPoints.pVirtualChannelWriteEx(drdynvc->InitHandle,
drdynvc->OpenHandle, Stream_Buffer(s), (UINT32) Stream_GetPosition(s), s); drdynvc->OpenHandle, Stream_Buffer(s), (UINT32) Stream_GetPosition(s), s);
} }
if (status != CHANNEL_RC_OK) if (status != CHANNEL_RC_OK)
{ {
Stream_Free(s, TRUE); Stream_Free(s, TRUE);
WLog_ERR(TAG, "VirtualChannelWrite failed with %s [%08X]", WTSErrorToString(status), status); WLog_ERR(TAG, "VirtualChannelWriteEx failed with %s [%08X]", WTSErrorToString(status), status);
} }
return status; return status;
@ -799,7 +799,7 @@ static UINT drdynvc_write_data(drdynvcPlugin* drdynvc, UINT32 ChannelId,
if (status != CHANNEL_RC_OK) if (status != CHANNEL_RC_OK)
{ {
WLog_ERR(TAG, "VirtualChannelWrite failed with %s [%08X]", WLog_ERR(TAG, "VirtualChannelWriteEx failed with %s [%08X]",
WTSErrorToString(status), status); WTSErrorToString(status), status);
return status; return status;
} }
@ -832,7 +832,7 @@ static UINT drdynvc_send_capability_response(drdynvcPlugin* drdynvc)
if (status != CHANNEL_RC_OK) if (status != CHANNEL_RC_OK)
{ {
WLog_ERR(TAG, "VirtualChannelWrite failed with %s [%08X]", WLog_ERR(TAG, "VirtualChannelWriteEx failed with %s [%08X]",
WTSErrorToString(status), status); WTSErrorToString(status), status);
} }
@ -956,7 +956,7 @@ static UINT drdynvc_process_create_request(drdynvcPlugin* drdynvc, int Sp,
if (status != CHANNEL_RC_OK) if (status != CHANNEL_RC_OK)
{ {
WLog_ERR(TAG, "VirtualChannelWrite failed with %s [%08X]", WLog_ERR(TAG, "VirtualChannelWriteEx failed with %s [%08X]",
WTSErrorToString(status), status); WTSErrorToString(status), status);
return status; return status;
} }
@ -1053,7 +1053,7 @@ static UINT drdynvc_process_close_request(drdynvcPlugin* drdynvc, int Sp,
error = drdynvc_send(drdynvc, data_out); error = drdynvc_send(drdynvc, data_out);
if (error) if (error)
WLog_ERR(TAG, "VirtualChannelWrite failed with %s [%08X]", WLog_ERR(TAG, "VirtualChannelWriteEx failed with %s [%08X]",
WTSErrorToString(error), error); WTSErrorToString(error), error);
return error; return error;
@ -1182,8 +1182,10 @@ static void VCAPITYPE drdynvc_virtual_channel_open_event_ex(LPVOID lpUserParam,
switch (event) switch (event)
{ {
case CHANNEL_EVENT_DATA_RECEIVED: case CHANNEL_EVENT_DATA_RECEIVED:
if ((error = drdynvc_virtual_channel_event_data_received(drdynvc, pData, dataLength, totalLength, dataFlags))) if ((error = drdynvc_virtual_channel_event_data_received(drdynvc, pData, dataLength, totalLength,
dataFlags)))
WLog_ERR(TAG, "drdynvc_virtual_channel_event_data_received failed with error %lu", error); WLog_ERR(TAG, "drdynvc_virtual_channel_event_data_received failed with error %lu", error);
break; break;
case CHANNEL_EVENT_WRITE_COMPLETE: case CHANNEL_EVENT_WRITE_COMPLETE:
@ -1240,7 +1242,8 @@ static void* drdynvc_virtual_channel_client_thread(void* arg)
} }
if (error && drdynvc->rdpcontext) if (error && drdynvc->rdpcontext)
setChannelError(drdynvc->rdpcontext, error, "drdynvc_virtual_channel_client_thread reported an error"); setChannelError(drdynvc->rdpcontext, error,
"drdynvc_virtual_channel_client_thread reported an error");
ExitThread((DWORD) error); ExitThread((DWORD) error);
return NULL; return NULL;
@ -1251,14 +1254,14 @@ static void* drdynvc_virtual_channel_client_thread(void* arg)
* *
* @return 0 on success, otherwise a Win32 error code * @return 0 on success, otherwise a Win32 error code
*/ */
static UINT drdynvc_virtual_channel_event_connected(drdynvcPlugin* drdynvc, LPVOID pData, UINT32 dataLength) static UINT drdynvc_virtual_channel_event_connected(drdynvcPlugin* drdynvc, LPVOID pData,
UINT32 dataLength)
{ {
UINT error; UINT error;
UINT32 status; UINT32 status;
UINT32 index; UINT32 index;
ADDIN_ARGV* args; ADDIN_ARGV* args;
rdpSettings* settings; rdpSettings* settings;
status = drdynvc->channelEntryPoints.pVirtualChannelOpenEx(drdynvc->InitHandle, status = drdynvc->channelEntryPoints.pVirtualChannelOpenEx(drdynvc->InitHandle,
&drdynvc->OpenHandle, drdynvc->channelDef.name, drdynvc_virtual_channel_open_event_ex); &drdynvc->OpenHandle, drdynvc->channelDef.name, drdynvc_virtual_channel_open_event_ex);
@ -1329,7 +1332,7 @@ static UINT drdynvc_virtual_channel_event_disconnected(drdynvcPlugin* drdynvc)
UINT status; UINT status;
if (MessageQueue_PostQuit(drdynvc->queue, 0) && if (MessageQueue_PostQuit(drdynvc->queue, 0) &&
(WaitForSingleObject(drdynvc->thread, INFINITE) == WAIT_FAILED)) (WaitForSingleObject(drdynvc->thread, INFINITE) == WAIT_FAILED))
{ {
status = GetLastError(); status = GetLastError();
WLog_ERR(TAG, "WaitForSingleObject failed with error %lu", status); WLog_ERR(TAG, "WaitForSingleObject failed with error %lu", status);
@ -1340,8 +1343,8 @@ static UINT drdynvc_virtual_channel_event_disconnected(drdynvcPlugin* drdynvc)
CloseHandle(drdynvc->thread); CloseHandle(drdynvc->thread);
drdynvc->queue = NULL; drdynvc->queue = NULL;
drdynvc->thread = NULL; drdynvc->thread = NULL;
status = drdynvc->channelEntryPoints.pVirtualChannelCloseEx(drdynvc->InitHandle,
status = drdynvc->channelEntryPoints.pVirtualChannelCloseEx(drdynvc->InitHandle, drdynvc->OpenHandle); drdynvc->OpenHandle);
if (status != CHANNEL_RC_OK) if (status != CHANNEL_RC_OK)
{ {
@ -1378,7 +1381,8 @@ static UINT drdynvc_virtual_channel_event_terminated(drdynvcPlugin* drdynvc)
return CHANNEL_RC_OK; return CHANNEL_RC_OK;
} }
static VOID VCAPITYPE drdynvc_virtual_channel_init_event_ex(LPVOID lpUserParam, LPVOID pInitHandle, UINT event, LPVOID pData, UINT dataLength) static VOID VCAPITYPE drdynvc_virtual_channel_init_event_ex(LPVOID lpUserParam, LPVOID pInitHandle,
UINT event, LPVOID pData, UINT dataLength)
{ {
UINT error = CHANNEL_RC_OK; UINT error = CHANNEL_RC_OK;
drdynvcPlugin* drdynvc = (drdynvcPlugin*) lpUserParam; drdynvcPlugin* drdynvc = (drdynvcPlugin*) lpUserParam;
@ -1394,21 +1398,25 @@ static VOID VCAPITYPE drdynvc_virtual_channel_init_event_ex(LPVOID lpUserParam,
case CHANNEL_EVENT_CONNECTED: case CHANNEL_EVENT_CONNECTED:
if ((error = drdynvc_virtual_channel_event_connected(drdynvc, pData, dataLength))) if ((error = drdynvc_virtual_channel_event_connected(drdynvc, pData, dataLength)))
WLog_ERR(TAG, "drdynvc_virtual_channel_event_connected failed with error %lu", error); WLog_ERR(TAG, "drdynvc_virtual_channel_event_connected failed with error %lu", error);
break; break;
case CHANNEL_EVENT_DISCONNECTED: case CHANNEL_EVENT_DISCONNECTED:
if ((error = drdynvc_virtual_channel_event_disconnected(drdynvc))) if ((error = drdynvc_virtual_channel_event_disconnected(drdynvc)))
WLog_ERR(TAG, "drdynvc_virtual_channel_event_disconnected failed with error %lu", error); WLog_ERR(TAG, "drdynvc_virtual_channel_event_disconnected failed with error %lu", error);
break; break;
case CHANNEL_EVENT_TERMINATED: case CHANNEL_EVENT_TERMINATED:
if ((error = drdynvc_virtual_channel_event_terminated(drdynvc))) if ((error = drdynvc_virtual_channel_event_terminated(drdynvc)))
WLog_ERR(TAG, "drdynvc_virtual_channel_event_terminated failed with error %lu", error); WLog_ERR(TAG, "drdynvc_virtual_channel_event_terminated failed with error %lu", error);
break; break;
} }
if (error && drdynvc->rdpcontext) if (error && drdynvc->rdpcontext)
setChannelError(drdynvc->rdpcontext, error, "drdynvc_virtual_channel_init_event_ex reported an error"); setChannelError(drdynvc->rdpcontext, error,
"drdynvc_virtual_channel_init_event_ex reported an error");
} }
/** /**
@ -1439,13 +1447,11 @@ BOOL VCAPITYPE VirtualChannelEntryEx(PCHANNEL_ENTRY_POINTS_EX pEntryPoints, PVOI
} }
drdynvc->channelDef.options = drdynvc->channelDef.options =
CHANNEL_OPTION_INITIALIZED | CHANNEL_OPTION_INITIALIZED |
CHANNEL_OPTION_ENCRYPT_RDP | CHANNEL_OPTION_ENCRYPT_RDP |
CHANNEL_OPTION_COMPRESS_RDP; CHANNEL_OPTION_COMPRESS_RDP;
strcpy(drdynvc->channelDef.name, "drdynvc"); strcpy(drdynvc->channelDef.name, "drdynvc");
drdynvc->state = DRDYNVC_STATE_INITIAL; drdynvc->state = DRDYNVC_STATE_INITIAL;
pEntryPointsEx = (CHANNEL_ENTRY_POINTS_FREERDP_EX*) pEntryPoints; pEntryPointsEx = (CHANNEL_ENTRY_POINTS_FREERDP_EX*) pEntryPoints;
if ((pEntryPointsEx->cbSize >= sizeof(CHANNEL_ENTRY_POINTS_FREERDP_EX)) && if ((pEntryPointsEx->cbSize >= sizeof(CHANNEL_ENTRY_POINTS_FREERDP_EX)) &&
@ -1465,37 +1471,25 @@ BOOL VCAPITYPE VirtualChannelEntryEx(PCHANNEL_ENTRY_POINTS_EX pEntryPoints, PVOI
drdynvc->context = context; drdynvc->context = context;
context->GetVersion = drdynvc_get_version; context->GetVersion = drdynvc_get_version;
drdynvc->rdpcontext = pEntryPointsEx->context; drdynvc->rdpcontext = pEntryPointsEx->context;
*(pEntryPointsEx->ppInterface) = (void*) context;
} }
drdynvc->log = WLog_Get("com.freerdp.channels.drdynvc.client"); drdynvc->log = WLog_Get("com.freerdp.channels.drdynvc.client");
WLog_Print(drdynvc->log, WLOG_DEBUG, "VirtualChannelEntryEx"); WLog_Print(drdynvc->log, WLOG_DEBUG, "VirtualChannelEntryEx");
CopyMemory(&(drdynvc->channelEntryPoints), pEntryPoints, sizeof(CHANNEL_ENTRY_POINTS_FREERDP_EX)); CopyMemory(&(drdynvc->channelEntryPoints), pEntryPoints, sizeof(CHANNEL_ENTRY_POINTS_FREERDP_EX));
drdynvc->InitHandle = pInitHandle; drdynvc->InitHandle = pInitHandle;
rc = drdynvc->channelEntryPoints.pVirtualChannelInitEx(drdynvc, context, pInitHandle,
rc = drdynvc->channelEntryPoints.pVirtualChannelInitEx((void*) drdynvc, pInitHandle, &drdynvc->channelDef, 1, VIRTUAL_CHANNEL_VERSION_WIN2000, drdynvc_virtual_channel_init_event_ex);
&drdynvc->channelDef, 1, VIRTUAL_CHANNEL_VERSION_WIN2000, drdynvc_virtual_channel_init_event_ex);
if (CHANNEL_RC_OK != rc) if (CHANNEL_RC_OK != rc)
{ {
WLog_ERR(TAG, "pVirtualChannelInit failed with %s [%08X]", WLog_ERR(TAG, "pVirtualChannelInit failed with %s [%08X]",
WTSErrorToString(rc), rc); WTSErrorToString(rc), rc);
if (context)
*(pEntryPointsEx->ppInterface) = NULL;
free(drdynvc->context); free(drdynvc->context);
free(drdynvc); free(drdynvc);
return FALSE; return FALSE;
} }
drdynvc->channelEntryPoints.pInterface = * drdynvc->channelEntryPoints.pInterface = context;
(drdynvc->channelEntryPoints.ppInterface);
drdynvc->channelEntryPoints.ppInterface = &
(drdynvc->channelEntryPoints.pInterface);
return TRUE; return TRUE;
} }

View File

@ -23,7 +23,7 @@ set(${MODULE_PREFIX}_SRCS
encomsp_main.c encomsp_main.c
encomsp_main.h) encomsp_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") set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "Channels/${CHANNEL_NAME}/Client")

View File

@ -31,8 +31,6 @@
#include "encomsp_main.h" #include "encomsp_main.h"
static rdpChannelHandles g_ChannelHandles = { NULL, NULL };
/** /**
* Function description * Function description
* *
@ -120,11 +118,12 @@ static UINT encomsp_virtual_channel_write(encomspPlugin* encomsp, wStream* s)
WLog_INFO(TAG, "EncomspWrite (%d)", Stream_Length(s)); WLog_INFO(TAG, "EncomspWrite (%d)", Stream_Length(s));
winpr_HexDump(Stream_Buffer(s), Stream_Length(s)); winpr_HexDump(Stream_Buffer(s), Stream_Length(s));
#endif #endif
status = encomsp->channelEntryPoints.pVirtualChannelWrite(encomsp->OpenHandle, status = encomsp->channelEntryPoints.pVirtualChannelWriteEx(encomsp->InitHandle,
encomsp->OpenHandle,
Stream_Buffer(s), (UINT32) Stream_Length(s), s); Stream_Buffer(s), (UINT32) Stream_Length(s), s);
if (status != CHANNEL_RC_OK) if (status != CHANNEL_RC_OK)
WLog_ERR(TAG, "VirtualChannelWrite failed with %s [%08X]", WLog_ERR(TAG, "VirtualChannelWriteEx failed with %s [%08X]",
WTSErrorToString(status), status); WTSErrorToString(status), status);
return status; return status;
@ -928,14 +927,14 @@ static int encomsp_send(encomspPlugin* encomsp, wStream* s)
} }
else else
{ {
status = plugin->channelEntryPoints.pVirtualChannelWrite(plugin->OpenHandle, status = plugin->channelEntryPoints.pVirtualChannelWriteEx(plugin->InitHandle, plugin->OpenHandle,
Stream_Buffer(s), (UINT32) Stream_GetPosition(s), s); Stream_Buffer(s), (UINT32) Stream_GetPosition(s), s);
} }
if (status != CHANNEL_RC_OK) if (status != CHANNEL_RC_OK)
{ {
Stream_Free(s, TRUE); Stream_Free(s, TRUE);
WLog_ERR(TAG, "VirtualChannelWrite failed with %s [%08X]", WLog_ERR(TAG, "VirtualChannelWriteEx failed with %s [%08X]",
WTSErrorToString(status), status); WTSErrorToString(status), status);
} }
@ -1001,16 +1000,16 @@ static UINT encomsp_virtual_channel_event_data_received(encomspPlugin* encomsp,
return CHANNEL_RC_OK; return CHANNEL_RC_OK;
} }
static VOID VCAPITYPE encomsp_virtual_channel_open_event(DWORD openHandle, static VOID VCAPITYPE encomsp_virtual_channel_open_event_ex(LPVOID lpUserParam, DWORD openHandle,
UINT event, UINT event,
LPVOID pData, UINT32 dataLength, UINT32 totalLength, UINT32 dataFlags) LPVOID pData, UINT32 dataLength, UINT32 totalLength, UINT32 dataFlags)
{ {
UINT error = CHANNEL_RC_OK; UINT error = CHANNEL_RC_OK;
encomspPlugin* encomsp = (encomspPlugin*) freerdp_channel_get_open_handle_data(&g_ChannelHandles, openHandle); encomspPlugin* encomsp = (encomspPlugin*) lpUserParam;
if (!encomsp || (encomsp->OpenHandle != openHandle)) if (!encomsp || (encomsp->OpenHandle != openHandle))
{ {
WLog_ERR(TAG, "encomsp_virtual_channel_open_event: error no match"); WLog_ERR(TAG, "error no match");
return; return;
} }
@ -1033,8 +1032,7 @@ static VOID VCAPITYPE encomsp_virtual_channel_open_event(DWORD openHandle,
} }
if (error && encomsp->rdpcontext) if (error && encomsp->rdpcontext)
setChannelError(encomsp->rdpcontext, error, setChannelError(encomsp->rdpcontext, error, "encomsp_virtual_channel_open_event reported an error");
"encomsp_virtual_channel_open_event reported an error");
return; return;
} }
@ -1045,7 +1043,6 @@ static void* encomsp_virtual_channel_client_thread(void* arg)
wMessage message; wMessage message;
encomspPlugin* encomsp = (encomspPlugin*) arg; encomspPlugin* encomsp = (encomspPlugin*) arg;
UINT error = CHANNEL_RC_OK; UINT error = CHANNEL_RC_OK;
encomsp_process_connect(encomsp); encomsp_process_connect(encomsp);
while (1) while (1)
@ -1096,9 +1093,9 @@ static UINT encomsp_virtual_channel_event_connected(encomspPlugin* encomsp,
LPVOID pData, UINT32 dataLength) LPVOID pData, UINT32 dataLength)
{ {
UINT32 status; UINT32 status;
status = encomsp->channelEntryPoints.pVirtualChannelOpen(encomsp->InitHandle, status = encomsp->channelEntryPoints.pVirtualChannelOpenEx(encomsp->InitHandle,
&encomsp->OpenHandle, encomsp->channelDef.name, &encomsp->OpenHandle, encomsp->channelDef.name,
encomsp_virtual_channel_open_event); encomsp_virtual_channel_open_event_ex);
if (status != CHANNEL_RC_OK) if (status != CHANNEL_RC_OK)
{ {
@ -1107,8 +1104,6 @@ static UINT encomsp_virtual_channel_event_connected(encomspPlugin* encomsp,
return status; return status;
} }
freerdp_channel_add_open_handle_data(&g_ChannelHandles, encomsp->OpenHandle, (void*) encomsp);
encomsp->queue = MessageQueue_New(NULL); encomsp->queue = MessageQueue_New(NULL);
if (!encomsp->queue) if (!encomsp->queue)
@ -1150,7 +1145,7 @@ static UINT encomsp_virtual_channel_event_disconnected(encomspPlugin* encomsp)
CloseHandle(encomsp->thread); CloseHandle(encomsp->thread);
encomsp->queue = NULL; encomsp->queue = NULL;
encomsp->thread = NULL; encomsp->thread = NULL;
rc = encomsp->channelEntryPoints.pVirtualChannelClose(encomsp->OpenHandle); rc = encomsp->channelEntryPoints.pVirtualChannelCloseEx(encomsp->InitHandle, encomsp->OpenHandle);
if (CHANNEL_RC_OK != rc) if (CHANNEL_RC_OK != rc)
{ {
@ -1167,8 +1162,6 @@ static UINT encomsp_virtual_channel_event_disconnected(encomspPlugin* encomsp)
encomsp->data_in = NULL; encomsp->data_in = NULL;
} }
freerdp_channel_remove_open_handle_data(&g_ChannelHandles, encomsp->OpenHandle);
return CHANNEL_RC_OK; return CHANNEL_RC_OK;
} }
@ -1180,22 +1173,20 @@ static UINT encomsp_virtual_channel_event_disconnected(encomspPlugin* encomsp)
*/ */
static UINT encomsp_virtual_channel_event_terminated(encomspPlugin* encomsp) static UINT encomsp_virtual_channel_event_terminated(encomspPlugin* encomsp)
{ {
freerdp_channel_remove_init_handle_data(&g_ChannelHandles, (void*) encomsp);
encomsp->InitHandle = 0; encomsp->InitHandle = 0;
free(encomsp); free(encomsp);
return CHANNEL_RC_OK; return CHANNEL_RC_OK;
} }
static VOID VCAPITYPE encomsp_virtual_channel_init_event(LPVOID pInitHandle, static VOID VCAPITYPE encomsp_virtual_channel_init_event_ex(LPVOID lpUserParam, LPVOID pInitHandle,
UINT event, LPVOID pData, UINT event, LPVOID pData, UINT dataLength)
UINT dataLength)
{ {
UINT error = CHANNEL_RC_OK; UINT error = CHANNEL_RC_OK;
encomspPlugin* encomsp = (encomspPlugin*) freerdp_channel_get_init_handle_data(&g_ChannelHandles, pInitHandle); encomspPlugin* encomsp = (encomspPlugin*) lpUserParam;
if (!encomsp || (encomsp->InitHandle != pInitHandle)) if (!encomsp || (encomsp->InitHandle != pInitHandle))
{ {
WLog_ERR(TAG, "encomsp_virtual_channel_init_event: error no match"); WLog_ERR(TAG, "error no match");
return; return;
} }
@ -1225,19 +1216,18 @@ static VOID VCAPITYPE encomsp_virtual_channel_init_event(LPVOID pInitHandle,
} }
if (error && encomsp->rdpcontext) if (error && encomsp->rdpcontext)
setChannelError(encomsp->rdpcontext, error, setChannelError(encomsp->rdpcontext, error, "encomsp_virtual_channel_init_event reported an error");
"encomsp_virtual_channel_init_event reported an error");
} }
/* encomsp is always built-in */ /* encomsp is always built-in */
#define VirtualChannelEntry encomsp_VirtualChannelEntry #define VirtualChannelEntryEx encomsp_VirtualChannelEntryEx
BOOL VCAPITYPE VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints) BOOL VCAPITYPE VirtualChannelEntryEx(PCHANNEL_ENTRY_POINTS_EX pEntryPoints, PVOID pInitHandle)
{ {
UINT rc; UINT rc;
encomspPlugin* encomsp; encomspPlugin* encomsp;
EncomspClientContext* context = NULL; EncomspClientContext* context = NULL;
CHANNEL_ENTRY_POINTS_FREERDP* pEntryPointsEx; CHANNEL_ENTRY_POINTS_FREERDP_EX* pEntryPointsEx;
BOOL isFreerdp = FALSE; BOOL isFreerdp = FALSE;
encomsp = (encomspPlugin*) calloc(1, sizeof(encomspPlugin)); encomsp = (encomspPlugin*) calloc(1, sizeof(encomspPlugin));
@ -1253,9 +1243,9 @@ BOOL VCAPITYPE VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints)
CHANNEL_OPTION_COMPRESS_RDP | CHANNEL_OPTION_COMPRESS_RDP |
CHANNEL_OPTION_SHOW_PROTOCOL; CHANNEL_OPTION_SHOW_PROTOCOL;
strcpy(encomsp->channelDef.name, "encomsp"); strcpy(encomsp->channelDef.name, "encomsp");
pEntryPointsEx = (CHANNEL_ENTRY_POINTS_FREERDP*) pEntryPoints; pEntryPointsEx = (CHANNEL_ENTRY_POINTS_FREERDP_EX*) pEntryPoints;
if ((pEntryPointsEx->cbSize >= sizeof(CHANNEL_ENTRY_POINTS_FREERDP)) && if ((pEntryPointsEx->cbSize >= sizeof(CHANNEL_ENTRY_POINTS_FREERDP_EX)) &&
(pEntryPointsEx->MagicNumber == FREERDP_CHANNEL_MAGIC_NUMBER)) (pEntryPointsEx->MagicNumber == FREERDP_CHANNEL_MAGIC_NUMBER))
{ {
context = (EncomspClientContext*) calloc(1, sizeof(EncomspClientContext)); context = (EncomspClientContext*) calloc(1, sizeof(EncomspClientContext));
@ -1279,38 +1269,29 @@ BOOL VCAPITYPE VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints)
encomsp_send_change_participant_control_level_pdu; encomsp_send_change_participant_control_level_pdu;
context->GraphicsStreamPaused = NULL; context->GraphicsStreamPaused = NULL;
context->GraphicsStreamResumed = NULL; context->GraphicsStreamResumed = NULL;
*(pEntryPointsEx->ppInterface) = (void*) context;
encomsp->context = context; encomsp->context = context;
encomsp->rdpcontext = pEntryPointsEx->context; encomsp->rdpcontext = pEntryPointsEx->context;
isFreerdp = TRUE; isFreerdp = TRUE;
} }
CopyMemory(&(encomsp->channelEntryPoints), pEntryPoints, CopyMemory(&(encomsp->channelEntryPoints), pEntryPoints,
sizeof(CHANNEL_ENTRY_POINTS_FREERDP)); sizeof(CHANNEL_ENTRY_POINTS_FREERDP_EX));
rc = encomsp->channelEntryPoints.pVirtualChannelInit(&encomsp->InitHandle, encomsp->InitHandle = pInitHandle;
rc = encomsp->channelEntryPoints.pVirtualChannelInitEx(encomsp, context, pInitHandle,
&encomsp->channelDef, 1, VIRTUAL_CHANNEL_VERSION_WIN2000, &encomsp->channelDef, 1, VIRTUAL_CHANNEL_VERSION_WIN2000,
encomsp_virtual_channel_init_event); encomsp_virtual_channel_init_event_ex);
if (CHANNEL_RC_OK != rc) if (CHANNEL_RC_OK != rc)
{ {
WLog_ERR(TAG, "pVirtualChannelInit failed with %s [%08X]", WLog_ERR(TAG, "failed with %s [%08X]",
WTSErrorToString(rc), rc); WTSErrorToString(rc), rc);
goto error_out; goto error_out;
} }
encomsp->channelEntryPoints.pInterface = * encomsp->channelEntryPoints.pInterface = context;
(encomsp->channelEntryPoints.ppInterface);
encomsp->channelEntryPoints.ppInterface = &
(encomsp->channelEntryPoints.pInterface);
freerdp_channel_add_init_handle_data(&g_ChannelHandles, encomsp->InitHandle, (void*) encomsp);
return TRUE; return TRUE;
error_out: error_out:
if (context)
*(pEntryPointsEx->ppInterface) = NULL;
if (isFreerdp) if (isFreerdp)
free(encomsp->context); free(encomsp->context);

View File

@ -40,7 +40,7 @@
struct encomsp_plugin struct encomsp_plugin
{ {
CHANNEL_DEF channelDef; CHANNEL_DEF channelDef;
CHANNEL_ENTRY_POINTS_FREERDP channelEntryPoints; CHANNEL_ENTRY_POINTS_FREERDP_EX channelEntryPoints;
EncomspClientContext* context; EncomspClientContext* context;

View File

@ -25,7 +25,7 @@ set(${MODULE_PREFIX}_SRCS
rail_orders.c rail_orders.c
rail_orders.h) rail_orders.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")

View File

@ -33,8 +33,6 @@
#include "rail_orders.h" #include "rail_orders.h"
#include "rail_main.h" #include "rail_main.h"
static rdpChannelHandles g_ChannelHandles = { NULL, NULL };
RailClientContext* rail_get_client_interface(railPlugin* rail) RailClientContext* rail_get_client_interface(railPlugin* rail)
{ {
RailClientContext* pInterface; RailClientContext* pInterface;
@ -57,14 +55,14 @@ static UINT rail_send(railPlugin* rail, wStream* s)
} }
else else
{ {
status = rail->channelEntryPoints.pVirtualChannelWrite(rail->OpenHandle, status = rail->channelEntryPoints.pVirtualChannelWriteEx(rail->InitHandle, rail->OpenHandle,
Stream_Buffer(s), (UINT32) Stream_GetPosition(s), s); Stream_Buffer(s), (UINT32) Stream_GetPosition(s), s);
} }
if (status != CHANNEL_RC_OK) if (status != CHANNEL_RC_OK)
{ {
Stream_Free(s, TRUE); Stream_Free(s, TRUE);
WLog_ERR(TAG, "VirtualChannelWrite failed with %s [%08X]", WLog_ERR(TAG, "pVirtualChannelWriteEx failed with %s [%08X]",
WTSErrorToString(status), status); WTSErrorToString(status), status);
} }
@ -542,16 +540,16 @@ static UINT rail_virtual_channel_event_data_received(railPlugin* rail,
return CHANNEL_RC_OK; return CHANNEL_RC_OK;
} }
static VOID VCAPITYPE rail_virtual_channel_open_event(DWORD openHandle, static VOID VCAPITYPE rail_virtual_channel_open_event_ex(LPVOID lpUserParam, DWORD openHandle,
UINT event, UINT event,
LPVOID pData, UINT32 dataLength, UINT32 totalLength, UINT32 dataFlags) LPVOID pData, UINT32 dataLength, UINT32 totalLength, UINT32 dataFlags)
{ {
UINT error = CHANNEL_RC_OK; UINT error = CHANNEL_RC_OK;
railPlugin* rail = (railPlugin*) freerdp_channel_get_open_handle_data(&g_ChannelHandles, openHandle); railPlugin* rail = (railPlugin*) lpUserParam;
if (!rail || (rail->OpenHandle != openHandle)) if (!rail || (rail->OpenHandle != openHandle))
{ {
WLog_ERR(TAG, "rail_virtual_channel_open_event: error no match"); WLog_ERR(TAG, "error no match");
return; return;
} }
@ -635,8 +633,8 @@ static UINT rail_virtual_channel_event_connected(railPlugin* rail, LPVOID pData,
UINT32 dataLength) UINT32 dataLength)
{ {
UINT status; UINT status;
status = rail->channelEntryPoints.pVirtualChannelOpen(rail->InitHandle, status = rail->channelEntryPoints.pVirtualChannelOpenEx(rail->InitHandle,
&rail->OpenHandle, rail->channelDef.name, rail_virtual_channel_open_event); &rail->OpenHandle, rail->channelDef.name, rail_virtual_channel_open_event_ex);
if (status != CHANNEL_RC_OK) if (status != CHANNEL_RC_OK)
{ {
@ -645,8 +643,6 @@ static UINT rail_virtual_channel_event_connected(railPlugin* rail, LPVOID pData,
return status; return status;
} }
freerdp_channel_add_open_handle_data(&g_ChannelHandles, rail->OpenHandle, (void*) rail);
rail->queue = MessageQueue_New(NULL); rail->queue = MessageQueue_New(NULL);
if (!rail->queue) if (!rail->queue)
@ -689,11 +685,11 @@ static UINT rail_virtual_channel_event_disconnected(railPlugin* rail)
CloseHandle(rail->thread); CloseHandle(rail->thread);
rail->queue = NULL; rail->queue = NULL;
rail->thread = NULL; rail->thread = NULL;
rc = rail->channelEntryPoints.pVirtualChannelClose(rail->OpenHandle); rc = rail->channelEntryPoints.pVirtualChannelCloseEx(rail->InitHandle, rail->OpenHandle);
if (CHANNEL_RC_OK != rc) if (CHANNEL_RC_OK != rc)
{ {
WLog_ERR(TAG, "pVirtualChannelClose failed with %s [%08X]", WLog_ERR(TAG, "pVirtualChannelCloseEx failed with %s [%08X]",
WTSErrorToString(rc), rc); WTSErrorToString(rc), rc);
return rc; return rc;
} }
@ -706,27 +702,24 @@ static UINT rail_virtual_channel_event_disconnected(railPlugin* rail)
rail->data_in = NULL; rail->data_in = NULL;
} }
freerdp_channel_remove_open_handle_data(&g_ChannelHandles, rail->OpenHandle);
return CHANNEL_RC_OK; return CHANNEL_RC_OK;
} }
static void rail_virtual_channel_event_terminated(railPlugin* rail) static void rail_virtual_channel_event_terminated(railPlugin* rail)
{ {
freerdp_channel_remove_init_handle_data(&g_ChannelHandles, (void*) rail);
rail->InitHandle = 0; rail->InitHandle = 0;
free(rail); free(rail);
} }
static VOID VCAPITYPE rail_virtual_channel_init_event(LPVOID pInitHandle, static VOID VCAPITYPE rail_virtual_channel_init_event_ex(LPVOID lpUserParam, LPVOID pInitHandle,
UINT event, LPVOID pData, UINT dataLength) UINT event, LPVOID pData, UINT dataLength)
{ {
UINT error = CHANNEL_RC_OK; UINT error = CHANNEL_RC_OK;
railPlugin* rail = (railPlugin*) freerdp_channel_get_init_handle_data(&g_ChannelHandles, pInitHandle); railPlugin* rail = (railPlugin*) lpUserParam;
if (!rail || (rail->InitHandle != pInitHandle)) if (!rail || (rail->InitHandle != pInitHandle))
{ {
WLog_ERR(TAG, "rail_virtual_channel_init_event: error no match"); WLog_ERR(TAG, "error no match");
return; return;
} }
@ -752,19 +745,18 @@ static VOID VCAPITYPE rail_virtual_channel_init_event(LPVOID pInitHandle,
} }
if (error && rail->rdpcontext) if (error && rail->rdpcontext)
setChannelError(rail->rdpcontext, error, setChannelError(rail->rdpcontext, error, "rail_virtual_channel_init_event_ex reported an error");
"rail_virtual_channel_init_event reported an error");
} }
/* rail is always built-in */ /* rail is always built-in */
#define VirtualChannelEntry rail_VirtualChannelEntry #define VirtualChannelEntryEx rail_VirtualChannelEntryEx
BOOL VCAPITYPE VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints) BOOL VCAPITYPE VirtualChannelEntryEx(PCHANNEL_ENTRY_POINTS pEntryPoints, PVOID pInitHandle)
{ {
UINT rc; UINT rc;
railPlugin* rail; railPlugin* rail;
RailClientContext* context = NULL; RailClientContext* context = NULL;
CHANNEL_ENTRY_POINTS_FREERDP* pEntryPointsEx; CHANNEL_ENTRY_POINTS_FREERDP_EX* pEntryPointsEx;
BOOL isFreerdp = FALSE; BOOL isFreerdp = FALSE;
rail = (railPlugin*) calloc(1, sizeof(railPlugin)); rail = (railPlugin*) calloc(1, sizeof(railPlugin));
@ -780,9 +772,9 @@ BOOL VCAPITYPE VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints)
CHANNEL_OPTION_COMPRESS_RDP | CHANNEL_OPTION_COMPRESS_RDP |
CHANNEL_OPTION_SHOW_PROTOCOL; CHANNEL_OPTION_SHOW_PROTOCOL;
strcpy(rail->channelDef.name, "rail"); strcpy(rail->channelDef.name, "rail");
pEntryPointsEx = (CHANNEL_ENTRY_POINTS_FREERDP*) pEntryPoints; pEntryPointsEx = (CHANNEL_ENTRY_POINTS_FREERDP_EX*) pEntryPoints;
if ((pEntryPointsEx->cbSize >= sizeof(CHANNEL_ENTRY_POINTS_FREERDP)) && if ((pEntryPointsEx->cbSize >= sizeof(CHANNEL_ENTRY_POINTS_FREERDP_EX)) &&
(pEntryPointsEx->MagicNumber == FREERDP_CHANNEL_MAGIC_NUMBER)) (pEntryPointsEx->MagicNumber == FREERDP_CHANNEL_MAGIC_NUMBER))
{ {
context = (RailClientContext*) calloc(1, sizeof(RailClientContext)); context = (RailClientContext*) calloc(1, sizeof(RailClientContext));
@ -817,38 +809,31 @@ BOOL VCAPITYPE VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints)
context->ClientGetAppIdRequest = rail_client_get_appid_request; context->ClientGetAppIdRequest = rail_client_get_appid_request;
context->ServerGetAppIdResponse = rail_server_get_appid_response; context->ServerGetAppIdResponse = rail_server_get_appid_response;
rail->rdpcontext = pEntryPointsEx->context; rail->rdpcontext = pEntryPointsEx->context;
*(pEntryPointsEx->ppInterface) = (void*) context;
rail->context = context; rail->context = context;
isFreerdp = TRUE; isFreerdp = TRUE;
} }
WLog_Init(); WLog_Init();
rail->log = WLog_Get("com.freerdp.channels.rail.client"); rail->log = WLog_Get("com.freerdp.channels.rail.client");
WLog_Print(rail->log, WLOG_DEBUG, "VirtualChannelEntry"); WLog_Print(rail->log, WLOG_DEBUG, "VirtualChannelEntryEx");
CopyMemory(&(rail->channelEntryPoints), pEntryPoints, CopyMemory(&(rail->channelEntryPoints), pEntryPoints,
sizeof(CHANNEL_ENTRY_POINTS_FREERDP)); sizeof(CHANNEL_ENTRY_POINTS_FREERDP_EX));
rc = rail->channelEntryPoints.pVirtualChannelInit(&rail->InitHandle, rail->InitHandle = pInitHandle;
rc = rail->channelEntryPoints.pVirtualChannelInitEx(rail, context, pInitHandle,
&rail->channelDef, 1, VIRTUAL_CHANNEL_VERSION_WIN2000, &rail->channelDef, 1, VIRTUAL_CHANNEL_VERSION_WIN2000,
rail_virtual_channel_init_event); rail_virtual_channel_init_event_ex);
if (CHANNEL_RC_OK != rc) if (CHANNEL_RC_OK != rc)
{ {
WLog_ERR(TAG, "pVirtualChannelInit failed with %s [%08X]", WLog_ERR(TAG, "failed with %s [%08X]",
WTSErrorToString(rc), rc); WTSErrorToString(rc), rc);
goto error_out; goto error_out;
} }
rail->channelEntryPoints.pInterface = *(rail->channelEntryPoints.ppInterface); rail->channelEntryPoints.pInterface = context;
rail->channelEntryPoints.ppInterface = &(rail->channelEntryPoints.pInterface);
freerdp_channel_add_init_handle_data(&g_ChannelHandles, rail->InitHandle, (void*) rail);
return TRUE; return TRUE;
error_out: error_out:
if (context)
*(pEntryPointsEx->ppInterface) = NULL;
if (isFreerdp) if (isFreerdp)
free(rail->context); free(rail->context);

View File

@ -39,7 +39,7 @@
struct rail_plugin struct rail_plugin
{ {
CHANNEL_DEF channelDef; CHANNEL_DEF channelDef;
CHANNEL_ENTRY_POINTS_FREERDP channelEntryPoints; CHANNEL_ENTRY_POINTS_FREERDP_EX channelEntryPoints;
RailClientContext* context; RailClientContext* context;

View File

@ -29,7 +29,7 @@ set(${MODULE_PREFIX}_SRCS
rdpdr_capabilities.c rdpdr_capabilities.c
rdpdr_capabilities.h) rdpdr_capabilities.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")

57
channels/rdpdr/client/rdpdr_main.c Executable file → Normal file
View File

@ -67,8 +67,6 @@
#include "rdpdr_main.h" #include "rdpdr_main.h"
static rdpChannelHandles g_ChannelHandles = { NULL, NULL };
typedef struct _DEVICE_DRIVE_EXT DEVICE_DRIVE_EXT; typedef struct _DEVICE_DRIVE_EXT DEVICE_DRIVE_EXT;
struct _DEVICE_DRIVE_EXT struct _DEVICE_DRIVE_EXT
@ -1430,14 +1428,14 @@ UINT rdpdr_send(rdpdrPlugin* rdpdr, wStream* s)
status = CHANNEL_RC_BAD_INIT_HANDLE; status = CHANNEL_RC_BAD_INIT_HANDLE;
else else
{ {
status = plugin->channelEntryPoints.pVirtualChannelWrite(plugin->OpenHandle, status = plugin->channelEntryPoints.pVirtualChannelWriteEx(plugin->InitHandle, plugin->OpenHandle,
Stream_Buffer(s), (UINT32) Stream_GetPosition(s), s); Stream_Buffer(s), (UINT32) Stream_GetPosition(s), s);
} }
if (status != CHANNEL_RC_OK) if (status != CHANNEL_RC_OK)
{ {
Stream_Free(s, TRUE); Stream_Free(s, TRUE);
WLog_ERR(TAG, "VirtualChannelWrite failed with %s [%08X]", WLog_ERR(TAG, "pVirtualChannelWriteEx failed with %s [%08X]",
WTSErrorToString(status), status); WTSErrorToString(status), status);
} }
@ -1511,16 +1509,16 @@ static UINT rdpdr_virtual_channel_event_data_received(rdpdrPlugin* rdpdr,
return CHANNEL_RC_OK; return CHANNEL_RC_OK;
} }
static VOID VCAPITYPE rdpdr_virtual_channel_open_event(DWORD openHandle, static VOID VCAPITYPE rdpdr_virtual_channel_open_event_ex(LPVOID lpUserParam, DWORD openHandle,
UINT event, UINT event,
LPVOID pData, UINT32 dataLength, UINT32 totalLength, UINT32 dataFlags) LPVOID pData, UINT32 dataLength, UINT32 totalLength, UINT32 dataFlags)
{ {
UINT error = CHANNEL_RC_OK; UINT error = CHANNEL_RC_OK;
rdpdrPlugin* rdpdr = (rdpdrPlugin*) freerdp_channel_get_open_handle_data(&g_ChannelHandles, openHandle); rdpdrPlugin* rdpdr = (rdpdrPlugin*) lpUserParam;
if (!rdpdr || !pData || (rdpdr->OpenHandle != openHandle)) if (!rdpdr || !pData || (rdpdr->OpenHandle != openHandle))
{ {
WLog_ERR(TAG, "rdpdr_virtual_channel_open_event: error no match"); WLog_ERR(TAG, "error no match");
return; return;
} }
@ -1544,7 +1542,7 @@ static VOID VCAPITYPE rdpdr_virtual_channel_open_event(DWORD openHandle,
if (error && rdpdr->rdpcontext) if (error && rdpdr->rdpcontext)
setChannelError(rdpdr->rdpcontext, error, setChannelError(rdpdr->rdpcontext, error,
"rdpdr_virtual_channel_open_event reported an error"); "rdpdr_virtual_channel_open_event_ex reported an error");
return; return;
} }
@ -1616,18 +1614,16 @@ static UINT rdpdr_virtual_channel_event_connected(rdpdrPlugin* rdpdr,
LPVOID pData, UINT32 dataLength) LPVOID pData, UINT32 dataLength)
{ {
UINT32 status; UINT32 status;
status = rdpdr->channelEntryPoints.pVirtualChannelOpen(rdpdr->InitHandle, status = rdpdr->channelEntryPoints.pVirtualChannelOpenEx(rdpdr->InitHandle,
&rdpdr->OpenHandle, rdpdr->channelDef.name, rdpdr_virtual_channel_open_event); &rdpdr->OpenHandle, rdpdr->channelDef.name, rdpdr_virtual_channel_open_event_ex);
if (status != CHANNEL_RC_OK) if (status != CHANNEL_RC_OK)
{ {
WLog_ERR(TAG, "pVirtualChannelOpen failed with %s [%08X]", WLog_ERR(TAG, "pVirtualChannelOpenEx failed with %s [%08X]",
WTSErrorToString(status), status); WTSErrorToString(status), status);
return status; return status;
} }
freerdp_channel_add_open_handle_data(&g_ChannelHandles, rdpdr->OpenHandle, (void*) rdpdr);
rdpdr->queue = MessageQueue_New(NULL); rdpdr->queue = MessageQueue_New(NULL);
if (!rdpdr->queue) if (!rdpdr->queue)
@ -1675,11 +1671,11 @@ static UINT rdpdr_virtual_channel_event_disconnected(rdpdrPlugin* rdpdr)
return error; return error;
} }
error = rdpdr->channelEntryPoints.pVirtualChannelClose(rdpdr->OpenHandle); error = rdpdr->channelEntryPoints.pVirtualChannelCloseEx(rdpdr->InitHandle, rdpdr->OpenHandle);
if (CHANNEL_RC_OK != error) if (CHANNEL_RC_OK != error)
{ {
WLog_ERR(TAG, "pVirtualChannelClose failed with %s [%08X]", WLog_ERR(TAG, "pVirtualChannelCloseEx failed with %s [%08X]",
WTSErrorToString(error), error); WTSErrorToString(error), error);
} }
@ -1697,23 +1693,21 @@ static UINT rdpdr_virtual_channel_event_disconnected(rdpdrPlugin* rdpdr)
rdpdr->devman = NULL; rdpdr->devman = NULL;
} }
freerdp_channel_remove_open_handle_data(&g_ChannelHandles, rdpdr->OpenHandle);
return error; return error;
} }
static void rdpdr_virtual_channel_event_terminated(rdpdrPlugin* rdpdr) static void rdpdr_virtual_channel_event_terminated(rdpdrPlugin* rdpdr)
{ {
freerdp_channel_remove_init_handle_data(&g_ChannelHandles, (void*) rdpdr); rdpdr->InitHandle = 0;
free(rdpdr); free(rdpdr);
} }
static VOID VCAPITYPE rdpdr_virtual_channel_init_event(LPVOID pInitHandle, static VOID VCAPITYPE rdpdr_virtual_channel_init_event_ex(LPVOID lpUserParam, LPVOID pInitHandle,
UINT event, UINT event,
LPVOID pData, UINT dataLength) LPVOID pData, UINT dataLength)
{ {
UINT error = CHANNEL_RC_OK; UINT error = CHANNEL_RC_OK;
rdpdrPlugin* rdpdr = (rdpdrPlugin*) freerdp_channel_get_init_handle_data(&g_ChannelHandles, pInitHandle); rdpdrPlugin* rdpdr = (rdpdrPlugin*) lpUserParam;
if (!rdpdr || (rdpdr->InitHandle != pInitHandle)) if (!rdpdr || (rdpdr->InitHandle != pInitHandle))
{ {
@ -1752,17 +1746,17 @@ static VOID VCAPITYPE rdpdr_virtual_channel_init_event(LPVOID pInitHandle,
if (error && rdpdr->rdpcontext) if (error && rdpdr->rdpcontext)
setChannelError(rdpdr->rdpcontext, error, setChannelError(rdpdr->rdpcontext, error,
"rdpdr_virtual_channel_init_event reported an error"); "rdpdr_virtual_channel_init_event_ex reported an error");
} }
/* rdpdr is always built-in */ /* rdpdr is always built-in */
#define VirtualChannelEntry rdpdr_VirtualChannelEntry #define VirtualChannelEntryEx rdpdr_VirtualChannelEntryEx
BOOL VCAPITYPE VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints) BOOL VCAPITYPE VirtualChannelEntryEx(PCHANNEL_ENTRY_POINTS pEntryPoints, PVOID pInitHandle)
{ {
UINT rc; UINT rc;
rdpdrPlugin* rdpdr; rdpdrPlugin* rdpdr;
CHANNEL_ENTRY_POINTS_FREERDP* pEntryPointsEx; CHANNEL_ENTRY_POINTS_FREERDP_EX* pEntryPointsEx;
rdpdr = (rdpdrPlugin*) calloc(1, sizeof(rdpdrPlugin)); rdpdr = (rdpdrPlugin*) calloc(1, sizeof(rdpdrPlugin));
if (!rdpdr) if (!rdpdr)
@ -1777,29 +1771,28 @@ BOOL VCAPITYPE VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints)
CHANNEL_OPTION_COMPRESS_RDP; CHANNEL_OPTION_COMPRESS_RDP;
strcpy(rdpdr->channelDef.name, "rdpdr"); strcpy(rdpdr->channelDef.name, "rdpdr");
rdpdr->sequenceId = 0; rdpdr->sequenceId = 0;
pEntryPointsEx = (CHANNEL_ENTRY_POINTS_FREERDP*) pEntryPoints; pEntryPointsEx = (CHANNEL_ENTRY_POINTS_FREERDP_EX*) pEntryPoints;
if ((pEntryPointsEx->cbSize >= sizeof(CHANNEL_ENTRY_POINTS_FREERDP)) && if ((pEntryPointsEx->cbSize >= sizeof(CHANNEL_ENTRY_POINTS_FREERDP_EX)) &&
(pEntryPointsEx->MagicNumber == FREERDP_CHANNEL_MAGIC_NUMBER)) (pEntryPointsEx->MagicNumber == FREERDP_CHANNEL_MAGIC_NUMBER))
{ {
rdpdr->rdpcontext = pEntryPointsEx->context; rdpdr->rdpcontext = pEntryPointsEx->context;
} }
CopyMemory(&(rdpdr->channelEntryPoints), pEntryPoints, CopyMemory(&(rdpdr->channelEntryPoints), pEntryPoints,
sizeof(CHANNEL_ENTRY_POINTS_FREERDP)); sizeof(CHANNEL_ENTRY_POINTS_FREERDP_EX));
rc = rdpdr->channelEntryPoints.pVirtualChannelInit(&rdpdr->InitHandle, rdpdr->InitHandle = pInitHandle;
rc = rdpdr->channelEntryPoints.pVirtualChannelInitEx(rdpdr, NULL, pInitHandle,
&rdpdr->channelDef, 1, VIRTUAL_CHANNEL_VERSION_WIN2000, &rdpdr->channelDef, 1, VIRTUAL_CHANNEL_VERSION_WIN2000,
rdpdr_virtual_channel_init_event); rdpdr_virtual_channel_init_event_ex);
if (CHANNEL_RC_OK != rc) if (CHANNEL_RC_OK != rc)
{ {
WLog_ERR(TAG, "pVirtualChannelInit failed with %s [%08X]", WLog_ERR(TAG, "pVirtualChannelInitEx failed with %s [%08X]",
WTSErrorToString(rc), rc); WTSErrorToString(rc), rc);
free(rdpdr); free(rdpdr);
return FALSE; return FALSE;
} }
freerdp_channel_add_init_handle_data(&g_ChannelHandles, rdpdr->InitHandle, (void*) rdpdr);
return TRUE; return TRUE;
} }

View File

@ -49,7 +49,7 @@ typedef struct rdpdr_plugin rdpdrPlugin;
struct rdpdr_plugin struct rdpdr_plugin
{ {
CHANNEL_DEF channelDef; CHANNEL_DEF channelDef;
CHANNEL_ENTRY_POINTS_FREERDP channelEntryPoints; CHANNEL_ENTRY_POINTS_FREERDP_EX channelEntryPoints;
HANDLE thread; HANDLE thread;
wStream* data_in; wStream* data_in;

View File

@ -21,7 +21,7 @@ set(${MODULE_PREFIX}_SRCS
rdpsnd_main.c rdpsnd_main.c
rdpsnd_main.h) rdpsnd_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")

View File

@ -52,7 +52,7 @@
struct rdpsnd_plugin struct rdpsnd_plugin
{ {
CHANNEL_DEF channelDef; CHANNEL_DEF channelDef;
CHANNEL_ENTRY_POINTS_FREERDP channelEntryPoints; CHANNEL_ENTRY_POINTS_FREERDP_EX channelEntryPoints;
HANDLE thread; HANDLE thread;
wStream* data_in; wStream* data_in;
@ -93,8 +93,6 @@ struct rdpsnd_plugin
rdpContext* rdpcontext; rdpContext* rdpcontext;
}; };
static rdpChannelHandles g_ChannelHandles = { NULL, NULL };
/** /**
* Function description * Function description
* *
@ -113,7 +111,6 @@ static void* rdpsnd_schedule_thread(void* arg)
HANDLE events[2]; HANDLE events[2];
UINT error = CHANNEL_RC_OK; UINT error = CHANNEL_RC_OK;
DWORD status; DWORD status;
events[0] = MessageQueue_Event(rdpsnd->MsgPipe->Out); events[0] = MessageQueue_Event(rdpsnd->MsgPipe->Out);
events[1] = rdpsnd->stopEvent; events[1] = rdpsnd->stopEvent;
@ -1130,14 +1127,14 @@ UINT rdpsnd_virtual_channel_write(rdpsndPlugin* rdpsnd, wStream* s)
} }
else else
{ {
status = rdpsnd->channelEntryPoints.pVirtualChannelWrite(rdpsnd->OpenHandle, status = rdpsnd->channelEntryPoints.pVirtualChannelWriteEx(rdpsnd->InitHandle, rdpsnd->OpenHandle,
Stream_Buffer(s), (UINT32) Stream_GetPosition(s), s); Stream_Buffer(s), (UINT32) Stream_GetPosition(s), s);
} }
if (status != CHANNEL_RC_OK) if (status != CHANNEL_RC_OK)
{ {
Stream_Free(s, TRUE); Stream_Free(s, TRUE);
WLog_ERR(TAG, "VirtualChannelWrite failed with %s [%08X]", WLog_ERR(TAG, "pVirtualChannelWriteEx failed with %s [%08X]",
WTSErrorToString(status), status); WTSErrorToString(status), status);
} }
@ -1205,16 +1202,16 @@ static UINT rdpsnd_virtual_channel_event_data_received(rdpsndPlugin* plugin,
return CHANNEL_RC_OK; return CHANNEL_RC_OK;
} }
static VOID VCAPITYPE rdpsnd_virtual_channel_open_event(DWORD openHandle, static VOID VCAPITYPE rdpsnd_virtual_channel_open_event_ex(LPVOID lpUserParam, DWORD openHandle,
UINT event, UINT event,
LPVOID pData, UINT32 dataLength, UINT32 totalLength, UINT32 dataFlags) LPVOID pData, UINT32 dataLength, UINT32 totalLength, UINT32 dataFlags)
{ {
UINT error = CHANNEL_RC_OK; UINT error = CHANNEL_RC_OK;
rdpsndPlugin* rdpsnd = (rdpsndPlugin*) freerdp_channel_get_open_handle_data(&g_ChannelHandles, openHandle); rdpsndPlugin* rdpsnd = (rdpsndPlugin*) lpUserParam;
if (!rdpsnd || (rdpsnd->OpenHandle != openHandle)) if (!rdpsnd || (rdpsnd->OpenHandle != openHandle))
{ {
WLog_ERR(TAG, "rdpsnd_virtual_channel_open_event: error no match"); WLog_ERR(TAG, "error no match");
return; return;
} }
@ -1238,7 +1235,7 @@ static VOID VCAPITYPE rdpsnd_virtual_channel_open_event(DWORD openHandle,
if (error && rdpsnd->rdpcontext) if (error && rdpsnd->rdpcontext)
setChannelError(rdpsnd->rdpcontext, error, setChannelError(rdpsnd->rdpcontext, error,
"rdpsnd_virtual_channel_open_event reported an error"); "rdpsnd_virtual_channel_open_event_ex reported an error");
} }
static void* rdpsnd_virtual_channel_client_thread(void* arg) static void* rdpsnd_virtual_channel_client_thread(void* arg)
@ -1305,19 +1302,17 @@ static UINT rdpsnd_virtual_channel_event_connected(rdpsndPlugin* rdpsnd,
LPVOID pData, UINT32 dataLength) LPVOID pData, UINT32 dataLength)
{ {
UINT32 status; UINT32 status;
status = rdpsnd->channelEntryPoints.pVirtualChannelOpen(rdpsnd->InitHandle, status = rdpsnd->channelEntryPoints.pVirtualChannelOpenEx(rdpsnd->InitHandle,
&rdpsnd->OpenHandle, rdpsnd->channelDef.name, &rdpsnd->OpenHandle, rdpsnd->channelDef.name,
rdpsnd_virtual_channel_open_event); rdpsnd_virtual_channel_open_event_ex);
if (status != CHANNEL_RC_OK) if (status != CHANNEL_RC_OK)
{ {
WLog_ERR(TAG, "pVirtualChannelOpen failed with %s [%08X]", WLog_ERR(TAG, "pVirtualChannelOpenEx failed with %s [%08X]",
WTSErrorToString(status), status); WTSErrorToString(status), status);
return status; return status;
} }
freerdp_channel_add_open_handle_data(&g_ChannelHandles, rdpsnd->OpenHandle, (void*) rdpsnd);
rdpsnd->MsgPipe = MessagePipe_New(); rdpsnd->MsgPipe = MessagePipe_New();
if (!rdpsnd->MsgPipe) if (!rdpsnd->MsgPipe)
@ -1360,11 +1355,11 @@ static UINT rdpsnd_virtual_channel_event_disconnected(rdpsndPlugin* rdpsnd)
CloseHandle(rdpsnd->thread); CloseHandle(rdpsnd->thread);
rdpsnd->thread = NULL; rdpsnd->thread = NULL;
error = rdpsnd->channelEntryPoints.pVirtualChannelClose(rdpsnd->OpenHandle); error = rdpsnd->channelEntryPoints.pVirtualChannelCloseEx(rdpsnd->InitHandle, rdpsnd->OpenHandle);
if (CHANNEL_RC_OK != error) if (CHANNEL_RC_OK != error)
{ {
WLog_ERR(TAG, "pVirtualChannelClose failed with %s [%08X]", WLog_ERR(TAG, "pVirtualChannelCloseEx failed with %s [%08X]",
WTSErrorToString(error), error); WTSErrorToString(error), error);
return error; return error;
} }
@ -1404,27 +1399,24 @@ static UINT rdpsnd_virtual_channel_event_disconnected(rdpsndPlugin* rdpsnd)
rdpsnd->device_name = NULL; rdpsnd->device_name = NULL;
} }
freerdp_channel_remove_open_handle_data(&g_ChannelHandles, rdpsnd->OpenHandle);
return CHANNEL_RC_OK; return CHANNEL_RC_OK;
} }
static void rdpsnd_virtual_channel_event_terminated(rdpsndPlugin* rdpsnd) static void rdpsnd_virtual_channel_event_terminated(rdpsndPlugin* rdpsnd)
{ {
freerdp_channel_remove_init_handle_data(&g_ChannelHandles, (void*) rdpsnd);
rdpsnd->InitHandle = 0; rdpsnd->InitHandle = 0;
free(rdpsnd); free(rdpsnd);
} }
static VOID VCAPITYPE rdpsnd_virtual_channel_init_event(LPVOID pInitHandle, static VOID VCAPITYPE rdpsnd_virtual_channel_init_event_ex(LPVOID lpUserParam, LPVOID pInitHandle,
UINT event, LPVOID pData, UINT dataLength) UINT event, LPVOID pData, UINT dataLength)
{ {
UINT error = CHANNEL_RC_OK; UINT error = CHANNEL_RC_OK;
rdpsndPlugin* plugin = (rdpsndPlugin*) freerdp_channel_get_init_handle_data(&g_ChannelHandles, pInitHandle); rdpsndPlugin* plugin = (rdpsndPlugin*) lpUserParam;
if (!plugin || (plugin->InitHandle != pInitHandle)) if (!plugin || (plugin->InitHandle != pInitHandle))
{ {
WLog_ERR(TAG, "rdpsnd_virtual_channel_init_event: error no match"); WLog_ERR(TAG, "error no match");
return; return;
} }
@ -1461,13 +1453,13 @@ static VOID VCAPITYPE rdpsnd_virtual_channel_init_event(LPVOID pInitHandle,
} }
/* rdpsnd is always built-in */ /* rdpsnd is always built-in */
#define VirtualChannelEntry rdpsnd_VirtualChannelEntry #define VirtualChannelEntryEx rdpsnd_VirtualChannelEntryEx
BOOL VCAPITYPE VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints) BOOL VCAPITYPE VirtualChannelEntryEx(PCHANNEL_ENTRY_POINTS pEntryPoints, PVOID pInitHandle)
{ {
UINT rc; UINT rc;
rdpsndPlugin* rdpsnd; rdpsndPlugin* rdpsnd;
CHANNEL_ENTRY_POINTS_FREERDP* pEntryPointsEx; CHANNEL_ENTRY_POINTS_FREERDP_EX* pEntryPointsEx;
if (!pEntryPoints) if (!pEntryPoints)
{ {
@ -1494,30 +1486,31 @@ BOOL VCAPITYPE VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints)
CHANNEL_OPTION_INITIALIZED | CHANNEL_OPTION_INITIALIZED |
CHANNEL_OPTION_ENCRYPT_RDP; CHANNEL_OPTION_ENCRYPT_RDP;
strcpy(rdpsnd->channelDef.name, "rdpsnd"); strcpy(rdpsnd->channelDef.name, "rdpsnd");
pEntryPointsEx = (CHANNEL_ENTRY_POINTS_FREERDP*) pEntryPoints; pEntryPointsEx = (CHANNEL_ENTRY_POINTS_FREERDP_EX*) pEntryPoints;
if ((pEntryPointsEx->cbSize >= sizeof(CHANNEL_ENTRY_POINTS_FREERDP)) && if ((pEntryPointsEx->cbSize >= sizeof(CHANNEL_ENTRY_POINTS_FREERDP_EX)) &&
(pEntryPointsEx->MagicNumber == FREERDP_CHANNEL_MAGIC_NUMBER)) (pEntryPointsEx->MagicNumber == FREERDP_CHANNEL_MAGIC_NUMBER))
{ {
rdpsnd->rdpcontext = pEntryPointsEx->context; rdpsnd->rdpcontext = pEntryPointsEx->context;
} }
CopyMemory(&(rdpsnd->channelEntryPoints), pEntryPoints,
sizeof(CHANNEL_ENTRY_POINTS_FREERDP));
rdpsnd->log = WLog_Get("com.freerdp.channels.rdpsnd.client"); rdpsnd->log = WLog_Get("com.freerdp.channels.rdpsnd.client");
rc = rdpsnd->channelEntryPoints.pVirtualChannelInit(&rdpsnd->InitHandle, CopyMemory(&(rdpsnd->channelEntryPoints), pEntryPoints,
sizeof(CHANNEL_ENTRY_POINTS_FREERDP_EX));
rdpsnd->InitHandle = pInitHandle;
rc = rdpsnd->channelEntryPoints.pVirtualChannelInitEx(rdpsnd, NULL, pInitHandle,
&rdpsnd->channelDef, 1, VIRTUAL_CHANNEL_VERSION_WIN2000, &rdpsnd->channelDef, 1, VIRTUAL_CHANNEL_VERSION_WIN2000,
rdpsnd_virtual_channel_init_event); rdpsnd_virtual_channel_init_event_ex);
if (CHANNEL_RC_OK != rc) if (CHANNEL_RC_OK != rc)
{ {
WLog_ERR(TAG, "pVirtualChannelInit failed with %s [%08X]", WLog_ERR(TAG, "pVirtualChannelInitEx failed with %s [%08X]",
WTSErrorToString(rc), rc); WTSErrorToString(rc), rc);
free(rdpsnd); free(rdpsnd);
return FALSE; return FALSE;
} }
freerdp_channel_add_init_handle_data(&g_ChannelHandles, rdpsnd->InitHandle, (void*) rdpsnd);
return TRUE; return TRUE;
} }

View File

@ -21,7 +21,7 @@ set(${MODULE_PREFIX}_SRCS
remdesk_main.c remdesk_main.c
remdesk_main.h) remdesk_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")

View File

@ -33,8 +33,6 @@
#include "remdesk_main.h" #include "remdesk_main.h"
static rdpChannelHandles g_ChannelHandles = { NULL, NULL };
static RemdeskClientContext* remdesk_get_client_interface( static RemdeskClientContext* remdesk_get_client_interface(
remdeskPlugin* remdesk) remdeskPlugin* remdesk)
{ {
@ -58,11 +56,12 @@ static UINT remdesk_virtual_channel_write(remdeskPlugin* remdesk, wStream* s)
return CHANNEL_RC_INVALID_INSTANCE; return CHANNEL_RC_INVALID_INSTANCE;
} }
status = remdesk->channelEntryPoints.pVirtualChannelWrite(remdesk->OpenHandle, status = remdesk->channelEntryPoints.pVirtualChannelWriteEx(remdesk->InitHandle,
remdesk->OpenHandle,
Stream_Buffer(s), (UINT32) Stream_Length(s), s); Stream_Buffer(s), (UINT32) Stream_Length(s), s);
if (status != CHANNEL_RC_OK) if (status != CHANNEL_RC_OK)
WLog_ERR(TAG, "VirtualChannelWrite failed with %s [%08X]", WLog_ERR(TAG, "pVirtualChannelWriteEx failed with %s [%08X]",
WTSErrorToString(status), status); WTSErrorToString(status), status);
return status; return status;
@ -727,14 +726,14 @@ static UINT remdesk_send(remdeskPlugin* remdesk, wStream* s)
} }
else else
{ {
status = plugin->channelEntryPoints.pVirtualChannelWrite(plugin->OpenHandle, status = plugin->channelEntryPoints.pVirtualChannelWriteEx(plugin->InitHandle, plugin->OpenHandle,
Stream_Buffer(s), (UINT32) Stream_GetPosition(s), s); Stream_Buffer(s), (UINT32) Stream_GetPosition(s), s);
} }
if (status != CHANNEL_RC_OK) if (status != CHANNEL_RC_OK)
{ {
Stream_Free(s, TRUE); Stream_Free(s, TRUE);
WLog_ERR(TAG, "VirtualChannelWrite failed with %s [%08X]", WLog_ERR(TAG, "pVirtualChannelWriteEx failed with %s [%08X]",
WTSErrorToString(status), status); WTSErrorToString(status), status);
} }
@ -802,12 +801,12 @@ static UINT remdesk_virtual_channel_event_data_received(remdeskPlugin* remdesk,
return CHANNEL_RC_OK; return CHANNEL_RC_OK;
} }
static VOID VCAPITYPE remdesk_virtual_channel_open_event(DWORD openHandle, static VOID VCAPITYPE remdesk_virtual_channel_open_event_ex(LPVOID lpUserParam, DWORD openHandle,
UINT event, UINT event,
LPVOID pData, UINT32 dataLength, UINT32 totalLength, UINT32 dataFlags) LPVOID pData, UINT32 dataLength, UINT32 totalLength, UINT32 dataFlags)
{ {
UINT error = CHANNEL_RC_OK; UINT error = CHANNEL_RC_OK;
remdeskPlugin* remdesk = (remdeskPlugin*) freerdp_channel_get_open_handle_data(&g_ChannelHandles, openHandle); remdeskPlugin* remdesk = (remdeskPlugin*) lpUserParam;
if (!remdesk || (remdesk->OpenHandle != openHandle)) if (!remdesk || (remdesk->OpenHandle != openHandle))
{ {
@ -839,7 +838,7 @@ static VOID VCAPITYPE remdesk_virtual_channel_open_event(DWORD openHandle,
if (error && remdesk->rdpcontext) if (error && remdesk->rdpcontext)
setChannelError(remdesk->rdpcontext, error, setChannelError(remdesk->rdpcontext, error,
"remdesk_virtual_channel_open_event reported an error"); "remdesk_virtual_channel_open_event_ex reported an error");
} }
static void* remdesk_virtual_channel_client_thread(void* arg) static void* remdesk_virtual_channel_client_thread(void* arg)
@ -848,7 +847,6 @@ static void* remdesk_virtual_channel_client_thread(void* arg)
wMessage message; wMessage message;
remdeskPlugin* remdesk = (remdeskPlugin*) arg; remdeskPlugin* remdesk = (remdeskPlugin*) arg;
UINT error = CHANNEL_RC_OK; UINT error = CHANNEL_RC_OK;
remdesk_process_connect(remdesk); remdesk_process_connect(remdesk);
while (1) while (1)
@ -900,19 +898,17 @@ static UINT remdesk_virtual_channel_event_connected(remdeskPlugin* remdesk,
{ {
UINT32 status; UINT32 status;
UINT error; UINT error;
status = remdesk->channelEntryPoints.pVirtualChannelOpen(remdesk->InitHandle, status = remdesk->channelEntryPoints.pVirtualChannelOpenEx(remdesk->InitHandle,
&remdesk->OpenHandle, remdesk->channelDef.name, &remdesk->OpenHandle, remdesk->channelDef.name,
remdesk_virtual_channel_open_event); remdesk_virtual_channel_open_event_ex);
if (status != CHANNEL_RC_OK) if (status != CHANNEL_RC_OK)
{ {
WLog_ERR(TAG, "pVirtualChannelOpen failed with %s [%08X]", WLog_ERR(TAG, "pVirtualChannelOpenEx failed with %s [%08X]",
WTSErrorToString(status), status); WTSErrorToString(status), status);
return status; return status;
} }
freerdp_channel_add_open_handle_data(&g_ChannelHandles, remdesk->OpenHandle, (void*) remdesk);
remdesk->queue = MessageQueue_New(NULL); remdesk->queue = MessageQueue_New(NULL);
if (!remdesk->queue) if (!remdesk->queue)
@ -961,11 +957,11 @@ static UINT remdesk_virtual_channel_event_disconnected(remdeskPlugin* remdesk)
CloseHandle(remdesk->thread); CloseHandle(remdesk->thread);
remdesk->queue = NULL; remdesk->queue = NULL;
remdesk->thread = NULL; remdesk->thread = NULL;
rc = remdesk->channelEntryPoints.pVirtualChannelClose(remdesk->OpenHandle); rc = remdesk->channelEntryPoints.pVirtualChannelCloseEx(remdesk->InitHandle, remdesk->OpenHandle);
if (CHANNEL_RC_OK != rc) if (CHANNEL_RC_OK != rc)
{ {
WLog_ERR(TAG, "pVirtualChannelClose failed with %s [%08X]", WLog_ERR(TAG, "pVirtualChannelCloseEx failed with %s [%08X]",
WTSErrorToString(rc), rc); WTSErrorToString(rc), rc);
} }
@ -977,24 +973,21 @@ static UINT remdesk_virtual_channel_event_disconnected(remdeskPlugin* remdesk)
remdesk->data_in = NULL; remdesk->data_in = NULL;
} }
freerdp_channel_remove_open_handle_data(&g_ChannelHandles, remdesk->OpenHandle);
return rc; return rc;
} }
static void remdesk_virtual_channel_event_terminated(remdeskPlugin* remdesk) static void remdesk_virtual_channel_event_terminated(remdeskPlugin* remdesk)
{ {
freerdp_channel_remove_init_handle_data(&g_ChannelHandles, (void*) remdesk);
remdesk->InitHandle = 0; remdesk->InitHandle = 0;
free(remdesk); free(remdesk);
} }
static VOID VCAPITYPE remdesk_virtual_channel_init_event(LPVOID pInitHandle, static VOID VCAPITYPE remdesk_virtual_channel_init_event_ex(LPVOID lpUserParam, LPVOID pInitHandle,
UINT event, LPVOID pData, UINT event, LPVOID pData,
UINT dataLength) UINT dataLength)
{ {
UINT error = CHANNEL_RC_OK; UINT error = CHANNEL_RC_OK;
remdeskPlugin* remdesk = (remdeskPlugin*) freerdp_channel_get_init_handle_data(&g_ChannelHandles, pInitHandle); remdeskPlugin* remdesk = (remdeskPlugin*) lpUserParam;
if (!remdesk || (remdesk->InitHandle != pInitHandle)) if (!remdesk || (remdesk->InitHandle != pInitHandle))
{ {
@ -1030,14 +1023,14 @@ static VOID VCAPITYPE remdesk_virtual_channel_init_event(LPVOID pInitHandle,
} }
/* remdesk is always built-in */ /* remdesk is always built-in */
#define VirtualChannelEntry remdesk_VirtualChannelEntry #define VirtualChannelEntryEx remdesk_VirtualChannelEntryEx
BOOL VCAPITYPE VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints) BOOL VCAPITYPE VirtualChannelEntryEx(PCHANNEL_ENTRY_POINTS pEntryPoints, PVOID pInitHandle)
{ {
UINT rc; UINT rc;
remdeskPlugin* remdesk; remdeskPlugin* remdesk;
RemdeskClientContext* context = NULL; RemdeskClientContext* context = NULL;
CHANNEL_ENTRY_POINTS_FREERDP* pEntryPointsEx; CHANNEL_ENTRY_POINTS_FREERDP_EX* pEntryPointsEx;
if (!pEntryPoints) if (!pEntryPoints)
{ {
@ -1059,9 +1052,9 @@ BOOL VCAPITYPE VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints)
CHANNEL_OPTION_SHOW_PROTOCOL; CHANNEL_OPTION_SHOW_PROTOCOL;
strcpy(remdesk->channelDef.name, "remdesk"); strcpy(remdesk->channelDef.name, "remdesk");
remdesk->Version = 2; remdesk->Version = 2;
pEntryPointsEx = (CHANNEL_ENTRY_POINTS_FREERDP*) pEntryPoints; pEntryPointsEx = (CHANNEL_ENTRY_POINTS_FREERDP_EX*) pEntryPoints;
if ((pEntryPointsEx->cbSize >= sizeof(CHANNEL_ENTRY_POINTS_FREERDP)) && if ((pEntryPointsEx->cbSize >= sizeof(CHANNEL_ENTRY_POINTS_FREERDP_EX)) &&
(pEntryPointsEx->MagicNumber == FREERDP_CHANNEL_MAGIC_NUMBER)) (pEntryPointsEx->MagicNumber == FREERDP_CHANNEL_MAGIC_NUMBER))
{ {
context = (RemdeskClientContext*) calloc(1, sizeof(RemdeskClientContext)); context = (RemdeskClientContext*) calloc(1, sizeof(RemdeskClientContext));
@ -1073,37 +1066,27 @@ BOOL VCAPITYPE VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints)
} }
context->handle = (void*) remdesk; context->handle = (void*) remdesk;
*(pEntryPointsEx->ppInterface) = (void*) context;
remdesk->context = context; remdesk->context = context;
remdesk->rdpcontext = pEntryPointsEx->context; remdesk->rdpcontext = pEntryPointsEx->context;
} }
CopyMemory(&(remdesk->channelEntryPoints), pEntryPoints, CopyMemory(&(remdesk->channelEntryPoints), pEntryPoints,
sizeof(CHANNEL_ENTRY_POINTS_FREERDP)); sizeof(CHANNEL_ENTRY_POINTS_FREERDP_EX));
rc = remdesk->channelEntryPoints.pVirtualChannelInit(&remdesk->InitHandle, remdesk->InitHandle = pInitHandle;
rc = remdesk->channelEntryPoints.pVirtualChannelInitEx(remdesk, context, pInitHandle,
&remdesk->channelDef, 1, VIRTUAL_CHANNEL_VERSION_WIN2000, &remdesk->channelDef, 1, VIRTUAL_CHANNEL_VERSION_WIN2000,
remdesk_virtual_channel_init_event); remdesk_virtual_channel_init_event_ex);
if (CHANNEL_RC_OK != rc) if (CHANNEL_RC_OK != rc)
{ {
WLog_ERR(TAG, "pVirtualChannelInit failed with %s [%08X]", WLog_ERR(TAG, "pVirtualChannelInitEx failed with %s [%08X]",
WTSErrorToString(rc), rc); WTSErrorToString(rc), rc);
goto error_out; goto error_out;
} }
remdesk->channelEntryPoints.pInterface = * remdesk->channelEntryPoints.pInterface = context;
(remdesk->channelEntryPoints.ppInterface);
remdesk->channelEntryPoints.ppInterface = &
(remdesk->channelEntryPoints.pInterface);
freerdp_channel_add_init_handle_data(&g_ChannelHandles, remdesk->InitHandle, (void*) remdesk);
return TRUE; return TRUE;
error_out: error_out:
if (context)
*(pEntryPointsEx->ppInterface) = NULL;
free(remdesk); free(remdesk);
free(context); free(context);
return FALSE; return FALSE;

View File

@ -41,7 +41,7 @@
struct remdesk_plugin struct remdesk_plugin
{ {
CHANNEL_DEF channelDef; CHANNEL_DEF channelDef;
CHANNEL_ENTRY_POINTS_FREERDP channelEntryPoints; CHANNEL_ENTRY_POINTS_FREERDP_EX channelEntryPoints;
RemdeskClientContext* context; RemdeskClientContext* context;

View File

@ -34,7 +34,8 @@
static WINPR_TLS void* g_pInterface = NULL; static WINPR_TLS void* g_pInterface = NULL;
static WINPR_TLS rdpChannels* g_channels = NULL; /* use only for VirtualChannelInit hack */ static WINPR_TLS rdpChannels* g_channels = NULL; /* use only for VirtualChannelInit hack */
static UINT32 g_OpenHandleSeq = 1; /* use global counter to ensure uniqueness across channel manager instances */ static UINT32 g_OpenHandleSeq =
1; /* use global counter to ensure uniqueness across channel manager instances */
static rdpChannelHandles g_ChannelHandles = { NULL, NULL }; static rdpChannelHandles g_ChannelHandles = { NULL, NULL };
static CHANNEL_OPEN_DATA* freerdp_channels_find_channel_open_data_by_name( static CHANNEL_OPEN_DATA* freerdp_channels_find_channel_open_data_by_name(
@ -198,12 +199,12 @@ UINT freerdp_channels_pre_connect(rdpChannels* channels, freerdp* instance)
if (pChannelClientData->pChannelInitEventProc) if (pChannelClientData->pChannelInitEventProc)
{ {
pChannelClientData->pChannelInitEventProc( pChannelClientData->pChannelInitEventProc(
pChannelClientData->pInitHandle, CHANNEL_EVENT_INITIALIZED, 0, 0); pChannelClientData->pInitHandle, CHANNEL_EVENT_INITIALIZED, 0, 0);
} }
else if (pChannelClientData->pChannelInitEventProcEx) else if (pChannelClientData->pChannelInitEventProcEx)
{ {
pChannelClientData->pChannelInitEventProcEx(pChannelClientData->lpUserParam, pChannelClientData->pChannelInitEventProcEx(pChannelClientData->lpUserParam,
pChannelClientData->pInitHandle, CHANNEL_EVENT_INITIALIZED, 0, 0); pChannelClientData->pInitHandle, CHANNEL_EVENT_INITIALIZED, 0, 0);
} }
if (CHANNEL_RC_OK != getChannelError(instance->context)) if (CHANNEL_RC_OK != getChannelError(instance->context))
@ -234,25 +235,23 @@ UINT freerdp_channels_post_connect(rdpChannels* channels, freerdp* instance)
{ {
ChannelConnectedEventArgs e; ChannelConnectedEventArgs e;
CHANNEL_OPEN_DATA* pChannelOpenData = NULL; CHANNEL_OPEN_DATA* pChannelOpenData = NULL;
pChannelClientData = &channels->clientDataList[index]; pChannelClientData = &channels->clientDataList[index];
if (pChannelClientData->pChannelInitEventProc) if (pChannelClientData->pChannelInitEventProc)
{ {
pChannelClientData->pChannelInitEventProc( pChannelClientData->pChannelInitEventProc(
pChannelClientData->pInitHandle, CHANNEL_EVENT_CONNECTED, hostname, hostnameLength); pChannelClientData->pInitHandle, CHANNEL_EVENT_CONNECTED, hostname, hostnameLength);
} }
else if (pChannelClientData->pChannelInitEventProcEx) else if (pChannelClientData->pChannelInitEventProcEx)
{ {
pChannelClientData->pChannelInitEventProcEx(pChannelClientData->lpUserParam, pChannelClientData->pChannelInitEventProcEx(pChannelClientData->lpUserParam,
pChannelClientData->pInitHandle, CHANNEL_EVENT_CONNECTED, hostname, hostnameLength); pChannelClientData->pInitHandle, CHANNEL_EVENT_CONNECTED, hostname, hostnameLength);
} }
if (getChannelError(instance->context) != CHANNEL_RC_OK) if (getChannelError(instance->context) != CHANNEL_RC_OK)
goto fail; goto fail;
pChannelOpenData = &channels->openDataList[index]; pChannelOpenData = &channels->openDataList[index];
name = (char*) malloc(9); name = (char*) malloc(9);
if (!name) if (!name)
@ -327,12 +326,12 @@ int freerdp_channels_data(freerdp* instance, UINT16 channelId, BYTE* data,
if (pChannelOpenData->pChannelOpenEventProc) if (pChannelOpenData->pChannelOpenEventProc)
{ {
pChannelOpenData->pChannelOpenEventProc( pChannelOpenData->pChannelOpenEventProc(
pChannelOpenData->OpenHandle, CHANNEL_EVENT_DATA_RECEIVED, data, dataSize, totalSize, flags); pChannelOpenData->OpenHandle, CHANNEL_EVENT_DATA_RECEIVED, data, dataSize, totalSize, flags);
} }
else if (pChannelOpenData->pChannelOpenEventProcEx) else if (pChannelOpenData->pChannelOpenEventProcEx)
{ {
pChannelOpenData->pChannelOpenEventProcEx(pChannelOpenData->lpUserParam, pChannelOpenData->pChannelOpenEventProcEx(pChannelOpenData->lpUserParam,
pChannelOpenData->OpenHandle, CHANNEL_EVENT_DATA_RECEIVED, data, dataSize, totalSize, flags); pChannelOpenData->OpenHandle, CHANNEL_EVENT_DATA_RECEIVED, data, dataSize, totalSize, flags);
} }
return 0; return 0;
@ -374,12 +373,14 @@ static int freerdp_channels_process_sync(rdpChannels* channels,
if (pChannelOpenData->pChannelOpenEventProc) if (pChannelOpenData->pChannelOpenEventProc)
{ {
pChannelOpenData->pChannelOpenEventProc( pChannelOpenData->pChannelOpenEventProc(
pChannelOpenData->OpenHandle, CHANNEL_EVENT_WRITE_COMPLETE, item->UserData, item->DataLength, item->DataLength, 0); pChannelOpenData->OpenHandle, CHANNEL_EVENT_WRITE_COMPLETE, item->UserData, item->DataLength,
item->DataLength, 0);
} }
else if (pChannelOpenData->pChannelOpenEventProcEx) else if (pChannelOpenData->pChannelOpenEventProcEx)
{ {
pChannelOpenData->pChannelOpenEventProcEx(pChannelOpenData->lpUserParam, pChannelOpenData->pChannelOpenEventProcEx(pChannelOpenData->lpUserParam,
pChannelOpenData->OpenHandle, CHANNEL_EVENT_WRITE_COMPLETE, item->UserData, item->DataLength, item->DataLength, 0); pChannelOpenData->OpenHandle, CHANNEL_EVENT_WRITE_COMPLETE, item->UserData, item->DataLength,
item->DataLength, 0);
} }
free(item); free(item);
@ -482,12 +483,12 @@ UINT freerdp_channels_disconnect(rdpChannels* channels, freerdp* instance)
if (pChannelClientData->pChannelInitEventProc) if (pChannelClientData->pChannelInitEventProc)
{ {
pChannelClientData->pChannelInitEventProc( pChannelClientData->pChannelInitEventProc(
pChannelClientData->pInitHandle, CHANNEL_EVENT_DISCONNECTED, 0, 0); pChannelClientData->pInitHandle, CHANNEL_EVENT_DISCONNECTED, 0, 0);
} }
else if (pChannelClientData->pChannelInitEventProcEx) else if (pChannelClientData->pChannelInitEventProcEx)
{ {
pChannelClientData->pChannelInitEventProcEx(pChannelClientData->lpUserParam, pChannelClientData->pChannelInitEventProcEx(pChannelClientData->lpUserParam,
pChannelClientData->pInitHandle, CHANNEL_EVENT_DISCONNECTED, 0, 0); pChannelClientData->pInitHandle, CHANNEL_EVENT_DISCONNECTED, 0, 0);
} }
if (getChannelError(instance->context) != CHANNEL_RC_OK) if (getChannelError(instance->context) != CHANNEL_RC_OK)
@ -526,24 +527,24 @@ void freerdp_channels_close(rdpChannels* channels, freerdp* instance)
if (pChannelClientData->pChannelInitEventProc) if (pChannelClientData->pChannelInitEventProc)
{ {
pChannelClientData->pChannelInitEventProc( pChannelClientData->pChannelInitEventProc(
pChannelClientData->pInitHandle, CHANNEL_EVENT_TERMINATED, 0, 0); pChannelClientData->pInitHandle, CHANNEL_EVENT_TERMINATED, 0, 0);
} }
else if (pChannelClientData->pChannelInitEventProcEx) else if (pChannelClientData->pChannelInitEventProcEx)
{ {
pChannelClientData->pChannelInitEventProcEx(pChannelClientData->lpUserParam, pChannelClientData->pChannelInitEventProcEx(pChannelClientData->lpUserParam,
pChannelClientData->pInitHandle, CHANNEL_EVENT_TERMINATED, 0, 0); pChannelClientData->pInitHandle, CHANNEL_EVENT_TERMINATED, 0, 0);
} }
} }
MessageQueue_PostQuit(channels->queue, 0); MessageQueue_PostQuit(channels->queue, 0);
} }
static UINT VCAPITYPE FreeRDP_VirtualChannelInitEx(LPVOID lpUserParam, LPVOID pInitHandle, static UINT VCAPITYPE FreeRDP_VirtualChannelInitEx(LPVOID lpUserParam, LPVOID clientContext,
PCHANNEL_DEF pChannel, INT channelCount, ULONG versionRequested, PCHANNEL_INIT_EVENT_EX_FN pChannelInitEventProcEx) LPVOID pInitHandle,
PCHANNEL_DEF pChannel, INT channelCount, ULONG versionRequested,
PCHANNEL_INIT_EVENT_EX_FN pChannelInitEventProcEx)
{ {
INT index; INT index;
void* pInterface;
DWORD OpenHandle;
CHANNEL_DEF* channel; CHANNEL_DEF* channel;
rdpSettings* settings; rdpSettings* settings;
PCHANNEL_DEF pChannelDef; PCHANNEL_DEF pChannelDef;
@ -558,11 +559,9 @@ static UINT VCAPITYPE FreeRDP_VirtualChannelInitEx(LPVOID lpUserParam, LPVOID pI
if (!pChannel || (channelCount <= 0) || !pChannelInitEventProcEx) if (!pChannel || (channelCount <= 0) || !pChannelInitEventProcEx)
return CHANNEL_RC_INITIALIZATION_ERROR; return CHANNEL_RC_INITIALIZATION_ERROR;
pInterface = g_pInterface;
pChannelInitData = (CHANNEL_INIT_DATA*) pInitHandle; pChannelInitData = (CHANNEL_INIT_DATA*) pInitHandle;
channels = pChannelInitData->channels; channels = pChannelInitData->channels;
pChannelInitData->pInterface = pInterface; pChannelInitData->pInterface = clientContext;
if (!channels->can_call_init) if (!channels->can_call_init)
return CHANNEL_RC_NOT_IN_VIRTUALCHANNELENTRY; return CHANNEL_RC_NOT_IN_VIRTUALCHANNELENTRY;
@ -601,12 +600,10 @@ static UINT VCAPITYPE FreeRDP_VirtualChannelInitEx(LPVOID lpUserParam, LPVOID pI
{ {
pChannelDef = &pChannel[index]; pChannelDef = &pChannel[index];
pChannelOpenData = &channels->openDataList[channels->openDataCount]; pChannelOpenData = &channels->openDataList[channels->openDataCount];
OpenHandle = g_OpenHandleSeq++; pChannelOpenData->OpenHandle = ++channels->openHandleSequence;
pChannelOpenData->OpenHandle = OpenHandle;
pChannelOpenData->channels = channels; pChannelOpenData->channels = channels;
pChannelOpenData->lpUserParam = lpUserParam; pChannelOpenData->lpUserParam = lpUserParam;
freerdp_channel_add_open_handle_data(&g_ChannelHandles, OpenHandle, (void*) channels); HashTable_Add(channels->openHandles, (void*)(UINT_PTR) pChannelOpenData->OpenHandle,
HashTable_Add(channels->openHandles, (void*)(UINT_PTR) OpenHandle,
(void*) pChannelOpenData); (void*) pChannelOpenData);
pChannelOpenData->flags = 1; /* init */ pChannelOpenData->flags = 1; /* init */
strncpy(pChannelOpenData->name, pChannelDef->name, CHANNEL_NAME_LEN); strncpy(pChannelOpenData->name, pChannelDef->name, CHANNEL_NAME_LEN);
@ -717,13 +714,12 @@ static UINT VCAPITYPE FreeRDP_VirtualChannelInit(LPVOID* ppInitHandle,
} }
static UINT VCAPITYPE FreeRDP_VirtualChannelOpenEx(LPVOID pInitHandle, static UINT VCAPITYPE FreeRDP_VirtualChannelOpenEx(LPVOID pInitHandle,
LPDWORD pOpenHandle, PCHAR pChannelName, PCHANNEL_OPEN_EVENT_EX_FN pChannelOpenEventProcEx) LPDWORD pOpenHandle, PCHAR pChannelName, PCHANNEL_OPEN_EVENT_EX_FN pChannelOpenEventProcEx)
{ {
void* pInterface; void* pInterface;
rdpChannels* channels; rdpChannels* channels;
CHANNEL_INIT_DATA* pChannelInitData; CHANNEL_INIT_DATA* pChannelInitData;
CHANNEL_OPEN_DATA* pChannelOpenData; CHANNEL_OPEN_DATA* pChannelOpenData;
pChannelInitData = (CHANNEL_INIT_DATA*) pInitHandle; pChannelInitData = (CHANNEL_INIT_DATA*) pInitHandle;
channels = pChannelInitData->channels; channels = pChannelInitData->channels;
pInterface = pChannelInitData->pInterface; pInterface = pChannelInitData->pInterface;
@ -749,7 +745,6 @@ static UINT VCAPITYPE FreeRDP_VirtualChannelOpenEx(LPVOID pInitHandle,
pChannelOpenData->pInterface = pInterface; pChannelOpenData->pInterface = pInterface;
pChannelOpenData->pChannelOpenEventProcEx = pChannelOpenEventProcEx; pChannelOpenData->pChannelOpenEventProcEx = pChannelOpenEventProcEx;
*pOpenHandle = pChannelOpenData->OpenHandle; *pOpenHandle = pChannelOpenData->OpenHandle;
return CHANNEL_RC_OK; return CHANNEL_RC_OK;
} }
@ -760,7 +755,6 @@ static UINT VCAPITYPE FreeRDP_VirtualChannelOpen(LPVOID pInitHandle,
rdpChannels* channels; rdpChannels* channels;
CHANNEL_INIT_DATA* pChannelInitData; CHANNEL_INIT_DATA* pChannelInitData;
CHANNEL_OPEN_DATA* pChannelOpenData; CHANNEL_OPEN_DATA* pChannelOpenData;
pChannelInitData = (CHANNEL_INIT_DATA*) pInitHandle; pChannelInitData = (CHANNEL_INIT_DATA*) pInitHandle;
channels = pChannelInitData->channels; channels = pChannelInitData->channels;
pInterface = pChannelInitData->pInterface; pInterface = pChannelInitData->pInterface;
@ -786,7 +780,6 @@ static UINT VCAPITYPE FreeRDP_VirtualChannelOpen(LPVOID pInitHandle,
pChannelOpenData->pInterface = pInterface; pChannelOpenData->pInterface = pInterface;
pChannelOpenData->pChannelOpenEventProc = pChannelOpenEventProc; pChannelOpenData->pChannelOpenEventProc = pChannelOpenEventProc;
*pOpenHandle = pChannelOpenData->OpenHandle; *pOpenHandle = pChannelOpenData->OpenHandle;
return CHANNEL_RC_OK; return CHANNEL_RC_OK;
} }
@ -814,7 +807,6 @@ static UINT VCAPITYPE FreeRDP_VirtualChannelCloseEx(LPVOID pInitHandle, DWORD op
return CHANNEL_RC_NOT_OPEN; return CHANNEL_RC_NOT_OPEN;
pChannelOpenData->flags = 0; pChannelOpenData->flags = 0;
return CHANNEL_RC_OK; return CHANNEL_RC_OK;
} }
@ -822,7 +814,6 @@ static UINT VCAPITYPE FreeRDP_VirtualChannelClose(DWORD openHandle)
{ {
rdpChannels* channels; rdpChannels* channels;
CHANNEL_OPEN_DATA* pChannelOpenData; CHANNEL_OPEN_DATA* pChannelOpenData;
channels = (rdpChannels*) freerdp_channel_get_open_handle_data(&g_ChannelHandles, openHandle); channels = (rdpChannels*) freerdp_channel_get_open_handle_data(&g_ChannelHandles, openHandle);
if (!channels) if (!channels)
@ -837,12 +828,11 @@ static UINT VCAPITYPE FreeRDP_VirtualChannelClose(DWORD openHandle)
return CHANNEL_RC_NOT_OPEN; return CHANNEL_RC_NOT_OPEN;
pChannelOpenData->flags = 0; pChannelOpenData->flags = 0;
return CHANNEL_RC_OK; return CHANNEL_RC_OK;
} }
static UINT VCAPITYPE FreeRDP_VirtualChannelWriteEx(LPVOID pInitHandle, DWORD openHandle, static UINT VCAPITYPE FreeRDP_VirtualChannelWriteEx(LPVOID pInitHandle, DWORD openHandle,
LPVOID pData, ULONG dataLength, LPVOID pUserData) LPVOID pData, ULONG dataLength, LPVOID pUserData)
{ {
rdpChannels* channels = NULL; rdpChannels* channels = NULL;
CHANNEL_INIT_DATA* pChannelInitData = NULL; CHANNEL_INIT_DATA* pChannelInitData = NULL;
@ -899,7 +889,8 @@ static UINT VCAPITYPE FreeRDP_VirtualChannelWrite(DWORD openHandle,
{ {
CHANNEL_OPEN_DATA* pChannelOpenData; CHANNEL_OPEN_DATA* pChannelOpenData;
CHANNEL_OPEN_EVENT* pChannelOpenEvent; CHANNEL_OPEN_EVENT* pChannelOpenEvent;
rdpChannels* channels = (rdpChannels*) freerdp_channel_get_open_handle_data(&g_ChannelHandles, openHandle); rdpChannels* channels = (rdpChannels*) freerdp_channel_get_open_handle_data(&g_ChannelHandles,
openHandle);
if (!channels) if (!channels)
return CHANNEL_RC_BAD_CHANNEL_HANDLE; return CHANNEL_RC_BAD_CHANNEL_HANDLE;
@ -1022,7 +1013,7 @@ int freerdp_channels_client_load(rdpChannels* channels, rdpSettings* settings,
} }
int freerdp_channels_client_load_ex(rdpChannels* channels, rdpSettings* settings, int freerdp_channels_client_load_ex(rdpChannels* channels, rdpSettings* settings,
PVIRTUALCHANNELENTRYEX entryEx, void* data) PVIRTUALCHANNELENTRYEX entryEx, void* data)
{ {
int status; int status;
void* pInitHandle = NULL; void* pInitHandle = NULL;
@ -1044,11 +1035,9 @@ int freerdp_channels_client_load_ex(rdpChannels* channels, rdpSettings* settings
pChannelClientData = &channels->clientDataList[channels->clientDataCount]; pChannelClientData = &channels->clientDataList[channels->clientDataCount];
pChannelClientData->entryEx = entryEx; pChannelClientData->entryEx = entryEx;
pChannelInitData = &(channels->initDataList[channels->initDataCount++]); pChannelInitData = &(channels->initDataList[channels->initDataCount++]);
pInitHandle = pChannelInitData; pInitHandle = pChannelInitData;
pChannelInitData->channels = channels; pChannelInitData->channels = channels;
ZeroMemory(&EntryPointsEx, sizeof(CHANNEL_ENTRY_POINTS_FREERDP_EX)); ZeroMemory(&EntryPointsEx, sizeof(CHANNEL_ENTRY_POINTS_FREERDP_EX));
EntryPointsEx.cbSize = sizeof(EntryPointsEx); EntryPointsEx.cbSize = sizeof(EntryPointsEx);
EntryPointsEx.protocolVersion = VIRTUAL_CHANNEL_VERSION_WIN2000; EntryPointsEx.protocolVersion = VIRTUAL_CHANNEL_VERSION_WIN2000;
@ -1057,13 +1046,11 @@ int freerdp_channels_client_load_ex(rdpChannels* channels, rdpSettings* settings
EntryPointsEx.pVirtualChannelCloseEx = FreeRDP_VirtualChannelCloseEx; EntryPointsEx.pVirtualChannelCloseEx = FreeRDP_VirtualChannelCloseEx;
EntryPointsEx.pVirtualChannelWriteEx = FreeRDP_VirtualChannelWriteEx; EntryPointsEx.pVirtualChannelWriteEx = FreeRDP_VirtualChannelWriteEx;
EntryPointsEx.MagicNumber = FREERDP_CHANNEL_MAGIC_NUMBER; EntryPointsEx.MagicNumber = FREERDP_CHANNEL_MAGIC_NUMBER;
EntryPointsEx.ppInterface = &g_pInterface;
EntryPointsEx.pExtendedData = data; EntryPointsEx.pExtendedData = data;
EntryPointsEx.context = ((freerdp*) settings->instance)->context; EntryPointsEx.context = ((freerdp*) settings->instance)->context;
/* enable VirtualChannelInit */ /* enable VirtualChannelInit */
channels->can_call_init = TRUE; channels->can_call_init = TRUE;
EnterCriticalSection(&channels->channelsLock); EnterCriticalSection(&channels->channelsLock);
g_pInterface = NULL;
status = pChannelClientData->entryEx((PCHANNEL_ENTRY_POINTS_EX) &EntryPointsEx, pInitHandle); status = pChannelClientData->entryEx((PCHANNEL_ENTRY_POINTS_EX) &EntryPointsEx, pInitHandle);
LeaveCriticalSection(&channels->channelsLock); LeaveCriticalSection(&channels->channelsLock);
/* disable MyVirtualChannelInit */ /* disable MyVirtualChannelInit */
@ -1082,10 +1069,10 @@ int freerdp_channels_client_load_ex(rdpChannels* channels, rdpSettings* settings
* this is called when processing the command line parameters * this is called when processing the command line parameters
* called only from main thread * called only from main thread
*/ */
int freerdp_channels_load_plugin(rdpChannels* channels, rdpSettings* settings, const char* name, void* data) int freerdp_channels_load_plugin(rdpChannels* channels, rdpSettings* settings, const char* name,
void* data)
{ {
PVIRTUALCHANNELENTRY entry; PVIRTUALCHANNELENTRY entry;
entry = freerdp_load_channel_addin_entry(name, NULL, NULL, FREERDP_ADDIN_CHANNEL_STATIC); entry = freerdp_load_channel_addin_entry(name, NULL, NULL, FREERDP_ADDIN_CHANNEL_STATIC);
if (!entry) if (!entry)

View File

@ -110,6 +110,8 @@ struct rdp_channels
DrdynvcClientContext* drdynvc; DrdynvcClientContext* drdynvc;
CRITICAL_SECTION channelsLock; CRITICAL_SECTION channelsLock;
int openHandleSequence;
wHashTable* openHandles; wHashTable* openHandles;
}; };

View File

@ -179,7 +179,7 @@ typedef UINT VCAPITYPE VIRTUALCHANNELINIT(LPVOID* ppInitHandle,
typedef VIRTUALCHANNELINIT* PVIRTUALCHANNELINIT; typedef VIRTUALCHANNELINIT* PVIRTUALCHANNELINIT;
typedef UINT VCAPITYPE VIRTUALCHANNELINITEX(LPVOID lpUserParam, typedef UINT VCAPITYPE VIRTUALCHANNELINITEX(LPVOID lpUserParam, LPVOID clientContext,
LPVOID pInitHandle, PCHANNEL_DEF pChannel, LPVOID pInitHandle, PCHANNEL_DEF pChannel,
INT channelCount, ULONG versionRequested, INT channelCount, ULONG versionRequested,
PCHANNEL_INIT_EVENT_EX_FN pChannelInitEventProcEx); PCHANNEL_INIT_EVENT_EX_FN pChannelInitEventProcEx);