rail: fixed sending of actual PDUs

This commit is contained in:
Marc-André Moreau
2011-08-10 18:08:44 -04:00
parent d9b7d29e3d
commit e5a3355099
5 changed files with 131 additions and 24 deletions

View File

@@ -24,6 +24,7 @@
#include <freerdp/constants.h>
#include <freerdp/types.h>
#include <freerdp/utils/memory.h>
#include <freerdp/utils/unicode.h>
#include <freerdp/utils/svc_plugin.h>
#include <freerdp/rail.h>
@@ -76,6 +77,20 @@ void init_rail_string(RAIL_STRING * rail_string, const char * string)
rail_string->length = strlen(string) + 1;
}
void rail_string_to_unicode_string(rdpRail* rail, char* string, UNICODE_STRING* unicode_string)
{
char* buffer;
size_t length = 0;
unicode_string->string = NULL;
unicode_string->length = 0;
buffer = freerdp_uniconv_out(rail->uniconv, string, &length);
unicode_string->string = (uint8*) buffer;
unicode_string->length = (uint16) length;
}
void rail_string2unicode_string(RAIL_SESSION* session, RAIL_STRING* string, UNICODE_STRING* unicode_string)
{
size_t result_length = 0;
@@ -119,6 +134,9 @@ RAIL_SESSION* rail_core_session_new(RAIL_VCHANNEL_DATA_SENDER* data_sender, RAIL
self->data_sender = data_sender;
self->event_sender = event_sender;
self->uniconv = freerdp_uniconv_new();
self->rail = rail_new();
self->rail->data_sender = data_sender;
self->rail->event_sender = event_sender;
}
return self;
@@ -128,6 +146,7 @@ void rail_core_session_free(RAIL_SESSION* rail_session)
{
if (rail_session != NULL)
{
rail_free(rail_session->rail);
freerdp_uniconv_free(rail_session->uniconv);
xfree(rail_session);
}
@@ -150,6 +169,26 @@ void rail_core_handle_server_handshake(RAIL_SESSION* session, uint32 build_numbe
DEBUG_RAIL("rail_core_handle_server_handshake: session=0x%p buildNumber=0x%X.", session, build_number);
#if 1
session->rail->handshake.buildNumber = 0x00001DB0;
rail_send_handshake_order(session->rail);
session->rail->client_status.flags = RAIL_CLIENTSTATUS_ALLOWLOCALMOVESIZE;
rail_send_client_status_order(session->rail);
session->rail->exec.flags =
RAIL_EXEC_FLAG_EXPAND_WORKINGDIRECTORY |
RAIL_EXEC_FLAG_EXPAND_ARGUMENTS;
rail_string_to_unicode_string(session->rail, "||firefox", &session->rail->exec.exeOrFile);
rail_string_to_unicode_string(session->rail, "", &session->rail->exec.workingDir);
rail_string_to_unicode_string(session->rail, "", &session->rail->exec.arguments);
//rail_send_client_exec_order(session->rail);
rail_core_send_client_execute(session, False, "||firefox", "", "");
#else
// Step 1. Send Handshake PDU (2.2.2.2.1)
// Fixed: MS-RDPERP 1.3.2.1 is not correct!
rail_vchannel_send_handshake_order(session, client_build_number);
@@ -168,6 +207,7 @@ void rail_core_handle_server_handshake(RAIL_SESSION* session, uint32 build_numbe
// will be processed after Destop Sync processed.
// So maybe send after receive Destop Sync sequence?
rail_core_send_client_execute(session, False, "||firefox", "", "");
#endif
}
void rail_core_handle_exec_result(RAIL_SESSION* session, uint16 flags, uint16 exec_result, uint32 raw_result, UNICODE_STRING* exe_or_file)
@@ -203,6 +243,20 @@ void rail_core_handle_server_sysparam(RAIL_SESSION* session, RAIL_SERVER_SYSPARA
session, sysparam->type, sysparam->value.screen_saver_enabled,
sysparam->value.screen_saver_lock_enabled);
#if 1
session->rail->sysparam.systemParam = SPI_SET_DRAG_FULL_WINDOWS;
session->rail->sysparam.value = True;
session->rail->sysparam.systemParam = SPI_SET_KEYBOARD_CUES;
session->rail->sysparam.value = False;
session->rail->sysparam.systemParam = SPI_SET_KEYBOARD_PREF;
session->rail->sysparam.value = False;
session->rail->sysparam.systemParam = SPI_SET_MOUSE_BUTTON_SWAP;
session->rail->sysparam.value = False;
#else
init_vchannel_event(&event, RAIL_VCHANNEL_EVENT_SERVER_SYSPARAM_RECEIVED);
event.param.server_param_info.param_type = sysparam->type;
event.param.server_param_info.screen_saver_enabled =
@@ -212,6 +266,7 @@ void rail_core_handle_server_sysparam(RAIL_SESSION* session, RAIL_SERVER_SYSPARA
((sysparam->value.screen_saver_lock_enabled != 0) ? True: False);
session->event_sender->send_rail_vchannel_event(session->event_sender->event_sender_object, &event);
#endif
}
void rail_core_handle_server_movesize(RAIL_SESSION* session, uint32 window_id,
@@ -311,8 +366,6 @@ void rail_core_send_client_execute(RAIL_SESSION* session,
UNICODE_STRING arguments;
uint16 flags;
DEBUG_RAIL("RAIL_ORDER_EXEC");
init_rail_string(&exe_or_file_, rail_exe_or_file);
init_rail_string(&working_directory_, rail_working_directory);
init_rail_string(&arguments_, rail_arguments);

View File

@@ -29,6 +29,12 @@
#include <assert.h>
#include <freerdp/utils/debug.h>
typedef struct _RAIL_SESSION RAIL_SESSION;
typedef struct _RAIL_VCHANNEL_DATA_SENDER RAIL_VCHANNEL_DATA_SENDER;
typedef struct _RAIL_VCHANNEL_EVENT_SENDER RAIL_VCHANNEL_EVENT_SENDER;
#include "rail_orders.h"
#define WITH_DEBUG_RAIL 1
#ifdef WITH_DEBUG_RAIL
@@ -86,22 +92,20 @@ struct _RAIL_VCHANNEL_DATA_SENDER
void* data_sender_object;
void (*send_rail_vchannel_data)(void* sender_object, void* data, size_t length);
};
typedef struct _RAIL_VCHANNEL_DATA_SENDER RAIL_VCHANNEL_DATA_SENDER;
struct _RAIL_VCHANNEL_EVENT_SENDER
{
void * event_sender_object;
void (*send_rail_vchannel_event)(void* ui_event_sender_object, RAIL_VCHANNEL_EVENT* event);
};
typedef struct _RAIL_VCHANNEL_EVENT_SENDER RAIL_VCHANNEL_EVENT_SENDER;
struct _RAIL_SESSION
{
rdpRail* rail;
UNICONV* uniconv;
RAIL_VCHANNEL_DATA_SENDER* data_sender;
RAIL_VCHANNEL_EVENT_SENDER* event_sender;
};
typedef struct _RAIL_SESSION RAIL_SESSION;
RAIL_SESSION* rail_core_session_new(RAIL_VCHANNEL_DATA_SENDER *data_sender, RAIL_VCHANNEL_EVENT_SENDER *event_sender);
void rail_core_session_free(RAIL_SESSION * rail_session);

View File

@@ -22,6 +22,43 @@
#include "rail_orders.h"
#define RAIL_ORDER_TYPE_EXEC 0x0001
#define RAIL_ORDER_TYPE_ACTIVATE 0x0002
#define RAIL_ORDER_TYPE_SYSPARAM 0x0003
#define RAIL_ORDER_TYPE_SYSCOMMAND 0x0004
#define RAIL_ORDER_TYPE_HANDSHAKE 0x0005
#define RAIL_ORDER_TYPE_NOTIFY_EVENT 0x0006
#define RAIL_ORDER_TYPE_WINDOW_MOVE 0x0008
#define RAIL_ORDER_TYPE_LOCALMOVESIZE 0x0009
#define RAIL_ORDER_TYPE_MINMAXINFO 0x000A
#define RAIL_ORDER_TYPE_CLIENT_STATUS 0x000B
#define RAIL_ORDER_TYPE_SYSMENU 0x000C
#define RAIL_ORDER_TYPE_LANGBAR_INFO 0x000D
#define RAIL_ORDER_TYPE_EXEC_RESULT 0x0080
#define RAIL_ORDER_TYPE_GET_APPID_REQ 0x000E
#define RAIL_ORDER_TYPE_GET_APPID_RESP 0x000F
uint8 RAIL_ORDER_TYPE_STRINGS[][32] =
{
"",
"Execute",
"Activate",
"System Parameters Update",
"System Command",
"Handshake",
"Notify Event",
"",
"Window Move",
"Local Move/Size",
"Min Max Info",
"Client Status",
"System Menu",
"Language Bar Info",
"Get Application ID Request",
"Get Application ID Response",
"Execute Result"
};
void rail_read_pdu_header(STREAM* s, uint16* orderType, uint16* orderLength)
{
stream_read_uint16(s, *orderType); /* orderType (2 bytes) */
@@ -42,7 +79,7 @@ STREAM* rail_pdu_init(int length)
return s;
}
void rail_send_pdu(STREAM* s, uint16 orderType)
void rail_send_pdu(rdpRail* rail, STREAM* s, uint16 orderType)
{
uint16 orderLength;
@@ -53,6 +90,10 @@ void rail_send_pdu(STREAM* s, uint16 orderType)
stream_set_pos(s, orderLength);
/* send */
printf("Sending %s PDU, length:%d\n",
RAIL_ORDER_TYPE_STRINGS[((orderType & 0xF0) >> 3) + orderType], orderLength);
rail->data_sender->send_rail_vchannel_data(rail->data_sender->data_sender_object, s->data, orderLength);
}
void rail_write_high_contrast(STREAM* s, HIGH_CONTRAST* high_contrast)
@@ -139,9 +180,9 @@ void rail_write_client_exec_order(STREAM* s, RAIL_EXEC_ORDER* exec)
stream_write_uint16(s, exec->exeOrFile.length); /* exeOrFileLength (2 bytes) */
stream_write_uint16(s, exec->workingDir.length); /* workingDirLength (2 bytes) */
stream_write_uint16(s, exec->arguments.length); /* argumentsLength (2 bytes) */
rail_write_unicode_string_value(s, exec->exeOrFile); /* exeOrFile */
rail_write_unicode_string_value(s, exec->workingDir); /* workingDir */
rail_write_unicode_string_value(s, exec->arguments); /* arguments */
rail_write_unicode_string_value(s, &exec->exeOrFile); /* exeOrFile */
rail_write_unicode_string_value(s, &exec->workingDir); /* workingDir */
rail_write_unicode_string_value(s, &exec->arguments); /* arguments */
}
void rail_write_client_sysparam_order(STREAM* s, RAIL_SYSPARAM_ORDER* sysparam)
@@ -227,6 +268,9 @@ void rail_order_recv(rdpRail* rail, STREAM* s)
rail_read_pdu_header(s, &orderType, &orderLength);
printf("Received %s PDU, length:%d\n",
RAIL_ORDER_TYPE_STRINGS[((orderType & 0xF0) >> 3) + orderType], orderLength);
switch (orderType)
{
case RDP_RAIL_ORDER_HANDSHAKE:
@@ -267,7 +311,7 @@ void rail_send_handshake_order(rdpRail* rail)
STREAM* s;
s = rail_pdu_init(RAIL_HANDSHAKE_ORDER_LENGTH);
rail_write_handshake_order(s, &rail->handshake);
rail_send_pdu(s, RAIL_ORDER_TYPE_HANDSHAKE);
rail_send_pdu(rail, s, RAIL_ORDER_TYPE_HANDSHAKE);
}
void rail_send_client_status_order(rdpRail* rail)
@@ -275,7 +319,7 @@ void rail_send_client_status_order(rdpRail* rail)
STREAM* s;
s = rail_pdu_init(RAIL_CLIENT_STATUS_ORDER_LENGTH);
rail_write_client_status_order(s, &rail->client_status);
rail_send_pdu(s, RAIL_ORDER_TYPE_CLIENT_STATUS);
rail_send_pdu(rail, s, RAIL_ORDER_TYPE_CLIENT_STATUS);
}
void rail_send_client_exec_order(rdpRail* rail)
@@ -285,12 +329,12 @@ void rail_send_client_exec_order(rdpRail* rail)
length = RAIL_EXEC_ORDER_LENGTH +
rail->exec.exeOrFile.length +
rail->exec.workingDir.length;
rail->exec.workingDir.length +
rail->exec.arguments.length;
s = rail_pdu_init(RAIL_EXEC_ORDER_LENGTH);
rail_write_exec_order(s, &rail->exec);
rail_send_pdu(s, RAIL_ORDER_TYPE_EXEC);
rail_write_client_exec_order(s, &rail->exec);
rail_send_pdu(rail, s, RAIL_ORDER_TYPE_EXEC);
}
void rail_send_client_sysparam_order(rdpRail* rail)
@@ -322,7 +366,7 @@ void rail_send_client_sysparam_order(rdpRail* rail)
s = rail_pdu_init(RAIL_SYSPARAM_ORDER_LENGTH);
rail_write_sysparam_order(s, &rail->sysparam);
rail_send_pdu(s, RAIL_ORDER_TYPE_SYSPARAM);
rail_send_pdu(rail, s, RAIL_ORDER_TYPE_SYSPARAM);
}
void rail_send_client_activate_order(rdpRail* rail)
@@ -330,7 +374,7 @@ void rail_send_client_activate_order(rdpRail* rail)
STREAM* s;
s = rail_pdu_init(RAIL_ACTIVATE_ORDER_LENGTH);
rail_write_activate_order(s, &rail->activate);
rail_send_pdu(s, RAIL_ORDER_TYPE_ACTIVATE);
rail_send_pdu(rail, s, RAIL_ORDER_TYPE_ACTIVATE);
}
void rail_send_client_sysmenu_order(rdpRail* rail)
@@ -338,7 +382,7 @@ void rail_send_client_sysmenu_order(rdpRail* rail)
STREAM* s;
s = rail_pdu_init(RAIL_SYSMENU_ORDER_LENGTH);
rail_write_sysmenu_order(s, &rail->sysmenu);
rail_send_pdu(s, RAIL_ORDER_TYPE_SYSMENU);
rail_send_pdu(rail, s, RAIL_ORDER_TYPE_SYSMENU);
}
void rail_send_client_syscommand_order(rdpRail* rail)
@@ -346,7 +390,7 @@ void rail_send_client_syscommand_order(rdpRail* rail)
STREAM* s;
s = rail_pdu_init(RAIL_SYSCOMMAND_ORDER_LENGTH);
rail_write_syscommand_order(s, &rail->syscommand);
rail_send_pdu(s, RAIL_ORDER_TYPE_SYSCOMMAND);
rail_send_pdu(rail, s, RAIL_ORDER_TYPE_SYSCOMMAND);
}
void rail_send_client_notify_event_order(rdpRail* rail)
@@ -354,7 +398,7 @@ void rail_send_client_notify_event_order(rdpRail* rail)
STREAM* s;
s = rail_pdu_init(RAIL_NOTIFY_EVENT_ORDER_LENGTH);
rail_write_notify_event_order(s, &rail->notify_event);
rail_send_pdu(s, RAIL_ORDER_TYPE_NOTIFY_EVENT);
rail_send_pdu(rail, s, RAIL_ORDER_TYPE_NOTIFY_EVENT);
}
void rail_send_client_window_move_order(rdpRail* rail)
@@ -362,7 +406,7 @@ void rail_send_client_window_move_order(rdpRail* rail)
STREAM* s;
s = rail_pdu_init(RAIL_WINDOW_MOVE_ORDER_LENGTH);
rail_write_window_move_order(s, &rail->window_move);
rail_send_pdu(s, RAIL_ORDER_TYPE_WINDOW_MOVE);
rail_send_pdu(rail, s, RAIL_ORDER_TYPE_WINDOW_MOVE);
}
void rail_send_client_get_appid_req_order(rdpRail* rail)
@@ -370,7 +414,7 @@ void rail_send_client_get_appid_req_order(rdpRail* rail)
STREAM* s;
s = rail_pdu_init(RAIL_GET_APPID_REQ_ORDER_LENGTH);
rail_write_window_move_order(s, &rail->get_appid_req);
rail_send_pdu(s, RAIL_ORDER_TYPE_GET_APPID_REQ);
rail_send_pdu(rail, s, RAIL_ORDER_TYPE_GET_APPID_REQ);
}
void rail_send_client_langbar_info_order(rdpRail* rail)
@@ -378,7 +422,7 @@ void rail_send_client_langbar_info_order(rdpRail* rail)
STREAM* s;
s = rail_pdu_init(RAIL_LANGBAR_INFO_ORDER_LENGTH);
rail_write_window_move_order(s, &rail->langbar_info);
rail_send_pdu(s, RAIL_ORDER_TYPE_LANGBAR_INFO);
rail_send_pdu(rail, s, RAIL_ORDER_TYPE_LANGBAR_INFO);
}
rdpRail* rail_new()

