static void* tf_debug_channel_thread_func(void* arg) { void* fd; STREAM* s; void* buffer; UINT32 bytes_returned = 0; testPeerContext* context = (testPeerContext*) arg; freerdp_thread* thread = context->debug_channel_thread; if (WTSVirtualChannelQuery(context->debug_channel, WTSVirtualFileHandle, &buffer, &bytes_returned) == TRUE) { fd = *((void**) buffer); WTSFreeMemory(buffer); thread->signals[thread->num_signals++] = CreateFileDescriptorEvent(NULL, TRUE, FALSE, ((int) (long) fd)); } s = stream_new(4096); WTSVirtualChannelWrite(context->debug_channel, (BYTE*) "test1", 5, NULL); while (1) { freerdp_thread_wait(thread); if (freerdp_thread_is_stopped(thread)) break; stream_set_pos(s, 0); if (WTSVirtualChannelRead(context->debug_channel, 0, stream_get_head(s), stream_get_size(s), &bytes_returned) == FALSE) { if (bytes_returned == 0) break; stream_check_size(s, bytes_returned); if (WTSVirtualChannelRead(context->debug_channel, 0, stream_get_head(s), stream_get_size(s), &bytes_returned) == FALSE) { /* should not happen */ break; } } stream_set_pos(s, bytes_returned); printf("got %d bytes\n", bytes_returned); } stream_free(s); freerdp_thread_quit(thread); return 0; }
static void* tf_debug_channel_thread_func(void* arg) { void* fd; wStream* s; void* buffer; DWORD BytesReturned = 0; testPeerContext* context = (testPeerContext*) arg; if (WTSVirtualChannelQuery(context->debug_channel, WTSVirtualFileHandle, &buffer, &BytesReturned) == TRUE) { fd = *((void**) buffer); WTSFreeMemory(buffer); context->event = CreateWaitObjectEvent(NULL, TRUE, FALSE, fd); } s = Stream_New(NULL, 4096); WTSVirtualChannelWrite(context->debug_channel, (PCHAR) "test1", 5, NULL); while (1) { WaitForSingleObject(context->event, INFINITE); if (WaitForSingleObject(context->stopEvent, 0) == WAIT_OBJECT_0) break; Stream_SetPosition(s, 0); if (WTSVirtualChannelRead(context->debug_channel, 0, (PCHAR) Stream_Buffer(s), Stream_Capacity(s), &BytesReturned) == FALSE) { if (BytesReturned == 0) break; Stream_EnsureRemainingCapacity(s, BytesReturned); if (WTSVirtualChannelRead(context->debug_channel, 0, (PCHAR) Stream_Buffer(s), Stream_Capacity(s), &BytesReturned) == FALSE) { /* should not happen */ break; } } Stream_SetPosition(s, BytesReturned); printf("got %lu bytes\n", BytesReturned); } Stream_Free(s, TRUE); return 0; }
static void* tf_debug_channel_thread_func(void* arg) { void* fd; STREAM* s; void* buffer; uint32 bytes_returned = 0; testPeerContext* context = (testPeerContext*) arg; freerdp_thread* thread = context->debug_channel_thread; if (WTSVirtualChannelQuery(context->debug_channel, WTSVirtualFileHandle, &buffer, &bytes_returned) == true) { fd = *((void**)buffer); WTSFreeMemory(buffer); thread->signals[thread->num_signals++] = wait_obj_new_with_fd(fd); } s = stream_new(4096); WTSVirtualChannelWrite(context->debug_channel, (uint8*) "test1", 5, NULL); while (1) { freerdp_thread_wait(thread); if (freerdp_thread_is_stopped(thread)) break; stream_set_pos(s, 0); if (WTSVirtualChannelRead(context->debug_channel, 0, stream_get_head(s), stream_get_size(s), &bytes_returned) == false) { if (bytes_returned == 0) break; stream_check_size(s, bytes_returned); if (WTSVirtualChannelRead(context->debug_channel, 0, stream_get_head(s), stream_get_size(s), &bytes_returned) == false) { /* should not happen */ break; } } stream_set_pos(s, bytes_returned); printf("got %d bytes\n", bytes_returned); } stream_free(s); freerdp_thread_quit(thread); return 0; }
static int xrdpvr_read_from_client(void *channel, STREAM *s, int bytes, int timeout) { unsigned int bytes_read; int total_read; int ok; //printf("xrdpvr_read_from_client:\n"); total_read = 0; while (total_read < bytes) { //printf("xrdpvr_read_from_client: loop\n"); bytes_read = bytes - total_read; ok = WTSVirtualChannelRead(channel, timeout, s->p, bytes_read, &bytes_read); //printf("xrdpvr_read_from_client: loop ok %d\n", ok); if (ok) { //printf("xrdpvr_read_from_client: bytes_read %d\n", bytes_read); total_read += bytes_read; s->p += bytes_read; } } return 0; }
int main() { // Initialize the data for send/receive char* data; char* data1; data = (char*)malloc(DSIZE); data1 = (char*)malloc(DSIZE); memset(data, 0xca, DSIZE); memset(data1, 0, DSIZE); // Open the skel channel in current session void* channel = WTSVirtualChannelOpenEx(WTS_CURRENT_SESSION, "skel", 0); unsigned long written = 0; // Write the data to the channel bool ret = WTSVirtualChannelWrite(channel, data, DSIZE, &written); if (!ret) { long err = GetLastError(); fprintf(stderr, "error 0x%8.8x\n", err); return 1; } ret = WTSVirtualChannelRead(channel, 100, data1, DSIZE, &written); if (!ret) { long err = GetLastError(); fprintf(stderr, "error 0x%8.8x\n", err); return 1; } if (written != DSIZE) { fprintf(stderr, "error read %d\n", written); return 1; } ret = WTSVirtualChannelClose(channel); if (memcmp(data, data1, DSIZE) == 0) { } else { fprintf(stderr, "error data no match\n"); return 1; } fprintf(stderr, "Success!\n"); Sleep(2000); return 0; }
int TestWtsApiExtraVirtualChannel(int argc, char* argv[]) { BOOL bSuccess; ULONG length; ULONG bytesRead; ULONG bytesWritten; BYTE buffer[1024]; HANDLE hVirtualChannel; length = sizeof(buffer); hVirtualChannel = WTSVirtualChannelOpen(WTS_CURRENT_SERVER_HANDLE, WTS_CURRENT_SESSION, "sample"); if (hVirtualChannel == INVALID_HANDLE_VALUE) { printf("WTSVirtualChannelOpen failed: %d\n", (int) GetLastError()); return -1; } printf("WTSVirtualChannelOpen opend"); bytesWritten = 0; bSuccess = WTSVirtualChannelWrite(hVirtualChannel, (PCHAR) buffer, length, &bytesWritten); if (!bSuccess) { printf("WTSVirtualChannelWrite failed: %d\n", (int) GetLastError()); return -1; } printf("WTSVirtualChannelWrite written"); bytesRead = 0; bSuccess = WTSVirtualChannelRead(hVirtualChannel, 5000, (PCHAR) buffer, length, &bytesRead); if (!bSuccess) { printf("WTSVirtualChannelRead failed: %d\n", (int) GetLastError()); return -1; } printf("WTSVirtualChannelRead read"); if (!WTSVirtualChannelClose(hVirtualChannel)) { printf("WTSVirtualChannelClose failed\n"); return -1; } return 0; }
static void* audin_server_thread_func(void* arg) { void* fd; STREAM* s; void* buffer; BYTE MessageId; BOOL ready = FALSE; UINT32 bytes_returned = 0; audin_server* audin = (audin_server*) arg; freerdp_thread* thread = audin->audin_channel_thread; if (WTSVirtualChannelQuery(audin->audin_channel, WTSVirtualFileHandle, &buffer, &bytes_returned) == TRUE) { fd = *((void**)buffer); WTSFreeMemory(buffer); thread->signals[thread->num_signals++] = wait_obj_new_with_fd(fd); } /* Wait for the client to confirm that the Audio Input dynamic channel is ready */ while (1) { freerdp_thread_wait(thread); if (freerdp_thread_is_stopped(thread)) break; if (WTSVirtualChannelQuery(audin->audin_channel, WTSVirtualChannelReady, &buffer, &bytes_returned) == FALSE) break; ready = *((BOOL*)buffer); WTSFreeMemory(buffer); if (ready) break; } s = stream_new(4096); if (ready) { audin_server_send_version(audin, s); } while (ready) { freerdp_thread_wait(thread); if (freerdp_thread_is_stopped(thread)) break; stream_set_pos(s, 0); if (WTSVirtualChannelRead(audin->audin_channel, 0, stream_get_head(s), stream_get_size(s), &bytes_returned) == FALSE) { if (bytes_returned == 0) break; stream_check_size(s, (int) bytes_returned); if (WTSVirtualChannelRead(audin->audin_channel, 0, stream_get_head(s), stream_get_size(s), &bytes_returned) == FALSE) break; } if (bytes_returned < 1) continue; stream_read_BYTE(s, MessageId); bytes_returned--; switch (MessageId) { case MSG_SNDIN_VERSION: if (audin_server_recv_version(audin, s, bytes_returned)) audin_server_send_formats(audin, s); break; case MSG_SNDIN_FORMATS: if (audin_server_recv_formats(audin, s, bytes_returned)) audin_server_send_open(audin, s); break; case MSG_SNDIN_OPEN_REPLY: audin_server_recv_open_reply(audin, s, bytes_returned); break; case MSG_SNDIN_DATA_INCOMING: break; case MSG_SNDIN_DATA: audin_server_recv_data(audin, s, bytes_returned); break; case MSG_SNDIN_FORMATCHANGE: break; default: printf("audin_server_thread_func: unknown MessageId %d\n", MessageId); break; } } stream_free(s); WTSVirtualChannelClose(audin->audin_channel); audin->audin_channel = NULL; freerdp_thread_quit(thread); return NULL; }
static void* echo_server_thread_func(void* arg) { wStream* s; void* buffer; DWORD nCount; HANDLE events[8]; BOOL ready = FALSE; HANDLE ChannelEvent; DWORD BytesReturned = 0; echo_server* echo = (echo_server*) arg; UINT error; DWORD status; if ((error = echo_server_open_channel(echo))) { UINT error2 = 0; WLog_ERR(TAG, "echo_server_open_channel failed with error %lu!", error); IFCALLRET(echo->context.OpenResult, error2, &echo->context, ECHO_SERVER_OPEN_RESULT_NOTSUPPORTED); if (error2) WLog_ERR(TAG, "echo server's OpenResult callback failed with error %lu", error2); goto out; } buffer = NULL; BytesReturned = 0; ChannelEvent = NULL; if (WTSVirtualChannelQuery(echo->echo_channel, WTSVirtualEventHandle, &buffer, &BytesReturned) == TRUE) { if (BytesReturned == sizeof(HANDLE)) CopyMemory(&ChannelEvent, buffer, sizeof(HANDLE)); WTSFreeMemory(buffer); } nCount = 0; events[nCount++] = echo->stopEvent; events[nCount++] = ChannelEvent; /* Wait for the client to confirm that the Graphics Pipeline dynamic channel is ready */ while (1) { status = WaitForMultipleObjects(nCount, events, FALSE, 100); if (status == WAIT_FAILED) { error = GetLastError(); WLog_ERR(TAG, "WaitForMultipleObjects failed with error %lu", error); break; } if (status == WAIT_OBJECT_0) { IFCALLRET(echo->context.OpenResult, error, &echo->context, ECHO_SERVER_OPEN_RESULT_CLOSED); if (error) WLog_ERR(TAG, "OpenResult failed with error %lu!", error); break; } if (WTSVirtualChannelQuery(echo->echo_channel, WTSVirtualChannelReady, &buffer, &BytesReturned) == FALSE) { IFCALLRET(echo->context.OpenResult, error, &echo->context, ECHO_SERVER_OPEN_RESULT_ERROR); if (error) WLog_ERR(TAG, "OpenResult failed with error %lu!", error); break; } ready = *((BOOL*) buffer); WTSFreeMemory(buffer); if (ready) { IFCALLRET(echo->context.OpenResult, error, &echo->context, ECHO_SERVER_OPEN_RESULT_OK); if (error) WLog_ERR(TAG, "OpenResult failed with error %lu!", error); break; } } s = Stream_New(NULL, 4096); if (!s) { WLog_ERR(TAG, "Stream_New failed!"); WTSVirtualChannelClose(echo->echo_channel); ExitThread((DWORD)ERROR_NOT_ENOUGH_MEMORY); return NULL; } while (ready) { status = WaitForMultipleObjects(nCount, events, FALSE, INFINITE); if (status == WAIT_FAILED) { error = GetLastError(); WLog_ERR(TAG, "WaitForMultipleObjects failed with error %lu", error); break; } if (status == WAIT_OBJECT_0) break; Stream_SetPosition(s, 0); WTSVirtualChannelRead(echo->echo_channel, 0, NULL, 0, &BytesReturned); if (BytesReturned < 1) continue; if (!Stream_EnsureRemainingCapacity(s, BytesReturned)) { WLog_ERR(TAG, "Stream_EnsureRemainingCapacity failed!"); error = CHANNEL_RC_NO_MEMORY; break; } if (WTSVirtualChannelRead(echo->echo_channel, 0, (PCHAR) Stream_Buffer(s), (ULONG) Stream_Capacity(s), &BytesReturned) == FALSE) { WLog_ERR(TAG, "WTSVirtualChannelRead failed!"); error = ERROR_INTERNAL_ERROR; break; } IFCALLRET(echo->context.Response, error, &echo->context, (BYTE*) Stream_Buffer(s), BytesReturned); if (error) { WLog_ERR(TAG, "Response failed with error %lu!", error); break; } } Stream_Free(s, TRUE); WTSVirtualChannelClose(echo->echo_channel); echo->echo_channel = NULL; out: if (error && echo->context.rdpcontext) setChannelError(echo->context.rdpcontext, error, "echo_server_thread_func reported an error"); ExitThread((DWORD)error); return NULL; }
/* * Handle rpdgfx messages - server side * * @param Server side context * * @return 0 on success * ERROR_NO_DATA if no data could be read this time * otherwise a Win32 error code */ UINT rdpgfx_server_handle_messages(RdpgfxServerContext* context) { DWORD BytesReturned; void* buffer; UINT ret = CHANNEL_RC_OK; RdpgfxServerPrivate* priv = context->priv; wStream* s = priv->input_stream; /* Check whether the dynamic channel is ready */ if (!priv->isReady) { if (WTSVirtualChannelQuery(priv->rdpgfx_channel, WTSVirtualChannelReady, &buffer, &BytesReturned) == FALSE) { if (GetLastError() == ERROR_NO_DATA) return ERROR_NO_DATA; WLog_ERR(TAG, "WTSVirtualChannelQuery failed"); return ERROR_INTERNAL_ERROR; } priv->isReady = *((BOOL*) buffer); WTSFreeMemory(buffer); } /* Consume channel event only after the gfx dynamic channel is ready */ if (priv->isReady) { Stream_SetPosition(s, 0); if (!WTSVirtualChannelRead(priv->rdpgfx_channel, 0, NULL, 0, &BytesReturned)) { if (GetLastError() == ERROR_NO_DATA) return ERROR_NO_DATA; WLog_ERR(TAG, "WTSVirtualChannelRead failed!"); return ERROR_INTERNAL_ERROR; } if (BytesReturned < 1) return CHANNEL_RC_OK; if (!Stream_EnsureRemainingCapacity(s, BytesReturned)) { WLog_ERR(TAG, "Stream_EnsureRemainingCapacity failed!"); return CHANNEL_RC_NO_MEMORY; } if (WTSVirtualChannelRead(priv->rdpgfx_channel, 0, (PCHAR) Stream_Buffer(s), Stream_Capacity(s), &BytesReturned) == FALSE) { WLog_ERR(TAG, "WTSVirtualChannelRead failed!"); return ERROR_INTERNAL_ERROR; } Stream_SetLength(s, BytesReturned); Stream_SetPosition(s, 0); while (((size_t) Stream_GetPosition(s)) < Stream_Length(s)) { if ((ret = rdpgfx_server_receive_pdu(context, s))) { WLog_ERR(TAG, "rdpgfx_server_receive_pdu " "failed with error %u!", ret); return ret; } } } return ret; }
static void* rdpsnd_server_thread(void* arg) { wStream* s; DWORD status; DWORD nCount; void* buffer; BYTE msgType; UINT16 BodySize; HANDLE events[8]; HANDLE ChannelEvent; DWORD BytesReturned; RdpsndServerContext* context; BOOL doRun; context = (RdpsndServerContext *)arg; buffer = NULL; BytesReturned = 0; ChannelEvent = NULL; s = Stream_New(NULL, 4096); if (!s) return NULL; if (WTSVirtualChannelQuery(context->priv->ChannelHandle, WTSVirtualEventHandle, &buffer, &BytesReturned)) { if (BytesReturned == sizeof(HANDLE)) CopyMemory(&ChannelEvent, buffer, sizeof(HANDLE)); WTSFreeMemory(buffer); } nCount = 0; if (ChannelEvent) events[nCount++] = ChannelEvent; events[nCount++] = context->priv->StopEvent; if (!rdpsnd_server_send_formats(context, s)) goto out; doRun = TRUE; while (doRun) { status = WaitForMultipleObjects(nCount, events, FALSE, INFINITE); if (WaitForSingleObject(context->priv->StopEvent, 0) == WAIT_OBJECT_0) break; Stream_SetPosition(s, 0); if (!WTSVirtualChannelRead(context->priv->ChannelHandle, 0, (PCHAR)Stream_Buffer(s), Stream_Capacity(s), &BytesReturned)) { if (!BytesReturned) break; Stream_EnsureRemainingCapacity(s, BytesReturned); if (!WTSVirtualChannelRead(context->priv->ChannelHandle, 0, (PCHAR)Stream_Buffer(s), Stream_Capacity(s), &BytesReturned)) break; } if (Stream_GetRemainingLength(s) < 4) break; Stream_Read_UINT8(s, msgType); Stream_Seek_UINT8(s); /* bPad */ Stream_Read_UINT16(s, BodySize); if (Stream_GetRemainingLength(s) < BodySize) break; switch (msgType) { case SNDC_WAVECONFIRM: doRun = rdpsnd_server_recv_waveconfirm(context, s); break; case SNDC_QUALITYMODE: doRun = rdpsnd_server_recv_quality_mode(context, s); break; case SNDC_FORMATS: doRun = rdpsnd_server_recv_formats(context, s); if (doRun) { IFCALL(context->Activated, context); } break; default: fprintf(stderr, "%s: UNKOWN MESSAGE TYPE!! (%#0X)\n\n", __FUNCTION__, msgType); break; } } out: Stream_Free(s, TRUE); return NULL; }
static void* remdesk_server_thread(void* arg) { wStream* s; DWORD status; DWORD nCount; void* buffer; UINT32* pHeader; UINT32 PduLength; HANDLE events[8]; HANDLE ChannelEvent; DWORD BytesReturned; RemdeskServerContext* context; UINT error; context = (RemdeskServerContext*) arg; buffer = NULL; BytesReturned = 0; ChannelEvent = NULL; s = Stream_New(NULL, 4096); if (!s) { WLog_ERR(TAG, "Stream_New failed!"); error = CHANNEL_RC_NO_MEMORY; goto out; } if (WTSVirtualChannelQuery(context->priv->ChannelHandle, WTSVirtualEventHandle, &buffer, &BytesReturned) == TRUE) { if (BytesReturned == sizeof(HANDLE)) CopyMemory(&ChannelEvent, buffer, sizeof(HANDLE)); WTSFreeMemory(buffer); } else { WLog_ERR(TAG, "WTSVirtualChannelQuery failed!"); error = ERROR_INTERNAL_ERROR; goto out; } nCount = 0; events[nCount++] = ChannelEvent; events[nCount++] = context->priv->StopEvent; if ((error = remdesk_send_ctl_version_info_pdu(context))) { WLog_ERR(TAG, "remdesk_send_ctl_version_info_pdu failed with error %"PRIu32"!", error); goto out; } while (1) { status = WaitForMultipleObjects(nCount, events, FALSE, INFINITE); if (status == WAIT_FAILED) { error = GetLastError(); WLog_ERR(TAG, "WaitForMultipleObjects failed with error %"PRIu32"", error); break; } status = WaitForSingleObject(context->priv->StopEvent, 0); if (status == WAIT_FAILED) { error = GetLastError(); WLog_ERR(TAG, "WaitForSingleObject failed with error %"PRIu32"", error); break; } if (status == WAIT_OBJECT_0) { break; } if (WTSVirtualChannelRead(context->priv->ChannelHandle, 0, (PCHAR) Stream_Buffer(s), Stream_Capacity(s), &BytesReturned)) { if (BytesReturned) Stream_Seek(s, BytesReturned); } else { if (!Stream_EnsureRemainingCapacity(s, BytesReturned)) { WLog_ERR(TAG, "Stream_EnsureRemainingCapacity failed!"); error = CHANNEL_RC_NO_MEMORY; break; } } if (Stream_GetPosition(s) >= 8) { pHeader = (UINT32*) Stream_Buffer(s); PduLength = pHeader[0] + pHeader[1] + 8; if (PduLength >= Stream_GetPosition(s)) { Stream_SealLength(s); Stream_SetPosition(s, 0); if ((error = remdesk_server_receive_pdu(context, s))) { WLog_ERR(TAG, "remdesk_server_receive_pdu failed with error %"PRIu32"!", error); break; } Stream_SetPosition(s, 0); } } } Stream_Free(s, TRUE); out: if (error && context->rdpcontext) setChannelError(context->rdpcontext, error, "remdesk_server_thread reported an error"); ExitThread((DWORD)error); return NULL; }
static void* rdpdr_server_thread(void* arg) { wStream* s; DWORD status; DWORD nCount; void* buffer; int position; HANDLE events[8]; RDPDR_HEADER header; HANDLE ChannelEvent; DWORD BytesReturned; RdpdrServerContext* context; context = (RdpdrServerContext*) arg; buffer = NULL; BytesReturned = 0; ChannelEvent = NULL; s = Stream_New(NULL, 4096); if (WTSVirtualChannelQuery(context->priv->ChannelHandle, WTSVirtualEventHandle, &buffer, &BytesReturned) == TRUE) { if (BytesReturned == sizeof(HANDLE)) CopyMemory(&ChannelEvent, buffer, sizeof(HANDLE)); WTSFreeMemory(buffer); } nCount = 0; events[nCount++] = ChannelEvent; events[nCount++] = context->priv->StopEvent; rdpdr_server_send_announce_request(context); while (1) { BytesReturned = 0; status = WaitForMultipleObjects(nCount, events, FALSE, INFINITE); if (WaitForSingleObject(context->priv->StopEvent, 0) == WAIT_OBJECT_0) { break; } WTSVirtualChannelRead(context->priv->ChannelHandle, 0, NULL, 0, &BytesReturned); if (BytesReturned < 1) continue; Stream_EnsureRemainingCapacity(s, BytesReturned); if (!WTSVirtualChannelRead(context->priv->ChannelHandle, 0, (PCHAR) Stream_Buffer(s), Stream_Capacity(s), &BytesReturned)) { break; } if (Stream_GetPosition(s) >= RDPDR_HEADER_LENGTH) { position = Stream_GetPosition(s); Stream_SetPosition(s, 0); Stream_Read_UINT16(s, header.Component); /* Component (2 bytes) */ Stream_Read_UINT16(s, header.PacketId); /* PacketId (2 bytes) */ Stream_SetPosition(s, position); Stream_SealLength(s); Stream_SetPosition(s, RDPDR_HEADER_LENGTH); rdpdr_server_receive_pdu(context, s, &header); Stream_SetPosition(s, 0); } } Stream_Free(s, TRUE); return NULL; }
/** * Function description * * @return 0 on success, otherwise a Win32 error code */ UINT cliprdr_server_read(CliprdrServerContext* context) { wStream* s; int position; DWORD BytesToRead; DWORD BytesReturned; CLIPRDR_HEADER header; CliprdrServerPrivate* cliprdr = (CliprdrServerPrivate*) context->handle; UINT error; DWORD status; s = cliprdr->s; if (Stream_GetPosition(s) < CLIPRDR_HEADER_LENGTH) { BytesReturned = 0; BytesToRead = CLIPRDR_HEADER_LENGTH - Stream_GetPosition(s); status = WaitForSingleObject(cliprdr->ChannelEvent, 0); if (status == WAIT_FAILED) { error = GetLastError(); WLog_ERR(TAG, "WaitForSingleObject failed with error %lu", error); return error; } if (status == WAIT_TIMEOUT) return CHANNEL_RC_OK; if (!WTSVirtualChannelRead(cliprdr->ChannelHandle, 0, (PCHAR) Stream_Pointer(s), BytesToRead, &BytesReturned)) { WLog_ERR(TAG, "WTSVirtualChannelRead failed!"); return ERROR_INTERNAL_ERROR; } Stream_Seek(s, BytesReturned); } if (Stream_GetPosition(s) >= CLIPRDR_HEADER_LENGTH) { position = Stream_GetPosition(s); Stream_SetPosition(s, 0); Stream_Read_UINT16(s, header.msgType); /* msgType (2 bytes) */ Stream_Read_UINT16(s, header.msgFlags); /* msgFlags (2 bytes) */ Stream_Read_UINT32(s, header.dataLen); /* dataLen (4 bytes) */ if (!Stream_EnsureCapacity(s, (header.dataLen + CLIPRDR_HEADER_LENGTH))) { WLog_ERR(TAG, "Stream_EnsureCapacity failed!"); return CHANNEL_RC_NO_MEMORY; } Stream_SetPosition(s, position); if (Stream_GetPosition(s) < (header.dataLen + CLIPRDR_HEADER_LENGTH)) { BytesReturned = 0; BytesToRead = (header.dataLen + CLIPRDR_HEADER_LENGTH) - Stream_GetPosition(s); status = WaitForSingleObject(cliprdr->ChannelEvent, 0); if (status == WAIT_FAILED) { error = GetLastError(); WLog_ERR(TAG, "WaitForSingleObject failed with error %lu", error); return error; } if (status == WAIT_TIMEOUT) return CHANNEL_RC_OK; if (!WTSVirtualChannelRead(cliprdr->ChannelHandle, 0, (PCHAR) Stream_Pointer(s), BytesToRead, &BytesReturned)) { WLog_ERR(TAG, "WTSVirtualChannelRead failed!"); return ERROR_INTERNAL_ERROR; } Stream_Seek(s, BytesReturned); } if (Stream_GetPosition(s) >= (header.dataLen + CLIPRDR_HEADER_LENGTH)) { Stream_SetPosition(s, (header.dataLen + CLIPRDR_HEADER_LENGTH)); Stream_SealLength(s); Stream_SetPosition(s, CLIPRDR_HEADER_LENGTH); if ((error = cliprdr_server_receive_pdu(context, s, &header))) { WLog_ERR(TAG, "cliprdr_server_receive_pdu failed with error code %lu!", error); return error; } Stream_SetPosition(s, 0); /* check for trailing zero bytes */ status = WaitForSingleObject(cliprdr->ChannelEvent, 0); if (status == WAIT_FAILED) { error = GetLastError(); WLog_ERR(TAG, "WaitForSingleObject failed with error %lu", error); return error; } if (status == WAIT_TIMEOUT) return CHANNEL_RC_OK; BytesReturned = 0; BytesToRead = 4; if (!WTSVirtualChannelRead(cliprdr->ChannelHandle, 0, (PCHAR) Stream_Pointer(s), BytesToRead, &BytesReturned)) { WLog_ERR(TAG, "WTSVirtualChannelRead failed!"); return ERROR_INTERNAL_ERROR; } if (BytesReturned == 4) { Stream_Read_UINT16(s, header.msgType); /* msgType (2 bytes) */ Stream_Read_UINT16(s, header.msgFlags); /* msgFlags (2 bytes) */ if (!header.msgType) { /* ignore trailing bytes */ Stream_SetPosition(s, 0); } } else { Stream_Seek(s, BytesReturned); } } } return CHANNEL_RC_OK; }
static void* audin_server_thread_func(void* arg) { wStream* s; void* buffer; DWORD nCount; BYTE MessageId; HANDLE events[8]; BOOL ready = FALSE; HANDLE ChannelEvent; DWORD BytesReturned = 0; audin_server* audin = (audin_server*) arg; buffer = NULL; BytesReturned = 0; ChannelEvent = NULL; if (WTSVirtualChannelQuery(audin->audin_channel, WTSVirtualEventHandle, &buffer, &BytesReturned) == TRUE) { if (BytesReturned == sizeof(HANDLE)) CopyMemory(&ChannelEvent, buffer, sizeof(HANDLE)); WTSFreeMemory(buffer); } nCount = 0; events[nCount++] = audin->stopEvent; events[nCount++] = ChannelEvent; /* Wait for the client to confirm that the Audio Input dynamic channel is ready */ while (1) { if (WaitForMultipleObjects(nCount, events, FALSE, 100) == WAIT_OBJECT_0) break; if (WTSVirtualChannelQuery(audin->audin_channel, WTSVirtualChannelReady, &buffer, &BytesReturned) == FALSE) break; ready = *((BOOL*) buffer); WTSFreeMemory(buffer); if (ready) break; } s = Stream_New(NULL, 4096); if (!s) goto out; if (ready) { audin_server_send_version(audin, s); } while (ready) { if (WaitForMultipleObjects(nCount, events, FALSE, INFINITE) == WAIT_OBJECT_0) break; Stream_SetPosition(s, 0); if (WTSVirtualChannelRead(audin->audin_channel, 0, (PCHAR) Stream_Buffer(s), Stream_Capacity(s), &BytesReturned) == FALSE) { if (BytesReturned == 0) break; Stream_EnsureRemainingCapacity(s, BytesReturned); if (WTSVirtualChannelRead(audin->audin_channel, 0, (PCHAR) Stream_Buffer(s), Stream_Capacity(s), &BytesReturned) == FALSE) { break; } } if (BytesReturned < 1) continue; Stream_Read_UINT8(s, MessageId); BytesReturned--; switch (MessageId) { case MSG_SNDIN_VERSION: if (audin_server_recv_version(audin, s, BytesReturned)) audin_server_send_formats(audin, s); break; case MSG_SNDIN_FORMATS: if (audin_server_recv_formats(audin, s, BytesReturned)) audin_server_send_open(audin, s); break; case MSG_SNDIN_OPEN_REPLY: audin_server_recv_open_reply(audin, s, BytesReturned); break; case MSG_SNDIN_DATA_INCOMING: break; case MSG_SNDIN_DATA: audin_server_recv_data(audin, s, BytesReturned); break; case MSG_SNDIN_FORMATCHANGE: break; default: fprintf(stderr, "audin_server_thread_func: unknown MessageId %d\n", MessageId); break; } } Stream_Free(s, TRUE); out: WTSVirtualChannelClose(audin->audin_channel); audin->audin_channel = NULL; return NULL; }
int _tmain(int argc, _TCHAR* argv[]) { HANDLE hChannel = NULL; PingPayload payload = { 0 }; ULONG bytesRead=0, bytesWritten=0; UINT32 currentSequenceNo = 0; hChannel = WTSVirtualChannelOpen(WTS_CURRENT_SERVER_HANDLE, -1, "JDECHO"); if (hChannel == NULL) { Log("Unable to open virtual channel: %i\r\n", GetLastError()); Log("Are you running inside a remote desktop session?"); goto End; } while (true) { // Send the ping packet across the virtual channel payload.SequenceNo = currentSequenceNo++; payload.TimeStamp = GetTickCount(); if (!WTSVirtualChannelWrite(hChannel, (PCHAR)&payload, sizeof(payload), &bytesWritten)) { Log("WTSVirtualChannelWrite failed: %i\t\n", GetLastError()); goto End; } if (bytesWritten != sizeof(payload)) { Log("Error: Partial writes are not handled"); goto End; } // Wait for the echo channel to send the same packet back if (!WTSVirtualChannelRead(hChannel, INFINITE, (PCHAR)&payload, sizeof(payload), &bytesRead)) { Log("WTSVirtualChannelRead failed: %i", GetLastError()); goto End; } if (bytesRead != sizeof(payload)) { Log("Error partial reads are not handled"); goto End; } // Print statistics Log("Got ping reply: %i, %ims", (int)payload.SequenceNo, (int)(GetTickCount()-payload.TimeStamp)); // Wait for a second before pinging again Sleep(1000); } End: if (hChannel != NULL) { WTSVirtualChannelClose(hChannel); } }
BOOL rdpsnd_server_handle_messages(RdpsndServerContext *context) { DWORD bytesReturned; BOOL ret; RdpsndServerPrivate *priv = context->priv; wStream *s = priv->input_stream; if (!WTSVirtualChannelRead(priv->ChannelHandle, 0, (PCHAR)Stream_Pointer(s), priv->expectedBytes, &bytesReturned)) { if (GetLastError() == ERROR_NO_DATA) return TRUE; CLOG_ERR( "%s: channel connection closed\n", __FUNCTION__); return FALSE; } priv->expectedBytes -= bytesReturned; Stream_Seek(s, bytesReturned); if (priv->expectedBytes) return TRUE; Stream_SetPosition(s, 0); if (priv->waitingHeader) { /* header case */ Stream_Read_UINT8(s, priv->msgType); Stream_Seek_UINT8(s); /* bPad */ Stream_Read_UINT16(s, priv->expectedBytes); priv->waitingHeader = FALSE; Stream_SetPosition(s, 0); if (priv->expectedBytes) { Stream_EnsureCapacity(s, priv->expectedBytes); return TRUE; } } /* when here we have the header + the body */ #ifdef WITH_DEBUG_SND CLOG_ERR( "%s: message type %d\n", __FUNCTION__, priv->msgType); #endif priv->expectedBytes = 4; priv->waitingHeader = TRUE; switch (priv->msgType) { case SNDC_WAVECONFIRM: ret = rdpsnd_server_recv_waveconfirm(context, s); break; case SNDC_FORMATS: ret = rdpsnd_server_recv_formats(context, s); break; case SNDC_QUALITYMODE: ret = rdpsnd_server_recv_quality_mode(context, s); Stream_SetPosition(s, 0); /* in case the Activated callback tries to treat some messages */ if (ret) { IFCALL(context->Activated, context); } break; default: CLOG_ERR( "%s: UNKOWN MESSAGE TYPE!! (%#0X)\n\n", __FUNCTION__, priv->msgType); ret = FALSE; break; } Stream_SetPosition(s, 0); return ret; }
/** * 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; }
static void* encomsp_server_thread(void* arg) { wStream* s; DWORD nCount; void* buffer; HANDLE events[8]; HANDLE ChannelEvent; DWORD BytesReturned; ENCOMSP_ORDER_HEADER* header; EncomspServerContext* context; UINT error = CHANNEL_RC_OK; DWORD status; context = (EncomspServerContext*) arg; buffer = NULL; BytesReturned = 0; ChannelEvent = NULL; s = Stream_New(NULL, 4096); if (!s) { WLog_ERR(TAG, "Stream_New failed!"); error = CHANNEL_RC_NO_MEMORY; goto out; } if (WTSVirtualChannelQuery(context->priv->ChannelHandle, WTSVirtualEventHandle, &buffer, &BytesReturned) == TRUE) { if (BytesReturned == sizeof(HANDLE)) CopyMemory(&ChannelEvent, buffer, sizeof(HANDLE)); WTSFreeMemory(buffer); } nCount = 0; events[nCount++] = ChannelEvent; events[nCount++] = context->priv->StopEvent; while (1) { status = WaitForMultipleObjects(nCount, events, FALSE, INFINITE); if (status == WAIT_FAILED) { error = GetLastError(); WLog_ERR(TAG, "WaitForMultipleObjects failed with error %u", error); break; } status = WaitForSingleObject(context->priv->StopEvent, 0); if (status == WAIT_FAILED) { error = GetLastError(); WLog_ERR(TAG, "WaitForSingleObject failed with error %u", error); break; } if (status == WAIT_OBJECT_0) { break; } WTSVirtualChannelRead(context->priv->ChannelHandle, 0, NULL, 0, &BytesReturned); if (BytesReturned < 1) continue; if (!Stream_EnsureRemainingCapacity(s, BytesReturned)) { WLog_ERR(TAG, "Stream_EnsureRemainingCapacity failed!"); error = CHANNEL_RC_NO_MEMORY; break; } if (!WTSVirtualChannelRead(context->priv->ChannelHandle, 0, (PCHAR) Stream_Buffer(s), Stream_Capacity(s), &BytesReturned)) { WLog_ERR(TAG, "WTSVirtualChannelRead failed!"); error = ERROR_INTERNAL_ERROR; break; } if (Stream_GetPosition(s) >= ENCOMSP_ORDER_HEADER_SIZE) { header = (ENCOMSP_ORDER_HEADER*) Stream_Buffer(s); if (header->Length >= Stream_GetPosition(s)) { Stream_SealLength(s); Stream_SetPosition(s, 0); if ((error = encomsp_server_receive_pdu(context, s))) { WLog_ERR(TAG, "encomsp_server_receive_pdu failed with error %u!", error); break; } Stream_SetPosition(s, 0); } } } Stream_Free(s, TRUE); out: if (error && context->rdpcontext) setChannelError(context->rdpcontext, error, "encomsp_server_thread reported an error"); ExitThread((DWORD)error); return NULL; }
static void* drdynvc_server_thread(void* arg) { #if 0 wStream* s; DWORD status; DWORD nCount; void* buffer; HANDLE events[8]; HANDLE ChannelEvent; DWORD BytesReturned; DrdynvcServerContext* context; UINT error = ERROR_INTERNAL_ERROR; context = (DrdynvcServerContext*) arg; buffer = NULL; BytesReturned = 0; ChannelEvent = NULL; s = Stream_New(NULL, 4096); if (!s) { WLog_ERR(TAG, "Stream_New failed!"); ExitThread((DWORD) CHANNEL_RC_NO_MEMORY); return NULL; } if (WTSVirtualChannelQuery(context->priv->ChannelHandle, WTSVirtualEventHandle, &buffer, &BytesReturned) == TRUE) { if (BytesReturned == sizeof(HANDLE)) CopyMemory(&ChannelEvent, buffer, sizeof(HANDLE)); WTSFreeMemory(buffer); } nCount = 0; events[nCount++] = ChannelEvent; events[nCount++] = context->priv->StopEvent; while (1) { status = WaitForMultipleObjects(nCount, events, FALSE, INFINITE); if (WaitForSingleObject(context->priv->StopEvent, 0) == WAIT_OBJECT_0) { error = CHANNEL_RC_OK; break; } if (!WTSVirtualChannelRead(context->priv->ChannelHandle, 0, NULL, 0, &BytesReturned)) { WLog_ERR(TAG, "WTSVirtualChannelRead failed!"); break; } if (BytesReturned < 1) continue; if (!Stream_EnsureRemainingCapacity(s, BytesReturned)) { WLog_ERR(TAG, "Stream_EnsureRemainingCapacity failed!"); break; } if (!WTSVirtualChannelRead(context->priv->ChannelHandle, 0, (PCHAR) Stream_Buffer(s), Stream_Capacity(s), &BytesReturned)) { WLog_ERR(TAG, "WTSVirtualChannelRead failed!"); break; } } Stream_Free(s, TRUE); ExitThread((DWORD) error); #endif // WTF ... this code only reads data into the stream until there is no more memory ExitThread(0); return NULL; }
/** * Function description * * @return 0 on success, otherwise a Win32 error code */ UINT rdpsnd_server_handle_messages(RdpsndServerContext *context) { DWORD bytesReturned; UINT ret = CHANNEL_RC_OK; RdpsndServerPrivate *priv = context->priv; wStream *s = priv->input_stream; if (!WTSVirtualChannelRead(priv->ChannelHandle, 0, (PCHAR)Stream_Pointer(s), priv->expectedBytes, &bytesReturned)) { if (GetLastError() == ERROR_NO_DATA) return ERROR_NO_DATA; WLog_ERR(TAG, "channel connection closed"); return ERROR_INTERNAL_ERROR; } priv->expectedBytes -= bytesReturned; Stream_Seek(s, bytesReturned); if (priv->expectedBytes) return CHANNEL_RC_OK; Stream_SealLength(s); Stream_SetPosition(s, 0); if (priv->waitingHeader) { /* header case */ Stream_Read_UINT8(s, priv->msgType); Stream_Seek_UINT8(s); /* bPad */ Stream_Read_UINT16(s, priv->expectedBytes); priv->waitingHeader = 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 */ #ifdef WITH_DEBUG_SND WLog_DBG(TAG, "message type %d", priv->msgType); #endif priv->expectedBytes = 4; priv->waitingHeader = TRUE; switch (priv->msgType) { case SNDC_WAVECONFIRM: ret = rdpsnd_server_recv_waveconfirm(context, s); break; case SNDC_FORMATS: ret = rdpsnd_server_recv_formats(context, s); if ((ret == CHANNEL_RC_OK) && (context->clientVersion < 6)) IFCALL(context->Activated, context); break; case SNDC_QUALITYMODE: ret = rdpsnd_server_recv_quality_mode(context, s); Stream_SetPosition(s, 0); /* in case the Activated callback tries to treat some messages */ if ((ret == CHANNEL_RC_OK) && (context->clientVersion >= 6)) IFCALL(context->Activated, context); break; default: WLog_ERR(TAG, "UNKOWN MESSAGE TYPE!! (%#0X)", priv->msgType); ret = ERROR_INVALID_DATA; break; } Stream_SetPosition(s, 0); return ret; }
static void* remdesk_server_thread(void* arg) { wStream* s; DWORD status; DWORD nCount; void* buffer; UINT32* pHeader; UINT32 PduLength; HANDLE events[8]; HANDLE ChannelEvent; DWORD BytesReturned; RemdeskServerContext* context; context = (RemdeskServerContext*) arg; buffer = NULL; BytesReturned = 0; ChannelEvent = NULL; s = Stream_New(NULL, 4096); if (WTSVirtualChannelQuery(context->priv->ChannelHandle, WTSVirtualEventHandle, &buffer, &BytesReturned) == TRUE) { if (BytesReturned == sizeof(HANDLE)) CopyMemory(&ChannelEvent, buffer, sizeof(HANDLE)); WTSFreeMemory(buffer); } nCount = 0; events[nCount++] = ChannelEvent; events[nCount++] = context->priv->StopEvent; remdesk_send_ctl_version_info_pdu(context); while (1) { status = WaitForMultipleObjects(nCount, events, FALSE, INFINITE); if (WaitForSingleObject(context->priv->StopEvent, 0) == WAIT_OBJECT_0) { break; } if (WTSVirtualChannelRead(context->priv->ChannelHandle, 0, (PCHAR) Stream_Buffer(s), Stream_Capacity(s), &BytesReturned)) { if (BytesReturned) Stream_Seek(s, BytesReturned); } else { Stream_EnsureRemainingCapacity(s, BytesReturned); } if (Stream_GetPosition(s) >= 8) { 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); } } } Stream_Free(s, TRUE); return NULL; }
static void* rdpsnd_server_thread_func(void* arg) { void* fd; STREAM* s; void* buffer; BYTE msgType; UINT16 BodySize; UINT32 bytes_returned = 0; rdpsnd_server* rdpsnd = (rdpsnd_server*) arg; freerdp_thread* thread = rdpsnd->rdpsnd_channel_thread; if (WTSVirtualChannelQuery(rdpsnd->rdpsnd_channel, WTSVirtualFileHandle, &buffer, &bytes_returned) == TRUE) { fd = *((void**)buffer); WTSFreeMemory(buffer); thread->signals[thread->num_signals++] = wait_obj_new_with_fd(fd); } s = stream_new(4096); rdpsnd_server_send_formats(rdpsnd, s); while (1) { freerdp_thread_wait(thread); if (freerdp_thread_is_stopped(thread)) break; stream_set_pos(s, 0); if (WTSVirtualChannelRead(rdpsnd->rdpsnd_channel, 0, stream_get_head(s), stream_get_size(s), &bytes_returned) == FALSE) { if (bytes_returned == 0) break; stream_check_size(s, (int) bytes_returned); if (WTSVirtualChannelRead(rdpsnd->rdpsnd_channel, 0, stream_get_head(s), stream_get_size(s), &bytes_returned) == FALSE) break; } stream_read_BYTE(s, msgType); stream_seek_BYTE(s); /* bPad */ stream_read_UINT16(s, BodySize); if (BodySize + 4 > (int) bytes_returned) continue; switch (msgType) { case SNDC_FORMATS: if (rdpsnd_server_recv_formats(rdpsnd, s)) { IFCALL(rdpsnd->context.Activated, &rdpsnd->context); } break; default: break; } } stream_free(s); freerdp_thread_quit(thread); return 0; }
static void* audin_server_thread_func(void* arg) { wStream* s; void* buffer; DWORD nCount; BYTE MessageId; HANDLE events[8]; BOOL ready = FALSE; HANDLE ChannelEvent; DWORD BytesReturned = 0; audin_server* audin = (audin_server*) arg; UINT error = CHANNEL_RC_OK; DWORD status; buffer = NULL; BytesReturned = 0; ChannelEvent = NULL; if (WTSVirtualChannelQuery(audin->audin_channel, WTSVirtualEventHandle, &buffer, &BytesReturned) == TRUE) { if (BytesReturned == sizeof(HANDLE)) CopyMemory(&ChannelEvent, buffer, sizeof(HANDLE)); WTSFreeMemory(buffer); } else { WLog_ERR(TAG, "WTSVirtualChannelQuery failed"); error = ERROR_INTERNAL_ERROR; goto out; } nCount = 0; events[nCount++] = audin->stopEvent; events[nCount++] = ChannelEvent; /* Wait for the client to confirm that the Audio Input dynamic channel is ready */ while (1) { if ((status = WaitForMultipleObjects(nCount, events, FALSE, 100)) == WAIT_OBJECT_0) goto out; if (status == WAIT_FAILED) { error = GetLastError(); WLog_ERR(TAG, "WaitForMultipleObjects failed with error %lu", error); goto out; } if (WTSVirtualChannelQuery(audin->audin_channel, WTSVirtualChannelReady, &buffer, &BytesReturned) == FALSE) { WLog_ERR(TAG, "WTSVirtualChannelQuery failed"); error = ERROR_INTERNAL_ERROR; goto out; } ready = *((BOOL*) buffer); WTSFreeMemory(buffer); if (ready) break; } s = Stream_New(NULL, 4096); if (!s) { WLog_ERR(TAG, "Stream_New failed!"); error = CHANNEL_RC_NO_MEMORY; goto out; } if (ready) { if ((error = audin_server_send_version(audin, s))) { WLog_ERR(TAG, "audin_server_send_version failed with error %lu!", error); goto out_capacity; } } while (ready) { if ((status = WaitForMultipleObjects(nCount, events, FALSE, INFINITE)) == WAIT_OBJECT_0) break; if (status == WAIT_FAILED) { error = GetLastError(); WLog_ERR(TAG, "WaitForMultipleObjects failed with error %lu", error); goto out; } Stream_SetPosition(s, 0); if (!WTSVirtualChannelRead(audin->audin_channel, 0, NULL, 0, &BytesReturned)) { WLog_ERR(TAG, "WTSVirtualChannelRead failed!"); error = ERROR_INTERNAL_ERROR; break; } if (BytesReturned < 1) continue; if (!Stream_EnsureRemainingCapacity(s, BytesReturned)) break; if (WTSVirtualChannelRead(audin->audin_channel, 0, (PCHAR) Stream_Buffer(s), Stream_Capacity(s), &BytesReturned) == FALSE) { WLog_ERR(TAG, "WTSVirtualChannelRead failed!"); error = ERROR_INTERNAL_ERROR; break; } Stream_Read_UINT8(s, MessageId); BytesReturned--; switch (MessageId) { case MSG_SNDIN_VERSION: if ((error = audin_server_recv_version(audin, s, BytesReturned))) { WLog_ERR(TAG, "audin_server_recv_version failed with error %lu!", error); goto out_capacity; } if ((error = audin_server_send_formats(audin, s))) { WLog_ERR(TAG, "audin_server_send_formats failed with error %lu!", error); goto out_capacity; } break; case MSG_SNDIN_FORMATS: if ((error = audin_server_recv_formats(audin, s, BytesReturned))) { WLog_ERR(TAG, "audin_server_recv_formats failed with error %lu!", error); goto out_capacity; } if ((error = audin_server_send_open(audin, s))) { WLog_ERR(TAG, "audin_server_send_open failed with error %lu!", error); goto out_capacity; } break; case MSG_SNDIN_OPEN_REPLY: if ((error = audin_server_recv_open_reply(audin, s, BytesReturned))) { WLog_ERR(TAG, "audin_server_recv_open_reply failed with error %lu!", error); goto out_capacity; } break; case MSG_SNDIN_DATA_INCOMING: break; case MSG_SNDIN_DATA: if ((error = audin_server_recv_data(audin, s, BytesReturned))) { WLog_ERR(TAG, "audin_server_recv_data failed with error %lu!", error); goto out_capacity; }; break; case MSG_SNDIN_FORMATCHANGE: break; default: WLog_ERR(TAG, "audin_server_thread_func: unknown MessageId %d", MessageId); break; } } out_capacity: Stream_Free(s, TRUE); out: WTSVirtualChannelClose(audin->audin_channel); audin->audin_channel = NULL; if (error && audin->context.rdpcontext) setChannelError(audin->context.rdpcontext, error, "audin_server_thread_func reported an error"); ExitThread((DWORD)error); return NULL; }
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; }