Ejemplo n.º 1
0
static INLINE BOOL shadow_client_rdpgfx_new_surface(rdpShadowClient *client)
{
	UINT error = CHANNEL_RC_OK;
	RDPGFX_CREATE_SURFACE_PDU createSurface;
	RDPGFX_MAP_SURFACE_TO_OUTPUT_PDU surfaceToOutput;
	RdpgfxServerContext* context = client->rdpgfx;
	rdpSettings* settings = ((rdpContext*) client)->settings;

	createSurface.width = settings->DesktopWidth;
	createSurface.height = settings->DesktopHeight;
	createSurface.pixelFormat = PIXEL_FORMAT_XRGB_8888;
	createSurface.surfaceId = 0;

	surfaceToOutput.outputOriginX = 0;
	surfaceToOutput.outputOriginY = 0;
	surfaceToOutput.surfaceId = 0;
	surfaceToOutput.reserved = 0;
	
	IFCALLRET(context->CreateSurface, error, context, &createSurface); 
	if (error)
	{
		WLog_ERR(TAG, "CreateSurface failed with error %lu", error);
		return FALSE;
	}

	IFCALLRET(context->MapSurfaceToOutput, error, context, &surfaceToOutput); 
	if (error)
	{
		WLog_ERR(TAG, "MapSurfaceToOutput failed with error %lu", error);
		return FALSE;
	}

	return TRUE;
}
Ejemplo n.º 2
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;
}
Ejemplo n.º 3
0
/**
 * Function description
 *
 * @return 0 on success, otherwise a Win32 error code
 */
static UINT gdi_SurfaceCommand_RemoteFX(rdpGdi* gdi,
                                        RdpgfxClientContext* context,
                                        const RDPGFX_SURFACE_COMMAND* cmd)
{
	UINT status = CHANNEL_RC_OK;
	gdiGfxSurface* surface;
	surface = (gdiGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId);

	if (!surface)
		return ERROR_INTERNAL_ERROR;

	if (!rfx_process_message(surface->codecs->rfx, cmd->data, cmd->format,
	                         cmd->length,
	                         cmd->left, cmd->top,
	                         surface->data, surface->format, surface->scanline,
	                         surface->height, &surface->invalidRegion))
	{
		WLog_ERR(TAG, "Failed to process RemoteFX message");
		return ERROR_INTERNAL_ERROR;
	}

	if (!gdi->inGfxFrame)
	{
		status = CHANNEL_RC_NOT_INITIALIZED;
		IFCALLRET(context->UpdateSurfaces, status, context);
	}

	return status;
}
Ejemplo n.º 4
0
/**
 * Function description
 *
 * @return 0 on success, otherwise a Win32 error code
 */
static UINT rdpgfx_recv_qoe_frame_acknowledge_pdu(RdpgfxServerContext* context,
        wStream* s)
{
	RDPGFX_QOE_FRAME_ACKNOWLEDGE_PDU pdu;
	UINT error = CHANNEL_RC_OK;

	if (Stream_GetRemainingLength(s) < 12)
	{
		WLog_ERR(TAG, "not enough data!");
		return ERROR_INVALID_DATA;
	}

	Stream_Read_UINT32(s, pdu.frameId); /* frameId (4 bytes) */
	Stream_Read_UINT32(s, pdu.timestamp); /* timestamp (4 bytes) */
	Stream_Read_UINT16(s, pdu.timeDiffSE); /* timeDiffSE (2 bytes) */
	Stream_Read_UINT16(s, pdu.timeDiffEDR); /* timeDiffEDR (2 bytes) */

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

		if (error)
			WLog_ERR(TAG, "context->QoeFrameAcknowledge failed with error %u",
			         error);
	}

	return error;
}
Ejemplo n.º 5
0
/**
 * Function description
 *
 * @return 0 on success, otherwise a Win32 error code
 */
