channels/remdesk: initial dummy server-side remote assistance message parsing
authorMarc-André Moreau <marcandre.moreau@gmail.com>
Tue, 15 Jul 2014 22:38:32 +0000 (18:38 -0400)
committerMarc-André Moreau <marcandre.moreau@gmail.com>
Tue, 15 Jul 2014 22:38:32 +0000 (18:38 -0400)
channels/remdesk/client/remdesk_main.c
channels/remdesk/server/remdesk_main.c
channels/remdesk/server/remdesk_main.h
include/freerdp/channels/remdesk.h
server/shadow/shadow_client.c
server/shadow/shadow_remdesk.c

index 8527b59..66b7ed1 100644 (file)
@@ -98,7 +98,7 @@ int remdesk_generate_expert_blob(remdeskPlugin* remdesk)
        return 1;
 }
 
-int remdesk_read_channel_header(wStream* s, REMDESK_CHANNEL_HEADER* header)
+static int remdesk_read_channel_header(wStream* s, REMDESK_CHANNEL_HEADER* header)
 {
        int status;
        UINT32 ChannelNameLen;
@@ -133,7 +133,7 @@ int remdesk_read_channel_header(wStream* s, REMDESK_CHANNEL_HEADER* header)
        return 1;
 }
 
-int remdesk_write_channel_header(wStream* s, REMDESK_CHANNEL_HEADER* header)
+static int remdesk_write_channel_header(wStream* s, REMDESK_CHANNEL_HEADER* header)
 {
        int index;
        UINT32 ChannelNameLen;
@@ -156,14 +156,14 @@ int remdesk_write_channel_header(wStream* s, REMDESK_CHANNEL_HEADER* header)
        return 1;
 }
 
-int remdesk_write_ctl_header(wStream* s, REMDESK_CTL_HEADER* ctlHeader)
+static int remdesk_write_ctl_header(wStream* s, REMDESK_CTL_HEADER* ctlHeader)
 {
        remdesk_write_channel_header(s, (REMDESK_CHANNEL_HEADER*) ctlHeader);
        Stream_Write_UINT32(s, ctlHeader->msgType); /* msgType (4 bytes) */
        return 1;
 }
 
