/// <summary> /// Method to send RDPRFX raw data. /// </summary> /// <param name="surfStreamCmd">TS_SURFCMD_STREAM_SURF_BITS to be send.</param> private void SendSurfaceCmd_StreamSurfBits(TS_SURFCMD_STREAM_SURF_BITS surfStreamCmd) { if (rdpbcgrAdapter != null) { rdpbcgrAdapter.SendStreamSurfaceBitsCommand(surfStreamCmd); } else if (this.rdpbcgrServerStack != null && this.rdpbcgrSessionContext != null) { //TS_FRAME_MARKER frameMakerCmdBegin = new TS_FRAME_MARKER(); //frameMakerCmdBegin.cmdType = cmdType_Values.CMDTYPE_FRAME_MARKER; //frameMakerCmdBegin.frameAction = frameAction_Values.SURFACECMD_FRAMEACTION_BEGIN; //frameMakerCmdBegin.frameId = frameIndex; //TS_FRAME_MARKER frameMakerCmdEnd = new TS_FRAME_MARKER(); //frameMakerCmdEnd.cmdType = cmdType_Values.CMDTYPE_FRAME_MARKER; //frameMakerCmdEnd.frameAction = frameAction_Values.SURFACECMD_FRAMEACTION_END; //frameMakerCmdEnd.frameId = frameIndex++; TS_FP_SURFCMDS surfCmds = new TS_FP_SURFCMDS(); surfCmds.updateHeader = (byte)(((int)updateCode_Values.FASTPATH_UPDATETYPE_SURFCMDS & 0x0f) | (((int)fragmentation_Value.FASTPATH_FRAGMENT_SINGLE) << 4) | ((int)compressedType_Values.None << 6)); surfCmds.compressionFlags = compressedType_Values.None; int subLength = 8 + 8 + 22; if(surfStreamCmd.bitmapData.exBitmapDataHeader != null) { subLength += 24; } surfCmds.size = (ushort)(subLength + surfStreamCmd.bitmapData.bitmapDataLength);//size of TS_SURFCMD_STREAM_SURF_BITS; surfCmds.surfaceCommands = new TS_SURFCMD[1]; surfCmds.surfaceCommands[0] = surfStreamCmd; TS_FP_UPDATE_PDU fpOutput; TS_FP_UPDATE[] updates = new TS_FP_UPDATE[1]; updates[0] = surfCmds; fpOutput = rdpbcgrServerStack.CreateFastPathUpdatePdu(rdpbcgrSessionContext, updates); rdpbcgrServerStack.SendPdu(rdpbcgrSessionContext, fpOutput); } }
/// <summary> /// Parse TS_FP_UPDATE array /// (parser index is updated according to parsed length) /// </summary> /// <param name="data">data to be parsed</param> /// <param name="currentIndex">current parser index</param> /// <returns>parsed TS_FP_UPDATE array</returns> private TS_FP_UPDATE[] ParseTsFpUpdates(byte[] data, ref int currentIndex) { List<TS_FP_UPDATE> listUpdate = new List<TS_FP_UPDATE>(); // One by one parse TS_FP_UPDATE while (currentIndex < data.Length) { TS_FP_UPDATE update = null; // Update header byte updateHeader = ParseByte(data, ref currentIndex); // Get infomation from updateHeader updateCode_Values updateCode; fragmentation_Value fragmentation; compression_Values compression; GetFpUpdateHeaderInfo(updateHeader, out updateCode, out fragmentation, out compression); // Get compressionFlags (optional) compressedType_Values compressionFlags = 0; if (compression_Values.FASTPATH_OUTPUT_COMPRESSION_USED == compression) { compressionFlags = (compressedType_Values)ParseByte(data, ref currentIndex); } // Get size and update data UInt16 updateDataSize = ParseUInt16(data, ref currentIndex, false); byte[] updateData = GetBytes(data, ref currentIndex, updateDataSize); // Decompress update data (according to compressionFlags) byte[] decompressedUpdateData = clientContext.Decompress(updateData, compressionFlags); // Parse fast-path updates by updateCode switch (updateCode) { // Fast-Path Orders Update case updateCode_Values.FASTPATH_UPDATETYPE_ORDERS: update = ParseTsFpUpdateOrders(updateHeader, compressionFlags, updateDataSize, decompressedUpdateData); break; // Fast-Path Bitmap Update case updateCode_Values.FASTPATH_UPDATETYPE_BITMAP: update = ParseTsFpUpdateBitmap(updateHeader, compressionFlags, updateDataSize, decompressedUpdateData); break; // Fast-Path Palette Update case updateCode_Values.FASTPATH_UPDATETYPE_PALETTE: update = ParseTsFpUpdatePalette(updateHeader, compressionFlags, updateDataSize, decompressedUpdateData); break; // Fast-Path Synchronize Update case updateCode_Values.FASTPATH_UPDATETYPE_SYNCHRONIZE: update = ParseTsFpUpdateSynchronize( updateHeader, compressionFlags, updateDataSize); break; // Fast-Path Surface commands Update case updateCode_Values.FASTPATH_UPDATETYPE_SURFCMDS: update = ParseTsFpSurfCmds(updateHeader, compressionFlags, updateDataSize, decompressedUpdateData); break; // Fast-Path System Pointer Hidden Update case updateCode_Values.FASTPATH_UPDATETYPE_PTR_NULL: update = ParseTsFpSystemPointerHiddenAttribute( updateHeader, compressionFlags, updateDataSize); break; // Fast-Path System Pointer Default Update case updateCode_Values.FASTPATH_UPDATETYPE_PTR_DEFAULT: update = ParseTsFpSystemPointerDefaultAttribute( updateHeader, compressionFlags, updateDataSize); break; // Fast-Path Pointer Position Update case updateCode_Values.FASTPATH_UPDATETYPE_PTR_POSITION: update = ParseTsFpPointerPosAttribute(updateHeader, compressionFlags, updateDataSize, decompressedUpdateData); break; // Fast-Path Color Pointer Update case updateCode_Values.FASTPATH_UPDATETYPE_COLOR: update = ParseTsFpColorPointerAttribute(updateHeader, compressionFlags, updateDataSize, decompressedUpdateData); break; // Fast-Path Cached Pointer Update case updateCode_Values.FASTPATH_UPDATETYPE_CACHED: update = ParseTsFpCachedPointerAttribute(updateHeader, compressionFlags, updateDataSize, decompressedUpdateData); break; // Fast-Path New Pointer Update case updateCode_Values.FASTPATH_UPDATETYPE_POINTER: update = ParseTsFpPointerAttribute(updateHeader, compressionFlags, updateDataSize, decompressedUpdateData); break; default: throw new FormatException(ConstValue.ERROR_MESSAGE_ENUM_UNRECOGNIZED); } listUpdate.Add(update); } // Copy list to array TS_FP_UPDATE[] updates = new TS_FP_UPDATE[listUpdate.Count]; for (int i = 0; i < updates.Length; i++) { updates[i] = listUpdate[i]; } return updates; }
public static TS_FP_UPDATE_PDU CreateFPUpdatePDU(RdpbcgrServerSessionContext context, TS_FP_UPDATE update) { TS_FP_UPDATE_PDU fpOutput = new TS_FP_UPDATE_PDU(context); fpOutput.fpOutputHeader = (byte)(((int)nested_TS_FP_UPDATE_PDU_fpOutputHeader_actionCode_Values.FASTPATH_OUTPUT_ACTION_FASTPATH & 0x03) | ((int)((int)reserved_Values.V1 & 0x0f) << 2)); fpOutput.dataSignature = null; fpOutput.length1 = 0; fpOutput.length2 = 0; fpOutput.fpOutputUpdates = new TS_FP_UPDATE[1]; fpOutput.fpOutputUpdates[0] = update; return fpOutput; }