channels/drdynvc: add state machine, add workaround for missing capabilities pdu
This commit is contained in:
parent
8ea161de61
commit
3d7524cac9
@ -153,12 +153,32 @@ int drdynvc_push_event(drdynvcPlugin* drdynvc, wMessage* event)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int drdynvc_send_capability_response(drdynvcPlugin* drdynvc)
|
||||||
|
{
|
||||||
|
int status;
|
||||||
|
wStream* data_out;
|
||||||
|
|
||||||
|
data_out = Stream_New(NULL, 4);
|
||||||
|
Stream_Write_UINT16(data_out, 0x0050); /* Cmd+Sp+cbChId+Pad. Note: MSTSC sends 0x005c */
|
||||||
|
Stream_Write_UINT16(data_out, drdynvc->version);
|
||||||
|
|
||||||
|
status = svc_plugin_send((rdpSvcPlugin*) drdynvc, data_out);
|
||||||
|
|
||||||
|
if (status != CHANNEL_RC_OK)
|
||||||
|
{
|
||||||
|
DEBUG_WARN("VirtualChannelWrite failed %d", status);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
static int drdynvc_process_capability_request(drdynvcPlugin* drdynvc, int Sp, int cbChId, wStream* s)
|
static int drdynvc_process_capability_request(drdynvcPlugin* drdynvc, int Sp, int cbChId, wStream* s)
|
||||||
{
|
{
|
||||||
wStream* data_out;
|
int status;
|
||||||
int error;
|
|
||||||
|
|
||||||
DEBUG_DVC("Sp=%d cbChId=%d", Sp, cbChId);
|
DEBUG_DVC("Sp=%d cbChId=%d", Sp, cbChId);
|
||||||
|
|
||||||
Stream_Seek(s, 1); /* pad */
|
Stream_Seek(s, 1); /* pad */
|
||||||
Stream_Read_UINT16(s, drdynvc->version);
|
Stream_Read_UINT16(s, drdynvc->version);
|
||||||
|
|
||||||
@ -173,18 +193,11 @@ static int drdynvc_process_capability_request(drdynvcPlugin* drdynvc, int Sp, in
|
|||||||
Stream_Read_UINT16(s, drdynvc->PriorityCharge3);
|
Stream_Read_UINT16(s, drdynvc->PriorityCharge3);
|
||||||
}
|
}
|
||||||
|
|
||||||
data_out = Stream_New(NULL, 4);
|
status = drdynvc_send_capability_response(drdynvc);
|
||||||
Stream_Write_UINT16(data_out, 0x0050); /* Cmd+Sp+cbChId+Pad. Note: MSTSC sends 0x005c */
|
|
||||||
Stream_Write_UINT16(data_out, drdynvc->version);
|
|
||||||
error = svc_plugin_send((rdpSvcPlugin*) drdynvc, data_out);
|
|
||||||
|
|
||||||
if (error != CHANNEL_RC_OK)
|
drdynvc->channel_error = status;
|
||||||
{
|
|
||||||
DEBUG_WARN("VirtualChannelWrite failed %d", error);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
drdynvc->channel_error = error;
|
drdynvc->state = DRDYNVC_STATE_READY;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -219,6 +232,19 @@ static int drdynvc_process_create_request(drdynvcPlugin* drdynvc, int Sp, int cb
|
|||||||
wStream* data_out;
|
wStream* data_out;
|
||||||
int channel_status;
|
int channel_status;
|
||||||
|
|
||||||
|
if (drdynvc->state == DRDYNVC_STATE_CAPABILITIES)
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* For some reason the server does not always send the
|
||||||
|
* capabilities pdu as it should. When this happens,
|
||||||
|
* send a capabilities response.
|
||||||
|
*/
|
||||||
|
|
||||||
|
drdynvc->version = 3;
|
||||||
|
drdynvc_send_capability_response(drdynvc);
|
||||||
|
drdynvc->state = DRDYNVC_STATE_READY;
|
||||||
|
}
|
||||||
|
|
||||||
ChannelId = drdynvc_read_variable_uint(s, cbChId);
|
ChannelId = drdynvc_read_variable_uint(s, cbChId);
|
||||||
pos = Stream_GetPosition(s);
|
pos = Stream_GetPosition(s);
|
||||||
DEBUG_DVC("ChannelId=%d ChannelName=%s", ChannelId, Stream_Pointer(s));
|
DEBUG_DVC("ChannelId=%d ChannelName=%s", ChannelId, Stream_Pointer(s));
|
||||||
@ -381,6 +407,8 @@ static void drdynvc_process_connect(rdpSvcPlugin* plugin)
|
|||||||
}
|
}
|
||||||
|
|
||||||
dvcman_init(drdynvc->channel_mgr);
|
dvcman_init(drdynvc->channel_mgr);
|
||||||
|
|
||||||
|
drdynvc->state = DRDYNVC_STATE_CAPABILITIES;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void drdynvc_process_event(rdpSvcPlugin* plugin, wMessage* event)
|
static void drdynvc_process_event(rdpSvcPlugin* plugin, wMessage* event)
|
||||||
@ -419,8 +447,7 @@ BOOL VCAPITYPE VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints)
|
|||||||
DrdynvcClientContext* context;
|
DrdynvcClientContext* context;
|
||||||
CHANNEL_ENTRY_POINTS_FREERDP* pEntryPointsEx;
|
CHANNEL_ENTRY_POINTS_FREERDP* pEntryPointsEx;
|
||||||
|
|
||||||
_p = (drdynvcPlugin*) malloc(sizeof(drdynvcPlugin));
|
_p = (drdynvcPlugin*) calloc(1, sizeof(drdynvcPlugin));
|
||||||
ZeroMemory(_p, sizeof(drdynvcPlugin));
|
|
||||||
|
|
||||||
_p->plugin.channel_def.options =
|
_p->plugin.channel_def.options =
|
||||||
CHANNEL_OPTION_INITIALIZED |
|
CHANNEL_OPTION_INITIALIZED |
|
||||||
@ -429,6 +456,8 @@ BOOL VCAPITYPE VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints)
|
|||||||
|
|
||||||
strcpy(_p->plugin.channel_def.name, "drdynvc");
|
strcpy(_p->plugin.channel_def.name, "drdynvc");
|
||||||
|
|
||||||
|
_p->state = DRDYNVC_STATE_INITIAL;
|
||||||
|
|
||||||
_p->plugin.connect_callback = drdynvc_process_connect;
|
_p->plugin.connect_callback = drdynvc_process_connect;
|
||||||
_p->plugin.receive_callback = drdynvc_process_receive;
|
_p->plugin.receive_callback = drdynvc_process_receive;
|
||||||
_p->plugin.event_callback = drdynvc_process_event;
|
_p->plugin.event_callback = drdynvc_process_event;
|
||||||
|
@ -26,6 +26,17 @@
|
|||||||
#include <freerdp/client/drdynvc.h>
|
#include <freerdp/client/drdynvc.h>
|
||||||
#include <freerdp/utils/svc_plugin.h>
|
#include <freerdp/utils/svc_plugin.h>
|
||||||
|
|
||||||
|
enum _DRDYNVC_STATE
|
||||||
|
{
|
||||||
|
DRDYNVC_STATE_INITIAL,
|
||||||
|
DRDYNVC_STATE_CAPABILITIES,
|
||||||
|
DRDYNVC_STATE_READY,
|
||||||
|
DRDYNVC_STATE_OPENING_CHANNEL,
|
||||||
|
DRDYNVC_STATE_SEND_RECEIVE,
|
||||||
|
DRDYNVC_STATE_FINAL
|
||||||
|
};
|
||||||
|
typedef enum _DRDYNVC_STATE DRDYNVC_STATE;
|
||||||
|
|
||||||
#define CREATE_REQUEST_PDU 0x01
|
#define CREATE_REQUEST_PDU 0x01
|
||||||
#define DATA_FIRST_PDU 0x02
|
#define DATA_FIRST_PDU 0x02
|
||||||
#define DATA_PDU 0x03
|
#define DATA_PDU 0x03
|
||||||
@ -38,6 +49,7 @@ struct drdynvc_plugin
|
|||||||
{
|
{
|
||||||
rdpSvcPlugin plugin;
|
rdpSvcPlugin plugin;
|
||||||
|
|
||||||
|
DRDYNVC_STATE state;
|
||||||
DrdynvcClientContext* context;
|
DrdynvcClientContext* context;
|
||||||
|
|
||||||
int version;
|
int version;
|
||||||
|
Loading…
Reference in New Issue
Block a user