libfreerdp-core: add capabilities debug output
authorMarc-André Moreau <marcandre.moreau@gmail.com>
Tue, 12 Feb 2013 21:25:16 +0000 (16:25 -0500)
committerMarc-André Moreau <marcandre.moreau@gmail.com>
Tue, 12 Feb 2013 21:25:16 +0000 (16:25 -0500)
cmake/ConfigOptions.cmake
config.h.in
include/freerdp/settings.h
libfreerdp/core/capabilities.c
libfreerdp/core/errinfo.c
libfreerdp/core/errinfo.h

index ab51258..805299c 100644 (file)
@@ -74,6 +74,7 @@ else()
 endif()
 
 option(WITH_DEBUG_CERTIFICATE "Print certificate related debug messages." ${DEFAULT_DEBUG_OPTION})
+option(WITH_DEBUG_CAPABILITIES "Print capability negotiation debug messages." ${DEFAULT_DEBUG_OPTION})
 option(WITH_DEBUG_CHANNELS "Print channel manager debug messages." ${DEFAULT_DEBUG_OPTION})
 option(WITH_DEBUG_CLIPRDR "Print clipboard redirection debug messages" ${DEFAULT_DEBUG_OPTION})
 option(WITH_DEBUG_DVC "Print dynamic virtual channel debug messages." ${DEFAULT_DEBUG_OPTION})
index 8cbaf26..cfc9fe2 100644 (file)
@@ -48,6 +48,7 @@
 
 /* Debug */
 #cmakedefine WITH_DEBUG_CERTIFICATE
+#cmakedefine WITH_DEBUG_CAPABILITIES
 #cmakedefine WITH_DEBUG_CHANNELS
 #cmakedefine WITH_DEBUG_CLIPRDR
 #cmakedefine WITH_DEBUG_DVC
index f91946e..5018ac4 100644 (file)
 #define NEG_POLYGON_SC_INDEX                   0x14
 #define NEG_POLYGON_CB_INDEX                   0x15
 #define NEG_POLYLINE_INDEX                     0x16
+#define NEG_UNUSED23_INDEX                     0x17
 #define NEG_FAST_GLYPH_INDEX                   0x18
 #define NEG_ELLIPSE_SC_INDEX                   0x19
 #define NEG_ELLIPSE_CB_INDEX                   0x1A
 #define NEG_GLYPH_WEXTTEXTOUT_INDEX            0x1C
 #define NEG_GLYPH_WLONGTEXTOUT_INDEX           0x1D
 #define NEG_GLYPH_WLONGEXTTEXTOUT_INDEX                0x1E
+#define NEG_UNUSED31_INDEX                     0x1F
 
 /* Glyph Support Level */
 #define GLYPH_SUPPORT_NONE                     0x0000
index ef99a36..fdaec0a 100644 (file)
 
 #include "capabilities.h"
 
-/*
-static const char* const CAPSET_TYPE_STRINGS[] =
+//#define WITH_DEBUG_CAPABILITIES              1
+
+#ifdef WITH_DEBUG_CAPABILITIES
+
+const char* const CAPSET_TYPE_STRINGS[] =
 {
                "Unknown",
                "General",
@@ -57,7 +60,11 @@ static const char* const CAPSET_TYPE_STRINGS[] =
                "Surface Commands",
                "Bitmap Codecs",
                "Frame Acknowledge"
-};*/
+};
+
+#endif
+
+BOOL rdp_print_capability_sets(STREAM* s, UINT16 numberCapabilities, BOOL receiving);
 
 /* CODEC_GUID_REMOTEFX 0x76772F12BD724463AFB3B73C9C6F7886 */
 #define CODEC_GUID_REMOTEFX "\x12\x2F\x77\x76\x72\xBD\x63\x44\xAF\xB3\xB7\x3C\x9C\x6F\x78\x86"
@@ -199,6 +206,52 @@ void rdp_write_general_capability_set(STREAM* s, rdpSettings* settings)
        rdp_capability_set_finish(s, header, CAPSET_TYPE_GENERAL);
 }
 
+BOOL rdp_print_general_capability_set(STREAM* s, UINT16 length)
+{
+       UINT16 osMajorType;
+       UINT16 osMinorType;
+       UINT16 protocolVersion;
+       UINT16 pad2OctetsA;
+       UINT16 generalCompressionTypes;
+       UINT16 extraFlags;
+       UINT16 updateCapabilityFlag;
+       UINT16 remoteUnshareFlag;
+       UINT16 generalCompressionLevel;
+       BYTE refreshRectSupport;
+       BYTE suppressOutputSupport;
+
+       if (length < 24)
+               return FALSE;
+
+       printf("GeneralCapabilitySet (length %d):\n", length);
+
+       stream_read_UINT16(s, osMajorType); /* osMajorType (2 bytes) */
+       stream_read_UINT16(s, osMinorType); /* osMinorType (2 bytes) */
+       stream_read_UINT16(s, protocolVersion); /* protocolVersion (2 bytes) */
+       stream_read_UINT16(s, pad2OctetsA); /* pad2OctetsA (2 bytes) */
+       stream_read_UINT16(s, generalCompressionTypes); /* generalCompressionTypes (2 bytes) */
+       stream_read_UINT16(s, extraFlags); /* extraFlags (2 bytes) */
+       stream_read_UINT16(s, updateCapabilityFlag); /* updateCapabilityFlag (2 bytes) */
+       stream_read_UINT16(s, remoteUnshareFlag); /* remoteUnshareFlag (2 bytes) */
+       stream_read_UINT16(s, generalCompressionLevel); /* generalCompressionLevel (2 bytes) */
+       stream_read_BYTE(s, refreshRectSupport); /* refreshRectSupport (1 byte) */
+       stream_read_BYTE(s, suppressOutputSupport); /* suppressOutputSupport (1 byte) */
+
+       printf("\tosMajorType: 0x%04X\n", osMajorType);
+       printf("\tosMinorType: 0x%04X\n", osMinorType);
+       printf("\tprotocolVersion: 0x%04X\n", protocolVersion);
+       printf("\tpad2OctetsA: 0x%04X\n", pad2OctetsA);
+       printf("\tgeneralCompressionTypes: 0x%04X\n", generalCompressionTypes);
+       printf("\textraFlags: 0x%04X\n", extraFlags);
+       printf("\tupdateCapabilityFlag: 0x%04X\n", updateCapabilityFlag);
+       printf("\tremoteUnshareFlag: 0x%04X\n", remoteUnshareFlag);
+       printf("\tgeneralCompressionLevel: 0x%04X\n", generalCompressionLevel);
+       printf("\trefreshRectSupport: 0x%02X\n", refreshRectSupport);
+       printf("\tsuppressOutputSupport: 0x%02X\n", suppressOutputSupport);
+
+       return TRUE;
+}
+
 /**
  * Read bitmap capability set.\n
  * @msdn{cc240554}
@@ -268,6 +321,7 @@ void rdp_write_bitmap_capability_set(STREAM* s, rdpSettings* settings)
        header = rdp_capability_set_start(s);
 
        drawingFlags |= DRAW_ALLOW_SKIP_ALPHA;
+       drawingFlags |= DRAW_ALLOW_COLOR_SUBSAMPLING;
 
        if (settings->RdpVersion > 5)
                preferredBitsPerPixel = settings->ColorDepth;
@@ -293,6 +347,58 @@ void rdp_write_bitmap_capability_set(STREAM* s, rdpSettings* settings)
        rdp_capability_set_finish(s, header, CAPSET_TYPE_BITMAP);
 }
 
+BOOL rdp_print_bitmap_capability_set(STREAM* s, UINT16 length)
+{
+       UINT16 preferredBitsPerPixel;
+       UINT16 receive1BitPerPixel;
+       UINT16 receive4BitsPerPixel;
+       UINT16 receive8BitsPerPixel;
+       UINT16 desktopWidth;
+       UINT16 desktopHeight;
+       UINT16 pad2Octets;
+       UINT16 desktopResizeFlag;
+       UINT16 bitmapCompressionFlag;
+       BYTE highColorFlags;
+       BYTE drawingFlags;
+       UINT16 multipleRectangleSupport;
+       UINT16 pad2OctetsB;
+
+       printf("BitmapCapabilitySet (length %d):\n", length);
+
+       if (length < 28)
+               return FALSE;
+
+       stream_read_UINT16(s, preferredBitsPerPixel); /* preferredBitsPerPixel (2 bytes) */
+       stream_read_UINT16(s, receive1BitPerPixel); /* receive1BitPerPixel (2 bytes) */
+       stream_read_UINT16(s, receive4BitsPerPixel); /* receive4BitsPerPixel (2 bytes) */
+       stream_read_UINT16(s, receive8BitsPerPixel); /* receive8BitsPerPixel (2 bytes) */
+       stream_read_UINT16(s, desktopWidth); /* desktopWidth (2 bytes) */
+       stream_read_UINT16(s, desktopHeight); /* desktopHeight (2 bytes) */
+       stream_read_UINT16(s, pad2Octets); /* pad2Octets (2 bytes) */
+       stream_read_UINT16(s, desktopResizeFlag); /* desktopResizeFlag (2 bytes) */
+       stream_read_UINT16(s, bitmapCompressionFlag); /* bitmapCompressionFlag (2 bytes) */
+       stream_read_BYTE(s, highColorFlags); /* highColorFlags (1 byte) */
+       stream_read_BYTE(s, drawingFlags); /* drawingFlags (1 byte) */
+       stream_read_UINT16(s, multipleRectangleSupport); /* multipleRectangleSupport (2 bytes) */
+       stream_read_UINT16(s, pad2OctetsB); /* pad2OctetsB (2 bytes) */
+
+       printf("\tpreferredBitsPerPixel: 0x%04X\n", preferredBitsPerPixel);
+       printf("\treceive1BitPerPixel: 0x%04X\n", receive1BitPerPixel);
+       printf("\treceive4BitsPerPixel: 0x%04X\n", receive4BitsPerPixel);
+       printf("\treceive8BitsPerPixel: 0x%04X\n", receive8BitsPerPixel);
+       printf("\tdesktopWidth: 0x%04X\n", desktopWidth);
+       printf("\tdesktopHeight: 0x%04X\n", desktopHeight);
+       printf("\tpad2Octets: 0x%04X\n", pad2Octets);
+       printf("\tdesktopResizeFlag: 0x%04X\n", desktopResizeFlag);
+       printf("\tbitmapCompressionFlag: 0x%04X\n", bitmapCompressionFlag);
+       printf("\thighColorFlags: 0x%02X\n", highColorFlags);
+       printf("\tdrawingFlags: 0x%02X\n", drawingFlags);
+       printf("\tmultipleRectangleSupport: 0x%04X\n", multipleRectangleSupport);
+       printf("\tpad2OctetsB: 0x%04X\n", pad2OctetsB);
+
+       return TRUE;
+}
+
 /**
  * Read order capability set.\n
  * @msdn{cc240556}
@@ -308,8 +414,9 @@ BOOL rdp_read_order_capability_set(STREAM* s, UINT16 length, rdpSettings* settin
        BYTE orderSupport[32];
        UINT16 orderSupportExFlags;
 
-       if(length < 88)
+       if (length < 88)
                return FALSE;
+
        stream_seek(s, 16); /* terminalDescriptor (16 bytes) */
        stream_seek_UINT32(s); /* pad4OctetsA (4 bytes) */
        stream_seek_UINT16(s); /* desktopSaveXGranularity (2 bytes) */
@@ -334,12 +441,6 @@ BOOL rdp_read_order_capability_set(STREAM* s, UINT16 length, rdpSettings* settin
                        settings->OrderSupport[i] = FALSE;
        }
 
