156 lines · 2.2 KB · C
RawDownload
/* * [MS-RDPBCGR] 3.1.5.2 Static Virtual Channels * http://msdn.microsoft.com/en-us/library/cc240926.aspx */#include <u.h>#include <libc.h>#include "dat.h"#include "fns.h" enum{	/* 2.2.1.3.4.1 Channel Definition Structure */	Inited=	1<<31,		/* 2.2.6.1 Virtual Channel PDU */	MTU=	1600, 	/* 2.2.6.1.1 Channel PDU Header */	First=	1<<0,	Last=	1<<1,	Vis=  	1<<4,}; static Vchan vctab[] ={	{		.mcsid = GLOBALCHAN+1,	/* iota */		.name = "CLIPRDR",		.fn = clipvcfn,		.flags = Inited,	},	{		.mcsid = GLOBALCHAN+2,		.name = "RDPSND",		.fn = audiovcfn,		.flags = Inited,	},};static uint nvc = nelem(vctab); voidinitvc(Rdp* c){	c->vc = vctab;	c->nvc = nvc;} static Vchan*lookupvc(int mcsid){	int i; 	for(i=0; i<nvc; i++)	if(vctab[i].mcsid == mcsid)		return &vctab[i];	return nil;} static Vchan*namevc(char* name){	int i; 	for(i=0; i<nvc; i++)	if(strcmp(vctab[i].name, name) == 0)		return &vctab[i];	return nil;} intdefragvc(Rdp* c, Msg* m){	Vchan* vc;	int n; 	USED(c);	vc = lookupvc(m->chanid);	if(vc == nil){		fprint(2, "defragvc: bad chanid\n");		return -1;	} 	if(m->flags&First)		vc->pos = 0; 	if(m->len > vc->nb){		vc->buf = erealloc(vc->buf, m->len);		vc->nb = m->len;	}	n = m->len - vc->pos;	if(n > m->ndata)		n = m->ndata;	memcpy(vc->buf+vc->pos, m->data, n);	vc->pos += n; 	if(m->flags&Last){		m->data = vc->buf;		m->ndata = m->len;		return m->len;	}	return 0;} voidcallvcfunc(Rdp *c, Msg* m){	Vchan* vc;	vc = lookupvc(m->chanid);	if(vc == nil || vc->fn==nil){		fprint(2, "unhandled virtual channel[%d] msg\n", m->chanid);		return;	}	vc->fn(c, m->data, m->ndata);} intsendvc(Rdp* c, char* cname, uchar* a, int n){	int sofar, chunk;	Vchan* vc;	Msg t;		if(n < 0)		return -1; 	vc = namevc(cname);	if(vc == nil){		werrstr("%s: no such vchannel", cname);		return -1;	}	if(vc->mcsid < 0)		return -1; 	t.type = Mvchan;	t.originid = c->userchan;	t.chanid = vc->mcsid;	t.flags = First | Vis;	t.len = n;	t.data = a; 	for(sofar=0; sofar<n; sofar += chunk){		chunk = n-sofar;		if(chunk > MTU)			chunk = MTU;		else			t.flags |= Last; 		t.data = a+sofar;		t.ndata = chunk;		writemsg(c, &t); 		t.flags &= ~First;	}	return n;}