void remove_callback_by_name(const char *name, void *context) { if (!cb_dict) { DEBUG_WARN("trying to remove '%s', but function list does not exist.", name); return; } if (!ListDictionary_Contains(cb_dict, (void *)name)) { DEBUG_WARN("trying to remove '%s', which is not in function list.", name); return; } DEBUG_DVC("Removing '%s' from function list.", name); ListDictionary_Remove(cb_dict, (void *)name); if (ListDictionary_Count(cb_dict) < 1) { DEBUG_DVC("Function list is empty, freeing resources."); ListDictionary_Free(cb_dict); cb_dict = NULL; } dump_callbacks(); }
int shadow_encoder_create_frame_id(rdpShadowEncoder* encoder) { UINT32 frameId; int inFlightFrames; SURFACE_FRAME* frame; inFlightFrames = ListDictionary_Count(encoder->frameList); if (inFlightFrames > encoder->frameAck) { encoder->fps = (100 / (inFlightFrames + 1) * encoder->maxFps) / 100; } else { encoder->fps += 2; if (encoder->fps > encoder->maxFps) encoder->fps = encoder->maxFps; } if (encoder->fps < 1) encoder->fps = 1; frame = (SURFACE_FRAME*) malloc(sizeof(SURFACE_FRAME)); if (!frame) return -1; frameId = frame->frameId = ++encoder->frameId; ListDictionary_Add(encoder->frameList, (void*) (size_t) frame->frameId, frame); return (int) frame->frameId; }
void encomsp_remove_init_handle_data(void* pInitHandle) { ListDictionary_Remove(g_InitHandles, pInitHandle); if (ListDictionary_Count(g_InitHandles) < 1) { ListDictionary_Free(g_InitHandles); g_InitHandles = NULL; } }
void encomsp_remove_open_handle_data(DWORD openHandle) { void* pOpenHandle = (void*) (size_t) openHandle; ListDictionary_Remove(g_OpenHandles, pOpenHandle); if (ListDictionary_Count(g_OpenHandles) < 1) { ListDictionary_Free(g_OpenHandles); g_OpenHandles = NULL; } }
void freerdp_channel_remove_init_handle_data(rdpChannelHandles* handles, void* pInitHandle) { ListDictionary_Remove(handles->init, pInitHandle); if (ListDictionary_Count(handles->init) < 1) { ListDictionary_Free(handles->init); handles->init = NULL; } }
void freerdp_channel_remove_open_handle_data(rdpChannelHandles* handles, DWORD openHandle) { void* pOpenHandle = (void*)(size_t) openHandle; ListDictionary_Remove(handles->open, pOpenHandle); if (ListDictionary_Count(handles->open) < 1) { ListDictionary_Free(handles->open); handles->open = NULL; } }
static void drdynvc_remove_open_handle_data(DWORD openHandle) { void* pOpenHandle = (void*) (size_t) openHandle; if (!g_OpenHandles) return; ListDictionary_Remove(g_OpenHandles, pOpenHandle); if (ListDictionary_Count(g_OpenHandles) < 1) { ListDictionary_Free(g_OpenHandles); g_OpenHandles = NULL; } }
BOOL ThreadCloseHandle(HANDLE handle) { WINPR_THREAD* thread = (WINPR_THREAD*) handle; if (!thread_list) { WLog_ERR(TAG, "Thread list does not exist, check call!"); dump_thread(thread); } else if (!ListDictionary_Contains(thread_list, &thread->thread)) { WLog_ERR(TAG, "Thread list does not contain this thread! check call!"); dump_thread(thread); } else { ListDictionary_Lock(thread_list); dump_thread(thread); if ((thread->started) && (WaitForSingleObject(thread, 0) != WAIT_OBJECT_0)) { WLog_ERR(TAG, "Thread running, setting to detached state!"); thread->detached = TRUE; pthread_detach(thread->thread); } else { cleanup_handle(thread); } ListDictionary_Unlock(thread_list); if (ListDictionary_Count(thread_list) < 1) { ListDictionary_Free(thread_list); thread_list = NULL; } } return TRUE; }
int freerds_client_inbound_paint_rect(rdsModuleConnector* connector, RDS_MSG_PAINT_RECT* msg) { int bpp; int inFlightFrames; SURFACE_FRAME* frame; rdsConnection* connection; rdpSettings* settings; connection = connector->connection; settings = connection->settings; bpp = msg->framebuffer->fbBitsPerPixel; if (connection->codecMode) { inFlightFrames = ListDictionary_Count(connection->FrameList); if (inFlightFrames > settings->FrameAcknowledge) connector->fps = (100 / (inFlightFrames + 1) * connector->MaxFps) / 100; else connector->fps = connector->MaxFps; if (connector->fps < 1) connector->fps = 1; frame = (SURFACE_FRAME*) malloc(sizeof(SURFACE_FRAME)); frame->frameId = ++connection->frameId; ListDictionary_Add(connection->FrameList, (void*) (size_t) frame->frameId, frame); freerds_orders_send_frame_marker(connection, SURFACECMD_FRAMEACTION_BEGIN, frame->frameId); freerds_send_surface_bits(connection, bpp, msg); freerds_orders_send_frame_marker(connection, SURFACECMD_FRAMEACTION_END, frame->frameId); } else { freerds_send_bitmap_update(connection, bpp, msg); } return 0; }
int xrdp_server_paint_rect(xrdpModule* mod, XRDP_MSG_PAINT_RECT* msg) { int bpp; int inFlightFrames; SURFACE_FRAME* frame; bpp = msg->framebuffer->fbBitsPerPixel; if (mod->session->codecMode) { inFlightFrames = ListDictionary_Count(mod->session->FrameList); if (inFlightFrames > mod->session->settings->FrameAcknowledge) mod->fps = (100 / (inFlightFrames + 1) * mod->MaxFps) / 100; else mod->fps = mod->MaxFps; if (mod->fps < 1) mod->fps = 1; frame = (SURFACE_FRAME*) malloc(sizeof(SURFACE_FRAME)); frame->frameId = ++mod->session->frameId; ListDictionary_Add(mod->session->FrameList, (void*) (size_t) frame->frameId, frame); libxrdp_orders_send_frame_marker(mod->session, SURFACECMD_FRAMEACTION_BEGIN, frame->frameId); libxrdp_send_surface_bits(mod->session, bpp, msg); libxrdp_orders_send_frame_marker(mod->session, SURFACECMD_FRAMEACTION_END, frame->frameId); } else { libxrdp_send_bitmap_update(mod->session, bpp, msg); } return 0; }
static void create_irp_thread(SERIAL_DEVICE* serial, IRP* irp) { IRP_THREAD_DATA* data = NULL; HANDLE irpThread; HANDLE previousIrpThread; uintptr_t key; /* for a test/debug purpose, uncomment the code below to get a * single thread for all IRPs. NB: two IRPs could not be * processed at the same time, typically two concurent * Read/Write operations could block each other. */ /* serial_process_irp(serial, irp); */ /* irp->Complete(irp); */ /* return; */ /* NOTE: for good or bad, this implementation relies on the * server to avoid a flooding of requests. see also _purge(). */ EnterCriticalSection(&serial->TerminatingIrpThreadsLock); while (serial->IrpThreadToBeTerminatedCount > 0) { /* Cleaning up termitating and pending irp * threads. See also: irp_thread_func() */ HANDLE irpThread; ULONG_PTR* ids; int i, nbIds; nbIds = ListDictionary_GetKeys(serial->IrpThreads, &ids); for (i = 0; i < nbIds; i++) { /* Checking if ids[i] is terminating or pending */ DWORD waitResult; ULONG_PTR id = ids[i]; irpThread = ListDictionary_GetItemValue(serial->IrpThreads, (void*)id); /* FIXME: not quite sure a zero timeout is a good thing to check whether a thread is stil alived or not */ waitResult = WaitForSingleObject(irpThread, 0); if (waitResult == WAIT_OBJECT_0) { /* terminating thread */ /* WLog_Print(serial->log, WLOG_DEBUG, "IRP thread with CompletionId=%"PRIuz" naturally died", id); */ CloseHandle(irpThread); ListDictionary_Remove(serial->IrpThreads, (void*)id); serial->IrpThreadToBeTerminatedCount--; } else if (waitResult != WAIT_TIMEOUT) { /* unexpected thread state */ WLog_Print(serial->log, WLOG_WARN, "WaitForSingleObject, got an unexpected result=0x%"PRIX32"\n", waitResult); assert(FALSE); } /* pending thread (but not yet terminating thread) if waitResult == WAIT_TIMEOUT */ } if (serial->IrpThreadToBeTerminatedCount > 0) { WLog_Print(serial->log, WLOG_DEBUG, "%"PRIu32" IRP thread(s) not yet terminated", serial->IrpThreadToBeTerminatedCount); Sleep(1); /* 1 ms */ } } LeaveCriticalSection(&serial->TerminatingIrpThreadsLock); /* NB: At this point and thanks to the synchronization we're * sure that the incoming IRP uses well a recycled * CompletionId or the server sent again an IRP already posted * which didn't get yet a response (this later server behavior * at least observed with IOCTL_SERIAL_WAIT_ON_MASK and * mstsc.exe). * * FIXME: behavior documented somewhere? behavior not yet * observed with FreeRDP). */ key = irp->CompletionId; previousIrpThread = ListDictionary_GetItemValue(serial->IrpThreads, (void*)key); if (previousIrpThread) { /* Thread still alived <=> Request still pending */ WLog_Print(serial->log, WLOG_DEBUG, "IRP recall: IRP with the CompletionId=%"PRIu32" not yet completed!", irp->CompletionId); assert(FALSE); /* unimplemented */ /* TODO: asserts that previousIrpThread handles well * the same request by checking more details. Need an * access to the IRP object used by previousIrpThread */ /* TODO: taking over the pending IRP or sending a kind * of wake up signal to accelerate the pending * request * * To be considered: * if (IoControlCode == IOCTL_SERIAL_WAIT_ON_MASK) { * pComm->PendingEvents |= SERIAL_EV_FREERDP_*; * } */ irp->Discard(irp); return; } if (ListDictionary_Count(serial->IrpThreads) >= MAX_IRP_THREADS) { WLog_Print(serial->log, WLOG_WARN, "Number of IRP threads threshold reached: %d, keep on anyway", ListDictionary_Count(serial->IrpThreads)); assert(FALSE); /* unimplemented */ /* TODO: MAX_IRP_THREADS has been thought to avoid a * flooding of pending requests. Use * WaitForMultipleObjects() when available in winpr * for threads. */ } /* error_handle to be used ... */ data = (IRP_THREAD_DATA*)calloc(1, sizeof(IRP_THREAD_DATA)); if (data == NULL) { WLog_Print(serial->log, WLOG_WARN, "Could not allocate a new IRP_THREAD_DATA."); goto error_handle; } data->serial = serial; data->irp = irp; /* data freed by irp_thread_func */ irpThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)irp_thread_func, (void*)data, 0, NULL); if (irpThread == INVALID_HANDLE_VALUE) { WLog_Print(serial->log, WLOG_WARN, "Could not allocate a new IRP thread."); goto error_handle; } key = irp->CompletionId; if (!ListDictionary_Add(serial->IrpThreads, (void*)key, irpThread)) { WLog_ERR(TAG, "ListDictionary_Add failed!"); goto error_handle; } return; error_handle: irp->IoStatus = STATUS_NO_MEMORY; irp->Complete(irp); free(data); }
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); } }
static void smartcard_init(DEVICE* device) { int index; int keyCount; ULONG_PTR* pKeys; SCARDCONTEXT hContext; SMARTCARD_CONTEXT* pContext; SMARTCARD_DEVICE* smartcard = (SMARTCARD_DEVICE*) device; /** * On protocol termination, the following actions are performed: * For each context in rgSCardContextList, SCardCancel is called causing all outstanding messages to be processed. * After there are no more outstanding messages, SCardReleaseContext is called on each context and the context MUST * be removed from rgSCardContextList. */ /** * Call SCardCancel on existing contexts, unblocking all outstanding IRPs. */ 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)) { 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)) { SCardReleaseContext(hContext); } } free(pKeys); } }
int TestListDictionary(int argc, char* argv[]) { int count; char* value; wListDictionary* list; list = ListDictionary_New(FALSE); ListDictionary_Add(list, key1, val1); ListDictionary_Add(list, key2, val2); ListDictionary_Add(list, key3, val3); count = ListDictionary_Count(list); if (count != 3) { printf("ListDictionary_Count: Expected : %d, Actual: %d\n", 3, count); return -1; } ListDictionary_Remove(list, key2); count = ListDictionary_Count(list); if (count != 2) { printf("ListDictionary_Count: Expected : %d, Actual: %d\n", 2, count); return -1; } ListDictionary_Remove(list, key3); count = ListDictionary_Count(list); if (count != 1) { printf("ListDictionary_Count: Expected : %d, Actual: %d\n", 1, count); return -1; } ListDictionary_Remove(list, key1); count = ListDictionary_Count(list); if (count != 0) { printf("ListDictionary_Count: Expected : %d, Actual: %d\n", 0, count); return -1; } ListDictionary_Add(list, key1, val1); ListDictionary_Add(list, key2, val2); ListDictionary_Add(list, key3, val3); count = ListDictionary_Count(list); if (count != 3) { printf("ListDictionary_Count: Expected : %d, Actual: %d\n", 3, count); return -1; } value = (char*) ListDictionary_GetItemValue(list, key1); if (strcmp(value, val1) != 0) { printf("ListDictionary_GetItemValue: Expected : %d, Actual: %d\n", val1, value); return -1; } value = (char*) ListDictionary_GetItemValue(list, key2); if (strcmp(value, val2) != 0) { printf("ListDictionary_GetItemValue: Expected : %d, Actual: %d\n", val2, value); return -1; } value = (char*) ListDictionary_GetItemValue(list, key3); if (strcmp(value, val3) != 0) { printf("ListDictionary_GetItemValue: Expected : %d, Actual: %d\n", val3, value); return -1; } ListDictionary_SetItemValue(list, key2, "apple"); value = (char*) ListDictionary_GetItemValue(list, key2); if (strcmp(value, "apple") != 0) { printf("ListDictionary_GetItemValue: Expected : %d, Actual: %d\n", "apple", value); return -1; } if (!ListDictionary_Contains(list, key2)) { printf("ListDictionary_Contains: Expected : %d, Actual: %d\n", TRUE, FALSE); return -1; } ListDictionary_Clear(list); count = ListDictionary_Count(list); if (count != 0) { printf("ListDictionary_Count: Expected : %d, Actual: %d\n", 0, count); return -1; } ListDictionary_Free(list); return 0; }