static UINT rdpgfx_recv_frame_acknowledge_pdu(RdpgfxServerContext* context,
        wStream* s)
{
	RDPGFX_FRAME_ACKNOWLEDGE_PDU pdu;
	UINT error = CHANNEL_RC_OK;

	if (Stream_GetRemainingLength(s) < 12)
	{
		WLog_ERR(TAG, "not enough data!");
		return ERROR_INVALID_DATA;
	}

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

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

		if (error)
			WLog_ERR(TAG, "context->FrameAcknowledge failed with error %u",
			         error);
	}

	return error;
}
Ejemplo n.º 6
0
static BOOL autodetect_send_bandwidth_measure_results(rdpRdp* rdp, UINT16 responseType, UINT16 sequenceNumber)
{
	BOOL success = TRUE;
	wStream* s;
	UINT32 timeDelta;

	/* Compute the total time */
	timeDelta = GetTickCountPrecise() - rdp->autodetect->bandwidthMeasureStartTime;

	/* Send the result PDU to the server */

	s = rdp_message_channel_pdu_init(rdp);

	if (!s)
		return FALSE;

	WLog_VRB(AUTODETECT_TAG, "sending Bandwidth Measure Results PDU -> timeDelta=%u, byteCount=%u", timeDelta, rdp->autodetect->bandwidthMeasureByteCount);

	Stream_Write_UINT8(s, 0x0E); /* headerLength (1 byte) */
	Stream_Write_UINT8(s, TYPE_ID_AUTODETECT_RESPONSE); /* headerTypeId (1 byte) */
	Stream_Write_UINT16(s, sequenceNumber); /* sequenceNumber (2 bytes) */
	Stream_Write_UINT16(s, responseType); /* responseType (1 byte) */
	Stream_Write_UINT32(s, timeDelta); /* timeDelta (4 bytes) */
	Stream_Write_UINT32(s, rdp->autodetect->bandwidthMeasureByteCount); /* byteCount (4 bytes) */

	IFCALLRET(rdp->autodetect->ClientBandwidthMeasureResult, success,
						rdp->context, rdp->autodetect);

	if (!success)
		return FALSE;

	return rdp_send_message_channel_pdu(rdp, s, SEC_AUTODETECT_RSP);
}
Ejemplo n.º 7
0
/**
 * Function description
 *
 * @return 0 on success, otherwise a Win32 error code
 */
static UINT cliprdr_server_receive_filecontents_request(CliprdrServerContext* context, wStream* s, CLIPRDR_HEADER* header)
{
	CLIPRDR_FILE_CONTENTS_REQUEST request;
	UINT error = CHANNEL_RC_OK;

	WLog_DBG(TAG, "CliprdrClientFileContentsRequest");

	request.msgType = CB_FILECONTENTS_REQUEST;
	request.msgFlags = header->msgFlags;
	request.dataLen = header->dataLen;

	if (Stream_GetRemainingLength(s) < 28)
	{
		WLog_ERR(TAG, "not enought data in stream!");
		return ERROR_INVALID_DATA;
	}

	Stream_Read_UINT32(s, request.streamId); /* streamId (4 bytes) */
	Stream_Read_UINT32(s, request.listIndex); /* listIndex (4 bytes) */
	Stream_Read_UINT32(s, request.dwFlags); /* dwFlags (4 bytes) */
	Stream_Read_UINT32(s, request.nPositionLow); /* nPositionLow (4 bytes) */
	Stream_Read_UINT32(s, request.nPositionHigh); /* nPositionHigh (4 bytes) */
	Stream_Read_UINT32(s, request.cbRequested); /* cbRequested (4 bytes) */
	Stream_Read_UINT32(s, request.clipDataId); /* clipDataId (4 bytes) */

	IFCALLRET(context->ClientFileContentsRequest, error, context, &request);
	if (error)
		WLog_ERR(TAG, "ClientFileContentsRequest failed with error %lu!", error);

	return error;
}
Ejemplo n.º 8
0
/**
 * Function description
 *
 * @return 0 on success, otherwise a Win32 error code
 */