-int remdesk_prepare_ctl_header(REMDESK_CTL_HEADER* ctlHeader, UINT32 msgType, UINT32 msgSize)
+static int remdesk_prepare_ctl_header(REMDESK_CTL_HEADER* ctlHeader, UINT32 msgType, UINT32 msgSize)
 {
        ctlHeader->msgType = msgType;
        strcpy(ctlHeader->ChannelName, REMDESK_CHANNEL_CTL_NAME);
@@ -171,12 +171,12 @@ int remdesk_prepare_ctl_header(REMDESK_CTL_HEADER* ctlHeader, UINT32 msgType, UI
        return 1;
 }
 
-int remdesk_recv_ctl_server_announce_pdu(remdeskPlugin* remdesk, wStream* s, REMDESK_CHANNEL_HEADER* header)
+static int remdesk_recv_ctl_server_announce_pdu(remdeskPlugin* remdesk, wStream* s, REMDESK_CHANNEL_HEADER* header)
 {
        return 1;
 }
 
-int remdesk_recv_ctl_version_info_pdu(remdeskPlugin* remdesk, wStream* s, REMDESK_CHANNEL_HEADER* header)
+static int remdesk_recv_ctl_version_info_pdu(remdeskPlugin* remdesk, wStream* s, REMDESK_CHANNEL_HEADER* header)
 {
        UINT32 versionMajor;
        UINT32 versionMinor;
@@ -190,7 +190,7 @@ int remdesk_recv_ctl_version_info_pdu(remdeskPlugin* remdesk, wStream* s, REMDES
        return 1;
 }
 
-int remdesk_send_ctl_version_info_pdu(remdeskPlugin* remdesk)
+static int remdesk_send_ctl_version_info_pdu(remdeskPlugin* remdesk)
 {
        wStream* s;
        REMDESK_CTL_VERSION_INFO_PDU pdu;
@@ -214,7 +214,7 @@ int remdesk_send_ctl_version_info_pdu(remdeskPlugin* remdesk)
        return 1;
 }
 
-int remdesk_recv_result_pdu(remdeskPlugin* remdesk, wStream* s, REMDESK_CHANNEL_HEADER* header, UINT32 *pResult)
+static int remdesk_recv_ctl_result_pdu(remdeskPlugin* remdesk, wStream* s, REMDESK_CHANNEL_HEADER* header, UINT32 *pResult)
 {
        UINT32 result;
 
@@ -230,7 +230,7 @@ int remdesk_recv_result_pdu(remdeskPlugin* remdesk, wStream* s, REMDESK_CHANNEL_
        return 1;
 }
 
-int remdesk_send_ctl_authenticate_pdu(remdeskPlugin* remdesk)
+static int remdesk_send_ctl_authenticate_pdu(remdeskPlugin* remdesk)
 {
        int status;
        wStream* s;
@@ -282,7 +282,7 @@ int remdesk_send_ctl_authenticate_pdu(remdeskPlugin* remdesk)
        return 1;
 }
 
-int remdesk_send_ctl_remote_control_desktop_pdu(remdeskPlugin* remdesk)
+static int remdesk_send_ctl_remote_control_desktop_pdu(remdeskPlugin* remdesk)
 {
        int status;
        wStream* s;
@@ -316,7 +316,7 @@ int remdesk_send_ctl_remote_control_desktop_pdu(remdeskPlugin* remdesk)
        return 1;
 }
 
-int remdesk_send_ctl_verify_password_pdu(remdeskPlugin* remdesk)
+static int remdesk_send_ctl_verify_password_pdu(remdeskPlugin* remdesk)
 {
        int status;
        wStream* s;
@@ -355,7 +355,7 @@ int remdesk_send_ctl_verify_password_pdu(remdeskPlugin* remdesk)
        return 1;
 }
 
-int remdesk_send_ctl_expert_on_vista_pdu(remdeskPlugin* remdesk)
+static int remdesk_send_ctl_expert_on_vista_pdu(remdeskPlugin* remdesk)
 {
        int status;
        wStream* s;
@@ -385,7 +385,7 @@ int remdesk_send_ctl_expert_on_vista_pdu(remdeskPlugin* remdesk)
        return 1;
 }
 
-int remdesk_recv_ctl_pdu(remdeskPlugin* remdesk, wStream* s, REMDESK_CHANNEL_HEADER* header)
+static int remdesk_recv_ctl_pdu(remdeskPlugin* remdesk, wStream* s, REMDESK_CHANNEL_HEADER* header)
 {
        int status = 1;
        UINT32 msgType = 0;
@@ -404,7 +404,7 @@ int remdesk_recv_ctl_pdu(remdeskPlugin* remdesk, wStream* s, REMDESK_CHANNEL_HEA
                        break;
 
                case REMDESK_CTL_RESULT:
-                       status = remdesk_recv_result_pdu(remdesk, s, header, &result);
+                       status = remdesk_recv_ctl_result_pdu(remdesk, s, header, &result);
                        break;
 
                case REMDESK_CTL_AUTHENTICATE:
@@ -469,7 +469,7 @@ int remdesk_recv_ctl_pdu(remdeskPlugin* remdesk, wStream* s, REMDESK_CHANNEL_HEA
        return status;
 }
 
-int remdesk_process_receive(remdeskPlugin* remdesk, wStream* s)
+static int remdesk_process_receive(remdeskPlugin* remdesk, wStream* s)
 {
        int status = 1;
        REMDESK_CHANNEL_HEADER header;
index 3cd00ad..8c193e0 100644 (file)
 
 #include "remdesk_main.h"
 
+int remdesk_virtual_channel_write(RemdeskServerContext* context, wStream* s)
+{
+       BOOL status;
+       ULONG BytesWritten = 0;
+
+       status = WTSVirtualChannelWrite(context->priv->ChannelHandle,
+                       (PCHAR) Stream_Buffer(s), Stream_Length(s), &BytesWritten);
+
+       return (status) ? 1 : -1;
+}
+
+static int remdesk_read_channel_header(wStream* s, REMDESK_CHANNEL_HEADER* header)
+{
+       int status;
+       UINT32 ChannelNameLen;
+       char* pChannelName = NULL;
+
+       if (Stream_GetRemainingLength(s) < 8)
+               return -1;
+
+       Stream_Read_UINT32(s, ChannelNameLen); /* ChannelNameLen (4 bytes) */
+       Stream_Read_UINT32(s, header->DataLength); /* DataLen (4 bytes) */
+
+       if (ChannelNameLen > 64)
+               return -1;
+
+       if ((ChannelNameLen % 2) != 0)
+               return -1;
+
+       if (Stream_GetRemainingLength(s) < ChannelNameLen)
+               return -1;
+
+       ZeroMemory(header->ChannelName, sizeof(header->ChannelName));
+
+       pChannelName = (char*) header->ChannelName;
+       status = ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) Stream_Pointer(s),
+                       ChannelNameLen / 2, &pChannelName, 32, NULL, NULL);
+
+       Stream_Seek(s, ChannelNameLen);
+
+       if (status <= 0)
+               return -1;
+
+       return 1;
+}
+
+static int remdesk_write_channel_header(wStream* s, REMDESK_CHANNEL_HEADER* header)
+{
+       int index;
+       UINT32 ChannelNameLen;
+       WCHAR ChannelNameW[32];
+
+       ZeroMemory(ChannelNameW, sizeof(ChannelNameW));
+
+       for (index = 0; index < 32; index++)
+       {
+               ChannelNameW[index] = (WCHAR) header->ChannelName[index];
+       }
+
+       ChannelNameLen = (strlen(header->ChannelName) + 1) * 2;
+
+       Stream_Write_UINT32(s, ChannelNameLen); /* ChannelNameLen (4 bytes) */
+       Stream_Write_UINT32(s, header->DataLength); /* DataLen (4 bytes) */
+
+       Stream_Write(s, ChannelNameW, ChannelNameLen); /* ChannelName (variable) */
+
+       return 1;
+}
+
+static int remdesk_write_ctl_header(wStream* s, REMDESK_CTL_HEADER* ctlHeader)
+{
+       remdesk_write_channel_header(s, (REMDESK_CHANNEL_HEADER*) ctlHeader);
+       Stream_Write_UINT32(s, ctlHeader->msgType); /* msgType (4 bytes) */
+       return 1;
+}
+
+static int remdesk_prepare_ctl_header(REMDESK_CTL_HEADER* ctlHeader, UINT32 msgType, UINT32 msgSize)
+{
+       ctlHeader->msgType = msgType;
+       strcpy(ctlHeader->ChannelName, REMDESK_CHANNEL_CTL_NAME);
+       ctlHeader->DataLength = 4 + msgSize;
+       return 1;
+}
+
+static int remdesk_send_ctl_result_pdu(RemdeskServerContext* context, UINT32 result)
+{
+       wStream* s;
+       REMDESK_CTL_RESULT_PDU pdu;
+
+       pdu.result = result;
+
+       remdesk_prepare_ctl_header(&(pdu.ctlHeader), REMDESK_CTL_RESULT, 4);
+
+       s = Stream_New(NULL, REMDESK_CHANNEL_CTL_SIZE + pdu.ctlHeader.DataLength);
+
+       remdesk_write_ctl_header(s, &(pdu.ctlHeader));
+
+       Stream_Write_UINT32(s, pdu.result); /* result (4 bytes) */
+
+       Stream_SealLength(s);
+
+       remdesk_virtual_channel_write(context, s);
+
+       Stream_Free(s, TRUE);
+
+       return 1;
+}
+
+static int remdesk_send_ctl_version_info_pdu(RemdeskServerContext* context)
+{
+       wStream* s;
+       REMDESK_CTL_VERSION_INFO_PDU pdu;
+
+       remdesk_prepare_ctl_header(&(pdu.ctlHeader), REMDESK_CTL_VERSIONINFO, 8);
+
+       pdu.versionMajor = 1;
+       pdu.versionMinor = 2;
+
+       s = Stream_New(NULL, REMDESK_CHANNEL_CTL_SIZE + pdu.ctlHeader.DataLength);
+
+       remdesk_write_ctl_header(s, &(pdu.ctlHeader));
+
+       Stream_Write_UINT32(s, pdu.versionMajor); /* versionMajor (4 bytes) */
+       Stream_Write_UINT32(s, pdu.versionMinor); /* versionMinor (4 bytes) */
+
+       Stream_SealLength(s);
+
+       remdesk_virtual_channel_write(context, s);
+
+       return 1;
+}
+
+static int remdesk_recv_ctl_version_info_pdu(RemdeskServerContext* context, wStream* s, REMDESK_CHANNEL_HEADER* header)
+{
+       UINT32 versionMajor;
+       UINT32 versionMinor;
+
+       if (Stream_GetRemainingLength(s) < 8)
+               return -1;
+
+       Stream_Read_UINT32(s, versionMajor); /* versionMajor (4 bytes) */
+       Stream_Read_UINT32(s, versionMinor); /* versionMinor (4 bytes) */
+
+       return 1;
+}
+
+static int remdesk_recv_ctl_remote_control_desktop_pdu(RemdeskServerContext* context, wStream* s, REMDESK_CHANNEL_HEADER* header)
+{
+       int status;
+       int cchStringW;
+       WCHAR* pStringW;
+       UINT32 msgLength;
+       int cbRaConnectionStringW = 0;
+       WCHAR* raConnectionStringW = NULL;
+       REMDESK_CTL_REMOTE_CONTROL_DESKTOP_PDU pdu;
+
+       msgLength = header->DataLength - 4;
+
+       pStringW = (WCHAR*) Stream_Pointer(s);
+       raConnectionStringW = pStringW;
+       cchStringW = 0;
+
+       while ((msgLength > 0) && pStringW[cchStringW])
+       {
+               msgLength -= 2;
+               cchStringW++;
+       }
+
+       if (pStringW[cchStringW] || !cchStringW)
+               return -1;
+
+       cchStringW++;
+       cbRaConnectionStringW = cchStringW * 2;
+
+       pdu.raConnectionString = NULL;
+
+       status = ConvertFromUnicode(CP_UTF8, 0, raConnectionStringW,
+                       cbRaConnectionStringW / 2, &pdu.raConnectionString, 0, NULL, NULL);
+
+       if (status <= 0)
+               return -1;
+
+       printf("RaConnectionString: %s\n",
+                       pdu.raConnectionString);
+
+       free(pdu.raConnectionString);
+
+       remdesk_send_ctl_result_pdu(context, 0);
+
+       return 1;
+}
+
+static int remdesk_recv_ctl_authenticate_pdu(RemdeskServerContext* context, wStream* s, REMDESK_CHANNEL_HEADER* header)
+{
+       int status;
+       int cchStringW;
+       WCHAR* pStringW;
+       UINT32 msgLength;
+       int cbExpertBlobW = 0;
+       WCHAR* expertBlobW = NULL;
+       int cbRaConnectionStringW = 0;
+       WCHAR* raConnectionStringW = NULL;
+       REMDESK_CTL_AUTHENTICATE_PDU pdu;
+
+       msgLength = header->DataLength - 4;
+
+       pStringW = (WCHAR*) Stream_Pointer(s);
+       raConnectionStringW = pStringW;
+       cchStringW = 0;
+
+       while ((msgLength > 0) && pStringW[cchStringW])
+       {
+               msgLength -= 2;
+               cchStringW++;
+       }
+
+       if (pStringW[cchStringW] || !cchStringW)
+               return -1;
+
+       cchStringW++;
+       cbRaConnectionStringW = cchStringW * 2;
+
+       pStringW += cchStringW;
+       expertBlobW = pStringW;
+       cchStringW = 0;
+
+       while ((msgLength > 0) && pStringW[cchStringW])
+       {
+               msgLength -= 2;
+               cchStringW++;
+       }
+
+       if (pStringW[cchStringW] || !cchStringW)
+               return -1;
+
+       cchStringW++;
+       cbExpertBlobW = cchStringW * 2;
+
+       pdu.raConnectionString = NULL;
+
+       status = ConvertFromUnicode(CP_UTF8, 0, raConnectionStringW,
+                       cbRaConnectionStringW / 2, &pdu.raConnectionString, 0, NULL, NULL);
+
+       if (status <= 0)
+               return -1;
+
+       pdu.expertBlob = NULL;
+
+       status = ConvertFromUnicode(CP_UTF8, 0, expertBlobW,
+                       cbExpertBlobW / 2, &pdu.expertBlob, 0, NULL, NULL);
+
+       if (status <= 0)
+               return -1;
+
+       printf("RaConnectionString: %s ExpertBlob: %s\n",
+                       pdu.raConnectionString, pdu.expertBlob);
+
+       free(pdu.raConnectionString);
+       free(pdu.expertBlob);
+
+       return 1;
+}
+
+static int remdesk_recv_ctl_verify_password_pdu(RemdeskServerContext* context, wStream* s, REMDESK_CHANNEL_HEADER* header)
+{
+       int status;
+       int cbExpertBlobW = 0;
+       WCHAR* expertBlobW = NULL;
+       REMDESK_CTL_VERIFY_PASSWORD_PDU pdu;
+
+       if (Stream_GetRemainingLength(s) < 8)
+               return -1;
+
+       pdu.expertBlob = NULL;
+       expertBlobW = (WCHAR*) Stream_Pointer(s);
+       cbExpertBlobW = header->DataLength - 4;
+
+       status = ConvertFromUnicode(CP_UTF8, 0, expertBlobW, cbExpertBlobW / 2, &pdu.expertBlob, 0, NULL, NULL);
+
+       printf("ExpertBlob: %s\n", pdu.expertBlob);
+
+       remdesk_send_ctl_result_pdu(context, 0);
+
+       return 1;
+}
+
+static int remdesk_recv_ctl_pdu(RemdeskServerContext* context, wStream* s, REMDESK_CHANNEL_HEADER* header)
+{
+       int status = 1;
+       UINT32 msgType = 0;
+
+       if (Stream_GetRemainingLength(s) < 4)
+               return -1;
+
+       Stream_Read_UINT32(s, msgType); /* msgType (4 bytes) */
+
+       printf("msgType: %d\n", msgType);
+
+       switch (msgType)
+       {
+               case REMDESK_CTL_REMOTE_CONTROL_DESKTOP:
+                       status = remdesk_recv_ctl_remote_control_desktop_pdu(context, s, header);
+                       break;
+
+               case REMDESK_CTL_AUTHENTICATE:
+                       status = remdesk_recv_ctl_authenticate_pdu(context, s, header);
+                       break;
+
+               case REMDESK_CTL_DISCONNECT:
+                       break;
+
+               case REMDESK_CTL_VERSIONINFO:
+                       status = remdesk_recv_ctl_version_info_pdu(context, s, header);
+                       break;
+
+               case REMDESK_CTL_ISCONNECTED:
+                       break;
+
+               case REMDESK_CTL_VERIFY_PASSWORD:
+                       status = remdesk_recv_ctl_verify_password_pdu(context, s, header);
+                       break;
+
+               case REMDESK_CTL_EXPERT_ON_VISTA:
+                       break;
+
+               case REMDESK_CTL_RANOVICE_NAME:
+                       break;
+
+               case REMDESK_CTL_RAEXPERT_NAME:
+                       break;
+
+               case REMDESK_CTL_TOKEN:
+                       break;
+
+               default:
+                       fprintf(stderr, "remdesk_recv_control_pdu: unknown msgType: %d\n", msgType);
+                       status = -1;
+                       break;
+       }
+
+       return status;
+}
+
 static int remdesk_server_receive_pdu(RemdeskServerContext* context, wStream* s)
 {
-       return 0;
+       int status = 1;
+       REMDESK_CHANNEL_HEADER header;
+
+#if 0
+       printf("RemdeskReceive: %d\n", Stream_GetRemainingLength(s));
+       winpr_HexDump(Stream_Pointer(s), Stream_GetRemainingLength(s));
+#endif
+
+       remdesk_read_channel_header(s, &header);
+
+       if (strcmp(header.ChannelName, "RC_CTL") == 0)
+       {
+               status = remdesk_recv_ctl_pdu(context, s, &header);
+       }
+       else if (strcmp(header.ChannelName, "70") == 0)
+       {
+
+       }
+       else if (strcmp(header.ChannelName, "71") == 0)
+       {
+
+       }
+       else if (strcmp(header.ChannelName, ".") == 0)
+       {
+
+       }
+       else if (strcmp(header.ChannelName, "1000.") == 0)
+       {
+
+       }
+       else if (strcmp(header.ChannelName, "RA_FX") == 0)
+       {
+
+       }
+       else
+       {
+
+       }
+
+       return 1;
 }
 
 static void* remdesk_server_thread(void* arg)
@@ -38,6 +420,8 @@ static void* remdesk_server_thread(void* arg)
        DWORD status;
        DWORD nCount;
        void* buffer;
+       UINT32* pHeader;
+       UINT32 PduLength;
        HANDLE events[8];
        HANDLE ChannelEvent;
        DWORD BytesReturned;
@@ -63,6 +447,8 @@ static void* remdesk_server_thread(void* arg)
        events[nCount++] = ChannelEvent;
        events[nCount++] = context->priv->StopEvent;
 
+       remdesk_send_ctl_version_info_pdu(context);
+
        while (1)
        {
                status = WaitForMultipleObjects(nCount, events, FALSE, INFINITE);
@@ -83,9 +469,18 @@ static void* remdesk_server_thread(void* arg)
                        Stream_EnsureRemainingCapacity(s, BytesReturned);
                }
 
-               if (0)
+               if (Stream_GetPosition(s) >= 8)
                {
-                       remdesk_server_receive_pdu(context, s);
+                       pHeader = (UINT32*) Stream_Buffer(s);
+                       PduLength = pHeader[0] + pHeader[1] + 8;
+
+                       if (PduLength >= Stream_GetPosition(s))
+                       {
+                               Stream_SealLength(s);
+                               Stream_SetPosition(s, 0);
+                               remdesk_server_receive_pdu(context, s);
+                               Stream_SetPosition(s, 0);
+                       }
                }
        }
 
@@ -106,7 +501,7 @@ static int remdesk_server_start(RemdeskServerContext* context)
        context->priv->Thread = CreateThread(NULL, 0,
                        (LPTHREAD_START_ROUTINE) remdesk_server_thread, (void*) context, 0, NULL);
 
-       return 0;
+       return 1;
 }
 
 static int remdesk_server_stop(RemdeskServerContext* context)
@@ -116,7 +511,7 @@ static int remdesk_server_stop(RemdeskServerContext* context)
        WaitForSingleObject(context->priv->Thread, INFINITE);
        CloseHandle(context->priv->Thread);
 
-       return 0;
+       return 1;
 }
 
 RemdeskServerContext* remdesk_server_context_new(HANDLE vcm)
@@ -136,7 +531,7 @@ RemdeskServerContext* remdesk_server_context_new(HANDLE vcm)
 
                if (context->priv)
                {
-
+                       context->priv->Version = 1;
                }
        }
 
