int CallInLogOffUserSession::doStuff()
	{
		ConnectionPtr currentConnection = APP_CONTEXT.getConnectionStore()->getConnection(mConnectionId);

		if (!currentConnection)
		{
			WLog_Print(logger_CallInLogOffUserSession, WLOG_ERROR,
				"connection does not exist for connectionId=%lu", mConnectionId);
			mLoggedOff = false;
			return -1;
		}

		UINT32 sessionId = currentConnection->getSessionId();
		SessionPtr currentSession = APP_CONTEXT.getSessionStore()->getSession(sessionId);

		if (!currentSession)
		{
			WLog_Print(logger_CallInLogOffUserSession, WLOG_ERROR,
				"session does not exist for sessionId=%lu", sessionId);
			mLoggedOff = false;
			return -1;
		}

		WLog_Print(logger_CallInLogOffUserSession, WLOG_DEBUG,
			"logging off session (connectionId=%lu, sessionId=%lu)",
			mConnectionId, sessionId);

		currentSession->stopModule();

		APP_CONTEXT.getSessionStore()->removeSession(sessionId);
		APP_CONTEXT.getConnectionStore()->removeConnection(mConnectionId);
		mLoggedOff = true;

		return 0;
	}
Exemple #2
0
/**
 * Function description
 *
 * @return 0 on success, otherwise a Win32 error code
 */
static UINT rdpgfx_recv_create_surface_pdu(RDPGFX_CHANNEL_CALLBACK* callback,
        wStream* s)
{
	RDPGFX_CREATE_SURFACE_PDU pdu;
	RDPGFX_PLUGIN* gfx = (RDPGFX_PLUGIN*) callback->plugin;
	RdpgfxClientContext* context = (RdpgfxClientContext*) gfx->iface.pInterface;
	UINT error = CHANNEL_RC_OK;

	if (Stream_GetRemainingLength(s) < 7)
	{
		WLog_Print(gfx->log, WLOG_ERROR, "not enough data!");
		return ERROR_INVALID_DATA;
	}

	Stream_Read_UINT16(s, pdu.surfaceId); /* surfaceId (2 bytes) */
	Stream_Read_UINT16(s, pdu.width); /* width (2 bytes) */
	Stream_Read_UINT16(s, pdu.height); /* height (2 bytes) */
	Stream_Read_UINT8(s, pdu.pixelFormat); /* RDPGFX_PIXELFORMAT (1 byte) */
	WLog_Print(gfx->log, WLOG_DEBUG,
	         "RecvCreateSurfacePdu: surfaceId: %"PRIu16" width: %"PRIu16" height: %"PRIu16" pixelFormat: 0x%02"PRIX8"",
	         pdu.surfaceId, pdu.width, pdu.height, pdu.pixelFormat);

	if (context)
	{
		IFCALLRET(context->CreateSurface, error, context, &pdu);

		if (error)
			WLog_Print(gfx->log, WLOG_ERROR, "context->CreateSurface failed with error %"PRIu32"", error);
	}

	return error;
}
Exemple #3
0
/**
 * Function description
 *
 * @return 0 on success, otherwise a Win32 error code
 */
static UINT rdpgfx_recv_delete_encoding_context_pdu(RDPGFX_CHANNEL_CALLBACK*
        callback, wStream* s)
{
	RDPGFX_DELETE_ENCODING_CONTEXT_PDU pdu;
	RDPGFX_PLUGIN* gfx = (RDPGFX_PLUGIN*) callback->plugin;
	RdpgfxClientContext* context = (RdpgfxClientContext*) gfx->iface.pInterface;
	UINT error = CHANNEL_RC_OK;

	if (Stream_GetRemainingLength(s) < 6)
	{
		WLog_Print(gfx->log, WLOG_ERROR, "not enough data!");
		return ERROR_INVALID_DATA;
	}

	Stream_Read_UINT16(s, pdu.surfaceId); /* surfaceId (2 bytes) */
	Stream_Read_UINT32(s, pdu.codecContextId); /* codecContextId (4 bytes) */
	WLog_Print(gfx->log, WLOG_DEBUG, "RecvDeleteEncodingContextPdu: surfaceId: %"PRIu16" codecContextId: %"PRIu32"",
	         pdu.surfaceId, pdu.codecContextId);

	if (context)
	{
		IFCALLRET(context->DeleteEncodingContext, error, context, &pdu);

		if (error)
			WLog_Print(gfx->log, WLOG_ERROR, "context->DeleteEncodingContext failed with error %"PRIu32"", error);
	}

	return error;
}
Exemple #4
0
/**
 * Function description
 *
 * @return 0 on success, otherwise a Win32 error code
 */
static UINT rdpgfx_recv_start_frame_pdu(RDPGFX_CHANNEL_CALLBACK* callback,
                                        wStream* s)
{
	RDPGFX_START_FRAME_PDU pdu;
	RDPGFX_PLUGIN* gfx = (RDPGFX_PLUGIN*) callback->plugin;
	RdpgfxClientContext* context = (RdpgfxClientContext*) gfx->iface.pInterface;
	UINT error = CHANNEL_RC_OK;

	if (Stream_GetRemainingLength(s) < RDPGFX_START_FRAME_PDU_SIZE)
	{
		WLog_Print(gfx->log, WLOG_ERROR, "not enough data!");
		return ERROR_INVALID_DATA;
	}

	Stream_Read_UINT32(s, pdu.timestamp); /* timestamp (4 bytes) */
	Stream_Read_UINT32(s, pdu.frameId); /* frameId (4 bytes) */
	WLog_Print(gfx->log, WLOG_DEBUG, "RecvStartFramePdu: frameId: %"PRIu32" timestamp: 0x%08"PRIX32"",
	         pdu.frameId, pdu.timestamp);

	gfx->StartDecodingTime = GetTickCountPrecise();
	if (context)
	{
		IFCALLRET(context->StartFrame, error, context, &pdu);

		if (error)
			WLog_Print(gfx->log, WLOG_ERROR, "context->StartFrame failed with error %"PRIu32"", error);
	}

	gfx->UnacknowledgedFrames++;
	return error;
}
Exemple #5
0
/**
 * Function description
 *
 * @return 0 on success, otherwise a Win32 error code
 */