static UINT cliprdr_server_receive_format_data_request(CliprdrServerContext* context, wStream* s, CLIPRDR_HEADER* header)
{
	CLIPRDR_FORMAT_DATA_REQUEST formatDataRequest;
	UINT error = CHANNEL_RC_OK;

	WLog_DBG(TAG, "CliprdrClientFormatDataRequest");

	formatDataRequest.msgType = CB_FORMAT_DATA_REQUEST;
	formatDataRequest.msgFlags = header->msgFlags;
	formatDataRequest.dataLen = header->dataLen;

	if (Stream_GetRemainingLength(s) < 4)
	{
		WLog_ERR(TAG, "not enought data in stream!");
		return ERROR_INVALID_DATA;
	}

	Stream_Read_UINT32(s, formatDataRequest.requestedFormatId); /* requestedFormatId (4 bytes) */

	IFCALLRET(context->ClientFormatDataRequest, error, context, &formatDataRequest);
	if (error)
		WLog_ERR(TAG, "ClientFormatDataRequest failed with error %lu!", error);

	return error;
}
Ejemplo n.º 9
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;
}
Ejemplo n.º 10
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;
}
Ejemplo n.º 11
0
/**
 * Function description
 *
 * @return 0 on success, otherwise a Win32 error code
 */
static UINT gdi_SurfaceToSurface(RdpgfxClientContext* context,
                                 const RDPGFX_SURFACE_TO_SURFACE_PDU* surfaceToSurface)
{
	UINT status = CHANNEL_RC_OK;
	UINT16 index;
	BOOL sameSurface;
	UINT32 nWidth, nHeight;
	const RECTANGLE_16* rectSrc;
	RDPGFX_POINT16* destPt;
	RECTANGLE_16 invalidRect;
	gdiGfxSurface* surfaceSrc;
	gdiGfxSurface* surfaceDst;
	rdpGdi* gdi = (rdpGdi*) context->custom;
	rectSrc = &(surfaceToSurface->rectSrc);
	surfaceSrc = (gdiGfxSurface*) context->GetSurfaceData(context,
	             surfaceToSurface->surfaceIdSrc);
	sameSurface = (surfaceToSurface->surfaceIdSrc ==
	               surfaceToSurface->surfaceIdDest) ? TRUE : FALSE;

	if (!sameSurface)
		surfaceDst = (gdiGfxSurface*) context->GetSurfaceData(context,
		             surfaceToSurface->surfaceIdDest);
	else
		surfaceDst = surfaceSrc;

	if (!surfaceSrc || !surfaceDst)
		return ERROR_INTERNAL_ERROR;

	nWidth = rectSrc->right - rectSrc->left;
	nHeight = rectSrc->bottom - rectSrc->top;

	for (index = 0; index < surfaceToSurface->destPtsCount; index++)
	{
		destPt = &surfaceToSurface->destPts[index];

		if (!freerdp_image_copy(surfaceDst->data, surfaceDst->format,
		                        surfaceDst->scanline,
		                        destPt->x, destPt->y, nWidth, nHeight,
		                        surfaceSrc->data, surfaceSrc->format,
		                        surfaceSrc->scanline,
		                        rectSrc->left, rectSrc->top, NULL, FREERDP_FLIP_NONE))
			return ERROR_INTERNAL_ERROR;

		invalidRect.left = destPt->x;
		invalidRect.top = destPt->y;
		invalidRect.right = destPt->x + rectSrc->right;
		invalidRect.bottom = destPt->y + rectSrc->bottom;
		region16_union_rect(&surfaceDst->invalidRegion, &surfaceDst->invalidRegion,
		                    &invalidRect);
		IFCALL(context->UpdateSurfaceArea, context, surfaceDst->surfaceId, 1, &invalidRect);
	}

	if (!gdi->inGfxFrame)
	{
		status = CHANNEL_RC_NOT_INITIALIZED;
		IFCALLRET(context->UpdateSurfaces, status, context);
	}

	return status;
}
Ejemplo n.º 12
0
/**
 * Function description
 *
 * @return 0 on success, otherwise a Win32 error code
 */