View File

@@ -21,6 +21,10 @@
#ifndef __RAIL_ORDERS_H
#define __RAIL_ORDERS_H
typedef struct rdp_rail rdpRail;
#include "rail_core.h"
#include <freerdp/rail.h>
#include <freerdp/utils/stream.h>
@@ -42,8 +46,9 @@ struct rdp_rail
RAIL_LANGBAR_INFO_ORDER langbar_info;
RAIL_GET_APPID_REQ_ORDER get_appid_req;
RAIL_GET_APPID_RESP_ORDER get_appid_resp;
RAIL_VCHANNEL_DATA_SENDER* data_sender;
RAIL_VCHANNEL_EVENT_SENDER* event_sender;
};
typedef struct rdp_rail rdpRail;
#define RAIL_ORDER_TYPE_EXEC 0x0001
#define RAIL_ORDER_TYPE_ACTIVATE 0x0002

View File

@@ -55,7 +55,8 @@ void rail_write_unicode_string(STREAM* s, UNICODE_STRING* unicode_string)
void rail_write_unicode_string_value(STREAM* s, UNICODE_STRING* unicode_string)
{
stream_write(s, unicode_string->string, unicode_string->length); /* string */
if (unicode_string->length > 0)
stream_write(s, unicode_string->string, unicode_string->length); /* string */
}
void rail_read_rectangle_16(STREAM* s, RECTANGLE_16* rectangle_16)