Merge pull request #3708 from akallabeth/termination_fixes

Client channel shutdown fixes
This commit is contained in:
Bernhard Miklautz
2017-01-23 15:47:39 +01:00
committed by GitHub
4 changed files with 125 additions and 89 deletions

View File

@@ -390,6 +390,10 @@ static UINT dvcman_write_channel(IWTSVirtualChannel* pChannel, ULONG cbSize,
{
UINT status;
DVCMAN_CHANNEL* channel = (DVCMAN_CHANNEL*) pChannel;
if (!channel || !channel->dvcman)
return CHANNEL_RC_BAD_CHANNEL;
EnterCriticalSection(&(channel->lock));
status = drdynvc_write_data(channel->dvcman->drdynvc,
channel->channel_id, pBuffer, cbSize);
@@ -405,6 +409,10 @@ static UINT dvcman_write_channel(IWTSVirtualChannel* pChannel, ULONG cbSize,
static UINT dvcman_close_channel_iface(IWTSVirtualChannel* pChannel)
{
DVCMAN_CHANNEL* channel = (DVCMAN_CHANNEL*) pChannel;
if (!channel)
return CHANNEL_RC_BAD_CHANNEL;
WLog_DBG(TAG, "close_channel_iface: id=%"PRIu32"", channel->channel_id);
return CHANNEL_RC_OK;
}
@@ -694,23 +702,26 @@ static UINT drdynvc_send(drdynvcPlugin* drdynvc, wStream* s)
UINT status;
if (!drdynvc)
{
status = CHANNEL_RC_BAD_INIT_HANDLE;
}
status = CHANNEL_RC_BAD_CHANNEL_HANDLE;
else
{
status = drdynvc->channelEntryPoints.pVirtualChannelWriteEx(drdynvc->InitHandle,
drdynvc->OpenHandle, Stream_Buffer(s), (UINT32) Stream_GetPosition(s), s);
}
if (status != CHANNEL_RC_OK)
switch (status)
{
Stream_Free(s, TRUE);
WLog_ERR(TAG, "VirtualChannelWriteEx failed with %s [%08"PRIX32"]", WTSErrorToString(status),
status);
}
case CHANNEL_RC_OK:
case CHANNEL_RC_NOT_CONNECTED:
return CHANNEL_RC_OK;
return status;
default:
Stream_Free(s, TRUE);
WLog_Print(drdynvc->log, WLOG_ERROR, "VirtualChannelWriteEx failed with %s [%08"PRIX32"]",
WTSErrorToString(status),
status);
return status;
}
}
/**
@@ -727,12 +738,17 @@ static UINT drdynvc_write_data(drdynvcPlugin* drdynvc, UINT32 ChannelId,
UINT32 cbLen;
unsigned long chunkLength;
UINT status;
WLog_DBG(TAG, "write_data: ChannelId=%"PRIu32" size=%"PRIu32"", ChannelId, dataSize);
if (!drdynvc)
return CHANNEL_RC_BAD_CHANNEL_HANDLE;
WLog_Print(drdynvc->log, WLOG_DEBUG, "write_data: ChannelId=%"PRIu32" size=%"PRIu32"", ChannelId,
dataSize);
data_out = Stream_New(NULL, CHANNEL_CHUNK_LENGTH);
if (!data_out)
{
WLog_ERR(TAG, "Stream_New failed!");
WLog_Print(drdynvc->log, WLOG_ERROR, "Stream_New failed!");
return CHANNEL_RC_NO_MEMORY;
}
@@ -775,7 +791,7 @@ static UINT drdynvc_write_data(drdynvcPlugin* drdynvc, UINT32 ChannelId,
if (!data_out)
{
WLog_ERR(TAG, "Stream_New failed!");
WLog_Print(drdynvc->log, WLOG_ERROR, "Stream_New failed!");
return CHANNEL_RC_NO_MEMORY;
}
@@ -799,8 +815,8 @@ static UINT drdynvc_write_data(drdynvcPlugin* drdynvc, UINT32 ChannelId,
if (status != CHANNEL_RC_OK)
{
WLog_ERR(TAG, "VirtualChannelWriteEx failed with %s [%08"PRIX32"]",
WTSErrorToString(status), status);
WLog_Print(drdynvc->log, WLOG_ERROR, "VirtualChannelWriteEx failed with %s [%08"PRIX32"]",
WTSErrorToString(status), status);
return status;
}
@@ -816,12 +832,16 @@ static UINT drdynvc_send_capability_response(drdynvcPlugin* drdynvc)
{
UINT status;
wStream* s;
WLog_DBG(TAG, "capability_response");
if (!drdynvc)
return CHANNEL_RC_BAD_CHANNEL_HANDLE;
WLog_Print(drdynvc->log, WLOG_TRACE, "capability_response");
s = Stream_New(NULL, 4);
if (!s)
{
WLog_ERR(TAG, "Stream_Ndrdynvc_write_variable_uintew failed!");
WLog_Print(drdynvc->log, WLOG_ERROR, "Stream_Ndrdynvc_write_variable_uintew failed!");
return CHANNEL_RC_NO_MEMORY;
}
@@ -832,8 +852,8 @@ static UINT drdynvc_send_capability_response(drdynvcPlugin* drdynvc)
if (status != CHANNEL_RC_OK)
{
WLog_ERR(TAG, "VirtualChannelWriteEx failed with %s [%08"PRIX32"]",
WTSErrorToString(status), status);
WLog_Print(drdynvc->log, WLOG_ERROR, "VirtualChannelWriteEx failed with %s [%08"PRIX32"]",
WTSErrorToString(status), status);
}
return status;
@@ -848,7 +868,11 @@ static UINT drdynvc_process_capability_request(drdynvcPlugin* drdynvc, int Sp,
int cbChId, wStream* s)
{
UINT status;
WLog_DBG(TAG, "capability_request Sp=%d cbChId=%d", Sp, cbChId);
if (!drdynvc)
return CHANNEL_RC_BAD_INIT_HANDLE;
WLog_Print(drdynvc->log, WLOG_TRACE, "capability_request Sp=%d cbChId=%d", Sp, cbChId);
Stream_Seek(s, 1); /* pad */
Stream_Read_UINT16(s, drdynvc->version);
@@ -904,6 +928,9 @@ static UINT drdynvc_process_create_request(drdynvcPlugin* drdynvc, int Sp,
wStream* data_out;
UINT channel_status;
if (!drdynvc)
return CHANNEL_RC_BAD_CHANNEL_HANDLE;
if (drdynvc->state == DRDYNVC_STATE_CAPABILITIES)
{
/**
@@ -915,7 +942,7 @@ static UINT drdynvc_process_create_request(drdynvcPlugin* drdynvc, int Sp,
if ((status = drdynvc_send_capability_response(drdynvc)))
{
WLog_ERR(TAG, "drdynvc_send_capability_response failed!");
WLog_Print(drdynvc->log, WLOG_ERROR, "drdynvc_send_capability_response failed!");
return status;
}
@@ -924,15 +951,16 @@ static UINT drdynvc_process_create_request(drdynvcPlugin* drdynvc, int Sp,
ChannelId = drdynvc_read_variable_uint(s, cbChId);
pos = Stream_GetPosition(s);
WLog_DBG(TAG, "process_create_request: ChannelId=%"PRIu32" ChannelName=%s", ChannelId,
Stream_Pointer(s));
WLog_Print(drdynvc->log, WLOG_DEBUG, "process_create_request: ChannelId=%"PRIu32" ChannelName=%s",
ChannelId,
Stream_Pointer(s));
channel_status = dvcman_create_channel(drdynvc->channel_mgr, ChannelId,
(char*) Stream_Pointer(s));
data_out = Stream_New(NULL, pos + 4);
if (!s)
{
WLog_ERR(TAG, "Stream_New failed!");
WLog_Print(drdynvc->log, WLOG_ERROR, "Stream_New failed!");
return CHANNEL_RC_NO_MEMORY;
}
@@ -942,12 +970,12 @@ static UINT drdynvc_process_create_request(drdynvcPlugin* drdynvc, int Sp,
if (channel_status == CHANNEL_RC_OK)
{
WLog_DBG(TAG, "channel created");
WLog_Print(drdynvc->log, WLOG_DEBUG, "channel created");
Stream_Write_UINT32(data_out, 0);
}
else
{
WLog_DBG(TAG, "no listener");
WLog_Print(drdynvc->log, WLOG_DEBUG, "no listener");
Stream_Write_UINT32(data_out,
(UINT32) 0xC0000001); /* same code used by mstsc */
}
@@ -965,14 +993,14 @@ static UINT drdynvc_process_create_request(drdynvcPlugin* drdynvc, int Sp,
{
if ((status = dvcman_open_channel(drdynvc->channel_mgr, ChannelId)))
{
WLog_ERR(TAG, "dvcman_open_channel failed with error %"PRIu32"!", status);
WLog_Print(drdynvc->log, WLOG_ERROR, "dvcman_open_channel failed with error %"PRIu32"!", status);
return status;
}
}
else
{
if ((status = dvcman_close_channel(drdynvc->channel_mgr, ChannelId)))
WLog_ERR(TAG, "dvcman_close_channel failed with error %"PRIu32"!", status);
WLog_Print(drdynvc->log, WLOG_ERROR, "dvcman_close_channel failed with error %"PRIu32"!", status);
}
return status;
@@ -1012,8 +1040,9 @@ static UINT drdynvc_process_data(drdynvcPlugin* drdynvc, int Sp, int cbChId,
{
UINT32 ChannelId;
ChannelId = drdynvc_read_variable_uint(s, cbChId);
WLog_DBG(TAG, "process_data: Sp=%d cbChId=%d, ChannelId=%"PRIu32"", Sp, cbChId,
ChannelId);
WLog_Print(drdynvc->log, WLOG_TRACE, "process_data: Sp=%d cbChId=%d, ChannelId=%"PRIu32"", Sp,
cbChId,
ChannelId);
return dvcman_receive_channel_data(drdynvc->channel_mgr, ChannelId, s);
}
@@ -1074,34 +1103,28 @@ static UINT drdynvc_order_recv(drdynvcPlugin* drdynvc, wStream* s)
Cmd = (value & 0xf0) >> 4;
Sp = (value & 0x0c) >> 2;
cbChId = (value & 0x03) >> 0;
WLog_DBG(TAG, "order_recv: Cmd=0x%x, Sp=%d cbChId=%d", Cmd, Sp, cbChId);
WLog_Print(drdynvc->log, WLOG_DEBUG, "order_recv: Cmd=0x%x, Sp=%d cbChId=%d", Cmd, Sp, cbChId);
switch (Cmd)
{
case CAPABILITY_REQUEST_PDU:
return drdynvc_process_capability_request(drdynvc, Sp, cbChId, s);
break;
case CREATE_REQUEST_PDU:
return drdynvc_process_create_request(drdynvc, Sp, cbChId, s);
break;
case DATA_FIRST_PDU:
return drdynvc_process_data_first(drdynvc, Sp, cbChId, s);
break;
case DATA_PDU:
return drdynvc_process_data(drdynvc, Sp, cbChId, s);
break;
case CLOSE_REQUEST_PDU:
return drdynvc_process_close_request(drdynvc, Sp, cbChId, s);
break;
default:
WLog_ERR(TAG, "unknown drdynvc cmd 0x%x", Cmd);
return ERROR_INTERNAL_ERROR;
break;
}
}
@@ -1206,18 +1229,24 @@ static void* drdynvc_virtual_channel_client_thread(void* arg)
UINT error = CHANNEL_RC_OK;
drdynvcPlugin* drdynvc = (drdynvcPlugin*) arg;
if (!drdynvc)
{
ExitThread((DWORD) CHANNEL_RC_BAD_CHANNEL_HANDLE);
return NULL;
}
while (1)
{
if (!MessageQueue_Wait(drdynvc->queue))
{
WLog_ERR(TAG, "MessageQueue_Wait failed!");
WLog_Print(drdynvc->log, WLOG_ERROR, "MessageQueue_Wait failed!");
error = ERROR_INTERNAL_ERROR;
break;
}
if (!MessageQueue_Peek(drdynvc->queue, &message, TRUE))
{
WLog_ERR(TAG, "MessageQueue_Peek failed!");
WLog_Print(drdynvc->log, WLOG_ERROR, "MessageQueue_Peek failed!");
error = ERROR_INTERNAL_ERROR;
break;
}
@@ -1232,7 +1261,7 @@ static void* drdynvc_virtual_channel_client_thread(void* arg)
if ((error = drdynvc_order_recv(drdynvc, data)))
{
Stream_Free(data, TRUE);
WLog_ERR(TAG, "drdynvc_order_recv failed with error %"PRIu32"!", error);
WLog_Print(drdynvc->log, WLOG_ERROR, "drdynvc_order_recv failed with error %"PRIu32"!", error);
break;
}
@@ -1261,13 +1290,17 @@ static UINT drdynvc_virtual_channel_event_connected(drdynvcPlugin* drdynvc, LPVO
UINT32 index;
ADDIN_ARGV* args;
rdpSettings* settings;
if (!drdynvc)
return CHANNEL_RC_BAD_CHANNEL_HANDLE;
status = drdynvc->channelEntryPoints.pVirtualChannelOpenEx(drdynvc->InitHandle,
&drdynvc->OpenHandle, drdynvc->channelDef.name, drdynvc_virtual_channel_open_event_ex);
if (status != CHANNEL_RC_OK)
{
WLog_ERR(TAG, "pVirtualChannelOpen failed with %s [%08"PRIX32"]",
WTSErrorToString(status), status);
WLog_Print(drdynvc->log, WLOG_ERROR, "pVirtualChannelOpen failed with %s [%08"PRIX32"]",
WTSErrorToString(status), status);
return status;
}
@@ -1276,7 +1309,7 @@ static UINT drdynvc_virtual_channel_event_connected(drdynvcPlugin* drdynvc, LPVO
if (!drdynvc->queue)
{
error = CHANNEL_RC_NO_MEMORY;
WLog_ERR(TAG, "MessageQueue_New failed!");
WLog_Print(drdynvc->log, WLOG_ERROR, "MessageQueue_New failed!");
goto error;
}
@@ -1285,7 +1318,7 @@ static UINT drdynvc_virtual_channel_event_connected(drdynvcPlugin* drdynvc, LPVO
if (!drdynvc->channel_mgr)
{
error = CHANNEL_RC_NO_MEMORY;
WLog_ERR(TAG, "dvcman_new failed!");
WLog_Print(drdynvc->log, WLOG_ERROR, "dvcman_new failed!");
goto error;
}
@@ -1302,7 +1335,7 @@ static UINT drdynvc_virtual_channel_event_connected(drdynvcPlugin* drdynvc, LPVO
if ((error = dvcman_init(drdynvc->channel_mgr)))
{
WLog_ERR(TAG, "dvcman_init failed with error %"PRIu32"!", error);
WLog_Print(drdynvc->log, WLOG_ERROR, "dvcman_init failed with error %"PRIu32"!", error);
goto error;
}
@@ -1313,7 +1346,7 @@ static UINT drdynvc_virtual_channel_event_connected(drdynvcPlugin* drdynvc, LPVO
0, NULL)))
{
error = ERROR_INTERNAL_ERROR;
WLog_ERR(TAG, "CreateThread failed!");
WLog_Print(drdynvc->log, WLOG_ERROR, "CreateThread failed!");
goto error;
}
@@ -1330,11 +1363,20 @@ static UINT drdynvc_virtual_channel_event_disconnected(drdynvcPlugin* drdynvc)
{
UINT status;
if (MessageQueue_PostQuit(drdynvc->queue, 0) &&
(WaitForSingleObject(drdynvc->thread, INFINITE) == WAIT_FAILED))
if (!drdynvc)
return CHANNEL_RC_BAD_CHANNEL_HANDLE;
if (!MessageQueue_PostQuit(drdynvc->queue, 0))
{
status = GetLastError();
WLog_ERR(TAG, "WaitForSingleObject failed with error %"PRIu32"", status);
WLog_Print(drdynvc->log, WLOG_ERROR, "MessageQueue_PostQuit failed with error %"PRIu32"", status);
return status;
}
if (WaitForSingleObject(drdynvc->thread, INFINITE) != WAIT_OBJECT_0)
{
status = GetLastError();
WLog_Print(drdynvc->log, WLOG_ERROR, "WaitForSingleObject failed with error %"PRIu32"", status);
return status;
}
@@ -1347,8 +1389,8 @@ static UINT drdynvc_virtual_channel_event_disconnected(drdynvcPlugin* drdynvc)
if (status != CHANNEL_RC_OK)
{
WLog_ERR(TAG, "pVirtualChannelClose failed with %s [%08"PRIX32"]",
WTSErrorToString(status), status);
WLog_Print(drdynvc->log, WLOG_ERROR, "pVirtualChannelClose failed with %s [%08"PRIX32"]",
WTSErrorToString(status), status);
}
drdynvc->OpenHandle = 0;
@@ -1375,6 +1417,9 @@ static UINT drdynvc_virtual_channel_event_disconnected(drdynvcPlugin* drdynvc)
*/
static UINT drdynvc_virtual_channel_event_terminated(drdynvcPlugin* drdynvc)
{
if (!drdynvc)
return CHANNEL_RC_BAD_CHANNEL_HANDLE;
drdynvc->InitHandle = 0;
free(drdynvc);
return CHANNEL_RC_OK;
@@ -1401,7 +1446,7 @@ static UINT drdynvc_virtual_channel_event_attached(drdynvcPlugin* drdynvc)
if (pPlugin->Attached)
if ((error = pPlugin->Attached(pPlugin)))
{
WLog_ERR(TAG, "Attach failed with error %"PRIu32"!", error);
WLog_Print(drdynvc->log, WLOG_ERROR, "Attach failed with error %"PRIu32"!", error);
return error;
}
}
@@ -1430,7 +1475,7 @@ static UINT drdynvc_virtual_channel_event_detached(drdynvcPlugin* drdynvc)
if (pPlugin->Detached)
if ((error = pPlugin->Detached(pPlugin)))
{
WLog_ERR(TAG, "Detach failed with error %"PRIu32"!", error);
WLog_Print(drdynvc->log, WLOG_ERROR, "Detach failed with error %"PRIu32"!", error);
return error;
}
}
@@ -1454,31 +1499,36 @@ static VOID VCAPITYPE drdynvc_virtual_channel_init_event_ex(LPVOID lpUserParam,
{
case CHANNEL_EVENT_CONNECTED:
if ((error = drdynvc_virtual_channel_event_connected(drdynvc, pData, dataLength)))
WLog_ERR(TAG, "drdynvc_virtual_channel_event_connected failed with error %"PRIu32"", error);
WLog_Print(drdynvc->log, WLOG_ERROR,
"drdynvc_virtual_channel_event_connected failed with error %"PRIu32"", error);
break;
case CHANNEL_EVENT_DISCONNECTED:
if ((error = drdynvc_virtual_channel_event_disconnected(drdynvc)))
WLog_ERR(TAG, "drdynvc_virtual_channel_event_disconnected failed with error %"PRIu32"", error);
WLog_Print(drdynvc->log, WLOG_ERROR,
"drdynvc_virtual_channel_event_disconnected failed with error %"PRIu32"", error);
break;
case CHANNEL_EVENT_TERMINATED:
if ((error = drdynvc_virtual_channel_event_terminated(drdynvc)))
WLog_ERR(TAG, "drdynvc_virtual_channel_event_terminated failed with error %"PRIu32"", error);
WLog_Print(drdynvc->log, WLOG_ERROR,
"drdynvc_virtual_channel_event_terminated failed with error %"PRIu32"", error);
break;
case CHANNEL_EVENT_ATTACHED:
if ((error = drdynvc_virtual_channel_event_attached(drdynvc)))
WLog_ERR(TAG, "drdynvc_virtual_channel_event_attached failed with error %"PRIu32"", error);
WLog_Print(drdynvc->log, WLOG_ERROR,
"drdynvc_virtual_channel_event_attached failed with error %"PRIu32"", error);
break;
case CHANNEL_EVENT_DETACHED:
if ((error = drdynvc_virtual_channel_event_detached(drdynvc)))
WLog_ERR(TAG, "drdynvc_virtual_channel_event_detached failed with error %"PRIu32"", error);
WLog_Print(drdynvc->log, WLOG_ERROR,
"drdynvc_virtual_channel_event_detached failed with error %"PRIu32"", error);
break;
@@ -1554,8 +1604,8 @@ BOOL VCAPITYPE VirtualChannelEntryEx(PCHANNEL_ENTRY_POINTS_EX pEntryPoints, PVOI
if (CHANNEL_RC_OK != rc)
{
WLog_ERR(TAG, "pVirtualChannelInit failed with %s [%08"PRIX32"]",
WTSErrorToString(rc), rc);
WLog_Print(drdynvc->log, WLOG_ERROR, "pVirtualChannelInit failed with %s [%08"PRIX32"]",
WTSErrorToString(rc), rc);
free(drdynvc->context);
free(drdynvc);
return FALSE;

View File

@@ -532,7 +532,7 @@ static UINT rdpgfx_recv_end_frame_pdu(RDPGFX_CHANNEL_CALLBACK* callback,
ack.queueDepth = QUEUE_DEPTH_UNAVAILABLE;
if ((error = rdpgfx_send_frame_acknowledge_pdu(callback, &ack)))
WLog_ERR(TAG, "rdpgfx_send_frame_acknowledge_pdu failed with error %"PRIu32"", error);
WLog_DBG(TAG, "rdpgfx_send_frame_acknowledge_pdu failed with error %"PRIu32"", error);
}
return error;
@@ -578,14 +578,13 @@ static UINT rdpgfx_recv_wire_to_surface_1_pdu(RDPGFX_CHANNEL_CALLBACK* callback,
pdu.bitmapData = Stream_Pointer(s);
Stream_Seek(s, pdu.bitmapDataLength);
WLog_DBG(TAG,
"RecvWireToSurface1Pdu: surfaceId: %"PRIu16" codecId: %s (0x%04"PRIX16") pixelFormat: 0x%02"PRIX8" "
"destRect: left: %"PRIu16" top: %"PRIu16" right: %"PRIu16" bottom: %"PRIu16" bitmapDataLength: %"PRIu32"",
pdu.surfaceId, rdpgfx_get_codec_id_string(pdu.codecId),
pdu.codecId, pdu.pixelFormat,
pdu.destRect.left, pdu.destRect.top,
pdu.destRect.right, pdu.destRect.bottom,
pdu.bitmapDataLength);
"RecvWireToSurface1Pdu: surfaceId: %"PRIu16" codecId: %s (0x%04"PRIX16") pixelFormat: 0x%02"PRIX8" "
"destRect: left: %"PRIu16" top: %"PRIu16" right: %"PRIu16" bottom: %"PRIu16" bitmapDataLength: %"PRIu32"",
pdu.surfaceId, rdpgfx_get_codec_id_string(pdu.codecId),
pdu.codecId, pdu.pixelFormat,
pdu.destRect.left, pdu.destRect.top,
pdu.destRect.right, pdu.destRect.bottom,
pdu.bitmapDataLength);
cmd.surfaceId = pdu.surfaceId;
cmd.codecId = pdu.codecId;
cmd.contextId = 0;

View File

@@ -1442,13 +1442,7 @@ static VOID VCAPITYPE rdpsnd_virtual_channel_init_event_ex(LPVOID lpUserParam, L
break;
case CHANNEL_EVENT_TERMINATED:
if (plugin->thread != NULL)
if ((error = rdpsnd_virtual_channel_event_disconnected(plugin)))
WLog_ERR(TAG,
"rdpsnd_virtual_channel_event_disconnected failed with error %"PRIu32"!", error);
rdpsnd_virtual_channel_event_terminated(plugin);
plugin = NULL;
break;
case CHANNEL_EVENT_ATTACHED:

View File

@@ -34,7 +34,8 @@
static WINPR_TLS void* g_pInterface = NULL;
static WINPR_TLS rdpChannels* g_channels = NULL; /* use only for VirtualChannelInit hack */
static volatile LONG g_OpenHandleSeq = 1; /* use global counter to ensure uniqueness across channel manager instances */
static volatile LONG g_OpenHandleSeq =
1; /* use global counter to ensure uniqueness across channel manager instances */
static WINPR_TLS rdpChannelHandles g_ChannelHandles = { NULL, NULL };
static CHANNEL_OPEN_DATA* freerdp_channels_find_channel_open_data_by_name(
@@ -253,7 +254,6 @@ UINT freerdp_channels_attach(freerdp* instance)
rdpChannels* channels;
CHANNEL_CLIENT_DATA* pChannelClientData;
channels = instance->context->channels;
channels->connected = 1;
hostname = instance->settings->ServerHostname;
hostnameLength = (int) strlen(hostname);
@@ -311,7 +311,6 @@ UINT freerdp_channels_detach(freerdp* instance)
rdpChannels* channels;
CHANNEL_CLIENT_DATA* pChannelClientData;
channels = instance->context->channels;
channels->connected = 1;
hostname = instance->settings->ServerHostname;
hostnameLength = (int) strlen(hostname);
@@ -372,7 +371,7 @@ UINT freerdp_channels_post_connect(rdpChannels* channels, freerdp* instance)
char* hostname;
int hostnameLength;
CHANNEL_CLIENT_DATA* pChannelClientData;
channels->connected = 1;
channels->connected = TRUE;
hostname = instance->settings->ServerHostname;
hostnameLength = (int) strlen(hostname);
@@ -611,19 +610,18 @@ UINT freerdp_channels_disconnect(rdpChannels* channels, freerdp* instance)
{
UINT error = CHANNEL_RC_OK;
int index;
char* name;
CHANNEL_OPEN_DATA* pChannelOpenData;
CHANNEL_CLIENT_DATA* pChannelClientData;
if (!channels->connected)
return 0;
channels->connected = 0;
freerdp_channels_check_fds(channels, instance);
/* tell all libraries we are shutting down */
for (index = 0; index < channels->clientDataCount; index++)
{
char name[9];
ChannelDisconnectedEventArgs e;
pChannelClientData = &channels->clientDataList[index];
@@ -639,24 +637,18 @@ UINT freerdp_channels_disconnect(rdpChannels* channels, freerdp* instance)
}
if (getChannelError(instance->context) != CHANNEL_RC_OK)
goto fail;
continue;
pChannelOpenData = &channels->openDataList[index];
name = (char*) malloc(9);
if (!name)
return -1;
CopyMemory(name, pChannelOpenData->name, 8);
name[8] = '\0';
EventArgsInit(&e, "freerdp");
e.name = name;
e.pInterface = pChannelOpenData->pInterface;
PubSub_OnChannelDisconnected(instance->context->pubSub, instance->context, &e);
free(name);
}
fail:
channels->connected = FALSE;
return error;
}
@@ -837,7 +829,8 @@ static UINT VCAPITYPE FreeRDP_VirtualChannelInit(LPVOID* ppInitHandle,
pChannelOpenData = &channels->openDataList[channels->openDataCount];
pChannelOpenData->OpenHandle = InterlockedIncrement(&g_OpenHandleSeq);
pChannelOpenData->channels = channels;
freerdp_channel_add_open_handle_data(&g_ChannelHandles, pChannelOpenData->OpenHandle, (void*) channels);
freerdp_channel_add_open_handle_data(&g_ChannelHandles, pChannelOpenData->OpenHandle,
(void*) channels);
HashTable_Add(channels->openHandles, (void*)(UINT_PTR) pChannelOpenData->OpenHandle,
(void*) pChannelOpenData);
pChannelOpenData->flags = 1; /* init */