static UINT rdpgfx_recv_delete_surface_pdu(RDPGFX_CHANNEL_CALLBACK* callback,
        wStream* s)
{
	RDPGFX_DELETE_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) < 2)
	{
		WLog_ERR(TAG, "not enough data!");
		return ERROR_INVALID_DATA;
	}

	Stream_Read_UINT16(s, pdu.surfaceId); /* surfaceId (2 bytes) */
	WLog_DBG(TAG, "RecvDeleteSurfacePdu: surfaceId: %d", pdu.surfaceId);

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

		if (error)
			WLog_ERR(TAG, "context->DeleteSurface failed with error %u", error);
	}

	return error;
}
Ejemplo n.º 13
0
/**
 * Function description
 *
 * @return 0 on success, otherwise a Win32 error code
 */
static UINT read_cs_ready_message(RdpeiServerContext *context, wStream *s)
{
	UINT error = CHANNEL_RC_OK;
	if (Stream_GetRemainingLength(s) < 10)
	{
		WLog_ERR(TAG, "Not enought data!");
		return ERROR_INVALID_DATA;
	}

	Stream_Read_UINT32(s, context->protocolFlags);
	Stream_Read_UINT32(s, context->clientVersion);
	Stream_Read_UINT16(s, context->maxTouchPoints);

	switch (context->clientVersion)
	{
	case RDPINPUT_PROTOCOL_V10:
	case RDPINPUT_PROTOCOL_V101:
		break;
	default:
		WLog_ERR(TAG, "unhandled RPDEI protocol version 0x%x", context->clientVersion);
		break;
	}

	IFCALLRET(context->onClientReady, error, context);
	if (error)
		WLog_ERR(TAG, "context->onClientReady failed with error %lu", error);

	return error;
}
Ejemplo n.º 14
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) < 8)
	{
		WLog_ERR(TAG, "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_DBG(TAG, "RecvStartFramePdu: frameId: %d timestamp: 0x%04X",
			pdu.frameId, pdu.timestamp);

	if (context)
	{
		IFCALLRET(context->StartFrame, error, context, &pdu);
		if (error)
			WLog_ERR(TAG, "context->StartFrame failed with error %lu", error);
	}

	gfx->UnacknowledgedFrames++;

	return error;
}
Ejemplo n.º 15
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;
}
Ejemplo n.º 16
0
/**
 * Function description
 *
 * @return 0 on success, otherwise a Win32 error code
 */
static UINT cliprdr_server_receive_unlock_clipdata(CliprdrServerContext* context, wStream* s, CLIPRDR_HEADER* header)
{
	CLIPRDR_UNLOCK_CLIPBOARD_DATA unlockClipboardData;
	UINT error = CHANNEL_RC_OK;

	WLog_DBG(TAG, "CliprdrClientUnlockClipData");

	unlockClipboardData.msgType = CB_UNLOCK_CLIPDATA;
	unlockClipboardData.msgFlags = header->msgFlags;
	unlockClipboardData.dataLen = header->dataLen;

	if (Stream_GetRemainingLength(s) < 4)
	{
		WLog_ERR(TAG, "not enought data in stream!");
		return ERROR_INVALID_DATA;
	}

	Stream_Read_UINT32(s, unlockClipboardData.clipDataId); /* clipDataId (4 bytes) */

	IFCALLRET(context->ClientUnlockClipboardData, error, context, &unlockClipboardData);
	if (error)
		WLog_ERR(TAG, "ClientUnlockClipboardData failed with error %lu!", error);

	return error;
}
Ejemplo n.º 17
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;
}
Ejemplo n.º 18
0
/**
 * Function description
 *
 * @return 0 on success, otherwise a Win32 error code
 */
