s->p += len;
}
-void rdp_send_bitmap_update(void)
+void rdp_send_bitmap_update(unsigned x, unsigned y, unsigned width, unsigned height, unsigned char *data)
{
STREAM s;
- static unsigned int x = 1, y = 1;
- x += 2;
- if (x > 300) {
- x = 2;
- y += 2;
- }
+ int length = 10*2 + width*height*3 + 5 + 3;
+
+ s = rdp5_init(length, 1);
+
+ out_uint8(s, 3); // ??
+ out_uint16_le(s, 0); // length
+
+ out_uint8(s, 1); // process bitmap update
+ out_uint16_le(s, 10*2 + width*height*3 + 2); // RDP5 chunk length
+ out_uint16_le(s, 10*2 + width*height*3); // part length
- s = rdp_init_data(11*2 + 2*2*3);
- out_uint16_le(s, RDP_UPDATE_BITMAP);
out_uint16_le(s, 1); // one update
out_uint16_le(s, x); // left, top, right, bottom
out_uint16_le(s, y);
- out_uint16_le(s, x+2);
- out_uint16_le(s, y+2);
- out_uint16_le(s, 2); // width, height
- out_uint16_le(s, 2);
+ out_uint16_le(s, x+width);
+ out_uint16_le(s, y+height);
+ out_uint16_le(s, width); // width, height
+ out_uint16_le(s, height);
out_uint16_le(s, 24); // bpp
out_uint16_le(s, 0); // no compression
- out_uint16_le(s, 2*2*3); // bufsize
+ out_uint16_le(s, width*height*3); // bufsize
- out_uint8(s, 255);
- out_uint8(s, 0);
- out_uint8(s, 0);
-
- out_uint8(s, 0);
- out_uint8(s, 255);
- out_uint8(s, 0);
-
- out_uint8(s, 0);
- out_uint8(s, 0);
- out_uint8(s, 255);
-
- out_uint8(s, 255);
- out_uint8(s, 255);
- out_uint8(s, 255);
+ out_uint8p(s, data, width*height*3);
s_mark_end(s);
- rdp_send_data(s, RDP_DATA_PDU_UPDATE);
+ rdp5_send(s, 1);
}
+#define EXPECT16(value) { in_uint16_le(s, unknown); if (unknown != (value)) printf("Unknown value on code line %u; expected 0x%x, got 0x%x\n", __LINE__, (value), unknown); }
+#define EXPECT32(value) { in_uint32_le(s, unknown); if (unknown != (value)) printf("Unknown value on code line %u; expected 0x%x, got 0x%x\n", __LINE__, (value), unknown); }
void
rdp_get_logon_info(STREAM s)
{
- uint32 flags;
- int len_domain, len_user, len_password, len_program, len_directory;
- char domain[256], user[256], password[256], program[256], directory[256]; // FIXME
+ uint32 flags, unknown;
+ uint16 tzone_major, tzone_minor;
+ int len_domain, len_user, len_password, len_program, len_directory, len_ip, len_dll;
+ char domain[256], user[256], password[256], program[256], directory[256], ip[256], dll[256], tz1[256], tz2[256]; // FIXME
- in_uint32_le(s, flags); // unknown
+ in_uint32_le(s, unknown);
in_uint32_le(s, flags);
-
- if (flags & RDP_LOGON_BLOB)
- error("got RDP5-style logon packet, can't handle this yet");
-
+
printf("logon flags: %x\n", flags);
- in_uint16_le(s, len_domain);
- in_uint16_le(s, len_user);
- in_uint16_le(s, len_password);
- in_uint16_le(s, len_program);
- in_uint16_le(s, len_directory);
- rdp_in_unistr(s, domain, len_domain);
- rdp_in_unistr(s, user, len_user);
- rdp_in_unistr(s, password, len_password);
- rdp_in_unistr(s, program, len_program);
- rdp_in_unistr(s, directory, len_directory);
-
- printf("domain='%s'\n", domain);
- printf("user='%s'\n", user);
- printf("password='%s'\n", password);
- printf("program='%s'\n", program);
- printf("directory='%s'\n", directory);
-
- if (!s_check_end(s))
- error("Unknown data at end of logon packet!");
+ if (flags & RDP_LOGON_BLOB) {
+ printf("RDP5-style logon packet\n");
+
+ in_uint16_le(s, len_domain);
+ in_uint16_le(s, len_user);
+
+ if (flags & RDP_LOGON_AUTO) {
+ in_uint16_le(s, len_password);
+ } else {
+ strcpy(password, "<none>");
+ }
+ if (flags & RDP_LOGON_BLOB && !(flags & RDP_LOGON_AUTO)) {
+ // is this too some kind of length?
+ EXPECT16(0);
+ }
+ in_uint16_le(s, len_program);
+ in_uint16_le(s, len_directory);
+
+ rdp_in_unistr(s, domain, len_domain);
+ rdp_in_unistr(s, user, len_user);
+
+ if (flags & RDP_LOGON_AUTO)
+ rdp_in_unistr(s, password, len_password);
+
+ if (flags & RDP_LOGON_BLOB && !(flags & RDP_LOGON_AUTO))
+ EXPECT16(0);
+
+ rdp_in_unistr(s, program, len_program);
+ rdp_in_unistr(s, directory, len_directory);
+
+ EXPECT16(2);
+
+ in_uint16_le(s, len_ip);
+ rdp_in_unistr(s, ip, len_ip - 2);
+
+ in_uint16_le(s, len_dll);
+ rdp_in_unistr(s, dll, len_dll - 2);
+
+ in_uint16_le(s, tzone_major);
+ in_uint16_le(s, tzone_minor);
+
+ // time zone names?
+ rdp_in_unistr(s, tz1, 62);
+ EXPECT32(0x0a0000);
+ EXPECT32(0x050000);
+ EXPECT32(3);
+ EXPECT32(0);
+ EXPECT32(0);
+
+ rdp_in_unistr(s, tz2, 62);
+ EXPECT32(0x030000);
+ EXPECT32(0x050000);
+ EXPECT32(2);
+ EXPECT32(0);
+ EXPECT32(0xffffffc4);
+ EXPECT32(0xfffffffe);
+ EXPECT32(0x0f);
+ EXPECT32(0);
+
+ printf("domain='%s'\n", domain);
+ printf("user='%s'\n", user);
+ printf("password='%s'\n", password);
+ printf("program='%s'\n", program);
+ printf("directory='%s'\n", directory);
+ printf("ip='%s'\n", ip);
+ printf("dll='%s'\n", dll);
+ printf("timezone=%d:%02d\n", tzone_major, tzone_minor);
+ printf("tz1='%64s'\n", tz1);
+ printf("tz2='%64s'\n", tz2);
+ } else {
+ in_uint16_le(s, len_domain);
+ in_uint16_le(s, len_user);
+ in_uint16_le(s, len_password);
+ in_uint16_le(s, len_program);
+ in_uint16_le(s, len_directory);
+ rdp_in_unistr(s, domain, len_domain);
+ rdp_in_unistr(s, user, len_user);
+ rdp_in_unistr(s, password, len_password);
+ rdp_in_unistr(s, program, len_program);
+ rdp_in_unistr(s, directory, len_directory);
+
+ printf("domain='%s'\n", domain);
+ printf("user='%s'\n", user);
+ printf("password='%s'\n", password);
+ printf("program='%s'\n", program);
+ printf("directory='%s'\n", directory);
+ }
+
+ if (!s_check_end(s)) {
+ printf("Unknown data at end of logon packet!\n");
+ }
}
/* Send a control PDU */
-static void
+void
rdp_send_control(uint16 action)
{
STREAM s;
}
/* Send a synchronisation PDU */
-static void
-rdp_send_synchronise(void)
+void
+rdp_send_synchronise(uint16 id)
{
STREAM s;
s = rdp_init_data(4);
out_uint16_le(s, 1); /* type */
- out_uint16_le(s, 1002);
+ out_uint16_le(s, id);
s_mark_end(s);
rdp_send_data(s, RDP_DATA_PDU_SYNCHRONISE);