index 42b504c..94184ae 100644 (file)
@@ -31,6 +31,8 @@ struct _remdesk_server_private
        HANDLE Thread;
        HANDLE StopEvent;
        void* ChannelHandle;
+
+       UINT32 Version;
 };
 
 #endif /* FREERDP_CHANNEL_SERVER_REMDESK_MAIN_H */
index a3fa55a..0400bb9 100644 (file)
@@ -57,6 +57,14 @@ typedef struct _REMDESK_CTL_HEADER REMDESK_CTL_HEADER;
 #define REMDESK_CTL_RAEXPERT_NAME                      11
 #define REMDESK_CTL_TOKEN                              12
 
+struct _REMDESK_CTL_RESULT_PDU
+{
+       REMDESK_CTL_HEADER ctlHeader;
+
+       UINT32 result;
+};
+typedef struct _REMDESK_CTL_RESULT_PDU REMDESK_CTL_RESULT_PDU;
+
 struct _REMDESK_CTL_VERSION_INFO_PDU
 {
        REMDESK_CTL_HEADER ctlHeader;
index 743cb5d..7ee3f8d 100644 (file)
@@ -600,6 +600,7 @@ void* shadow_client_thread(rdpShadowClient* client)
        HANDLE events[32];
        HANDLE StopEvent;
        HANDLE ClientEvent;
+       HANDLE ChannelEvent;
        freerdp_peer* peer;
        rdpSettings* settings;
        rdpShadowServer* server;
@@ -633,12 +634,14 @@ void* shadow_client_thread(rdpShadowClient* client)
 
        StopEvent = client->StopEvent;
        ClientEvent = peer->GetEventHandle(peer);
+       ChannelEvent = WTSVirtualChannelManagerGetEventHandle(client->vcm);
 
        while (1)
        {
                nCount = 0;
                events[nCount++] = StopEvent;
                events[nCount++] = ClientEvent;
+               events[nCount++] = ChannelEvent;
 
                cTime = GetTickCount64();
                dwTimeout = (cTime > frameTime) ? 0 : frameTime - cTime;
@@ -659,6 +662,15 @@ void* shadow_client_thread(rdpShadowClient* client)
                        }
                }
 
+               if (WaitForSingleObject(ChannelEvent, 0) == WAIT_OBJECT_0)
+               {
+                       if (WTSVirtualChannelManagerCheckFileDescriptor(client->vcm) != TRUE)
+                       {
+                               fprintf(stderr, "WTSVirtualChannelManagerCheckFileDescriptor failure\n");
+                               break;
+                       }
+               }
+
                if ((status == WAIT_TIMEOUT) || (GetTickCount64() > frameTime))
                {
                        if (client->activated)
index c886813..62af217 100644 (file)
 
 int shadow_client_remdesk_init(rdpShadowClient* client)
 {
-       client->remdesk = remdesk_server_context_new(client->vcm);
+       RemdeskServerContext* remdesk;
+
+       remdesk = client->remdesk = remdesk_server_context_new(client->vcm);
+
+       remdesk->custom = (void*) client;
 
        if (client->remdesk)
                client->remdesk->Start(client->remdesk);