static UINT cliprdr_server_receive_format_data_response(CliprdrServerContext* context, wStream* s, CLIPRDR_HEADER* header)
{
	CLIPRDR_FORMAT_DATA_RESPONSE formatDataResponse;
	UINT error = CHANNEL_RC_OK;

	WLog_DBG(TAG, "CliprdrClientFormatDataResponse");

	formatDataResponse.msgType = CB_FORMAT_DATA_RESPONSE;
	formatDataResponse.msgFlags = header->msgFlags;
	formatDataResponse.dataLen = header->dataLen;
	formatDataResponse.requestedFormatData = NULL;

	if (Stream_GetRemainingLength(s) < header->dataLen)
	{
		WLog_ERR(TAG, "not enought data in stream!");
		return ERROR_INVALID_DATA;
	}

	if (header->dataLen)
	{
		formatDataResponse.requestedFormatData = (BYTE*) malloc(header->dataLen);
		Stream_Read(s, formatDataResponse.requestedFormatData, header->dataLen);
	}

	IFCALLRET(context->ClientFormatDataResponse, error, context, &formatDataResponse);
	if (error)
		WLog_ERR(TAG, "ClientFormatDataResponse failed with error %lu!", error);

	free(formatDataResponse.requestedFormatData);

	return error;
}
Ejemplo n.º 19
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;
}
Ejemplo n.º 20
0
/**
 * Function description
 *
 * @return 0 on success, otherwise a Win32 error code
 */
static UINT cliprdr_server_receive_filecontents_response(CliprdrServerContext* context, wStream* s, CLIPRDR_HEADER* header)
{
	CLIPRDR_FILE_CONTENTS_RESPONSE response;
	UINT error = CHANNEL_RC_OK;

	WLog_DBG(TAG, "CliprdrClientFileContentsResponse");

	response.msgType = CB_FILECONTENTS_RESPONSE;
	response.msgFlags = header->msgFlags;
	response.dataLen = header->dataLen;

	if (Stream_GetRemainingLength(s) < 4)
	{
		WLog_ERR(TAG, "not enought data in stream!");
		return ERROR_INVALID_DATA;
	}

	Stream_Read_UINT32(s, response.streamId); /* streamId (4 bytes) */

	response.cbRequested = header->dataLen - 4;
	response.requestedData = Stream_Pointer(s); /* requestedFileContentsData */

	IFCALLRET(context->ServerFileContentsResponse, error, context, &response);
	if (error)
		WLog_ERR(TAG, "ServerFileContentsResponse failed with error %lu!", error);

	return error;
}
Ejemplo n.º 21
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;
}
Ejemplo n.º 22
0
/**
 * Function description
 *
 * @return 0 on success, otherwise a Win32 error code
 */
UINT rdpgfx_decode(RDPGFX_PLUGIN* gfx, RDPGFX_SURFACE_COMMAND* cmd)
{
	UINT error = CHANNEL_RC_OK;
	RdpgfxClientContext* context = (RdpgfxClientContext*) gfx->iface.pInterface;

	switch (cmd->codecId)
	{
		case RDPGFX_CODECID_AVC420:
			if ((error = rdpgfx_decode_AVC420(gfx, cmd)))
			{
				WLog_ERR(TAG, "rdpgfx_decode_AVC420 failed with error %"PRIu32"", error);
				return error;
			}
			break;

		case RDPGFX_CODECID_AVC444:
			if ((error = rdpgfx_decode_AVC444(gfx, cmd)))
			{
				WLog_ERR(TAG, "rdpgfx_decode_AVC444 failed with error %"PRIu32"", error);
				return error;
			}
			break;

		default:
			if (context)
			{
				IFCALLRET(context->SurfaceCommand, error, context, cmd);
				if (error)
					WLog_ERR(TAG, "context->SurfaceCommand failed with error %"PRIu32"", error);
			}
			break;
	}

	return error;
}
Ejemplo n.º 23
0
/**
 * Function description
 *
 * @return 0 on success, otherwise a Win32 error code
 */
