基本适应win7,win10,win server 08,win server 12,win server 16的截图

This commit is contained in:
2025-01-03 23:00:47 +08:00
parent 909b89dfce
commit 84362607c2
77 changed files with 69638 additions and 1 deletions

760
grdp/protocol/pdu/caps.go Normal file
View File

@@ -0,0 +1,760 @@
package pdu
import (
"bytes"
"encoding/hex"
"errors"
"fmt"
"io"
"ShotRDP/grdp/glog"
"ShotRDP/grdp/core"
"ShotRDP/grdp/protocol/t125/gcc"
"github.com/lunixbochs/struc"
)
type CapsType uint16
const (
CAPSTYPE_GENERAL CapsType = 0x0001
CAPSTYPE_BITMAP = 0x0002
CAPSTYPE_ORDER = 0x0003
CAPSTYPE_BITMAPCACHE = 0x0004
CAPSTYPE_CONTROL = 0x0005
CAPSTYPE_ACTIVATION = 0x0007
CAPSTYPE_POINTER = 0x0008
CAPSTYPE_SHARE = 0x0009
CAPSTYPE_COLORCACHE = 0x000A
CAPSTYPE_SOUND = 0x000C
CAPSTYPE_INPUT = 0x000D
CAPSTYPE_FONT = 0x000E
CAPSTYPE_BRUSH = 0x000F
CAPSTYPE_GLYPHCACHE = 0x0010
CAPSTYPE_OFFSCREENCACHE = 0x0011
CAPSTYPE_BITMAPCACHE_HOSTSUPPORT = 0x0012
CAPSTYPE_BITMAPCACHE_REV2 = 0x0013
CAPSTYPE_VIRTUALCHANNEL = 0x0014
CAPSTYPE_DRAWNINEGRIDCACHE = 0x0015
CAPSTYPE_DRAWGDIPLUS = 0x0016
CAPSTYPE_RAIL = 0x0017
CAPSTYPE_WINDOW = 0x0018
CAPSETTYPE_COMPDESK = 0x0019
CAPSETTYPE_MULTIFRAGMENTUPDATE = 0x001A
CAPSETTYPE_LARGE_POINTER = 0x001B
CAPSETTYPE_SURFACE_COMMANDS = 0x001C
CAPSETTYPE_BITMAP_CODECS = 0x001D
CAPSSETTYPE_FRAME_ACKNOWLEDGE = 0x001E
)
func (c CapsType) String() string {
switch c {
case CAPSTYPE_GENERAL:
return "CAPSTYPE_GENERAL"
case CAPSTYPE_BITMAP:
return "CAPSTYPE_BITMAP"
case CAPSTYPE_ORDER:
return "CAPSTYPE_ORDER"
case CAPSTYPE_BITMAPCACHE:
return "CAPSTYPE_BITMAPCACHE"
case CAPSTYPE_CONTROL:
return "CAPSTYPE_CONTROL"
case CAPSTYPE_ACTIVATION:
return "CAPSTYPE_ACTIVATION"
case CAPSTYPE_POINTER:
return "CAPSTYPE_POINTER"
case CAPSTYPE_SHARE:
return "CAPSTYPE_SHARE"
case CAPSTYPE_COLORCACHE:
return "CAPSTYPE_COLORCACHE"
case CAPSTYPE_SOUND:
return "CAPSTYPE_SOUND"
case CAPSTYPE_INPUT:
return "CAPSTYPE_INPUT"
case CAPSTYPE_FONT:
return "CAPSTYPE_FONT"
case CAPSTYPE_BRUSH:
return "CAPSTYPE_BRUSH"
case CAPSTYPE_GLYPHCACHE:
return "CAPSTYPE_GLYPHCACHE"
case CAPSTYPE_OFFSCREENCACHE:
return "CAPSTYPE_OFFSCREENCACHE"
case CAPSTYPE_BITMAPCACHE_HOSTSUPPORT:
return "CAPSTYPE_BITMAPCACHE_HOSTSUPPORT"
case CAPSTYPE_BITMAPCACHE_REV2:
return "CAPSTYPE_BITMAPCACHE_REV2"
case CAPSTYPE_VIRTUALCHANNEL:
return "CAPSTYPE_VIRTUALCHANNEL"
case CAPSTYPE_DRAWNINEGRIDCACHE:
return "CAPSTYPE_DRAWNINEGRIDCACHE"
case CAPSTYPE_DRAWGDIPLUS:
return "CAPSTYPE_DRAWGDIPLUS"
case CAPSTYPE_RAIL:
return "CAPSTYPE_RAIL"
case CAPSTYPE_WINDOW:
return "CAPSTYPE_WINDOW"
case CAPSETTYPE_COMPDESK:
return "CAPSETTYPE_COMPDESK"
case CAPSETTYPE_MULTIFRAGMENTUPDATE:
return "CAPSETTYPE_MULTIFRAGMENTUPDATE"
case CAPSETTYPE_LARGE_POINTER:
return "CAPSETTYPE_LARGE_POINTER"
case CAPSETTYPE_SURFACE_COMMANDS:
return "CAPSETTYPE_SURFACE_COMMANDS"
case CAPSETTYPE_BITMAP_CODECS:
return "CAPSETTYPE_BITMAP_CODECS"
case CAPSSETTYPE_FRAME_ACKNOWLEDGE:
return "CAPSSETTYPE_FRAME_ACKNOWLEDGE"
}
return "Unknown"
}
type MajorType uint16
const (
OSMAJORTYPE_UNSPECIFIED MajorType = 0x0000
OSMAJORTYPE_WINDOWS = 0x0001
OSMAJORTYPE_OS2 = 0x0002
OSMAJORTYPE_MACINTOSH = 0x0003
OSMAJORTYPE_UNIX = 0x0004
OSMAJORTYPE_IOS = 0x0005
OSMAJORTYPE_OSX = 0x0006
OSMAJORTYPE_ANDROID = 0x0007
)
type MinorType uint16
const (
OSMINORTYPE_UNSPECIFIED MinorType = 0x0000
OSMINORTYPE_WINDOWS_31X = 0x0001
OSMINORTYPE_WINDOWS_95 = 0x0002
OSMINORTYPE_WINDOWS_NT = 0x0003
OSMINORTYPE_OS2_V21 = 0x0004
OSMINORTYPE_POWER_PC = 0x0005
OSMINORTYPE_MACINTOSH = 0x0006
OSMINORTYPE_NATIVE_XSERVER = 0x0007
OSMINORTYPE_PSEUDO_XSERVER = 0x0008
OSMINORTYPE_WINDOWS_RT = 0x0009
)
const (
FASTPATH_OUTPUT_SUPPORTED uint16 = 0x0001
NO_BITMAP_COMPRESSION_HDR = 0x0400
LONG_CREDENTIALS_SUPPORTED = 0x0004
AUTORECONNECT_SUPPORTED = 0x0008
ENC_SALTED_CHECKSUM = 0x0010
)
type OrderFlag uint16
const (
NEGOTIATEORDERSUPPORT OrderFlag = 0x0002
ZEROBOUNDSDELTASSUPPORT = 0x0008
COLORINDEXSUPPORT = 0x0020
SOLIDPATTERNBRUSHONLY = 0x0040
ORDERFLAGS_EXTRA_FLAGS = 0x0080
)
/**
* @see http://msdn.microsoft.com/en-us/library/cc240556.aspx
*/
type Order uint8
const (
TS_NEG_DSTBLT_INDEX Order = 0x00
TS_NEG_PATBLT_INDEX = 0x01
TS_NEG_SCRBLT_INDEX = 0x02
TS_NEG_MEMBLT_INDEX = 0x03
TS_NEG_MEM3BLT_INDEX = 0x04
TS_NEG_DRAWNINEGRID_INDEX = 0x07
TS_NEG_LINETO_INDEX = 0x08
TS_NEG_MULTI_DRAWNINEGRID_INDEX = 0x09
TS_NEG_SAVEBITMAP_INDEX = 0x0B
TS_NEG_MULTIDSTBLT_INDEX = 0x0F
TS_NEG_MULTIPATBLT_INDEX = 0x10
TS_NEG_MULTISCRBLT_INDEX = 0x11
TS_NEG_MULTIOPAQUERECT_INDEX = 0x12
TS_NEG_FAST_INDEX_INDEX = 0x13
TS_NEG_POLYGON_SC_INDEX = 0x14
TS_NEG_POLYGON_CB_INDEX = 0x15
TS_NEG_POLYLINE_INDEX = 0x16
TS_NEG_FAST_GLYPH_INDEX = 0x18
TS_NEG_ELLIPSE_SC_INDEX = 0x19
TS_NEG_ELLIPSE_CB_INDEX = 0x1A
TS_NEG_GLYPH_INDEX_INDEX = 0x1B
)
type OrderEx uint16
const (
ORDERFLAGS_EX_CACHE_BITMAP_REV3_SUPPORT OrderEx = 0x0002
ORDERFLAGS_EX_ALTSEC_FRAME_MARKER_SUPPORT = 0x0004
)
/**
* @see http://msdn.microsoft.com/en-us/library/cc240563.aspx
*/
const (
INPUT_FLAG_SCANCODES uint16 = 0x0001
INPUT_FLAG_MOUSEX = 0x0004
INPUT_FLAG_FASTPATH_INPUT = 0x0008
INPUT_FLAG_UNICODE = 0x0010
INPUT_FLAG_FASTPATH_INPUT2 = 0x0020
INPUT_FLAG_UNUSED1 = 0x0040
INPUT_FLAG_UNUSED2 = 0x0080
INPUT_FLAG_MOUSE_HWHEEL = 0x0100
)
/**
* @see http://msdn.microsoft.com/en-us/library/cc240564.aspx
*/
type BrushSupport uint32
const (
BRUSH_DEFAULT BrushSupport = 0x00000000
BRUSH_COLOR_8x8 = 0x00000001
BRUSH_COLOR_FULL = 0x00000002
)
/**
* @see http://msdn.microsoft.com/en-us/library/cc240565.aspx
*/
type GlyphSupport uint16
const (
GLYPH_SUPPORT_NONE GlyphSupport = 0x0000
GLYPH_SUPPORT_PARTIAL = 0x0001
GLYPH_SUPPORT_FULL = 0x0002
GLYPH_SUPPORT_ENCODE = 0x0003
)
/**
* @see http://msdn.microsoft.com/en-us/library/cc240550.aspx
*/
type OffscreenSupportLevel uint32
const (
OSL_FALSE OffscreenSupportLevel = 0x00000000
OSL_TRUE = 0x00000001
)
/**
* @see http://msdn.microsoft.com/en-us/library/cc240551.aspx
*/
type VirtualChannelCompressionFlag uint32
const (
VCCAPS_NO_COMPR VirtualChannelCompressionFlag = 0x00000000
VCCAPS_COMPR_SC = 0x00000001
VCCAPS_COMPR_CS_8K = 0x00000002
)
type SoundFlag uint16
const (
SOUND_NONE SoundFlag = 0x0000
SOUND_BEEPS_FLAG = 0x0001
)
type RailsupportLevel uint32
const (
RAIL_LEVEL_SUPPORTED = 0x00000001
RAIL_LEVEL_DOCKED_LANGBAR_SUPPORTED = 0x00000002
RAIL_LEVEL_SHELL_INTEGRATION_SUPPORTED = 0x00000004
RAIL_LEVEL_LANGUAGE_IME_SYNC_SUPPORTED = 0x00000008
RAIL_LEVEL_SERVER_TO_CLIENT_IME_SYNC_SUPPORTED = 0x00000010
RAIL_LEVEL_HIDE_MINIMIZED_APPS_SUPPORTED = 0x00000020
RAIL_LEVEL_WINDOW_CLOAKING_SUPPORTED = 0x00000040
RAIL_LEVEL_HANDSHAKE_EX_SUPPORTED = 0x00000080
)
const (
INPUT_EVENT_SYNC = 0x0000
INPUT_EVENT_UNUSED = 0x0002
INPUT_EVENT_SCANCODE = 0x0004
INPUT_EVENT_UNICODE = 0x0005
INPUT_EVENT_MOUSE = 0x8001
INPUT_EVENT_MOUSEX = 0x8002
)
const (
PTRFLAGS_HWHEEL = 0x0400
PTRFLAGS_WHEEL = 0x0200
PTRFLAGS_WHEEL_NEGATIVE = 0x0100
WheelRotationMask = 0x01FF
PTRFLAGS_MOVE = 0x0800
PTRFLAGS_DOWN = 0x8000
PTRFLAGS_BUTTON1 = 0x1000
PTRFLAGS_BUTTON2 = 0x2000
PTRFLAGS_BUTTON3 = 0x4000
)
const (
KBDFLAGS_EXTENDED = 0x0100
KBDFLAGS_DOWN = 0x4000
KBDFLAGS_RELEASE = 0x8000
)
type SurfaceCmdFlags uint32
const (
SURFCMDS_SET_SURFACE_BITS = 0x00000002
SURFCMDS_FRAME_MARKER = 0x00000010
SURFCMDS_STREAM_SURFACE_BITS = 0x00000040
)
type Capability interface {
Type() CapsType
}
type GeneralCapability struct {
// 010018000100030000020000000015040000000000000000
OSMajorType MajorType `struc:"little"`
OSMinorType MinorType `struc:"little"`
ProtocolVersion uint16 `struc:"little"`
Pad2octetsA uint16 `struc:"little"`
GeneralCompressionTypes uint16 `struc:"little"`
ExtraFlags uint16 `struc:"little"`
UpdateCapabilityFlag uint16 `struc:"little"`
RemoteUnshareFlag uint16 `struc:"little"`
GeneralCompressionLevel uint16 `struc:"little"`
RefreshRectSupport uint8 `struc:"little"`
SuppressOutputSupport uint8 `struc:"little"`
}
func (*GeneralCapability) Type() CapsType {
return CAPSTYPE_GENERAL
}
type BitmapCapability struct {
// 02001c00180001000100010000052003000000000100000001000000
PreferredBitsPerPixel gcc.HighColor `struc:"little"`
Receive1BitPerPixel uint16 `struc:"little"`
Receive4BitsPerPixel uint16 `struc:"little"`
Receive8BitsPerPixel uint16 `struc:"little"`
DesktopWidth uint16 `struc:"little"`
DesktopHeight uint16 `struc:"little"`
Pad2octets uint16 `struc:"little"`
DesktopResizeFlag uint16 `struc:"little"`
BitmapCompressionFlag uint16 `struc:"little"`
HighColorFlags uint8 `struc:"little"`
DrawingFlags uint8 `struc:"little"`
MultipleRectangleSupport uint16 `struc:"little"`
Pad2octetsB uint16 `struc:"little"`
}
func (*BitmapCapability) Type() CapsType {
return CAPSTYPE_BITMAP
}
type BitmapCacheCapability struct {
// 04002800000000000000000000000000000000000000000000000000000000000000000000000000
Pad1 uint32 `struc:"little"`
Pad2 uint32 `struc:"little"`
Pad3 uint32 `struc:"little"`
Pad4 uint32 `struc:"little"`
Pad5 uint32 `struc:"little"`
Pad6 uint32 `struc:"little"`
Cache0Entries uint16 `struc:"little"`
Cache0MaximumCellSize uint16 `struc:"little"`
Cache1Entries uint16 `struc:"little"`
Cache1MaximumCellSize uint16 `struc:"little"`
Cache2Entries uint16 `struc:"little"`
Cache2MaximumCellSize uint16 `struc:"little"`
}
func (*BitmapCacheCapability) Type() CapsType {
return CAPSTYPE_BITMAPCACHE
}
type OrderCapability struct {
// 030058000000000000000000000000000000000000000000010014000000010000000a0000000000000000000000000000000000000000000000000000000000000000000000000000000000008403000000000000000000
TerminalDescriptor [16]byte
Pad4octetsA uint32 `struc:"little"`
DesktopSaveXGranularity uint16 `struc:"little"`
DesktopSaveYGranularity uint16 `struc:"little"`
Pad2octetsA uint16 `struc:"little"`
MaximumOrderLevel uint16 `struc:"little"`
NumberFonts uint16 `struc:"little"`
OrderFlags OrderFlag `struc:"little"`
OrderSupport [32]byte
TextFlags uint16 `struc:"little"`
OrderSupportExFlags uint16 `struc:"little"`
Pad4octetsB uint32 `struc:"little"`
DesktopSaveSize uint32 `struc:"little"`
Pad2octetsC uint16 `struc:"little"`
Pad2octetsD uint16 `struc:"little"`
TextANSICodePage uint16 `struc:"little"`
Pad2octetsE uint16 `struc:"little"`
}
func (*OrderCapability) Type() CapsType {
return CAPSTYPE_ORDER
}
type PointerCapability struct {
ColorPointerFlag uint16 `struc:"little"`
ColorPointerCacheSize uint16 `struc:"little"`
// old version of rdp doesn't support ...
PointerCacheSize uint16 `struc:"little"` // only server need
}
func (*PointerCapability) Type() CapsType {
return CAPSTYPE_POINTER
}
type InputCapability struct {
// 0d005c001500000009040000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c000000
Flags uint16 `struc:"little"`
Pad2octetsA uint16 `struc:"little"`
// same value as gcc.ClientCoreSettings.kbdLayout
KeyboardLayout gcc.KeyboardLayout `struc:"little"`
// same value as gcc.ClientCoreSettings.keyboardType
KeyboardType uint32 `struc:"little"`
// same value as gcc.ClientCoreSettings.keyboardSubType
KeyboardSubType uint32 `struc:"little"`
// same value as gcc.ClientCoreSettings.keyboardFnKeys
KeyboardFunctionKey uint32 `struc:"little"`
// same value as gcc.ClientCoreSettingrrs.imeFileName
ImeFileName [64]byte
//need add 0c000000 in the end
}
func (*InputCapability) Type() CapsType {
return CAPSTYPE_INPUT
}
type BrushCapability struct {
// 0f00080000000000
SupportLevel BrushSupport `struc:"little"`
}
func (*BrushCapability) Type() CapsType {
return CAPSTYPE_BRUSH
}
type cacheEntry struct {
Entries uint16 `struc:"little"`
MaximumCellSize uint16 `struc:"little"`
}
type GlyphCapability struct {
// 10003400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
GlyphCache [10]cacheEntry `struc:"little"`
FragCache uint32 `struc:"little"`
SupportLevel GlyphSupport `struc:"little"`
Pad2octets uint16 `struc:"little"`
}
func (*GlyphCapability) Type() CapsType {
return CAPSTYPE_GLYPHCACHE
}
type OffscreenBitmapCacheCapability struct {
// 11000c000000000000000000
SupportLevel OffscreenSupportLevel `struc:"little"`
CacheSize uint16 `struc:"little"`
CacheEntries uint16 `struc:"little"`
}
func (*OffscreenBitmapCacheCapability) Type() CapsType {
return CAPSTYPE_OFFSCREENCACHE
}
type BitmapCache2Capability struct {
BitmapCachePersist uint16 `struc:"little"`
Pad2octets uint8 `struc:"little"`
CachesNum uint8 `struc:"little"`
BmpC0Cells uint32 `struc:"little"`
BmpC1Cells uint32 `struc:"little"`
BmpC2Cells uint32 `struc:"little"`
BmpC3Cells uint32 `struc:"little"`
BmpC4Cells uint32 `struc:"little"`
Pad2octets1 [12]byte `struc:"little"`
}
func (*BitmapCache2Capability) Type() CapsType {
return CAPSTYPE_BITMAPCACHE_REV2
}
type VirtualChannelCapability struct {
// 14000c000000000000000000
Flags VirtualChannelCompressionFlag `struc:"little"`
VCChunkSize uint32 `struc:"little"` // optional
}
func (*VirtualChannelCapability) Type() CapsType {
return CAPSTYPE_VIRTUALCHANNEL
}
type SoundCapability struct {
// 0c00080000000000
Flags SoundFlag `struc:"little"`
Pad2octets uint16 `struc:"little"`
}
func (*SoundCapability) Type() CapsType {
return CAPSTYPE_SOUND
}
type ControlCapability struct {
ControlFlags uint16 `struc:"little"`
RemoteDetachFlag uint16 `struc:"little"`
ControlInterest uint16 `struc:"little"`
DetachInterest uint16 `struc:"little"`
}
func (*ControlCapability) Type() CapsType {
return CAPSTYPE_CONTROL
}
type WindowActivationCapability struct {
HelpKeyFlag uint16 `struc:"little"`
HelpKeyIndexFlag uint16 `struc:"little"`
HelpExtendedKeyFlag uint16 `struc:"little"`
WindowManagerKeyFlag uint16 `struc:"little"`
}
func (*WindowActivationCapability) Type() CapsType {
return CAPSTYPE_ACTIVATION
}
type FontCapability struct {
SupportFlags uint16 `struc:"little"`
Pad2octets uint16 `struc:"little"`
}
func (*FontCapability) Type() CapsType {
return CAPSTYPE_FONT
}
type ColorCacheCapability struct {
CacheSize uint16 `struc:"little"`
Pad2octets uint16 `struc:"little"`
}
func (*ColorCacheCapability) Type() CapsType {
return CAPSTYPE_COLORCACHE
}
type ShareCapability struct {
NodeId uint16 `struc:"little"`
Pad2octets uint16 `struc:"little"`
}
func (*ShareCapability) Type() CapsType {
return CAPSTYPE_SHARE
}
type MultiFragmentUpdate struct {
// 1a00080000000000
MaxRequestSize uint32 `struc:"little"`
}
func (*MultiFragmentUpdate) Type() CapsType {
return CAPSETTYPE_MULTIFRAGMENTUPDATE
}
// see https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpegdi/52635737-d144-4f47-9c88-b48ceaf3efb4
type DrawGDIPlusCapability struct {
SupportLevel uint32
GdipVersion uint32
CacheLevel uint32
GdipCacheEntries [10]byte
GdipCacheChunkSize [8]byte
GdipImageCacheProperties [6]byte
}
func (*DrawGDIPlusCapability) Type() CapsType {
return CAPSTYPE_DRAWGDIPLUS
}
// see https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpbcgr/86507fed-a0ee-4242-b802-237534a8f65e
type BitmapCodec struct {
GUID [16]byte
ID uint8
PropertiesLength uint16 `struc:"little,sizeof=Properties"`
Properties []byte
}
// see https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpbcgr/408b1878-9f6e-4106-8329-1af42219ba6a
type BitmapCodecS struct {
Count uint8 `struc:"sizeof=Array"`
Array []BitmapCodec
}
// see https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpbcgr/17e80f50-d163-49de-a23b-fd6456aa472f
type BitmapCodecsCapability struct {
SupportedBitmapCodecs BitmapCodecS // A variable-length field containing a TS_BITMAPCODECS structure (section 2.2.7.2.10.1).
}
func (*BitmapCodecsCapability) Type() CapsType {
return CAPSETTYPE_BITMAP_CODECS
}
// see https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpbcgr/fc05c385-46c3-42cb-9ed2-c475a3990e0b
type BitmapCacheHostSupportCapability struct {
CacheVersion uint8
Pad1 uint8
Pad2 uint16
}
func (*BitmapCacheHostSupportCapability) Type() CapsType {
return CAPSTYPE_BITMAPCACHE_HOSTSUPPORT
}
// see https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpbcgr/41323437-c753-460e-8108-495a6fdd68a8
type LargePointerCapability struct {
SupportFlags uint16 `struc:"little"`
}
func (*LargePointerCapability) Type() CapsType {
return CAPSETTYPE_LARGE_POINTER
}
// see https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdperp/36a25e21-25e1-4954-aae8-09aaf6715c79
type RemoteProgramsCapability struct {
RailSupportLevel uint32 `struc:"little"`
}
func (*RemoteProgramsCapability) Type() CapsType {
return CAPSTYPE_RAIL
}
// see https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdperp/82ec7a69-f7e3-4294-830d-666178b35d15
type WindowListCapability struct {
WndSupportLevel uint32 `struc:"little"`
NumIconCaches uint8
NumIconCacheEntries uint16 `struc:"little"`
}
func (*WindowListCapability) Type() CapsType {
return CAPSTYPE_WINDOW
}
// see https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpbcgr/9132002f-f133-4a0f-ba2f-2dc48f1e7f93
type DesktopCompositionCapability struct {
CompDeskSupportLevel uint16 `struc:"little"`
}
func (*DesktopCompositionCapability) Type() CapsType {
return CAPSETTYPE_COMPDESK
}
// see https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpbcgr/aa953018-c0a8-4761-bb12-86586c2cd56a
type SurfaceCommandsCapability struct {
CmdFlags uint32 `struc:"little"`
Reserved uint32 `struc:"little"`
}
func (*SurfaceCommandsCapability) Type() CapsType {
return CAPSETTYPE_SURFACE_COMMANDS
}
type FrameAcknowledgeCapability struct {
FrameCount uint32 `struc:"little"`
}
func (*FrameAcknowledgeCapability) Type() CapsType {
return CAPSSETTYPE_FRAME_ACKNOWLEDGE
}
type DrawNineGridCapability struct {
SupportLevel uint32 `struc:"little"`
CacheSize uint16 `struc:"little"`
CacheEntries uint16 `struc:"little"`
}
func (*DrawNineGridCapability) Type() CapsType {
return CAPSTYPE_DRAWNINEGRIDCACHE
}
func readCapability(r io.Reader) (Capability, error) {
capType, err := core.ReadUint16LE(r)
if err != nil {
return nil, err
}
capLen, err := core.ReadUint16LE(r)
if err != nil {
return nil, err
}
if int(capLen)-4 <= 0 {
return nil, errors.New(fmt.Sprintf("Capability length expected %d", capLen))
}
capBytes, err := core.ReadBytes(int(capLen)-4, r)
if err != nil {
return nil, err
}
capReader := bytes.NewReader(capBytes)
var c Capability
glog.Debugf("Capability type 0x%04x", capType)
switch CapsType(capType) {
case CAPSTYPE_GENERAL:
c = &GeneralCapability{}
case CAPSTYPE_BITMAP:
c = &BitmapCapability{}
case CAPSTYPE_ORDER:
c = &OrderCapability{}
case CAPSTYPE_BITMAPCACHE:
c = &BitmapCacheCapability{}
case CAPSTYPE_POINTER:
c = &PointerCapability{}
case CAPSTYPE_INPUT:
c = &InputCapability{}
case CAPSTYPE_BRUSH:
c = &BrushCapability{}
case CAPSTYPE_GLYPHCACHE:
c = &GlyphCapability{}
case CAPSTYPE_OFFSCREENCACHE:
c = &OffscreenBitmapCacheCapability{}
case CAPSTYPE_VIRTUALCHANNEL:
c = &VirtualChannelCapability{}
case CAPSTYPE_SOUND:
c = &SoundCapability{}
case CAPSTYPE_CONTROL:
c = &ControlCapability{}
case CAPSTYPE_ACTIVATION:
c = &WindowActivationCapability{}
case CAPSTYPE_FONT:
c = &FontCapability{}
case CAPSTYPE_COLORCACHE:
c = &ColorCacheCapability{}
case CAPSTYPE_SHARE:
c = &ShareCapability{}
case CAPSETTYPE_MULTIFRAGMENTUPDATE:
c = &MultiFragmentUpdate{}
case CAPSTYPE_DRAWGDIPLUS:
c = &DrawGDIPlusCapability{}
case CAPSETTYPE_BITMAP_CODECS:
c = &BitmapCodecsCapability{}
case CAPSTYPE_BITMAPCACHE_HOSTSUPPORT:
c = &BitmapCacheHostSupportCapability{}
case CAPSETTYPE_LARGE_POINTER:
c = &LargePointerCapability{}
case CAPSTYPE_RAIL:
c = &RemoteProgramsCapability{}
case CAPSTYPE_WINDOW:
c = &WindowListCapability{}
case CAPSETTYPE_COMPDESK:
c = &DesktopCompositionCapability{}
case CAPSETTYPE_SURFACE_COMMANDS:
c = &SurfaceCommandsCapability{}
case CAPSSETTYPE_FRAME_ACKNOWLEDGE:
c = &FrameAcknowledgeCapability{}
default:
err := errors.New(fmt.Sprintf("unsupported Capability type 0x%04x", capType))
glog.Error(err)
return nil, err
}
if err := struc.Unpack(capReader, c); err != nil {
glog.Error("Capability unpack error", err, fmt.Sprintf("0x%04x", capType), hex.EncodeToString(capBytes))
return nil, err
}
glog.Debugf("Capability<%s>: %+v", c.Type(), c)
return c, nil
}