-       /* pad4octetsB (4 bytes) */
-       /* desktopSaveSize (4 bytes) */
-       /* pad2octetsC (2 bytes) */
-       /* pad2octetsD (2 bytes) */
-       /* textANSICodePage (2 bytes) */
-       /* pad2octetsE (2 bytes) */
        return TRUE;
 }
 
@@ -398,6 +499,103 @@ void rdp_write_order_capability_set(STREAM* s, rdpSettings* settings)
        rdp_capability_set_finish(s, header, CAPSET_TYPE_ORDER);
 }
 
+BOOL rdp_print_order_capability_set(STREAM* s, UINT16 length)
+{
+       BYTE terminalDescriptor[16];
+       UINT32 pad4OctetsA;
+       UINT16 desktopSaveXGranularity;
+       UINT16 desktopSaveYGranularity;
+       UINT16 pad2OctetsA;
+       UINT16 maximumOrderLevel;
+       UINT16 numberFonts;
+       UINT16 orderFlags;
+       BYTE orderSupport[32];
+       UINT16 textFlags;
+       UINT16 orderSupportExFlags;
+       UINT32 pad4OctetsB;
+       UINT32 desktopSaveSize;
+       UINT16 pad2OctetsC;
+       UINT16 pad2OctetsD;
+       UINT16 textANSICodePage;
+       UINT16 pad2OctetsE;
+
+       printf("OrderCapabilitySet (length %d):\n", length);
+
+       if (length < 88)
+               return FALSE;
+
+       stream_read(s, terminalDescriptor, 16); /* terminalDescriptor (16 bytes) */
+       stream_read_UINT32(s, pad4OctetsA); /* pad4OctetsA (4 bytes) */
+       stream_read_UINT16(s, desktopSaveXGranularity); /* desktopSaveXGranularity (2 bytes) */
+       stream_read_UINT16(s, desktopSaveYGranularity); /* desktopSaveYGranularity (2 bytes) */
+       stream_read_UINT16(s, pad2OctetsA); /* pad2OctetsA (2 bytes) */
+       stream_read_UINT16(s, maximumOrderLevel); /* maximumOrderLevel (2 bytes) */
+       stream_read_UINT16(s, numberFonts); /* numberFonts (2 bytes) */
+       stream_read_UINT16(s, orderFlags); /* orderFlags (2 bytes) */
+       stream_read(s, orderSupport, 32); /* orderSupport (32 bytes) */
+       stream_read_UINT16(s, textFlags); /* textFlags (2 bytes) */
+       stream_read_UINT16(s, orderSupportExFlags); /* orderSupportExFlags (2 bytes) */
+       stream_read_UINT32(s, pad4OctetsB); /* pad4OctetsB (4 bytes) */
+       stream_read_UINT32(s, desktopSaveSize); /* desktopSaveSize (4 bytes) */
+       stream_read_UINT16(s, pad2OctetsC); /* pad2OctetsC (2 bytes) */
+       stream_read_UINT16(s, pad2OctetsD); /* pad2OctetsD (2 bytes) */
+       stream_read_UINT16(s, textANSICodePage); /* textANSICodePage (2 bytes) */
+       stream_read_UINT16(s, pad2OctetsE); /* pad2OctetsE (2 bytes) */
+
+       printf("\tpad4OctetsA: 0x%08X\n", pad4OctetsA);
+       printf("\tdesktopSaveXGranularity: 0x%04X\n", desktopSaveXGranularity);
+       printf("\tdesktopSaveYGranularity: 0x%04X\n", desktopSaveYGranularity);
+       printf("\tpad2OctetsA: 0x%04X\n", pad2OctetsA);
+       printf("\tmaximumOrderLevel: 0x%04X\n", maximumOrderLevel);
+       printf("\tnumberFonts: 0x%04X\n", numberFonts);
+       printf("\torderFlags: 0x%04X\n", orderFlags);
+
+       printf("\torderSupport:\n");
+       printf("\t\tDSTBLT: %d\n", orderSupport[NEG_DSTBLT_INDEX]);
+       printf("\t\tPATBLT: %d\n", orderSupport[NEG_PATBLT_INDEX]);
+       printf("\t\tSCRBLT: %d\n", orderSupport[NEG_SCRBLT_INDEX]);
+       printf("\t\tMEMBLT: %d\n", orderSupport[NEG_MEMBLT_INDEX]);
+       printf("\t\tMEM3BLT: %d\n", orderSupport[NEG_MEM3BLT_INDEX]);
+       printf("\t\tATEXTOUT: %d\n", orderSupport[NEG_ATEXTOUT_INDEX]);
+       printf("\t\tAEXTTEXTOUT: %d\n", orderSupport[NEG_AEXTTEXTOUT_INDEX]);
+       printf("\t\tDRAWNINEGRID: %d\n", orderSupport[NEG_DRAWNINEGRID_INDEX]);
+       printf("\t\tLINETO: %d\n", orderSupport[NEG_LINETO_INDEX]);
+       printf("\t\tMULTI_DRAWNINEGRID: %d\n", orderSupport[NEG_MULTI_DRAWNINEGRID_INDEX]);
+       printf("\t\tOPAQUE_RECT: %d\n", orderSupport[NEG_OPAQUE_RECT_INDEX]);
+       printf("\t\tSAVEBITMAP: %d\n", orderSupport[NEG_SAVEBITMAP_INDEX]);
+       printf("\t\tWTEXTOUT: %d\n", orderSupport[NEG_WTEXTOUT_INDEX]);
+       printf("\t\tMEMBLT_V2: %d\n", orderSupport[NEG_MEMBLT_V2_INDEX]);
+       printf("\t\tMEM3BLT_V2: %d\n", orderSupport[NEG_MEM3BLT_V2_INDEX]);
+       printf("\t\tMULTIDSTBLT: %d\n", orderSupport[NEG_MULTIDSTBLT_INDEX]);
+       printf("\t\tMULTIPATBLT: %d\n", orderSupport[NEG_MULTIPATBLT_INDEX]);
+       printf("\t\tMULTISCRBLT: %d\n", orderSupport[NEG_MULTISCRBLT_INDEX]);
+       printf("\t\tMULTIOPAQUERECT: %d\n", orderSupport[NEG_MULTIOPAQUERECT_INDEX]);
+       printf("\t\tFAST_INDEX: %d\n", orderSupport[NEG_FAST_INDEX_INDEX]);
+       printf("\t\tPOLYGON_SC: %d\n", orderSupport[NEG_POLYGON_SC_INDEX]);
+       printf("\t\tPOLYGON_CB: %d\n", orderSupport[NEG_POLYGON_CB_INDEX]);
+       printf("\t\tPOLYLINE: %d\n", orderSupport[NEG_POLYLINE_INDEX]);
+       printf("\t\tUNUSED23: %d\n", orderSupport[NEG_UNUSED23_INDEX]);
+       printf("\t\tFAST_GLYPH: %d\n", orderSupport[NEG_FAST_GLYPH_INDEX]);
+       printf("\t\tELLIPSE_SC: %d\n", orderSupport[NEG_ELLIPSE_SC_INDEX]);
+       printf("\t\tELLIPSE_CB: %d\n", orderSupport[NEG_ELLIPSE_CB_INDEX]);
+       printf("\t\tGLYPH_INDEX: %d\n", orderSupport[NEG_GLYPH_INDEX_INDEX]);
+       printf("\t\tGLYPH_WEXTTEXTOUT: %d\n", orderSupport[NEG_GLYPH_WEXTTEXTOUT_INDEX]);
+       printf("\t\tGLYPH_WLONGTEXTOUT: %d\n", orderSupport[NEG_GLYPH_WLONGTEXTOUT_INDEX]);
+       printf("\t\tGLYPH_WLONGEXTTEXTOUT: %d\n", orderSupport[NEG_GLYPH_WLONGEXTTEXTOUT_INDEX]);
+       printf("\t\tUNUSED31: %d\n", orderSupport[NEG_UNUSED31_INDEX]);
+
+       printf("\ttextFlags: 0x%04X\n", textFlags);
+       printf("\torderSupportExFlags: 0x%04X\n", orderSupportExFlags);
+       printf("\tpad4OctetsB: 0x%08X\n", pad4OctetsB);
+       printf("\tdesktopSaveSize: 0x%08X\n", desktopSaveSize);
+       printf("\tpad2OctetsC: 0x%04X\n", pad2OctetsC);
+       printf("\tpad2OctetsD: 0x%04X\n", pad2OctetsD);
+       printf("\ttextANSICodePage: 0x%04X\n", textANSICodePage);
+       printf("\tpad2OctetsE: 0x%04X\n", pad2OctetsE);
+
+       return TRUE;
+}
+
 /**
  * Read bitmap cache capability set.\n
  * @msdn{cc240559}
@@ -408,8 +606,9 @@ void rdp_write_order_capability_set(STREAM* s, rdpSettings* settings)
 
 BOOL rdp_read_bitmap_cache_capability_set(STREAM* s, UINT16 length, rdpSettings* settings)
 {
-       if(length < 40)
+       if (length < 40)
                return FALSE;
+
        stream_seek_UINT32(s); /* pad1 (4 bytes) */
        stream_seek_UINT32(s); /* pad2 (4 bytes) */
        stream_seek_UINT32(s); /* pad3 (4 bytes) */
@@ -422,6 +621,7 @@ BOOL rdp_read_bitmap_cache_capability_set(STREAM* s, UINT16 length, rdpSettings*
        stream_seek_UINT16(s); /* Cache1MaximumCellSize (2 bytes) */
        stream_seek_UINT16(s); /* Cache2Entries (2 bytes) */
        stream_seek_UINT16(s); /* Cache2MaximumCellSize (2 bytes) */
+
        return TRUE;
 }
 
@@ -464,6 +664,51 @@ void rdp_write_bitmap_cache_capability_set(STREAM* s, rdpSettings* settings)
        rdp_capability_set_finish(s, header, CAPSET_TYPE_BITMAP_CACHE);
 }
 
+BOOL rdp_print_bitmap_cache_capability_set(STREAM* s, UINT16 length)
+{
+       UINT32 pad1, pad2, pad3;
+       UINT32 pad4, pad5, pad6;
+       UINT16 Cache0Entries;
+       UINT16 Cache0MaximumCellSize;
+       UINT16 Cache1Entries;
+       UINT16 Cache1MaximumCellSize;
+       UINT16 Cache2Entries;
+       UINT16 Cache2MaximumCellSize;
+
+       printf("BitmapCacheCapabilitySet (length %d):\n", length);
+
+       if (length < 40)
+               return FALSE;
+
+       stream_read_UINT32(s, pad1); /* pad1 (4 bytes) */
+       stream_read_UINT32(s, pad2); /* pad2 (4 bytes) */
+       stream_read_UINT32(s, pad3); /* pad3 (4 bytes) */
+       stream_read_UINT32(s, pad4); /* pad4 (4 bytes) */
+       stream_read_UINT32(s, pad5); /* pad5 (4 bytes) */
+       stream_read_UINT32(s, pad6); /* pad6 (4 bytes) */
+       stream_read_UINT16(s, Cache0Entries); /* Cache0Entries (2 bytes) */
+       stream_read_UINT16(s, Cache0MaximumCellSize); /* Cache0MaximumCellSize (2 bytes) */
+       stream_read_UINT16(s, Cache1Entries); /* Cache1Entries (2 bytes) */
+       stream_read_UINT16(s, Cache1MaximumCellSize); /* Cache1MaximumCellSize (2 bytes) */
+       stream_read_UINT16(s, Cache2Entries); /* Cache2Entries (2 bytes) */
+       stream_read_UINT16(s, Cache2MaximumCellSize); /* Cache2MaximumCellSize (2 bytes) */
+
+       printf("\tpad1: 0x%08X\n", pad1);
+       printf("\tpad2: 0x%08X\n", pad2);
+       printf("\tpad3: 0x%08X\n", pad3);
+       printf("\tpad4: 0x%08X\n", pad4);
+       printf("\tpad5: 0x%08X\n", pad5);
+       printf("\tpad6: 0x%08X\n", pad6);
+       printf("\tCache0Entries: 0x%04X\n", Cache0Entries);
+       printf("\tCache0MaximumCellSize: 0x%04X\n", Cache0MaximumCellSize);
+       printf("\tCache1Entries: 0x%04X\n", Cache1Entries);
+       printf("\tCache1MaximumCellSize: 0x%04X\n", Cache1MaximumCellSize);
+       printf("\tCache2Entries: 0x%04X\n", Cache2Entries);
+       printf("\tCache2MaximumCellSize: 0x%04X\n", Cache2MaximumCellSize);
+
+       return TRUE;
+}
+
 /**
  * Read control capability set.\n
  * @msdn{cc240568}
@@ -474,12 +719,14 @@ void rdp_write_bitmap_cache_capability_set(STREAM* s, rdpSettings* settings)
 
 BOOL rdp_read_control_capability_set(STREAM* s, UINT16 length, rdpSettings* settings)
 {
-       if(length < 12)
+       if (length < 12)
                return FALSE;
+
        stream_seek_UINT16(s); /* controlFlags (2 bytes) */
        stream_seek_UINT16(s); /* remoteDetachFlag (2 bytes) */
        stream_seek_UINT16(s); /* controlInterest (2 bytes) */
        stream_seek_UINT16(s); /* detachInterest (2 bytes) */