static UINT rdpgfx_recv_cache_to_surface_pdu(RDPGFX_CHANNEL_CALLBACK* callback,
        wStream* s)
{
	UINT16 index;
	RDPGFX_POINT16* destPt;
	RDPGFX_CACHE_TO_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) < 6)
	{
		WLog_Print(gfx->log, WLOG_ERROR, "not enough data!");
		return ERROR_INVALID_DATA;
	}

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

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

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

	for (index = 0; index < pdu.destPtsCount; index++)
	{
		destPt = &(pdu.destPts[index]);

		if ((error = rdpgfx_read_point16(s, destPt)))
		{
			WLog_Print(gfx->log, WLOG_ERROR, "rdpgfx_read_point16 failed with error %"PRIu32"", error);
			free(pdu.destPts);
			return error;
		}
	}

	WLog_Print(gfx->log, WLOG_DEBUG,
	         "RdpGfxRecvCacheToSurfacePdu: cacheSlot: %"PRIu16" surfaceId: %"PRIu16" destPtsCount: %"PRIu16"",
	         pdu.cacheSlot, pdu.surfaceId, pdu.destPtsCount);

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

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

	free(pdu.destPts);
	return error;
}
Ejemplo n.º 24
0
/**
 * Function description
 *
 * @return 0 on success, otherwise a Win32 error code
 */
UINT cliprdr_process_format_data_request(cliprdrPlugin* cliprdr, wStream* s, UINT32 dataLen, UINT16 msgFlags)
{
	CLIPRDR_FORMAT_DATA_REQUEST formatDataRequest;
	CliprdrClientContext* context = cliprdr_get_client_interface(cliprdr);
	UINT error = CHANNEL_RC_OK;

	WLog_Print(cliprdr->log, WLOG_DEBUG, "ServerFormatDataRequest");

	if (!context->custom)
	{
		WLog_ERR(TAG, "context->custom not set!");
		return ERROR_INTERNAL_ERROR;
	}

	formatDataRequest.msgType = CB_FORMAT_DATA_REQUEST;
	formatDataRequest.msgFlags = msgFlags;
	formatDataRequest.dataLen = dataLen;

	Stream_Read_UINT32(s, formatDataRequest.requestedFormatId); /* requestedFormatId (4 bytes) */


	IFCALLRET(context->ServerFormatDataRequest, error, context, &formatDataRequest);
	if (error)
		WLog_ERR(TAG, "ServerFormatDataRequest failed with error %lu!", error);

	return error;
}
Ejemplo n.º 25
0
/**
 * Function description
 *
 * @return 0 on success, otherwise a Win32 error code
 */
static UINT gdi_SurfaceCommand_Uncompressed(rdpGdi* gdi,
        RdpgfxClientContext* context,
        const RDPGFX_SURFACE_COMMAND* cmd)
{
	UINT status = CHANNEL_RC_OK;
	gdiGfxSurface* surface;
	RECTANGLE_16 invalidRect;
	surface = (gdiGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId);

	if (!surface)
		return ERROR_INTERNAL_ERROR;

	if (!freerdp_image_copy(surface->data, surface->format, surface->scanline,
	                        cmd->left, cmd->top, cmd->width, cmd->height,
	                        cmd->data, cmd->format, 0, 0, 0, NULL, FREERDP_FLIP_NONE))
		return ERROR_INTERNAL_ERROR;

	invalidRect.left = cmd->left;
	invalidRect.top = cmd->top;
	invalidRect.right = cmd->right;
	invalidRect.bottom = cmd->bottom;
	region16_union_rect(&(surface->invalidRegion), &(surface->invalidRegion),
	                    &invalidRect);

	if (!gdi->inGfxFrame)
	{
		status = CHANNEL_RC_NOT_INITIALIZED;
		IFCALLRET(context->UpdateSurfaces, status, context);
	}

	return status;
}
Ejemplo n.º 26
0
/**
 * Function description
 *
 * @return 0 on success, otherwise a Win32 error code
 */
