static int update_recv_surfcmd_surface_bits(rdpUpdate* update, wStream* s, UINT32* length) { int pos; SURFACE_BITS_COMMAND* cmd = &update->surface_bits_command; if (Stream_GetRemainingLength(s) < 20) return -1; Stream_Read_UINT16(s, cmd->destLeft); Stream_Read_UINT16(s, cmd->destTop); Stream_Read_UINT16(s, cmd->destRight); Stream_Read_UINT16(s, cmd->destBottom); Stream_Read_UINT8(s, cmd->bpp); Stream_Seek(s, 2); /* reserved1, reserved2 */ Stream_Read_UINT8(s, cmd->codecID); Stream_Read_UINT16(s, cmd->width); Stream_Read_UINT16(s, cmd->height); Stream_Read_UINT32(s, cmd->bitmapDataLength); if (Stream_GetRemainingLength(s) < cmd->bitmapDataLength) return -1; pos = Stream_GetPosition(s) + cmd->bitmapDataLength; cmd->bitmapData = Stream_Pointer(s); Stream_SetPosition(s, pos); *length = 20 + cmd->bitmapDataLength; IFCALL(update->SurfaceBits, update->context, cmd); return 0; }
BOOL rdpei_read_2byte_unsigned(wStream* s, UINT32* value) { BYTE byte; if (Stream_GetRemainingLength(s) < 1) return FALSE; Stream_Read_UINT8(s, byte); if (byte & 0x80) { if (Stream_GetRemainingLength(s) < 1) return FALSE; *value = (byte & 0x7F) << 8; Stream_Read_UINT8(s, byte); *value |= byte; } else { *value = (byte & 0x7F); } return TRUE; }
int rdp_recv_autodetect_request_packet(rdpRdp* rdp, wStream* s) { AUTODETECT_REQ_PDU autodetectReqPdu; BOOL success = FALSE; if (Stream_GetRemainingLength(s) < 6) return -1; Stream_Read_UINT8(s, autodetectReqPdu.headerLength); /* headerLength (1 byte) */ Stream_Read_UINT8(s, autodetectReqPdu.headerTypeId); /* headerTypeId (1 byte) */ Stream_Read_UINT16(s, autodetectReqPdu.sequenceNumber); /* sequenceNumber (2 bytes) */ Stream_Read_UINT16(s, autodetectReqPdu.requestType); /* requestType (2 bytes) */ WLog_VRB(AUTODETECT_TAG, "rdp_recv_autodetect_request_packet: headerLength=%"PRIu8", headerTypeId=%"PRIu8", sequenceNumber=%"PRIu16", requestType=%04"PRIx16"", autodetectReqPdu.headerLength, autodetectReqPdu.headerTypeId, autodetectReqPdu.sequenceNumber, autodetectReqPdu.requestType); if (autodetectReqPdu.headerTypeId != TYPE_ID_AUTODETECT_REQUEST) return -1; switch (autodetectReqPdu.requestType) { case RDP_RTT_REQUEST_TYPE_CONTINUOUS: case RDP_RTT_REQUEST_TYPE_CONNECTTIME: /* RTT Measure Request (RDP_RTT_REQUEST) - MS-RDPBCGR 2.2.14.1.1 */ success = autodetect_recv_rtt_measure_request(rdp, s, &autodetectReqPdu); break; case RDP_BW_START_REQUEST_TYPE_CONTINUOUS: case RDP_BW_START_REQUEST_TYPE_TUNNEL: case RDP_BW_START_REQUEST_TYPE_CONNECTTIME: /* Bandwidth Measure Start (RDP_BW_START) - MS-RDPBCGR 2.2.14.1.2 */ success = autodetect_recv_bandwidth_measure_start(rdp, s, &autodetectReqPdu); break; case RDP_BW_PAYLOAD_REQUEST_TYPE: /* Bandwidth Measure Payload (RDP_BW_PAYLOAD) - MS-RDPBCGR 2.2.14.1.3 */ success = autodetect_recv_bandwidth_measure_payload(rdp, s, &autodetectReqPdu); break; case RDP_BW_STOP_REQUEST_TYPE_CONNECTTIME: case RDP_BW_STOP_REQUEST_TYPE_CONTINUOUS: case RDP_BW_STOP_REQUEST_TYPE_TUNNEL: /* Bandwidth Measure Stop (RDP_BW_STOP) - MS-RDPBCGR 2.2.14.1.4 */ success = autodetect_recv_bandwidth_measure_stop(rdp, s, &autodetectReqPdu); break; case 0x0840: case 0x0880: case 0x08C0: /* Network Characteristics Result (RDP_NETCHAR_RESULT) - MS-RDPBCGR 2.2.14.1.5 */ success = autodetect_recv_netchar_result(rdp, s, &autodetectReqPdu); break; default: break; } return success ? 0 : -1; }
static BOOL rfx_process_message_codec_versions(RFX_CONTEXT* context, wStream* s) { BYTE numCodecs; if (Stream_GetRemainingLength(s) < 1) { DEBUG_WARN("RfxCodecVersion packet too small"); return FALSE; } Stream_Read_UINT8(s, numCodecs); /* numCodecs (1 byte), must be set to 0x01 */ if (numCodecs != 1) { DEBUG_WARN("numCodecs: %d, expected:1", numCodecs); return FALSE; } if (Stream_GetRemainingLength(s) < 2 * numCodecs) { DEBUG_WARN("RfxCodecVersion packet too small for numCodecs=%d", numCodecs); return FALSE; } /* RFX_CODEC_VERSIONT */ Stream_Read_UINT8(s, context->codec_id); /* codecId (1 byte) */ Stream_Read_UINT8(s, context->codec_version); /* version (2 bytes) */ DEBUG_RFX("id %d version 0x%X.", context->codec_id, context->codec_version); return TRUE; }
BOOL ber_read_length(wStream* s, int* length) { BYTE byte; if (Stream_GetRemainingLength(s) < 1) return FALSE; Stream_Read_UINT8(s, byte); if (byte & 0x80) { byte &= ~(0x80); if (Stream_GetRemainingLength(s) < byte) return FALSE; if (byte == 1) Stream_Read_UINT8(s, *length); else if (byte == 2) Stream_Read_UINT16_BE(s, *length); else return FALSE; } else { *length = byte; } return TRUE; }
BOOL update_read_palette(rdpUpdate* update, wStream* s, PALETTE_UPDATE* palette_update) { int i; PALETTE_ENTRY* entry; if (Stream_GetRemainingLength(s) < 6) return FALSE; Stream_Seek_UINT16(s); /* pad2Octets (2 bytes) */ Stream_Read_UINT32(s, palette_update->number); /* numberColors (4 bytes), must be set to 256 */ if (palette_update->number > 256) palette_update->number = 256; if (Stream_GetRemainingLength(s) < palette_update->number * 3) return FALSE; /* paletteEntries */ for (i = 0; i < (int) palette_update->number; i++) { entry = &palette_update->entries[i]; Stream_Read_UINT8(s, entry->blue); Stream_Read_UINT8(s, entry->green); Stream_Read_UINT8(s, entry->red); } return TRUE; }
void ntlm_read_version_info(wStream* s, NTLM_VERSION_INFO* versionInfo) { Stream_Read_UINT8(s, versionInfo->ProductMajorVersion); /* ProductMajorVersion (1 byte) */ Stream_Read_UINT8(s, versionInfo->ProductMinorVersion); /* ProductMinorVersion (1 byte) */ Stream_Read_UINT16(s, versionInfo->ProductBuild); /* ProductBuild (2 bytes) */ Stream_Read(s, versionInfo->Reserved, sizeof(versionInfo->Reserved)); /* Reserved (3 bytes) */ Stream_Read_UINT8(s, versionInfo->NTLMRevisionCurrent); /* NTLMRevisionCurrent (1 byte) */ }
int rdpgfx_read_color32(wStream* s, RDPGFX_COLOR32* color32) { Stream_Read_UINT8(s, color32->B); /* B (1 byte) */ Stream_Read_UINT8(s, color32->G); /* G (1 byte) */ Stream_Read_UINT8(s, color32->R); /* R (1 byte) */ Stream_Read_UINT8(s, color32->XA); /* XA (1 byte) */ return 0; }
static BOOL rfx_process_message_channels(RFX_CONTEXT* context, wStream* s) { BYTE channelId; BYTE numChannels; context->decodedHeaderBlocks &= ~_RFX_DECODED_CHANNELS; if (Stream_GetRemainingLength(s) < 1) { WLog_ERR(TAG, "RfxMessageChannels packet too small"); return FALSE; } Stream_Read_UINT8(s, numChannels); /* numChannels (1 byte), must bet set to 0x01 */ /* In RDVH sessions, numChannels will represent the number of virtual monitors * configured and does not always be set to 0x01 as [MS-RDPRFX] said. */ if (numChannels < 1) { WLog_ERR(TAG, "no channels announced"); return FALSE; } if (Stream_GetRemainingLength(s) < (size_t) (numChannels * 5)) { WLog_ERR(TAG, "RfxMessageChannels packet too small for numChannels=%d", numChannels); return FALSE; } /* RFX_CHANNELT */ Stream_Read_UINT8(s, channelId); /* channelId (1 byte), must be set to 0x00 */ if (channelId != 0x00) { WLog_ERR(TAG, "channelId:0x%02X, expected:0x00", channelId); return FALSE; } Stream_Read_UINT16(s, context->width); /* width (2 bytes) */ Stream_Read_UINT16(s, context->height); /* height (2 bytes) */ if (!context->width || !context->height) { WLog_ERR(TAG, "%s: invalid channel with/height: %ux%u", __FUNCTION__, context->width, context->height); return FALSE; } /* Now, only the first monitor can be used, therefore the other channels will be ignored. */ Stream_Seek(s, 5 * (numChannels - 1)); WLog_Print(context->priv->log, WLOG_DEBUG, "numChannels %d id %d, %dx%d.", numChannels, channelId, context->width, context->height); context->decodedHeaderBlocks |= _RFX_DECODED_CHANNELS; return TRUE; }
int rdpgfx_read_h264_metablock(RDPGFX_PLUGIN* gfx, wStream* s, RDPGFX_H264_METABLOCK* meta) { UINT32 index; RDPGFX_RECT16* regionRect; RDPGFX_H264_QUANT_QUALITY* quantQualityVal; meta->regionRects = NULL; meta->quantQualityVals = NULL; if (Stream_GetRemainingLength(s) < 4) return -1; Stream_Read_UINT32(s, meta->numRegionRects); /* numRegionRects (4 bytes) */ if (Stream_GetRemainingLength(s) < (meta->numRegionRects * 8)) return -1; meta->regionRects = (RDPGFX_RECT16*) malloc(meta->numRegionRects * sizeof(RDPGFX_RECT16)); if (!meta->regionRects) return -1; meta->quantQualityVals = (RDPGFX_H264_QUANT_QUALITY*) malloc(meta->numRegionRects * sizeof(RDPGFX_H264_QUANT_QUALITY)); if (!meta->quantQualityVals) return -1; WLog_DBG(TAG, "H264_METABLOCK: numRegionRects: %d", (int) meta->numRegionRects); for (index = 0; index < meta->numRegionRects; index++) { regionRect = &(meta->regionRects[index]); rdpgfx_read_rect16(s, regionRect); WLog_DBG(TAG, "regionRects[%d]: left: %d top: %d right: %d bottom: %d", index, regionRect->left, regionRect->top, regionRect->right, regionRect->bottom); } if (Stream_GetRemainingLength(s) < (meta->numRegionRects * 2)) return -1; for (index = 0; index < meta->numRegionRects; index++) { quantQualityVal = &(meta->quantQualityVals[index]); Stream_Read_UINT8(s, quantQualityVal->qpVal); /* qpVal (1 byte) */ Stream_Read_UINT8(s, quantQualityVal->qualityVal); /* qualityVal (1 byte) */ quantQualityVal->qp = quantQualityVal->qpVal & 0x3F; quantQualityVal->r = (quantQualityVal->qpVal >> 6) & 1; quantQualityVal->p = (quantQualityVal->qpVal >> 7) & 1; WLog_DBG(TAG, "quantQualityVals[%d]: qp: %d r: %d p: %d qualityVal: %d", index, quantQualityVal->qp, quantQualityVal->r, quantQualityVal->p, quantQualityVal->qualityVal); } return 1; }
static UINT video_data_on_data_received(IWTSVirtualChannelCallback* pChannelCallback, wStream *s) { VIDEO_CHANNEL_CALLBACK* callback = (VIDEO_CHANNEL_CALLBACK*) pChannelCallback; VIDEO_PLUGIN* video; VideoClientContext *context; UINT32 cbSize, packetType; TSMM_VIDEO_DATA data; video = (VIDEO_PLUGIN*) callback->plugin; context = (VideoClientContext *)video->wtsPlugin.pInterface; if (Stream_GetRemainingLength(s) < 4) return ERROR_INVALID_DATA; Stream_Read_UINT32(s, cbSize); if (cbSize < 8 || Stream_GetRemainingLength(s) < (cbSize-4)) { WLog_ERR(TAG, "invalid cbSize"); return ERROR_INVALID_DATA; } Stream_Read_UINT32(s, packetType); if (packetType != TSMM_PACKET_TYPE_VIDEO_DATA) { WLog_ERR(TAG, "only expecting VIDEO_DATA on the data channel"); return ERROR_INVALID_DATA; } if (Stream_GetRemainingLength(s) < 32) { WLog_ERR(TAG, "not enough bytes for a TSMM_VIDEO_DATA"); return ERROR_INVALID_DATA; } Stream_Read_UINT8(s, data.PresentationId); Stream_Read_UINT8(s, data.Version); Stream_Read_UINT8(s, data.Flags); Stream_Seek_UINT8(s); /* reserved */ Stream_Read_UINT64(s, data.hnsTimestamp); Stream_Read_UINT64(s, data.hnsDuration); Stream_Read_UINT16(s, data.CurrentPacketIndex); Stream_Read_UINT16(s, data.PacketsInSample); Stream_Read_UINT32(s, data.SampleNumber); Stream_Read_UINT32(s, data.cbSample); data.pSample = Stream_Pointer(s); /* WLog_DBG(TAG, "videoData: id:%"PRIu8" version:%"PRIu8" flags:0x%"PRIx8" timestamp=%"PRIu64" duration=%"PRIu64 " curPacketIndex:%"PRIu16" packetInSample:%"PRIu16" sampleNumber:%"PRIu32" cbSample:%"PRIu32"", data.PresentationId, data.Version, data.Flags, data.hnsTimestamp, data.hnsDuration, data.CurrentPacketIndex, data.PacketsInSample, data.SampleNumber, data.cbSample); */ return video_VideoData(context, &data); }
BOOL license_read_preamble(wStream* s, BYTE* bMsgType, BYTE* flags, UINT16* wMsgSize) { /* preamble (4 bytes) */ if (Stream_GetRemainingLength(s) < 4) return FALSE; Stream_Read_UINT8(s, *bMsgType); /* bMsgType (1 byte) */ Stream_Read_UINT8(s, *flags); /* flags (1 byte) */ Stream_Read_UINT16(s, *wMsgSize); /* wMsgSize (2 bytes) */ return TRUE; }
BOOL nego_read_request(rdpNego* nego, wStream* s) { BYTE li; BYTE c; BYTE type; tpkt_read_header(s); if (!tpdu_read_connection_request(s, &li)) return FALSE; if (li != Stream_GetRemainingLength(s) + 6) { fprintf(stderr, "Incorrect TPDU length indicator.\n"); return FALSE; } if (Stream_GetRemainingLength(s) > 8) { /* Optional routingToken or cookie, ending with CR+LF */ while (Stream_GetRemainingLength(s) > 0) { Stream_Read_UINT8(s, c); if (c != '\x0D') continue; Stream_Peek_UINT8(s, c); if (c != '\x0A') continue; Stream_Seek_UINT8(s); break; } } if (Stream_GetRemainingLength(s) >= 8) { /* rdpNegData (optional) */ Stream_Read_UINT8(s, type); /* Type */ if (type != TYPE_RDP_NEG_REQ) { fprintf(stderr, "Incorrect negotiation request type %d\n", type); return FALSE; } nego_process_negotiation_request(nego, s); } return TRUE; }
int rdpgfx_read_color32(wStream* s, RDPGFX_COLOR32* color32) { if (Stream_GetRemainingLength(s) < 4) return -1; Stream_Read_UINT8(s, color32->B); /* B (1 byte) */ Stream_Read_UINT8(s, color32->G); /* G (1 byte) */ Stream_Read_UINT8(s, color32->R); /* R (1 byte) */ Stream_Read_UINT8(s, color32->XA); /* XA (1 byte) */ return 1; }
int ntlm_read_version_info(wStream* s, NTLM_VERSION_INFO* versionInfo) { if (Stream_GetRemainingLength(s) < 8) return -1; Stream_Read_UINT8(s, versionInfo->ProductMajorVersion); /* ProductMajorVersion (1 byte) */ Stream_Read_UINT8(s, versionInfo->ProductMinorVersion); /* ProductMinorVersion (1 byte) */ Stream_Read_UINT16(s, versionInfo->ProductBuild); /* ProductBuild (2 bytes) */ Stream_Read(s, versionInfo->Reserved, sizeof(versionInfo->Reserved)); /* Reserved (3 bytes) */ Stream_Read_UINT8(s, versionInfo->NTLMRevisionCurrent); /* NTLMRevisionCurrent (1 byte) */ return 1; }
/** * Function description * * @return 0 on success, otherwise a Win32 error code */ UINT rdpgfx_read_color32(wStream* s, RDPGFX_COLOR32* color32) { if (Stream_GetRemainingLength(s) < 4) { WLog_ERR(TAG, "not enough data!"); return ERROR_INVALID_DATA; } Stream_Read_UINT8(s, color32->B); /* B (1 byte) */ Stream_Read_UINT8(s, color32->G); /* G (1 byte) */ Stream_Read_UINT8(s, color32->R); /* R (1 byte) */ Stream_Read_UINT8(s, color32->XA); /* XA (1 byte) */ return CHANNEL_RC_OK; }
void ntlm_read_ntlm_v2_client_challenge(wStream* s, NTLMv2_CLIENT_CHALLENGE* challenge) { size_t size; Stream_Read_UINT8(s, challenge->RespType); Stream_Read_UINT8(s, challenge->HiRespType); Stream_Read_UINT16(s, challenge->Reserved1); Stream_Read_UINT32(s, challenge->Reserved2); Stream_Read(s, challenge->Timestamp, 8); Stream_Read(s, challenge->ClientChallenge, 8); Stream_Read_UINT32(s, challenge->Reserved3); size = Stream_Length(s) - Stream_GetPosition(s); challenge->AvPairs = (NTLM_AV_PAIR*) malloc(size); Stream_Read(s, challenge->AvPairs, size); }
/** * 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; }
static int wts_read_variable_uint(wStream* s, int cbLen, UINT32* val) { switch (cbLen) { case 0: if (Stream_GetRemainingLength(s) < 1) return 0; Stream_Read_UINT8(s, *val); return 1; case 1: if (Stream_GetRemainingLength(s) < 2) return 0; Stream_Read_UINT16(s, *val); return 2; default: if (Stream_GetRemainingLength(s) < 4) return 0; Stream_Read_UINT32(s, *val); return 4; } }
BOOL rail_read_server_sysparam_order(wStream* s, RAIL_SYSPARAM_ORDER* sysparam) { BYTE body; if (Stream_GetRemainingLength(s) < 5) return FALSE; Stream_Read_UINT32(s, sysparam->param); /* systemParam (4 bytes) */ Stream_Read_UINT8(s, body); /* body (1 byte) */ switch (sysparam->param) { case SPI_SET_SCREEN_SAVE_ACTIVE: sysparam->setScreenSaveActive = (body != 0) ? TRUE : FALSE; break; case SPI_SET_SCREEN_SAVE_SECURE: sysparam->setScreenSaveSecure = (body != 0) ? TRUE : FALSE; break; default: break; } return TRUE; }
static int read_touch_contact_data(RdpeiServerContext *context, wStream *s, RDPINPUT_CONTACT_DATA *contactData) { if (Stream_GetRemainingLength(s) < 1) return -1; Stream_Read_UINT8(s, contactData->contactId); if (!rdpei_read_2byte_unsigned(s, &contactData->fieldsPresent) || !rdpei_read_4byte_signed(s, &contactData->x) || !rdpei_read_4byte_signed(s, &contactData->y) || !rdpei_read_4byte_unsigned(s, &contactData->contactFlags)) return -1; if (contactData->fieldsPresent & CONTACT_DATA_CONTACTRECT_PRESENT) { if (!rdpei_read_2byte_signed(s, &contactData->contactRectLeft) || !rdpei_read_2byte_signed(s, &contactData->contactRectTop) || !rdpei_read_2byte_signed(s, &contactData->contactRectRight) || !rdpei_read_2byte_signed(s, &contactData->contactRectBottom)) return -1; } if ((contactData->fieldsPresent & CONTACT_DATA_ORIENTATION_PRESENT) && !rdpei_read_4byte_unsigned(s, &contactData->orientation)) return -1; if ((contactData->fieldsPresent & CONTACT_DATA_PRESSURE_PRESENT) && !rdpei_read_4byte_unsigned(s, &contactData->pressure)) return -1; return 0; }
BOOL rdp_read_share_data_header(wStream* s, UINT16* length, BYTE* type, UINT32* share_id, BYTE *compressed_type, UINT16 *compressed_len) { if (Stream_GetRemainingLength(s) < 12) return FALSE; /* Share Data Header */ Stream_Read_UINT32(s, *share_id); /* shareId (4 bytes) */ Stream_Seek_UINT8(s); /* pad1 (1 byte) */ Stream_Seek_UINT8(s); /* streamId (1 byte) */ Stream_Read_UINT16(s, *length); /* uncompressedLength (2 bytes) */ Stream_Read_UINT8(s, *type); /* pduType2, Data PDU Type (1 byte) */ Stream_Read_UINT8(s, *compressed_type); /* compressedType (1 byte) */ Stream_Read_UINT16(s, *compressed_len); /* compressedLength (2 bytes) */ return TRUE; }
BOOL update_read_refresh_rect(rdpUpdate* update, wStream* s) { int index; BYTE numberOfAreas; RECTANGLE_16* areas; if (Stream_GetRemainingLength(s) < 4) return FALSE; Stream_Read_UINT8(s, numberOfAreas); Stream_Seek(s, 3); /* pad3Octects */ if (Stream_GetRemainingLength(s) < numberOfAreas * 4 * 2) return FALSE; areas = (RECTANGLE_16*) malloc(sizeof(RECTANGLE_16) * numberOfAreas); for (index = 0; index < numberOfAreas; index++) { Stream_Read_UINT16(s, areas[index].left); Stream_Read_UINT16(s, areas[index].top); Stream_Read_UINT16(s, areas[index].right); Stream_Read_UINT16(s, areas[index].bottom); } IFCALL(update->RefreshRect, update->context, numberOfAreas, areas); free(areas); return TRUE; }
BOOL ber_read_integer(wStream* s, UINT32* value) { int length; if (!ber_read_universal_tag(s, BER_TAG_INTEGER, FALSE) || !ber_read_length(s, &length) || ((int) Stream_GetRemainingLength(s)) < length) return FALSE; if (value == NULL) { // even if we don't care the integer value, check the announced size return Stream_SafeSeek(s, length); } if (length == 1) { Stream_Read_UINT8(s, *value); } else if (length == 2) { Stream_Read_UINT16_BE(s, *value); } else if (length == 3) { BYTE byte; Stream_Read_UINT8(s, byte); Stream_Read_UINT16_BE(s, *value); *value += (byte << 16); } else if (length == 4) { Stream_Read_UINT32_BE(s, *value); } else if (length == 8) { WLog_ERR(TAG, "should implement reading an 8 bytes integer"); return FALSE; } else { WLog_ERR(TAG, "should implement reading an integer with length=%d", length); return FALSE; } return TRUE; }
static BOOL FDSAPI_DecodeUINT8(wStream* s, UINT8* uint8Value) { if (Stream_GetRemainingLength(s) < 1) return FALSE; Stream_Read_UINT8(s, *uint8Value); return TRUE; }
/** * Function description * * @return 0 on success, otherwise a Win32 error code */ static UINT rdpgfx_recv_wire_to_surface_1_pdu(RDPGFX_CHANNEL_CALLBACK* callback, wStream* s) { RDPGFX_SURFACE_COMMAND cmd; RDPGFX_WIRE_TO_SURFACE_PDU_1 pdu; RDPGFX_PLUGIN* gfx = (RDPGFX_PLUGIN*) callback->plugin; UINT error; if (Stream_GetRemainingLength(s) < 17) { WLog_ERR(TAG, "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_UINT8(s, pdu.pixelFormat); /* pixelFormat (1 byte) */ if ((error = rdpgfx_read_rect16(s, &(pdu.destRect)))) /* destRect (8 bytes) */ { WLog_ERR(TAG, "rdpgfx_read_rect16 failed with error %lu", error); return error; } Stream_Read_UINT32(s, pdu.bitmapDataLength); /* bitmapDataLength (4 bytes) */ if (pdu.bitmapDataLength > Stream_GetRemainingLength(s)) { WLog_ERR(TAG, "not enough data!"); return ERROR_INVALID_DATA; } pdu.bitmapData = Stream_Pointer(s); Stream_Seek(s, pdu.bitmapDataLength); WLog_DBG(TAG, "RecvWireToSurface1Pdu: surfaceId: %d codecId: %s (0x%04X) pixelFormat: 0x%04X " "destRect: left: %d top: %d right: %d bottom: %d bitmapDataLength: %d", (int) pdu.surfaceId, rdpgfx_get_codec_id_string(pdu.codecId), pdu.codecId, pdu.pixelFormat, pdu.destRect.left, pdu.destRect.top, pdu.destRect.right, pdu.destRect.bottom, pdu.bitmapDataLength); cmd.surfaceId = pdu.surfaceId; cmd.codecId = pdu.codecId; cmd.contextId = 0; cmd.format = pdu.pixelFormat; cmd.left = pdu.destRect.left; cmd.top = pdu.destRect.top; cmd.right = pdu.destRect.right; cmd.bottom = pdu.destRect.bottom; cmd.width = cmd.right - cmd.left; cmd.height = cmd.bottom - cmd.top; cmd.length = pdu.bitmapDataLength; cmd.data = pdu.bitmapData; if ((error = rdpgfx_decode(gfx, &cmd))) WLog_ERR(TAG, "rdpgfx_decode failed with error %lu!", error); return error; }
int rdpgfx_recv_wire_to_surface_1_pdu(RDPGFX_CHANNEL_CALLBACK* callback, wStream* s) { RDPGFX_SURFACE_COMMAND cmd; RDPGFX_WIRE_TO_SURFACE_PDU_1 pdu; RDPGFX_PLUGIN* gfx = (RDPGFX_PLUGIN*) callback->plugin; RdpgfxClientContext* context = (RdpgfxClientContext*) gfx->iface.pInterface; if (Stream_GetRemainingLength(s) < 17) return -1; Stream_Read_UINT16(s, pdu.surfaceId); /* surfaceId (2 bytes) */ Stream_Read_UINT16(s, pdu.codecId); /* codecId (2 bytes) */ Stream_Read_UINT8(s, pdu.pixelFormat); /* pixelFormat (1 byte) */ rdpgfx_read_rect16(s, &(pdu.destRect)); /* destRect (8 bytes) */ Stream_Read_UINT32(s, pdu.bitmapDataLength); /* bitmapDataLength (4 bytes) */ if (pdu.bitmapDataLength > Stream_GetRemainingLength(s)) return -1; pdu.bitmapData = Stream_Pointer(s); Stream_Seek(s, pdu.bitmapDataLength); WLog_Print(gfx->log, WLOG_DEBUG, "RecvWireToSurface1Pdu: surfaceId: %d codecId: %s (0x%04X) pixelFormat: 0x%04X " "destRect: left: %d top: %d right: %d bottom: %d bitmapDataLength: %d", (int) pdu.surfaceId, rdpgfx_get_codec_id_string(pdu.codecId), pdu.codecId, pdu.pixelFormat, pdu.destRect.left, pdu.destRect.top, pdu.destRect.right, pdu.destRect.bottom, pdu.bitmapDataLength); cmd.surfaceId = pdu.surfaceId; cmd.codecId = pdu.codecId; cmd.contextId = 0; cmd.format = pdu.pixelFormat; cmd.left = pdu.destRect.left; cmd.top = pdu.destRect.top; cmd.right = pdu.destRect.right; cmd.bottom = pdu.destRect.bottom; cmd.width = cmd.right - cmd.left; cmd.height = cmd.bottom - cmd.top; cmd.length = pdu.bitmapDataLength; cmd.data = pdu.bitmapData; if (cmd.codecId == RDPGFX_CODECID_H264) { rdpgfx_decode(gfx, &cmd); } else { if (context && context->SurfaceCommand) { context->SurfaceCommand(context, &cmd); } } return 1; }
static UINT video_read_tsmm_presentation_req(VideoClientContext *context, wStream *s) { TSMM_PRESENTATION_REQUEST req; if (Stream_GetRemainingLength(s) < 60) { WLog_ERR(TAG, "not enough bytes for a TSMM_PRESENTATION_REQUEST"); return ERROR_INVALID_DATA; } Stream_Read_UINT8(s, req.PresentationId); Stream_Read_UINT8(s, req.Version); Stream_Read_UINT8(s, req.Command); Stream_Read_UINT8(s, req.FrameRate); /* FrameRate - reserved and ignored */ Stream_Seek_UINT16(s); /* AverageBitrateKbps reserved and ignored */ Stream_Seek_UINT16(s); /* reserved */ Stream_Read_UINT32(s, req.SourceWidth); Stream_Read_UINT32(s, req.SourceHeight); Stream_Read_UINT32(s, req.ScaledWidth); Stream_Read_UINT32(s, req.ScaledHeight); Stream_Read_UINT64(s, req.hnsTimestampOffset); Stream_Read_UINT64(s, req.GeometryMappingId); Stream_Read(s, req.VideoSubtypeId, 16); Stream_Read_UINT32(s, req.cbExtra); if (Stream_GetRemainingLength(s) < req.cbExtra) { WLog_ERR(TAG, "not enough bytes for cbExtra of TSMM_PRESENTATION_REQUEST"); return ERROR_INVALID_DATA; } req.pExtraData = Stream_Pointer(s); WLog_DBG(TAG, "presentationReq: id:%"PRIu8" version:%"PRIu8" command:%s srcWidth/srcHeight=%"PRIu32"x%"PRIu32 " scaled Width/Height=%"PRIu32"x%"PRIu32" timestamp=%"PRIu64" mappingId=%"PRIx64"", req.PresentationId, req.Version, video_command_name(req.Command), req.SourceWidth, req.SourceHeight, req.ScaledWidth, req.ScaledHeight, req.hnsTimestampOffset, req.GeometryMappingId); return video_PresentationRequest(context, &req); }
void nego_process_negotiation_request(rdpNego* nego, wStream* s) { BYTE flags; UINT16 length; Stream_Read_UINT8(s, flags); Stream_Read_UINT16(s, length); Stream_Read_UINT32(s, nego->RequestedProtocols); WLog_DBG(TAG, "RDP_NEG_REQ: RequestedProtocol: 0x%08"PRIX32"", nego->RequestedProtocols); nego->state = NEGO_STATE_FINAL; }
BOOL update_read_cached_icon_info(wStream* s, CACHED_ICON_INFO* cachedIconInfo) { if (Stream_GetRemainingLength(s) < 3) return FALSE; Stream_Read_UINT16(s, cachedIconInfo->cacheEntry); /* cacheEntry (2 bytes) */ Stream_Read_UINT8(s, cachedIconInfo->cacheId); /* cacheId (1 byte) */ return TRUE; }