static UINT rdpgfx_recv_evict_cache_entry_pdu(RDPGFX_CHANNEL_CALLBACK* callback,
        wStream* s)
{
	RDPGFX_EVICT_CACHE_ENTRY_PDU pdu;
	RDPGFX_PLUGIN* gfx = (RDPGFX_PLUGIN*) callback->plugin;
	RdpgfxClientContext* context = (RdpgfxClientContext*) gfx->iface.pInterface;
	UINT error = CHANNEL_RC_OK;

	if (Stream_GetRemainingLength(s) < 2)
	{
		WLog_Print(gfx->log, WLOG_ERROR, "not enough data!");
		return ERROR_INVALID_DATA;
	}

	Stream_Read_UINT16(s, pdu.cacheSlot); /* cacheSlot (2 bytes) */
	WLog_Print(gfx->log, WLOG_DEBUG, "RecvEvictCacheEntryPdu: cacheSlot: %"PRIu16"", pdu.cacheSlot);

	if (context)
	{
		IFCALLRET(context->EvictCacheEntry, error, context, &pdu);

		if (error)
			WLog_Print(gfx->log, WLOG_ERROR, "context->EvictCacheEntry failed with error %"PRIu32"", error);
	}

	return error;
}
Exemple #6
0
/**
 * Function description
 *
 * @return 0 on success, otherwise a Win32 error code
 */
static UINT rdpgfx_recv_map_surface_to_output_pdu(RDPGFX_CHANNEL_CALLBACK*
        callback, wStream* s)
{
	RDPGFX_MAP_SURFACE_TO_OUTPUT_PDU pdu;
	RDPGFX_PLUGIN* gfx = (RDPGFX_PLUGIN*) callback->plugin;
	RdpgfxClientContext* context = (RdpgfxClientContext*) gfx->iface.pInterface;
	UINT error = CHANNEL_RC_OK;

	if (Stream_GetRemainingLength(s) < 12)
	{
		WLog_Print(gfx->log, WLOG_ERROR, "not enough data!");
		return ERROR_INVALID_DATA;
	}

	Stream_Read_UINT16(s, pdu.surfaceId); /* surfaceId (2 bytes) */
	Stream_Read_UINT16(s, pdu.reserved); /* reserved (2 bytes) */
	Stream_Read_UINT32(s, pdu.outputOriginX); /* outputOriginX (4 bytes) */
	Stream_Read_UINT32(s, pdu.outputOriginY); /* outputOriginY (4 bytes) */
	WLog_Print(gfx->log, WLOG_DEBUG,
	         "RecvMapSurfaceToOutputPdu: surfaceId: %"PRIu16" outputOriginX: %"PRIu32" outputOriginY: %"PRIu32"",
	         pdu.surfaceId, pdu.outputOriginX, pdu.outputOriginY);

	if (context)
	{
		IFCALLRET(context->MapSurfaceToOutput, error, context, &pdu);

		if (error)
			WLog_Print(gfx->log, WLOG_ERROR, "context->MapSurfaceToOutput failed with error %"PRIu32"", error);
	}

	return error;
}
Exemple #7
0
/**
 * Function description
 *
 * @return 0 on success, otherwise a Win32 error code
 */
static UINT rdpgfx_recv_map_surface_to_window_pdu(RDPGFX_CHANNEL_CALLBACK* callback,
        wStream* s)
{
	RDPGFX_MAP_SURFACE_TO_WINDOW_PDU pdu;
	RDPGFX_PLUGIN* gfx = (RDPGFX_PLUGIN*) callback->plugin;
	RdpgfxClientContext* context = (RdpgfxClientContext*) gfx->iface.pInterface;
	UINT error = CHANNEL_RC_OK;

	if (Stream_GetRemainingLength(s) < 18)
	{
		WLog_Print(gfx->log, WLOG_ERROR, "not enough data!");
		return ERROR_INVALID_DATA;
	}

	Stream_Read_UINT16(s, pdu.surfaceId); /* surfaceId (2 bytes) */
	Stream_Read_UINT64(s, pdu.windowId); /* windowId (8 bytes) */
	Stream_Read_UINT32(s, pdu.mappedWidth); /* mappedWidth (4 bytes) */
	Stream_Read_UINT32(s, pdu.mappedHeight); /* mappedHeight (4 bytes) */
	WLog_Print(gfx->log, WLOG_DEBUG,
	         "RecvMapSurfaceToWindowPdu: surfaceId: %"PRIu16" windowId: 0x%016"PRIX64" mappedWidth: %"PRIu32" mappedHeight: %"PRIu32"",
	         pdu.surfaceId, pdu.windowId, pdu.mappedWidth, pdu.mappedHeight);

	if (context && context->MapSurfaceToWindow)
	{
		IFCALLRET(context->MapSurfaceToWindow, error, context, &pdu);

		if (error)
			WLog_Print(gfx->log, WLOG_ERROR, "context->MapSurfaceToWindow failed with error %"PRIu32"", error);
	}

	return error;
}
Exemple #8
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 %d",
		           id);
	}

	ListDictionary_Clear(serial->IrpThreads);
}
Exemple #9
0
	void TaskSwitchTo::cleanUpOnError()
	{
		SessionPtr currentSession = APP_CONTEXT.getSessionStore()->getSession(m_NewSessionId);

		if (currentSession)
		{
			if (currentSession->getConnectState() == WTSActive)
			{
				// this was a new session for the connection, remove it
				currentSession->stopModule();
				APP_CONTEXT.getSessionStore()->removeSession(currentSession->getSessionId());
				WLog_Print(logger_taskSwitchTo, WLOG_INFO, "TaskSwitchTo: cleaning up session with sessionId %d", m_NewSessionId);
			}
			else if (currentSession->getConnectState() == WTSConnectQuery)
			{
				// was a previous disconnected session
				currentSession->setConnectState(WTSDisconnected);
			}
		}
		else
		{
			WLog_Print(logger_taskSwitchTo, WLOG_ERROR, "TaskSwitchTo: no session was found for sessionId %d!", m_NewSessionId);
		}

		ConnectionPtr connection = APP_CONTEXT.getConnectionStore()->getConnection(m_ConnectionId);

		if (connection) {
			connection->setAbout2SwitchSessionId(0);
		}
	}
