xfreerdp: initial remote assistance controls (ctrl+alt+c to request/release control)
This commit is contained in:
parent
5606c64f61
commit
e42465372a
@ -21,6 +21,9 @@
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/print.h>
|
||||
|
||||
#include <freerdp/client/encomsp.h>
|
||||
|
||||
#include "encomsp_main.h"
|
||||
@ -32,6 +35,30 @@ EncomspClientContext* encomsp_get_client_interface(encomspPlugin* encomsp)
|
||||
return pInterface;
|
||||
}
|
||||
|
||||
int encomsp_virtual_channel_write(encomspPlugin* encomsp, wStream* s)
|
||||
{
|
||||
UINT32 status = 0;
|
||||
|
||||
if (!encomsp)
|
||||
return -1;
|
||||
|
||||
#if 0
|
||||
printf("EncomspWrite (%d)\n", Stream_Length(s));
|
||||
winpr_HexDump(Stream_Buffer(s), Stream_Length(s));
|
||||
#endif
|
||||
|
||||
status = encomsp->channelEntryPoints.pVirtualChannelWrite(encomsp->OpenHandle,
|
||||
Stream_Buffer(s), (UINT32) Stream_Length(s), s);
|
||||
|
||||
if (status != CHANNEL_RC_OK)
|
||||
{
|
||||
fprintf(stderr, "encomsp_virtual_channel_write: VirtualChannelWrite failed %d\n", status);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int encomsp_read_header(wStream* s, ENCOMSP_ORDER_HEADER* header)
|
||||
{
|
||||
if (Stream_GetRemainingLength(s) < ENCOMSP_ORDER_HEADER_SIZE)
|
||||
@ -43,6 +70,14 @@ int encomsp_read_header(wStream* s, ENCOMSP_ORDER_HEADER* header)
|
||||
return 1;
|
||||
}
|
||||
|
||||
int encomsp_write_header(wStream* s, ENCOMSP_ORDER_HEADER* header)
|
||||
{
|
||||
Stream_Write_UINT16(s, header->Type); /* Type (2 bytes) */
|
||||
Stream_Write_UINT16(s, header->Length); /* Length (2 bytes) */
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int encomsp_read_unicode_string(wStream* s, ENCOMSP_UNICODE_STRING* str)
|
||||
{
|
||||
ZeroMemory(str, sizeof(ENCOMSP_UNICODE_STRING));
|
||||
@ -449,6 +484,30 @@ int encomsp_recv_change_participant_control_level_pdu(encomspPlugin* encomsp, wS
|
||||
return 1;
|
||||
}
|
||||
|
||||
int encomsp_send_change_participant_control_level_pdu(EncomspClientContext* context, ENCOMSP_CHANGE_PARTICIPANT_CONTROL_LEVEL_PDU* pdu)
|
||||
{
|
||||
wStream* s;
|
||||
encomspPlugin* encomsp;
|
||||
|
||||
encomsp = (encomspPlugin*) context->handle;
|
||||
|
||||
pdu->Type = ODTYPE_PARTICIPANT_CTRL_CHANGED;
|
||||
pdu->Length = ENCOMSP_ORDER_HEADER_SIZE + 6;
|
||||
|
||||
s = Stream_New(NULL, pdu->Length);
|
||||
|
||||
encomsp_write_header(s, (ENCOMSP_ORDER_HEADER*) pdu);
|
||||
|
||||
Stream_Write_UINT16(s, pdu->Flags); /* Flags (2 bytes) */
|
||||
Stream_Write_UINT32(s, pdu->ParticipantId); /* ParticipantId (4 bytes) */
|
||||
|
||||
Stream_SealLength(s);
|
||||
|
||||
encomsp_virtual_channel_write(encomsp, s);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int encomsp_recv_graphics_stream_paused_pdu(encomspPlugin* encomsp, wStream* s, ENCOMSP_ORDER_HEADER* header)
|
||||
{
|
||||
int beg, end;
|
||||
@ -531,6 +590,8 @@ static int encomsp_process_receive(encomspPlugin* encomsp, wStream* s)
|
||||
if (encomsp_read_header(s, &header) < 0)
|
||||
return -1;
|
||||
|
||||
//printf("EncomspReceive: Type: %d Length: %d\n", header.Type, header.Length);
|
||||
|
||||
switch (header.Type)
|
||||
{
|
||||
case ODTYPE_FILTER_STATE_UPDATED:
|
||||
@ -866,7 +927,7 @@ BOOL VCAPITYPE VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints)
|
||||
context->ShowWindow = NULL;
|
||||
context->ParticipantCreated = NULL;
|
||||
context->ParticipantRemoved = NULL;
|
||||
context->ChangeParticipantControlLevel = NULL;
|
||||
context->ChangeParticipantControlLevel = encomsp_send_change_participant_control_level_pdu;
|
||||
context->GraphicsStreamPaused = NULL;
|
||||
context->GraphicsStreamResumed = NULL;
|
||||
|
||||
@ -878,6 +939,9 @@ BOOL VCAPITYPE VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints)
|
||||
encomsp->channelEntryPoints.pVirtualChannelInit(&encomsp->InitHandle,
|
||||
&encomsp->channelDef, 1, VIRTUAL_CHANNEL_VERSION_WIN2000, encomsp_virtual_channel_init_event);
|
||||
|
||||
encomsp->channelEntryPoints.pInterface = *(encomsp->channelEntryPoints.ppInterface);
|
||||
encomsp->channelEntryPoints.ppInterface = &(encomsp->channelEntryPoints.pInterface);
|
||||
|
||||
encomsp_add_init_handle_data(encomsp->InitHandle, (void*) encomsp);
|
||||
|
||||
return 1;
|
||||
|
@ -44,9 +44,6 @@ int remdesk_virtual_channel_write(remdeskPlugin* remdesk, wStream* s)
|
||||
if (!remdesk)
|
||||
return -1;
|
||||
|
||||
printf("RemdeskWrite (%d)\n", Stream_Length(s));
|
||||
winpr_HexDump(Stream_Buffer(s), Stream_Length(s));
|
||||
|
||||
status = remdesk->channelEntryPoints.pVirtualChannelWrite(remdesk->OpenHandle,
|
||||
Stream_Buffer(s), (UINT32) Stream_Length(s), s);
|
||||
|
||||
@ -176,8 +173,6 @@ int remdesk_prepare_ctl_header(REMDESK_CTL_HEADER* ctlHeader, UINT32 msgType, UI
|
||||
|
||||
int remdesk_recv_ctl_server_announce_pdu(remdeskPlugin* remdesk, wStream* s, REMDESK_CHANNEL_HEADER* header)
|
||||
{
|
||||
printf("RemdeskServerAnnounce\n");
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -192,9 +187,6 @@ int remdesk_recv_ctl_version_info_pdu(remdeskPlugin* remdesk, wStream* s, REMDES
|
||||
Stream_Read_UINT32(s, versionMajor); /* versionMajor (4 bytes) */
|
||||
Stream_Read_UINT32(s, versionMinor); /* versionMinor (4 bytes) */
|
||||
|
||||
printf("RemdeskVersionInfo: versionMajor: 0x%04X versionMinor: 0x%04X\n",
|
||||
versionMajor, versionMinor);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -233,7 +225,7 @@ int remdesk_recv_result_pdu(remdeskPlugin* remdesk, wStream* s, REMDESK_CHANNEL_
|
||||
|
||||
*pResult = result;
|
||||
|
||||
printf("RemdeskRecvResult: 0x%04X\n", result);
|
||||
//printf("RemdeskRecvResult: 0x%04X\n", result);
|
||||
|
||||
return 1;
|
||||
}
|
||||
@ -404,7 +396,7 @@ int remdesk_recv_ctl_pdu(remdeskPlugin* remdesk, wStream* s, REMDESK_CHANNEL_HEA
|
||||
|
||||
Stream_Read_UINT32(s, msgType); /* msgType (4 bytes) */
|
||||
|
||||
printf("msgType: %d\n", msgType);
|
||||
//printf("msgType: %d\n", msgType);
|
||||
|
||||
switch (msgType)
|
||||
{
|
||||
@ -482,8 +474,10 @@ int remdesk_process_receive(remdeskPlugin* remdesk, wStream* s)
|
||||
int status = 1;
|
||||
REMDESK_CHANNEL_HEADER header;
|
||||
|
||||
#if 0
|
||||
printf("RemdeskReceive: %d\n", Stream_GetRemainingLength(s));
|
||||
winpr_HexDump(Stream_Pointer(s), Stream_GetRemainingLength(s));
|
||||
#endif
|
||||
|
||||
remdesk_read_channel_header(s, &header);
|
||||
|
||||
@ -521,8 +515,6 @@ int remdesk_process_receive(remdeskPlugin* remdesk, wStream* s)
|
||||
|
||||
static void remdesk_process_connect(remdeskPlugin* remdesk)
|
||||
{
|
||||
printf("RemdeskProcessConnect\n");
|
||||
|
||||
remdesk->settings = (rdpSettings*) remdesk->channelEntryPoints.pExtendedData;
|
||||
}
|
||||
|
||||
@ -803,6 +795,9 @@ BOOL VCAPITYPE VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints)
|
||||
remdesk->channelEntryPoints.pVirtualChannelInit(&remdesk->InitHandle,
|
||||
&remdesk->channelDef, 1, VIRTUAL_CHANNEL_VERSION_WIN2000, remdesk_virtual_channel_init_event);
|
||||
|
||||
remdesk->channelEntryPoints.pInterface = *(remdesk->channelEntryPoints.ppInterface);
|
||||
remdesk->channelEntryPoints.ppInterface = &(remdesk->channelEntryPoints.pInterface);
|
||||
|
||||
remdesk_add_init_handle_data(remdesk->InitHandle, (void*) remdesk);
|
||||
|
||||
return 1;
|
||||
|
@ -40,6 +40,10 @@ void xf_OnChannelConnectedEventHandler(rdpContext* context, ChannelConnectedEven
|
||||
{
|
||||
xf_graphics_pipeline_init(xfc, (RdpgfxClientContext*) e->pInterface);
|
||||
}
|
||||
else if (strcmp(e->name, ENCOMSP_SVC_CHANNEL_NAME) == 0)
|
||||
{
|
||||
xf_encomsp_init(xfc, (EncomspClientContext*) e->pInterface);
|
||||
}
|
||||
}
|
||||
|
||||
void xf_OnChannelDisconnectedEventHandler(rdpContext* context, ChannelDisconnectedEventArgs* e)
|
||||
@ -54,4 +58,8 @@ void xf_OnChannelDisconnectedEventHandler(rdpContext* context, ChannelDisconnect
|
||||
{
|
||||
xf_graphics_pipeline_uninit(xfc, (RdpgfxClientContext*) e->pInterface);
|
||||
}
|
||||
else if (strcmp(e->name, ENCOMSP_SVC_CHANNEL_NAME) == 0)
|
||||
{
|
||||
xf_encomsp_uninit(xfc, (EncomspClientContext*) e->pInterface);
|
||||
}
|
||||
}
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include <freerdp/client/channels.h>
|
||||
#include <freerdp/client/rdpei.h>
|
||||
#include <freerdp/client/rdpgfx.h>
|
||||
#include <freerdp/client/encomsp.h>
|
||||
|
||||
int xf_on_channel_connected(freerdp* instance, const char* name, void* pInterface);
|
||||
int xf_on_channel_disconnected(freerdp* instance, const char* name, void* pInterface);
|
||||
|
@ -468,7 +468,7 @@ void xf_create_window(xfContext *xfc)
|
||||
}
|
||||
}
|
||||
|
||||
void xf_toggle_fullscreen(xfContext *xfc)
|
||||
void xf_toggle_fullscreen(xfContext* xfc)
|
||||
{
|
||||
Pixmap contents = 0;
|
||||
WindowStateChangeEventArgs e;
|
||||
@ -486,6 +486,53 @@ void xf_toggle_fullscreen(xfContext *xfc)
|
||||
PubSub_OnWindowStateChange(((rdpContext *) xfc)->pubSub, xfc, &e);
|
||||
}
|
||||
|
||||
void xf_toggle_control(xfContext* xfc)
|
||||
{
|
||||
EncomspClientContext* encomsp;
|
||||
ENCOMSP_CHANGE_PARTICIPANT_CONTROL_LEVEL_PDU pdu;
|
||||
|
||||
encomsp = xfc->encomsp;
|
||||
|
||||
if (!encomsp)
|
||||
return;
|
||||
|
||||
pdu.ParticipantId = 0;
|
||||
pdu.Flags = ENCOMSP_REQUEST_VIEW;
|
||||
|
||||
if (!xfc->controlToggle)
|
||||
pdu.Flags |= ENCOMSP_REQUEST_INTERACT;
|
||||
|
||||
encomsp->ChangeParticipantControlLevel(encomsp, &pdu);
|
||||
|
||||
xfc->controlToggle = !xfc->controlToggle;
|
||||
}
|
||||
|
||||
int xf_encomsp_participant_created(EncomspClientContext* context, ENCOMSP_PARTICIPANT_CREATED_PDU* participantCreated)
|
||||
{
|
||||
#if 0
|
||||
xfContext* xfc = (xfContext*) context->custom;
|
||||
|
||||
printf("ParticipantCreated: ParticipantId: %d GroupId: %d Flags: 0x%04X xfc: %p\n",
|
||||
(int) participantCreated->ParticipantId, (int) participantCreated->GroupId,
|
||||
(int) participantCreated->Flags, xfc);
|
||||
#endif
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void xf_encomsp_init(xfContext* xfc, EncomspClientContext* encomsp)
|
||||
{
|
||||
xfc->encomsp = encomsp;
|
||||
encomsp->custom = (void*) xfc;
|
||||
|
||||
encomsp->ParticipantCreated = xf_encomsp_participant_created;
|
||||
}
|
||||
|
||||
void xf_encomsp_uninit(xfContext* xfc, EncomspClientContext* encomsp)
|
||||
{
|
||||
xfc->encomsp = NULL;
|
||||
}
|
||||
|
||||
void xf_lock_x11(xfContext *xfc, BOOL display)
|
||||
{
|
||||
if(!xfc->UseXThreads)
|
||||
|
@ -415,6 +415,16 @@ BOOL xf_keyboard_handle_special_keys(xfContext* xfc, KeySym keysym)
|
||||
}
|
||||
}
|
||||
|
||||
if ((keysym == XK_c) || (keysym == XK_C))
|
||||
{
|
||||
if (mod.Ctrl && mod.Alt)
|
||||
{
|
||||
/* Ctrl-Alt-C: toggle control */
|
||||
xf_toggle_control(xfc);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (keysym == XK_period)
|
||||
{
|
||||
if (mod.Ctrl && mod.Alt)
|
||||
|
@ -137,6 +137,7 @@ struct xf_context
|
||||
BOOL mouse_active;
|
||||
BOOL suppress_output;
|
||||
BOOL fullscreen_toggle;
|
||||
BOOL controlToggle;
|
||||
UINT32 KeyboardLayout;
|
||||
BOOL KeyboardState[256];
|
||||
XModifierKeymap* modifierMap;
|
||||
@ -182,12 +183,17 @@ struct xf_context
|
||||
/* Channels */
|
||||
RdpeiClientContext* rdpei;
|
||||
RdpgfxClientContext* gfx;
|
||||
EncomspClientContext* encomsp;
|
||||
};
|
||||
|
||||
void xf_create_window(xfContext* xfc);
|
||||
void xf_toggle_fullscreen(xfContext* xfc);
|
||||
void xf_toggle_control(xfContext* xfc);
|
||||
BOOL xf_post_connect(freerdp* instance);
|
||||
|
||||
void xf_encomsp_init(xfContext* xfc, EncomspClientContext* encomsp);
|
||||
void xf_encomsp_uninit(xfContext* xfc, EncomspClientContext* encomsp);
|
||||
|
||||
enum XF_EXIT_CODE
|
||||
{
|
||||
/* section 0-15: protocol-independent codes */
|
||||
|
@ -112,7 +112,7 @@ int freerdp_assistance_crypt_derive_key_sha1(BYTE* hash, int hashLength, BYTE* k
|
||||
return 1;
|
||||
}
|
||||
|
||||
int freerdp_assistance_parse_connection_string1(rdpAssistanceFile* file)
|
||||
int freerdp_assistance_parse_address_list(rdpAssistanceFile* file, char* list)
|
||||
{
|
||||
int i;
|
||||
char* p;
|
||||
@ -120,7 +120,71 @@ int freerdp_assistance_parse_connection_string1(rdpAssistanceFile* file)
|
||||
char* str;
|
||||
int count;
|
||||
int length;
|
||||
char* list;
|
||||
char** tokens;
|
||||
|
||||
count = 1;
|
||||
str = _strdup(list);
|
||||
|
||||
if (!str)
|
||||
return -1;
|
||||
|
||||
length = strlen(str);
|
||||
|
||||
for (i = 0; i < length; i++)
|
||||
{
|
||||
if (str[i] == ';')
|
||||
count++;
|
||||
}
|
||||
|
||||
tokens = (char**) malloc(sizeof(char*) * count);
|
||||
|
||||
count = 0;
|
||||
tokens[count++] = str;
|
||||
|
||||
for (i = 0; i < length; i++)
|
||||
{
|
||||
if (str[i] == ';')
|
||||
{
|
||||
str[i] = '\0';
|
||||
tokens[count++] = &str[i + 1];
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
length = strlen(tokens[i]);
|
||||
|
||||
if (length > 8)
|
||||
{
|
||||
if (strncmp(tokens[i], "169.254.", 8) == 0)
|
||||
continue;
|
||||
}
|
||||
|
||||
p = tokens[i];
|
||||
|
||||
q = strchr(p, ':');
|
||||
|
||||
if (!q)
|
||||
return -1;
|
||||
|
||||
q[0] = '\0';
|
||||
q++;
|
||||
|
||||
file->MachineAddress = _strdup(p);
|
||||
file->MachinePort = (UINT32) atoi(q);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int freerdp_assistance_parse_connection_string1(rdpAssistanceFile* file)
|
||||
{
|
||||
int i;
|
||||
char* str;
|
||||
int count;
|
||||
int length;
|
||||
char* tokens[8];
|
||||
|
||||
/**
|
||||
@ -182,25 +246,7 @@ int freerdp_assistance_parse_connection_string1(rdpAssistanceFile* file)
|
||||
if (!file->RASpecificParams)
|
||||
return -1;
|
||||
|
||||
list = tokens[2];
|
||||
|
||||
q = strchr(list, ';');
|
||||
|
||||
if (q)
|
||||
q[0] = '\0';
|
||||
|
||||
p = list;
|
||||
|
||||
q = strchr(p, ':');
|
||||
|
||||
if (!q)
|
||||
return -1;
|
||||
|
||||
q[0] = '\0';
|
||||
q++;
|
||||
|
||||
file->MachineAddress = _strdup(p);
|
||||
file->MachinePort = (UINT32) atoi(q);
|
||||
freerdp_assistance_parse_address_list(file, tokens[2]);
|
||||
|
||||
free(str);
|
||||
|
||||
@ -374,9 +420,6 @@ BYTE* freerdp_assistance_encrypt_pass_stub(const char* password, const char* pas
|
||||
*((UINT32*) pbIn) = cbPassStubW;
|
||||
CopyMemory(&pbIn[4], PassStubW, cbPassStubW);
|
||||
|
||||
printf("PlainBlob (%d)\n", EncryptedSize);
|
||||
winpr_HexDump(pbIn, EncryptedSize);
|
||||
|
||||
EVP_CIPHER_CTX_init(&rc4Ctx);
|
||||
|
||||
status = EVP_EncryptInit_ex(&rc4Ctx, EVP_rc4(), NULL, NULL, NULL);
|
||||
@ -416,9 +459,6 @@ BYTE* freerdp_assistance_encrypt_pass_stub(const char* password, const char* pas
|
||||
|
||||
EVP_CIPHER_CTX_cleanup(&rc4Ctx);
|
||||
|
||||
printf("EncryptedBlob (%d):\n", EncryptedSize);
|
||||
winpr_HexDump(pbOut, EncryptedSize);
|
||||
|
||||
free(pbIn);
|
||||
free(PasswordW);
|
||||
free(PassStubW);
|
||||
|
Loading…
x
Reference in New Issue
Block a user