Fixed FreeRDP_WTS* failure handling

This commit is contained in:
akallabeth 2021-09-17 09:27:01 +02:00 committed by akallabeth
parent bc800175d1
commit 3ce622b638

View File

@ -551,6 +551,8 @@ BOOL WTSVirtualChannelManagerCheckFileDescriptorEx(HANDLE hServer, BOOL autoOpen
buffer = (BYTE*)message.wParam; buffer = (BYTE*)message.wParam;
length = (UINT32)(UINT_PTR)message.lParam; length = (UINT32)(UINT_PTR)message.lParam;
WINPR_ASSERT(vcm->client);
WINPR_ASSERT(vcm->client->SendChannelData);
if (!vcm->client->SendChannelData(vcm->client, channelId, buffer, length)) if (!vcm->client->SendChannelData(vcm->client, channelId, buffer, length))
{ {
status = FALSE; status = FALSE;
@ -848,6 +850,8 @@ static void wts_virtual_channel_manager_free_message(void* obj)
} }
} }
static void channel_free(rdpPeerChannel* channel);
HANDLE WINAPI FreeRDP_WTSOpenServerA(LPSTR pServerName) HANDLE WINAPI FreeRDP_WTSOpenServerA(LPSTR pServerName)
{ {
rdpContext* context; rdpContext* context;
@ -901,6 +905,11 @@ HANDLE WINAPI FreeRDP_WTSOpenServerA(LPSTR pServerName)
if (!vcm->dynamicVirtualChannels) if (!vcm->dynamicVirtualChannels)
goto error_dynamicVirtualChannels; goto error_dynamicVirtualChannels;
{
wObject* obj = ArrayList_Object(vcm->dynamicVirtualChannels);
WINPR_ASSERT(obj);
obj->fnObjectFree = channel_free;
}
client->ReceiveChannelData = WTSReceiveChannelData; client->ReceiveChannelData = WTSReceiveChannelData;
hServer = (HANDLE)vcm; hServer = (HANDLE)vcm;
return hServer; return hServer;
@ -927,25 +936,14 @@ HANDLE WINAPI FreeRDP_WTSOpenServerExA(LPSTR pServerName)
VOID WINAPI FreeRDP_WTSCloseServer(HANDLE hServer) VOID WINAPI FreeRDP_WTSCloseServer(HANDLE hServer)
{ {
int index;
int count;
rdpPeerChannel* channel;
WTSVirtualChannelManager* vcm; WTSVirtualChannelManager* vcm;
vcm = (WTSVirtualChannelManager*)hServer; vcm = (WTSVirtualChannelManager*)hServer;
if (vcm) if (vcm && (vcm != INVALID_HANDLE_VALUE))
{ {
HashTable_Remove(g_ServerHandles, (void*)(UINT_PTR)vcm->SessionId); HashTable_Remove(g_ServerHandles, (void*)(UINT_PTR)vcm->SessionId);
ArrayList_Lock(vcm->dynamicVirtualChannels);
count = ArrayList_Count(vcm->dynamicVirtualChannels);
for (index = 0; index < count; index++) ArrayList_Clear(vcm->dynamicVirtualChannels);
{
channel = (rdpPeerChannel*)ArrayList_GetItem(vcm->dynamicVirtualChannels, index);
WTSVirtualChannelClose(channel);
}
ArrayList_Unlock(vcm->dynamicVirtualChannels);
ArrayList_Free(vcm->dynamicVirtualChannels); ArrayList_Free(vcm->dynamicVirtualChannels);
if (vcm->drdynvc_channel) if (vcm->drdynvc_channel)
@ -1110,7 +1108,7 @@ static void peer_channel_queue_free_message(void* obj)
free(msg->context); free(msg->context);
} }
static void channel_free(rdpPeerChannel* channel) void channel_free(rdpPeerChannel* channel)
{ {
if (!channel) if (!channel)
return; return;
@ -1143,6 +1141,7 @@ static rdpPeerChannel* channel_new(WTSVirtualChannelManager* vcm, freerdp_peer*
goto fail; goto fail;
queueCallbacks.fnObjectFree = peer_channel_queue_free_message; queueCallbacks.fnObjectFree = peer_channel_queue_free_message;
channel->queue = MessageQueue_New(&queueCallbacks); channel->queue = MessageQueue_New(&queueCallbacks);
if (!channel->queue) if (!channel->queue)
@ -1287,22 +1286,23 @@ HANDLE WINAPI FreeRDP_WTSVirtualChannelOpenEx(DWORD SessionId, LPSTR pVirtualNam
s = Stream_New(NULL, 64); s = Stream_New(NULL, 64);
if (!s) if (!s)
goto fail; goto fail2;
if (!wts_write_drdynvc_create_request(s, channel->channelId, pVirtualName)) if (!wts_write_drdynvc_create_request(s, channel->channelId, pVirtualName))
goto fail; goto fail2;
if (!WTSVirtualChannelWrite(vcm->drdynvc_channel, (PCHAR)Stream_Buffer(s), if (!WTSVirtualChannelWrite(vcm->drdynvc_channel, (PCHAR)Stream_Buffer(s),
Stream_GetPosition(s), &written)) Stream_GetPosition(s), &written))
goto fail; goto fail2;
Stream_Free(s, TRUE); Stream_Free(s, TRUE);
return channel; return channel;
fail: fail:
Stream_Free(s, TRUE);
if (vcm)
ArrayList_Remove(vcm->dynamicVirtualChannels, channel);
channel_free(channel); channel_free(channel);
fail2:
Stream_Free(s, TRUE);
ArrayList_Remove(vcm->dynamicVirtualChannels, channel);
SetLastError(ERROR_NOT_ENOUGH_MEMORY); SetLastError(ERROR_NOT_ENOUGH_MEMORY);
return NULL; return NULL;
} }