Exemple #10
0
static void* transport_client_thread(void* arg)
{
	DWORD status;
	DWORD nCount;
	HANDLE handles[8];
	freerdp* instance;
	rdpContext* context;
	rdpTransport* transport;
	transport = (rdpTransport*) arg;
	assert(NULL != transport);
	assert(NULL != transport->settings);
	instance = (freerdp*) transport->settings->instance;
	assert(NULL != instance);
	context = instance->context;
	assert(NULL != instance->context);
	WLog_Print(transport->log, WLOG_DEBUG, "Starting transport thread");
	nCount = 0;
	handles[nCount++] = transport->stopEvent;
	handles[nCount++] = transport->connectedEvent;
	status = WaitForMultipleObjects(nCount, handles, FALSE, INFINITE);

	if (WaitForSingleObject(transport->stopEvent, 0) == WAIT_OBJECT_0)
	{
		WLog_Print(transport->log, WLOG_DEBUG, "Terminating transport thread");
		ExitThread(0);
		return NULL;
	}

	WLog_Print(transport->log, WLOG_DEBUG, "Asynchronous transport activated");

	while (1)
	{
		nCount = 0;
		handles[nCount++] = transport->stopEvent;
		transport_get_read_handles(transport, (HANDLE*) &handles, &nCount);
		status = WaitForMultipleObjects(nCount, handles, FALSE, INFINITE);

		if (transport->layer == TRANSPORT_LAYER_CLOSED)
		{
			rdpRdp* rdp = (rdpRdp*) transport->rdp;
			rdp_set_error_info(rdp, ERRINFO_PEER_DISCONNECTED);
			break;
		}
		else if (status != WAIT_TIMEOUT)
		{
			if (WaitForSingleObject(transport->stopEvent, 0) == WAIT_OBJECT_0)
				break;

			if (!freerdp_check_fds(instance))
			{
			}
		}
	}

	WLog_Print(transport->log, WLOG_DEBUG, "Terminating transport thread");
	ExitThread(0);
	return NULL;
}
Exemple #11
0
static VOID VCAPITYPE drdynvc_virtual_channel_init_event_ex(LPVOID lpUserParam, LPVOID pInitHandle,
        UINT event, LPVOID pData, UINT dataLength)
{
	UINT error = CHANNEL_RC_OK;
	drdynvcPlugin* drdynvc = (drdynvcPlugin*) lpUserParam;

	if (!drdynvc || (drdynvc->InitHandle != pInitHandle))
	{
		WLog_ERR(TAG, "drdynvc_virtual_channel_init_event: error no match");
		return;
	}

	switch (event)
	{
		case CHANNEL_EVENT_CONNECTED:
			if ((error = drdynvc_virtual_channel_event_connected(drdynvc, pData, dataLength)))
				WLog_Print(drdynvc->log, WLOG_ERROR,
				           "drdynvc_virtual_channel_event_connected failed with error %"PRIu32"", error);

			break;

		case CHANNEL_EVENT_DISCONNECTED:
			if ((error =  drdynvc_virtual_channel_event_disconnected(drdynvc)))
				WLog_Print(drdynvc->log, WLOG_ERROR,
				           "drdynvc_virtual_channel_event_disconnected failed with error %"PRIu32"", error);

			break;

		case CHANNEL_EVENT_TERMINATED:
			if ((error =  drdynvc_virtual_channel_event_terminated(drdynvc)))
				WLog_Print(drdynvc->log, WLOG_ERROR,
				           "drdynvc_virtual_channel_event_terminated failed with error %"PRIu32"", error);

			break;

		case CHANNEL_EVENT_ATTACHED:
			if ((error =  drdynvc_virtual_channel_event_attached(drdynvc)))
				WLog_Print(drdynvc->log, WLOG_ERROR,
				           "drdynvc_virtual_channel_event_attached failed with error %"PRIu32"", error);

			break;

		case CHANNEL_EVENT_DETACHED:
			if ((error =  drdynvc_virtual_channel_event_detached(drdynvc)))
				WLog_Print(drdynvc->log, WLOG_ERROR,
				           "drdynvc_virtual_channel_event_detached failed with error %"PRIu32"", error);

			break;

		default:
			break;
	}

	if (error && drdynvc->rdpcontext)
		setChannelError(drdynvc->rdpcontext, error,
		                "drdynvc_virtual_channel_init_event_ex reported an error");
}
Exemple #12
0
BOOL gdi_init_ex(freerdp* instance, UINT32 format, UINT32 stride, BYTE* buffer,
                 void (*pfree)(void*))
{
	UINT32 SrcFormat = gdi_get_pixel_format(instance->settings->ColorDepth);
	rdpGdi* gdi = (rdpGdi*) calloc(1, sizeof(rdpGdi));
	rdpContext* context = instance->context;

	if (!gdi)
		goto fail;

	instance->context->gdi = gdi;
	gdi->log = WLog_Get(TAG);

	if (!gdi->log)
		goto fail;

	gdi->context = instance->context;
	gdi->width = instance->settings->DesktopWidth;
	gdi->height = instance->settings->DesktopHeight;
	gdi->dstFormat = format;
	/* default internal buffer format */
	WLog_Print(gdi->log, WLOG_INFO, "Local framebuffer format  %s",
	           GetColorFormatName(gdi->dstFormat));
	WLog_Print(gdi->log, WLOG_INFO, "Remote framebuffer format %s",
	           GetColorFormatName(SrcFormat));

	if (!(gdi->hdc = gdi_GetDC()))
		goto fail;

	gdi->hdc->format = gdi->dstFormat;

	if (!gdi_init_primary(gdi, stride, gdi->dstFormat, buffer, pfree))
		goto fail;

	if (!(context->cache = cache_new(instance->settings)))
		goto fail;

	if (!freerdp_client_codecs_prepare(context->codecs, FREERDP_CODEC_ALL,
	                                   gdi->width, gdi->height))
		goto fail;

	gdi_register_update_callbacks(instance->update);
	brush_cache_register_callbacks(instance->update);
	glyph_cache_register_callbacks(instance->update);
	bitmap_cache_register_callbacks(instance->update);
	offscreen_cache_register_callbacks(instance->update);
	palette_cache_register_callbacks(instance->update);

	if (!gdi_register_graphics(instance->context->graphics))
		goto fail;

	return TRUE;
fail:
	gdi_free(instance);
	WLog_ERR(TAG,  "failed to initialize gdi");
	return FALSE;
}
Exemple #13
0
static void* transport_client_thread(void* arg)
{
	DWORD status;
	DWORD nCount;
	HANDLE handles[8];
	freerdp* instance;
	rdpContext* context;
	rdpTransport* transport;

	transport = (rdpTransport*) arg;
	assert(NULL != transport);
	assert(NULL != transport->settings);
	
	instance = (freerdp*) transport->settings->instance;
	assert(NULL != instance);
	
	context = instance->context;
	assert(NULL != instance->context);
	
	WLog_Print(transport->log, WLOG_DEBUG, "Starting transport thread");

	nCount = 0;
	handles[nCount++] = transport->stopEvent;
	handles[nCount++] = transport->connectedEvent;
	
	status = WaitForMultipleObjects(nCount, handles, FALSE, INFINITE);
	
	if (WaitForSingleObject(transport->stopEvent, 0) == WAIT_OBJECT_0)
	{
		WLog_Print(transport->log, WLOG_DEBUG, "Terminating transport thread");
		ExitThread(0);
		return NULL;
	}

	WLog_Print(transport->log, WLOG_DEBUG, "Asynchronous transport activated");

	while (1)
	{
		nCount = 0;
		handles[nCount++] = transport->stopEvent;

		transport_get_read_handles(transport, (HANDLE*) &handles, &nCount);

		status = WaitForMultipleObjects(nCount, handles, FALSE, INFINITE);

		if (WaitForSingleObject(transport->stopEvent, 0) == WAIT_OBJECT_0)
			break;

		if (!freerdp_check_fds(instance))
			break;
	}

	WLog_Print(transport->log, WLOG_DEBUG, "Terminating transport thread");

	ExitThread(0);
	return NULL;
}
Exemple #14
0
/**
 * Function description
 *
 * @return 0 on success, otherwise a Win32 error code
 */
