void pbrcp_call_method_async(pbRPCContext* context, UINT32 type, pbRPCPayload* request, pbRpcResponseCallback callback, void *callback_args) { UINT32 tag; pbRPCTransaction* ta; FDSAPI_MSG_PACKET* msg; if (!context->isConnected) { callback(PBRCP_TRANSPORT_ERROR, 0, callback_args); return; } ta = (pbRPCTransaction*) calloc(1, sizeof(pbRPCTransaction)); ta->freeAfterResponse = TRUE; ta->responseCallback = callback; ta->callbackArg = callback_args; tag = pbrpc_getTag(context); msg = pbrpc_message_new(); msg->callId = tag; msg->status = FDSAPI_STATUS_SUCCESS; msg->buffer = request->buffer; msg->length = request->length; msg->msgType = FDSAPI_REQUEST_ID(type); ListDictionary_Add(context->transactions, (void*)((UINT_PTR)(msg->callId)), ta); Queue_Enqueue(context->writeQueue, msg); }
void remdesk_add_init_handle_data(void* pInitHandle, void* pUserData) { if (!g_InitHandles) g_InitHandles = ListDictionary_New(TRUE); ListDictionary_Add(g_InitHandles, pInitHandle, pUserData); }
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; }
static UINT32 smartcard_EstablishContext_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation, EstablishContext_Call* call) { UINT32 status; SCARDCONTEXT hContext = -1; EstablishContext_Return ret; IRP* irp = operation->irp; status = ret.ReturnCode = SCardEstablishContext(call->dwScope, NULL, NULL, &hContext); if (ret.ReturnCode == SCARD_S_SUCCESS) { SMARTCARD_CONTEXT* pContext; void* key = (void*) (size_t) hContext; pContext = smartcard_context_new(smartcard, hContext); ListDictionary_Add(smartcard->rgSCardContextList, key, (void*) pContext); } smartcard_scard_context_native_to_redir(smartcard, &(ret.hContext), hContext); smartcard_trace_establish_context_return(smartcard, &ret); status = smartcard_pack_establish_context_return(smartcard, irp->output, &ret); if (status) return status; return ret.ReturnCode; }
void remdesk_add_open_handle_data(DWORD openHandle, void* pUserData) { void* pOpenHandle = (void*) (size_t) openHandle; if (!g_OpenHandles) g_OpenHandles = ListDictionary_New(TRUE); ListDictionary_Add(g_OpenHandles, pOpenHandle, pUserData); }
BOOL http_response_parse_header_field(HttpResponse* response, char* name, char* value) { BOOL status = TRUE; if (_stricmp(name, "Content-Length") == 0) { response->ContentLength = atoi(value); } else if (_stricmp(name, "Content-Type") == 0) { response->ContentType = _strdup(value); if (!response->ContentType) return FALSE; } else if (_stricmp(name, "WWW-Authenticate") == 0) { char* separator = NULL; char* authScheme = NULL; char* authValue = NULL; separator = strchr(value, ' '); if (separator) { /* WWW-Authenticate: Basic realm="" * WWW-Authenticate: NTLM base64token * WWW-Authenticate: Digest realm="*****@*****.**", qop="auth, auth-int", * nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093", * opaque="5ccc069c403ebaf9f0171e9517f40e41" */ *separator = '\0'; authScheme = _strdup(value); authValue = _strdup(separator + 1); if (!authScheme || !authValue) return FALSE; *separator = ' '; } else { authScheme = _strdup(value); if (!authScheme) return FALSE; authValue = NULL; } status = ListDictionary_Add(response->Authenticates, authScheme, authValue); } return status; }
BOOL CryptProtectMemory(LPVOID pData, DWORD cbData, DWORD dwFlags) { BYTE* pCipherText; int cbOut, cbFinal; BYTE randomKey[256]; WINPR_PROTECTED_MEMORY_BLOCK* pMemBlock; if (dwFlags != CRYPTPROTECTMEMORY_SAME_PROCESS) return FALSE; if (!g_ProtectedMemoryBlocks) g_ProtectedMemoryBlocks = ListDictionary_New(TRUE); pMemBlock = (WINPR_PROTECTED_MEMORY_BLOCK*) malloc(sizeof(WINPR_PROTECTED_MEMORY_BLOCK)); ZeroMemory(pMemBlock, sizeof(WINPR_PROTECTED_MEMORY_BLOCK)); pMemBlock->pData = pData; pMemBlock->cbData = cbData; pMemBlock->dwFlags = dwFlags; /* AES Initialization */ RAND_bytes(pMemBlock->salt, 8); RAND_bytes(randomKey, sizeof(randomKey)); EVP_BytesToKey(EVP_aes_256_cbc(), EVP_sha1(), pMemBlock->salt, randomKey, sizeof(randomKey), 4, pMemBlock->key, pMemBlock->iv); SecureZeroMemory(randomKey, sizeof(randomKey)); EVP_CIPHER_CTX_init(&(pMemBlock->enc)); EVP_EncryptInit_ex(&(pMemBlock->enc), EVP_aes_256_cbc(), NULL, pMemBlock->key, pMemBlock->iv); EVP_CIPHER_CTX_init(&(pMemBlock->dec)); EVP_DecryptInit_ex(&(pMemBlock->dec), EVP_aes_256_cbc(), NULL, pMemBlock->key, pMemBlock->iv); /* AES Encryption */ cbOut = pMemBlock->cbData + AES_BLOCK_SIZE - 1; pCipherText = (BYTE*) malloc(cbOut); EVP_EncryptInit_ex(&(pMemBlock->enc), NULL, NULL, NULL, NULL); EVP_EncryptUpdate(&(pMemBlock->enc), pCipherText, &cbOut, pMemBlock->pData, pMemBlock->cbData); EVP_EncryptFinal_ex(&(pMemBlock->enc), pCipherText + cbOut, &cbFinal); CopyMemory(pMemBlock->pData, pCipherText, pMemBlock->cbData); free(pCipherText); ListDictionary_Add(g_ProtectedMemoryBlocks, pData, pMemBlock); return TRUE; }
BOOL rail_add_init_handle_data(void* pInitHandle, void* pUserData) { if (!g_InitHandles) { g_InitHandles = ListDictionary_New(TRUE); if (!g_InitHandles) return FALSE; } return ListDictionary_Add(g_InitHandles, pInitHandle, pUserData); }
/** * Function description * * @return 0 on success, otherwise a Win32 error code */ UINT remdesk_add_init_handle_data(void* pInitHandle, void* pUserData) { if (!g_InitHandles) { g_InitHandles = ListDictionary_New(TRUE); if (!g_InitHandles) return CHANNEL_RC_NO_MEMORY; } return ListDictionary_Add(g_InitHandles, pInitHandle, pUserData) ? CHANNEL_RC_OK : ERROR_INTERNAL_ERROR; }
/** * Function description * * @return 0 on success, otherwise a Win32 error code */ UINT remdesk_add_open_handle_data(DWORD openHandle, void* pUserData) { void* pOpenHandle = (void*) (size_t) openHandle; if (!g_OpenHandles) { g_OpenHandles = ListDictionary_New(TRUE); if (!g_OpenHandles) return CHANNEL_RC_NO_MEMORY; } return ListDictionary_Add(g_OpenHandles, pOpenHandle, pUserData) ? CHANNEL_RC_OK : ERROR_INTERNAL_ERROR; }
BOOL rail_add_open_handle_data(DWORD openHandle, void* pUserData) { void* pOpenHandle = (void*) (size_t) openHandle; if (!g_OpenHandles) { g_OpenHandles = ListDictionary_New(TRUE); if (!g_OpenHandles) return FALSE; } return ListDictionary_Add(g_OpenHandles, pOpenHandle, pUserData); }
/** * Function description * * @return 0 on success, otherwise a Win32 error code */ static UINT devman_register_device(DEVMAN* devman, DEVICE* device) { void* key = NULL; device->id = devman->id_sequence++; key = (void*) (size_t) device->id; if (!ListDictionary_Add(devman->devices, key, device)) { WLog_INFO(TAG, "ListDictionary_Add failed!"); return ERROR_INTERNAL_ERROR; } return CHANNEL_RC_OK; }
/** * Function description * * @return 0 on success, otherwise a Win32 error code */ UINT cliprdr_add_init_handle_data(void* pInitHandle, void* pUserData) { if (!g_InitHandles) g_InitHandles = ListDictionary_New(TRUE); if (!g_InitHandles) { WLog_ERR(TAG, "ListDictionary_New failed!"); return ERROR_NOT_ENOUGH_MEMORY; } if (!ListDictionary_Add(g_InitHandles, pInitHandle, pUserData)) { WLog_ERR(TAG, "ListDictionary_Add failed!"); return ERROR_INTERNAL_ERROR; } return CHANNEL_RC_OK; }
UINT freerdp_channel_add_init_handle_data(rdpChannelHandles* handles, void* pInitHandle, void* pUserData) { if (!handles->init) handles->init = ListDictionary_New(TRUE); if (!handles->init) { WLog_ERR(TAG, "ListDictionary_New failed!"); return ERROR_NOT_ENOUGH_MEMORY; } if (!ListDictionary_Add(handles->init, pInitHandle, pUserData)) { WLog_ERR(TAG, "ListDictionary_Add failed!"); return ERROR_INTERNAL_ERROR; } return CHANNEL_RC_OK; }
static BOOL winpr_StartThread(WINPR_THREAD* thread) { pthread_attr_t attr; pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); if (thread->dwStackSize > 0) pthread_attr_setstacksize(&attr, (size_t) thread->dwStackSize); thread->started = TRUE; reset_event(thread); if (pthread_create(&thread->thread, &attr, thread_launcher, thread)) goto error; if (pthread_mutex_lock(&thread->threadIsReadyMutex)) goto error; if (!ListDictionary_Add(thread_list, &thread->thread, thread)) { WLog_ERR(TAG, "failed to add the thread to the thread list"); pthread_mutex_unlock(&thread->threadIsReadyMutex); goto error; } if (pthread_cond_signal(&thread->threadIsReady) != 0) { WLog_ERR(TAG, "failed to signal the thread was ready"); pthread_mutex_unlock(&thread->threadIsReadyMutex); goto error; } if (pthread_mutex_unlock(&thread->threadIsReadyMutex)) goto error; pthread_attr_destroy(&attr); dump_thread(thread); return TRUE; error: pthread_attr_destroy(&attr); return FALSE; }
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; }
/** * Function description * * @return 0 on success, otherwise a Win32 error code */ static UINT drdynvc_add_open_handle_data(DWORD openHandle, void* pUserData) { void* pOpenHandle = (void*) (size_t) openHandle; if (!g_OpenHandles) g_OpenHandles = ListDictionary_New(TRUE); if (!g_OpenHandles) { WLog_ERR(TAG, "ListDictionary_New failed!"); return CHANNEL_RC_NO_MEMORY; } if (!ListDictionary_Add(g_OpenHandles, pOpenHandle, pUserData)) { WLog_ERR(TAG, "ListDictionary_New failed!"); return ERROR_INTERNAL_ERROR; } return CHANNEL_RC_OK; }
UINT freerdp_channel_add_open_handle_data(rdpChannelHandles* handles, DWORD openHandle, void* pUserData) { void* pOpenHandle = (void*) (size_t) openHandle; if (!handles->open) handles->open = ListDictionary_New(TRUE); if (!handles->open) { WLog_ERR(TAG, "ListDictionary_New failed!"); return ERROR_NOT_ENOUGH_MEMORY; } if (!ListDictionary_Add(handles->open, pOpenHandle, pUserData)) { WLog_ERR(TAG, "ListDictionary_Add failed!"); return ERROR_INTERNAL_ERROR; } return CHANNEL_RC_OK; }
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; }
void add_callback_by_name(const char *name, void *fkt, void *context) { struct cb_value *value = calloc(1, sizeof(struct cb_value)); if (!value) { DEBUG_WARN("calloc failed %s (%d)!", strerror(errno), errno); assert(FALSE); return; } if (!cb_dict) { DEBUG_DVC("Function list is empty, allocating new."); cb_dict = ListDictionary_New(TRUE); ListDictionary_KeyObject(cb_dict)->fnObjectEquals = callback_key_cmp; } value->fkt = fkt; value->context = context; DEBUG_DVC("Adding '%s'=%p to function list.", name, fkt); ListDictionary_Add(cb_dict, (void *)name, value); dump_callbacks(); }
static BOOL winpr_StartThread(WINPR_THREAD *thread) { pthread_attr_t attr; pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); if (thread->dwStackSize > 0) pthread_attr_setstacksize(&attr, (size_t) thread->dwStackSize); thread->started = TRUE; reset_event(thread); if (pthread_create(&thread->thread, &attr, thread_launcher, thread)) goto error; if (!ListDictionary_Add(thread_list, &thread->thread, thread)) goto error; pthread_attr_destroy(&attr); dump_thread(thread); return TRUE; error: pthread_attr_destroy(&attr); return FALSE; }
void smartcard_process_irp(SMARTCARD_DEVICE* smartcard, IRP* irp) { void* key; BOOL asyncIrp = FALSE; UINT32 ioControlCode = 0; key = (void*) (size_t) irp->CompletionId; ListDictionary_Add(smartcard->rgOutstandingMessages, key, irp); if (irp->MajorFunction == IRP_MJ_DEVICE_CONTROL) { smartcard_irp_device_control_peek_io_control_code(smartcard, irp, &ioControlCode); if (!ioControlCode) return; asyncIrp = TRUE; /** * The following matches mstsc's behavior of processing * only certain requests asynchronously while processing * those expected to return fast synchronously. */ switch (ioControlCode) { case SCARD_IOCTL_ESTABLISHCONTEXT: case SCARD_IOCTL_RELEASECONTEXT: case SCARD_IOCTL_ISVALIDCONTEXT: case SCARD_IOCTL_LISTREADERGROUPSA: case SCARD_IOCTL_LISTREADERGROUPSW: case SCARD_IOCTL_LISTREADERSA: case SCARD_IOCTL_LISTREADERSW: case SCARD_IOCTL_INTRODUCEREADERGROUPA: case SCARD_IOCTL_INTRODUCEREADERGROUPW: case SCARD_IOCTL_FORGETREADERGROUPA: case SCARD_IOCTL_FORGETREADERGROUPW: case SCARD_IOCTL_INTRODUCEREADERA: case SCARD_IOCTL_INTRODUCEREADERW: case SCARD_IOCTL_FORGETREADERA: case SCARD_IOCTL_FORGETREADERW: case SCARD_IOCTL_ADDREADERTOGROUPA: case SCARD_IOCTL_ADDREADERTOGROUPW: case SCARD_IOCTL_REMOVEREADERFROMGROUPA: case SCARD_IOCTL_REMOVEREADERFROMGROUPW: case SCARD_IOCTL_LOCATECARDSA: case SCARD_IOCTL_LOCATECARDSW: case SCARD_IOCTL_LOCATECARDSBYATRA: case SCARD_IOCTL_LOCATECARDSBYATRW: case SCARD_IOCTL_CANCEL: case SCARD_IOCTL_READCACHEA: case SCARD_IOCTL_READCACHEW: case SCARD_IOCTL_WRITECACHEA: case SCARD_IOCTL_WRITECACHEW: case SCARD_IOCTL_GETREADERICON: case SCARD_IOCTL_GETDEVICETYPEID: asyncIrp = FALSE; break; case SCARD_IOCTL_GETSTATUSCHANGEA: case SCARD_IOCTL_GETSTATUSCHANGEW: asyncIrp = TRUE; break; case SCARD_IOCTL_CONNECTA: case SCARD_IOCTL_CONNECTW: case SCARD_IOCTL_RECONNECT: case SCARD_IOCTL_DISCONNECT: case SCARD_IOCTL_BEGINTRANSACTION: case SCARD_IOCTL_ENDTRANSACTION: case SCARD_IOCTL_STATE: case SCARD_IOCTL_STATUSA: case SCARD_IOCTL_STATUSW: case SCARD_IOCTL_TRANSMIT: case SCARD_IOCTL_CONTROL: case SCARD_IOCTL_GETATTRIB: case SCARD_IOCTL_SETATTRIB: case SCARD_IOCTL_GETTRANSMITCOUNT: asyncIrp = TRUE; break; case SCARD_IOCTL_ACCESSSTARTEDEVENT: case SCARD_IOCTL_RELEASESTARTEDEVENT: asyncIrp = FALSE; break; } if (!asyncIrp) { smartcard_irp_device_control(smartcard, irp); Queue_Enqueue(smartcard->CompletedIrpQueue, (void*) irp); } else { irp->thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) smartcard_process_irp_worker_proc, irp, 0, NULL); } } else { fprintf(stderr, "Unexpected SmartCard IRP: MajorFunction 0x%08X MinorFunction: 0x%08X", irp->MajorFunction, irp->MinorFunction); irp->IoStatus = STATUS_NOT_SUPPORTED; Queue_Enqueue(smartcard->CompletedIrpQueue, (void*) irp); } }
static BOOL http_response_parse_header_field(HttpResponse* response, const char* name, const char* value) { BOOL status = TRUE; if (!response || !name) return FALSE; if (_stricmp(name, "Content-Length") == 0) { unsigned long long val; errno = 0; val = _strtoui64(value, NULL, 0); if ((errno != 0) || (val > INT32_MAX)) return FALSE; response->ContentLength = val; } else if (_stricmp(name, "Content-Type") == 0) { response->ContentType = value; if (!response->ContentType) return FALSE; } else if (_stricmp(name, "WWW-Authenticate") == 0) { char* separator = NULL; const char* authScheme = NULL; char* authValue = NULL; separator = strchr(value, ' '); if (separator) { /* WWW-Authenticate: Basic realm="" * WWW-Authenticate: NTLM base64token * WWW-Authenticate: Digest realm="*****@*****.**", qop="auth, auth-int", * nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093", * opaque="5ccc069c403ebaf9f0171e9517f40e41" */ *separator = '\0'; authScheme = value; authValue = separator + 1; if (!authScheme || !authValue) return FALSE; } else { authScheme = value; if (!authScheme) return FALSE; authValue = NULL; } status = ListDictionary_Add(response->Authenticates, authScheme, authValue); } return status; }
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; }
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); }
BOOL CryptProtectMemory(LPVOID pData, DWORD cbData, DWORD dwFlags) { BYTE* pCipherText; size_t cbOut, cbFinal; WINPR_CIPHER_CTX* enc = NULL; BYTE randomKey[256]; WINPR_PROTECTED_MEMORY_BLOCK* pMemBlock; if (dwFlags != CRYPTPROTECTMEMORY_SAME_PROCESS) return FALSE; if (!g_ProtectedMemoryBlocks) { g_ProtectedMemoryBlocks = ListDictionary_New(TRUE); if (!g_ProtectedMemoryBlocks) return FALSE; } pMemBlock = (WINPR_PROTECTED_MEMORY_BLOCK*) calloc(1, sizeof(WINPR_PROTECTED_MEMORY_BLOCK)); if (!pMemBlock) return FALSE; pMemBlock->pData = pData; pMemBlock->cbData = cbData; pMemBlock->dwFlags = dwFlags; winpr_RAND(pMemBlock->salt, 8); winpr_RAND(randomKey, sizeof(randomKey)); winpr_openssl_BytesToKey(WINPR_CIPHER_AES_256_CBC, WINPR_MD_SHA1, pMemBlock->salt, randomKey, sizeof(randomKey), 4, pMemBlock->key, pMemBlock->iv); SecureZeroMemory(randomKey, sizeof(randomKey)); cbOut = pMemBlock->cbData + 16 - 1; pCipherText = (BYTE*) malloc(cbOut); if (!pCipherText) goto out; if ((enc = winpr_Cipher_New(WINPR_CIPHER_AES_256_CBC, WINPR_ENCRYPT, pMemBlock->key, pMemBlock->iv)) == NULL) goto out; if (!winpr_Cipher_Update(enc, pMemBlock->pData, pMemBlock->cbData, pCipherText, &cbOut)) goto out; if (!winpr_Cipher_Final(enc, pCipherText + cbOut, &cbFinal)) goto out; winpr_Cipher_Free(enc); CopyMemory(pMemBlock->pData, pCipherText, pMemBlock->cbData); free(pCipherText); return ListDictionary_Add(g_ProtectedMemoryBlocks, pData, pMemBlock); out: free (pMemBlock); free (pCipherText); winpr_Cipher_Free(enc); return FALSE; }
/** * Function description * * @return 0 on success, otherwise a Win32 error code */ static UINT drive_process_irp_create(DRIVE_DEVICE* drive, IRP* irp) { int status; void* key; UINT32 FileId; DRIVE_FILE* file; BYTE Information; UINT32 DesiredAccess; UINT32 CreateDisposition; UINT32 CreateOptions; UINT32 PathLength; char* path = NULL; Stream_Read_UINT32(irp->input, DesiredAccess); Stream_Seek(irp->input, 16); /* AllocationSize(8), FileAttributes(4), SharedAccess(4) */ Stream_Read_UINT32(irp->input, CreateDisposition); Stream_Read_UINT32(irp->input, CreateOptions); Stream_Read_UINT32(irp->input, PathLength); status = ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) Stream_Pointer(irp->input), PathLength / 2, &path, 0, NULL, NULL); if (status < 1) { path = (char*) calloc(1, 1); if (!path) { WLog_ERR(TAG, "calloc failed!"); return CHANNEL_RC_NO_MEMORY; } } FileId = irp->devman->id_sequence++; file = drive_file_new(drive->path, path, FileId, DesiredAccess, CreateDisposition, CreateOptions); if (!file) { irp->IoStatus = STATUS_UNSUCCESSFUL; FileId = 0; Information = 0; } else if (file->err) { FileId = 0; Information = 0; /* map errno to windows result */ irp->IoStatus = drive_map_posix_err(file->err); drive_file_free(file); } else { key = (void*)(size_t) file->id; if (!ListDictionary_Add(drive->files, key, file)) { WLog_ERR(TAG, "ListDictionary_Add failed!"); free(path); return ERROR_INTERNAL_ERROR; } switch (CreateDisposition) { case FILE_SUPERSEDE: case FILE_OPEN: case FILE_CREATE: case FILE_OVERWRITE: Information = FILE_SUPERSEDED; break; case FILE_OPEN_IF: Information = FILE_OPENED; break; case FILE_OVERWRITE_IF: Information = FILE_OVERWRITTEN; break; default: Information = 0; break; } } Stream_Write_UINT32(irp->output, FileId); Stream_Write_UINT8(irp->output, Information); free(path); return irp->Complete(irp); }
/** * Function description * * @return 0 on success, otherwise a Win32 error code */ UINT smartcard_process_irp(SMARTCARD_DEVICE* smartcard, IRP* irp) { void* key; LONG status; BOOL asyncIrp = FALSE; SMARTCARD_CONTEXT* pContext = NULL; SMARTCARD_OPERATION* operation = NULL; key = (void*) (size_t) irp->CompletionId; if (!ListDictionary_Add(smartcard->rgOutstandingMessages, key, irp)) { WLog_ERR(TAG, "ListDictionary_Add failed!"); return ERROR_INTERNAL_ERROR; } if (irp->MajorFunction == IRP_MJ_DEVICE_CONTROL) { operation = (SMARTCARD_OPERATION*) calloc(1, sizeof(SMARTCARD_OPERATION)); if (!operation) { WLog_ERR(TAG, "calloc failed!"); return CHANNEL_RC_NO_MEMORY; } operation->irp = irp; status = smartcard_irp_device_control_decode(smartcard, operation); if (status != SCARD_S_SUCCESS) { irp->IoStatus = (UINT32)STATUS_UNSUCCESSFUL; if (!Queue_Enqueue(smartcard->CompletedIrpQueue, (void*) irp)) { WLog_ERR(TAG, "Queue_Enqueue failed!"); return ERROR_INTERNAL_ERROR; } return CHANNEL_RC_OK; } asyncIrp = TRUE; /** * The following matches mstsc's behavior of processing * only certain requests asynchronously while processing * those expected to return fast synchronously. */ switch (operation->ioControlCode) { case SCARD_IOCTL_ESTABLISHCONTEXT: case SCARD_IOCTL_RELEASECONTEXT: case SCARD_IOCTL_ISVALIDCONTEXT: case SCARD_IOCTL_LISTREADERGROUPSA: case SCARD_IOCTL_LISTREADERGROUPSW: case SCARD_IOCTL_LISTREADERSA: case SCARD_IOCTL_LISTREADERSW: case SCARD_IOCTL_INTRODUCEREADERGROUPA: case SCARD_IOCTL_INTRODUCEREADERGROUPW: case SCARD_IOCTL_FORGETREADERGROUPA: case SCARD_IOCTL_FORGETREADERGROUPW: case SCARD_IOCTL_INTRODUCEREADERA: case SCARD_IOCTL_INTRODUCEREADERW: case SCARD_IOCTL_FORGETREADERA: case SCARD_IOCTL_FORGETREADERW: case SCARD_IOCTL_ADDREADERTOGROUPA: case SCARD_IOCTL_ADDREADERTOGROUPW: case SCARD_IOCTL_REMOVEREADERFROMGROUPA: case SCARD_IOCTL_REMOVEREADERFROMGROUPW: case SCARD_IOCTL_LOCATECARDSA: case SCARD_IOCTL_LOCATECARDSW: case SCARD_IOCTL_LOCATECARDSBYATRA: case SCARD_IOCTL_LOCATECARDSBYATRW: case SCARD_IOCTL_CANCEL: case SCARD_IOCTL_READCACHEA: case SCARD_IOCTL_READCACHEW: case SCARD_IOCTL_WRITECACHEA: case SCARD_IOCTL_WRITECACHEW: case SCARD_IOCTL_GETREADERICON: case SCARD_IOCTL_GETDEVICETYPEID: asyncIrp = FALSE; break; case SCARD_IOCTL_GETSTATUSCHANGEA: case SCARD_IOCTL_GETSTATUSCHANGEW: asyncIrp = TRUE; break; case SCARD_IOCTL_CONNECTA: case SCARD_IOCTL_CONNECTW: case SCARD_IOCTL_RECONNECT: case SCARD_IOCTL_DISCONNECT: case SCARD_IOCTL_BEGINTRANSACTION: case SCARD_IOCTL_ENDTRANSACTION: case SCARD_IOCTL_STATE: case SCARD_IOCTL_STATUSA: case SCARD_IOCTL_STATUSW: case SCARD_IOCTL_TRANSMIT: case SCARD_IOCTL_CONTROL: case SCARD_IOCTL_GETATTRIB: case SCARD_IOCTL_SETATTRIB: case SCARD_IOCTL_GETTRANSMITCOUNT: asyncIrp = TRUE; break; case SCARD_IOCTL_ACCESSSTARTEDEVENT: case SCARD_IOCTL_RELEASESTARTEDEVENT: asyncIrp = FALSE; break; } pContext = ListDictionary_GetItemValue(smartcard->rgSCardContextList, (void*) operation->hContext); if (!pContext) asyncIrp = FALSE; if (!asyncIrp) { if ((status = smartcard_irp_device_control_call(smartcard, operation))) { WLog_ERR(TAG, "smartcard_irp_device_control_call failed with error %lu!", status); return (UINT32)status; } if (!Queue_Enqueue(smartcard->CompletedIrpQueue, (void*) irp)) { WLog_ERR(TAG, "Queue_Enqueue failed!"); return ERROR_INTERNAL_ERROR; } free(operation); } else { if (pContext) { if (!MessageQueue_Post(pContext->IrpQueue, NULL, 0, (void*) operation, NULL)) { WLog_ERR(TAG, "MessageQueue_Post failed!"); return ERROR_INTERNAL_ERROR; } } } } else { WLog_ERR(TAG, "Unexpected SmartCard IRP: MajorFunction 0x%08X MinorFunction: 0x%08X", irp->MajorFunction, irp->MinorFunction); irp->IoStatus = (UINT32)STATUS_NOT_SUPPORTED; if (!Queue_Enqueue(smartcard->CompletedIrpQueue, (void*) irp)) { WLog_ERR(TAG, "Queue_Enqueue failed!"); return ERROR_INTERNAL_ERROR; } } return CHANNEL_RC_OK; }
int pbrpc_call_method(rdsServer* server, UINT32 type, pbRPCPayload* request, pbRPCPayload** response) { UINT32 tag; DWORD wait_ret; pbRPCTransaction ta; UINT32 ret = PBRPC_FAILED; FDSAPI_MSG_PACKET* msg; pbRPCContext* context = server->rpc; struct pbrpc_local_call_context local_context; if (!context->isConnected) return PBRCP_TRANSPORT_ERROR; tag = pbrpc_getTag(context); msg = pbrpc_message_new(); msg->callId = tag; msg->status = FDSAPI_STATUS_SUCCESS; msg->buffer = request->buffer; msg->length = request->length; msg->msgType = FDSAPI_REQUEST_ID(type); ZeroMemory(&local_context, sizeof(local_context)); local_context.event = CreateEvent(NULL, TRUE, FALSE, NULL); local_context.status = PBRCP_CALL_TIMEOUT; ta.responseCallback = pbrpc_response_local_cb; ta.callbackArg = &local_context; ta.freeAfterResponse = FALSE; ListDictionary_Add(context->transactions, (void*)((UINT_PTR)(msg->callId)), &ta); Queue_Enqueue(context->writeQueue, msg); wait_ret = WaitForSingleObject(local_context.event, 10000); if (wait_ret != WAIT_OBJECT_0) { if (!ListDictionary_Remove(context->transactions, (void*)((UINT_PTR)(tag)))) { // special case - timeout occurred but request is already processing, see comment above WaitForSingleObject(local_context.event, INFINITE); } else { ret = PBRCP_CALL_TIMEOUT; } } CloseHandle(local_context.event); msg = local_context.response; if (!msg) { if (local_context.status) ret = local_context.status; else ret = PBRPC_FAILED; } else { *response = pbrpc_fill_payload(msg); ret = msg->status; pbrpc_message_free(msg, FALSE); } return ret; }