예제 #1
0
파일: freerdp.c 프로젝트: bjcollins/FreeRDP
void* freerdp_channel_get_open_handle_data(rdpChannelHandles* handles, DWORD openHandle)
{
	void* pUserData = NULL;
	void* pOpenHandle = (void*)(size_t) openHandle;
	pUserData = ListDictionary_GetItemValue(handles->open, pOpenHandle);
	return pUserData;
}
예제 #2
0
static void terminate_pending_irp_threads(SERIAL_DEVICE* serial)
{
	ULONG_PTR* ids;
	int i, nbIds;
	nbIds = ListDictionary_GetKeys(serial->IrpThreads, &ids);
	WLog_Print(serial->log, WLOG_DEBUG, "Terminating %d IRP thread(s)", nbIds);

	for (i = 0; i < nbIds; i++)
	{
		HANDLE irpThread;
		ULONG_PTR id = ids[i];
		irpThread = ListDictionary_GetItemValue(serial->IrpThreads, (void*)id);
		TerminateThread(irpThread, 0);

		if (WaitForSingleObject(irpThread, INFINITE) == WAIT_FAILED)
		{
			WLog_ERR(TAG, "WaitForSingleObject failed!");
			continue;
		}

		CloseHandle(irpThread);
		WLog_Print(serial->log, WLOG_DEBUG, "IRP thread terminated, CompletionId %p", (void*) id);
	}

	ListDictionary_Clear(serial->IrpThreads);
}
예제 #3
0
파일: thread.c 프로젝트: dcatonR1/FreeRDP
HANDLE _GetCurrentThread(VOID)
{
	HANDLE hdl = NULL;
	pthread_t tid = pthread_self();

	if (!thread_list)
	{
		WLog_ERR(TAG, "function called without existing thread list!");
#if defined(WITH_DEBUG_THREADS)
		DumpThreadHandles();
#endif
	}
	else if (!ListDictionary_Contains(thread_list, &tid))
	{
		WLog_ERR(TAG, "function called, but no matching entry in thread list!");
#if defined(WITH_DEBUG_THREADS)
		DumpThreadHandles();
#endif
	}
	else
	{
		hdl = ListDictionary_GetItemValue(thread_list, &tid);
	}

	return hdl;
}
예제 #4
0
파일: rdg.c 프로젝트: mfleisz/FreeRDP
static BOOL rdg_handle_ntlm_challenge(rdpNtlm* ntlm, HttpResponse* response)
{
	char* token64 = NULL;
	int ntlmTokenLength = 0;
	BYTE* ntlmTokenData = NULL;

	if (response->StatusCode != HTTP_STATUS_DENIED)
	{
		WLog_DBG(TAG, "Unexpected NTLM challenge HTTP status: %d",
		         response->StatusCode);
		return FALSE;
	}

	token64 = ListDictionary_GetItemValue(response->Authenticates, "NTLM");

	if (!token64)
		return FALSE;

	crypto_base64_decode(token64, strlen(token64), &ntlmTokenData, &ntlmTokenLength);

	if (ntlmTokenData && ntlmTokenLength)
	{
		ntlm->inputBuffer[0].pvBuffer = ntlmTokenData;
		ntlm->inputBuffer[0].cbBuffer = ntlmTokenLength;
	}

	ntlm_authenticate(ntlm);
	return TRUE;
}
예제 #5
0
파일: dvcman.c 프로젝트: Auto-Droid/FreeRDP
void *get_callback_by_name(const char *name, void **context)
{
	struct cb_value *rc;

	if (!cb_dict)
	{
		DEBUG_WARN("'%s' not found, function list does not exist.",
				   name);
		return NULL;
	}

	if (!ListDictionary_Contains(cb_dict, (void *)name))
	{
		DEBUG_WARN("'%s' not found", name);
		return NULL;
	}

	rc = ListDictionary_GetItemValue(cb_dict, (void *)name);
	DEBUG_DVC("'%s'=%p found", name, rc);

	if (context)
		*context = rc->context;

	return rc->fkt;
}
예제 #6
0
int rpc_ncacn_http_recv_out_channel_response(rdpRpc* rpc, HttpResponse* response)
{
	char* token64 = NULL;
	int ntlmTokenLength = 0;
	BYTE* ntlmTokenData = NULL;
	rdpNtlm* ntlm = rpc->NtlmHttpOut->ntlm;

	if (ListDictionary_Contains(response->Authenticates, "NTLM"))
	{
		token64 = ListDictionary_GetItemValue(response->Authenticates, "NTLM");

		if (!token64)
			return -1;

		crypto_base64_decode(token64, strlen(token64), &ntlmTokenData, &ntlmTokenLength);
	}

	if (ntlmTokenData && ntlmTokenLength)
	{
		ntlm->inputBuffer[0].pvBuffer = ntlmTokenData;
		ntlm->inputBuffer[0].cbBuffer = ntlmTokenLength;
	}

	return 1;
}
예제 #7
0
void* encomsp_get_open_handle_data(DWORD openHandle)
{
	void* pUserData = NULL;
	void* pOpenHandle = (void*) (size_t) openHandle;
	pUserData = ListDictionary_GetItemValue(g_OpenHandles, pOpenHandle);
	return pUserData;
}
예제 #8
0
static DRIVE_FILE* drive_get_file_by_id(DRIVE_DEVICE* drive, UINT32 id)
{
	DRIVE_FILE* file = NULL;
	void* key = (void*)(size_t) id;
	file = (DRIVE_FILE*) ListDictionary_GetItemValue(drive->files, key);
	return file;
}
예제 #9
0
파일: ncacn_http.c 프로젝트: orosam/FreeRDP
int rpc_ncacn_http_recv_in_channel_response(rdpRpc* rpc)
{
	char* token64;
	int ntlm_token_length = 0;
	BYTE* ntlm_token_data = NULL;
	HttpResponse* http_response;
	rdpNtlm* ntlm = rpc->NtlmHttpIn->ntlm;

	http_response = http_response_recv(rpc->TlsIn);

	if (!http_response)
		return -1;

	if (ListDictionary_Contains(http_response->Authenticates, "NTLM"))
	{
		token64 = ListDictionary_GetItemValue(http_response->Authenticates, "NTLM");

		if (!token64)
			goto out;

		crypto_base64_decode(token64, strlen(token64), &ntlm_token_data, &ntlm_token_length);
	}

out:
	ntlm->inputBuffer[0].pvBuffer = ntlm_token_data;
	ntlm->inputBuffer[0].cbBuffer = ntlm_token_length;
	http_response_free(http_response);

	return 0;
}
예제 #10
0
파일: rdg.c 프로젝트: bceverly/FreeRDP
BOOL rdg_process_out_channel_response(rdpRdg* rdg, HttpResponse* response)
{
	int status;
	wStream* s;
	char* token64 = NULL;
	int ntlmTokenLength = 0;
	BYTE* ntlmTokenData = NULL;
	rdpNtlm* ntlm = rdg->ntlm;

	if (response->StatusCode != HTTP_STATUS_DENIED)
	{
		WLog_DBG(TAG, "RDG not supported");
		rdg->state = RDG_CLIENT_STATE_NOT_FOUND;
		return FALSE;
	}

	WLog_DBG(TAG, "Out Channel authorization required");

	if (ListDictionary_Contains(response->Authenticates, "NTLM"))
	{
		token64 = ListDictionary_GetItemValue(response->Authenticates, "NTLM");

		if (!token64)
		{
			return FALSE;
		}

		crypto_base64_decode(token64, strlen(token64), &ntlmTokenData, &ntlmTokenLength);
	}

	if (ntlmTokenData && ntlmTokenLength)
	{
		ntlm->inputBuffer[0].pvBuffer = ntlmTokenData;
		ntlm->inputBuffer[0].cbBuffer = ntlmTokenLength;
	}

	ntlm_authenticate(ntlm);

	s = rdg_build_http_request(rdg, "RDG_OUT_DATA");

	if (!s)
		return FALSE;

	status = tls_write_all(rdg->tlsOut, Stream_Buffer(s), Stream_Length(s));

	Stream_Free(s, TRUE);

	ntlm_free(rdg->ntlm);
	rdg->ntlm = NULL;

	if (status < 0)
	{
		return FALSE;
	}

	rdg->state = RDG_CLIENT_STATE_OUT_CHANNEL_AUTHORIZE;

	return TRUE;
}
예제 #11
0
파일: devman.c 프로젝트: BUGgs/FreeRDP
DEVICE* devman_get_device_by_id(DEVMAN* devman, UINT32 id)
{
	DEVICE* device = NULL;
	void* key = (void*) (size_t) id;

	device = (DEVICE*) ListDictionary_GetItemValue(devman->devices, key);

	return device;
}
예제 #12
0
파일: http.c 프로젝트: FreeRDP/FreeRDP
const char* http_response_get_auth_token(HttpResponse* respone, const char* method)
{
	if (!respone || !method)
		return NULL;

	if (!ListDictionary_Contains(respone->Authenticates, method))
		return NULL;

	return ListDictionary_GetItemValue(respone->Authenticates, method);
}
예제 #13
0
void freerds_update_frame_acknowledge(rdpContext* context, UINT32 frameId)
{
	SURFACE_FRAME* frame;
	rdsConnection* connection = (rdsConnection*) context;

	frame = (SURFACE_FRAME*) ListDictionary_GetItemValue(connection->FrameList, (void*) (size_t) frameId);

	if (frame)
	{
		ListDictionary_Remove(connection->FrameList, (void*) (size_t) frameId);
		free(frame);
	}
}
예제 #14
0
BOOL CryptUnprotectMemory(LPVOID pData, DWORD cbData, DWORD dwFlags)
{
	BYTE* pPlainText = NULL;
	size_t cbOut, cbFinal;
	WINPR_CIPHER_CTX* dec = NULL;
	WINPR_PROTECTED_MEMORY_BLOCK* pMemBlock = NULL;

	if (dwFlags != CRYPTPROTECTMEMORY_SAME_PROCESS)
		return FALSE;

	if (!g_ProtectedMemoryBlocks)
		return FALSE;

	pMemBlock = (WINPR_PROTECTED_MEMORY_BLOCK*) ListDictionary_GetItemValue(g_ProtectedMemoryBlocks, pData);

	if (!pMemBlock)
		goto out;

	cbOut = pMemBlock->cbData + 16 - 1;

	pPlainText = (BYTE*) malloc(cbOut);

	if (!pPlainText)
		goto out;

	if ((dec = winpr_Cipher_New(WINPR_CIPHER_AES_256_CBC, WINPR_DECRYPT,
				    pMemBlock->key, pMemBlock->iv)) == NULL)
		goto out;
	if (!winpr_Cipher_Update(dec, pMemBlock->pData, pMemBlock->cbData, pPlainText, &cbOut))
		goto out;
	if (!winpr_Cipher_Final(dec, pPlainText + cbOut, &cbFinal))
		goto out;
	winpr_Cipher_Free(dec);

	CopyMemory(pMemBlock->pData, pPlainText, pMemBlock->cbData);
	SecureZeroMemory(pPlainText, pMemBlock->cbData);
	free(pPlainText);

	ListDictionary_Remove(g_ProtectedMemoryBlocks, pData);

	free(pMemBlock);

	return TRUE;

out:
	free(pPlainText);
	free(pMemBlock);
	winpr_Cipher_Free(dec);
	return FALSE;
}
예제 #15
0
파일: thread.c 프로젝트: LoveSn0w/FreeRDP
VOID ExitThread(DWORD dwExitCode)
{
	DWORD rc;
	pthread_t tid = pthread_self();

	if (!thread_list)
	{
		WLog_ERR(TAG, "function called without existing thread list!");
#if defined(WITH_DEBUG_THREADS)
		DumpThreadHandles();
#endif
		pthread_exit(0);
	}
	else if (!ListDictionary_Contains(thread_list, &tid))
	{
		WLog_ERR(TAG, "function called, but no matching entry in thread list!");
#if defined(WITH_DEBUG_THREADS)
		DumpThreadHandles();
#endif
		pthread_exit(0);
	}
	else
	{
		WINPR_THREAD* thread;

		ListDictionary_Lock(thread_list);
		thread = ListDictionary_GetItemValue(thread_list, &tid);

		assert(thread);
		thread->exited = TRUE;
		thread->dwExitCode = dwExitCode;
#if defined(WITH_DEBUG_THREADS)
		thread->exit_stack = winpr_backtrace(20);
#endif
		ListDictionary_Unlock(thread_list);
		set_event(thread);

		rc = thread->dwExitCode;
		if (thread->detached || !thread->started)
			cleanup_handle(thread);

		pthread_exit((void*) (size_t) rc);
	}
}
예제 #16
0
파일: crypto.c 프로젝트: 10084462/FreeRDP
BOOL CryptUnprotectMemory(LPVOID pData, DWORD cbData, DWORD dwFlags)
{
	BYTE* pPlainText;
	int cbOut, cbFinal;
	WINPR_PROTECTED_MEMORY_BLOCK* pMemBlock;

	if (dwFlags != CRYPTPROTECTMEMORY_SAME_PROCESS)
		return FALSE;

	if (!g_ProtectedMemoryBlocks)
		return FALSE;

	pMemBlock = (WINPR_PROTECTED_MEMORY_BLOCK*) ListDictionary_GetItemValue(g_ProtectedMemoryBlocks, pData);

	if (!pMemBlock)
		return FALSE;

	/* AES Decryption */

	cbOut = pMemBlock->cbData + AES_BLOCK_SIZE - 1;
	pPlainText = (BYTE*) malloc(cbOut);

	EVP_DecryptInit_ex(&(pMemBlock->dec), NULL, NULL, NULL, NULL);
	EVP_DecryptUpdate(&(pMemBlock->dec), pPlainText, &cbOut, pMemBlock->pData, pMemBlock->cbData);
	EVP_DecryptFinal_ex(&(pMemBlock->dec), pPlainText + cbOut, &cbFinal);

	CopyMemory(pMemBlock->pData, pPlainText, pMemBlock->cbData);
	SecureZeroMemory(pPlainText, pMemBlock->cbData);
	free(pPlainText);

	ListDictionary_Remove(g_ProtectedMemoryBlocks, pData);

	/* AES Cleanup */

	EVP_CIPHER_CTX_cleanup(&(pMemBlock->enc));
	EVP_CIPHER_CTX_cleanup(&(pMemBlock->dec));

	free(pMemBlock);

	return TRUE;
}
예제 #17
0
파일: rpc.c 프로젝트: awakecoding/FreeRDS
static int pbrpc_process_response(rdsServer* server, FDSAPI_MSG_PACKET* msg)
{
	pbRPCContext* context = server->rpc;
	pbRPCTransaction* ta = ListDictionary_GetItemValue(context->transactions, (void*)((UINT_PTR)msg->callId));

	if (!ta)
	{
		fprintf(stderr,"unsoliciated response - ignoring (tag %d)\n", msg->callId);
		return 1;
	}

	ListDictionary_Remove(context->transactions, (void*)((UINT_PTR)msg->callId));

	if (ta->responseCallback)
		ta->responseCallback(msg->status, msg, ta->callbackArg);

	if (ta->freeAfterResponse)
		free(ta);

	return 0;
}
예제 #18
0
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;
}
예제 #19
0
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);
	}
}
예제 #20
0
LRESULT CALLBACK hotplug_proc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
	rdpdrPlugin *rdpdr;
	PDEV_BROADCAST_HDR lpdb = (PDEV_BROADCAST_HDR)lParam;

	rdpdr = (rdpdrPlugin *)GetWindowLongPtr(hWnd, GWLP_USERDATA);

	switch(Msg)
	{
		case WM_DEVICECHANGE:
			switch (wParam)
			{
				case DBT_DEVICEARRIVAL:
					if (lpdb -> dbch_devicetype == DBT_DEVTYP_VOLUME)
					{
						PDEV_BROADCAST_VOLUME lpdbv = (PDEV_BROADCAST_VOLUME)lpdb;
						DWORD unitmask = lpdbv->dbcv_unitmask;
						int i;
						char drive_path[4] = { 'c', ':', '/', '\0'};

						for (i = 0; i < 26; i++)
						{
							if (unitmask & 0x01)
							{
								RDPDR_DRIVE* drive;

								drive_path[0] = 'A' + i;

								drive = (RDPDR_DRIVE*) malloc(sizeof(RDPDR_DRIVE));
								ZeroMemory(drive, sizeof(RDPDR_DRIVE));

								drive->Type = RDPDR_DTYP_FILESYSTEM;

								drive->Path = _strdup(drive_path);
								drive_path[1] = '\0';
								drive->Name = _strdup(drive_path);
								devman_load_device_service(rdpdr->devman, (RDPDR_DEVICE *)drive);
								rdpdr_send_device_list_announce_request(rdpdr, TRUE);
							}
							unitmask = unitmask >> 1;
						}
					}
					break;

				case DBT_DEVICEREMOVECOMPLETE:
					if (lpdb -> dbch_devicetype == DBT_DEVTYP_VOLUME)
					{
						PDEV_BROADCAST_VOLUME lpdbv = (PDEV_BROADCAST_VOLUME)lpdb;
						DWORD unitmask = lpdbv->dbcv_unitmask;
						int i, j, count;
						char drive_name_upper, drive_name_lower;

						ULONG_PTR *keys;
						DEVICE_DRIVE_EXT *device_ext;
						UINT32 ids[1];

						for (i = 0; i < 26; i++)
						{
							if (unitmask & 0x01)
							{
								drive_name_upper = 'A' + i;
								drive_name_lower = 'a' + i;

								count = ListDictionary_GetKeys(rdpdr->devman->devices, &keys);

								for (j = 0; j < count; j++)
								{
									device_ext = (DEVICE_DRIVE_EXT *)ListDictionary_GetItemValue(rdpdr->devman->devices, (void *)keys[j]);
									if (device_ext->path[0] == drive_name_upper || device_ext->path[0] == drive_name_lower)
									{
										devman_unregister_device(rdpdr->devman, (void *)keys[j]);
										ids[0] = keys[j];
										rdpdr_send_device_list_remove_request(rdpdr, 1, ids);
										break;
									}
								}
							}
							unitmask = unitmask >> 1;
						}
					}
					break;

				default:
					break;
			}
예제 #21
0
void* encomsp_get_init_handle_data(void* pInitHandle)
{
	void* pUserData = NULL;
	pUserData = ListDictionary_GetItemValue(g_InitHandles, pInitHandle);
	return pUserData;
}
예제 #22
0
파일: thread.c 프로젝트: dcatonR1/FreeRDP
VOID DumpThreadHandles(void)
{
	char** msg;
	size_t used, i;
	void* stack = winpr_backtrace(20);
	WLog_DBG(TAG, "---------------- Called from ----------------------------");
	msg = winpr_backtrace_symbols(stack, &used);

	for (i = 0; i < used; i++)
	{
		WLog_DBG(TAG, "[%d]: %s", i, msg[i]);
	}

	free(msg);
	winpr_backtrace_free(stack);
	WLog_DBG(TAG, "---------------- Start Dumping thread handles -----------");

	if (!thread_list)
	{
		WLog_DBG(TAG, "All threads properly shut down and disposed of.");
	}
	else
	{
		ULONG_PTR* keys = NULL;
		ListDictionary_Lock(thread_list);
		int x, count = ListDictionary_GetKeys(thread_list, &keys);
		WLog_DBG(TAG, "Dumping %d elements", count);

		for (x = 0; x < count; x++)
		{
			WINPR_THREAD* thread = ListDictionary_GetItemValue(thread_list,
			                       (void*) keys[x]);
			WLog_DBG(TAG, "Thread [%d] handle created still not closed!", x);
			msg = winpr_backtrace_symbols(thread->create_stack, &used);

			for (i = 0; i < used; i++)
			{
				WLog_DBG(TAG, "[%d]: %s", i, msg[i]);
			}

			free(msg);

			if (thread->started)
			{
				WLog_DBG(TAG, "Thread [%d] still running!",	x);
			}
			else
			{
				WLog_DBG(TAG, "Thread [%d] exited at:", x);
				msg = winpr_backtrace_symbols(thread->exit_stack, &used);

				for (i = 0; i < used; i++)
					WLog_DBG(TAG, "[%d]: %s", i, msg[i]);

				free(msg);
			}
		}

		free(keys);
		ListDictionary_Unlock(thread_list);
	}

	WLog_DBG(TAG, "---------------- End Dumping thread handles -------------");
}
예제 #23
0
파일: freerdp.c 프로젝트: bjcollins/FreeRDP
void* freerdp_channel_get_init_handle_data(rdpChannelHandles* handles, void* pInitHandle)
{
	void* pUserData = NULL;
	pUserData = ListDictionary_GetItemValue(handles->init, pInitHandle);
	return pUserData;
}
예제 #24
0
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);
	}
}
예제 #25
0
/**
 * 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;
}
예제 #26
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);
}