static UINT serial_process_irp_read(SERIAL_DEVICE* serial, IRP* irp)
{
	UINT32 Length;
	UINT64 Offset;
	BYTE* buffer = NULL;
	DWORD nbRead = 0;
	Stream_Read_UINT32(irp->input, Length); /* Length (4 bytes) */
	Stream_Read_UINT64(irp->input, Offset); /* Offset (8 bytes) */
	Stream_Seek(irp->input, 20); /* Padding (20 bytes) */
	buffer = (BYTE*)calloc(Length, sizeof(BYTE));

	if (buffer == NULL)
	{
		irp->IoStatus = STATUS_NO_MEMORY;
		goto error_handle;
	}

	/* MS-RDPESP 3.2.5.1.4: If the Offset field is not set to 0, the value MUST be ignored
	 * assert(Offset == 0);
	 */
	WLog_Print(serial->log, WLOG_DEBUG, "reading %d bytes from %s", Length,
	           serial->device.name);

	/* FIXME: CommReadFile to be replaced by ReadFile */
	if (CommReadFile(serial->hComm, buffer, Length, &nbRead, NULL))
	{
		irp->IoStatus = STATUS_SUCCESS;
	}
	else
	{
		WLog_Print(serial->log, WLOG_DEBUG,
		           "read failure to %s, nbRead=%ld, last-error: 0x%lX", serial->device.name,
		           nbRead, GetLastError());
		irp->IoStatus = _GetLastErrorToIoStatus(serial);
	}

	WLog_Print(serial->log, WLOG_DEBUG, "%lu bytes read from %s", nbRead,
	           serial->device.name);
error_handle:
	Stream_Write_UINT32(irp->output, nbRead); /* Length (4 bytes) */

	if (nbRead > 0)
	{
		if (!Stream_EnsureRemainingCapacity(irp->output, nbRead))
		{
			WLog_ERR(TAG, "Stream_EnsureRemainingCapacity failed!");
			free(buffer);
			return CHANNEL_RC_NO_MEMORY;
		}

		Stream_Write(irp->output, buffer, nbRead); /* ReadData */
	}

	free(buffer);
	return CHANNEL_RC_OK;
}
Exemple #15
0
/**
 * Function description
 *
 * @return 0 on success, otherwise a Win32 error code
 */
