mirror of
https://github.com/morgan9e/FreeRDP
synced 2026-04-15 00:44:19 +09:00
rail: fixed sending of actual PDUs
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user