+
        return TRUE;
 }
 
@@ -504,6 +751,31 @@ void rdp_write_control_capability_set(STREAM* s, rdpSettings* settings)
        rdp_capability_set_finish(s, header, CAPSET_TYPE_CONTROL);
 }
 
+BOOL rdp_print_control_capability_set(STREAM* s, UINT16 length)
+{
+       UINT16 controlFlags;
+       UINT16 remoteDetachFlag;
+       UINT16 controlInterest;
+       UINT16 detachInterest;
+
+       printf("ControlCapabilitySet (length %d):\n", length);
+
+       if (length < 12)
+               return FALSE;
+
+       stream_read_UINT16(s, controlFlags); /* controlFlags (2 bytes) */
+       stream_read_UINT16(s, remoteDetachFlag); /* remoteDetachFlag (2 bytes) */
+       stream_read_UINT16(s, controlInterest); /* controlInterest (2 bytes) */
+       stream_read_UINT16(s, detachInterest); /* detachInterest (2 bytes) */
+
+       printf("\tcontrolFlags: 0x%04X\n", controlFlags);
+       printf("\tremoteDetachFlag: 0x%04X\n", remoteDetachFlag);
+       printf("\tcontrolInterest: 0x%04X\n", controlInterest);
+       printf("\tdetachInterest: 0x%04X\n", detachInterest);
+
+       return TRUE;
+}
+
 /**
  * Read window activation capability set.\n
  * @msdn{cc240569}
@@ -514,12 +786,14 @@ void rdp_write_control_capability_set(STREAM* s, rdpSettings* settings)
 
 BOOL rdp_read_window_activation_capability_set(STREAM* s, UINT16 length, rdpSettings* settings)
 {
-       if(length < 12)
+       if (length < 12)
                return FALSE;
+
        stream_seek_UINT16(s); /* helpKeyFlag (2 bytes) */
        stream_seek_UINT16(s); /* helpKeyIndexFlag (2 bytes) */
        stream_seek_UINT16(s); /* helpExtendedKeyFlag (2 bytes) */
        stream_seek_UINT16(s); /* windowManagerKeyFlag (2 bytes) */
+
        return TRUE;
 }
 
@@ -544,6 +818,31 @@ void rdp_write_window_activation_capability_set(STREAM* s, rdpSettings* settings
        rdp_capability_set_finish(s, header, CAPSET_TYPE_ACTIVATION);
 }
 
+BOOL rdp_print_window_activation_capability_set(STREAM* s, UINT16 length)
+{
+       UINT16 helpKeyFlag;
+       UINT16 helpKeyIndexFlag;
+       UINT16 helpExtendedKeyFlag;
+       UINT16 windowManagerKeyFlag;
+
+       printf("WindowActivationCapabilitySet (length %d):\n", length);
+
+       if (length < 12)
+               return FALSE;
+
+       stream_read_UINT16(s, helpKeyFlag); /* helpKeyFlag (2 bytes) */
+       stream_read_UINT16(s, helpKeyIndexFlag); /* helpKeyIndexFlag (2 bytes) */
+       stream_read_UINT16(s, helpExtendedKeyFlag); /* helpExtendedKeyFlag (2 bytes) */
+       stream_read_UINT16(s, windowManagerKeyFlag); /* windowManagerKeyFlag (2 bytes) */
+
+       printf("\thelpKeyFlag: 0x%04X\n", helpKeyFlag);
+       printf("\thelpKeyIndexFlag: 0x%04X\n", helpKeyIndexFlag);
+       printf("\thelpExtendedKeyFlag: 0x%04X\n", helpExtendedKeyFlag);
+       printf("\twindowManagerKeyFlag: 0x%04X\n", windowManagerKeyFlag);
+
+       return TRUE;
+}
+
 /**
  * Read pointer capability set.\n
  * @msdn{cc240562}
@@ -558,8 +857,9 @@ BOOL rdp_read_pointer_capability_set(STREAM* s, UINT16 length, rdpSettings* sett
        UINT16 colorPointerCacheSize;
        UINT16 pointerCacheSize;
 
-       if(length < 10)
+       if (length < 10)
                return FALSE;
+
        stream_read_UINT16(s, colorPointerFlag); /* colorPointerFlag (2 bytes) */
        stream_read_UINT16(s, colorPointerCacheSize); /* colorPointerCacheSize (2 bytes) */
        stream_read_UINT16(s, pointerCacheSize); /* pointerCacheSize (2 bytes) */
@@ -601,6 +901,28 @@ void rdp_write_pointer_capability_set(STREAM* s, rdpSettings* settings)
        rdp_capability_set_finish(s, header, CAPSET_TYPE_POINTER);
 }
 
+BOOL rdp_print_pointer_capability_set(STREAM* s, UINT16 length)
+{
+       UINT16 colorPointerFlag;
+       UINT16 colorPointerCacheSize;
+       UINT16 pointerCacheSize;
+
+       if (length < 10)
+               return FALSE;
+
+       printf("PointerCapabilitySet (length %d):\n", length);
+
+       stream_read_UINT16(s, colorPointerFlag); /* colorPointerFlag (2 bytes) */
+       stream_read_UINT16(s, colorPointerCacheSize); /* colorPointerCacheSize (2 bytes) */
+       stream_read_UINT16(s, pointerCacheSize); /* pointerCacheSize (2 bytes) */
+
+       printf("\tcolorPointerFlag: 0x%04X\n", colorPointerFlag);
+       printf("\tcolorPointerCacheSize: 0x%04X\n", colorPointerCacheSize);
+       printf("\tpointerCacheSize: 0x%04X\n", pointerCacheSize);
+
+       return TRUE;
+}
+
 /**
  * Read share capability set.\n
  * @msdn{cc240570}
@@ -611,10 +933,12 @@ void rdp_write_pointer_capability_set(STREAM* s, rdpSettings* settings)
 
 BOOL rdp_read_share_capability_set(STREAM* s, UINT16 length, rdpSettings* settings)
 {
-       if(length < 8)
+       if (length < 8)
                return FALSE;
+
        stream_seek_UINT16(s); /* nodeId (2 bytes) */
        stream_seek_UINT16(s); /* pad2Octets (2 bytes) */
+
        return TRUE;
 }
 
@@ -640,6 +964,25 @@ void rdp_write_share_capability_set(STREAM* s, rdpSettings* settings)
        rdp_capability_set_finish(s, header, CAPSET_TYPE_SHARE);
 }
 
+BOOL rdp_print_share_capability_set(STREAM* s, UINT16 length)
+{
+       UINT16 nodeId;
+       UINT16 pad2Octets;
+
+       printf("ShareCapabilitySet (length %d):\n", length);
+
+       if (length < 8)
+               return FALSE;
+
+       stream_read_UINT16(s, nodeId); /* nodeId (2 bytes) */
+       stream_read_UINT16(s, pad2Octets); /* pad2Octets (2 bytes) */
+
+       printf("\tnodeId: 0x%04X\n", nodeId);
+       printf("\tpad2Octets: 0x%04X\n", pad2Octets);
+
+       return TRUE;
+}
+
 /**
  * Read color cache capability set.\n
  * @msdn{cc241564}
@@ -650,10 +993,12 @@ void rdp_write_share_capability_set(STREAM* s, rdpSettings* settings)
 
 BOOL rdp_read_color_cache_capability_set(STREAM* s, UINT16 length, rdpSettings* settings)
 {
-       if(length < 8)
+       if (length < 8)
                return FALSE;
+
        stream_seek_UINT16(s); /* colorTableCacheSize (2 bytes) */
        stream_seek_UINT16(s); /* pad2Octets (2 bytes) */
+
        return TRUE;
 }
 
@@ -676,6 +1021,25 @@ void rdp_write_color_cache_capability_set(STREAM* s, rdpSettings* settings)
        rdp_capability_set_finish(s, header, CAPSET_TYPE_COLOR_CACHE);
 }
 
+BOOL rdp_print_color_cache_capability_set(STREAM* s, UINT16 length)
+{
+       UINT16 colorTableCacheSize;
+       UINT16 pad2Octets;
+
+       printf("ColorCacheCapabilitySet (length %d):\n", length);
+
+       if (length < 8)
+               return FALSE;
+
+       stream_read_UINT16(s, colorTableCacheSize); /* colorTableCacheSize (2 bytes) */
+       stream_read_UINT16(s, pad2Octets); /* pad2Octets (2 bytes) */
+
+       printf("\tcolorTableCacheSize: 0x%04X\n", colorTableCacheSize);
+       printf("\tpad2Octets: 0x%04X\n", pad2Octets);
+
+       return TRUE;
+}
+
 /**
  * Read sound capability set.\n
  * @msdn{cc240552}
@@ -688,12 +1052,14 @@ BOOL rdp_read_sound_capability_set(STREAM* s, UINT16 length, rdpSettings* settin
 {
        UINT16 soundFlags;
 
-       if(length < 8)
+       if (length < 8)
                return FALSE;
+
        stream_read_UINT16(s, soundFlags); /* soundFlags (2 bytes) */
        stream_seek_UINT16(s); /* pad2OctetsA (2 bytes) */
 
        settings->SoundBeepsEnabled = (soundFlags & SOUND_BEEPS_FLAG) ? TRUE : FALSE;
+
        return TRUE;
 }
 
@@ -719,6 +1085,25 @@ void rdp_write_sound_capability_set(STREAM* s, rdpSettings* settings)
        rdp_capability_set_finish(s, header, CAPSET_TYPE_SOUND);
 }
 
+BOOL rdp_print_sound_capability_set(STREAM* s, UINT16 length)
+{
+       UINT16 soundFlags;
+       UINT16 pad2OctetsA;
+
+       printf("SoundCapabilitySet (length %d):\n", length);
+
+       if (length < 8)
+               return FALSE;
+
+       stream_read_UINT16(s, soundFlags); /* soundFlags (2 bytes) */
+       stream_read_UINT16(s, pad2OctetsA); /* pad2OctetsA (2 bytes) */
+
+       printf("\tsoundFlags: 0x%04X\n", soundFlags);
+       printf("\tpad2OctetsA: 0x%04X\n", pad2OctetsA);
+
+       return TRUE;
+}
+
 /**
  * Read input capability set.\n
  * @msdn{cc240563}
@@ -731,8 +1116,9 @@ BOOL rdp_read_input_capability_set(STREAM* s, UINT16 length, rdpSettings* settin
 {
        UINT16 inputFlags;
 
-       if(length < 88)
+       if (length < 88)
                return FALSE;
+
        stream_read_UINT16(s, inputFlags); /* inputFlags (2 bytes) */
        stream_seek_UINT16(s); /* pad2OctetsA (2 bytes) */
 