static UINT drdynvc_virtual_channel_event_data_received(drdynvcPlugin* drdynvc,
        void* pData, UINT32 dataLength, UINT32 totalLength, UINT32 dataFlags)
{
	wStream* data_in;

	if ((dataFlags & CHANNEL_FLAG_SUSPEND) || (dataFlags & CHANNEL_FLAG_RESUME))
	{
		return CHANNEL_RC_OK;
	}

	if (dataFlags & CHANNEL_FLAG_FIRST)
	{
		if (drdynvc->data_in)
			Stream_Free(drdynvc->data_in, TRUE);

		drdynvc->data_in = Stream_New(NULL, totalLength);
	}

	if (!(data_in = drdynvc->data_in))
	{
		WLog_Print(drdynvc->log, WLOG_ERROR, "Stream_New failed!");
		return CHANNEL_RC_NO_MEMORY;
	}

	if (!Stream_EnsureRemainingCapacity(data_in, dataLength))
	{
		WLog_Print(drdynvc->log, WLOG_ERROR, "Stream_EnsureRemainingCapacity failed!");
		Stream_Free(drdynvc->data_in, TRUE);
		drdynvc->data_in = NULL;
		return ERROR_INTERNAL_ERROR;
	}

	Stream_Write(data_in, pData, dataLength);

	if (dataFlags & CHANNEL_FLAG_LAST)
	{
		if (Stream_Capacity(data_in) != Stream_GetPosition(data_in))
		{
			WLog_Print(drdynvc->log, WLOG_ERROR, "drdynvc_plugin_process_received: read error");
			return ERROR_INVALID_DATA;
		}

		drdynvc->data_in = NULL;
		Stream_SealLength(data_in);
		Stream_SetPosition(data_in, 0);

		if (!MessageQueue_Post(drdynvc->queue, NULL, 0, (void*) data_in, NULL))
		{
			WLog_Print(drdynvc->log, WLOG_ERROR, "MessageQueue_Post failed!");
			return ERROR_INTERNAL_ERROR;
		}
	}

	return CHANNEL_RC_OK;
}
Exemple #16
0
static void transport_ssl_cb(SSL* ssl, int where, int ret)
{
	if (where & SSL_CB_ALERT)
	{
		rdpTransport* transport = (rdpTransport*) SSL_get_app_data(ssl);

		switch (ret)
		{
			case (SSL3_AL_FATAL << 8) | SSL_AD_ACCESS_DENIED:
				{
					if (!freerdp_get_last_error(transport->context))
					{
						WLog_Print(transport->log, WLOG_ERROR, "%s: ACCESS DENIED", __FUNCTION__);
						freerdp_set_last_error(transport->context, FREERDP_ERROR_AUTHENTICATION_FAILED);
					}
				}
				break;

			case (SSL3_AL_FATAL << 8) | SSL_AD_INTERNAL_ERROR:
				{
					if (transport->NlaMode)
					{
						UINT32 kret = 0;
#ifdef WITH_GSSAPI

						if ((strlen(transport->settings->Domain) != 0) &&
						    (strncmp(transport->settings->Domain, ".", 1) != 0))
						{
							kret = transport_krb5_check_account(transport, transport->settings->Username,
							                                    transport->settings->Domain,
							                                    transport->settings->Password);
						}
						else
#endif /* WITH_GSSAPI */
							kret = FREERDP_ERROR_CONNECT_PASSWORD_CERTAINLY_EXPIRED;

						if (!freerdp_get_last_error(transport->context))
							freerdp_set_last_error(transport->context, kret);
					}

					break;

				case (SSL3_AL_WARNING << 8) | SSL3_AD_CLOSE_NOTIFY:
					break;

				default:
					WLog_Print(transport->log, WLOG_WARN, "Unhandled SSL error (where=%d, ret=%d [%s, %s])", where, ret,
					           SSL_alert_type_string_long(ret), SSL_alert_desc_string_long(ret));
					break;
				}
		}
	}
}
Exemple #17
0
/**
 * 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;
}
Exemple #18
0
static BOOL rfx_process_message_context(RFX_CONTEXT* context, wStream* s)
{
	BYTE ctxId;
	UINT16 tileSize;
	UINT16 properties;

	context->decodedHeaderBlocks &= ~_RFX_DECODED_CONTEXT;

	if (Stream_GetRemainingLength(s) < 5)
	{
		WLog_ERR(TAG, "RfxMessageContext packet too small");
		return FALSE;
	}

	Stream_Read_UINT8(s, ctxId); /* ctxId (1 byte), must be set to 0x00 */
	Stream_Read_UINT16(s, tileSize); /* tileSize (2 bytes), must be set to CT_TILE_64x64 (0x0040) */
	Stream_Read_UINT16(s, properties); /* properties (2 bytes) */

	WLog_Print(context->priv->log, WLOG_DEBUG, "ctxId %d tileSize %d properties 0x%X.",
			ctxId, tileSize, properties);

	context->properties = properties;
	context->flags = (properties & 0x0007);

	if (context->flags == CODEC_MODE)
	{
		WLog_Print(context->priv->log, WLOG_DEBUG, "codec is in image mode.");
	}
	else
	{
		WLog_Print(context->priv->log, WLOG_DEBUG, "codec is in video mode.");
	}

	switch ((properties & 0x1E00) >> 9)
	{
		case CLW_ENTROPY_RLGR1:
			context->mode = RLGR1;
			WLog_Print(context->priv->log, WLOG_DEBUG, "RLGR1.");
			break;

		case CLW_ENTROPY_RLGR3:
			context->mode = RLGR3;
			WLog_Print(context->priv->log, WLOG_DEBUG, "RLGR3.");
			break;

		default:
			WLog_ERR(TAG, "unknown RLGR algorithm.");
			return FALSE;
	}

	context->decodedHeaderBlocks |= _RFX_DECODED_CONTEXT;
	return TRUE;
}
Exemple #19
0
static BOOL openh264_load_functionpointers(H264_CONTEXT* h264, const char* name)
{
	H264_CONTEXT_OPENH264* sysContexts;

	if (!h264)
		return FALSE;

	sysContexts = h264->pSystemData;

	if (!sysContexts)
		return FALSE;

	sysContexts->lib = LoadLibraryA(name);

	if (!sysContexts->lib)
		return FALSE;

	sysContexts->WelsGetCodecVersionEx = (pWelsGetCodecVersionEx) GetProcAddress(sysContexts->lib, "WelsGetCodecVersionEx");
	sysContexts->WelsCreateDecoder = (pWelsCreateDecoder) GetProcAddress(sysContexts->lib, "WelsCreateDecoder");
	sysContexts->WelsDestroyDecoder = (pWelsDestroyDecoder) GetProcAddress(sysContexts->lib, "WelsDestroyDecoder");
	sysContexts->WelsCreateSVCEncoder = (pWelsCreateSVCEncoder) GetProcAddress(sysContexts->lib, "WelsCreateSVCEncoder");
	sysContexts->WelsDestroySVCEncoder = (pWelsDestroySVCEncoder) GetProcAddress(sysContexts->lib, "WelsDestroySVCEncoder");

	if (!sysContexts->WelsCreateDecoder || !sysContexts->WelsDestroyDecoder ||
	    !sysContexts->WelsCreateSVCEncoder || !sysContexts->WelsDestroySVCEncoder ||
	    !sysContexts->WelsGetCodecVersionEx)
	{
		FreeLibrary(sysContexts->lib);
		sysContexts->lib = NULL;
		return FALSE;
	}

	sysContexts->WelsGetCodecVersionEx(&sysContexts->version);
	WLog_Print(h264->log, WLOG_INFO, "loaded %s %d.%d.%d", name, sysContexts->version.uMajor,
	           sysContexts->version.uMinor,
	           sysContexts->version.uRevision);

	if ((sysContexts->version.uMajor < 1) || (sysContexts->version.uMinor < 6))
	{
		WLog_Print(h264->log, WLOG_ERROR,
		           "OpenH264 %s %d.%d.%d is too old, need at least version 1.6.0 for dynamic loading",
		           name, sysContexts->version.uMajor, sysContexts->version.uMinor,
		           sysContexts->version.uRevision);
		FreeLibrary(sysContexts->lib);
		sysContexts->lib = NULL;
		return FALSE;
	}

	return TRUE;
}
Exemple #20
0
BOOL update_recv_window_info_order(rdpUpdate* update, wStream* s, WINDOW_ORDER_INFO* orderInfo)
{
	rdpContext* context = update->context;
	rdpWindowUpdate* window = update->window;
	BOOL result = TRUE;

	if (Stream_GetRemainingLength(s) < 4)
		return FALSE;

	Stream_Read_UINT32(s, orderInfo->windowId); /* windowId (4 bytes) */

	if (orderInfo->fieldFlags & WINDOW_ORDER_ICON)
	{
		if (!update_read_window_icon_order(s, orderInfo, &window->window_icon))
			return FALSE;
		WLog_Print(update->log, WLOG_DEBUG, "WindowIcon");
		IFCALLRET(window->WindowIcon, result, context, orderInfo, &window->window_icon);
	}
	else if (orderInfo->fieldFlags & WINDOW_ORDER_CACHED_ICON)
	{
		if (!update_read_window_cached_icon_order(s, orderInfo, &window->window_cached_icon))
			return FALSE;
		WLog_Print(update->log, WLOG_DEBUG, "WindowCachedIcon");
		IFCALLRET(window->WindowCachedIcon, result, context, orderInfo, &window->window_cached_icon);
	}
	else if (orderInfo->fieldFlags & WINDOW_ORDER_STATE_DELETED)
	{
		update_read_window_delete_order(s, orderInfo);
		WLog_Print(update->log, WLOG_DEBUG, "WindowDelete");
		IFCALLRET(window->WindowDelete, result, context, orderInfo);
	}
	else
	{
		if (!update_read_window_state_order(s, orderInfo, &window->window_state))
			return FALSE;

		if (orderInfo->fieldFlags & WINDOW_ORDER_STATE_NEW)
		{
			WLog_Print(update->log, WLOG_DEBUG, "WindowCreate");
			IFCALLRET(window->WindowCreate, result, context, orderInfo, &window->window_state);
		}
		else
		{
			WLog_Print(update->log, WLOG_DEBUG, "WindowUpdate");
			IFCALLRET(window->WindowUpdate, result, context, orderInfo, &window->window_state);
		}
	}

	return result;
}
Exemple #21
0
/**
 * Function description
 *
 * @return 0 on success, otherwise a Win32 error code
 */
