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;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
wStream* data_out;
|
||||
int error;
|
||||
int status;
|
||||
|
||||
DEBUG_DVC("Sp=%d cbChId=%d", Sp, cbChId);
|
||||
|
||||
Stream_Seek(s, 1); /* pad */
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
error = svc_plugin_send((rdpSvcPlugin*) drdynvc, data_out);
|
||||
status = drdynvc_send_capability_response(drdynvc);
|
||||
|
||||
if (error != CHANNEL_RC_OK)
|
||||
{
|
||||
DEBUG_WARN("VirtualChannelWrite failed %d", error);
|
||||
return 1;
|
||||
}
|
||||
drdynvc->channel_error = status;
|
||||
|
||||
drdynvc->channel_error = error;
|
||||
drdynvc->state = DRDYNVC_STATE_READY;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -219,6 +232,19 @@ static int drdynvc_process_create_request(drdynvcPlugin* drdynvc, int Sp, int cb
|
||||
wStream* data_out;
|
||||
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);
|
||||
pos = Stream_GetPosition(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);
|
||||
|
||||
drdynvc->state = DRDYNVC_STATE_CAPABILITIES;
|
||||
}
|
||||
|
||||
static void drdynvc_process_event(rdpSvcPlugin* plugin, wMessage* event)
|
||||
@ -419,8 +447,7 @@ BOOL VCAPITYPE VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints)
|
||||
DrdynvcClientContext* context;
|
||||
CHANNEL_ENTRY_POINTS_FREERDP* pEntryPointsEx;
|
||||
|
||||
_p = (drdynvcPlugin*) malloc(sizeof(drdynvcPlugin));
|
||||
ZeroMemory(_p, sizeof(drdynvcPlugin));
|
||||
_p = (drdynvcPlugin*) calloc(1, sizeof(drdynvcPlugin));
|
||||
|
||||
_p->plugin.channel_def.options =
|
||||
CHANNEL_OPTION_INITIALIZED |
|
||||
@ -429,6 +456,8 @@ BOOL VCAPITYPE VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints)
|
||||
|
||||
strcpy(_p->plugin.channel_def.name, "drdynvc");
|
||||
|
||||
_p->state = DRDYNVC_STATE_INITIAL;
|
||||
|
||||
_p->plugin.connect_callback = drdynvc_process_connect;
|
||||
_p->plugin.receive_callback = drdynvc_process_receive;
|
||||
_p->plugin.event_callback = drdynvc_process_event;
|
||||
|
@ -26,6 +26,17 @@
|
||||
#include <freerdp/client/drdynvc.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 DATA_FIRST_PDU 0x02
|
||||
#define DATA_PDU 0x03
|
||||
@ -38,6 +49,7 @@ struct drdynvc_plugin
|
||||
{
|
||||
rdpSvcPlugin plugin;
|
||||
|
||||
DRDYNVC_STATE state;
|
||||
DrdynvcClientContext* context;
|
||||
|
||||
int version;
|
||||
|
Loading…
Reference in New Issue
Block a user