@@ -805,6 +1191,38 @@ void rdp_write_input_capability_set(STREAM* s, rdpSettings* settings)
        rdp_capability_set_finish(s, header, CAPSET_TYPE_INPUT);
 }
 
+BOOL rdp_print_input_capability_set(STREAM* s, UINT16 length)
+{
+       UINT16 inputFlags;
+       UINT16 pad2OctetsA;
+       UINT32 keyboardLayout;
+       UINT32 keyboardType;
+       UINT32 keyboardSubType;
+       UINT32 keyboardFunctionKey;
+
+       printf("InputCapabilitySet (length %d)\n", length);
+
+       if (length < 88)
+               return FALSE;
+
+       stream_read_UINT16(s, inputFlags); /* inputFlags (2 bytes) */
+       stream_read_UINT16(s, pad2OctetsA); /* pad2OctetsA (2 bytes) */
+       stream_read_UINT32(s, keyboardLayout); /* keyboardLayout (4 bytes) */
+       stream_read_UINT32(s, keyboardType); /* keyboardType (4 bytes) */
+       stream_read_UINT32(s, keyboardSubType); /* keyboardSubType (4 bytes) */
+       stream_read_UINT32(s, keyboardFunctionKey); /* keyboardFunctionKeys (4 bytes) */
+       stream_seek(s, 64); /* imeFileName (64 bytes) */
+
+       printf("\tinputFlags: 0x%04X\n", inputFlags);
+       printf("\tpad2OctetsA: 0x%04X\n", pad2OctetsA);
+       printf("\tkeyboardLayout: 0x%08X\n", keyboardLayout);
+       printf("\tkeyboardType: 0x%08X\n", keyboardType);
+       printf("\tkeyboardSubType: 0x%08X\n", keyboardSubType);
+       printf("\tkeyboardFunctionKey: 0x%08X\n", keyboardFunctionKey);
+
+       return TRUE;
+}
+
 /**
  * Read font capability set.\n
  * @msdn{cc240571}
@@ -820,6 +1238,7 @@ BOOL rdp_read_font_capability_set(STREAM* s, UINT16 length, rdpSettings* setting
 
        if (length > 6)
                stream_seek_UINT16(s); /* pad2Octets (2 bytes) */
+
        return TRUE;
 }
 
@@ -842,6 +1261,25 @@ void rdp_write_font_capability_set(STREAM* s, rdpSettings* settings)
        rdp_capability_set_finish(s, header, CAPSET_TYPE_FONT);
 }
 
+BOOL rdp_print_font_capability_set(STREAM* s, UINT16 length)
+{
+       UINT16 fontSupportFlags = 0;
+       UINT16 pad2Octets = 0;
+
+       printf("FontCapabilitySet (length %d):\n", length);
+
+       if (length > 4)
+               stream_read_UINT16(s, fontSupportFlags); /* fontSupportFlags (2 bytes) */
+
+       if (length > 6)
+               stream_read_UINT16(s, pad2Octets); /* pad2Octets (2 bytes) */
+
+       printf("\tfontSupportFlags: 0x%04X\n", fontSupportFlags);
+       printf("\tpad2Octets: 0x%04X\n", pad2Octets);
+
+       return TRUE;
+}
+
 /**
  * Read brush capability set.\n
  * @msdn{cc240564}
@@ -852,9 +1290,11 @@ void rdp_write_font_capability_set(STREAM* s, rdpSettings* settings)
 
 BOOL rdp_read_brush_capability_set(STREAM* s, UINT16 length, rdpSettings* settings)
 {
-       if(length < 8)
+       if (length < 8)
                return FALSE;
+
        stream_seek_UINT32(s); /* brushSupportLevel (4 bytes) */
+
        return TRUE;
 }
 
@@ -876,6 +1316,22 @@ void rdp_write_brush_capability_set(STREAM* s, rdpSettings* settings)
        rdp_capability_set_finish(s, header, CAPSET_TYPE_BRUSH);
 }
 
+BOOL rdp_print_brush_capability_set(STREAM* s, UINT16 length)
+{
+       UINT32 brushSupportLevel;
+
+       printf("BrushCapabilitySet (length %d):\n", length);
+
+       if (length < 8)
+               return FALSE;
+
+       stream_read_UINT32(s, brushSupportLevel); /* brushSupportLevel (4 bytes) */
+
+       printf("\tbrushSupportLevel: 0x%08X\n", brushSupportLevel);
+
+       return TRUE;
+}
+
 /**
  * Read cache definition (glyph).\n
  * @msdn{cc240566}
@@ -910,14 +1366,16 @@ BOOL rdp_read_glyph_cache_capability_set(STREAM* s, UINT16 length, rdpSettings*
 {
        UINT16 glyphSupportLevel;
 
-       if(length < 52)
+       if (length < 52)
                return FALSE;
+
        stream_seek(s, 40); /* glyphCache (40 bytes) */
        stream_seek_UINT32(s); /* fragCache (4 bytes) */
        stream_read_UINT16(s, glyphSupportLevel); /* glyphSupportLevel (2 bytes) */
        stream_seek_UINT16(s); /* pad2Octets (2 bytes) */
 
        settings->GlyphSupportLevel = glyphSupportLevel;
+
        return TRUE;
 }
 
@@ -945,7 +1403,6 @@ void rdp_write_glyph_cache_capability_set(STREAM* s, rdpSettings* settings)
        rdp_write_cache_definition(s, &(settings->GlyphCache[7])); /* glyphCache7 (4 bytes) */
        rdp_write_cache_definition(s, &(settings->GlyphCache[8])); /* glyphCache8 (4 bytes) */
        rdp_write_cache_definition(s, &(settings->GlyphCache[9])); /* glyphCache9 (4 bytes) */
-
        rdp_write_cache_definition(s, settings->FragCache);  /* fragCache (4 bytes) */
 
        stream_write_UINT16(s, settings->GlyphSupportLevel); /* glyphSupportLevel (2 bytes) */
@@ -955,6 +1412,51 @@ void rdp_write_glyph_cache_capability_set(STREAM* s, rdpSettings* settings)
        rdp_capability_set_finish(s, header, CAPSET_TYPE_GLYPH_CACHE);
 }
 
+BOOL rdp_print_glyph_cache_capability_set(STREAM* s, UINT16 length)
+{
+       GLYPH_CACHE_DEFINITION glyphCache[10];
+       GLYPH_CACHE_DEFINITION fragCache;
+       UINT16 glyphSupportLevel;
+       UINT16 pad2Octets;
+
+       printf("GlyphCacheCapabilitySet (length %d):\n", length);
+
+       if (length < 52)
+               return FALSE;
+
+       /* glyphCache (40 bytes) */
+       rdp_read_cache_definition(s, &glyphCache[0]); /* glyphCache0 (4 bytes) */
+       rdp_read_cache_definition(s, &glyphCache[1]); /* glyphCache1 (4 bytes) */
+       rdp_read_cache_definition(s, &glyphCache[2]); /* glyphCache2 (4 bytes) */
+       rdp_read_cache_definition(s, &glyphCache[3]); /* glyphCache3 (4 bytes) */
+       rdp_read_cache_definition(s, &glyphCache[4]); /* glyphCache4 (4 bytes) */
+       rdp_read_cache_definition(s, &glyphCache[5]); /* glyphCache5 (4 bytes) */
+       rdp_read_cache_definition(s, &glyphCache[6]); /* glyphCache6 (4 bytes) */
+       rdp_read_cache_definition(s, &glyphCache[7]); /* glyphCache7 (4 bytes) */
+       rdp_read_cache_definition(s, &glyphCache[8]); /* glyphCache8 (4 bytes) */
+       rdp_read_cache_definition(s, &glyphCache[9]); /* glyphCache9 (4 bytes) */
+       rdp_read_cache_definition(s, &fragCache);  /* fragCache (4 bytes) */
+
+       stream_read_UINT16(s, glyphSupportLevel); /* glyphSupportLevel (2 bytes) */
+       stream_read_UINT16(s, pad2Octets); /* pad2Octets (2 bytes) */
+
+       printf("\tglyphCache0: Entries: %d MaximumCellSize: %d\n", glyphCache[0].cacheEntries, glyphCache[0].cacheMaximumCellSize);
+       printf("\tglyphCache1: Entries: %d MaximumCellSize: %d\n", glyphCache[1].cacheEntries, glyphCache[1].cacheMaximumCellSize);
+       printf("\tglyphCache2: Entries: %d MaximumCellSize: %d\n", glyphCache[2].cacheEntries, glyphCache[2].cacheMaximumCellSize);
+       printf("\tglyphCache3: Entries: %d MaximumCellSize: %d\n", glyphCache[3].cacheEntries, glyphCache[3].cacheMaximumCellSize);
+       printf("\tglyphCache4: Entries: %d MaximumCellSize: %d\n", glyphCache[4].cacheEntries, glyphCache[4].cacheMaximumCellSize);
+       printf("\tglyphCache5: Entries: %d MaximumCellSize: %d\n", glyphCache[5].cacheEntries, glyphCache[5].cacheMaximumCellSize);
+       printf("\tglyphCache6: Entries: %d MaximumCellSize: %d\n", glyphCache[6].cacheEntries, glyphCache[6].cacheMaximumCellSize);
+       printf("\tglyphCache7: Entries: %d MaximumCellSize: %d\n", glyphCache[7].cacheEntries, glyphCache[7].cacheMaximumCellSize);
+       printf("\tglyphCache8: Entries: %d MaximumCellSize: %d\n", glyphCache[8].cacheEntries, glyphCache[8].cacheMaximumCellSize);
+       printf("\tglyphCache9: Entries: %d MaximumCellSize: %d\n", glyphCache[9].cacheEntries, glyphCache[9].cacheMaximumCellSize);
+       printf("\tfragCache: Entries: %d MaximumCellSize: %d\n", fragCache.cacheEntries, fragCache.cacheMaximumCellSize);
+       printf("\tglyphSupportLevel: 0x%04X\n", glyphSupportLevel);
+       printf("\tpad2Octets: 0x%04X\n", pad2Octets);
+
+       return TRUE;
+}
+
 /**
  * Read offscreen bitmap cache capability set.\n
  * @msdn{cc240550}
@@ -967,14 +1469,16 @@ BOOL rdp_read_offscreen_bitmap_cache_capability_set(STREAM* s, UINT16 length, rd
 {
        UINT32 offscreenSupportLevel;
 
-       if(length < 12)
+       if (length < 12)
                return FALSE;
+
        stream_read_UINT32(s, offscreenSupportLevel); /* offscreenSupportLevel (4 bytes) */
        stream_read_UINT16(s, settings->OffscreenCacheSize); /* offscreenCacheSize (2 bytes) */
        stream_read_UINT16(s, settings->OffscreenCacheEntries); /* offscreenCacheEntries (2 bytes) */
 
        if (offscreenSupportLevel & TRUE)
                settings->OffscreenSupportLevel = TRUE;
+
        return TRUE;
 }
 
@@ -1002,6 +1506,28 @@ void rdp_write_offscreen_bitmap_cache_capability_set(STREAM* s, rdpSettings* set
        rdp_capability_set_finish(s, header, CAPSET_TYPE_OFFSCREEN_CACHE);
 }
 