static UINT rdpgfx_recv_wire_to_surface_2_pdu(RDPGFX_CHANNEL_CALLBACK* callback,
        wStream* s)
{
	RDPGFX_SURFACE_COMMAND cmd;
	RDPGFX_WIRE_TO_SURFACE_PDU_2 pdu;
	RDPGFX_PLUGIN* gfx = (RDPGFX_PLUGIN*) callback->plugin;
	RdpgfxClientContext* context = (RdpgfxClientContext*) gfx->iface.pInterface;
	UINT error = CHANNEL_RC_OK;

	if (Stream_GetRemainingLength(s) < RDPGFX_WIRE_TO_SURFACE_PDU_2_SIZE)
	{
		WLog_Print(gfx->log, WLOG_ERROR, "not enough data!");
		return ERROR_INVALID_DATA;
	}

	Stream_Read_UINT16(s, pdu.surfaceId); /* surfaceId (2 bytes) */
	Stream_Read_UINT16(s, pdu.codecId); /* codecId (2 bytes) */
	Stream_Read_UINT32(s, pdu.codecContextId); /* codecContextId (4 bytes) */
	Stream_Read_UINT8(s, pdu.pixelFormat); /* pixelFormat (1 byte) */
	Stream_Read_UINT32(s, pdu.bitmapDataLength); /* bitmapDataLength (4 bytes) */
	pdu.bitmapData = Stream_Pointer(s);
	Stream_Seek(s, pdu.bitmapDataLength);
	WLog_Print(gfx->log, WLOG_DEBUG, "RecvWireToSurface2Pdu: surfaceId: %"PRIu16" codecId: %s (0x%04"PRIX16") "
	         "codecContextId: %"PRIu32" pixelFormat: 0x%02"PRIX8" bitmapDataLength: %"PRIu32"",
	         pdu.surfaceId, rdpgfx_get_codec_id_string(pdu.codecId), pdu.codecId,
	         pdu.codecContextId, pdu.pixelFormat, pdu.bitmapDataLength);
	cmd.surfaceId = pdu.surfaceId;
	cmd.codecId = pdu.codecId;
	cmd.contextId = pdu.codecContextId;
	cmd.format = pdu.pixelFormat;
	cmd.left = 0;
	cmd.top = 0;
	cmd.right = 0;
	cmd.bottom = 0;
	cmd.width = 0;
	cmd.height = 0;
	cmd.length = pdu.bitmapDataLength;
	cmd.data = pdu.bitmapData;
	cmd.extra = NULL;

	if (context)
	{
		IFCALLRET(context->SurfaceCommand, error, context, &cmd);

		if (error)
			WLog_Print(gfx->log, WLOG_ERROR, "context->SurfaceCommand failed with error %"PRIu32"", error);
	}

	return error;
}
Exemple #22
0
/**
 * Function description
 *
 * @return 0 on success, otherwise a Win32 error code
 */