1053
grdp/protocol/pdu/data.go Normal file

File diff suppressed because it is too large Load Diff

560
grdp/protocol/pdu/gdi.go Normal file
View File

@@ -0,0 +1,560 @@
package pdu
/* Binary Raster Operations (ROP2) */
const (
GDI_R2_BLACK = 0x01
GDI_R2_NOTMERGEPEN = 0x02
GDI_R2_MASKNOTPEN = 0x03
GDI_R2_NOTCOPYPEN = 0x04
GDI_R2_MASKPENNOT = 0x05
GDI_R2_NOT = 0x06
GDI_R2_XORPEN = 0x07
GDI_R2_NOTMASKPEN = 0x08
GDI_R2_MASKPEN = 0x09
GDI_R2_NOTXORPEN = 0x0A
GDI_R2_NOP = 0x0B
GDI_R2_MERGENOTPEN = 0x0C
GDI_R2_COPYPEN = 0x0D
GDI_R2_MERGEPENNOT = 0x0E
GDI_R2_MERGEPEN = 0x0F
GDI_R2_WHITE = 0x10
)
/* Ternary Raster Operations (ROP3) */
const (
GDI_BLACKNESS = 0x00000042
GDI_DPSoon = 0x00010289
GDI_DPSona = 0x00020C89
GDI_PSon = 0x000300AA
GDI_SDPona = 0x00040C88
GDI_DPon = 0x000500A9
GDI_PDSxnon = 0x00060865
GDI_PDSaon = 0x000702C5
GDI_SDPnaa = 0x00080F08
GDI_PDSxon = 0x00090245
GDI_DPna = 0x000A0329
GDI_PSDnaon = 0x000B0B2A
GDI_SPna = 0x000C0324
GDI_PDSnaon = 0x000D0B25
GDI_PDSonon = 0x000E08A5
GDI_Pn = 0x000F0001
GDI_PDSona = 0x00100C85
GDI_NOTSRCERASE = 0x001100A6
GDI_SDPxnon = 0x00120868
GDI_SDPaon = 0x001302C8
GDI_DPSxnon = 0x00140869
GDI_DPSaon = 0x001502C9
GDI_PSDPSanaxx = 0x00165CCA
GDI_SSPxDSxaxn = 0x00171D54
GDI_SPxPDxa = 0x00180D59
GDI_SDPSanaxn = 0x00191CC8
GDI_PDSPaox = 0x001A06C5
GDI_SDPSxaxn = 0x001B0768
GDI_PSDPaox = 0x001C06CA
GDI_DSPDxaxn = 0x001D0766
GDI_PDSox = 0x001E01A5
GDI_PDSoan = 0x001F0385
GDI_DPSnaa = 0x00200F09
GDI_SDPxon = 0x00210248
GDI_DSna = 0x00220326
GDI_SPDnaon = 0x00230B24
GDI_SPxDSxa = 0x00240D55
GDI_PDSPanaxn = 0x00251CC5
GDI_SDPSaox = 0x002606C8
GDI_SDPSxnox = 0x00271868
GDI_DPSxa = 0x00280369
GDI_PSDPSaoxxn = 0x002916CA
GDI_DPSana = 0x002A0CC9
GDI_SSPxPDxaxn = 0x002B1D58
GDI_SPDSoax = 0x002C0784
GDI_PSDnox = 0x002D060A
GDI_PSDPxox = 0x002E064A
GDI_PSDnoan = 0x002F0E2A
GDI_PSna = 0x0030032A
GDI_SDPnaon = 0x00310B28
GDI_SDPSoox = 0x00320688
GDI_NOTSRCCOPY = 0x00330008
GDI_SPDSaox = 0x003406C4
GDI_SPDSxnox = 0x00351864
GDI_SDPox = 0x003601A8
GDI_SDPoan = 0x00370388
GDI_PSDPoax = 0x0038078A
GDI_SPDnox = 0x00390604
GDI_SPDSxox = 0x003A0644
GDI_SPDnoan = 0x003B0E24
GDI_PSx = 0x003C004A
GDI_SPDSonox = 0x003D18A4
GDI_SPDSnaox = 0x003E1B24
GDI_PSan = 0x003F00EA
GDI_PSDnaa = 0x00400F0A
GDI_DPSxon = 0x00410249
GDI_SDxPDxa = 0x00420D5D
GDI_SPDSanaxn = 0x00431CC4
GDI_SRCERASE = 0x00440328
GDI_DPSnaon = 0x00450B29
GDI_DSPDaox = 0x004606C6
GDI_PSDPxaxn = 0x0047076A
GDI_SDPxa = 0x00480368
GDI_PDSPDaoxxn = 0x004916C5
GDI_DPSDoax = 0x004A0789
GDI_PDSnox = 0x004B0605
GDI_SDPana = 0x004C0CC8
GDI_SSPxDSxoxn = 0x004D1954
GDI_PDSPxox = 0x004E0645
GDI_PDSnoan = 0x004F0E25
GDI_PDna = 0x00500325
GDI_DSPnaon = 0x00510B26
GDI_DPSDaox = 0x005206C9
GDI_SPDSxaxn = 0x00530764
GDI_DPSonon = 0x005408A9
GDI_DSTINVERT = 0x00550009
GDI_DPSox = 0x005601A9
GDI_DPSoan = 0x00570389
GDI_PDSPoax = 0x00580785
GDI_DPSnox = 0x00590609
GDI_PATINVERT = 0x005A0049
GDI_DPSDonox = 0x005B18A9
GDI_DPSDxox = 0x005C0649
GDI_DPSnoan = 0x005D0E29
GDI_DPSDnaox = 0x005E1B29
GDI_DPan = 0x005F00E9
GDI_PDSxa = 0x00600365
GDI_DSPDSaoxxn = 0x006116C6
GDI_DSPDoax = 0x00620786
GDI_SDPnox = 0x00630608
GDI_SDPSoax = 0x00640788
GDI_DSPnox = 0x00650606
GDI_SRCINVERT = 0x00660046
GDI_SDPSonox = 0x006718A8
GDI_DSPDSonoxxn = 0x006858A6
GDI_PDSxxn = 0x00690145
GDI_DPSax = 0x006A01E9
GDI_PSDPSoaxxn = 0x006B178A
GDI_SDPax = 0x006C01E8
GDI_PDSPDoaxxn = 0x006D1785
GDI_SDPSnoax = 0x006E1E28
GDI_PDSxnan = 0x006F0C65
GDI_PDSana = 0x00700CC5
GDI_SSDxPDxaxn = 0x00711D5C
GDI_SDPSxox = 0x00720648
GDI_SDPnoan = 0x00730E28
GDI_DSPDxox = 0x00740646
GDI_DSPnoan = 0x00750E26
GDI_SDPSnaox = 0x00761B28
GDI_DSan = 0x007700E6
GDI_PDSax = 0x007801E5
GDI_DSPDSoaxxn = 0x00791786
GDI_DPSDnoax = 0x007A1E29
GDI_SDPxnan = 0x007B0C68
GDI_SPDSnoax = 0x007C1E24
GDI_DPSxnan = 0x007D0C69
GDI_SPxDSxo = 0x007E0955
GDI_DPSaan = 0x007F03C9
GDI_DPSaa = 0x008003E9
GDI_SPxDSxon = 0x00810975
GDI_DPSxna = 0x00820C49
GDI_SPDSnoaxn = 0x00831E04
GDI_SDPxna = 0x00840C48
GDI_PDSPnoaxn = 0x00851E05
GDI_DSPDSoaxx = 0x008617A6
GDI_PDSaxn = 0x008701C5
GDI_SRCAND = 0x008800C6
GDI_SDPSnaoxn = 0x00891B08
GDI_DSPnoa = 0x008A0E06
GDI_DSPDxoxn = 0x008B0666
GDI_SDPnoa = 0x008C0E08
GDI_SDPSxoxn = 0x008D0668
GDI_SSDxPDxax = 0x008E1D7C
GDI_PDSanan = 0x008F0CE5
GDI_PDSxna = 0x00900C45
GDI_SDPSnoaxn = 0x00911E08
GDI_DPSDPoaxx = 0x009217A9
GDI_SPDaxn = 0x009301C4
GDI_PSDPSoaxx = 0x009417AA
GDI_DPSaxn = 0x009501C9
GDI_DPSxx = 0x00960169
GDI_PSDPSonoxx = 0x0097588A
GDI_SDPSonoxn = 0x00981888
GDI_DSxn = 0x00990066
GDI_DPSnax = 0x009A0709
GDI_SDPSoaxn = 0x009B07A8
GDI_SPDnax = 0x009C0704
GDI_DSPDoaxn = 0x009D07A6
GDI_DSPDSaoxx = 0x009E16E6
GDI_PDSxan = 0x009F0345
GDI_DPa = 0x00A000C9
GDI_PDSPnaoxn = 0x00A11B05
GDI_DPSnoa = 0x00A20E09
GDI_DPSDxoxn = 0x00A30669
GDI_PDSPonoxn = 0x00A41885
GDI_PDxn = 0x00A50065
GDI_DSPnax = 0x00A60706
GDI_PDSPoaxn = 0x00A707A5
GDI_DPSoa = 0x00A803A9
GDI_DPSoxn = 0x00A90189
GDI_DSTCOPY = 0x00AA0029
GDI_DPSono = 0x00AB0889
GDI_SPDSxax = 0x00AC0744
GDI_DPSDaoxn = 0x00AD06E9
GDI_DSPnao = 0x00AE0B06
GDI_DPno = 0x00AF0229
GDI_PDSnoa = 0x00B00E05
GDI_PDSPxoxn = 0x00B10665
GDI_SSPxDSxox = 0x00B21974
GDI_SDPanan = 0x00B30CE8
GDI_PSDnax = 0x00B4070A
GDI_DPSDoaxn = 0x00B507A9
GDI_DPSDPaoxx = 0x00B616E9
GDI_SDPxan = 0x00B70348
GDI_PSDPxax = 0x00B8074A
GDI_DSPDaoxn = 0x00B906E6
GDI_DPSnao = 0x00BA0B09
GDI_MERGEPAINT = 0x00BB0226
GDI_SPDSanax = 0x00BC1CE4
GDI_SDxPDxan = 0x00BD0D7D
GDI_DPSxo = 0x00BE0269
GDI_DPSano = 0x00BF08C9
GDI_MERGECOPY = 0x00C000CA
GDI_SPDSnaoxn = 0x00C11B04
GDI_SPDSonoxn = 0x00C21884
GDI_PSxn = 0x00C3006A
GDI_SPDnoa = 0x00C40E04
GDI_SPDSxoxn = 0x00C50664
GDI_SDPnax = 0x00C60708
GDI_PSDPoaxn = 0x00C707AA
GDI_SDPoa = 0x00C803A8
GDI_SPDoxn = 0x00C90184
GDI_DPSDxax = 0x00CA0749
GDI_SPDSaoxn = 0x00CB06E4
GDI_SRCCOPY = 0x00CC0020
GDI_SDPono = 0x00CD0888
GDI_SDPnao = 0x00CE0B08
GDI_SPno = 0x00CF0224
GDI_PSDnoa = 0x00D00E0A
GDI_PSDPxoxn = 0x00D1066A
GDI_PDSnax = 0x00D20705
GDI_SPDSoaxn = 0x00D307A4
GDI_SSPxPDxax = 0x00D41D78
GDI_DPSanan = 0x00D50CE9
GDI_PSDPSaoxx = 0x00D616EA
GDI_DPSxan = 0x00D70349
GDI_PDSPxax = 0x00D80745
GDI_SDPSaoxn = 0x00D906E8
GDI_DPSDanax = 0x00DA1CE9
GDI_SPxDSxan = 0x00DB0D75
GDI_SPDnao = 0x00DC0B04
GDI_SDno = 0x00DD0228
GDI_SDPxo = 0x00DE0268
GDI_SDPano = 0x00DF08C8
GDI_PDSoa = 0x00E003A5
GDI_PDSoxn = 0x00E10185
GDI_DSPDxax = 0x00E20746
GDI_PSDPaoxn = 0x00E306EA
GDI_SDPSxax = 0x00E40748
GDI_PDSPaoxn = 0x00E506E5
GDI_SDPSanax = 0x00E61CE8
GDI_SPxPDxan = 0x00E70D79
GDI_SSPxDSxax = 0x00E81D74
GDI_DSPDSanaxxn = 0x00E95CE6
GDI_DPSao = 0x00EA02E9
GDI_DPSxno = 0x00EB0849
GDI_SDPao = 0x00EC02E8
GDI_SDPxno = 0x00ED0848
GDI_SRCPAINT = 0x00EE0086
GDI_SDPnoo = 0x00EF0A08
GDI_PATCOPY = 0x00F00021
GDI_PDSono = 0x00F10885
GDI_PDSnao = 0x00F20B05
GDI_PSno = 0x00F3022A
GDI_PSDnao = 0x00F40B0A
GDI_PDno = 0x00F50225
GDI_PDSxo = 0x00F60265
GDI_PDSano = 0x00F708C5
GDI_PDSao = 0x00F802E5
GDI_PDSxno = 0x00F90845
GDI_DPo = 0x00FA0089
GDI_PATPAINT = 0x00FB0A09
GDI_PSo = 0x00FC008A
GDI_PSDnoo = 0x00FD0A0A
GDI_DPSoo = 0x00FE02A9
GDI_WHITENESS = 0x00FF0062
GDI_GLYPH_ORDER = 0xFFFFFFFF
)
var Rop3CodeTable = map[int]string{
GDI_BLACKNESS: "0",
GDI_DPSoon: "DPSoon",
GDI_DPSona: "DPSona",
GDI_PSon: "PSon",
GDI_SDPona: "SDPona",
GDI_DPon: "DPon",
GDI_PDSxnon: "PDSxnon",
GDI_PDSaon: "PDSaon",
GDI_SDPnaa: "SDPnaa",
GDI_PDSxon: "PDSxon",
GDI_DPna: "DPna",
GDI_PSDnaon: "PSDnaon",
GDI_SPna: "SPna",
GDI_PDSnaon: "PDSnaon",
GDI_PDSonon: "PDSonon",
GDI_Pn: "Pn",
GDI_PDSona: "PDSona",
GDI_NOTSRCERASE: "DSon",
GDI_SDPxnon: "SDPxnon",
GDI_SDPaon: "SDPaon",
GDI_DPSxnon: "DPSxnon",
GDI_DPSaon: "DPSaon",
GDI_PSDPSanaxx: "PSDPSanaxx",
GDI_SSPxDSxaxn: "SSPxDSxaxn",
GDI_SPxPDxa: "SPxPDxa",
GDI_SDPSanaxn: "SDPSanaxn",
GDI_PDSPaox: "PDSPaox",
GDI_SDPSxaxn: "SDPSxaxn",
GDI_PSDPaox: "PSDPaox",
GDI_DSPDxaxn: "DSPDxaxn",
GDI_PDSox: "PDSox",
GDI_PDSoan: "PDSoan",
GDI_DPSnaa: "DPSnaa",
GDI_SDPxon: "SDPxon",
GDI_DSna: "DSna",
GDI_SPDnaon: "SPDnaon",
GDI_SPxDSxa: "SPxDSxa",
GDI_PDSPanaxn: "PDSPanaxn",
GDI_SDPSaox: "SDPSaox",
GDI_SDPSxnox: "SDPSxnox",
GDI_DPSxa: "DPSxa",
GDI_PSDPSaoxxn: "PSDPSaoxxn",
GDI_DPSana: "DPSana",
GDI_SSPxPDxaxn: "SSPxPDxaxn",
GDI_SPDSoax: "SPDSoax",
GDI_PSDnox: "PSDnox",
GDI_PSDPxox: "PSDPxox",
GDI_PSDnoan: "PSDnoan",
GDI_PSna: "PSna",
GDI_SDPnaon: "SDPnaon",
GDI_SDPSoox: "SDPSoox",
GDI_NOTSRCCOPY: "Sn",
GDI_SPDSaox: "SPDSaox",
GDI_SPDSxnox: "SPDSxnox",
GDI_SDPox: "SDPox",
GDI_SDPoan: "SDPoan",
GDI_PSDPoax: "PSDPoax",
GDI_SPDnox: "SPDnox",
GDI_SPDSxox: "SPDSxox",
GDI_SPDnoan: "SPDnoan",
GDI_PSx: "PSx",
GDI_SPDSonox: "SPDSonox",
GDI_SPDSnaox: "SPDSnaox",
GDI_PSan: "PSan",
GDI_PSDnaa: "PSDnaa",
GDI_DPSxon: "DPSxon",
GDI_SDxPDxa: "SDxPDxa",
GDI_SPDSanaxn: "SPDSanaxn",
GDI_SRCERASE: "SDna",
GDI_DPSnaon: "DPSnaon",
GDI_DSPDaox: "DSPDaox",
GDI_PSDPxaxn: "PSDPxaxn",
GDI_SDPxa: "SDPxa",
GDI_PDSPDaoxxn: "PDSPDaoxxn",
GDI_DPSDoax: "DPSDoax",
GDI_PDSnox: "PDSnox",
GDI_SDPana: "SDPana",
GDI_SSPxDSxoxn: "SSPxDSxoxn",
GDI_PDSPxox: "PDSPxox",
GDI_PDSnoan: "PDSnoan",
GDI_PDna: "PDna",
GDI_DSPnaon: "DSPnaon",
GDI_DPSDaox: "DPSDaox",
GDI_SPDSxaxn: "SPDSxaxn",
GDI_DPSonon: "DPSonon",
GDI_DSTINVERT: "Dn",
GDI_DPSox: "DPSox",
GDI_DPSoan: "DPSoan",
GDI_PDSPoax: "PDSPoax",
GDI_DPSnox: "DPSnox",
GDI_PATINVERT: "DPx",
GDI_DPSDonox: "DPSDonox",
GDI_DPSDxox: "DPSDxox",
GDI_DPSnoan: "DPSnoan",
GDI_DPSDnaox: "DPSDnaox",
GDI_DPan: "DPan",
GDI_PDSxa: "PDSxa",
GDI_DSPDSaoxxn: "DSPDSaoxxn",
GDI_DSPDoax: "DSPDoax",
GDI_SDPnox: "SDPnox",
GDI_SDPSoax: "SDPSoax",
GDI_DSPnox: "DSPnox",
GDI_SRCINVERT: "DSx",
GDI_SDPSonox: "SDPSonox",
GDI_DSPDSonoxxn: "DSPDSonoxxn",
GDI_PDSxxn: "PDSxxn",
GDI_DPSax: "DPSax",
GDI_PSDPSoaxxn: "PSDPSoaxxn",
GDI_SDPax: "SDPax",
GDI_PDSPDoaxxn: "PDSPDoaxxn",
GDI_SDPSnoax: "SDPSnoax",
GDI_PDSxnan: "PDSxnan",
GDI_PDSana: "PDSana",
GDI_SSDxPDxaxn: "SSDxPDxaxn",
GDI_SDPSxox: "SDPSxox",
GDI_SDPnoan: "SDPnoan",
GDI_DSPDxox: "DSPDxox",
GDI_DSPnoan: "DSPnoan",
GDI_SDPSnaox: "SDPSnaox",
GDI_DSan: "DSan",
GDI_PDSax: "PDSax",
GDI_DSPDSoaxxn: "DSPDSoaxxn",
GDI_DPSDnoax: "DPSDnoax",
GDI_SDPxnan: "SDPxnan",
GDI_SPDSnoax: "SPDSnoax",
GDI_DPSxnan: "DPSxnan",
GDI_SPxDSxo: "SPxDSxo",
GDI_DPSaan: "DPSaan",
GDI_DPSaa: "DPSaa",
GDI_SPxDSxon: "SPxDSxon",
GDI_DPSxna: "DPSxna",
GDI_SPDSnoaxn: "SPDSnoaxn",
GDI_SDPxna: "SDPxna",
GDI_PDSPnoaxn: "PDSPnoaxn",
GDI_DSPDSoaxx: "DSPDSoaxx",
GDI_PDSaxn: "PDSaxn",
GDI_SRCAND: "DSa",
GDI_SDPSnaoxn: "SDPSnaoxn",
GDI_DSPnoa: "DSPnoa",
GDI_DSPDxoxn: "DSPDxoxn",
GDI_SDPnoa: "SDPnoa",
GDI_SDPSxoxn: "SDPSxoxn",
GDI_SSDxPDxax: "SSDxPDxax",
GDI_PDSanan: "PDSanan",
GDI_PDSxna: "PDSxna",
GDI_SDPSnoaxn: "SDPSnoaxn",
GDI_DPSDPoaxx: "DPSDPoaxx",
GDI_SPDaxn: "SPDaxn",
GDI_PSDPSoaxx: "PSDPSoaxx",
GDI_DPSaxn: "DPSaxn",
GDI_DPSxx: "DPSxx",
GDI_PSDPSonoxx: "PSDPSonoxx",
GDI_SDPSonoxn: "SDPSonoxn",
GDI_DSxn: "DSxn",
GDI_DPSnax: "DPSnax",
GDI_SDPSoaxn: "SDPSoaxn",
GDI_SPDnax: "SPDnax",
GDI_DSPDoaxn: "DSPDoaxn",
GDI_DSPDSaoxx: "DSPDSaoxx",
GDI_PDSxan: "PDSxan",
GDI_DPa: "DPa",
GDI_PDSPnaoxn: "PDSPnaoxn",
GDI_DPSnoa: "DPSnoa",
GDI_DPSDxoxn: "DPSDxoxn",
GDI_PDSPonoxn: "PDSPonoxn",
GDI_PDxn: "PDxn",
GDI_DSPnax: "DSPnax",
GDI_PDSPoaxn: "PDSPoaxn",
GDI_DPSoa: "DPSoa",
GDI_DPSoxn: "DPSoxn",
GDI_DSTCOPY: "D",
GDI_DPSono: "DPSono",
GDI_SPDSxax: "SPDSxax",
GDI_DPSDaoxn: "DPSDaoxn",
GDI_DSPnao: "DSPnao",
GDI_DPno: "DPno",
GDI_PDSnoa: "PDSnoa",
GDI_PDSPxoxn: "PDSPxoxn",
GDI_SSPxDSxox: "SSPxDSxox",
GDI_SDPanan: "SDPanan",
GDI_PSDnax: "PSDnax",
GDI_DPSDoaxn: "DPSDoaxn",
GDI_DPSDPaoxx: "DPSDPaoxx",
GDI_SDPxan: "SDPxan",
GDI_PSDPxax: "PSDPxax",
GDI_DSPDaoxn: "DSPDaoxn",
GDI_DPSnao: "DPSnao",
GDI_MERGEPAINT: "DSno",
GDI_SPDSanax: "SPDSanax",
GDI_SDxPDxan: "SDxPDxan",
GDI_DPSxo: "DPSxo",
GDI_DPSano: "DPSano",
GDI_MERGECOPY: "PSa",
GDI_SPDSnaoxn: "SPDSnaoxn",
GDI_SPDSonoxn: "SPDSonoxn",
GDI_PSxn: "PSxn",
GDI_SPDnoa: "SPDnoa",
GDI_SPDSxoxn: "SPDSxoxn",
GDI_SDPnax: "SDPnax",
GDI_PSDPoaxn: "PSDPoaxn",
GDI_SDPoa: "SDPoa",
GDI_SPDoxn: "SPDoxn",
GDI_DPSDxax: "DPSDxax",
GDI_SPDSaoxn: "SPDSaoxn",
GDI_SRCCOPY: "S",
GDI_SDPono: "SDPono",
GDI_SDPnao: "SDPnao",
GDI_SPno: "SPno",
GDI_PSDnoa: "PSDnoa",
GDI_PSDPxoxn: "PSDPxoxn",
GDI_PDSnax: "PDSnax",
GDI_SPDSoaxn: "SPDSoaxn",
GDI_SSPxPDxax: "SSPxPDxax",
GDI_DPSanan: "DPSanan",
GDI_PSDPSaoxx: "PSDPSaoxx",
GDI_DPSxan: "DPSxan",
GDI_PDSPxax: "PDSPxax",
GDI_SDPSaoxn: "SDPSaoxn",
GDI_DPSDanax: "DPSDanax",
GDI_SPxDSxan: "SPxDSxan",
GDI_SPDnao: "SPDnao",
GDI_SDno: "SDno",
GDI_SDPxo: "SDPxo",
GDI_SDPano: "SDPano",
GDI_PDSoa: "PDSoa",
GDI_PDSoxn: "PDSoxn",
GDI_DSPDxax: "DSPDxax",
GDI_PSDPaoxn: "PSDPaoxn",
GDI_SDPSxax: "SDPSxax",
GDI_PDSPaoxn: "PDSPaoxn",
GDI_SDPSanax: "SDPSanax",
GDI_SPxPDxan: "SPxPDxan",
GDI_SSPxDSxax: "SSPxDSxax",
GDI_DSPDSanaxxn: "DSPDSanaxxn",
GDI_DPSao: "DPSao",
GDI_DPSxno: "DPSxno",
GDI_SDPao: "SDPao",
GDI_SDPxno: "SDPxno",
GDI_SRCPAINT: "DSo",
GDI_SDPnoo: "SDPnoo",
GDI_PATCOPY: "P",
GDI_PDSono: "PDSono",
GDI_PDSnao: "PDSnao",
GDI_PSno: "PSno",
GDI_PSDnao: "PSDnao",
GDI_PDno: "PDno",
GDI_PDSxo: "PDSxo",
GDI_PDSano: "PDSano",
GDI_PDSao: "PDSao",
GDI_PDSxno: "PDSxno",
GDI_DPo: "DPo",
GDI_PATPAINT: "DPSnoo",
GDI_PSo: "PSo",
GDI_PSDnoo: "PSDnoo",
GDI_DPSoo: "DPSoo",
GDI_WHITENESS: "1",
}
var rop2Table = [16]int{
GDI_R2_BLACK,
GDI_R2_NOTMERGEPEN,
GDI_R2_MASKNOTPEN,
GDI_R2_NOTCOPYPEN,
GDI_R2_MASKPENNOT,
GDI_R2_NOT,
GDI_R2_XORPEN,
GDI_R2_NOTMASKPEN,
GDI_R2_MASKPEN,
GDI_R2_NOTXORPEN,
GDI_R2_NOP,
GDI_R2_MERGENOTPEN,
GDI_R2_COPYPEN,
GDI_R2_MERGEPENNOT,
GDI_R2_MERGEPEN,
GDI_R2_WHITE,
}

