explicit ShareData_Recv(InStream & stream, rdp_mppc_dec * dec = nullptr) //============================================================================== : CheckShareData_Recv(stream) , share_id(stream.in_uint32_le()) , pad1(stream.in_uint8()) , streamid(stream.in_uint8()) , len(stream.in_uint16_le()) , pdutype2(stream.in_uint8()) , compressedType(stream.in_uint8()) , compressedLen(stream.in_uint16_le()) , payload([&stream, dec, this]() { if (this->compressedType & PACKET_COMPRESSED) { if (!dec) { LOG(LOG_INFO, "ShareData_Recv: got unexpected compressed share data"); throw Error(ERR_SEC); } const uint8_t * rdata; uint32_t rlen; dec->decompress(stream.get_data()+stream.get_offset(), stream.in_remain(), this->compressedType, rdata, rlen); return InStream(rdata, 0, rlen); } else { return InStream(stream.get_current(), stream.in_remain()); } }()) // BEGIN CONSTRUCTOR { //LOG( LOG_INFO, "ShareData_Recv: pdutype2=%u len=%u compressedLen=%u payload_size=%u" // , this->pdutype2, this->len, this->compressedLen, this->payload.size()); stream.in_skip_bytes(stream.in_remain()); } // END CONSTRUCTOR
void recv(InStream & stream, uint16_t len) { this->len = len; this->cacheVersion = stream.in_uint8(); this->pad1 = stream.in_uint8(); this->pad2 = stream.in_uint16_le(); }
explicit ShareFlow_Recv(InStream & stream) : flowMarker([&stream]{ if (!stream.in_check_rem(2+1+1+1+1+2)){ LOG(LOG_ERR, "Truncated " "[2: ShareFlow PDU packet]" "[1: ShareFlow pad]" "[1: ShareFlow PDU type]" "[1: flow Identifier]" "[1: flow number]" "[2: ShareFlow PDU packet] , remains=%zu", stream.in_remain()); throw Error(ERR_SEC); } return stream.in_uint16_le(); }()) , pad(stream.in_uint8()) , pduTypeFlow(stream.in_uint8()) , flowIdentifier(stream.in_uint8()) , flowNumber(stream.in_uint8()) , mcs_channel(stream.in_uint16_le()) { LOG(LOG_INFO, "Flow control packet %.4x (offset=%zu)", this->flowMarker, stream.get_offset()); if (this->flowMarker != 0x8000) { LOG(LOG_ERR, "Expected flow control packet, got %.4x", this->flowMarker); throw Error(ERR_SEC); } LOG(LOG_INFO, "PDUTypeFlow=%u", this->pduTypeFlow); if (stream.in_remain()) { LOG(LOG_INFO, "trailing bytes in FlowPDU, remains %zu bytes", stream.in_remain()); } }
void receive(InStream & stream, const RDPPrimaryOrderHeader & header) { //LOG(LOG_INFO, "RDPMultiDstBlt::receive: header fields=0x%02X", header.fields); header.receive_coord(stream, 0x0001, this->nLeftRect); header.receive_coord(stream, 0x0002, this->nTopRect); header.receive_coord(stream, 0x0004, this->nWidth); header.receive_coord(stream, 0x0008, this->nHeight); if (header.fields & 0x0010) { this->bRop = stream.in_uint8(); } if (header.fields & 0x0020) { this->nDeltaEntries = stream.in_uint8(); } if (header.fields & 0x0040) { uint16_t cbData = stream.in_uint16_le(); //LOG(LOG_INFO, "cbData=%d", cbData); InStream rgbData(stream.get_current(), cbData); stream.in_skip_bytes(cbData); //hexdump_d(rgbData.get_current(), rgbData.get_capacity()); uint8_t zeroBitsSize = ((this->nDeltaEntries + 1) / 2); //LOG(LOG_INFO, "zeroBitsSize=%d", zeroBitsSize); InStream zeroBits(rgbData.get_current(), zeroBitsSize); rgbData.in_skip_bytes(zeroBitsSize); uint8_t zeroBit = 0; for (uint8_t i = 0, m2 = 0; i < this->nDeltaEntries; i++, m2++) { if (m2 == 2) { m2 = 0; } if (!m2) { zeroBit = zeroBits.in_uint8(); //LOG(LOG_INFO, "0x%02X", zeroBit); } this->deltaEncodedRectangles[i].leftDelta = (!(zeroBit & 0x80) ? rgbData.in_DEP() : 0); this->deltaEncodedRectangles[i].topDelta = (!(zeroBit & 0x40) ? rgbData.in_DEP() : 0); this->deltaEncodedRectangles[i].width = (!(zeroBit & 0x20) ? rgbData.in_DEP() : 0); this->deltaEncodedRectangles[i].height = (!(zeroBit & 0x10) ? rgbData.in_DEP() : 0); //LOG(LOG_INFO, "RDPMultiDstBlt::receive: delta rectangle=(%d, %d, %d, %d)", // this->deltaEncodedRectangles[i].leftDelta, this->deltaEncodedRectangles[i].topDelta, // this->deltaEncodedRectangles[i].width, this->deltaEncodedRectangles[i].height); zeroBit <<= 4; } } } // void receive(InStream & stream, const RDPPrimaryOrderHeader & header)
void recv(InStream & stream) { // size_t size; this->RespType = stream.in_uint8(); this->HiRespType = stream.in_uint8(); stream.in_skip_bytes(2); stream.in_skip_bytes(4); stream.in_copy_bytes(this->Timestamp, 8); stream.in_copy_bytes(this->ClientChallenge, 8); stream.in_skip_bytes(4); this->AvPairList.recv(stream); stream.in_skip_bytes(4); }
void receive(InStream & stream) { { const unsigned expected = 4; // allowDisplayUpdates(1) + Padding(3) if (!stream.in_check_rem(expected)) { LOG(LOG_ERR, "Truncated SuppressOutputPDUData: expected=%u remains=%zu", expected, stream.in_remain()); throw Error(ERR_RDP_DATA_TRUNCATED); } } this->allowDisplayUpdates_ = stream.in_uint8(); stream.in_skip_bytes(3); // Padding(3) if (ALLOW_DISPLAY_UPDATES == this->allowDisplayUpdates_) { { const unsigned expected = 8; // left(2) + top(2) + right(2) + bottom(2) if (!stream.in_check_rem(expected)) { LOG(LOG_ERR, "Truncated SuppressOutputPDUData(2): expected=%u remains=%zu", expected, stream.in_remain()); throw Error(ERR_RDP_DATA_TRUNCATED); } } this->left_ = stream.in_uint16_le(); this->top_ = stream.in_uint16_le(); this->right_ = stream.in_uint16_le(); this->bottom_ = stream.in_uint16_le(); } } // void receive(InStream & stream)
void recv(InStream & stream, uint16_t len) { this->len = len; this->WndSupportLevel = stream.in_uint32_le(); this->NumIconCaches = stream.in_uint8(); this->NumIconCacheEntries = stream.in_uint16_le(); }
void receive(InStream & stream, const RDPSecondaryOrderHeader &/* header*/) { using namespace RDP; this->cacheIndex = stream.in_uint8(); LOG(LOG_INFO, "receiving colormap %u", this->cacheIndex); assert(this->cacheIndex < 6); uint16_t numberColors = stream.in_uint16_le(); for (size_t i = 0; i < numberColors; i++) { uint8_t b = stream.in_uint8(); uint8_t g = stream.in_uint8(); uint8_t r = stream.in_uint8(); stream.in_skip_bytes(1); this->palette.set_color(i, b|(g << 8)| (r << 16)); } }
void receive(InStream & stream, const RDPPrimaryOrderHeader & header) { // LOG(LOG_INFO, "RDPEllipseSC::receive: header fields=0x%02X", header.fields); int16_t leftRect = this->el.left(); int16_t topRect = this->el.top(); int16_t rightRect = this->el.right(); int16_t bottomRect = this->el.bottom(); header.receive_coord(stream, 0x0001, leftRect); header.receive_coord(stream, 0x0002, topRect); header.receive_coord(stream, 0x0004, rightRect); header.receive_coord(stream, 0x0008, bottomRect); this->el = Ellipse(leftRect, topRect, rightRect, bottomRect); if (header.fields & 0x0010) { this->bRop2 = stream.in_uint8(); } if (header.fields & 0x0020) { this->fillMode = stream.in_uint8(); } if (header.fields & 0x0040) { receive_rdp_color(stream, this->color); } }
inline void process_glyphcache(GlyphCache & gly_cache, InStream & stream) { const uint8_t cacheId = stream.in_uint8(); const uint8_t nglyphs = stream.in_uint8(); for (uint8_t i = 0; i < nglyphs; i++) { const uint16_t cacheIndex = stream.in_uint16_le(); const int16_t offset = stream.in_sint16_le(); const int16_t baseline = stream.in_sint16_le(); const uint16_t width = stream.in_uint16_le(); const uint16_t height = stream.in_uint16_le(); const unsigned int datasize = (height * nbbytes(width) + 3) & ~3; const uint8_t * data = stream.in_uint8p(datasize); server_add_char(gly_cache, cacheId, cacheIndex, offset, baseline, width, height, data); } }
void recv(InStream & stream, uint16_t len)override { this->len = len; if (len != CAPLEN_BITMAPCACHE_REV2 || !stream.in_check_rem(len)) { LOG(LOG_ERR, "Broken CAPSTYPE_BITMAPCACHE_REV2, need=%u (%" PRIu16 ") remains=%zu", CAPLEN_BITMAPCACHE_REV2, len, stream.in_remain()); throw Error(ERR_MCS_PDU_TRUNCATED); } this->cacheFlags = stream.in_uint16_le(); this->pad1 = stream.in_uint8(); this->numCellCaches = stream.in_uint8(); this->bitmapCache0CellInfo = stream.in_uint32_le(); this->bitmapCache1CellInfo = stream.in_uint32_le(); this->bitmapCache2CellInfo = stream.in_uint32_le(); this->bitmapCache3CellInfo = stream.in_uint32_le(); this->bitmapCache4CellInfo = stream.in_uint32_le(); stream.in_skip_bytes(12); }
void receive(InStream & stream, const RDPPrimaryOrderHeader & header) { using namespace RDP; if (header.fields & 0x001) { this->back_mode = stream.in_uint16_le(); } header.receive_coord(stream, 0x002, this->startx); header.receive_coord(stream, 0x004, this->starty); header.receive_coord(stream, 0x008, this->endx); header.receive_coord(stream, 0x010, this->endy); if (header.fields & 0x020) { receive_rdp_color(stream, this->back_color); } if (header.fields & 0x040) { this->rop2 = stream.in_uint8(); } header.receive_pen(stream, 0x080, this->pen); }
void receive(InStream & stream, const RDPPrimaryOrderHeader & header) { // LOG(LOG_INFO, "RDPPolygonSC::receive: header fields=0x%02X", header.fields); header.receive_coord(stream, 0x0001, this->xStart); header.receive_coord(stream, 0x0002, this->yStart); if (header.fields & 0x0004) { this->bRop2 = stream.in_uint8(); } if (header.fields & 0x0008) { this->fillMode = stream.in_uint8(); } if (header.fields & 0x0010) { receive_rdp_color(stream, this->backColor); } if (header.fields & 0x0020) { receive_rdp_color(stream, this->foreColor); } header.receive_brush(stream, 0x0040, this->brush); if (header.fields & 0x0800) { this->NumDeltaEntries = stream.in_uint8(); } if (header.fields & 0x1000) { uint8_t cbData = stream.in_uint8(); // LOG(LOG_INFO, "cbData=%d", cbData); InStream rgbData(stream.get_current(), cbData); stream.in_skip_bytes(cbData); // hexdump_d(rgbData.get_current(), rgbData.get_capacity()); uint8_t zeroBitsSize = ((this->NumDeltaEntries + 3) / 4); // LOG(LOG_INFO, "zeroBitsSize=%d", zeroBitsSize); InStream zeroBits(rgbData.get_current(), zeroBitsSize); rgbData.in_skip_bytes(zeroBitsSize); uint8_t zeroBit = 0; for (uint8_t i = 0, m4 = 0; i < this->NumDeltaEntries; i++, m4++) { if (m4 == 4) { m4 = 0; } if (!m4) { zeroBit = zeroBits.in_uint8(); // LOG(LOG_INFO, "0x%02X", zeroBit); } this->deltaPoints[i].xDelta = (!(zeroBit & 0x80) ? rgbData.in_DEP() : 0); this->deltaPoints[i].yDelta = (!(zeroBit & 0x40) ? rgbData.in_DEP() : 0); /* LOG(LOG_INFO, "RDPPolygonCB::receive: delta point=%d, %d", this->deltaPoints[i].xDelta, this->deltaPoints[i].yDelta); */ zeroBit <<= 2; } } } // receive
explicit AltsecDrawingOrderHeader(InStream & stream) { this->controlFlags = stream.in_uint8(); this->class_ = (this->controlFlags & 0x03); this->orderType = (this->controlFlags >> 2); }