+BOOL rdp_print_offscreen_bitmap_cache_capability_set(STREAM* s, UINT16 length)
+{
+       UINT32 offscreenSupportLevel;
+       UINT16 offscreenCacheSize;
+       UINT16 offscreenCacheEntries;
+
+       printf("OffscreenBitmapCacheCapabilitySet (length %d):\n", length);
+
+       if (length < 12)
+               return FALSE;
+
+       stream_read_UINT32(s, offscreenSupportLevel); /* offscreenSupportLevel (4 bytes) */
+       stream_read_UINT16(s, offscreenCacheSize); /* offscreenCacheSize (2 bytes) */
+       stream_read_UINT16(s, offscreenCacheEntries); /* offscreenCacheEntries (2 bytes) */
+
+       printf("\toffscreenSupportLevel: 0x%08X\n", offscreenSupportLevel);
+       printf("\toffscreenCacheSize: 0x%04X\n", offscreenCacheSize);
+       printf("\toffscreenCacheEntries: 0x%04X\n", offscreenCacheEntries);
+
+       return TRUE;
+}
+
 /**
  * Read bitmap cache host support capability set.\n
  * @msdn{cc240557}
@@ -1014,14 +1540,16 @@ BOOL rdp_read_bitmap_cache_host_support_capability_set(STREAM* s, UINT16 length,
 {
        BYTE cacheVersion;
 
-       if(length < 8)
+       if (length < 8)
                return FALSE;
+
        stream_read_BYTE(s, cacheVersion); /* cacheVersion (1 byte) */
        stream_seek_BYTE(s); /* pad1 (1 byte) */
        stream_seek_UINT16(s); /* pad2 (2 bytes) */
 
        if (cacheVersion & BITMAP_CACHE_V2)
                settings->BitmapCachePersistEnabled = TRUE;
+
        return TRUE;
 }
 
@@ -1045,6 +1573,28 @@ void rdp_write_bitmap_cache_host_support_capability_set(STREAM* s, rdpSettings*
        rdp_capability_set_finish(s, header, CAPSET_TYPE_BITMAP_CACHE_HOST_SUPPORT);
 }
 
+BOOL rdp_print_bitmap_cache_host_support_capability_set(STREAM* s, UINT16 length)
+{
+       BYTE cacheVersion;
+       BYTE pad1;
+       UINT16 pad2;
+
+       printf("BitmapCacheHostSupportCapabilitySet (length %d):\n", length);
+
+       if (length < 8)
+               return FALSE;
+
+       stream_read_BYTE(s, cacheVersion); /* cacheVersion (1 byte) */
+       stream_read_BYTE(s, pad1); /* pad1 (1 byte) */
+       stream_read_UINT16(s, pad2); /* pad2 (2 bytes) */
+
+       printf("\tcacheVersion: 0x%02X\n", cacheVersion);
+       printf("\tpad1: 0x%02X\n", pad1);
+       printf("\tpad2: 0x%04X\n", pad2);
+
+       return TRUE;
+}
+
 void rdp_write_bitmap_cache_cell_info(STREAM* s, BITMAP_CACHE_V2_CELL_INFO* cellInfo)
 {
        UINT32 info;
@@ -1068,7 +1618,7 @@ void rdp_write_bitmap_cache_cell_info(STREAM* s, BITMAP_CACHE_V2_CELL_INFO* cell
 
 BOOL rdp_read_bitmap_cache_v2_capability_set(STREAM* s, UINT16 length, rdpSettings* settings)
 {
-       if(length < 40)
+       if (length < 40)
                return FALSE;
 
        stream_seek_UINT16(s); /* cacheFlags (2 bytes) */
@@ -1080,6 +1630,7 @@ BOOL rdp_read_bitmap_cache_v2_capability_set(STREAM* s, UINT16 length, rdpSettin
        stream_seek(s, 4); /* bitmapCache3CellInfo (4 bytes) */
        stream_seek(s, 4); /* bitmapCache4CellInfo (4 bytes) */
        stream_seek(s, 12); /* pad3 (12 bytes) */
+
        return TRUE;
 }
 
@@ -1115,6 +1666,26 @@ void rdp_write_bitmap_cache_v2_capability_set(STREAM* s, rdpSettings* settings)
        rdp_capability_set_finish(s, header, CAPSET_TYPE_BITMAP_CACHE_V2);
 }
 
+BOOL rdp_print_bitmap_cache_v2_capability_set(STREAM* s, UINT16 length)
+{
+       printf("BitmapCacheV2CapabilitySet (length %d):\n", length);
+
+       if (length < 40)
+               return FALSE;
+
+       stream_seek_UINT16(s); /* cacheFlags (2 bytes) */
+       stream_seek_BYTE(s); /* pad2 (1 byte) */
+       stream_seek_BYTE(s); /* numCellCaches (1 byte) */
+       stream_seek(s, 4); /* bitmapCache0CellInfo (4 bytes) */
+       stream_seek(s, 4); /* bitmapCache1CellInfo (4 bytes) */
+       stream_seek(s, 4); /* bitmapCache2CellInfo (4 bytes) */
+       stream_seek(s, 4); /* bitmapCache3CellInfo (4 bytes) */
+       stream_seek(s, 4); /* bitmapCache4CellInfo (4 bytes) */
+       stream_seek(s, 12); /* pad3 (12 bytes) */
+
+       return TRUE;
+}
+
 /**
  * Read virtual channel capability set.\n
  * @msdn{cc240551}
@@ -1128,8 +1699,9 @@ BOOL rdp_read_virtual_channel_capability_set(STREAM* s, UINT16 length, rdpSettin
        UINT32 flags;
        UINT32 VCChunkSize;
 
-       if(length < 8)
+       if (length < 8)
                return FALSE;
+
        stream_read_UINT32(s, flags); /* flags (4 bytes) */
 
        if (length > 8)
@@ -1139,6 +1711,7 @@ BOOL rdp_read_virtual_channel_capability_set(STREAM* s, UINT16 length, rdpSettin
 
        if (settings->ServerMode != TRUE)
                settings->VirtualChannelChunkSize = VCChunkSize;
+
        return TRUE;
 }
 
@@ -1164,10 +1737,33 @@ void rdp_write_virtual_channel_capability_set(STREAM* s, rdpSettings* settings)
        rdp_capability_set_finish(s, header, CAPSET_TYPE_VIRTUAL_CHANNEL);
 }
 
-/**
- * Read drawn nine grid cache capability set.\n
- * @msdn{cc241565}
- * @param s stream
+BOOL rdp_print_virtual_channel_capability_set(STREAM* s, UINT16 length)
+{
+       UINT32 flags;
+       UINT32 VCChunkSize;
+
+       printf("VirtualChannelCapabilitySet (length %d):\n", length);
+
+       if (length < 8)
+               return FALSE;
+
+       stream_read_UINT32(s, flags); /* flags (4 bytes) */
+
+       if (length > 8)
+               stream_read_UINT32(s, VCChunkSize); /* VCChunkSize (4 bytes) */
+       else
+               VCChunkSize = 1600;
+
+       printf("\tflags: 0x%08X\n", flags);
+       printf("\tVCChunkSize: 0x%08X\n", VCChunkSize);
+
+       return TRUE;
+}
+
+/**
+ * Read drawn nine grid cache capability set.\n
+ * @msdn{cc241565}
+ * @param s stream
  * @param settings settings
  * @return if the operation completed successfully
  */
@@ -1176,8 +1772,9 @@ BOOL rdp_read_draw_nine_grid_cache_capability_set(STREAM* s, UINT16 length, rdpS
 {
        UINT32 drawNineGridSupportLevel;
 
-       if(length < 12)
+       if (length < 12)
                return FALSE;
+
        stream_read_UINT32(s, drawNineGridSupportLevel); /* drawNineGridSupportLevel (4 bytes) */
        stream_read_UINT16(s, settings->DrawNineGridCacheSize); /* drawNineGridCacheSize (2 bytes) */
        stream_read_UINT16(s, settings->DrawNineGridCacheEntries); /* drawNineGridCacheEntries (2 bytes) */
@@ -1185,6 +1782,7 @@ BOOL rdp_read_draw_nine_grid_cache_capability_set(STREAM* s, UINT16 length, rdpS
        if ((drawNineGridSupportLevel & DRAW_NINEGRID_SUPPORTED) ||
                        (drawNineGridSupportLevel & DRAW_NINEGRID_SUPPORTED_V2))
                settings->DrawNineGridEnabled = TRUE;
+
        return TRUE;
 }
 
@@ -1235,6 +1833,24 @@ void rdp_write_gdiplus_image_cache_properties(STREAM* s, UINT16 oiccs, UINT16 oi
        stream_write_UINT16(s, oicms); /* gdipObjectImageCacheMaxSize (2 bytes) */
 }
 
+BOOL rdp_print_draw_nine_grid_cache_capability_set(STREAM* s, UINT16 length)
+{
+       UINT32 drawNineGridSupportLevel;
+       UINT16 DrawNineGridCacheSize;
+       UINT16 DrawNineGridCacheEntries;
+
+       printf("DrawNineGridCacheCapabilitySet (length %d):\n", length);
+
+       if (length < 12)
+               return FALSE;
+
+       stream_read_UINT32(s, drawNineGridSupportLevel); /* drawNineGridSupportLevel (4 bytes) */
+       stream_read_UINT16(s, DrawNineGridCacheSize); /* drawNineGridCacheSize (2 bytes) */
+       stream_read_UINT16(s, DrawNineGridCacheEntries); /* drawNineGridCacheEntries (2 bytes) */
+
+       return TRUE;
+}
+
 /**
  * Read GDI+ cache capability set.\n
  * @msdn{cc241566}
@@ -1248,8 +1864,9 @@ BOOL rdp_read_draw_gdiplus_cache_capability_set(STREAM* s, UINT16 length, rdpSet
        UINT32 drawGDIPlusSupportLevel;
        UINT32 drawGdiplusCacheLevel;
 
-       if(length < 40)
+       if (length < 40)
                return FALSE;
+
        stream_read_UINT32(s, drawGDIPlusSupportLevel); /* drawGDIPlusSupportLevel (4 bytes) */
        stream_seek_UINT32(s); /* GdipVersion (4 bytes) */
        stream_read_UINT32(s, drawGdiplusCacheLevel); /* drawGdiplusCacheLevel (4 bytes) */
@@ -1262,6 +1879,7 @@ BOOL rdp_read_draw_gdiplus_cache_capability_set(STREAM* s, UINT16 length, rdpSet
 
        if (drawGdiplusCacheLevel & DRAW_GDIPLUS_CACHE_LEVEL_ONE)
                settings->DrawGdiPlusCacheEnabled = TRUE;
+
        return TRUE;
 }
 
@@ -1293,6 +1911,27 @@ void rdp_write_draw_gdiplus_cache_capability_set(STREAM* s, rdpSettings* setting
        rdp_capability_set_finish(s, header, CAPSET_TYPE_DRAW_GDI_PLUS);
 }
 
+BOOL rdp_print_draw_gdiplus_cache_capability_set(STREAM* s, UINT16 length)
+{
+       UINT32 drawGdiPlusSupportLevel;
+       UINT32 GdipVersion;
+       UINT32 drawGdiplusCacheLevel;
+
+       printf("DrawGdiPlusCacheCapabilitySet (length %d):\n", length);
+
+       if (length < 40)
+               return FALSE;
+
+       stream_read_UINT32(s, drawGdiPlusSupportLevel); /* drawGdiPlusSupportLevel (4 bytes) */
+       stream_read_UINT32(s, GdipVersion); /* GdipVersion (4 bytes) */
+       stream_read_UINT32(s, drawGdiplusCacheLevel); /* drawGdiPlusCacheLevel (4 bytes) */
+       stream_seek(s, 10); /* GdipCacheEntries (10 bytes) */
+       stream_seek(s, 8); /* GdipCacheChunkSize (8 bytes) */
+       stream_seek(s, 6); /* GdipImageCacheProperties (6 bytes) */
+
+       return TRUE;
+}
+
 /**
  * Read remote programs capability set.\n
  * @msdn{cc242518}
@@ -1305,8 +1944,9 @@ BOOL rdp_read_remote_programs_capability_set(STREAM* s, UINT16 length, rdpSettin
 {
        UINT32 railSupportLevel;
 
-       if(length < 8)
+       if (length < 8)
                return FALSE;
+
        stream_read_UINT32(s, railSupportLevel); /* railSupportLevel (4 bytes) */
 
        if ((railSupportLevel & RAIL_LEVEL_SUPPORTED) == 0)
@@ -1344,6 +1984,22 @@ void rdp_write_remote_programs_capability_set(STREAM* s, rdpSettings* settings)
        rdp_capability_set_finish(s, header, CAPSET_TYPE_RAIL);
 }
 
+BOOL rdp_print_remote_programs_capability_set(STREAM* s, UINT16 length)
+{
+       UINT32 railSupportLevel;
+
+       printf("RemoteProgramsCapabilitySet (length %d):\n", length);
+
+       if (length < 8)
+               return FALSE;
+
+       stream_read_UINT32(s, railSupportLevel); /* railSupportLevel (4 bytes) */
+
+       printf("\trailSupportLevel: 0x%08X\n", railSupportLevel);
+
+       return TRUE;
+}
+
 /**
  * Read window list capability set.\n
  * @msdn{cc242564}
@@ -1354,12 +2010,13 @@ void rdp_write_remote_programs_capability_set(STREAM* s, rdpSettings* settings)
 
 BOOL rdp_read_window_list_capability_set(STREAM* s, UINT16 length, rdpSettings* settings)
 {
-       if(length < 11)
+       if (length < 11)
                return FALSE;
 
        stream_seek_UINT32(s); /* wndSupportLevel (4 bytes) */
        stream_seek_BYTE(s); /* numIconCaches (1 byte) */
        stream_seek_UINT16(s); /* numIconCacheEntries (2 bytes) */
+
        return TRUE;
 }
 