1237
grdp/protocol/pdu/orders.go Normal file

File diff suppressed because it is too large Load Diff

459
grdp/protocol/pdu/pdu.go Normal file
View File

@@ -0,0 +1,459 @@
package pdu
import (
"bytes"
"encoding/hex"
"ShotRDP/grdp/core"
"ShotRDP/grdp/emission"
"ShotRDP/grdp/glog"
"ShotRDP/grdp/protocol/t125/gcc"
)
type PDULayer struct {
emission.Emitter
transport core.Transport
sharedId uint32
userId uint16
channelId uint16
serverCapabilities map[CapsType]Capability
clientCapabilities map[CapsType]Capability
fastPathSender core.FastPathSender
demandActivePDU *DemandActivePDU
}
func NewPDULayer(t core.Transport) *PDULayer {
p := &PDULayer{
Emitter: *emission.NewEmitter(),
transport: t,
sharedId: 0x103EA,
serverCapabilities: map[CapsType]Capability{
CAPSTYPE_GENERAL: &GeneralCapability{
ProtocolVersion: 0x0200,
},
CAPSTYPE_BITMAP: &BitmapCapability{
Receive1BitPerPixel: 0x0001,
Receive4BitsPerPixel: 0x0001,
Receive8BitsPerPixel: 0x0001,
BitmapCompressionFlag: 0x0001,
MultipleRectangleSupport: 0x0001,
},
CAPSTYPE_ORDER: &OrderCapability{
DesktopSaveXGranularity: 1,
DesktopSaveYGranularity: 20,
MaximumOrderLevel: 1,
OrderFlags: NEGOTIATEORDERSUPPORT,
DesktopSaveSize: 480 * 480,
},
CAPSTYPE_POINTER: &PointerCapability{ColorPointerCacheSize: 20},
CAPSTYPE_INPUT: &InputCapability{},
CAPSTYPE_VIRTUALCHANNEL: &VirtualChannelCapability{},
CAPSTYPE_FONT: &FontCapability{SupportFlags: 0x0001},
CAPSTYPE_COLORCACHE: &ColorCacheCapability{CacheSize: 0x0006},
CAPSTYPE_SHARE: &ShareCapability{},
},
clientCapabilities: map[CapsType]Capability{
CAPSTYPE_GENERAL: &GeneralCapability{
ProtocolVersion: 0x0200,
},
CAPSTYPE_BITMAP: &BitmapCapability{
Receive1BitPerPixel: 0x0001,
Receive4BitsPerPixel: 0x0001,
Receive8BitsPerPixel: 0x0001,
BitmapCompressionFlag: 0x0001,
MultipleRectangleSupport: 0x0001,
},
CAPSTYPE_ORDER: &OrderCapability{
DesktopSaveXGranularity: 1,
DesktopSaveYGranularity: 20,
MaximumOrderLevel: 1,
OrderFlags: NEGOTIATEORDERSUPPORT,
DesktopSaveSize: 480 * 480,
TextANSICodePage: 0x4e4,
},
CAPSTYPE_CONTROL: &ControlCapability{0, 0, 2, 2},
CAPSTYPE_ACTIVATION: &WindowActivationCapability{},
CAPSTYPE_POINTER: &PointerCapability{1, 20, 20},
CAPSTYPE_SHARE: &ShareCapability{},
CAPSTYPE_COLORCACHE: &ColorCacheCapability{6, 0},
CAPSTYPE_SOUND: &SoundCapability{0x0001, 0},
CAPSTYPE_INPUT: &InputCapability{},
CAPSTYPE_FONT: &FontCapability{0x0001, 0},
CAPSTYPE_BRUSH: &BrushCapability{BRUSH_COLOR_8x8},
CAPSTYPE_GLYPHCACHE: &GlyphCapability{},
CAPSETTYPE_BITMAP_CODECS: &BitmapCodecsCapability{},
CAPSTYPE_BITMAPCACHE_REV2: &BitmapCache2Capability{
BitmapCachePersist: 2,
CachesNum: 5,
BmpC0Cells: 0x258,
BmpC1Cells: 0x258,
BmpC2Cells: 0x800,
BmpC3Cells: 0x1000,
BmpC4Cells: 0x800,
},
CAPSTYPE_VIRTUALCHANNEL: &VirtualChannelCapability{0, 1600},
CAPSETTYPE_MULTIFRAGMENTUPDATE: &MultiFragmentUpdate{65535},
CAPSTYPE_RAIL: &RemoteProgramsCapability{
RailSupportLevel: RAIL_LEVEL_SUPPORTED |
RAIL_LEVEL_SHELL_INTEGRATION_SUPPORTED |
RAIL_LEVEL_LANGUAGE_IME_SYNC_SUPPORTED |
RAIL_LEVEL_SERVER_TO_CLIENT_IME_SYNC_SUPPORTED |
RAIL_LEVEL_HIDE_MINIMIZED_APPS_SUPPORTED |
RAIL_LEVEL_WINDOW_CLOAKING_SUPPORTED |
RAIL_LEVEL_HANDSHAKE_EX_SUPPORTED |
RAIL_LEVEL_DOCKED_LANGBAR_SUPPORTED,
},
CAPSETTYPE_LARGE_POINTER: &LargePointerCapability{1},
CAPSETTYPE_SURFACE_COMMANDS: &SurfaceCommandsCapability{
CmdFlags: SURFCMDS_SET_SURFACE_BITS | SURFCMDS_STREAM_SURFACE_BITS | SURFCMDS_FRAME_MARKER,
},
CAPSSETTYPE_FRAME_ACKNOWLEDGE: &FrameAcknowledgeCapability{2},
},
}
t.On("close", func() {
p.Emit("close")
}).On("error", func(err error) {
p.Emit("error", err)
})
return p
}
func (p *PDULayer) sendPDU(message PDUMessage) {
pdu := NewPDU(p.userId, message)
p.transport.Write(pdu.serialize())
}
func (p *PDULayer) sendDataPDU(message DataPDUData) {
dataPdu := NewDataPDU(message, p.sharedId)
p.sendPDU(dataPdu)
}
func (p *PDULayer) SetFastPathSender(f core.FastPathSender) {
p.fastPathSender = f
}
type Client struct {
*PDULayer
clientCoreData *gcc.ClientCoreData
buff *bytes.Buffer
}
func NewClient(t core.Transport) *Client {
c := &Client{
PDULayer: NewPDULayer(t),
buff: &bytes.Buffer{},
}
c.transport.Once("connect", c.connect)
return c
}
func (c *Client) connect(data *gcc.ClientCoreData, userId uint16, channelId uint16) {
glog.Debug("pdu connect:", userId, ",", channelId)
c.clientCoreData = data
c.userId = userId
c.channelId = channelId
c.transport.Once("data", c.recvDemandActivePDU)
}
func (c *Client) recvDemandActivePDU(s []byte) {
glog.Trace("PDU recvDemandActivePDU", hex.EncodeToString(s))
r := bytes.NewReader(s)
pdu, err := readPDU(r)
if err != nil {
glog.Error(err)
return
}
if pdu.ShareCtrlHeader.PDUType != PDUTYPE_DEMANDACTIVEPDU {
glog.Info("PDU ignore message during connection sequence, type is", pdu.ShareCtrlHeader.PDUType)
c.transport.Once("data", c.recvDemandActivePDU)
return
}
c.sharedId = pdu.Message.(*DemandActivePDU).SharedId
c.demandActivePDU = pdu.Message.(*DemandActivePDU)
for _, caps := range c.demandActivePDU.CapabilitySets {
glog.Debugf("serverCapabilities<%s>: %+v", caps.Type(), caps)
c.serverCapabilities[caps.Type()] = caps
}
c.sendConfirmActivePDU()
c.sendClientFinalizeSynchronizePDU()
c.transport.Once("data", c.recvServerSynchronizePDU)
}
func (c *Client) sendConfirmActivePDU() {
glog.Debug("PDU start sendConfirmActivePDU")
pdu := NewConfirmActivePDU()
generalCapa := c.clientCapabilities[CAPSTYPE_GENERAL].(*GeneralCapability)
generalCapa.OSMajorType = OSMAJORTYPE_WINDOWS
generalCapa.OSMinorType = OSMINORTYPE_WINDOWS_NT
generalCapa.ExtraFlags = LONG_CREDENTIALS_SUPPORTED | NO_BITMAP_COMPRESSION_HDR |
FASTPATH_OUTPUT_SUPPORTED | AUTORECONNECT_SUPPORTED
generalCapa.RefreshRectSupport = 0
generalCapa.SuppressOutputSupport = 0
bitmapCapa := c.clientCapabilities[CAPSTYPE_BITMAP].(*BitmapCapability)
bitmapCapa.PreferredBitsPerPixel = c.clientCoreData.HighColorDepth
bitmapCapa.DesktopWidth = c.clientCoreData.DesktopWidth
bitmapCapa.DesktopHeight = c.clientCoreData.DesktopHeight
bitmapCapa.DesktopResizeFlag = 0x0001
orderCapa := c.clientCapabilities[CAPSTYPE_ORDER].(*OrderCapability)
orderCapa.OrderFlags = NEGOTIATEORDERSUPPORT | ZEROBOUNDSDELTASSUPPORT | COLORINDEXSUPPORT | ORDERFLAGS_EXTRA_FLAGS
orderCapa.OrderSupportExFlags |= ORDERFLAGS_EX_ALTSEC_FRAME_MARKER_SUPPORT
orderCapa.OrderSupport[TS_NEG_DSTBLT_INDEX] = 1
orderCapa.OrderSupport[TS_NEG_PATBLT_INDEX] = 1
orderCapa.OrderSupport[TS_NEG_SCRBLT_INDEX] = 1
//orderCapa.OrderSupport[TS_NEG_LINETO_INDEX] = 1
//orderCapa.OrderSupport[TS_NEG_MEMBLT_INDEX] = 1
//orderCapa.OrderSupport[TS_NEG_MEM3BLT_INDEX] = 1
//orderCapa.OrderSupport[TS_NEG_POLYLINE_INDEX] = 1
/*orderCapa.OrderSupport[TS_NEG_MULTIOPAQUERECT_INDEX] = 1
orderCapa.OrderSupport[TS_NEG_GLYPH_INDEX_INDEX] = 1
//orderCapa.OrderSupport[TS_NEG_DRAWNINEGRID_INDEX] = 1
orderCapa.OrderSupport[TS_NEG_SAVEBITMAP_INDEX] = 1
orderCapa.OrderSupport[TS_NEG_POLYGON_SC_INDEX] = 1
orderCapa.OrderSupport[TS_NEG_POLYGON_CB_INDEX] = 1
orderCapa.OrderSupport[TS_NEG_ELLIPSE_SC_INDEX] = 1
orderCapa.OrderSupport[TS_NEG_ELLIPSE_CB_INDEX] = 1*/
orderCapa.OrderSupport[TS_NEG_FAST_GLYPH_INDEX] = 1
inputCapa := c.clientCapabilities[CAPSTYPE_INPUT].(*InputCapability)
inputCapa.Flags = INPUT_FLAG_SCANCODES | INPUT_FLAG_MOUSEX | INPUT_FLAG_UNICODE
inputCapa.KeyboardLayout = c.clientCoreData.KbdLayout
inputCapa.KeyboardType = c.clientCoreData.KeyboardType
inputCapa.KeyboardSubType = c.clientCoreData.KeyboardSubType
inputCapa.KeyboardFunctionKey = c.clientCoreData.KeyboardFnKeys
inputCapa.ImeFileName = c.clientCoreData.ImeFileName
glyphCapa := c.clientCapabilities[CAPSTYPE_GLYPHCACHE].(*GlyphCapability)
/*glyphCapa.GlyphCache[0] = cacheEntry{254, 4}
glyphCapa.GlyphCache[1] = cacheEntry{254, 4}
glyphCapa.GlyphCache[2] = cacheEntry{254, 8}
glyphCapa.GlyphCache[3] = cacheEntry{254, 8}
glyphCapa.GlyphCache[4] = cacheEntry{254, 16}
glyphCapa.GlyphCache[5] = cacheEntry{254, 32}
glyphCapa.GlyphCache[6] = cacheEntry{254, 64}
glyphCapa.GlyphCache[7] = cacheEntry{254, 128}
glyphCapa.GlyphCache[8] = cacheEntry{254, 256}
glyphCapa.GlyphCache[9] = cacheEntry{64, 2048}
glyphCapa.FragCache = 0x01000100*/
glyphCapa.SupportLevel = GLYPH_SUPPORT_NONE
pdu.SharedId = c.sharedId
for _, v := range c.clientCapabilities {
glog.Debugf("clientCapabilities<%s>: %+v", v.Type(), v)
pdu.CapabilitySets = append(pdu.CapabilitySets, v)
}
pdu.NumberCapabilities = uint16(len(pdu.CapabilitySets))
pdu.LengthSourceDescriptor = c.demandActivePDU.LengthSourceDescriptor
pdu.SourceDescriptor = c.demandActivePDU.SourceDescriptor
pdu.LengthCombinedCapabilities = c.demandActivePDU.LengthCombinedCapabilities
c.sendPDU(pdu)
}
func (c *Client) sendClientFinalizeSynchronizePDU() {
glog.Debug("PDU start sendClientFinalizeSynchronizePDU")
c.sendDataPDU(NewSynchronizeDataPDU(c.channelId))
c.sendDataPDU(&ControlDataPDU{Action: CTRLACTION_COOPERATE})
c.sendDataPDU(&ControlDataPDU{Action: CTRLACTION_REQUEST_CONTROL})
//c.sendDataPDU(&PersistKeyPDU{BBitMask: 0x03})
c.sendDataPDU(&FontListDataPDU{ListFlags: 0x0003, EntrySize: 0x0032})
}
func (c *Client) recvServerSynchronizePDU(s []byte) {
glog.Debug("PDU recvServerSynchronizePDU")
r := bytes.NewReader(s)
pdu, err := readPDU(r)
if err != nil {
glog.Error(err)
return
}
dataPdu, ok := pdu.Message.(*DataPDU)
if !ok || dataPdu.Header.PDUType2 != PDUTYPE2_SYNCHRONIZE {
if ok {
glog.Error("recvServerSynchronizePDU ignore datapdu type2", dataPdu.Header.PDUType2)
} else {
glog.Error("recvServerSynchronizePDU ignore message type", pdu.ShareCtrlHeader.PDUType)
}
glog.Infof("%+v", dataPdu)
c.transport.Once("data", c.recvServerSynchronizePDU)
return
}
c.transport.Once("data", c.recvServerControlCooperatePDU)
}
func (c *Client) recvServerControlCooperatePDU(s []byte) {
glog.Debug("PDU recvServerControlCooperatePDU")
r := bytes.NewReader(s)
pdu, err := readPDU(r)
if err != nil {
glog.Error(err)
return
}
dataPdu, ok := pdu.Message.(*DataPDU)
if !ok || dataPdu.Header.PDUType2 != PDUTYPE2_CONTROL {
if ok {
glog.Error("recvServerControlCooperatePDU ignore datapdu type2", dataPdu.Header.PDUType2)
} else {
glog.Error("recvServerControlCooperatePDU ignore message type", pdu.ShareCtrlHeader.PDUType)
}
c.transport.Once("data", c.recvServerControlCooperatePDU)
return
}
if dataPdu.Data.(*ControlDataPDU).Action != CTRLACTION_COOPERATE {
glog.Error("recvServerControlCooperatePDU ignore action", dataPdu.Data.(*ControlDataPDU).Action)
c.transport.Once("data", c.recvServerControlCooperatePDU)
return
}
c.transport.Once("data", c.recvServerControlGrantedPDU)
}
func (c *Client) recvServerControlGrantedPDU(s []byte) {
glog.Debug("PDU recvServerControlGrantedPDU")
r := bytes.NewReader(s)
pdu, err := readPDU(r)
if err != nil {
glog.Error(err)
return
}
dataPdu, ok := pdu.Message.(*DataPDU)
if !ok || dataPdu.Header.PDUType2 != PDUTYPE2_CONTROL {
if ok {
glog.Error("recvServerControlGrantedPDU ignore datapdu type2", dataPdu.Header.PDUType2)
} else {
glog.Error("recvServerControlGrantedPDU ignore message type", pdu.ShareCtrlHeader.PDUType)
}
c.transport.Once("data", c.recvServerControlGrantedPDU)
return
}
if dataPdu.Data.(*ControlDataPDU).Action != CTRLACTION_GRANTED_CONTROL {
glog.Error("recvServerControlGrantedPDU ignore action", dataPdu.Data.(*ControlDataPDU).Action)
c.transport.Once("data", c.recvServerControlGrantedPDU)
return
}
c.transport.Once("data", c.recvServerFontMapPDU)
}
func (c *Client) recvServerFontMapPDU(s []byte) {
glog.Debug("PDU recvServerFontMapPDU")
r := bytes.NewReader(s)
pdu, err := readPDU(r)
if err != nil {
glog.Error(err)
return
}
dataPdu, ok := pdu.Message.(*DataPDU)
if !ok || dataPdu.Header.PDUType2 != PDUTYPE2_FONTMAP {
if ok {
glog.Error("recvServerFontMapPDU ignore datapdu type2", dataPdu.Header.PDUType2)
} else {
glog.Error("recvServerFontMapPDU ignore message type", pdu.ShareCtrlHeader.PDUType)
}
return
}
c.transport.On("data", c.recvPDU)
c.Emit("ready")
}
func (c *Client) recvPDU(s []byte) {
glog.Trace("PDU recvPDU", hex.EncodeToString(s))
r := bytes.NewReader(s)
if r.Len() > 0 {
p, err := readPDU(r)
if err != nil {
glog.Error(err)
return
}
if p.ShareCtrlHeader.PDUType == PDUTYPE_DEACTIVATEALLPDU {
c.transport.Once("data", c.recvDemandActivePDU)
} else if p.ShareCtrlHeader.PDUType == PDUTYPE_DATAPDU {
d := p.Message.(*DataPDU)
if d.Header.PDUType2 == PDUTYPE2_UPDATE {
up := d.Data.(*UpdateDataPDU)
p := up.Udata
if up.UpdateType == FASTPATH_UPDATETYPE_BITMAP {
c.Emit("bitmap", p.(*BitmapUpdateDataPDU).Rectangles)
} else if up.UpdateType == FASTPATH_UPDATETYPE_ORDERS {
c.Emit("orders", p.(*FastPathOrdersPDU).OrderPdus)
}
}
}
}
}
func (c *Client) RecvFastPath(secFlag byte, s []byte) {
glog.Trace("PDU RecvFastPath", hex.EncodeToString(s))
r := bytes.NewReader(s)
for r.Len() > 0 {
updateHeader, err := core.ReadUInt8(r)
if err != nil {
return
}
updateCode := updateHeader & 0x0f
fragmentation := updateHeader & 0x30
compression := updateHeader & 0xC0
var compressionFlags uint8 = 0
if compression == FASTPATH_OUTPUT_COMPRESSION_USED {
compressionFlags, err = core.ReadUInt8(r)
}
size, err := core.ReadUint16LE(r)
if err != nil {
return
}
glog.Trace("Code:", FastPathUpdateType(updateCode),
"compressionFlags:", compressionFlags,
"fragmentation:", fragmentation,
"size:", size, "len:", r.Len())
if compressionFlags&RDP_MPPC_COMPRESSED != 0 {
glog.Info("RDP_MPPC_COMPRESSED")
}
if fragmentation != FASTPATH_FRAGMENT_SINGLE {
if fragmentation == FASTPATH_FRAGMENT_FIRST {
c.buff.Reset()
}
b, _ := core.ReadBytes(r.Len(), r)
c.buff.Write(b)
if fragmentation != FASTPATH_FRAGMENT_LAST {
return
}
r = bytes.NewReader(c.buff.Bytes())
}
p, err := readFastPathUpdatePDU(r, updateCode)
if err != nil || p == nil || p.Data == nil {
glog.Debug("readFastPathUpdatePDU:", err)
return
}
if updateCode == FASTPATH_UPDATETYPE_BITMAP {
c.Emit("bitmap", p.Data.(*FastPathBitmapUpdateDataPDU).Rectangles)
} else if updateCode == FASTPATH_UPDATETYPE_COLOR {
c.Emit("color", p.Data.(*FastPathColorPdu))
} else if updateCode == FASTPATH_UPDATETYPE_ORDERS {
c.Emit("orders", p.Data.(*FastPathOrdersPDU).OrderPdus)
}
}
}
type InputEventsInterface interface {
Serialize() []byte
}
func (c *Client) SendInputEvents(msgType uint16, events []InputEventsInterface) {
p := &ClientInputEventPDU{}
p.NumEvents = uint16(len(events))
p.SlowPathInputEvents = make([]SlowPathInputEvent, 0, p.NumEvents)
for _, in := range events {
seria := in.Serialize()
s := SlowPathInputEvent{0, msgType, len(seria), seria}
p.SlowPathInputEvents = append(p.SlowPathInputEvents, s)
}
c.sendDataPDU(p)
}