38
36
#define CLOSE_REQUEST_PDU 0x04
39
37
#define CAPABILITY_REQUEST_PDU 0x05
43
struct data_in_item * next;
48
39
struct drdynvc_plugin
50
rdpChanPlugin chan_plugin;
52
CHANNEL_ENTRY_POINTS ep;
53
CHANNEL_DEF channel_def;
58
struct wait_obj * term_event;
59
struct wait_obj * data_in_event;
60
struct data_in_item * in_list_head;
61
struct data_in_item * in_list_tail;
62
/* for locking the linked list */
63
pthread_mutex_t * in_mutex;
66
44
int PriorityCharge0;
67
45
int PriorityCharge1;
68
46
int PriorityCharge2;
69
47
int PriorityCharge3;
71
IWTSVirtualChannelManager * channel_mgr;
49
IWTSVirtualChannelManager* channel_mgr;
79
hexdump(char* p, int len)
86
line = (unsigned char*)p;
90
printf("%04x ", offset);
91
thisline = len - offset;
96
for (i = 0; i < thisline; i++)
98
printf("%02x ", line[i]);
104
for (i = 0; i < thisline; i++)
106
printf("%c", (line[i] >= 0x20 && line[i] < 0x7f) ? line[i] : '.');
114
#define hexdump(p,len)
118
set_variable_uint(uint32 val, char * data, uint32 * pos)
52
static int drdynvc_write_variable_uint(STREAM* stream, uint32 val)
125
SET_UINT8(data, *pos, val);
59
stream_write_uint8(stream, val);
128
61
else if (val <= 0xFFFF)
131
SET_UINT16(data, *pos, val);
64
stream_write_uint16(stream, val);
137
SET_UINT32(data, *pos, val);
69
stream_write_uint32(stream, val);
144
drdynvc_write_data(drdynvcPlugin * plugin, uint32 ChannelId, char * data, uint32 data_size)
74
int drdynvc_write_data(drdynvcPlugin* drdynvc, uint32 ChannelId, uint8* data, uint32 data_size)
150
char * out_data = NULL;
154
LLOGLN(10, ("drdynvc_write_data: ChannelId=%d size=%d", ChannelId, data_size));
156
out_data = (char *) malloc(CHANNEL_CHUNK_LENGTH);
157
memset(out_data, 0, CHANNEL_CHUNK_LENGTH);
159
cbChId = set_variable_uint(ChannelId, out_data, &pos);
83
DEBUG_DVC("ChannelId=%d size=%d", ChannelId, data_size);
85
data_out = stream_new(CHANNEL_CHUNK_LENGTH);
86
stream_set_pos(data_out, 1);
87
cbChId = drdynvc_write_variable_uint(data_out, ChannelId);
161
89
if (data_size <= CHANNEL_CHUNK_LENGTH - pos)
163
SET_UINT8(out_data, 0, 0x30 | cbChId);
164
memcpy(out_data + pos, data, data_size);
165
hexdump(out_data, data_size + pos);
166
error = plugin->ep.pVirtualChannelWrite(plugin->open_handle,
167
out_data, data_size + pos, out_data);
91
pos = stream_get_pos(data_out);
92
stream_set_pos(data_out, 0);
93
stream_write_uint8(data_out, 0x30 | cbChId);
94
stream_set_pos(data_out, pos);
95
stream_write(data_out, data, data_size);
96
error = svc_plugin_send((rdpSvcPlugin*)drdynvc, data_out);
171
100
/* Fragment the data */
172
cbLen = set_variable_uint(data_size, out_data, &pos);
173
SET_UINT8(out_data, 0, 0x20 | cbChId | (cbLen << 2));
174
data_pos = CHANNEL_CHUNK_LENGTH - pos;
175
memcpy(out_data + pos, data, data_pos);
176
hexdump(out_data, CHANNEL_CHUNK_LENGTH);
177
error = plugin->ep.pVirtualChannelWrite(plugin->open_handle,
178
out_data, CHANNEL_CHUNK_LENGTH, out_data);
101
cbLen = drdynvc_write_variable_uint(data_out, data_size);
102
pos = stream_get_pos(data_out);
103
stream_set_pos(data_out, 0);
104
stream_write_uint8(data_out, 0x20 | cbChId | (cbLen << 2));
105
stream_set_pos(data_out, pos);
106
chunk_len = CHANNEL_CHUNK_LENGTH - pos;
107
stream_write(data_out, data, chunk_len);
109
data_size -= chunk_len;
110
error = svc_plugin_send((rdpSvcPlugin*)drdynvc, data_out);
180
while (error == CHANNEL_RC_OK && data_pos < data_size)
112
while (error == CHANNEL_RC_OK && data_size > 0)
182
out_data = (char *) malloc(CHANNEL_CHUNK_LENGTH);
183
memset(out_data, 0, CHANNEL_CHUNK_LENGTH);
185
cbChId = set_variable_uint(ChannelId, out_data, &pos);
187
SET_UINT8(out_data, 0, 0x30 | cbChId);
188
t = data_size - data_pos;
189
if (t > CHANNEL_CHUNK_LENGTH - pos)
190
t = CHANNEL_CHUNK_LENGTH - pos;
191
memcpy(out_data + pos, data + data_pos, t);
193
hexdump(out_data, t + pos);
194
error = plugin->ep.pVirtualChannelWrite(plugin->open_handle,
195
out_data, t + pos, out_data);
114
data_out = stream_new(CHANNEL_CHUNK_LENGTH);
115
stream_set_pos(data_out, 1);
116
cbChId = drdynvc_write_variable_uint(data_out, ChannelId);
118
pos = stream_get_pos(data_out);
119
stream_set_pos(data_out, 0);
120
stream_write_uint8(data_out, 0x30 | cbChId);
121
stream_set_pos(data_out, pos);
123
chunk_len = data_size;
124
if (chunk_len > CHANNEL_CHUNK_LENGTH - pos)
125
chunk_len = CHANNEL_CHUNK_LENGTH - pos;
126
stream_write(data_out, data, chunk_len);
128
data_size -= chunk_len;
129
error = svc_plugin_send((rdpSvcPlugin*)drdynvc, data_out);
198
132
if (error != CHANNEL_RC_OK)
202
LLOGLN(0, ("drdynvc_write_data: "
203
"VirtualChannelWrite "
204
"failed %d", error));
210
/* called by main thread
211
add item to linked list and inform worker thread that there is data */
213
signal_data_in(drdynvcPlugin * plugin)
215
struct data_in_item * item;
217
item = (struct data_in_item *) malloc(sizeof(struct data_in_item));
219
item->data = plugin->data_in;
221
item->data_size = plugin->data_in_size;
222
plugin->data_in_size = 0;
223
pthread_mutex_lock(plugin->in_mutex);
224
if (plugin->in_list_tail == 0)
226
plugin->in_list_head = item;
227
plugin->in_list_tail = item;
231
plugin->in_list_tail->next = item;
232
plugin->in_list_tail = item;
234
pthread_mutex_unlock(plugin->in_mutex);
235
wait_obj_set(plugin->data_in_event);
239
process_CAPABILITY_REQUEST_PDU(drdynvcPlugin * plugin, int Sp, int cbChId,
240
char * data, int data_size)
246
LLOGLN(10, ("process_CAPABILITY_REQUEST_PDU:"));
247
plugin->version = GET_UINT16(data, 2);
248
if (plugin->version == 2)
250
plugin->PriorityCharge0 = GET_UINT16(data, 4);
251
plugin->PriorityCharge1 = GET_UINT16(data, 6);
252
plugin->PriorityCharge2 = GET_UINT16(data, 8);
253
plugin->PriorityCharge3 = GET_UINT16(data, 10);
256
out_data = (char *) malloc(size);
257
SET_UINT16(out_data, 0, 0x0050); /* Cmd+Sp+cbChId+Pad. Note: MSTSC sends 0x005c */
258
SET_UINT16(out_data, 2, plugin->version);
259
hexdump(out_data, 4);
260
error = plugin->ep.pVirtualChannelWrite(plugin->open_handle,
261
out_data, size, out_data);
262
if (error != CHANNEL_RC_OK)
264
LLOGLN(0, ("process_CAPABILITY_REQUEST_PDU: "
265
"VirtualChannelWrite "
266
"failed %d", error));
273
get_variable_uint(int cbLen, char * data, int * pos)
134
DEBUG_WARN("VirtualChannelWrite failed %d", error);
140
int drdynvc_push_event(drdynvcPlugin* drdynvc, RDP_EVENT* event)
144
error = svc_plugin_send_event((rdpSvcPlugin*)drdynvc, event);
145
if (error != CHANNEL_RC_OK)
147
DEBUG_WARN("pVirtualChannelEventPush failed %d", error);
153
static int drdynvc_process_capability_request(drdynvcPlugin* drdynvc, int Sp, int cbChId, STREAM* s)
158
DEBUG_DVC("Sp=%d cbChId=%d", Sp, cbChId);
159
stream_seek(s, 1); /* pad */
160
stream_read_uint16(s, drdynvc->version);
161
if (drdynvc->version == 2)
163
stream_read_uint16(s, drdynvc->PriorityCharge0);
164
stream_read_uint16(s, drdynvc->PriorityCharge1);
165
stream_read_uint16(s, drdynvc->PriorityCharge2);
166
stream_read_uint16(s, drdynvc->PriorityCharge3);
168
data_out = stream_new(4);
169
stream_write_uint16(data_out, 0x0050); /* Cmd+Sp+cbChId+Pad. Note: MSTSC sends 0x005c */
170
stream_write_uint16(data_out, drdynvc->version);
171
error = svc_plugin_send((rdpSvcPlugin*)drdynvc, data_out);
172
if (error != CHANNEL_RC_OK)
174
DEBUG_WARN("VirtualChannelWrite failed %d", error);
180
static uint32 drdynvc_read_variable_uint(STREAM* stream, int cbLen)
280
val = (uint32) GET_UINT8(data, *pos);
187
stream_read_uint8(stream, val);
284
val = (uint32) GET_UINT16(data, *pos);
190
stream_read_uint16(stream, val);
288
val = (uint32) GET_UINT32(data, *pos);
193
stream_read_uint32(stream, val);
296
process_CREATE_REQUEST_PDU(drdynvcPlugin * plugin, int Sp, int cbChId,
297
char * data, int data_size)
199
static int drdynvc_process_create_request(drdynvcPlugin* drdynvc, int Sp, int cbChId, STREAM* s)
303
204
uint32 ChannelId;
306
ChannelId = get_variable_uint(cbChId, data, &pos);
307
LLOGLN(10, ("process_CREATE_REQUEST_PDU: ChannelId=%d ChannelName=%s", ChannelId, data + pos));
310
out_data = (char *) malloc(size);
311
SET_UINT8(out_data, 0, 0x10 | cbChId);
312
memcpy(out_data + 1, data + 1, pos - 1);
206
ChannelId = drdynvc_read_variable_uint(s, cbChId);
207
pos = stream_get_pos(s);
208
DEBUG_DVC("ChannelId=%d ChannelName=%s", ChannelId, stream_get_tail(s));
210
error = dvcman_create_channel(drdynvc->channel_mgr, ChannelId, (char*)stream_get_tail(s));
212
data_out = stream_new(pos + 4);
213
stream_write_uint8(data_out, 0x10 | cbChId);
214
stream_set_pos(s, 1);
215
stream_copy(data_out, s, pos - 1);
314
error = dvcman_create_channel(plugin->channel_mgr, ChannelId, data + pos);
317
LLOGLN(10, ("process_CREATE_REQUEST_PDU: channel created"));
318
SET_UINT32(out_data, pos, 0);
219
DEBUG_DVC("channel created");
220
stream_write_uint32(data_out, 0);
322
LLOGLN(10, ("process_CREATE_REQUEST_PDU: no listener"));
323
SET_UINT32(out_data, pos, (uint32)(-1));
224
DEBUG_DVC("no listener");
225
stream_write_uint32(data_out, (uint32)(-1));
325
hexdump(out_data, size);
326
error = plugin->ep.pVirtualChannelWrite(plugin->open_handle,
327
out_data, size, out_data);
228
error = svc_plugin_send((rdpSvcPlugin*)drdynvc, data_out);
328
229
if (error != CHANNEL_RC_OK)
330
LLOGLN(0, ("process_CREATE_REQUEST_PDU: "
331
"VirtualChannelWrite "
332
"failed %d", error));
231
DEBUG_WARN("VirtualChannelWrite failed %d", error);
339
process_DATA(drdynvcPlugin * plugin, uint32 ChannelId,
340
char * data, int data_size)
344
if (plugin->dvc_data)
346
/* Fragmented data */
347
if (plugin->dvc_data_pos + (uint32) data_size > plugin->dvc_data_size)
349
LLOGLN(0, ("process_DATA: data exceeding declared length!"));
350
free(plugin->dvc_data);
351
plugin->dvc_data = NULL;
354
memcpy(plugin->dvc_data + plugin->dvc_data_pos, data, data_size);
355
plugin->dvc_data_pos += (uint32) data_size;
356
if (plugin->dvc_data_pos >= plugin->dvc_data_size)
358
error = dvcman_receive_channel_data(plugin->channel_mgr,
359
ChannelId, plugin->dvc_data, plugin->dvc_data_size);
360
free(plugin->dvc_data);
361
plugin->dvc_data = NULL;
366
error = dvcman_receive_channel_data(plugin->channel_mgr,
367
ChannelId, data, (uint32) data_size);
373
process_DATA_FIRST_PDU(drdynvcPlugin * plugin, int Sp, int cbChId,
374
char * data, int data_size)
237
static int drdynvc_process_data_first(drdynvcPlugin* drdynvc, int Sp, int cbChId, STREAM* s)
377
239
uint32 ChannelId;
381
ChannelId = get_variable_uint(cbChId, data, &pos);
382
Length = get_variable_uint(Sp, data, &pos);
383
LLOGLN(10, ("process_DATA_FIRST_PDU: ChannelId=%d Length=%d", ChannelId, Length));
385
if (plugin->dvc_data)
386
free(plugin->dvc_data);
387
plugin->dvc_data = (char *) malloc(Length);
388
memset(plugin->dvc_data, 0, Length);
389
plugin->dvc_data_pos = 0;
390
plugin->dvc_data_size = Length;
392
return process_DATA(plugin, ChannelId, data + pos, data_size - pos);
396
process_DATA_PDU(drdynvcPlugin * plugin, int Sp, int cbChId,
397
char * data, int data_size)
403
ChannelId = get_variable_uint(cbChId, data, &pos);
404
LLOGLN(10, ("process_DATA_PDU: ChannelId=%d", ChannelId));
406
return process_DATA(plugin, ChannelId, data + pos, data_size - pos);
410
process_CLOSE_REQUEST_PDU(drdynvcPlugin * plugin, int Sp, int cbChId,
411
char * data, int data_size)
417
ChannelId = get_variable_uint(cbChId, data, &pos);
418
LLOGLN(10, ("process_CLOSE_REQUEST_PDU: ChannelId=%d", ChannelId));
419
dvcman_close_channel(plugin->channel_mgr, ChannelId);
243
ChannelId = drdynvc_read_variable_uint(s, cbChId);
244
Length = drdynvc_read_variable_uint(s, Sp);
245
DEBUG_DVC("ChannelId=%d Length=%d", ChannelId, Length);
247
error = dvcman_receive_channel_data_first(drdynvc->channel_mgr, ChannelId, Length);
251
return dvcman_receive_channel_data(drdynvc->channel_mgr, ChannelId,
252
stream_get_tail(s), stream_get_left(s));
255
static int drdynvc_process_data(drdynvcPlugin* drdynvc, int Sp, int cbChId, STREAM* s)
259
ChannelId = drdynvc_read_variable_uint(s, cbChId);
260
DEBUG_DVC("ChannelId=%d", ChannelId);
262
return dvcman_receive_channel_data(drdynvc->channel_mgr, ChannelId,
263
stream_get_tail(s), stream_get_left(s));
266
static int drdynvc_process_close_request(drdynvcPlugin* drdynvc, int Sp, int cbChId, STREAM* s)
270
ChannelId = drdynvc_read_variable_uint(s, cbChId);
271
DEBUG_DVC("ChannelId=%d", ChannelId);
272
dvcman_close_channel(drdynvc->channel_mgr, ChannelId);
425
thread_process_message(drdynvcPlugin * plugin, char * data, int data_size)
277
static void drdynvc_process_receive(rdpSvcPlugin* plugin, STREAM* s)
279
drdynvcPlugin* drdynvc = (drdynvcPlugin*)plugin;
434
value = GET_UINT8(data, 0);
285
stream_read_uint8(s, value);
435
286
Cmd = (value & 0xf0) >> 4;
436
287
Sp = (value & 0x0c) >> 2;
437
288
cbChId = (value & 0x03) >> 0;
438
LLOGLN(10, ("thread_process_message: data_size %d cmd 0x%x", data_size, Cmd));
439
hexdump(data, data_size);
290
DEBUG_DVC("Cmd=0x%x", Cmd);
442
294
case CAPABILITY_REQUEST_PDU:
443
rv = process_CAPABILITY_REQUEST_PDU(plugin, Sp, cbChId, data, data_size);
295
drdynvc_process_capability_request(drdynvc, Sp, cbChId, s);
445
297
case CREATE_REQUEST_PDU:
446
rv = process_CREATE_REQUEST_PDU(plugin, Sp, cbChId, data, data_size);
298
drdynvc_process_create_request(drdynvc, Sp, cbChId, s);
448
300
case DATA_FIRST_PDU:
449
rv = process_DATA_FIRST_PDU(plugin, Sp, cbChId, data, data_size);
301
drdynvc_process_data_first(drdynvc, Sp, cbChId, s);
452
rv = process_DATA_PDU(plugin, Sp, cbChId, data, data_size);
304
drdynvc_process_data(drdynvc, Sp, cbChId, s);
454
306
case CLOSE_REQUEST_PDU:
455
rv = process_CLOSE_REQUEST_PDU(plugin, Sp, cbChId, data, data_size);
307
drdynvc_process_close_request(drdynvc, Sp, cbChId, s);
458
LLOGLN(0, ("thread_process_message: unknown drdynvc cmd 0x%x", Cmd));
464
/* process the linked list of data that has come in */
466
thread_process_data_in(drdynvcPlugin * plugin)
470
struct data_in_item * item;
474
if (wait_obj_is_set(plugin->term_event))
478
pthread_mutex_lock(plugin->in_mutex);
479
if (plugin->in_list_head == 0)
481
pthread_mutex_unlock(plugin->in_mutex);
484
data = plugin->in_list_head->data;
485
data_size = plugin->in_list_head->data_size;
486
item = plugin->in_list_head;
487
plugin->in_list_head = plugin->in_list_head->next;
488
if (plugin->in_list_head == 0)
490
plugin->in_list_tail = 0;
492
pthread_mutex_unlock(plugin->in_mutex);
495
thread_process_message(plugin, data, data_size);
507
thread_func(void * arg)
509
drdynvcPlugin * plugin;
510
struct wait_obj * listobj[2];
514
plugin = (drdynvcPlugin *) arg;
516
plugin->thread_status = 1;
517
LLOGLN(10, ("thread_func: in"));
520
listobj[0] = plugin->term_event;
521
listobj[1] = plugin->data_in_event;
524
wait_obj_select(listobj, numobj, NULL, 0, timeout);
525
if (wait_obj_is_set(plugin->term_event))
529
if (wait_obj_is_set(plugin->data_in_event))
531
wait_obj_clear(plugin->data_in_event);
532
/* process data in */
533
thread_process_data_in(plugin);
536
LLOGLN(10, ("thread_func: out"));
537
plugin->thread_status = -1;
542
OpenEventProcessReceived(uint32 openHandle, void * pData, uint32 dataLength,
543
uint32 totalLength, uint32 dataFlags)
545
drdynvcPlugin * plugin;
547
plugin = (drdynvcPlugin *) chan_plugin_find_by_open_handle(openHandle);
549
LLOGLN(10, ("OpenEventProcessReceived: receive openHandle %d dataLength %d "
550
"totalLength %d dataFlags %d",
551
openHandle, dataLength, totalLength, dataFlags));
552
if (dataFlags & CHANNEL_FLAG_FIRST)
554
plugin->data_in_read = 0;
555
if (plugin->data_in != 0)
557
free(plugin->data_in);
559
plugin->data_in = (char *) malloc(totalLength);
560
plugin->data_in_size = totalLength;
562
memcpy(plugin->data_in + plugin->data_in_read, pData, dataLength);
563
plugin->data_in_read += dataLength;
564
if (dataFlags & CHANNEL_FLAG_LAST)
566
if (plugin->data_in_read != plugin->data_in_size)
568
LLOGLN(0, ("OpenEventProcessReceived: read error"));
570
signal_data_in(plugin);
575
OpenEvent(uint32 openHandle, uint32 event, void * pData, uint32 dataLength,
576
uint32 totalLength, uint32 dataFlags)
578
LLOGLN(10, ("OpenEvent: event %d", event));
581
case CHANNEL_EVENT_DATA_RECEIVED:
582
OpenEventProcessReceived(openHandle, pData, dataLength,
583
totalLength, dataFlags);
585
case CHANNEL_EVENT_WRITE_COMPLETE:
592
InitEventProcessConnected(void * pInitHandle, void * pData, uint32 dataLength)
594
drdynvcPlugin * plugin;
598
plugin = (drdynvcPlugin *) chan_plugin_find_by_init_handle(pInitHandle);
601
LLOGLN(0, ("InitEventProcessConnected: error no match"));
605
error = plugin->ep.pVirtualChannelOpen(pInitHandle, &(plugin->open_handle),
606
plugin->channel_def.name, OpenEvent);
607
if (error != CHANNEL_RC_OK)
609
LLOGLN(0, ("InitEventProcessConnected: Open failed"));
612
chan_plugin_register_open_handle((rdpChanPlugin *) plugin, plugin->open_handle);
614
dvcman_initialize(plugin->channel_mgr);
616
pthread_create(&thread, 0, thread_func, plugin);
617
pthread_detach(thread);
621
InitEventProcessTerminated(void * pInitHandle)
623
drdynvcPlugin * plugin;
625
struct data_in_item * in_item;
627
plugin = (drdynvcPlugin *) chan_plugin_find_by_init_handle(pInitHandle);
630
LLOGLN(0, ("InitEventProcessConnected: error no match"));
634
wait_obj_set(plugin->term_event);
636
while ((plugin->thread_status > 0) && (index < 100))
641
wait_obj_free(plugin->term_event);
642
wait_obj_free(plugin->data_in_event);
644
pthread_mutex_destroy(plugin->in_mutex);
645
free(plugin->in_mutex);
647
/* free the un-processed in/out queue */
648
while (plugin->in_list_head != 0)
650
in_item = plugin->in_list_head;
651
plugin->in_list_head = in_item->next;
656
dvcman_free(plugin->channel_mgr);
657
if (plugin->dvc_data)
659
free(plugin->dvc_data);
660
plugin->dvc_data = NULL;
663
chan_plugin_uninit((rdpChanPlugin *) plugin);
668
InitEvent(void * pInitHandle, uint32 event, void * pData, uint32 dataLength)
670
LLOGLN(10, ("InitEvent: event %d", event));
673
case CHANNEL_EVENT_CONNECTED:
674
InitEventProcessConnected(pInitHandle, pData, dataLength);
676
case CHANNEL_EVENT_DISCONNECTED:
678
case CHANNEL_EVENT_TERMINATED:
679
InitEventProcessTerminated(pInitHandle);
685
VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints)
687
drdynvcPlugin * plugin;
688
RD_PLUGIN_DATA * data;
690
LLOGLN(10, ("VirtualChannelEntry:"));
692
plugin = (drdynvcPlugin *) malloc(sizeof(drdynvcPlugin));
693
memset(plugin, 0, sizeof(drdynvcPlugin));
695
chan_plugin_init((rdpChanPlugin *) plugin);
697
plugin->data_in_size = 0;
699
plugin->ep = *pEntryPoints;
700
memset(&(plugin->channel_def), 0, sizeof(plugin->channel_def));
701
plugin->channel_def.options = CHANNEL_OPTION_INITIALIZED |
702
CHANNEL_OPTION_ENCRYPT_RDP | CHANNEL_OPTION_COMPRESS_RDP;
703
strcpy(plugin->channel_def.name, "drdynvc");
704
plugin->in_mutex = (pthread_mutex_t *) malloc(sizeof(pthread_mutex_t));
705
pthread_mutex_init(plugin->in_mutex, 0);
706
plugin->in_list_head = 0;
707
plugin->in_list_tail = 0;
708
plugin->term_event = wait_obj_new("freerdprdrynvcterm");
709
plugin->data_in_event = wait_obj_new("freerdpdrdynvcdatain");
710
plugin->thread_status = 0;
711
plugin->ep.pVirtualChannelInit(&plugin->chan_plugin.init_handle, &plugin->channel_def, 1,
712
VIRTUAL_CHANNEL_VERSION_WIN2000, InitEvent);
714
plugin->channel_mgr = dvcman_new(plugin);
716
if (pEntryPoints->cbSize >= sizeof(CHANNEL_ENTRY_POINTS_EX))
718
data = (RD_PLUGIN_DATA *) (((PCHANNEL_ENTRY_POINTS_EX)pEntryPoints)->pExtendedData);
719
while (data && data->size > 0)
721
dvcman_load_plugin(plugin->channel_mgr, (char*)data->data[0]);
722
data = (RD_PLUGIN_DATA *) (((void *) data) + data->size);
310
DEBUG_WARN("unknown drdynvc cmd 0x%x", Cmd);
317
static void drdynvc_process_connect(rdpSvcPlugin* plugin)
319
drdynvcPlugin* drdynvc = (drdynvcPlugin*)plugin;
321
DEBUG_DVC("connecting");
323
drdynvc->channel_mgr = dvcman_new(drdynvc);
324
dvcman_load_plugin(drdynvc->channel_mgr, svc_plugin_get_data(plugin));
325
dvcman_init(drdynvc->channel_mgr);
328
static void drdynvc_process_event(rdpSvcPlugin* plugin, RDP_EVENT* event)
330
freerdp_event_free(event);
333
static void drdynvc_process_terminate(rdpSvcPlugin* plugin)
335
drdynvcPlugin* drdynvc = (drdynvcPlugin*)plugin;
337
DEBUG_DVC("terminating");
339
if (drdynvc->channel_mgr != NULL)
340
dvcman_free(drdynvc->channel_mgr);
344
DEFINE_SVC_PLUGIN(drdynvc, "drdynvc",
345
CHANNEL_OPTION_INITIALIZED | CHANNEL_OPTION_ENCRYPT_RDP |
346
CHANNEL_OPTION_COMPRESS_RDP)