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 }