pChannelClientData = &channels->clientDataList[index];
if (pChannelClientData->pChannelInitEventProc)
- pChannelClientData->pChannelInitEventProc(
- pChannelClientData->pInitHandle,
- CHANNEL_EVENT_INITIALIZED, 0, 0);
+ {
+ pChannelClientData->pChannelInitEventProc(pChannelClientData->pInitHandle, CHANNEL_EVENT_INITIALIZED, 0, 0);
+ }
if (CHANNEL_RC_OK != getChannelError(instance->context))
break;
return 1;
}
- pChannelOpenData = freerdp_channels_find_channel_open_data_by_name(channels,
- channel->Name);
+ pChannelOpenData = freerdp_channels_find_channel_open_data_by_name(channels, channel->Name);
if (!pChannelOpenData)
{
pChannelOpenData->pChannelOpenEventProc(pChannelOpenData->OpenHandle,
CHANNEL_EVENT_DATA_RECEIVED, data, dataSize, totalSize, flags);
}
+ else if (pChannelOpenData->pChannelOpenEventProcEx)
+ {
+ pChannelOpenData->pChannelOpenEventProcEx(pChannelOpenData->lpUserParam, pChannelOpenData->OpenHandle,
+ CHANNEL_EVENT_DATA_RECEIVED, data, dataSize, totalSize, flags);
+ }
return 0;
}
break;
pChannelOpenData = item->pChannelOpenData;
- channel = freerdp_channels_find_channel_by_name(instance->context->rdp,
- pChannelOpenData->name);
+ channel = freerdp_channels_find_channel_by_name(instance->context->rdp, pChannelOpenData->name);
if (channel)
instance->SendChannelData(instance, channel->ChannelId, item->Data,
CHANNEL_EVENT_WRITE_COMPLETE, item->UserData, item->DataLength,
item->DataLength, 0);
}
+ else if (pChannelOpenData->pChannelOpenEventProcEx)
+ {
+ pChannelOpenData->pChannelOpenEventProcEx(pChannelOpenData->lpUserParam, pChannelOpenData->OpenHandle,
+ CHANNEL_EVENT_WRITE_COMPLETE, item->UserData, item->DataLength,
+ item->DataLength, 0);
+ }
free(item);
}
pChannelClientData = &channels->clientDataList[index];
if (pChannelClientData->pChannelInitEventProc)
+ {
pChannelClientData->pChannelInitEventProc(
- pChannelClientData->pInitHandle,
- CHANNEL_EVENT_DISCONNECTED, 0, 0);
+ pChannelClientData->pInitHandle, CHANNEL_EVENT_DISCONNECTED, 0, 0);
+ }
if (getChannelError(instance->context) != CHANNEL_RC_OK)
goto fail;
MessageQueue_PostQuit(channels->queue, 0);
}
+static UINT VCAPITYPE FreeRDP_VirtualChannelInitEx(LPVOID lpUserParam, LPVOID pInitHandle,
+ PCHANNEL_DEF pChannel, INT channelCount, ULONG versionRequested, PCHANNEL_INIT_EVENT_EX_FN pChannelInitEventProcEx)
+{
+ INT index;
+ void* pInterface;
+ DWORD OpenHandle;
+ CHANNEL_DEF* channel;
+ rdpSettings* settings;
+ PCHANNEL_DEF pChannelDef;
+ CHANNEL_INIT_DATA* pChannelInitData;
+ CHANNEL_OPEN_DATA* pChannelOpenData;
+ CHANNEL_CLIENT_DATA* pChannelClientData;
+ rdpChannels* channels = (rdpChannels*) pInitHandle;
+
+ if (!pInitHandle)
+ return CHANNEL_RC_BAD_INIT_HANDLE;
+
+ if (!pChannel || (channelCount <= 0) || !pChannelInitEventProcEx)
+ return CHANNEL_RC_INITIALIZATION_ERROR;
+
+ pInterface = g_pInterface;
+
+ pChannelInitData = (CHANNEL_INIT_DATA*) pInitHandle;
+ channels = pChannelInitData->channels;
+ pChannelInitData->pInterface = pInterface;
+
+ if (!channels->can_call_init)
+ return CHANNEL_RC_NOT_IN_VIRTUALCHANNELENTRY;
+
+ if ((channels->openDataCount + channelCount) >= CHANNEL_MAX_COUNT)
+ return CHANNEL_RC_TOO_MANY_CHANNELS;
+
+ if (!pChannel)
+ return CHANNEL_RC_BAD_CHANNEL;
+
+ if (channels->connected)
+ return CHANNEL_RC_ALREADY_CONNECTED;
+
+ if (versionRequested != VIRTUAL_CHANNEL_VERSION_WIN2000)
+ {
+ }
+
+ for (index = 0; index < channelCount; index++)
+ {
+ pChannelDef = &pChannel[index];
+
+ if (freerdp_channels_find_channel_open_data_by_name(channels, pChannelDef->name) != 0)
+ {
+ return CHANNEL_RC_BAD_CHANNEL;
+ }
+ }
+
+ pChannelClientData = &channels->clientDataList[channels->clientDataCount];
+ pChannelClientData->pChannelInitEventProcEx = pChannelInitEventProcEx;
+ pChannelClientData->pInitHandle = pInitHandle;
+ channels->clientDataCount++;
+ settings = channels->instance->context->settings;
+
+ for (index = 0; index < channelCount; index++)
+ {
+ pChannelDef = &pChannel[index];
+ pChannelOpenData = &channels->openDataList[channels->openDataCount];
+ OpenHandle = g_OpenHandleSeq++;
+ pChannelOpenData->OpenHandle = OpenHandle;
+ pChannelOpenData->channels = channels;
+ freerdp_channel_add_open_handle_data(&g_ChannelHandles, OpenHandle, (void*) channels);
+ HashTable_Add(channels->openHandles, (void*)(UINT_PTR) OpenHandle,
+ (void*) pChannelOpenData);
+ pChannelOpenData->flags = 1; /* init */
+ strncpy(pChannelOpenData->name, pChannelDef->name, CHANNEL_NAME_LEN);
+ pChannelOpenData->options = pChannelDef->options;
+
+ if (settings->ChannelCount < CHANNEL_MAX_COUNT)
+ {
+ channel = &settings->ChannelDefArray[settings->ChannelCount];
+ strncpy(channel->name, pChannelDef->name, 7);
+ channel->options = pChannelDef->options;
+ settings->ChannelCount++;
+ }
+
+ channels->openDataCount++;
+ }
+
+ return CHANNEL_RC_OK;
+}
+
static UINT VCAPITYPE FreeRDP_VirtualChannelInit(LPVOID* ppInitHandle,
PCHANNEL_DEF pChannel,
INT channelCount, ULONG versionRequested,
return CHANNEL_RC_OK;
}
+static UINT VCAPITYPE FreeRDP_VirtualChannelOpenEx(LPVOID pInitHandle,
+ LPDWORD pOpenHandle, PCHAR pChannelName, PCHANNEL_OPEN_EVENT_EX_FN pChannelOpenEventProcEx)
+{
+ void* pInterface;
+ rdpChannels* channels;
+ CHANNEL_INIT_DATA* pChannelInitData;
+ CHANNEL_OPEN_DATA* pChannelOpenData;
+
+ pChannelInitData = (CHANNEL_INIT_DATA*) pInitHandle;
+ channels = pChannelInitData->channels;
+ pInterface = pChannelInitData->pInterface;
+
+ if (!pOpenHandle)
+ return CHANNEL_RC_BAD_CHANNEL_HANDLE;
+
+ if (!pChannelOpenEventProcEx)
+ return CHANNEL_RC_BAD_PROC;
+
+ if (!channels->connected)
+ return CHANNEL_RC_NOT_CONNECTED;
+
+ pChannelOpenData = freerdp_channels_find_channel_open_data_by_name(channels, pChannelName);
+
+ if (!pChannelOpenData)
+ return CHANNEL_RC_UNKNOWN_CHANNEL_NAME;
+
+ if (pChannelOpenData->flags == 2)
+ return CHANNEL_RC_ALREADY_OPEN;
+
+ pChannelOpenData->flags = 2; /* open */
+ pChannelOpenData->pInterface = pInterface;
+ pChannelOpenData->pChannelOpenEventProcEx = pChannelOpenEventProcEx;
+ *pOpenHandle = pChannelOpenData->OpenHandle;
+
+ return CHANNEL_RC_OK;
+}
+
static UINT VCAPITYPE FreeRDP_VirtualChannelOpen(LPVOID pInitHandle,
- LPDWORD pOpenHandle,
- PCHAR pChannelName, PCHANNEL_OPEN_EVENT_FN pChannelOpenEventProc)
+ LPDWORD pOpenHandle, PCHAR pChannelName, PCHANNEL_OPEN_EVENT_FN pChannelOpenEventProc)
{
void* pInterface;
rdpChannels* channels;
CHANNEL_INIT_DATA* pChannelInitData;
CHANNEL_OPEN_DATA* pChannelOpenData;
+
pChannelInitData = (CHANNEL_INIT_DATA*) pInitHandle;
channels = pChannelInitData->channels;
pInterface = pChannelInitData->pInterface;
if (!channels->connected)
return CHANNEL_RC_NOT_CONNECTED;
- pChannelOpenData = freerdp_channels_find_channel_open_data_by_name(channels,
- pChannelName);
+ pChannelOpenData = freerdp_channels_find_channel_open_data_by_name(channels, pChannelName);
if (!pChannelOpenData)
return CHANNEL_RC_UNKNOWN_CHANNEL_NAME;
pChannelOpenData->pInterface = pInterface;
pChannelOpenData->pChannelOpenEventProc = pChannelOpenEventProc;
*pOpenHandle = pChannelOpenData->OpenHandle;
+
+ return CHANNEL_RC_OK;
+}
+
+static UINT VCAPITYPE FreeRDP_VirtualChannelCloseEx(LPVOID pInitHandle, DWORD openHandle)
+{
+ rdpChannels* channels = NULL;
+ CHANNEL_INIT_DATA* pChannelInitData = NULL;
+ CHANNEL_OPEN_DATA* pChannelOpenData = NULL;
+
+ if (!pInitHandle)
+ return CHANNEL_RC_BAD_INIT_HANDLE;
+
+ pChannelInitData = (CHANNEL_INIT_DATA*) pInitHandle;
+ channels = pChannelInitData->channels;
+
+ if (!channels)
+ return CHANNEL_RC_BAD_CHANNEL_HANDLE;
+
+ pChannelOpenData = HashTable_GetItemValue(channels->openHandles, (void*)(UINT_PTR) openHandle);
+
+ if (!pChannelOpenData)
+ return CHANNEL_RC_BAD_CHANNEL_HANDLE;
+
+ if (pChannelOpenData->flags != 2)
+ return CHANNEL_RC_NOT_OPEN;
+
+ pChannelOpenData->flags = 0;
+
return CHANNEL_RC_OK;
}
static UINT VCAPITYPE FreeRDP_VirtualChannelClose(DWORD openHandle)
{
+ rdpChannels* channels;
CHANNEL_OPEN_DATA* pChannelOpenData;
- rdpChannels* channels = (rdpChannels*) freerdp_channel_get_open_handle_data(&g_ChannelHandles, openHandle);
+
+ channels = (rdpChannels*) freerdp_channel_get_open_handle_data(&g_ChannelHandles, openHandle);
if (!channels)
return CHANNEL_RC_BAD_CHANNEL_HANDLE;
- pChannelOpenData = HashTable_GetItemValue(channels->openHandles,
- (void*)(UINT_PTR) openHandle);
+ pChannelOpenData = HashTable_GetItemValue(channels->openHandles, (void*)(UINT_PTR) openHandle);
if (!pChannelOpenData)
return CHANNEL_RC_BAD_CHANNEL_HANDLE;
return CHANNEL_RC_NOT_OPEN;
pChannelOpenData->flags = 0;
+
+ return CHANNEL_RC_OK;
+}
+
+static UINT VCAPITYPE FreeRDP_VirtualChannelWriteEx(LPVOID pInitHandle, DWORD openHandle,
+ LPVOID pData, ULONG dataLength, LPVOID pUserData)
+{
+ rdpChannels* channels = NULL;
+ CHANNEL_INIT_DATA* pChannelInitData = NULL;
+ CHANNEL_OPEN_DATA* pChannelOpenData = NULL;
+ CHANNEL_OPEN_EVENT* pChannelOpenEvent = NULL;
+
+ if (!pInitHandle)
+ return CHANNEL_RC_BAD_INIT_HANDLE;
+
+ pChannelInitData = (CHANNEL_INIT_DATA*) pInitHandle;
+ channels = pChannelInitData->channels;
+
+ if (!channels)
+ return CHANNEL_RC_BAD_CHANNEL_HANDLE;
+
+ pChannelOpenData = HashTable_GetItemValue(channels->openHandles, (void*)(UINT_PTR) openHandle);
+
+ if (!pChannelOpenData)
+ return CHANNEL_RC_BAD_CHANNEL_HANDLE;
+
+ if (!channels->connected)
+ return CHANNEL_RC_NOT_CONNECTED;
+
+ if (!pData)
+ return CHANNEL_RC_NULL_DATA;
+
+ if (!dataLength)
+ return CHANNEL_RC_ZERO_LENGTH;
+
+ if (pChannelOpenData->flags != 2)
+ return CHANNEL_RC_NOT_OPEN;
+
+ pChannelOpenEvent = (CHANNEL_OPEN_EVENT*) malloc(sizeof(CHANNEL_OPEN_EVENT));
+
+ if (!pChannelOpenEvent)
+ return CHANNEL_RC_NO_MEMORY;
+
+ pChannelOpenEvent->Data = pData;
+ pChannelOpenEvent->DataLength = dataLength;
+ pChannelOpenEvent->UserData = pUserData;
+ pChannelOpenEvent->pChannelOpenData = pChannelOpenData;
+
+ if (!MessageQueue_Post(channels->queue, (void*) channels, 0, (void*) pChannelOpenEvent, NULL))
+ {
+ free(pChannelOpenEvent);
+ return CHANNEL_RC_NO_MEMORY;
+ }
+
return CHANNEL_RC_OK;
}
static UINT VCAPITYPE FreeRDP_VirtualChannelWrite(DWORD openHandle,
- LPVOID pData,
- ULONG dataLength, LPVOID pUserData)
+ LPVOID pData, ULONG dataLength, LPVOID pUserData)
{
CHANNEL_OPEN_DATA* pChannelOpenData;
CHANNEL_OPEN_EVENT* pChannelOpenEvent;
if (!channels)
return CHANNEL_RC_BAD_CHANNEL_HANDLE;
- pChannelOpenData = HashTable_GetItemValue(channels->openHandles,
- (void*)(UINT_PTR) openHandle);
+ pChannelOpenData = HashTable_GetItemValue(channels->openHandles, (void*)(UINT_PTR) openHandle);
if (!pChannelOpenData)
return CHANNEL_RC_BAD_CHANNEL_HANDLE;
pChannelOpenEvent->UserData = pUserData;
pChannelOpenEvent->pChannelOpenData = pChannelOpenData;
- if (!MessageQueue_Post(channels->queue, (void*) channels, 0,
- (void*) pChannelOpenEvent, NULL))
+ if (!MessageQueue_Post(channels->queue, (void*) channels, 0, (void*) pChannelOpenEvent, NULL))
{
free(pChannelOpenEvent);
return CHANNEL_RC_NO_MEMORY;
return CHANNEL_RC_OK;
}
-static BOOL freerdp_channels_is_loaded(rdpChannels* channels,
- PVIRTUALCHANNELENTRY entry)
+static BOOL freerdp_channels_is_loaded(rdpChannels* channels, PVIRTUALCHANNELENTRY entry)
{
int i;
return FALSE;
}
+static BOOL freerdp_channels_is_loaded_ex(rdpChannels* channels, PVIRTUALCHANNELENTRYEX entryEx)
+{
+ int i;
+
+ for (i = 0; i < channels->clientDataCount; i++)
+ {
+ CHANNEL_CLIENT_DATA* pChannelClientData = &channels->clientDataList[i];
+
+ if (pChannelClientData->entryEx == entryEx)
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
int freerdp_channels_client_load(rdpChannels* channels, rdpSettings* settings,
PVIRTUALCHANNELENTRY entry, void* data)
{
return 0;
}
+int freerdp_channels_client_load_ex(rdpChannels* channels, rdpSettings* settings,
+ PVIRTUALCHANNELENTRYEX entryEx, void* data)
+{
+ int status;
+ void* pInitHandle = NULL;
+ CHANNEL_ENTRY_POINTS_FREERDP_EX EntryPointsEx;
+ CHANNEL_INIT_DATA* pChannelInitData = NULL;
+ CHANNEL_CLIENT_DATA* pChannelClientData = NULL;
+
+ if (channels->clientDataCount + 1 >= CHANNEL_MAX_COUNT)
+ {
+ WLog_ERR(TAG, "error: too many channels");
+ return 1;
+ }
+
+ if (freerdp_channels_is_loaded_ex(channels, entryEx))
+ {
+ WLog_WARN(TAG, "Skipping, channel already loaded");
+ return 0;
+ }
+
+ pChannelClientData = &channels->clientDataList[channels->clientDataCount];
+ pChannelClientData->entryEx = entryEx;
+
+ pChannelInitData = &(channels->initDataList[channels->initDataCount++]);
+ pInitHandle = pChannelInitData;
+ pChannelInitData->channels = channels;
+
+ ZeroMemory(&EntryPointsEx, sizeof(CHANNEL_ENTRY_POINTS_FREERDP_EX));
+ EntryPointsEx.cbSize = sizeof(EntryPointsEx);
+ EntryPointsEx.protocolVersion = VIRTUAL_CHANNEL_VERSION_WIN2000;
+ EntryPointsEx.pVirtualChannelInitEx = FreeRDP_VirtualChannelInitEx;
+ EntryPointsEx.pVirtualChannelOpenEx = FreeRDP_VirtualChannelOpenEx;
+ EntryPointsEx.pVirtualChannelCloseEx = FreeRDP_VirtualChannelCloseEx;
+ EntryPointsEx.pVirtualChannelWriteEx = FreeRDP_VirtualChannelWriteEx;
+ EntryPointsEx.MagicNumber = FREERDP_CHANNEL_MAGIC_NUMBER;
+ EntryPointsEx.ppInterface = &g_pInterface;
+ EntryPointsEx.pExtendedData = data;
+ EntryPointsEx.context = ((freerdp*) settings->instance)->context;
+ /* enable VirtualChannelInit */
+ channels->can_call_init = TRUE;
+ EnterCriticalSection(&channels->channelsLock);
+ g_pInterface = NULL;
+ status = pChannelClientData->entryEx((PCHANNEL_ENTRY_POINTS_EX) &EntryPointsEx, pInitHandle);
+ LeaveCriticalSection(&channels->channelsLock);
+ /* disable MyVirtualChannelInit */
+ channels->can_call_init = FALSE;
+
+ if (!status)
+ {
+ WLog_ERR(TAG, "error: channel export function call failed");
+ return 1;
+ }
+
+ return 0;
+}
+
/**
* this is called when processing the command line parameters
* called only from main thread