static UINT rdpgfx_recv_cache_import_reply_pdu(RDPGFX_CHANNEL_CALLBACK* callback,
        wStream* s)
{
	UINT16 index;
	RDPGFX_CACHE_IMPORT_REPLY_PDU pdu;
	RDPGFX_PLUGIN* gfx = (RDPGFX_PLUGIN*) callback->plugin;
	RdpgfxClientContext* context = (RdpgfxClientContext*) gfx->iface.pInterface;
	UINT error = CHANNEL_RC_OK;

	if (Stream_GetRemainingLength(s) < 2)
	{
		WLog_Print(gfx->log, WLOG_ERROR, "not enough data!");
		return ERROR_INVALID_DATA;
	}

	Stream_Read_UINT16(s, pdu.importedEntriesCount); /* cacheSlot (2 bytes) */

	if (Stream_GetRemainingLength(s) < (size_t)(pdu.importedEntriesCount * 2))
	{
		WLog_Print(gfx->log, WLOG_ERROR, "not enough data!");
		return ERROR_INVALID_DATA;
	}

	pdu.cacheSlots = (UINT16*) calloc(pdu.importedEntriesCount, sizeof(UINT16));
	if (!pdu.cacheSlots)
	{
		WLog_Print(gfx->log, WLOG_ERROR, "calloc failed!");
		return CHANNEL_RC_NO_MEMORY;
	}

	for (index = 0; index < pdu.importedEntriesCount; index++)
	{
		Stream_Read_UINT16(s, pdu.cacheSlots[index]); /* cacheSlot (2 bytes) */
	}

	WLog_Print(gfx->log, WLOG_DEBUG, "RecvCacheImportReplyPdu: importedEntriesCount: %"PRIu16"",
	         pdu.importedEntriesCount);

	if (context)
	{
		IFCALLRET(context->CacheImportReply, error, context, &pdu);

		if (error)
			WLog_Print(gfx->log, WLOG_ERROR, "context->CacheImportReply failed with error %"PRIu32"", error);
	}

	free(pdu.cacheSlots);
	return error;
}
Exemple #23
0
/**
 * Function description
 *
 * @return 0 on success, otherwise a Win32 error code
 */