static UINT rdpgfx_recv_cache_import_offer_pdu(RdpgfxServerContext* context,
        wStream* s)
{
	UINT16 index;
	RDPGFX_CACHE_IMPORT_OFFER_PDU pdu;
	RDPGFX_CACHE_ENTRY_METADATA* cacheEntries;
	UINT error = CHANNEL_RC_OK;

	if (Stream_GetRemainingLength(s) < 2)
	{
		WLog_ERR(TAG, "not enough data!");
		return ERROR_INVALID_DATA;
	}

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

	if (pdu.cacheEntriesCount <= 0)
	{
		/* According to the latest spec, capsSetCount <= 3 */
		WLog_ERR(TAG, "Invalid cacheEntriesCount: %u", pdu.cacheEntriesCount);
		return ERROR_INVALID_DATA;
	}

	if (Stream_GetRemainingLength(s) < (pdu.cacheEntriesCount * 12))
	{
		WLog_ERR(TAG, "not enough data!");
		return ERROR_INVALID_DATA;
	}

	pdu.cacheEntries = (RDPGFX_CACHE_ENTRY_METADATA*)
	                   calloc(pdu.cacheEntriesCount,
	                          sizeof(RDPGFX_CACHE_ENTRY_METADATA));

	if (!pdu.cacheEntries)
	{
		WLog_ERR(TAG, "calloc failed!");
		return CHANNEL_RC_NO_MEMORY;
	}

	for (index = 0; index < pdu.cacheEntriesCount; index++)
	{
		cacheEntries = &(pdu.cacheEntries[index]);
		Stream_Read_UINT64(s, cacheEntries->cacheKey); /* cacheKey (8 bytes) */
		/* bitmapLength (4 bytes) */
		Stream_Read_UINT32(s, cacheEntries->bitmapLength);
	}

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

		if (error)
			WLog_ERR(TAG, "context->CacheImportOffer failed with error %u",
			         error);
	}

	free(pdu.cacheEntries);
	return error;
}
Ejemplo n.º 27
0
/**
 * Function description
 *
 * @return 0 on success, otherwise a Win32 error code
 */
static UINT gdi_SurfaceCommand_Alpha(rdpGdi* gdi, RdpgfxClientContext* context,
                                     const RDPGFX_SURFACE_COMMAND* cmd)
{
	UINT status = CHANNEL_RC_OK;
	gdiGfxSurface* surface;
	RECTANGLE_16 invalidRect;
	surface = (gdiGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId);

	if (!surface)
		return ERROR_INTERNAL_ERROR;

	WLog_WARN(TAG, "TODO gdi_SurfaceCommand_Alpha: status: %d", status);

	/* fill with green for now to distinguish from the rest */
	if (!freerdp_image_fill(surface->data, surface->format, surface->scanline,
	                        cmd->left, cmd->top, cmd->width, cmd->height, 0x00FF00))
		return ERROR_INTERNAL_ERROR;

	invalidRect.left = cmd->left;
	invalidRect.top = cmd->top;
	invalidRect.right = cmd->right;
	invalidRect.bottom = cmd->bottom;
	region16_union_rect(&(surface->invalidRegion), &(surface->invalidRegion),
	                    &invalidRect);

	if (!gdi->inGfxFrame)
	{
		status = CHANNEL_RC_NOT_INITIALIZED;
		IFCALLRET(context->UpdateSurfaces, status, context);
	}

	return status;
}
Ejemplo n.º 28
0
/**
 * Function description
 *
 * @return 0 on success, otherwise a Win32 error code
 */
