#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",
"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"
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}
header = rdp_capability_set_start(s);
drawingFlags |= DRAW_ALLOW_SKIP_ALPHA;
+ drawingFlags |= DRAW_ALLOW_COLOR_SUBSAMPLING;
if (settings->RdpVersion > 5)
preferredBitsPerPixel = settings->ColorDepth;
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}
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) */
settings->OrderSupport[i] = FALSE;
}
- /* pad4octetsB (4 bytes) */
- /* desktopSaveSize (4 bytes) */
- /* pad2octetsC (2 bytes) */
- /* pad2octetsD (2 bytes) */
- /* textANSICodePage (2 bytes) */
- /* pad2octetsE (2 bytes) */
return TRUE;
}
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}
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) */
stream_seek_UINT16(s); /* Cache1MaximumCellSize (2 bytes) */
stream_seek_UINT16(s); /* Cache2Entries (2 bytes) */
stream_seek_UINT16(s); /* Cache2MaximumCellSize (2 bytes) */
+
return TRUE;
}
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}
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;
}
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}
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;
}
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}
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) */
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}
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;
}
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}
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;
}
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}
{
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;
}
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}
{
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) */
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}
if (length > 6)
stream_seek_UINT16(s); /* pad2Octets (2 bytes) */
+
return TRUE;
}
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}
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;
}
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}
{
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;
}
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) */
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}
{
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;
}
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}
{
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;
}
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;
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) */
stream_seek(s, 4); /* bitmapCache3CellInfo (4 bytes) */
stream_seek(s, 4); /* bitmapCache4CellInfo (4 bytes) */
stream_seek(s, 12); /* pad3 (12 bytes) */
+
return TRUE;
}
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}
UINT32 flags;
UINT32 VCChunkSize;
- if(length < 8)
+ if (length < 8)
return FALSE;
+
stream_read_UINT32(s, flags); /* flags (4 bytes) */
if (length > 8)
if (settings->ServerMode != TRUE)
settings->VirtualChannelChunkSize = VCChunkSize;
+
return TRUE;
}
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
*/
{
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) */
if ((drawNineGridSupportLevel & DRAW_NINEGRID_SUPPORTED) ||
(drawNineGridSupportLevel & DRAW_NINEGRID_SUPPORTED_V2))
settings->DrawNineGridEnabled = TRUE;
+
return TRUE;
}
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}
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) */
if (drawGdiplusCacheLevel & DRAW_GDIPLUS_CACHE_LEVEL_ONE)
settings->DrawGdiPlusCacheEnabled = TRUE;
+
return TRUE;
}
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}
{
UINT32 railSupportLevel;
- if(length < 8)
+ if (length < 8)
return FALSE;
+
stream_read_UINT32(s, railSupportLevel); /* railSupportLevel (4 bytes) */
if ((railSupportLevel & RAIL_LEVEL_SUPPORTED) == 0)
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}
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;
}
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}
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;
}
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}
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;
}
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}
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;
}
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}
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;
}
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}
bitmapCodecCount--;
}
+
return TRUE;
}
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
BOOL rdp_read_frame_acknowledge_capability_set(STREAM* s, UINT16 length, rdpSettings* settings)
{
- if(length < 8)
+ if (length < 8)
return FALSE;
if (settings->ServerMode)
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;
}
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;
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;
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;
}
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) */
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 */
{
if (!rdp_read_security_header(s, &securityFlags))
return FALSE;
+
if (securityFlags & SEC_ENCRYPT)
{
if (!rdp_decrypt(rdp, s, length - 4, securityFlags))
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) */
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);
}