/** * Function description * * @return 0 on success, otherwise a Win32 error code */ static UINT serial_free(DEVICE* device) { UINT error; SERIAL_DEVICE* serial = (SERIAL_DEVICE*) device; WLog_Print(serial->log, WLOG_DEBUG, "freeing"); MessageQueue_PostQuit(serial->MainIrpQueue, 0); if (WaitForSingleObject(serial->MainThread, INFINITE) == WAIT_FAILED) { error = GetLastError(); WLog_ERR(TAG, "WaitForSingleObject failed with error %"PRIu32"!", error); return error; } CloseHandle(serial->MainThread); if (serial->hComm) CloseHandle(serial->hComm); /* Clean up resources */ Stream_Free(serial->device.data, TRUE); MessageQueue_Free(serial->MainIrpQueue); ListDictionary_Free(serial->IrpThreads); DeleteCriticalSection(&serial->TerminatingIrpThreadsLock); free(serial); return CHANNEL_RC_OK; }
/** * Function description * * @return 0 on success, otherwise a Win32 error code */ static UINT rail_virtual_channel_event_disconnected(railPlugin* rail) { UINT rc; if (MessageQueue_PostQuit(rail->queue, 0) && (WaitForSingleObject(rail->thread, INFINITE) == WAIT_FAILED)) { rc = GetLastError(); WLog_ERR(TAG, "WaitForSingleObject failed with error %"PRIu32"", rc); return rc; } MessageQueue_Free(rail->queue); CloseHandle(rail->thread); rail->queue = NULL; rail->thread = NULL; rc = rail->channelEntryPoints.pVirtualChannelCloseEx(rail->InitHandle, rail->OpenHandle); if (CHANNEL_RC_OK != rc) { WLog_ERR(TAG, "pVirtualChannelCloseEx failed with %s [%08"PRIX32"]", WTSErrorToString(rc), rc); return rc; } rail->OpenHandle = 0; if (rail->data_in) { Stream_Free(rail->data_in, TRUE); rail->data_in = NULL; } return CHANNEL_RC_OK; }
int TestMessageQueue(int argc, char* argv[]) { HANDLE thread; wMessageQueue* queue; if (!(queue = MessageQueue_New(NULL))) { printf("failed to create message queue\n"); return 1; } if (!(thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) message_queue_consumer_thread, (void*) queue, 0, NULL))) { printf("failed to create thread\n"); MessageQueue_Free(queue); return 1; } if (!MessageQueue_Post(queue, NULL, 123, NULL, NULL) || !MessageQueue_Post(queue, NULL, 456, NULL, NULL) || !MessageQueue_Post(queue, NULL, 789, NULL, NULL) || !MessageQueue_PostQuit(queue, 0) || WaitForSingleObject(thread, INFINITE) != WAIT_OBJECT_0) return -1; MessageQueue_Free(queue); CloseHandle(thread); return 0; }
BOOL freerdp_disconnect(freerdp* instance) { BOOL rc = TRUE; rdpRdp* rdp; rdp = instance->context->rdp; rdp_client_disconnect(rdp); update_post_disconnect(instance->update); if (instance->settings->AsyncInput) { wMessageQueue* inputQueue = freerdp_get_message_queue(instance, FREERDP_INPUT_MESSAGE_QUEUE); MessageQueue_PostQuit(inputQueue, 0); } if (freerdp_channels_disconnect(instance->context->channels, instance) != CHANNEL_RC_OK) rc = FALSE; IFCALL(instance->PostDisconnect, instance); if (instance->update->pcap_rfx) { instance->update->dump_rfx = FALSE; pcap_close(instance->update->pcap_rfx); instance->update->pcap_rfx = NULL; } codecs_free(instance->context->codecs); freerdp_channels_close(instance->context->channels, instance); return rc; }
void freerdp_channels_close(rdpChannels* channels, freerdp* instance) { int index; char* name; CHANNEL_OPEN_DATA* pChannelOpenData; CHANNEL_CLIENT_DATA* pChannelClientData; channels->is_connected = 0; freerdp_channels_check_fds(channels, instance); /* tell all libraries we are shutting down */ for (index = 0; index < channels->clientDataCount; index++) { ChannelDisconnectedEventArgs e; pChannelClientData = &channels->clientDataList[index]; pChannelOpenData = &channels->openDataList[index]; name = (char*) malloc(9); CopyMemory(name, pChannelOpenData->name, 8); name[8] = '\0'; EventArgsInit(&e, "freerdp"); e.name = name; e.pInterface = pChannelOpenData->pInterface; PubSub_OnChannelDisconnected(instance->context->pubSub, instance->context, &e); free(name); if (pChannelClientData->pChannelInitEventProc) pChannelClientData->pChannelInitEventProc(pChannelClientData->pInitHandle, CHANNEL_EVENT_TERMINATED, 0, 0); } MessageQueue_PostQuit(channels->queue, 0); }
static void rail_virtual_channel_event_disconnected(railPlugin* rail) { UINT rc; if (MessageQueue_PostQuit(rail->queue, 0)) WaitForSingleObject(rail->thread, INFINITE); MessageQueue_Free(rail->queue); CloseHandle(rail->thread); rail->queue = NULL; rail->thread = NULL; rc = rail->channelEntryPoints.pVirtualChannelClose(rail->OpenHandle); if (CHANNEL_RC_OK != rc) { WLog_ERR(TAG, "pVirtualChannelClose failed with %s [%08X]", WTSErrorToString(rc), rc); } if (rail->data_in) { Stream_Free(rail->data_in, TRUE); rail->data_in = NULL; } rail_remove_open_handle_data(rail->OpenHandle); }
void freerdp_channels_close(rdpChannels* channels, freerdp* instance) { int index; CHANNEL_CLIENT_DATA* pChannelClientData; freerdp_channels_check_fds(channels, instance); /* tell all libraries we are shutting down */ for (index = 0; index < channels->clientDataCount; index++) { pChannelClientData = &channels->clientDataList[index]; if (pChannelClientData->pChannelInitEventProc) { pChannelClientData->pChannelInitEventProc( pChannelClientData->pInitHandle, CHANNEL_EVENT_TERMINATED, 0, 0); } else if (pChannelClientData->pChannelInitEventProcEx) { pChannelClientData->pChannelInitEventProcEx(pChannelClientData->lpUserParam, pChannelClientData->pInitHandle, CHANNEL_EVENT_TERMINATED, 0, 0); } } MessageQueue_PostQuit(channels->queue, 0); }
static void smartcard_free(DEVICE* device) { SMARTCARD_DEVICE* smartcard = (SMARTCARD_DEVICE*) device; if (smartcard->IrpQueue) { if (MessageQueue_PostQuit(smartcard->IrpQueue, 0)) WaitForSingleObject(smartcard->thread, INFINITE); MessageQueue_Free(smartcard->IrpQueue); smartcard->IrpQueue = NULL; CloseHandle(smartcard->thread); smartcard->thread = NULL; } if (smartcard->device.data) { Stream_Free(smartcard->device.data, TRUE); smartcard->device.data = NULL; } ListDictionary_Free(smartcard->rgSCardContextList); ListDictionary_Free(smartcard->rgOutstandingMessages); Queue_Free(smartcard->CompletedIrpQueue); if (smartcard->StartedEvent) { SCardReleaseStartedEvent(); smartcard->StartedEvent = NULL; } free(device); }
/** * Function description * * @return 0 on success, otherwise a Win32 error code */ static UINT smartcard_free(DEVICE* device) { UINT error; SMARTCARD_DEVICE* smartcard = CAST_FROM_DEVICE(device); if (!smartcard) return ERROR_INVALID_PARAMETER; /** * Calling smartcard_release_all_contexts to unblock all operations waiting for transactions * to unlock. */ smartcard_release_all_contexts(smartcard); /* Stopping all threads and cancelling all IRPs */ if (smartcard->IrpQueue) { if (MessageQueue_PostQuit(smartcard->IrpQueue, 0) && (WaitForSingleObject(smartcard->thread, INFINITE) == WAIT_FAILED)) { error = GetLastError(); WLog_ERR(TAG, "WaitForSingleObject failed with error %"PRIu32"!", error); return error; } } if (sSmartcard == smartcard) sSmartcard = NULL; return smartcard_free_(smartcard); }
/** * Function description * * @return 0 on success, otherwise a Win32 error code */ static UINT encomsp_virtual_channel_event_disconnected(encomspPlugin* encomsp) { UINT rc; if (MessageQueue_PostQuit(encomsp->queue, 0) && (WaitForSingleObject(encomsp->thread, INFINITE) == WAIT_FAILED)) { rc = GetLastError(); WLog_ERR(TAG, "WaitForSingleObject failed with error %lu", rc); return rc; } MessageQueue_Free(encomsp->queue); CloseHandle(encomsp->thread); encomsp->queue = NULL; encomsp->thread = NULL; rc = encomsp->channelEntryPoints.pVirtualChannelClose(encomsp->OpenHandle); if (CHANNEL_RC_OK != rc) { WLog_ERR(TAG, "pVirtualChannelClose failed with %s [%08X]", WTSErrorToString(rc), rc); return rc; } if (encomsp->data_in) { Stream_Free(encomsp->data_in, TRUE); encomsp->data_in = NULL; } encomsp_remove_open_handle_data(encomsp->OpenHandle); return CHANNEL_RC_OK; }
static void* jni_input_thread(void* arg) { HANDLE event[3]; wMessageQueue* queue; freerdp* instance = (freerdp*) arg; androidContext *aCtx = (androidContext*)instance->context; assert(NULL != instance); assert(NULL != aCtx); DEBUG_ANDROID("input_thread Start."); if (!(queue = freerdp_get_message_queue(instance, FREERDP_INPUT_MESSAGE_QUEUE))) goto fail_get_message_queue; if (!(event[0] = CreateFileDescriptorEvent(NULL, FALSE, FALSE, aCtx->event_queue->pipe_fd[0], WINPR_FD_READ))) goto fail_create_event_0; if (!(event[1] = CreateFileDescriptorEvent(NULL, FALSE, FALSE, aCtx->event_queue->pipe_fd[1], WINPR_FD_READ))) goto fail_create_event_1; if (!(event[2] = freerdp_get_message_queue_event_handle(instance, FREERDP_INPUT_MESSAGE_QUEUE))) goto fail_get_message_queue_event; do { DWORD rc = WaitForMultipleObjects(3, event, FALSE, INFINITE); if ((rc < WAIT_OBJECT_0) || (rc > WAIT_OBJECT_0 + 2)) continue; if (rc == WAIT_OBJECT_0 + 2) { wMessage msg; MessageQueue_Peek(queue, &msg, FALSE); if (msg.id == WMQ_QUIT) break; } if (android_check_fds(instance) != TRUE) break; } while(1); DEBUG_ANDROID("input_thread Quit."); fail_get_message_queue_event: CloseHandle(event[1]); fail_create_event_1: CloseHandle(event[0]); fail_create_event_0: MessageQueue_PostQuit(queue, 0); fail_get_message_queue: ExitThread(0); return NULL; }
/** * Function description * * @return 0 on success, otherwise a Win32 error code */ static UINT drdynvc_virtual_channel_event_disconnected(drdynvcPlugin* drdynvc) { UINT status; if (drdynvc->OpenHandle == 0) return CHANNEL_RC_OK; if (!drdynvc) return CHANNEL_RC_BAD_CHANNEL_HANDLE; if (!MessageQueue_PostQuit(drdynvc->queue, 0)) { status = GetLastError(); WLog_Print(drdynvc->log, WLOG_ERROR, "MessageQueue_PostQuit failed with error %"PRIu32"", status); return status; } if (WaitForSingleObject(drdynvc->thread, INFINITE) != WAIT_OBJECT_0) { status = GetLastError(); WLog_Print(drdynvc->log, WLOG_ERROR, "WaitForSingleObject failed with error %"PRIu32"", status); return status; } MessageQueue_Free(drdynvc->queue); CloseHandle(drdynvc->thread); drdynvc->queue = NULL; drdynvc->thread = NULL; status = drdynvc->channelEntryPoints.pVirtualChannelCloseEx(drdynvc->InitHandle, drdynvc->OpenHandle); if (status != CHANNEL_RC_OK) { WLog_Print(drdynvc->log, WLOG_ERROR, "pVirtualChannelClose failed with %s [%08"PRIX32"]", WTSErrorToString(status), status); } drdynvc->OpenHandle = 0; if (drdynvc->data_in) { Stream_Free(drdynvc->data_in, TRUE); drdynvc->data_in = NULL; } if (drdynvc->channel_mgr) { dvcman_free(drdynvc, drdynvc->channel_mgr); drdynvc->channel_mgr = NULL; } return status; }
static void drive_free(DEVICE* device) { DRIVE_DEVICE* drive = (DRIVE_DEVICE*) device; MessageQueue_PostQuit(drive->IrpQueue, 0); WaitForSingleObject(drive->thread, INFINITE); CloseHandle(drive->thread); ListDictionary_Free(drive->files); free(drive); }
void smartcard_context_free(SMARTCARD_CONTEXT* pContext) { if (!pContext) return; MessageQueue_PostQuit(pContext->IrpQueue, 0); WaitForSingleObject(pContext->thread, INFINITE); CloseHandle(pContext->thread); MessageQueue_Free(pContext->IrpQueue); free(pContext); }
/** * Function description * * @return 0 on success, otherwise a Win32 error code */ static UINT smartcard_free(DEVICE* device) { UINT error; SMARTCARD_DEVICE* smartcard = (SMARTCARD_DEVICE*) device; /** * Calling smartcard_release_all_contexts to unblock all operations waiting for transactions * to unlock. */ smartcard_release_all_contexts(smartcard); /* Stopping all threads and cancelling all IRPs */ if (smartcard->IrpQueue) { if (MessageQueue_PostQuit(smartcard->IrpQueue, 0) && (WaitForSingleObject(smartcard->thread, INFINITE) == WAIT_FAILED)) { error = GetLastError(); WLog_ERR(TAG, "WaitForSingleObject failed with error %lu!", error); return error; } MessageQueue_Free(smartcard->IrpQueue); smartcard->IrpQueue = NULL; CloseHandle(smartcard->thread); smartcard->thread = NULL; } if (smartcard->device.data) { Stream_Free(smartcard->device.data, TRUE); smartcard->device.data = NULL; } ListDictionary_Free(smartcard->rgSCardContextList); ListDictionary_Free(smartcard->rgOutstandingMessages); Queue_Free(smartcard->CompletedIrpQueue); if (smartcard->StartedEvent) { SCardReleaseStartedEvent(); smartcard->StartedEvent = NULL; } free(device); return CHANNEL_RC_OK; }
static void parallel_free(DEVICE* device) { PARALLEL_DEVICE* parallel = (PARALLEL_DEVICE*) device; DEBUG_SVC("freeing device"); MessageQueue_PostQuit(parallel->queue, 0); WaitForSingleObject(parallel->thread, INFINITE); CloseHandle(parallel->thread); Stream_Free(parallel->device.data, TRUE); MessageQueue_Free(parallel->queue); free(parallel); }
void smartcard_context_free(SMARTCARD_CONTEXT* pContext) { if (!pContext) return; /* cancel blocking calls like SCardGetStatusChange */ SCardCancel(pContext->hContext); if (MessageQueue_PostQuit(pContext->IrpQueue, 0) && (WaitForSingleObject(pContext->thread, INFINITE) == WAIT_FAILED)) WLog_ERR(TAG, "WaitForSingleObject failed with error %lu!", GetLastError()); CloseHandle(pContext->thread); MessageQueue_Free(pContext->IrpQueue); free(pContext); }
void smartcard_context_free(SMARTCARD_CONTEXT* pContext) { if (!pContext) return; /* cancel blocking calls like SCardGetStatusChange */ SCardCancel(pContext->hContext); if (MessageQueue_PostQuit(pContext->IrpQueue, 0)) WaitForSingleObject(pContext->thread, INFINITE); CloseHandle(pContext->thread); MessageQueue_Free(pContext->IrpQueue); free(pContext); }
static void smartcard_free(DEVICE* device) { SMARTCARD_DEVICE* smartcard = (SMARTCARD_DEVICE*) device; MessageQueue_PostQuit(smartcard->IrpQueue, 0); WaitForSingleObject(smartcard->thread, INFINITE); CloseHandle(smartcard->thread); Stream_Free(smartcard->device.data, TRUE); MessageQueue_Free(smartcard->IrpQueue); ListDictionary_Free(smartcard->rgSCardContextList); ListDictionary_Free(smartcard->rgOutstandingMessages); Queue_Free(smartcard->CompletedIrpQueue); free(device); }
static void* jni_input_thread(void* arg) { HANDLE event[2]; wMessageQueue* queue; freerdp* instance = (freerdp*) arg; WLog_DBG(TAG, "input_thread Start."); if (!(queue = freerdp_get_message_queue(instance, FREERDP_INPUT_MESSAGE_QUEUE))) goto disconnect; if (!(event[0] = android_get_handle(instance))) goto disconnect; if (!(event[1] = freerdp_get_message_queue_event_handle(instance, FREERDP_INPUT_MESSAGE_QUEUE))) goto disconnect; do { DWORD rc = WaitForMultipleObjects(2, event, FALSE, INFINITE); if ((rc < WAIT_OBJECT_0) || (rc > WAIT_OBJECT_0 + 1)) continue; if (rc == WAIT_OBJECT_0 + 1) { wMessage msg; MessageQueue_Peek(queue, &msg, FALSE); if (msg.id == WMQ_QUIT) break; } if (android_check_handle(instance) != TRUE) break; } while (1); WLog_DBG(TAG, "input_thread Quit."); disconnect: MessageQueue_PostQuit(queue, 0); ExitThread(0); return NULL; }
/** * Function description * * @return 0 on success, otherwise a Win32 error code */ static UINT parallel_free(DEVICE* device) { UINT error; PARALLEL_DEVICE* parallel = (PARALLEL_DEVICE*) device; if (MessageQueue_PostQuit(parallel->queue, 0) && (WaitForSingleObject(parallel->thread, INFINITE) == WAIT_FAILED)) { error = GetLastError(); WLog_ERR(TAG, "WaitForSingleObject failed with error %lu!", error); return error; } CloseHandle(parallel->thread); Stream_Free(parallel->device.data, TRUE); MessageQueue_Free(parallel->queue); free(parallel); return CHANNEL_RC_OK; }
int shadow_client_boardcast_quit(rdpShadowServer* server, int nExitCode) { wMessageQueue* queue = NULL; int count = 0; int index = 0; ArrayList_Lock(server->clients); for (index = 0; index < ArrayList_Count(server->clients); index++) { queue = ((rdpShadowClient*)ArrayList_GetItem(server->clients, index))->MsgQueue; if (MessageQueue_PostQuit(queue, nExitCode)) { count++; } } ArrayList_Unlock(server->clients); return count; }
int TestMessageQueue(int argc, char* argv[]) { HANDLE thread; wMessageQueue* queue; queue = MessageQueue_New(NULL); thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) message_queue_consumer_thread, (void*) queue, 0, NULL); MessageQueue_Post(queue, NULL, 123, NULL, NULL); MessageQueue_Post(queue, NULL, 456, NULL, NULL); MessageQueue_Post(queue, NULL, 789, NULL, NULL); MessageQueue_PostQuit(queue, 0); WaitForSingleObject(thread, INFINITE); MessageQueue_Free(queue); return 0; }
/** * Function description * * @return 0 on success, otherwise a Win32 error code */ static UINT drive_free(DEVICE* device) { DRIVE_DEVICE* drive = (DRIVE_DEVICE*) device; UINT error = CHANNEL_RC_OK; if (MessageQueue_PostQuit(drive->IrpQueue, 0) && (WaitForSingleObject(drive->thread, INFINITE) == WAIT_FAILED)) { error = GetLastError(); WLog_ERR(TAG, "WaitForSingleObject failed with error %u", error); return error; } CloseHandle(drive->thread); ListDictionary_Free(drive->files); MessageQueue_Free(drive->IrpQueue); Stream_Free(drive->device.data, TRUE); free(drive); return error; }
/** * Function description * * @return 0 on success, otherwise a Win32 error code */ static UINT drdynvc_virtual_channel_event_disconnected(drdynvcPlugin* drdynvc) { UINT status; if (MessageQueue_PostQuit(drdynvc->queue, 0) && (WaitForSingleObject(drdynvc->thread, INFINITE) == WAIT_FAILED)) { status = GetLastError(); WLog_ERR(TAG, "WaitForSingleObject failed with error %lu", status); return status; } MessageQueue_Free(drdynvc->queue); CloseHandle(drdynvc->thread); drdynvc->queue = NULL; drdynvc->thread = NULL; status = drdynvc->channelEntryPoints.pVirtualChannelClose(drdynvc->OpenHandle); if (status != CHANNEL_RC_OK) { WLog_ERR(TAG, "pVirtualChannelClose failed with %s [%08X]", WTSErrorToString(status), status); } if (drdynvc->data_in) { Stream_Free(drdynvc->data_in, TRUE); drdynvc->data_in = NULL; } if (drdynvc->channel_mgr) { dvcman_free(drdynvc->channel_mgr); drdynvc->channel_mgr = NULL; } drdynvc_remove_open_handle_data(drdynvc->OpenHandle); return status; }
void freerdp_channels_close(rdpChannels* channels, freerdp* instance) { int index; CHANNEL_OPEN_DATA* pChannelOpenData; CHANNEL_CLIENT_DATA* pChannelClientData; freerdp_channels_check_fds(channels, instance); /* tell all libraries we are shutting down */ for (index = 0; index < channels->clientDataCount; index++) { pChannelClientData = &channels->clientDataList[index]; if (pChannelClientData->pChannelInitEventProc) { pChannelClientData->pChannelInitEventProc( pChannelClientData->pInitHandle, CHANNEL_EVENT_TERMINATED, 0, 0); } else if (pChannelClientData->pChannelInitEventProcEx) { pChannelClientData->pChannelInitEventProcEx(pChannelClientData->lpUserParam, pChannelClientData->pInitHandle, CHANNEL_EVENT_TERMINATED, 0, 0); } } channels->clientDataCount = 0; MessageQueue_PostQuit(channels->queue, 0); for (index = 0; index < channels->openDataCount; index++) { pChannelOpenData = &channels->openDataList[index]; freerdp_channel_remove_open_handle_data(&g_ChannelHandles, pChannelOpenData->OpenHandle); if (channels->openHandles) HashTable_Remove(channels->openHandles, (void*)(UINT_PTR)pChannelOpenData->OpenHandle); } channels->openDataCount = 0; channels->initDataCount = 0; instance->settings->ChannelCount = 0; }
static int android_freerdp_run(freerdp* instance) { int i; int fds; int max_fds; int rcount; int wcount; int fd_input_event; HANDLE input_event = NULL; void* rfds[32]; void* wfds[32]; fd_set rfds_set; fd_set wfds_set; int select_status; struct timeval timeout; const rdpSettings* settings = instance->context->settings; HANDLE input_thread = NULL; HANDLE channels_thread = NULL; BOOL async_input = settings->AsyncInput; BOOL async_channels = settings->AsyncChannels; BOOL async_transport = settings->AsyncTransport; DEBUG_ANDROID("AsyncUpdate=%d", settings->AsyncUpdate); DEBUG_ANDROID("AsyncInput=%d", settings->AsyncInput); DEBUG_ANDROID("AsyncChannels=%d", settings->AsyncChannels); DEBUG_ANDROID("AsyncTransport=%d", settings->AsyncTransport); memset(rfds, 0, sizeof(rfds)); memset(wfds, 0, sizeof(wfds)); if (!freerdp_connect(instance)) { freerdp_callback("OnConnectionFailure", "(I)V", instance); return 0; } if (async_input) { if (!(input_thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) jni_input_thread, instance, 0, NULL))) { DEBUG_ANDROID("Failed to create async input thread\n"); goto disconnect; } } if (async_channels) { if (!(channels_thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) jni_channels_thread, instance, 0, NULL))) { DEBUG_ANDROID("Failed to create async channels thread\n"); goto disconnect; } } ((androidContext*)instance->context)->is_connected = TRUE; while (!freerdp_shall_disconnect(instance)) { rcount = 0; wcount = 0; if (!async_transport) { if (freerdp_get_fds(instance, rfds, &rcount, wfds, &wcount) != TRUE) { DEBUG_ANDROID("Failed to get FreeRDP file descriptor\n"); break; } } if (!async_channels) { if (freerdp_channels_get_fds(instance->context->channels, instance, rfds, &rcount, wfds, &wcount) != TRUE) { DEBUG_ANDROID("Failed to get channel manager file descriptor\n"); break; } } if (!async_input) { if (android_get_fds(instance, rfds, &rcount, wfds, &wcount) != TRUE) { DEBUG_ANDROID("Failed to get android file descriptor\n"); break; } } else { input_event = freerdp_get_message_queue_event_handle(instance, FREERDP_INPUT_MESSAGE_QUEUE); fd_input_event = GetEventFileDescriptor(input_event); rfds[rcount++] = (void*) (long) fd_input_event; } max_fds = 0; FD_ZERO(&rfds_set); FD_ZERO(&wfds_set); for (i = 0; i < rcount; i++) { fds = (int)(long)(rfds[i]); if (fds > max_fds) max_fds = fds; FD_SET(fds, &rfds_set); } if (max_fds == 0) break; timeout.tv_sec = 1; timeout.tv_usec = 0; select_status = select(max_fds + 1, &rfds_set, NULL, NULL, &timeout); if (select_status == 0) continue; else if (select_status == -1) { /* these are not really errors */ if (!((errno == EAGAIN) || (errno == EWOULDBLOCK) || (errno == EINPROGRESS) || (errno == EINTR))) /* signal occurred */ { DEBUG_ANDROID("android_run: select failed\n"); break; } } if (freerdp_shall_disconnect(instance)) break; if (!async_transport) { if (freerdp_check_fds(instance) != TRUE) { DEBUG_ANDROID("Failed to check FreeRDP file descriptor\n"); break; } } if (!async_input) { if (android_check_fds(instance) != TRUE) { DEBUG_ANDROID("Failed to check android file descriptor\n"); break; } } else if (input_event) { if (WaitForSingleObject(input_event, 0) == WAIT_OBJECT_0) { if (!freerdp_message_queue_process_pending_messages(instance, FREERDP_INPUT_MESSAGE_QUEUE)) { DEBUG_ANDROID("User Disconnect"); break; } } } if (!async_channels) { if (freerdp_channels_check_fds(instance->context->channels, instance) != TRUE) { DEBUG_ANDROID("Failed to check channel manager file descriptor\n"); break; } } } disconnect: DEBUG_ANDROID("Prepare shutdown..."); // issue another OnDisconnecting here in case the disconnect was initiated by the server and not our client freerdp_callback("OnDisconnecting", "(I)V", instance); DEBUG_ANDROID("Close channels..."); freerdp_channels_disconnect(instance->context->channels, instance); DEBUG_ANDROID("Cleanup threads..."); if (async_channels && channels_thread) { WaitForSingleObject(channels_thread, INFINITE); CloseHandle(channels_thread); } if (async_input && input_thread) { wMessageQueue* input_queue = freerdp_get_message_queue(instance, FREERDP_INPUT_MESSAGE_QUEUE); if (input_queue) { if (MessageQueue_PostQuit(input_queue, 0)) WaitForSingleObject(input_thread, INFINITE); } CloseHandle(input_thread); } DEBUG_ANDROID("run Disconnecting..."); freerdp_disconnect(instance); freerdp_callback("OnDisconnected", "(I)V", instance); DEBUG_ANDROID("run Quit."); return 0; }
DWORD WINAPI wf_client_thread(LPVOID lpParam) { MSG msg; int width; int height; BOOL msg_ret; int quit_msg; DWORD nCount; HANDLE handles[64]; wfContext* wfc; freerdp* instance; rdpContext* context; rdpChannels* channels; rdpSettings* settings; BOOL async_input; BOOL async_transport; HANDLE input_thread; instance = (freerdp*) lpParam; context = instance->context; wfc = (wfContext*) instance->context; if (!freerdp_connect(instance)) return 0; channels = instance->context->channels; settings = instance->context->settings; async_input = settings->AsyncInput; async_transport = settings->AsyncTransport; if (async_input) { if (!(input_thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) wf_input_thread, instance, 0, NULL))) { WLog_ERR(TAG, "Failed to create async input thread."); goto disconnect; } } while (1) { nCount = 0; if (freerdp_focus_required(instance)) { wf_event_focus_in(wfc); wf_event_focus_in(wfc); } if (!async_transport) { DWORD tmp = freerdp_get_event_handles(context, &handles[nCount], 64 - nCount); if (tmp == 0) { WLog_ERR(TAG, "freerdp_get_event_handles failed"); break; } nCount += tmp; } if (MsgWaitForMultipleObjects(nCount, handles, FALSE, 1000, QS_ALLINPUT) == WAIT_FAILED) { WLog_ERR(TAG, "wfreerdp_run: WaitForMultipleObjects failed: 0x%04X", GetLastError()); break; } if (!async_transport) { if (!freerdp_check_event_handles(context)) { if (wf_auto_reconnect(instance)) continue; WLog_ERR(TAG, "Failed to check FreeRDP file descriptor"); break; } } if (freerdp_shall_disconnect(instance)) break; quit_msg = FALSE; while (PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE)) { msg_ret = GetMessage(&msg, NULL, 0, 0); if (instance->settings->EmbeddedWindow) { if ((msg.message == WM_SETFOCUS) && (msg.lParam == 1)) { PostMessage(wfc->hwnd, WM_SETFOCUS, 0, 0); } else if ((msg.message == WM_KILLFOCUS) && (msg.lParam == 1)) { PostMessage(wfc->hwnd, WM_KILLFOCUS, 0, 0); } } if (msg.message == WM_SIZE) { width = LOWORD(msg.lParam); height = HIWORD(msg.lParam); SetWindowPos(wfc->hwnd, HWND_TOP, 0, 0, width, height, SWP_FRAMECHANGED); } if ((msg_ret == 0) || (msg_ret == -1)) { quit_msg = TRUE; break; } TranslateMessage(&msg); DispatchMessage(&msg); } if (quit_msg) break; } /* cleanup */ freerdp_channels_disconnect(channels, instance); if (async_input) { wMessageQueue* input_queue; input_queue = freerdp_get_message_queue(instance, FREERDP_INPUT_MESSAGE_QUEUE); if (MessageQueue_PostQuit(input_queue, 0)) WaitForSingleObject(input_thread, INFINITE); CloseHandle(input_thread); } disconnect: freerdp_disconnect(instance); WLog_DBG(TAG, "Main thread exited."); ExitThread(0); return 0; }
void MessagePipe_PostQuit(wMessagePipe* pipe, int nExitCode) { MessageQueue_PostQuit(pipe->In, nExitCode); MessageQueue_PostQuit(pipe->Out, nExitCode); }
static void smartcard_release_all_contexts(SMARTCARD_DEVICE* smartcard) { int index; int keyCount; ULONG_PTR* pKeys; SCARDCONTEXT hContext; SMARTCARD_CONTEXT* pContext; /** * On protocol termination, the following actions are performed: * For each context in rgSCardContextList, SCardCancel is called causing all SCardGetStatusChange calls to be processed. * After that, SCardReleaseContext is called on each context and the context MUST be removed from rgSCardContextList. */ /** * Call SCardCancel on existing contexts, unblocking all outstanding SCardGetStatusChange calls. */ if (ListDictionary_Count(smartcard->rgSCardContextList) > 0) { pKeys = NULL; keyCount = ListDictionary_GetKeys(smartcard->rgSCardContextList, &pKeys); for (index = 0; index < keyCount; index++) { pContext = (SMARTCARD_CONTEXT*) ListDictionary_GetItemValue(smartcard->rgSCardContextList, (void*) pKeys[index]); if (!pContext) continue; hContext = pContext->hContext; if (SCardIsValidContext(hContext) == SCARD_S_SUCCESS) { SCardCancel(hContext); } } free(pKeys); } /** * Call SCardReleaseContext on remaining contexts and remove them from rgSCardContextList. */ if (ListDictionary_Count(smartcard->rgSCardContextList) > 0) { pKeys = NULL; keyCount = ListDictionary_GetKeys(smartcard->rgSCardContextList, &pKeys); for (index = 0; index < keyCount; index++) { pContext = (SMARTCARD_CONTEXT*) ListDictionary_Remove(smartcard->rgSCardContextList, (void*) pKeys[index]); if (!pContext) continue; hContext = pContext->hContext; if (SCardIsValidContext(hContext) == SCARD_S_SUCCESS) { SCardReleaseContext(hContext); if (MessageQueue_PostQuit(pContext->IrpQueue, 0) && (WaitForSingleObject(pContext->thread, INFINITE) == WAIT_FAILED)) WLog_ERR(TAG, "WaitForSingleObject failed with error %lu!", GetLastError()); CloseHandle(pContext->thread); MessageQueue_Free(pContext->IrpQueue); free(pContext); } } free(pKeys); } }