static UINT cliprdr_process_unlock_clipdata(cliprdrPlugin* cliprdr, wStream* s, UINT32 length, UINT16 flags)
{
	CLIPRDR_UNLOCK_CLIPBOARD_DATA unlockClipboardData;
	CliprdrClientContext* context = cliprdr_get_client_interface(cliprdr);
	UINT error = CHANNEL_RC_OK;

	WLog_Print(cliprdr->log, WLOG_DEBUG, "UnlockClipData");

	if (!context->custom)
	{
		WLog_ERR(TAG, "context->custom not set!");
		return ERROR_INTERNAL_ERROR;
	}

	if (Stream_GetRemainingLength(s) < 4)
	{
		WLog_ERR(TAG, "not enought remaining data");
		return ERROR_INVALID_DATA;
	}

	unlockClipboardData.msgType = CB_UNLOCK_CLIPDATA;
	unlockClipboardData.msgFlags = flags;
	unlockClipboardData.dataLen = length;

	Stream_Read_UINT32(s, unlockClipboardData.clipDataId); /* clipDataId (4 bytes) */


	IFCALLRET(context->ServerUnlockClipboardData, error, context, &unlockClipboardData);
	if (error)
		WLog_ERR(TAG, "ServerUnlockClipboardData failed with error %lu!", error);

	return error;
}
Ejemplo n.º 29
0
int rdp_client_connect_demand_active(rdpRdp* rdp, wStream* s)
{
	BYTE* mark;
	UINT16 width;
	UINT16 height;

	width = rdp->settings->DesktopWidth;
	height = rdp->settings->DesktopHeight;

	Stream_GetPointer(s, mark);

	if (!rdp_recv_demand_active(rdp, s))
	{
		UINT16 channelId;

		Stream_SetPointer(s, mark);
		rdp_recv_get_active_header(rdp, s, &channelId);

		/* Was Stream_Seek(s, RDP_PACKET_HEADER_MAX_LENGTH);
		 * but the headers aren't always that length,
		 * so that could result in a bad offset.
		 */

		return rdp_recv_out_of_sequence_pdu(rdp, s);
	}

	if (freerdp_shall_disconnect(rdp->instance))
		return 0;

	if (!rdp_send_confirm_active(rdp))
		return -1;

	if (!input_register_client_callbacks(rdp->input))
	{
		WLog_ERR(TAG, "error registering client callbacks");
		return -1;
	}

	/**
	 * The server may request a different desktop size during Deactivation-Reactivation sequence.
	 * In this case, the UI should be informed and do actual window resizing at this point.
	 */
	if (width != rdp->settings->DesktopWidth || height != rdp->settings->DesktopHeight)
	{
		BOOL status = TRUE;

		IFCALLRET(rdp->update->DesktopResize, status, rdp->update->context);

		if (!status)
		{
			WLog_ERR(TAG, "client desktop resize callback failed");
			return -1;
		}
	}

	rdp_client_transition_to_state(rdp, CONNECTION_STATE_FINALIZATION);

	return rdp_client_connect_finalize(rdp);
}
Ejemplo n.º 30
0
/**
 * Function description
 *
 * @return 0 on success, otherwise a Win32 error code
 */
static UINT encomsp_recv_participant_created_pdu(encomspPlugin* encomsp, wStream* s, ENCOMSP_ORDER_HEADER* header)
{
	int beg, end;
	EncomspClientContext* context;
	ENCOMSP_PARTICIPANT_CREATED_PDU pdu;
	UINT error;

	context = encomsp_get_client_interface(encomsp);

	if (!context)
		return ERROR_INVALID_HANDLE;

	beg = ((int) Stream_GetPosition(s)) - ENCOMSP_ORDER_HEADER_SIZE;

	CopyMemory(&pdu, header, sizeof(ENCOMSP_ORDER_HEADER));

	if (Stream_GetRemainingLength(s) < 10)
	{
		WLog_ERR(TAG, "Not enought data!");
		return ERROR_INVALID_DATA;
	}

	Stream_Read_UINT32(s, pdu.ParticipantId); /* ParticipantId (4 bytes) */
	Stream_Read_UINT32(s, pdu.GroupId); /* GroupId (4 bytes) */
	Stream_Read_UINT16(s, pdu.Flags); /* Flags (2 bytes) */


	if ((error = encomsp_read_unicode_string(s, &(pdu.FriendlyName))))
	{
		WLog_ERR(TAG, "encomsp_read_unicode_string failed with error %lu", error);
		return error;
	}

	end = (int) Stream_GetPosition(s);

	if ((beg + header->Length) < end)
	{
		WLog_ERR(TAG, "Not enought data!");
		return ERROR_INVALID_DATA;
	}

	if ((beg + header->Length) > end)
	{
		if (Stream_GetRemainingLength(s) < (size_t) ((beg + header->Length) - end))
		{
			WLog_ERR(TAG, "Not enought data!");
			return ERROR_INVALID_DATA;
		}

		Stream_SetPosition(s, (beg + header->Length));
	}

	IFCALLRET(context->ParticipantCreated, error, context, &pdu);
	if (error)
		WLog_ERR(TAG, "context->ParticipantCreated failed with error %lu", error);

	return error;
}