static UINT dvcman_receive_channel_data(drdynvcPlugin* drdynvc,
                                        IWTSVirtualChannelManager* pChannelMgr,
                                        UINT32 ChannelId, wStream* data)
{
	UINT status = CHANNEL_RC_OK;
	DVCMAN_CHANNEL* channel;
	size_t dataSize = Stream_GetRemainingLength(data);
	channel = (DVCMAN_CHANNEL*) dvcman_find_channel_by_id(pChannelMgr, ChannelId);

	if (!channel)
	{
		/* Windows 8.1 tries to open channels not created.
				 * Ignore cases like this. */
		WLog_Print(drdynvc->log, WLOG_ERROR, "ChannelId %"PRIu32" not found!", ChannelId);
		return CHANNEL_RC_OK;
	}

	if (channel->dvc_data)
	{
		/* Fragmented data */
		if (Stream_GetPosition(channel->dvc_data) + dataSize > Stream_Capacity(channel->dvc_data))
		{
			WLog_Print(drdynvc->log, WLOG_ERROR, "data exceeding declared length!");
			Stream_Release(channel->dvc_data);
			channel->dvc_data = NULL;
			return ERROR_INVALID_DATA;
		}

		Stream_Copy(data, channel->dvc_data, dataSize);

		if (Stream_GetPosition(channel->dvc_data) >= channel->dvc_data_length)
		{
			Stream_SealLength(channel->dvc_data);
			Stream_SetPosition(channel->dvc_data, 0);
			status = channel->channel_callback->OnDataReceived(channel->channel_callback,
			         channel->dvc_data);
			Stream_Release(channel->dvc_data);
			channel->dvc_data = NULL;
		}
	}
	else
	{
		status = channel->channel_callback->OnDataReceived(channel->channel_callback,
		         data);
	}

	return status;
}
Exemple #24
0
BOOL glyph_cache_fragment_put(rdpGlyphCache* glyphCache, UINT32 index,
                              UINT32 size, const void* fragment)
{
	void* prevFragment;
	void* copy;

	if (index > 255)
	{
		WLog_ERR(TAG, "invalid glyph cache fragment index: %"PRIu32"", index);
		return FALSE;
	}

	copy = malloc(size);

	if (!copy)
		return FALSE;

	WLog_Print(glyphCache->log, WLOG_DEBUG,
	           "GlyphCacheFragmentPut: index: %"PRIu32" size: %"PRIu32"", index, size);
	CopyMemory(copy, fragment, size);
	prevFragment = glyphCache->fragCache.entries[index].fragment;
	glyphCache->fragCache.entries[index].fragment = copy;
	glyphCache->fragCache.entries[index].size = size;
	free(prevFragment);
	return TRUE;
}
Exemple #25
0
BOOL glyph_cache_put(rdpGlyphCache* glyphCache, UINT32 id, UINT32 index,
                     rdpGlyph* glyph)
{
	rdpGlyph* prevGlyph;

	if (id > 9)
	{
		WLog_ERR(TAG, "invalid glyph cache id: %"PRIu32"", id);
		return FALSE;
	}

	if (index > glyphCache->glyphCache[id].number)
	{
		WLog_ERR(TAG, "invalid glyph cache index: %"PRIu32" in cache id: %"PRIu32"", index, id);
		return FALSE;
	}

	WLog_Print(glyphCache->log, WLOG_DEBUG, "GlyphCachePut: id: %"PRIu32" index: %"PRIu32"", id,
	           index);
	prevGlyph = glyphCache->glyphCache[id].entries[index];

	if (prevGlyph)
		prevGlyph->Free(glyphCache->context, prevGlyph);

	glyphCache->glyphCache[id].entries[index] = glyph;
	return TRUE;
}
Exemple #26
0
rdpGlyph* glyph_cache_get(rdpGlyphCache* glyphCache, UINT32 id, UINT32 index)
{
	rdpGlyph* glyph;
	WLog_Print(glyphCache->log, WLOG_DEBUG, "GlyphCacheGet: id: %"PRIu32" index: %"PRIu32"", id,
	           index);

	if (id > 9)
	{
		WLog_ERR(TAG, "invalid glyph cache id: %"PRIu32"", id);
		return NULL;
	}

	if (index > glyphCache->glyphCache[id].number)
	{
		WLog_ERR(TAG, "index %"PRIu32" out of range for cache id: %"PRIu32"", index, id);
		return NULL;
	}

	glyph = glyphCache->glyphCache[id].entries[index];

	if (!glyph)
		WLog_ERR(TAG, "no glyph found at cache index: %"PRIu32" in cache id: %"PRIu32"", index, id);

	return glyph;
}
Exemple #27
0
int rdpgfx_recv_surface_to_cache_pdu(RDPGFX_CHANNEL_CALLBACK* callback, wStream* s)
{
	RDPGFX_SURFACE_TO_CACHE_PDU pdu;
	RDPGFX_PLUGIN* gfx = (RDPGFX_PLUGIN*) callback->plugin;
	RdpgfxClientContext* context = (RdpgfxClientContext*) gfx->iface.pInterface;

	if (Stream_GetRemainingLength(s) < 20)
		return -1;

	Stream_Read_UINT16(s, pdu.surfaceId); /* surfaceId (2 bytes) */
	Stream_Read_UINT64(s, pdu.cacheKey); /* cacheKey (8 bytes) */
	Stream_Read_UINT16(s, pdu.cacheSlot); /* cacheSlot (2 bytes) */
	rdpgfx_read_rect16(s, &(pdu.rectSrc)); /* rectSrc (8 bytes ) */

	WLog_Print(gfx->log, WLOG_DEBUG, "RecvSurfaceToCachePdu: surfaceId: %d cacheKey: 0x%08X cacheSlot: %d "
			"left: %d top: %d right: %d bottom: %d",
			pdu.surfaceId, (int) pdu.cacheKey, pdu.cacheSlot,
			pdu.rectSrc.left, pdu.rectSrc.top,
			pdu.rectSrc.right, pdu.rectSrc.bottom);

	if (context && context->SurfaceToCache)
	{
		context->SurfaceToCache(context, &pdu);
	}

	return 1;
}
Exemple #28
0
int rdpgfx_recv_end_frame_pdu(RDPGFX_CHANNEL_CALLBACK* callback, wStream* s)
{
	RDPGFX_END_FRAME_PDU pdu;
	RDPGFX_FRAME_ACKNOWLEDGE_PDU ack;
	RDPGFX_PLUGIN* gfx = (RDPGFX_PLUGIN*) callback->plugin;
	RdpgfxClientContext* context = (RdpgfxClientContext*) gfx->iface.pInterface;

	if (Stream_GetRemainingLength(s) < 4)
		return -1;

	Stream_Read_UINT32(s, pdu.frameId); /* frameId (4 bytes) */

	WLog_Print(gfx->log, WLOG_DEBUG, "RecvEndFramePdu: frameId: %d", pdu.frameId);

	if (context && context->EndFrame)
	{
		context->EndFrame(context, &pdu);
	}

	gfx->UnacknowledgedFrames--;
	gfx->TotalDecodedFrames++;

	ack.frameId = pdu.frameId;
	ack.totalFramesDecoded = gfx->TotalDecodedFrames;

	//ack.queueDepth = SUSPEND_FRAME_ACKNOWLEDGEMENT;
	ack.queueDepth = QUEUE_DEPTH_UNAVAILABLE;

	rdpgfx_send_frame_acknowledge_pdu(callback, &ack);

	return 1;
}
Exemple #29
0
int rdpgfx_send_frame_acknowledge_pdu(RDPGFX_CHANNEL_CALLBACK* callback, RDPGFX_FRAME_ACKNOWLEDGE_PDU* pdu)
{
	int status;
	wStream* s;
	RDPGFX_HEADER header;
	RDPGFX_PLUGIN* gfx = (RDPGFX_PLUGIN*) callback->plugin;

	header.flags = 0;
	header.cmdId = RDPGFX_CMDID_FRAMEACKNOWLEDGE;
	header.pduLength = RDPGFX_HEADER_SIZE + 12;

	WLog_Print(gfx->log, WLOG_DEBUG, "SendFrameAcknowledgePdu: %d", pdu->frameId);

	s = Stream_New(NULL, header.pduLength);

	rdpgfx_write_header(s, &header);

	/* RDPGFX_FRAME_ACKNOWLEDGE_PDU */

	Stream_Write_UINT32(s, pdu->queueDepth); /* queueDepth (4 bytes) */
	Stream_Write_UINT32(s, pdu->frameId); /* frameId (4 bytes) */
	Stream_Write_UINT32(s, pdu->totalFramesDecoded); /* totalFramesDecoded (4 bytes) */

	status = callback->channel->Write(callback->channel, (UINT32) Stream_Length(s), Stream_Buffer(s), NULL);

	Stream_Free(s, TRUE);

	return status;
}
Exemple #30
0
void* RpcEngine::listenerThread(void* arg) {
	RpcEngine* engine;

	engine = (RpcEngine*) arg;
	WLog_Print(logger_RPCEngine, WLOG_TRACE, "started RPC listener Thread");

	while (1) {

		if (!engine->createServerPipe()) {
			break;
		}

		HANDLE clientPipe = engine->acceptClient();

		if (!clientPipe)
			break;

		if (engine->serveClient() == CLIENT_ERROR ) {
			break;
		}
		engine->resetStatus();

	}

	return NULL;
}