static void* printer_thread_func(void* arg) { IRP* irp; PRINTER_DEVICE* printer_dev = (PRINTER_DEVICE*) arg; HANDLE obj[] = {printer_dev->event, printer_dev->stopEvent}; UINT error = CHANNEL_RC_OK; freerdp_channel_init_thread_context(printer_dev->rdpcontext); while (1) { DWORD rc = WaitForMultipleObjects(2, obj, FALSE, INFINITE); if (rc == WAIT_FAILED) { error = GetLastError(); WLog_ERR(TAG, "WaitForMultipleObjects failed with error %lu!", error); break; } if (rc == WAIT_OBJECT_0 + 1) break; else if (rc != WAIT_OBJECT_0) continue; ResetEvent(printer_dev->event); irp = (IRP*) InterlockedPopEntrySList(printer_dev->pIrpList); if (irp == NULL) { WLog_ERR(TAG, "InterlockedPopEntrySList failed!"); error = ERROR_INTERNAL_ERROR; break; } if ((error = printer_process_irp(printer_dev, irp))) { WLog_ERR(TAG, "printer_process_irp failed with error %d!", error); break; } } if (error && printer_dev->rdpcontext) setChannelError(printer_dev->rdpcontext, error, "printer_thread_func reported an error"); ExitThread((DWORD) error); return NULL; }
static void* remdesk_virtual_channel_client_thread(void* arg) { wStream* data; wMessage message; remdeskPlugin* remdesk = (remdeskPlugin*) arg; UINT error = CHANNEL_RC_OK; freerdp_channel_init_thread_context(remdesk->rdpcontext); remdesk_process_connect(remdesk); while (1) { if (!MessageQueue_Wait(remdesk->queue)) { WLog_ERR(TAG, "MessageQueue_Wait failed!"); error = ERROR_INTERNAL_ERROR; break; } if (!MessageQueue_Peek(remdesk->queue, &message, TRUE)) { WLog_ERR(TAG, "MessageQueue_Peek failed!"); error = ERROR_INTERNAL_ERROR; break; } if (message.id == WMQ_QUIT) break; if (message.id == 0) { data = (wStream*) message.wParam; if ((error = remdesk_process_receive(remdesk, data))) { WLog_ERR(TAG, "remdesk_process_receive failed with error %lu!", error); break; } } } if (error && remdesk->rdpcontext) setChannelError(remdesk->rdpcontext, error, "remdesk_virtual_channel_client_thread reported an error"); ExitThread((DWORD)error); return NULL; }
static void* parallel_thread_func(void* arg) { IRP* irp; wMessage message; PARALLEL_DEVICE* parallel = (PARALLEL_DEVICE*) arg; UINT error = CHANNEL_RC_OK; freerdp_channel_init_thread_context(parallel->rdpcontext); while (1) { if (!MessageQueue_Wait(parallel->queue)) { WLog_ERR(TAG, "MessageQueue_Wait failed!"); error = ERROR_INTERNAL_ERROR; break; } if (!MessageQueue_Peek(parallel->queue, &message, TRUE)) { WLog_ERR(TAG, "MessageQueue_Peek failed!"); error = ERROR_INTERNAL_ERROR; break; } if (message.id == WMQ_QUIT) break; irp = (IRP*) message.wParam; if ((error = parallel_process_irp(parallel, irp))) { WLog_ERR(TAG, "parallel_process_irp failed with error %d!", error); break; } } if (error && parallel->rdpcontext) setChannelError(parallel->rdpcontext, error, "parallel_thread_func reported an error"); ExitThread((DWORD)error); return NULL; }
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; freerdp_channel_init_thread_context(context->rdpcontext); 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 %lu", error); break; } status = WaitForSingleObject(context->priv->StopEvent, 0); if (status == WAIT_FAILED) { error = GetLastError(); WLog_ERR(TAG, "WaitForSingleObject failed with error %lu", 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 %lu!", 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* cliprdr_server_thread(void* arg) { DWORD status; DWORD nCount; HANDLE events[8]; HANDLE ChannelEvent; CliprdrServerContext* context = (CliprdrServerContext*) arg; CliprdrServerPrivate* cliprdr = (CliprdrServerPrivate*) context->handle; UINT error; freerdp_channel_init_thread_context(context->rdpcontext); ChannelEvent = context->GetEventHandle(context); nCount = 0; events[nCount++] = cliprdr->StopEvent; events[nCount++] = ChannelEvent; if ((error = cliprdr_server_init(context))) { WLog_ERR(TAG, "cliprdr_server_init failed with error %lu!", error); goto out; } while (1) { status = WaitForMultipleObjects(nCount, events, FALSE, INFINITE); if (status == WAIT_FAILED) { error = GetLastError(); WLog_ERR(TAG, "WaitForMultipleObjects failed with error %lu", error); goto out; } status = WaitForSingleObject(cliprdr->StopEvent, 0); if (status == WAIT_FAILED) { error = GetLastError(); WLog_ERR(TAG, "WaitForSingleObject failed with error %lu", error); goto out; } if (status == WAIT_OBJECT_0) break; status = WaitForSingleObject(ChannelEvent, 0); if (status == WAIT_FAILED) { error = GetLastError(); WLog_ERR(TAG, "WaitForSingleObject failed with error %lu", error); goto out; } if (status == WAIT_OBJECT_0) { if ((error = context->CheckEventHandle(context))) { WLog_ERR(TAG, "CheckEventHandle failed with error %lu!", error); break; } } } out: if (error && context->rdpcontext) setChannelError(context->rdpcontext, error, "cliprdr_server_thread reported an error"); ExitThread((DWORD)error); 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; freerdp_channel_init_thread_context(context->rdpcontext); 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 %lu!", error); goto out; } while (1) { status = WaitForMultipleObjects(nCount, events, FALSE, INFINITE); if (status == WAIT_FAILED) { error = GetLastError(); WLog_ERR(TAG, "WaitForMultipleObjects failed with error %lu", error); break; } status = WaitForSingleObject(context->priv->StopEvent, 0); if (status == WAIT_FAILED) { error = GetLastError(); WLog_ERR(TAG, "WaitForSingleObject failed with error %lu", 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 %lu!", 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; }