@@ -1386,6 +2043,28 @@ void rdp_write_window_list_capability_set(STREAM* s, rdpSettings* settings)
        rdp_capability_set_finish(s, header, CAPSET_TYPE_WINDOW);
 }
 
+BOOL rdp_print_window_list_capability_set(STREAM* s, UINT16 length)
+{
+       UINT32 wndSupportLevel;
+       BYTE numIconCaches;
+       UINT16 numIconCacheEntries;
+
+       printf("WindowListCapabilitySet (length %d):\n", length);
+
+       if (length < 11)
+               return FALSE;
+
+       stream_read_UINT32(s, wndSupportLevel); /* wndSupportLevel (4 bytes) */
+       stream_read_BYTE(s, numIconCaches); /* numIconCaches (1 byte) */
+       stream_read_UINT16(s, numIconCacheEntries); /* numIconCacheEntries (2 bytes) */
+
+       printf("\twndSupportLevel: 0x%08X\n", wndSupportLevel);
+       printf("\tnumIconCaches: 0x%02X\n", numIconCaches);
+       printf("\tnumIconCacheEntries: 0x%04X\n", numIconCacheEntries);
+
+       return TRUE;
+}
+
 /**
  * Read desktop composition capability set.\n
  * @msdn{cc240855}
@@ -1396,9 +2075,11 @@ void rdp_write_window_list_capability_set(STREAM* s, rdpSettings* settings)
 
 BOOL rdp_read_desktop_composition_capability_set(STREAM* s, UINT16 length, rdpSettings* settings)
 {
-       if(length < 6)
+       if (length < 6)
                return FALSE;
+
        stream_seek_UINT16(s); /* compDeskSupportLevel (2 bytes) */
+
        return TRUE;
 }
 
@@ -1423,6 +2104,22 @@ void rdp_write_desktop_composition_capability_set(STREAM* s, rdpSettings* settin
        rdp_capability_set_finish(s, header, CAPSET_TYPE_COMP_DESK);
 }
 
+BOOL rdp_print_desktop_composition_capability_set(STREAM* s, UINT16 length)
+{
+       UINT16 compDeskSupportLevel;
+
+       printf("DesktopCompositionCapabilitySet (length %d):\n", length);
+
+       if (length < 6)
+               return FALSE;
+
+       stream_read_UINT16(s, compDeskSupportLevel); /* compDeskSupportLevel (2 bytes) */
+
+       printf("\tcompDeskSupportLevel: 0x%04X\n", compDeskSupportLevel);
+
+       return TRUE;
+}
+
 /**
  * Read multifragment update capability set.\n
  * @msdn{cc240649}
@@ -1433,9 +2130,11 @@ void rdp_write_desktop_composition_capability_set(STREAM* s, rdpSettings* settin
 
 BOOL rdp_read_multifragment_update_capability_set(STREAM* s, UINT16 length, rdpSettings* settings)
 {
-       if(length < 8)
+       if (length < 8)
                return FALSE;
+
        stream_read_UINT32(s, settings->MultifragMaxRequestSize); /* MaxRequestSize (4 bytes) */
+
        return TRUE;
 }
 
@@ -1457,6 +2156,22 @@ void rdp_write_multifragment_update_capability_set(STREAM* s, rdpSettings* setti
        rdp_capability_set_finish(s, header, CAPSET_TYPE_MULTI_FRAGMENT_UPDATE);
 }
 
+BOOL rdp_print_multifragment_update_capability_set(STREAM* s, UINT16 length)
+{
+       UINT32 maxRequestSize;
+
+       printf("MultifragmentUpdateCapabilitySet (length %d):\n", length);
+
+       if (length < 8)
+               return FALSE;
+
+       stream_read_UINT32(s, maxRequestSize); /* maxRequestSize (4 bytes) */
+
+       printf("\tmaxRequestSize: 0x%04X\n", maxRequestSize);
+
+       return TRUE;
+}
+
 /**
  * Read large pointer capability set.\n
  * @msdn{cc240650}
@@ -1467,9 +2182,11 @@ void rdp_write_multifragment_update_capability_set(STREAM* s, rdpSettings* setti
 
 BOOL rdp_read_large_pointer_capability_set(STREAM* s, UINT16 length, rdpSettings* settings)
 {
-       if(length < 6)
+       if (length < 6)
                return FALSE;
+
        stream_seek_UINT16(s); /* largePointerSupportFlags (2 bytes) */
+
        return TRUE;
 }
 
@@ -1494,6 +2211,22 @@ void rdp_write_large_pointer_capability_set(STREAM* s, rdpSettings* settings)
        rdp_capability_set_finish(s, header, CAPSET_TYPE_LARGE_POINTER);
 }
 
+BOOL rdp_print_large_pointer_capability_set(STREAM* s, UINT16 length)
+{
+       UINT16 largePointerSupportFlags;
+
+       printf("LargePointerCapabilitySet (length %d):\n", length);
+
+       if (length < 6)
+               return FALSE;
+
+       stream_read_UINT16(s, largePointerSupportFlags); /* largePointerSupportFlags (2 bytes) */
+
+       printf("\tlargePointerSupportFlags: 0x%04X\n", largePointerSupportFlags);
+
+       return TRUE;
+}
+
 /**
  * Read surface commands capability set.\n
  * @msdn{dd871563}
@@ -1504,12 +2237,14 @@ void rdp_write_large_pointer_capability_set(STREAM* s, rdpSettings* settings)
 
 BOOL rdp_read_surface_commands_capability_set(STREAM* s, UINT16 length, rdpSettings* settings)
 {
-       if(length < 12)
+       if (length < 12)
                return FALSE;
+
        stream_seek_UINT32(s); /* cmdFlags (4 bytes) */
        stream_seek_UINT32(s); /* reserved (4 bytes) */
 
        settings->SurfaceCommandsEnabled = TRUE;
+
        return TRUE;
 }
 
@@ -1537,6 +2272,25 @@ void rdp_write_surface_commands_capability_set(STREAM* s, rdpSettings* settings)
        rdp_capability_set_finish(s, header, CAPSET_TYPE_SURFACE_COMMANDS);
 }
 
+BOOL rdp_print_surface_commands_capability_set(STREAM* s, UINT16 length)
+{
+       UINT32 cmdFlags;
+       UINT32 reserved;
+
+       printf("SurfaceCommandsCapabilitySet (length %d):\n", length);
+
+       if (length < 12)
+               return FALSE;
+
+       stream_read_UINT32(s, cmdFlags); /* cmdFlags (4 bytes) */
+       stream_read_UINT32(s, reserved); /* reserved (4 bytes) */
+
+       printf("\tcmdFlags: 0x%08X\n", cmdFlags);
+       printf("\treserved: 0x%08X\n", reserved);
+
+       return TRUE;
+}
+
 /**
  * Read bitmap codecs capability set.\n
  * @msdn{dd891377}
@@ -1598,6 +2352,7 @@ BOOL rdp_read_bitmap_codecs_capability_set(STREAM* s, UINT16 length, rdpSettings
 
                bitmapCodecCount--;
        }
+
        return TRUE;
 }
 
@@ -1771,6 +2526,43 @@ void rdp_write_bitmap_codecs_capability_set(STREAM* s, rdpSettings* settings)
        rdp_capability_set_finish(s, header, CAPSET_TYPE_BITMAP_CODECS);
 }
 
+BOOL rdp_print_bitmap_codecs_capability_set(STREAM* s, UINT16 length)
+{
+       BYTE bitmapCodecCount;
+       UINT16 codecPropertiesLength;
+       UINT16 remainingLength;
+
+       printf("BitmapCodecsCapabilitySet (length %d):\n", length);
+
+       if (length < 5)
+               return FALSE;
+
+       stream_read_BYTE(s, bitmapCodecCount); /* bitmapCodecCount (1 byte) */
+       remainingLength = length - 5;
+
+       while (bitmapCodecCount > 0)
+       {
+               if (remainingLength < 19)
+                       return FALSE;
+
+               stream_seek(s, 16); /* codecGUID (16 bytes) */
+               stream_seek_BYTE(s);
+
+               stream_read_UINT16(s, codecPropertiesLength); /* codecPropertiesLength (2 bytes) */
+               remainingLength -= 19;
+
+               if (remainingLength < codecPropertiesLength)
+                       return FALSE;
+
+               stream_seek(s, codecPropertiesLength); /* codecProperties */
+               remainingLength -= codecPropertiesLength;
+
+               bitmapCodecCount--;
+       }
+
+       return TRUE;
+}
+
 /**
  * Read frame acknowledge capability set.\n
  * @param s stream
@@ -1780,7 +2572,7 @@ void rdp_write_bitmap_codecs_capability_set(STREAM* s, rdpSettings* settings)
 
 BOOL rdp_read_frame_acknowledge_capability_set(STREAM* s, UINT16 length, rdpSettings* settings)
 {
-       if(length < 8)
+       if (length < 8)
                return FALSE;
 
        if (settings->ServerMode)
@@ -1794,11 +2586,50 @@ BOOL rdp_read_frame_acknowledge_capability_set(STREAM* s, UINT16 length, rdpSett
        return TRUE;
 }
 
+/**
+ * Write frame acknowledge capability set.\n
+ * @param s stream
+ * @param settings settings
+ */
+
+void rdp_write_frame_acknowledge_capability_set(STREAM* s, rdpSettings* settings)
+{
+       BYTE* header;
+       UINT32 frame_acknowledge;
+
+       header = rdp_capability_set_start(s);
+
+       frame_acknowledge = settings->FrameAcknowledge;
+       stream_write_UINT32(s, frame_acknowledge); /* (4 bytes) */
+
+       rdp_capability_set_finish(s, header, CAPSET_TYPE_FRAME_ACKNOWLEDGE);
+}
+
+BOOL rdp_print_frame_acknowledge_capability_set(STREAM* s, UINT16 length)
+{
+       UINT32 frameAcknowledge;
+
+       printf("FrameAcknowledgeCapabilitySet (length %d):\n", length);
+
+       if (length < 8)
+               return FALSE;
+
+       stream_read_UINT32(s, frameAcknowledge); /* frameAcknowledge (4 bytes) */
+
+       printf("\tframeAcknowledge: 0x%08X\n", frameAcknowledge);
+
+       return TRUE;
+}
+
 BOOL rdp_read_bitmap_cache_v3_codec_id_capability_set(STREAM* s, UINT16 length, rdpSettings* settings)
 {
-       if(length < 5)
+       BYTE bitmapCacheV3CodecId;
+
+       if (length < 5)
                return FALSE;
-       stream_seek_BYTE(s); /* (1 byte) */
+
+       stream_read_BYTE(s, bitmapCacheV3CodecId); /* bitmapCacheV3CodecId (1 byte) */
+
        return TRUE;
 }
 
