/** * Function description * * @return 0 on success, otherwise a Win32 error code */ UINT rdpei_server_handle_messages(RdpeiServerContext *context) { DWORD bytesReturned; RdpeiServerPrivate *priv = context->priv; wStream *s = priv->inputStream; UINT error = CHANNEL_RC_OK; if (!WTSVirtualChannelRead(priv->channelHandle, 0, (PCHAR)Stream_Pointer(s), priv->expectedBytes, &bytesReturned)) { if (GetLastError() == ERROR_NO_DATA) return ERROR_READ_FAULT; WLog_DBG(TAG, "channel connection closed"); return CHANNEL_RC_OK; } priv->expectedBytes -= bytesReturned; Stream_Seek(s, bytesReturned); if (priv->expectedBytes) return CHANNEL_RC_OK; Stream_SealLength(s); Stream_SetPosition(s, 0); if (priv->waitingHeaders) { UINT32 pduLen; /* header case */ Stream_Read_UINT16(s, priv->currentMsgType); Stream_Read_UINT16(s, pduLen); if (pduLen < RDPINPUT_HEADER_LENGTH) { WLog_ERR(TAG, "invalid pduLength %d", pduLen); return ERROR_INVALID_DATA; } priv->expectedBytes = pduLen - RDPINPUT_HEADER_LENGTH; priv->waitingHeaders = FALSE; Stream_SetPosition(s, 0); if (priv->expectedBytes) { if (!Stream_EnsureCapacity(s, priv->expectedBytes)) { WLog_ERR(TAG, "Stream_EnsureCapacity failed!"); return CHANNEL_RC_NO_MEMORY; } return CHANNEL_RC_OK; } } /* when here we have the header + the body */ switch (priv->currentMsgType) { case EVENTID_CS_READY: if (priv->automataState != STATE_WAITING_CLIENT_READY) { WLog_ERR(TAG, "not expecting a CS_READY packet in this state(%d)", (int)priv->automataState); return ERROR_INVALID_STATE; } if ((error = read_cs_ready_message(context, s))) { WLog_ERR(TAG, "read_cs_ready_message failed with error %lu", error); return error; } break; case EVENTID_TOUCH: if ((error = read_touch_event(context, s))) { WLog_ERR(TAG, "read_touch_event failed with error %lu", error); return error; } break; case EVENTID_DISMISS_HOVERING_CONTACT: if ((error = read_dismiss_hovering_contact(context, s))) { WLog_ERR(TAG, "read_dismiss_hovering_contact failed with error %lu", error); return error; } break; default: WLog_ERR(TAG, "unexpected message type 0x%x", priv->currentMsgType); } Stream_SetPosition(s, 0); priv->waitingHeaders = TRUE; priv->expectedBytes = RDPINPUT_HEADER_LENGTH; return error; }
int rdpei_server_handle_messages(RdpeiServerContext *context) { DWORD bytesReturned; RdpeiServerPrivate *priv = context->priv; wStream *s = priv->inputStream; if (!WTSVirtualChannelRead(priv->channelHandle, 0, (PCHAR)Stream_Pointer(s), priv->expectedBytes, &bytesReturned)) { if (GetLastError() == ERROR_NO_DATA) return -1; fprintf(stderr, "%s: channel connection closed\n", __FUNCTION__); return 0; } priv->expectedBytes -= bytesReturned; Stream_Seek(s, bytesReturned); if (priv->expectedBytes) return 1; Stream_SealLength(s); Stream_SetPosition(s, 0); if (priv->waitingHeaders) { UINT32 pduLen; /* header case */ Stream_Read_UINT16(s, priv->currentMsgType); Stream_Read_UINT16(s, pduLen); if (pduLen < RDPINPUT_HEADER_LENGTH) { fprintf(stderr, "%s: invalid pduLength %d\n", __FUNCTION__, pduLen); return -1; } priv->expectedBytes = pduLen - RDPINPUT_HEADER_LENGTH; priv->waitingHeaders = FALSE; Stream_SetPosition(s, 0); if (priv->expectedBytes) { Stream_EnsureCapacity(s, priv->expectedBytes); return 1; } } /* when here we have the header + the body */ switch (priv->currentMsgType) { case EVENTID_CS_READY: if (priv->automataState != STATE_WAITING_CLIENT_READY) { fprintf(stderr, "%s: not expecting a CS_READY packet in this state(%d)\n", __FUNCTION__, (int)priv->automataState); return 0; } if (read_cs_ready_message(context, s) < 0) return 0; break; case EVENTID_TOUCH: if (read_touch_event(context, s) < 0) { fprintf(stderr, "%s: error in touch event packet\n", __FUNCTION__); return 0; } break; case EVENTID_DISMISS_HOVERING_CONTACT: if (read_dismiss_hovering_contact(context, s) < 0) { fprintf(stderr, "%s: error reading read_dismiss_hovering_contact\n", __FUNCTION__); return 0; } break; default: fprintf(stderr, "%s: unexpected message type 0x%x\n", __FUNCTION__, priv->currentMsgType); } Stream_SetPosition(s, 0); priv->waitingHeaders = TRUE; priv->expectedBytes = RDPINPUT_HEADER_LENGTH; return 1; }