@@ -1811,38 +2642,226 @@ void rdp_write_bitmap_cache_v3_codec_id_capability_set(STREAM* s, rdpSettings* s
        rdp_capability_set_finish(s, header, CAPSET_TYPE_BITMAP_CACHE_V3_CODEC_ID);
 }
 
+BOOL rdp_print_bitmap_cache_v3_codec_id_capability_set(STREAM* s, UINT16 length)
+{
+       BYTE bitmapCacheV3CodecId;
 
-/**
- * Write frame acknowledge capability set.\n
- * @param s stream
- * @param settings settings
- */
+       printf("BitmapCacheV3CodecIdCapabilitySet (length %d):\n", length);
 
-void rdp_write_frame_acknowledge_capability_set(STREAM* s, rdpSettings* settings)
+       if (length < 5)
+               return FALSE;
+
+       stream_read_BYTE(s, bitmapCacheV3CodecId); /* bitmapCacheV3CodecId (1 byte) */
+
+       printf("\tbitmapCacheV3CodecId: 0x%02X\n", bitmapCacheV3CodecId);
+
+       return TRUE;
+}
+
+BOOL rdp_print_capability_sets(STREAM* s, UINT16 numberCapabilities, BOOL receiving)
 {
-       BYTE* header;
-       UINT32 frame_acknowledge;
+       UINT16 type;
+       UINT16 length;
+       BYTE *bm, *em;
 
-       header = rdp_capability_set_start(s);
+       while (numberCapabilities > 0)
+       {
+               stream_get_mark(s, bm);
 
-       frame_acknowledge = settings->FrameAcknowledge;
-       stream_write_UINT32(s, frame_acknowledge); /* (4 bytes) */
+               rdp_read_capability_set_header(s, &length, &type);
 
-       rdp_capability_set_finish(s, header, CAPSET_TYPE_FRAME_ACKNOWLEDGE);
+               printf("%s ", receiving ? "Receiving" : "Sending");
+
+               em = bm + length;
+
+               if (stream_get_left(s) < length - 4)
+               {
+                       printf("error processing stream\n");
+                       return FALSE;
+               }
+
+               switch (type)
+               {
+                       case CAPSET_TYPE_GENERAL:
+                               if (!rdp_print_general_capability_set(s, length))
+                                       return FALSE;
+                               break;
+
+                       case CAPSET_TYPE_BITMAP:
+                               if (!rdp_print_bitmap_capability_set(s, length))
+                                       return FALSE;
+                               break;
+
+                       case CAPSET_TYPE_ORDER:
+                               if (!rdp_print_order_capability_set(s, length))
+                                       return FALSE;
+                               break;
+
+                       case CAPSET_TYPE_BITMAP_CACHE:
+                               if (!rdp_print_bitmap_cache_capability_set(s, length))
+                                       return FALSE;
+                               break;
+
+                       case CAPSET_TYPE_CONTROL:
+                               if (!rdp_print_control_capability_set(s, length))
+                                       return FALSE;
+                               break;
+
+                       case CAPSET_TYPE_ACTIVATION:
+                               if (!rdp_print_window_activation_capability_set(s, length))
+                                       return FALSE;
+                               break;
+
+                       case CAPSET_TYPE_POINTER:
+                               if (!rdp_print_pointer_capability_set(s, length))
+                                       return FALSE;
+                               break;
+
+                       case CAPSET_TYPE_SHARE:
+                               if (!rdp_print_share_capability_set(s, length))
+                                       return FALSE;
+                               break;
+
+                       case CAPSET_TYPE_COLOR_CACHE:
+                               if (!rdp_print_color_cache_capability_set(s, length))
+                                       return FALSE;
+                               break;
+
+                       case CAPSET_TYPE_SOUND:
+                               if (!rdp_print_sound_capability_set(s, length))
+                                       return FALSE;
+                               break;
+
+                       case CAPSET_TYPE_INPUT:
+                               if (!rdp_print_input_capability_set(s, length))
+                                       return FALSE;
+                               break;
+
+                       case CAPSET_TYPE_FONT:
+                               if (!rdp_print_font_capability_set(s, length))
+                                       return FALSE;
+                               break;
+
+                       case CAPSET_TYPE_BRUSH:
+                               if (!rdp_print_brush_capability_set(s, length))
+                                       return FALSE;
+                               break;
+
+                       case CAPSET_TYPE_GLYPH_CACHE:
+                               if (!rdp_print_glyph_cache_capability_set(s, length))
+                                       return FALSE;
+                               break;
+
+                       case CAPSET_TYPE_OFFSCREEN_CACHE:
+                               if (!rdp_print_offscreen_bitmap_cache_capability_set(s, length))
+                                       return FALSE;
+                               break;
+
+                       case CAPSET_TYPE_BITMAP_CACHE_HOST_SUPPORT:
+                               if (!rdp_print_bitmap_cache_host_support_capability_set(s, length))
+                                       return FALSE;
+                               break;
+
+                       case CAPSET_TYPE_BITMAP_CACHE_V2:
+                               if (!rdp_print_bitmap_cache_v2_capability_set(s, length))
+                                       return FALSE;
+                               break;
+
+                       case CAPSET_TYPE_VIRTUAL_CHANNEL:
+                               if (!rdp_print_virtual_channel_capability_set(s, length))
+                                       return FALSE;
+                               break;
+
+                       case CAPSET_TYPE_DRAW_NINE_GRID_CACHE:
+                               if (!rdp_print_draw_nine_grid_cache_capability_set(s, length))
+                                       return FALSE;
+                               break;
+
+                       case CAPSET_TYPE_DRAW_GDI_PLUS:
+                               if (!rdp_print_draw_gdiplus_cache_capability_set(s, length))
+                                       return FALSE;
+                               break;
+
+                       case CAPSET_TYPE_RAIL:
+                               if (!rdp_print_remote_programs_capability_set(s, length))
+                                       return FALSE;
+                               break;
+
+                       case CAPSET_TYPE_WINDOW:
+                               if (!rdp_print_window_list_capability_set(s, length))
+                                       return FALSE;
+                               break;
+
+                       case CAPSET_TYPE_COMP_DESK:
+                               if (!rdp_print_desktop_composition_capability_set(s, length))
+                                       return FALSE;
+                               break;
+
+                       case CAPSET_TYPE_MULTI_FRAGMENT_UPDATE:
+                               if (!rdp_print_multifragment_update_capability_set(s, length))
+                                       return FALSE;
+                               break;
+
+                       case CAPSET_TYPE_LARGE_POINTER:
+                               if (!rdp_print_large_pointer_capability_set(s, length))
+                                       return FALSE;
+                               break;
+
+                       case CAPSET_TYPE_SURFACE_COMMANDS:
+                               if (!rdp_print_surface_commands_capability_set(s, length))
+                                       return FALSE;
+                               break;
+
+                       case CAPSET_TYPE_BITMAP_CODECS:
+                               if (!rdp_print_bitmap_codecs_capability_set(s, length))
+                                       return FALSE;
+                               break;
+
+                       case CAPSET_TYPE_FRAME_ACKNOWLEDGE:
+                               if (!rdp_print_frame_acknowledge_capability_set(s, length))
+                                       return FALSE;
+                               break;
+
+                       case CAPSET_TYPE_BITMAP_CACHE_V3_CODEC_ID:
+                               if (!rdp_print_bitmap_cache_v3_codec_id_capability_set(s, length))
+                                       return FALSE;
+                               break;
+
+                       default:
+                               printf("unknown capability type %d\n", type);
+                               break;
+               }
+
+               if (s->p != em)
+               {
+                       printf("incorrect offset, type:0x%02X actual:%d expected:%d\n",
+                               type, (int) (s->p - bm), (int) (em - bm));
+               }
+
+               stream_set_mark(s, em);
+               numberCapabilities--;
+       }
+
+       return TRUE;
 }
 
 BOOL rdp_read_capability_sets(STREAM* s, rdpSettings* settings, UINT16 numberCapabilities)
 {
+       BYTE* mark;
+       UINT16 count;
        UINT16 type;
        UINT16 length;
        BYTE *bm, *em;
 
+       stream_get_mark(s, mark);
+       count = numberCapabilities;
+
        while (numberCapabilities > 0)
        {
                stream_get_mark(s, bm);
 
                rdp_read_capability_set_header(s, &length, &type);
-               //printf("%s Capability Set (0x%02X), length:%d\n", CAPSET_TYPE_STRINGS[type], type, length);
+
                settings->ReceivedCapabilities[type] = TRUE;
                em = bm + length;
 
@@ -1855,147 +2874,147 @@ BOOL rdp_read_capability_sets(STREAM* s, rdpSettings* settings, UINT16 numberCap
                switch (type)
                {
                        case CAPSET_TYPE_GENERAL:
-                               if(!rdp_read_general_capability_set(s, length, settings))
+                               if (!rdp_read_general_capability_set(s, length, settings))
                                        return FALSE;
                                break;
 
                        case CAPSET_TYPE_BITMAP:
-                               if(!rdp_read_bitmap_capability_set(s, length, settings))
+                               if (!rdp_read_bitmap_capability_set(s, length, settings))
                                        return FALSE;
                                break;
 
                        case CAPSET_TYPE_ORDER:
-                               if(!rdp_read_order_capability_set(s, length, settings))
+                               if (!rdp_read_order_capability_set(s, length, settings))
                                        return FALSE;
                                break;
 
                        case CAPSET_TYPE_BITMAP_CACHE:
-                               if(!rdp_read_bitmap_cache_capability_set(s, length, settings))
+                               if (!rdp_read_bitmap_cache_capability_set(s, length, settings))
                                        return FALSE;
                                break;
 
                        case CAPSET_TYPE_CONTROL:
-                               if(!rdp_read_control_capability_set(s, length, settings))
+                               if (!rdp_read_control_capability_set(s, length, settings))
                                        return FALSE;
                                break;
 
                        case CAPSET_TYPE_ACTIVATION:
-                               if(!rdp_read_window_activation_capability_set(s, length, settings))
+                               if (!rdp_read_window_activation_capability_set(s, length, settings))
                                        return FALSE;
                                break;
 
                        case CAPSET_TYPE_POINTER:
-                               if(!rdp_read_pointer_capability_set(s, length, settings))
+                               if (!rdp_read_pointer_capability_set(s, length, settings))
                                        return FALSE;
                                break;
 
                        case CAPSET_TYPE_SHARE:
-                               if(!rdp_read_share_capability_set(s, length, settings))
+                               if (!rdp_read_share_capability_set(s, length, settings))
                                        return FALSE;
                                break;
 
                        case CAPSET_TYPE_COLOR_CACHE:
-                               if(!rdp_read_color_cache_capability_set(s, length, settings))
+                               if (!rdp_read_color_cache_capability_set(s, length, settings))
                                        return FALSE;
                                break;
 
                        case CAPSET_TYPE_SOUND:
-                               if(!rdp_read_sound_capability_set(s, length, settings))
+                               if (!rdp_read_sound_capability_set(s, length, settings))
                                        return FALSE;
                                break;
 
                        case CAPSET_TYPE_INPUT:
-                               if(!rdp_read_input_capability_set(s, length, settings))
+                               if (!rdp_read_input_capability_set(s, length, settings))
                                        return FALSE;
                                break;
 
                        case CAPSET_TYPE_FONT:
-                               if(!rdp_read_font_capability_set(s, length, settings))
+                               if (!rdp_read_font_capability_set(s, length, settings))
                                        return FALSE;
                                break;
 
                        case CAPSET_TYPE_BRUSH:
-                               if(!rdp_read_brush_capability_set(s, length, settings))
+                               if (!rdp_read_brush_capability_set(s, length, settings))
                                        return FALSE;
                                break;
 
                        case CAPSET_TYPE_GLYPH_CACHE:
-                               if(!rdp_read_glyph_cache_capability_set(s, length, settings))
+                               if (!rdp_read_glyph_cache_capability_set(s, length, settings))
                                        return FALSE;
                                break;
 
                        case CAPSET_TYPE_OFFSCREEN_CACHE:
-                               if(!rdp_read_offscreen_bitmap_cache_capability_set(s, length, settings))
+                               if (!rdp_read_offscreen_bitmap_cache_capability_set(s, length, settings))
                                        return FALSE;
                                break;
 
                        case CAPSET_TYPE_BITMAP_CACHE_HOST_SUPPORT:
-                               if(!rdp_read_bitmap_cache_host_support_capability_set(s, length, settings))
+                               if (!rdp_read_bitmap_cache_host_support_capability_set(s, length, settings))
                                        return FALSE;
                                break;
 
                        case CAPSET_TYPE_BITMAP_CACHE_V2:
-                               if(!rdp_read_bitmap_cache_v2_capability_set(s, length, settings))
+                               if (!rdp_read_bitmap_cache_v2_capability_set(s, length, settings))
                                        return FALSE;
                                break;
 
                        case CAPSET_TYPE_VIRTUAL_CHANNEL:
-                               if(!rdp_read_virtual_channel_capability_set(s, length, settings))
+                               if (!rdp_read_virtual_channel_capability_set(s, length, settings))
                                        return FALSE;
                                break;
 
                        case CAPSET_TYPE_DRAW_NINE_GRID_CACHE:
-                               if(!rdp_read_draw_nine_grid_cache_capability_set(s, length, settings))
+                               if (!rdp_read_draw_nine_grid_cache_capability_set(s, length, settings))
                                        return FALSE;
                                break;
 
                        case CAPSET_TYPE_DRAW_GDI_PLUS:
-                               if(!rdp_read_draw_gdiplus_cache_capability_set(s, length, settings))
+                               if (!rdp_read_draw_gdiplus_cache_capability_set(s, length, settings))
                                        return FALSE;
                                break;
 
                        case CAPSET_TYPE_RAIL:
-                               if(!rdp_read_remote_programs_capability_set(s, length, settings))
+                               if (!rdp_read_remote_programs_capability_set(s, length, settings))
                                        return FALSE;
                                break;
 
                        case CAPSET_TYPE_WINDOW:
-                               if(!rdp_read_window_list_capability_set(s, length, settings))
+                               if (!rdp_read_window_list_capability_set(s, length, settings))
                                        return FALSE;
                                break;
 
                        case CAPSET_TYPE_COMP_DESK:
-                               if(!rdp_read_desktop_composition_capability_set(s, length, settings))
+                               if (!rdp_read_desktop_composition_capability_set(s, length, settings))
                                        return FALSE;
                                break;
 
                        case CAPSET_TYPE_MULTI_FRAGMENT_UPDATE:
-                               if(!rdp_read_multifragment_update_capability_set(s, length, settings))
+                               if (!rdp_read_multifragment_update_capability_set(s, length, settings))
                                        return FALSE;
                                break;
 
                        case CAPSET_TYPE_LARGE_POINTER:
-                               if(!rdp_read_large_pointer_capability_set(s, length, settings))
+                               if (!rdp_read_large_pointer_capability_set(s, length, settings))
                                        return FALSE;
                                break;
 
                        case CAPSET_TYPE_SURFACE_COMMANDS:
-                               if(!rdp_read_surface_commands_capability_set(s, length, settings))
+                               if (!rdp_read_surface_commands_capability_set(s, length, settings))
                                        return FALSE;
                                break;
 
                        case CAPSET_TYPE_BITMAP_CODECS:
-                               if(!rdp_read_bitmap_codecs_capability_set(s, length, settings))
+                               if (!rdp_read_bitmap_codecs_capability_set(s, length, settings))
                                        return FALSE;
                                break;
 
                        case CAPSET_TYPE_FRAME_ACKNOWLEDGE:
-                               if(!rdp_read_frame_acknowledge_capability_set(s, length, settings))
+                               if (!rdp_read_frame_acknowledge_capability_set(s, length, settings))
                                        return FALSE;
                                break;
 
                        case CAPSET_TYPE_BITMAP_CACHE_V3_CODEC_ID:
-                               if(!rdp_read_bitmap_cache_v3_codec_id_capability_set(s, length, settings))
+                               if (!rdp_read_bitmap_cache_v3_codec_id_capability_set(s, length, settings))
                                        return FALSE;
                                break;
 
@@ -2014,6 +3033,14 @@ BOOL rdp_read_capability_sets(STREAM* s, rdpSettings* settings, UINT16 numberCap
                numberCapabilities--;
        }
 
+#ifdef WITH_DEBUG_CAPABILITIES
+       stream_get_mark(s, em);
+       stream_set_mark(s, mark);
+       numberCapabilities = count;
+       rdp_print_capability_sets(s, numberCapabilities, TRUE);
+       stream_set_mark(s, em);
+#endif
+
        return TRUE;
 }
 
@@ -2070,13 +3097,16 @@ BOOL rdp_recv_demand_active(rdpRdp* rdp, STREAM* s)
                return FALSE;
        }
 
-       if(stream_get_left(s) < 8)
+       if (stream_get_left(s) < 8)
                return FALSE;
+
        stream_read_UINT32(s, rdp->settings->ShareId); /* shareId (4 bytes) */
        stream_read_UINT16(s, lengthSourceDescriptor); /* lengthSourceDescriptor (2 bytes) */
        stream_read_UINT16(s, lengthCombinedCapabilities); /* lengthCombinedCapabilities (2 bytes) */
+
        if (!stream_skip(s, lengthSourceDescriptor) || stream_get_left(s) < 4) /* sourceDescriptor */
                return FALSE;
+
        stream_read_UINT16(s, numberCapabilities); /* numberCapabilities (2 bytes) */
        stream_seek(s, 2); /* pad2Octets (2 bytes) */
 
@@ -2140,6 +3170,13 @@ void rdp_write_demand_active(STREAM* s, rdpSettings* settings)
        stream_set_mark(s, bm); /* go back to numberCapabilities */
        stream_write_UINT16(s, numberCapabilities); /* numberCapabilities (2 bytes) */
 
+#ifdef WITH_DEBUG_CAPABILITIES
+       stream_seek_UINT16(s);
+       rdp_print_capability_sets(s, numberCapabilities, FALSE);
+       stream_set_mark(s, bm);
+       stream_seek_UINT16(s);
+#endif
+
        stream_set_mark(s, em);
 
        stream_write_UINT32(s, 0); /* sessionId */
@@ -2177,6 +3214,7 @@ BOOL rdp_recv_confirm_active(rdpRdp* rdp, STREAM* s)
        {
                if (!rdp_read_security_header(s, &securityFlags))
                        return FALSE;
+
                if (securityFlags & SEC_ENCRYPT)
                {
                        if (!rdp_decrypt(rdp, s, length - 4, securityFlags))
@@ -2198,14 +3236,17 @@ BOOL rdp_recv_confirm_active(rdpRdp* rdp, STREAM* s)
        if (pduType != PDU_TYPE_CONFIRM_ACTIVE)
                return FALSE;
 
-       if(stream_get_left(s) < 10)
+       if (stream_get_left(s) < 10)
                return FALSE;
+
        stream_seek_UINT32(s); /* shareId (4 bytes) */
        stream_seek_UINT16(s); /* originatorId (2 bytes) */
        stream_read_UINT16(s, lengthSourceDescriptor); /* lengthSourceDescriptor (2 bytes) */
        stream_read_UINT16(s, lengthCombinedCapabilities); /* lengthCombinedCapabilities (2 bytes) */
-       if(stream_get_left(s) < lengthSourceDescriptor+4)
+
+       if (stream_get_left(s) < lengthSourceDescriptor + 4)
                return FALSE;
+
        stream_seek(s, lengthSourceDescriptor); /* sourceDescriptor */
        stream_read_UINT16(s, numberCapabilities); /* numberCapabilities (2 bytes) */
        stream_seek(s, 2); /* pad2Octets (2 bytes) */
@@ -2334,6 +3375,13 @@ void rdp_write_confirm_active(STREAM* s, rdpSettings* settings)
        stream_set_mark(s, bm); /* go back to numberCapabilities */
        stream_write_UINT16(s, numberCapabilities); /* numberCapabilities (2 bytes) */
 
+#ifdef WITH_DEBUG_CAPABILITIES
+       stream_seek_UINT16(s);
+       rdp_print_capability_sets(s, numberCapabilities, FALSE);
+       stream_set_mark(s, bm);
+       stream_seek_UINT16(s);
+#endif
+
        stream_set_mark(s, em);
 }
 
index c835f74..e1a634e 100644 (file)
@@ -59,6 +59,9 @@ int connectErrorCode;
 #define ERRINFO_RPC_INITIATED_DISCONNECT_BY_USER_STRING \
                "The disconnection was initiated by an administrative tool on the server running in the user's session."
 
+#define ERRINFO_LOGOFF_BY_USER_STRING \
+               "The disconnection was initiated by the user logging off his or her session on the server."
+
 /* Protocol-independent licensing codes */
 
 #define ERRINFO_LICENSE_INTERNAL_STRING \
@@ -351,6 +354,7 @@ static const ERRINFO ERRINFO_CODES[] =
                ERRINFO_DEFINE(SERVER_INSUFFICIENT_PRIVILEGES),
                ERRINFO_DEFINE(SERVER_FRESH_CREDENTIALS_REQUIRED),
                ERRINFO_DEFINE(RPC_INITIATED_DISCONNECT_BY_USER),
+               ERRINFO_DEFINE(LOGOFF_BY_USER),
 
                /* Protocol-independent licensing codes */
                ERRINFO_DEFINE(LICENSE_INTERNAL),
index 755ea7c..aab6ff3 100644 (file)
@@ -33,6 +33,7 @@
 #define ERRINFO_SERVER_INSUFFICIENT_PRIVILEGES                 0x00000009
 #define ERRINFO_SERVER_FRESH_CREDENTIALS_REQUIRED              0x0000000A
 #define ERRINFO_RPC_INITIATED_DISCONNECT_BY_USER               0x0000000B
+#define ERRINFO_LOGOFF_BY_USER                                 0x0000000C
 
 /* Protocol-independent licensing codes */
 #define        ERRINFO_LICENSE_INTERNAL                                0x00000100