ref: f283a6a6cf3a8283e3896e5556fe8cbdbd6413a8
parent: 05bd68a784ff9ed57439a16f8449444229ed16fc
author: Yaroslav K <yarikos@gmail.com>
date: Sat Aug 23 15:31:26 EDT 2025
merge with origin (legacy)
--- a/audio.c
+++ b/audio.c
@@ -5,8 +5,6 @@
#include "fns.h"
/*
-BUG requires RDPDR support...
-
[MS-RDPEA] "6 Appendix A: Product Behavior":
<1> Section 2.1: In Windows, the client advertises the static virtual
channel named "RDPDR", as defined in [MS-RDPEFS]. If that channel is
@@ -19,48 +17,131 @@
enum /* Audiomsg.type */
{- Awav= 2, /* WaveInfo PDU */
- Awavack= 5, /* Wave Confirm PDU */
- Aprobe= 6, /* Training PDU or Training Confirm PDU */
+ Awinf= 2, /* WaveInfo PDU */
+ Awav= 0, /* Wave PDU - always follows Awinf */
+ Awack= 5, /* Wave Confirm PDU */
+ Aping= 6, /* Training PDU or Training Confirm PDU */
Afmt= 7, /* Client/Server Audio Formats and Version PDU */
- /* 2.2.1 RDPSND PDU Header (SNDPROLOG) */
+ Afin= 1, /* 2.2.3.9 Close PDU */
};
+
+enum /* RFC2361 Appendix A */
+{+ FmtPCM= 0x01, /* WAVE_FORMAT_PCM */
+};
+
typedef struct Audiomsg Audiomsg;
struct Audiomsg
{uint type;
uint nfmt; /* Afmt */
- uint ack; /* Afmt */
+ uint seq; /* Afmt, Awinf, Awack */
+ uint time; /* Awinf, Awack, Aping */
+ uint ping; /* Aping */
uint ver; /* Afmt */
- uchar *data; /* Afmt */
- uint ndata; /* Afmt */
+ uint ndata; /* Afmt, Awinf */
+ uint nxdata; /* Awinf */
+ uchar *data; /* Afmt, Awinf, Awav */
};
-static int getaudiomsg(Audiomsg*,uchar*,int);
-static int putaudiomsg(uchar*,int, Audiomsg*);
+static int audiogetmsg(Audiomsg*,uchar*,int);
+static int audioputmsg(uchar*,int, Audiomsg*);
+static int audiosendmsg(Rdp*, Audiomsg*);
+static void sfmtrcvd(Rdp*,Audiomsg*);
+static void winfrcvd(Rdp*,Audiomsg*);
+static void wavrcvd(Rdp*,Audiomsg*);
+static void pingrcvd(Rdp*,Audiomsg*);
+static void finrcvd(Rdp*,Audiomsg*);
+static void sendcfmt(Rdp*);
+static void sendwack(Rdp*);
+static void sendping(Rdp*, uint, uint);
-enum
-{- FmtPCM= 0x01, /* WAVE_FORMAT_PCM */
- FmtMP3= 0x55, /* WAVE_FORMAT_MPEGLAYER3 */
- /* RFC2361 Appendix A */
-};
-
-
void
audiovcfn(Rdp* c, uchar* a, uint nb)
{Audiomsg r;
- USED(c);
-fprint(2, " A ");
- if(getaudiomsg(&r, a, nb) < 0){+ if(audiogetmsg(&r, a, nb) < 0){fprint(2, "audio: %r\n");
return;
}
-fprint(2, " a%ud ", r.type);
+ switch(r.type){+ case Afmt: sfmtrcvd(c, &r); break;
+ case Awinf: winfrcvd(c, &r); break;
+ case Awav: wavrcvd(c, &r); break;
+ case Aping: pingrcvd(c, &r); break;
+ case Afin: finrcvd(c, &r); break;
+ }
}
+static void
+sfmtrcvd(Rdp* c, Audiomsg* r)
+{+ c->audio.seq = r->seq;
+ sendcfmt(c);
+}
+static void
+winfrcvd(Rdp* c, Audiomsg* r)
+{+ c->audio.seq = r->seq;
+ c->audio.time = r->time;
+ playsound(c, r->data, r->ndata);
+}
+
+static void
+wavrcvd(Rdp* c, Audiomsg* r)
+{+ playsound(c, r->data, r->ndata);
+ sendwack(c);
+}
+
+static void
+pingrcvd(Rdp* c, Audiomsg* r)
+{+ sendping(c, r->time, r->ping);
+}
+
+static void
+finrcvd(Rdp* c, Audiomsg* r)
+{+ USED(c);
+ USED(r);
+}
+
+static void
+sendcfmt(Rdp* c)
+{+ Audiomsg t;
+
+ t.type = Afmt;
+ if(audiosendmsg(c, &t) < 0)
+ fprint(2, "audio: sendcfmt: %r\n");
+}
+
+static void
+sendwack(Rdp* c)
+{+ Audiomsg t;
+
+ t.type = Awack;
+ t.seq = c->audio.seq;
+ t.time = c->audio.time;
+ if(audiosendmsg(c, &t) < 0)
+ fprint(2, "audio: sendwack: %r\n");
+}
+
+static void
+sendping(Rdp* c, uint time, uint v)
+{+ Audiomsg t;
+
+ t.type = Aping;
+ t.time = time;
+ t.ping = v;
+ if(audiosendmsg(c, &t) < 0)
+ fprint(2, "audio: sendping: %r\n");
+}
+
/*
* 2.2.1 RDPSND PDU Header (SNDPROLOG)
* msgtype[1] pad[1] bodysize[2]
@@ -73,7 +154,7 @@
*/
static int
-getaudiomsg(Audiomsg* m, uchar* a, int nb)
+audiogetmsg(Audiomsg* m, uchar* a, int nb)
{ulong len;
@@ -83,7 +164,7 @@
}
m->type = *a;
- len = igets(a+2);
+ len = GSHORT(a+2);
switch(m->type){case Afmt:
if(len < 20 || nb < len+4){@@ -90,14 +171,115 @@
werrstr(Eshort);
return -1;
}
- m->nfmt = igets(a+18);
- m->ack = a[20];
- m->ver = igets(a+21);
+ m->nfmt = GSHORT(a+18);
+ m->seq = a[20];
+ m->ver = GSHORT(a+21);
m->data = a+24;
m->ndata = len-20;
return len+4;
+ case Awinf:
+ if(len < 16 || nb < 16){+ werrstr(Eshort);
+ return -1;
+ }
+ m->time = GSHORT(a+4);
+ m->seq = a[8];
+ m->data = a+12;
+ m->ndata = 4;
+ m->nxdata = len-16;
+ return 16;
+ case Awav:
+ m->data = a+4;
+ m->ndata = nb-4;
+ return nb;
+ case Aping:
+ if(nb < 8){+ werrstr(Eshort);
+ return -1;
+ }
+ m->time = GSHORT(a+4);
+ m->ping = GSHORT(a+6);
+ return 8;
+ case Afin:
+ return 4;
}
- werrstr("unrecognized audio msg type");+ werrstr("unrecognized audio msg type(%ud)", m->type);return -1;
}
+static int
+audioputmsg(uchar* a, int n, Audiomsg* m)
+{+ int len;
+
+ switch(m->type){+ case Afmt:
+ len = 42-4;
+ if(n < 42){+ werrstr(Esmall);
+ return -1;
+ }
+ a[0] = m->type;
+ a[1] = 0; // pad
+ PSHORT(a+2, len);
+ PLONG(a+4, 1); // flags: 1=alive
+ PLONG(a+8, 0xffffffff); // volume: l=100, r=100
+ PLONG(a+12, 1<<16); // pitch
+ PSHORT(a+16, 0); // dgport
+ PSHORT(a+18, 1); // nfmt
+ a[20] = 0; // seq
+ PSHORT(a+21, 5); // ver
+ a[23] = 0; // pad
+ // afmt[0]
+ PSHORT(a+24, FmtPCM); // ftag
+ PSHORT(a+26, 2); // nchan
+ PLONG(a+28, 44100); // samphz
+ PLONG(a+32, 44100*2*2); // avgbytehz
+ PSHORT(a+36, 4); // blocksz (nchan*sampbitsz/8)
+ PSHORT(a+38, 16); // sampbitsz
+ PSHORT(a+40, 0); // ndata
+ /* NOTE: we shouldn't send this unless the server
+ * also declared support for the exact same format */
+ return 42;
+ case Awack:
+ len = 8-4;
+ if(n < 8){+ werrstr(Esmall);
+ return -1;
+ }
+ a[0] = m->type;
+ a[1] = 0; // pad
+ PSHORT(a+2, len);
+ PSHORT(a+4, m->time);
+ a[6] = m->seq;
+ a[7] = 0; // pad
+ return 8;
+ case Aping:
+ len = 8-4;
+ if(n < 8){+ werrstr(Esmall);
+ return -1;
+ }
+ a[0] = m->type;
+ a[1] = 0; // pad
+ PSHORT(a+2, len);
+ PSHORT(a+4, m->time);
+ PSHORT(a+6, m->ping);
+ return 8;
+ }
+ werrstr("unrecognized audio msg type(%ud)", m->type);+ return -1;
+}
+
+
+static int
+audiosendmsg(Rdp* c, Audiomsg* m)
+{+ int n;
+ uchar buf[64];
+
+ n = audioputmsg(buf, sizeof buf, m);
+ if(n < 0)
+ return n;
+ return sendvc(c, rdpsnd, buf, n);
+}
--- a/byte.c
+++ /dev/null
@@ -1,58 +1,0 @@
-#include <u.h>
-#include "fns.h"
-
-short
-igets(uchar* p)
-{- return p[0] | (p[1]<<8);
-}
-
-long
-igetl(uchar* p)
-{- return p[0] | (p[1]<<8) | (p[2]<<16) | (p[3]<<24);
-}
-
-void
-iputs(uchar* p, short v)
-{- p[0]=(uchar)v;
- p[1]=(uchar)(v>>8);
-}
-
-void
-iputl(uchar* p, long v)
-{- p[0]=(uchar)v;
- p[1]=(uchar)(v>>8);
- p[2]=(uchar)(v>>16);
- p[3]=(uchar)(v>>24);
-}
-
-short
-nhgets(uchar* p)
-{- return (p[0]<<8) | p[1];
-}
-
-long
-nhgetl(uchar* p)
-{- return (p[0]<<24) | (p[1]<<16) | (p[2]<<8) | p[3];
-}
-
-void
-hnputs(uchar* p, short v)
-{- p[0]=(uchar)(v>>8);
- p[1]=(uchar)v;
-}
-
-void
-hnputl(uchar* p, long v)
-{- p[0]=(uchar)(v>>24);
- p[1]=(uchar)(v>>16);
- p[2]=(uchar)(v>>8);
- p[3]=(uchar)v;
-}
--- a/cap.c
+++ b/cap.c
@@ -58,11 +58,11 @@
ep = p+nb;
memset(caps, sizeof(*caps), 0);
- ncap = igets(p);
+ ncap = GSHORT(p);
p += 4;
for(; ncap>0 && p+4<ep; ncap--){- type = igets(p+0);
- len = igets(p+2);
+ type = GSHORT(p+0);
+ len = GSHORT(p+2);
if(p+len > ep){ werrstr("bad length in server's capability set");return -1;
@@ -75,7 +75,7 @@
return -1;
}
caps->general = 1;
- extraFlags = igets(p+14);
+ extraFlags = GSHORT(p+14);
caps->canrefresh = p[22];
caps->cansupress = p[23];
USED(extraFlags);
@@ -87,9 +87,9 @@
return -1;
}
caps->bitmap = 1;
- caps->depth = igets(p+4);
- caps->xsz = igets(p+12);
- caps->ysz = igets(p+14);
+ caps->depth = GSHORT(p+4);
+ caps->xsz = GSHORT(p+12);
+ caps->ysz = GSHORT(p+14);
break;
}
p += len;
@@ -139,8 +139,8 @@
werrstr(Eshort);
return -1;
}
- iputs(p, ncap);
- iputs(p+2, 0);
+ PSHORT(p, ncap);
+ PSHORT(p+2, 0);
return 4;
}
@@ -160,16 +160,16 @@
werrstr(Eshort);
return -1;
}
- iputs(p+0, CapGeneral);
- iputs(p+2, 24); // size
- iputs(p+4, 0); // OSMAJORTYPE_UNSPECIFIED
- iputs(p+6, 0); // OSMINORTYPE_UNSPECIFIED
- iputs(p+8, 0x200); // TS_CAPS_PROTOCOLVERSION
- iputs(p+12, 0); // generalCompressionTypes
- iputs(p+14, extraFlags);
- iputs(p+16, 0); // updateCapabilityFlag
- iputs(p+18, 0); // remoteUnshareFlag
- iputs(p+20, 0); // generalCompressionLevel
+ PSHORT(p+0, CapGeneral);
+ PSHORT(p+2, 24); // size
+ PSHORT(p+4, 0); // OSMAJORTYPE_UNSPECIFIED
+ PSHORT(p+6, 0); // OSMINORTYPE_UNSPECIFIED
+ PSHORT(p+8, 0x200); // TS_CAPS_PROTOCOLVERSION
+ PSHORT(p+12, 0); // generalCompressionTypes
+ PSHORT(p+14, extraFlags);
+ PSHORT(p+16, 0); // updateCapabilityFlag
+ PSHORT(p+18, 0); // remoteUnshareFlag
+ PSHORT(p+20, 0); // generalCompressionLevel
p[22] = 0; // refreshRectSupport - server only
p[23] = 0; // suppressOutputSupport - server only
return 24;
@@ -184,21 +184,21 @@
werrstr(Eshort);
return -1;
}
- iputs(p+0, CapBitmap);
- iputs(p+2, 30); // size
- iputs(p+4, caps->depth); // preferredBitsPerPixel
- iputs(p+6, 1); // receive1BitPerPixel
- iputs(p+8, 1); // receive4BitsPerPixel
- iputs(p+10, 1); // receive8BitsPerPixel
- iputs(p+12, caps->xsz); // desktopWidth
- iputs(p+14, caps->ysz); // desktopHeight
- iputs(p+16, 0); // pad2octets
- iputs(p+18, 1); // desktopResizeFlag
- iputs(p+20, 1); // bitmapCompressionFlag
- iputs(p+22, 0); // highColorFlags
- iputs(p+24, 1); // drawingFlags
- iputs(p+26, 1); // multipleRectangleSupport
- iputs(p+26, 0); // pad2octetsB
+ PSHORT(p+0, CapBitmap);
+ PSHORT(p+2, 30); // size
+ PSHORT(p+4, caps->depth); // preferredBitsPerPixel
+ PSHORT(p+6, 1); // receive1BitPerPixel
+ PSHORT(p+8, 1); // receive4BitsPerPixel
+ PSHORT(p+10, 1); // receive8BitsPerPixel
+ PSHORT(p+12, caps->xsz); // desktopWidth
+ PSHORT(p+14, caps->ysz); // desktopHeight
+ PSHORT(p+16, 0); // pad2octets
+ PSHORT(p+18, 1); // desktopResizeFlag
+ PSHORT(p+20, 1); // bitmapCompressionFlag
+ PSHORT(p+22, 0); // highColorFlags
+ PSHORT(p+24, 1); // drawingFlags
+ PSHORT(p+26, 1); // multipleRectangleSupport
+ PSHORT(p+26, 0); // pad2octetsB
return 30;
}
@@ -226,25 +226,25 @@
werrstr(Eshort);
return -1;
}
- iputs(p+0, CapOrder);
- iputs(p+2, 88); // size
+ PSHORT(p+0, CapOrder);
+ PSHORT(p+2, 88); // size
memset(p+4, 16, 0); // terminalDescriptor
- iputl(p+20, 0); // pad4octetsA
- iputs(p+24, 1); // desktopSaveXGranularity
- iputs(p+26, 20); // desktopSaveYGranularity
- iputs(p+28, 0); // pad2octetsA
- iputs(p+30, 1); // maximumOrderLevel
- iputs(p+32, 0); // numberFonts
- iputs(p+34, orderFlags);
+ PLONG(p+20, 0); // pad4octetsA
+ PSHORT(p+24, 1); // desktopSaveXGranularity
+ PSHORT(p+26, 20); // desktopSaveYGranularity
+ PSHORT(p+28, 0); // pad2octetsA
+ PSHORT(p+30, 1); // maximumOrderLevel
+ PSHORT(p+32, 0); // numberFonts
+ PSHORT(p+34, orderFlags);
memcpy(p+36, orderSupport, 32);
- iputs(p+68, 0x6a1); // textFlags
- iputs(p+70, 0); // orderSupportExFlags
- iputl(p+72, 0); // pad4octetsB
- iputl(p+76, 480*480); // desktopSaveSize
- iputs(p+80, 0); // pad2octetsC
- iputs(p+82, 0); // pad2octetsD
- iputs(p+84, 0xe4); // textANSICodePage
- iputs(p+86, 0x04); // pad2octetsE
+ PSHORT(p+68, 0x6a1); // textFlags
+ PSHORT(p+70, 0); // orderSupportExFlags
+ PLONG(p+72, 0); // pad4octetsB
+ PLONG(p+76, 480*480); // desktopSaveSize
+ PSHORT(p+80, 0); // pad2octetsC
+ PSHORT(p+82, 0); // pad2octetsD
+ PSHORT(p+84, 0xe4); // textANSICodePage
+ PSHORT(p+86, 0x04); // pad2octetsE
return 88;
}
@@ -258,16 +258,16 @@
werrstr(Eshort);
return -1;
}
- iputs(p+0, CapBitcache2);
- iputs(p+2, 40); // size
- iputs(p+4, 0); // CacheFlags (2 bytes):
+ PSHORT(p+0, CapBitcache2);
+ PSHORT(p+2, 40); // size
+ PSHORT(p+4, 0); // CacheFlags (2 bytes):
p[6] = 0; // pad2
p[7] = 3; // NumCellCaches
- iputl(p+8, 120); // BitmapCache0CellInfo
- iputl(p+12, 120); // BitmapCache1CellInfo
- iputl(p+16, 336); // BitmapCache2CellInfo
- iputl(p+20, 0); // BitmapCache3CellInfo
- iputl(p+24, 0); // BitmapCache4CellInfo
+ PLONG(p+8, 120); // BitmapCache0CellInfo
+ PLONG(p+12, 120); // BitmapCache1CellInfo
+ PLONG(p+16, 336); // BitmapCache2CellInfo
+ PLONG(p+20, 0); // BitmapCache3CellInfo
+ PLONG(p+24, 0); // BitmapCache4CellInfo
memset(p+28, 12, 0); // Pad3
return 40;
}
@@ -281,10 +281,10 @@
werrstr(Eshort);
return -1;
}
- iputs(p+0, CapPointer);
- iputs(p+2, 8); // size
- iputs(p+4, 0); // colorPointerFlag
- iputs(p+6, 20); // colorPointerCacheSize
+ PSHORT(p+0, CapPointer);
+ PSHORT(p+2, 8); // size
+ PSHORT(p+4, 0); // colorPointerFlag
+ PSHORT(p+6, 20); // colorPointerCacheSize
return 8;
}
@@ -311,16 +311,16 @@
werrstr(Eshort);
return -1;
}
- iputs(p+0, CapInput);
- iputs(p+2, 88); // size
- iputs(p+4, inputFlags); // inputFlags
- iputs(p+6, 0); // pad2octetsA
+ PSHORT(p+0, CapInput);
+ PSHORT(p+2, 88); // size
+ PSHORT(p+4, inputFlags); // inputFlags
+ PSHORT(p+6, 0); // pad2octetsA
// the below SHOULD be the same as in the Client Core Data (section 2.2.1.3.2).
- iputl(p+8, 0x409); // keyboardLayout
- iputl(p+12, 4); // keyboardType: IBM enhanced (101- or 102-key)
- iputl(p+16, 0); // keyboardSubType
- iputl(p+20, 12); // keyboardFunctionKey
+ PLONG(p+8, 0x409); // keyboardLayout
+ PLONG(p+12, 4); // keyboardType: IBM enhanced (101- or 102-key)
+ PLONG(p+16, 0); // keyboardSubType
+ PLONG(p+20, 12); // keyboardFunctionKey
memset(p+24, 64, 0); // imeFileName
return 88;
}
@@ -338,21 +338,21 @@
werrstr(Eshort);
return -1;
}
- iputs(p+0, CapGlyph);
- iputs(p+2, 52); // size
- iputl(p+4, 0x0400fe); // GlyphCache 0
- iputl(p+8, 0x0400fe); // GlyphCache 1
- iputl(p+12, 0x0800fe); // GlyphCache 2
- iputl(p+16, 0x0800fe); // GlyphCache 3
- iputl(p+20, 0x1000fe); // GlyphCache 4
- iputl(p+24, 0x2000fe); // GlyphCache 5
- iputl(p+28, 0x4000fe); // GlyphCache 6
- iputl(p+32, 0x8000fe); // GlyphCache 7
- iputl(p+36, 0x10000fe); // GlyphCache 8
- iputl(p+40, 0x8000040); // GlyphCache 9
- iputl(p+44, 0x01000100); // FragCache
- iputs(p+48, GLYPH_SUPPORT_NONE); // GlyphSupportLevel
- iputs(p+50, 0); // pad2octets
+ PSHORT(p+0, CapGlyph);
+ PSHORT(p+2, 52); // size
+ PLONG(p+4, 0x0400fe); // GlyphCache 0
+ PLONG(p+8, 0x0400fe); // GlyphCache 1
+ PLONG(p+12, 0x0800fe); // GlyphCache 2
+ PLONG(p+16, 0x0800fe); // GlyphCache 3
+ PLONG(p+20, 0x1000fe); // GlyphCache 4
+ PLONG(p+24, 0x2000fe); // GlyphCache 5
+ PLONG(p+28, 0x4000fe); // GlyphCache 6
+ PLONG(p+32, 0x8000fe); // GlyphCache 7
+ PLONG(p+36, 0x10000fe); // GlyphCache 8
+ PLONG(p+40, 0x8000040); // GlyphCache 9
+ PLONG(p+44, 0x01000100); // FragCache
+ PSHORT(p+48, GLYPH_SUPPORT_NONE); // GlyphSupportLevel
+ PSHORT(p+50, 0); // pad2octets
return 52;
}
@@ -365,9 +365,9 @@
werrstr(Eshort);
return -1;
}
- iputs(p+0, CapSound);
- iputs(p+2, 8); // size
- iputs(p+4, 0); // soundFlags
- iputs(p+6, 0); // pad2octetsA
+ PSHORT(p+0, CapSound);
+ PSHORT(p+2, 8); // size
+ PSHORT(p+4, 0); // soundFlags
+ PSHORT(p+6, 0); // pad2octetsA
return 8;
}
--- a/dat.h
+++ b/dat.h
@@ -4,12 +4,41 @@
typedef struct Share Share;
typedef struct Caps Caps;
typedef struct Imgupd Imgupd;
+typedef struct Audstate Audstate;
+typedef struct Efsstate Efsstate;
+typedef struct Efsmsg Efsmsg;
+#define GSHORT(p) ((p)[0]|((p)[1]<<8))
+#define GSHORTB(p) ((p)[0]<<8|((p)[1]))
+#define GLONG(p) ((p)[0]|((p)[1]<<8)|((p)[2]<<16)|((p)[3]<<24))
+#define GLONGB(p) (((p)[0]<<24)|((p)[1]<<16)|((p)[2]<<8)|(p)[3])
+#define PSHORT(p,v) (p)[0]=(uchar)(v);(p)[1]=(uchar)((v)>>8)
+#define PSHORTB(p,v) (p)[0]=(uchar)((v)>>8);(p)[1]=(uchar)(v)
+#define PLONG(p,v) \
+ (p)[0]=(uchar)(v);(p)[1]=(uchar)((v)>>8);\
+ (p)[2]=(uchar)((v)>>16);(p)[3]=(uchar)((v)>>24)
+#define PLONGB(p,v) \
+ (p)[0]=(uchar)((v)>>24);(p)[1]=(uchar)((v)>>16);\
+ (p)[2]=(uchar)((v)>>8);(p)[3]=(uchar)(v)
+
+#define MIN(x,y) (((x) < (y)) ? (x) : (y))
+
enum
{MAXTPDU= 16386, /* max TPDU size */
};
+struct Efsstate
+{+ uint cid; /* client ID */
+};
+
+struct Audstate
+{+ uint seq;
+ uint time;
+};
+
struct Rdp
{int fd; /* connection I/O descriptor */
@@ -24,7 +53,7 @@
int xsz; /* rfb dimensions */
int ysz; /* rfb dimensions */
int depth; /* rfb color depth */
- int hupreason; /* hangup reason as server explains */
+ int hupreason; /* hangup reason code */
int mcsuid; /* MCS [T.122] userId */
int userchan; /* MCS user channelId */
int srvchan; /* MCS server channel ID */
@@ -31,6 +60,8 @@
int shareid; /* share ID - [T128] section 8.4.2 */
int active; /* T.128 action state */
int wantconsole; /* attach to the console sesstion */
+ Efsstate efs; /* FS extension state (efs.c) */
+ Audstate audio; /* Audio extension state */
Vchan *vc; /* static virtual channels table */
uint nvc; /* number of vctab entries */
uchar cmap[256]; /* rfb color map for depths ≤ 8 */
@@ -52,8 +83,11 @@
void clipannounce(Rdp*);
void clipvcfn(Rdp*, uchar*,uint);
void audiovcfn(Rdp*, uchar*,uint);
+void efsvcfn(Rdp*, uchar*,uint);
void pollsnarf(Rdp*);
+void playsound(Rdp*, uchar*,uint);
+
void initscreen(Rdp*);
void readkbd(Rdp*);
void sendkbd(Rdp*, Rune);
@@ -220,7 +254,7 @@
Ubitmap,
Uscrblt,
Umemblt,
- Ucacheimg,
+ Uicache,
Umcache,
};
struct Imgupd
@@ -233,12 +267,12 @@
int xsz;
int ysz;
int depth;
- int clip;
- int compressed;
+ int iscompr;
int cid;
int coff;
int sx;
int sy;
+ int clipped;
int cx;
int cy;
int cxsz;
@@ -248,6 +282,31 @@
};
int getimgupd(Imgupd*, uchar*, uint);
int getfupd(Imgupd*, uchar*, uint);
+
+enum /* 2.2.1.1 Shared Header (RDPDR_HEADER) */
+{+ CTcore= 0x4472, // Device redirector core component
+ CTprn= 0x5052, // Printing component
+ // CTcore
+ CSann= 0x496e, // Server Announce Request
+ CCann= 0x4343, // Client Announce Reply
+ CCnrq= 0x434e, // Client Name Request
+};
+
+struct Efsmsg {+ uint ctype; // Component (core or printing)
+ uint pakid; // PackedId (identifies packet function)
+ // CSann, CCann
+ uint vermaj;
+ uint vermin;
+ uint cid; // ClientID
+ // CCnrq
+ char* cname;
+};
+int getefsmsg(Efsmsg*, uchar*, int);
+int putefsmsg(uchar*, int, Efsmsg*);
+int sendefsmsg(Rdp*, Efsmsg*);
+
enum
{--- a/draw.c
+++ b/draw.c
@@ -102,7 +102,7 @@
sysfatal("bad image depth");loadfn = loadbmp;
- if(up->compressed)
+ if(up->iscompr)
loadfn = loadrle;
r = rectaddpt(Rect(up->x, up->y, up->x+up->xsz, up->y+up->ysz), screen->r.min);
@@ -143,7 +143,7 @@
return;
}
- if(up->clip){+ if(up->clipped){clipr = Rect(up->cx, up->cy, up->cx+up->cxsz, up->cy+up->cysz);
replclipr(screen, screen->repl, rectaddpt(clipr, screen->r.min));
}
@@ -153,12 +153,12 @@
pt = Pt(up->sx, up->sy);
draw(screen, r, img, nil, pt);
- if(up->clip)
+ if(up->clipped)
replclipr(screen, screen->repl, screen->r);
}
static void
-cacheimg(Rdp* c, Imgupd* u)
+cacheimage2(Rdp* c, Imgupd* up)
{int (*loadfn)(Image*,Rectangle,uchar*,int,uchar*);
int chan;
@@ -166,25 +166,25 @@
Rectangle r;
loadfn = loadbmp;
- if(u->compressed)
+ if(up->iscompr)
loadfn = loadrle;
- r = Rect(0, 0, u->xsz, u->ysz);
+ r = Rect(0, 0, up->xsz, up->ysz);
- if(u->cid >= nelem(icache) || u->coff >= nelem(*icache))
- sysfatal("cacheimg: bad cache spec [%d %d]", u->cid, u->coff);+ if(up->cid >= nelem(icache) || up->coff >= nelem(*icache))
+ sysfatal("cacheimage2: bad cache spec [%d %d]", up->cid, up->coff);- img = icache[u->cid][u->coff];
+ img = icache[up->cid][up->coff];
if(img==nil || eqrect(img->r, r)==0){chan = depth2chan(c->depth);
freeimage(img);
img = allocimage(display, r, chan, 0, DNofill);
if(img == nil)
- sysfatal("cacheimg: %r");- icache[u->cid][u->coff] = img;
+ sysfatal("cacheimage2: %r");+ icache[up->cid][up->coff] = img;
}
- if(loadfn(img, r, u->bytes, u->nbytes, c->cmap) < 0)
+ if(loadfn(img, r, up->bytes, up->nbytes, c->cmap) < 0)
sysfatal("loadmemimg: %r");}
@@ -203,7 +203,7 @@
case Ubitmap: imgupd(c, up); break;
case Uscrblt: scrblt(c, up); break;
case Umemblt: memblt(c, up); break;
- case Ucacheimg: cacheimg(c, up); break;
+ case Uicache: cacheimage2(c, up); break;
case Umcache: cachecmap(c, up); break;
}
}
--- a/eclip.c
+++ b/eclip.c
@@ -182,8 +182,8 @@
werrstr(Esmall);
return -1;
}
- iputs(a+0, m->type);
- iputs(a+2, m->flags);
+ PSHORT(a+0, m->type);
+ PSHORT(a+2, m->flags);
switch(m->type){case Cannounce:
m->data = a+8;
@@ -192,7 +192,7 @@
werrstr(Esmall);
return -1;
}
- iputl(a+8, m->fmtid);
+ PLONG(a+8, m->fmtid);
memset(a+12, 0, 32); /* fmt name - who cares? */
break;
case Crq:
@@ -202,7 +202,7 @@
werrstr(Esmall);
return -1;
}
- iputl(a+8, m->fmtid);
+ PLONG(a+8, m->fmtid);
break;
case Cnoted:
m->ndata = 0;
@@ -213,7 +213,7 @@
werrstr(Esmall);
return -1;
}
- iputl(a+4, m->ndata);
+ PLONG(a+4, m->ndata);
memcpy(a+8, m->data, m->ndata);
return 8+m->ndata;
}
@@ -228,9 +228,9 @@
werrstr(Eshort);
return -1;
}
- m->type = igets(p);
- m->flags = igets(p+2);
- len = igetl(p+4);
+ m->type = GSHORT(p);
+ m->flags = GSHORT(p+2);
+ len = GLONG(p+4);
if(8+len > n){werrstr(Eshort);
return -1;
@@ -244,7 +244,7 @@
werrstr(Eshort);
return -1;
}
- m->fmtid = igetl(m->data);
+ m->fmtid = GLONG(m->data);
break;
case Cannounce:
m->fmtid = 0;
@@ -251,7 +251,7 @@
p += 8;
ep = p+len;
while(p < ep){- m->fmtid = igetl(p);
+ m->fmtid = GLONG(p);
if(m->fmtid == FmtUnicode)
break;
p += 4+32*1;
--- a/egdi.c
+++ b/egdi.c
@@ -8,6 +8,8 @@
#include "dat.h"
#include "fns.h"
+#define DBG if(0)
+
enum
{Bits2= 3,
@@ -23,10 +25,10 @@
};
enum /* 2.2.2.2.1.1.2 Primary Drawing Order (PRIMARY_DRAWING_ORDER) */
{- Clip= 1<<2,
+ Clipped= 1<<2,
NewOrder= 1<<3,
Diff= 1<<4,
- Lastclipr= 1<<5,
+ SameClipping= 1<<5,
ZeroFieldBit0= 1<<6,
ZeroFieldBit1= 1<<7,
};
@@ -117,8 +119,8 @@
Rectangle clipr;
} gc = {PatBlt};-static int loadclipr(Rectangle*,uchar*,int);
-static int loadpt(Point*,uchar*,int,int,int);
+static int cfclipr(Rectangle*,uchar*,int);
+static int cfpt(Point*,uchar*,int,int,int);
int
getfupd(Imgupd* up, uchar* a, uint nb)
@@ -137,10 +139,10 @@
if(ctl&Secondary){if(p+6>ep)
sysfatal("draworders: %s", Eshort);- size = ((short)igets(p+1))+13;
+ size = ((short)GSHORT(p+1))+13;
if(size < 0 || p+size > ep)
sysfatal("draworders: size: %s", Eshort);- opt = igets(p+3);
+ opt = GSHORT(p+3);
xorder = p[5];
if(xorder >= nelem(auxtab) || auxtab[xorder].get == nil){fprint(2, "egdi: unsupported secondary order %d\n", xorder);
@@ -166,7 +168,7 @@
fset = p[0]|(p[1]<<8)|(p[2]<<16);
break;
case 2:
- fset = igets(p);
+ fset = GSHORT(p);
break;
case 1:
fset = p[0];
@@ -175,8 +177,8 @@
}
p += fsize;
- if(ctl&Clip && !(ctl&Lastclipr))
- p += loadclipr(&gc.clipr, p, ep-p);
+ if(ctl&Clipped && !(ctl&SameClipping))
+ p += cfclipr(&gc.clipr, p, ep-p);
if(ordtab[gc.order].get == nil)
goto ErrNotsup;
@@ -195,7 +197,7 @@
}
static int
-loadpt(Point* p, uchar* a, int nb, int isdelta, int fset)
+cfpt(Point* p, uchar* a, int nb, int isdelta, int fset)
{int n;
@@ -212,7 +214,7 @@
n += 2;
}
if(n>nb)
- sysfatal("loadpt: %s", Eshort);+ sysfatal("cfpt: %s", Eshort); if(isdelta){if(fset&1<<0)
@@ -221,28 +223,28 @@
p->y += (signed char)*a;
}else{ if(fset&1<<0){- p->x = igets(a);
+ p->x = GSHORT(a);
a += 2;
};
if(fset&1<<1)
- p->y = igets(a);
+ p->y = GSHORT(a);
}
return n;
}
static int
-loadrect(Rectangle* pr, uchar* p, int nb, int isdelta, int fset){+cfrect(Rectangle* pr, uchar* p, int nb, int isdelta, int fset){int n, m;
pr->max = subpt(pr->max, pr->min);
- n = loadpt(&pr->min, p, nb, isdelta, fset);
- m = loadpt(&pr->max, p+n, nb-n, isdelta, fset>>2);
+ n = cfpt(&pr->min, p, nb, isdelta, fset);
+ m = cfpt(&pr->max, p+n, nb-n, isdelta, fset>>2);
pr->max = addpt(pr->max, pr->min);
return n+m;
}
static int
-loadclipr(Rectangle* pr, uchar* a, int nb)
+cfclipr(Rectangle* pr, uchar* a, int nb)
{int bctl;
uchar *p, *ep;
@@ -254,29 +256,29 @@
if(bctl&1<<4)
pr->min.x += (char)*p++;
else if(bctl&1<<0){- pr->min.x = igets(p);
+ pr->min.x = GSHORT(p);
p += 2;
}
if(bctl&1<<5)
pr->min.y += (char)*p++;
else if(bctl&1<<1){- pr->min.y = igets(p);
+ pr->min.y = GSHORT(p);
p += 2;
}
if(bctl&1<<6)
pr->max.x += (char)*p++;
else if(bctl&1<<2){- pr->max.x = igets(p)+1;
+ pr->max.x = GSHORT(p)+1;
p += 2;
}
if(bctl&1<<7)
pr->max.y += (char)*p++;
else if(bctl&1<<3){- pr->max.y = igets(p)+1;
+ pr->max.y = GSHORT(p)+1;
p += 2;
}
if(p>ep)
- sysfatal("loadclipr: %s", Eshort);+ sysfatal("cfclipr: %s", Eshort);return p-a;
}
@@ -291,10 +293,11 @@
static Point wp;
static int rop3;
+DBG fprint(2, "getscrblt...");
p = a;
ep = a+nb;
- n = loadrect(&wr, p, ep-p, ctl&Diff, fset);
+ n = cfrect(&wr, p, ep-p, ctl&Diff, fset);
p += n;
if(fset&1<<4){if(ep-p<1)
@@ -301,11 +304,11 @@
sysfatal(Eshort);
rop3 = *p++;
}
- n = loadpt(&wp, p, ep-p, ctl&Diff, fset>>5);
+ n = cfpt(&wp, p, ep-p, ctl&Diff, fset>>5);
p += n;
r = wr;
- if(ctl&Clip)
+ if(ctl&Clipped)
rectclip(&r, gc.clipr);
if(rop3 != Scopy)
@@ -332,22 +335,23 @@
static Point pt;
int n;
uchar *p, *ep;
+DBG fprint(2, "getmemblt...");
p = a;
ep = a+nb;
if(fset&1<<0){- cid = igets(p);
+ cid = GSHORT(p);
p += 2;
}
- n = loadrect(&r, p, ep-p, ctl&Diff, fset>>1);
+ n = cfrect(&r, p, ep-p, ctl&Diff, fset>>1);
p += n;
if(fset&1<<5)
rop3 = *p++;
- n = loadpt(&pt, p, ep-p, ctl&Diff, fset>>6);
+ n = cfpt(&pt, p, ep-p, ctl&Diff, fset>>6);
p += n;
if(fset&1<<8){- coff = igets(p);
+ coff = GSHORT(p);
p += 2;
}
if(p>ep)
@@ -366,9 +370,9 @@
up->ysz = Dy(r);
up->sx = pt.x;
up->sy = pt.y;
- up->clip = 0;
- if(ctl&Clip){- up->clip = 1;
+ up->clipped = 0;
+ if(ctl&Clipped){+ up->clipped = 1;
up->cx = gc.clipr.min.x;
up->cy = gc.clipr.min.y;
up->cxsz = Dx(gc.clipr);
@@ -388,10 +392,11 @@
int n, g;
int size;
+DBG fprint(2, "getimgcache2...");
p = a;
ep = a+nb;
- up->compressed = (xorder==CacheCompressed2);
+ up->iscompr = (xorder==CacheCompressed2);
cid = opt&Bits3;
opt >>= 7;
@@ -431,7 +436,7 @@
g = ((g&Bits7)<<8) | *p++;
coff = g;
- if(up->compressed && !(opt&1<<3)){+ if(up->iscompr && !(opt&1<<3)){p += 8; // bitmapComprHdr
size -= 8;
}
@@ -438,7 +443,7 @@
if(p+size > ep)
sysfatal("cacheimage2: size: %s", Eshort);- up->type = Ucacheimg;
+ up->type = Uicache;
up->cid = cid;
up->coff = coff;
up->nbytes = size;
@@ -451,11 +456,12 @@
getcmapcache(Imgupd* up, uchar* a, uint nb, int xorder, int opt)
{int cid, n;
+DBG fprint(2, "getcmapcache...");
USED(xorder);
USED(opt);
cid = a[6];
- n = igets(a+7);
+ n = GSHORT(a+7);
if(n != 256)
sysfatal("cachecmap: %d != 256", n);if(9+4*256 > nb)
@@ -466,3 +472,4 @@
up->nbytes = 4*256;
return 9+4*256;
}
+
--- a/ele.c
+++ b/ele.c
@@ -111,24 +111,24 @@
*/
p[0] = CNeedLicense;
p[1] = PreambleV3;
- iputs(p+2, ndata);
- iputl(p+4, KeyExRSA);
- iputl(p+8, 0);
+ PSHORT(p+2, ndata);
+ PLONG(p+4, KeyExRSA);
+ PLONG(p+8, 0);
memset(p+12, RandomSize, 0);
p += 12+RandomSize;
- iputs(p+0, Brandom);
- iputs(p+2, 48);
+ PSHORT(p+0, Brandom);
+ PSHORT(p+2, 48);
memset(p+4, 48, 0);
p += 4+48;
- iputs(p+0, Bcuser);
- iputs(p+2, usersize);
+ PSHORT(p+0, Bcuser);
+ PSHORT(p+2, usersize);
memcpy(p+4, m->user, usersize);
p+= 4+usersize;
- iputs(p+0, Bchost);
- iputs(p+2, hostsize);
+ PSHORT(p+0, Bchost);
+ PSHORT(p+2, hostsize);
memcpy(p+4, m->sysname, hostsize);
p+= 4+hostsize;
break;
@@ -140,11 +140,11 @@
/* type[1] flags[1] size[2] errcode[4] newstate[4] blob.type[2] blob.len[2] ... */
p[0] = Notify;
p[1] = PreambleV3;
- iputs(p+2, ndata);
- iputl(p+4, errcode);
- iputl(p+8, newstate);
- iputs(p+12, Berror);
- iputs(p+14, 0);
+ PSHORT(p+2, ndata);
+ PLONG(p+4, errcode);
+ PLONG(p+8, newstate);
+ PSHORT(p+12, Berror);
+ PSHORT(p+14, 0);
break;
}
assert(p == ep);
--- a/fns.h
+++ b/fns.h
@@ -1,14 +1,4 @@
-/* byte.c*/
-short igets(uchar*);
-long igetl(uchar*);
-void iputs(uchar*, short);
-void iputl(uchar*, long);
-short nhgets(uchar*);
-long nhgetl(uchar*);
-void hnputs(uchar*, short);
-void hnputl(uchar*, long);
-
/* mcs.c */
int mcschan(uchar*,uchar*);
int mcstype(uchar*,uchar*);
@@ -60,4 +50,3 @@
void pbshort(uchar*,int);
uchar* putsdh(uchar*,uchar*,int,int,int,int);
-
--- a/load.c
+++ b/load.c
@@ -42,11 +42,11 @@
return -1;
}
a[0] = 'y';
- iputl(a+1, i->id);
- iputl(a+5, r.min.x);
- iputl(a+9, r.max.y-1);
- iputl(a+13, r.max.x);
- iputl(a+17, r.max.y);
+ BPLONG(a+1, i->id);
+ BPLONG(a+5, r.min.x);
+ BPLONG(a+9, r.max.y-1);
+ BPLONG(a+13, r.max.x);
+ BPLONG(a+17, r.max.y);
memmove(a+21, data, n);
ndata += n;
data += n;
@@ -95,7 +95,7 @@
ep = as->data + as->ndata;
cmap = c->cmap;
- n = igets(p+4);
+ n = GSHORT(p+4);
p += 8;
if(n > sizeof(c->cmap)){fprint(2, "loadcmap: data too big");
--- a/mcs.c
+++ b/mcs.c
@@ -94,9 +94,9 @@
default: werrstr(Ebignum); return nil;
case 0: *plen = 0; break;
case 1: *plen = p[0]; break;
- case 2: *plen = nhgets(p); break;
- case 3: *plen = (nhgets(p)<<8)|p[2]; break;
- case 4: *plen = nhgetl(p); break;
+ case 2: *plen = GSHORTB(p); break;
+ case 3: *plen = (GSHORTB(p)<<8)|p[2]; break;
+ case 4: *plen = GLONGB(p); break;
}
return p+c;
}
@@ -106,7 +106,7 @@
{p[0]=2;
p[1]=2;
- hnputs(p+2,v);
+ PSHORTB(p+2,v);
}
int
@@ -145,7 +145,7 @@
werrstr(Eshort);
return -1;
}
- return nhgets(p+3);
+ return GSHORTB(p+3);
}
uchar*
@@ -184,9 +184,9 @@
return -1;
}
- hnputs(p, 0x7f65); /* Connect-Initial tag */
+ PSHORTB(p, 0x7f65); /* Connect-Initial tag */
p[2] = 0x82; /* length in next 2 bytes */
- hnputs(p+3, ndata+MCSCIFIXLEN-2*2-1);
+ PSHORTB(p+3, ndata+MCSCIFIXLEN-2*2-1);
p += 5;
/* BER callingDomainSelector */
@@ -247,7 +247,7 @@
/* BER userData */
p[0] = TagOctetString;
p[1] = 0x82; /* length in next 2 bytes */
- hnputs(p+2, ndata);
+ PSHORTB(p+2, ndata);
/* userData should follow */
return MCSCIFIXLEN+ndata;
@@ -299,73 +299,71 @@
earlyCapabilityFlags = CanErrinfo;
if(depth == 32)
earlyCapabilityFlags |= Want32bpp;
- if(depth > 24)
- depth = 24;
memcpy(p, t124IdentifierKeyOid, 7);
// connectPDU as a PER octet string
- hnputs(p+7, (gccsize | 0x8000)); // connectPDU length
- hnputs(p+9, 8); // ConferenceCreateRequest
- hnputs(p+11, 16);
+ PSHORTB(p+7, (gccsize | 0x8000)); // connectPDU length
+ PSHORTB(p+9, 8); // ConferenceCreateRequest
+ PSHORTB(p+11, 16);
p[13] = 0;
- iputs(p+14, 0xC001); // userData key: h221NonStandard
+ PSHORT(p+14, 0xC001); // userData key: h221NonStandard
p[16] = 0;
memcpy(p+17, "Duca", 4); // H.221 nonstandard key (3.2.5.3.3)
- hnputs(p+21, ((gccsize-14) | 0x8000)); // userData length
+ PSHORTB(p+21, ((gccsize-14) | 0x8000)); // userData length
p += 23;
// 2.2.1.3.2 Client Core Data
- iputs(p+0, ClientCore);
- iputs(p+2, 216); // length of the data block
- iputl(p+4, ver); // rdpVersion: RDP5=0x00080004
- iputs(p+8, width); // desktopWidth ≤ 4096
- iputs(p+10, height); // desktopHeight ≤ 2048
- iputs(p+12, 0xCA01); // colorDepth=8bpp, ignored
- iputs(p+14, 0xAA03); // SASSequence
- iputl(p+16, 0x409); // keyboardLayout=us
- iputl(p+20, 2600); // clientBuild
+ PSHORT(p+0, ClientCore);
+ PSHORT(p+2, 216); // length of the data block
+ PLONG(p+4, ver); // rdpVersion: RDP5=0x00080004
+ PSHORT(p+8, width); // desktopWidth ≤ 4096
+ PSHORT(p+10, height); // desktopHeight ≤ 2048
+ PSHORT(p+12, 0xCA01); // colorDepth=8bpp, ignored
+ PSHORT(p+14, 0xAA03); // SASSequence
+ PLONG(p+16, 0x409); // keyboardLayout=us
+ PLONG(p+20, 2600); // clientBuild
memset(p+24, 32, 0); // clientName[32]
toutf16(p+24, 32, sysname, strlen(sysname)+1);
- iputs(p+54, 0); // zero-terminateclientName
- iputl(p+56, 4); // keyboardType: 4="IBM enhanced (101-key or 102-key)"
- iputl(p+60, 0); // keyboardSubType
- iputl(p+64, 12); // keyboardFunctionKey
+ PSHORT(p+54, 0); // zero-terminateclientName
+ PLONG(p+56, 4); // keyboardType: 4="IBM enhanced (101-key or 102-key)"
+ PLONG(p+60, 0); // keyboardSubType
+ PLONG(p+64, 12); // keyboardFunctionKey
memset(p+68, 64, 0); // imeFileName[64]
- iputs(p+132, 0xCA01); // postBeta2ColorDepth=8bpp, ignored
- iputs(p+134, 1); // clientProductId
- iputl(p+136, 0); // serialNumber
- iputs(p+140, depth); // highColorDepth: 4, 8, 15, 16, 24 bpp.
- iputs(p+142, 1+2+4+8); // supportedColorDepths: 1=24, 2=16, 4=15, 8=32 bpp
- iputs(p+144, earlyCapabilityFlags); // earlyCapabilityFlags
+ PSHORT(p+132, 0xCA01); // postBeta2ColorDepth=8bpp, ignored
+ PSHORT(p+134, 1); // clientProductId
+ PLONG(p+136, 0); // serialNumber
+ PSHORT(p+140, MIN(depth, 24)); // highColorDepth: 4, 8, 15, 16, 24 bpp.
+ PSHORT(p+142, 1+2+4+8); // supportedColorDepths: 1=24, 2=16, 4=15, 8=32 bpp
+ PSHORT(p+144, earlyCapabilityFlags); // earlyCapabilityFlags
memset(p+146, 64, 0); // clientDigProductId[64]
p[210] = 7; // connectionType: 7=autodetect
p[211] = 0; // pad1octet
- iputl(p+212, sproto); // serverSelectedProtocol
+ PLONG(p+212, sproto); // serverSelectedProtocol
p += 216;
// 2.2.1.3.3 Client Security Data
- iputs(p+0, ClientSec);
- iputs(p+2, 12); // length of the data block
- iputl(p+4, 0); // (legacy) encryptionMethods
- iputl(p+8, 0); // extEncryptionMethods
+ PSHORT(p+0, ClientSec);
+ PSHORT(p+2, 12); // length of the data block
+ PLONG(p+4, 0); // (legacy) encryptionMethods
+ PLONG(p+8, 0); // extEncryptionMethods
p += 12;
// 2.2.1.3.5 Client Cluster Data *optional*
- iputs(p+0, ClientCluster);
- iputs(p+2, 12); // length of the data block
- iputl(p+4, (wantconsole? 11 : 9)); // Flags
- iputl(p+8, 0); // RedirectedSessionID
+ PSHORT(p+0, ClientCluster);
+ PSHORT(p+2, 12); // length of the data block
+ PLONG(p+4, (wantconsole? 11 : 9)); // Flags
+ PLONG(p+8, 0); // RedirectedSessionID
p += 12;
// 2.2.1.3.4 Client Network Data *optional*
// type[2] len[2] nchan[4] nchan*(name[8] options[4])
- iputs(p+0, ClientNet);
- iputs(p+2, 8+12*nv);
- iputl(p+4, nv);
+ PSHORT(p+0, ClientNet);
+ PSHORT(p+2, 8+12*nv);
+ PLONG(p+4, nv);
for(i=0; i<nv; i++){memcpy(p+8+12*i+0, v[i].name, 8);
- hnputl(p+8+12*i+8, v[i].flags);
+ PLONGB(p+8+12*i+8, v[i].flags);
}
p += 8+12*nv;
@@ -423,11 +421,11 @@
while(p<ep){/* 2.2.1.3.1 User Data Header (TS_UD_HEADER) */
- utype = igets(p+0);
- ulen = igets(p+2);
+ utype = GSHORT(p+0);
+ ulen = GSHORT(p+2);
switch(utype){case SrvCore: /* 2.2.1.4.2 Server Core Data */
- m->ver = igetl(p+4);
+ m->ver = GLONG(p+4);
break;
/* BUG: exract channel IDs from SrvNet */
}
@@ -447,9 +445,9 @@
}
p[0] = (Msdr<<2);
- hnputs(p+1, mcsuid);
- hnputs(p+3, chanid);
+ PSHORTB(p+1, mcsuid);
+ PSHORTB(p+3, chanid);
p[5] = 0x70;
- hnputs(p+6, ndata|0x8000);
+ PSHORTB(p+6, ndata|0x8000);
return 8;
}
--- a/mkfile
+++ b/mkfile
@@ -8,10 +8,10 @@
OFILES=\
alloc.$O\
audio.$O\
- byte.$O\
cap.$O\
draw.$O\
eclip.$O\
+ efs.$O\
egdi.$O\
ele.$O\
kbd.$O\
@@ -31,7 +31,11 @@
x224.$O\
THREADOFILES=${OFILES:rd.$O=rd-thread.$O}-CLEANFILES=$O.thread
+CLEANFILES=$O.thread $O.test
+TESTHFILES=audio.c
+TESTOFILES=\
+ efs_test.$O efs.$O utf16.$O \
+ aud_test.$O
</sys/src/cmd/mkone
#<$PLAN9/src/mkone
@@ -40,6 +44,12 @@
default:V: $O.thread
all:V: $O.thread
+test:V: $O.test
+ $O.test
$O.thread: $THREADOFILES $LIB
+ $LD $LDFLAGS -o $target $prereq
+
+$TESTOFILES: $TESTHFILES
+$O.test: $TESTOFILES $LIB
$LD $LDFLAGS -o $target $prereq
--- a/mpas.c
+++ b/mpas.c
@@ -83,7 +83,7 @@
werrstr(Eshort);
return -1;
}
- nb = igets(p);
+ nb = GSHORT(p);
p += 2;
q = p+nb;
if(cflags&Pcompress){@@ -105,7 +105,7 @@
return -1;
}
as->type = ShUorders;
- as->nr = igets(p);
+ as->nr = GSHORT(p);
as->data = p+2;
as->ndata = ep-(p+2);
break;
@@ -115,7 +115,7 @@
return -1;
}
as->type = ShUimg;
- as->nr = igets(p+2);
+ as->nr = GSHORT(p+2);
as->data = p+4;
as->ndata = ep-(p+4);
break;
@@ -130,8 +130,8 @@
return -1;
}
as->type = ShUwarp;
- as->x = igets(p+0);
- as->y = igets(p+2);
+ as->x = GSHORT(p+0);
+ as->y = GSHORT(p+2);
break;
}
return q-a;
@@ -157,13 +157,13 @@
werrstr(Eshort);
return -1;
}
- len = igets(p);
+ len = GSHORT(p);
if(len < SCHSIZE || len > nb){ werrstr("bad length in Share Control PDU header");return -1;
}
- type = igets(p+2)&Bits4;
- as->source = igets(p+4);
+ type = GSHORT(p+2)&Bits4;
+ as->source = GSHORT(p+4);
switch(type){case PDUactivate:
@@ -176,15 +176,15 @@
werrstr(Eshort);
return -1;
}
- as->shareid = igetl(p+6);
- nsrc = igets(p+10);
- as->ndata = igets(p+12);
+ as->shareid = GLONG(p+6);
+ nsrc = GSHORT(p+10);
+ as->ndata = GSHORT(p+12);
if(len<14+nsrc+as->ndata){werrstr(Eshort);
return -1;
}
as->data = p+14+nsrc;
- as->ncap = igets(p+14+nsrc);
+ as->ncap = GSHORT(p+14+nsrc);
break;
case PDUdeactivate:
as->type = ShDeactivate;
@@ -204,10 +204,10 @@
return -1;
}
- ulen = igets(p+12);
+ ulen = GSHORT(p+12);
pduType2 = p[14];
ctype = p[15];
- clen = igets(p+16) - SCDSIZE;
+ clen = GSHORT(p+16) - SCDSIZE;
p += 18;
if(ctype&(1<<5)){@@ -243,7 +243,7 @@
return -1;
}
as->type = ShEinfo;
- as->err = igetl(p);
+ as->err = GLONG(p);
break;
case ADdraw:
/* 2.2.9.1.1.3.1 Slow-Path Graphics Update (TS_GRAPHICS_UPDATE) */
@@ -252,7 +252,7 @@
werrstr("ADdraw: %s", Eshort);return -1;
}
- uptype = igets(p);
+ uptype = GSHORT(p);
switch(uptype){case UpdOrders:
if(p+8 > ep){@@ -260,7 +260,7 @@
return -1;
}
as->type = ShUorders;
- as->nr = igets(p+4);
+ as->nr = GSHORT(p+4);
as->data = p+8;
as->ndata = ep-(p+8);
break;
@@ -270,7 +270,7 @@
return -1;
}
as->type = ShUimg;
- as->nr = igets(p+2);
+ as->nr = GSHORT(p+2);
as->data = p+4;
as->ndata = ep-(p+4);
break;
@@ -287,7 +287,7 @@
werrstr(Eshort);
return -1;
}
- mtype = igets(p);
+ mtype = GSHORT(p);
if(mtype == PDUcursorwarp){ if(p+8 > ep){werrstr(Eshort);
@@ -294,8 +294,8 @@
return -1;
}
as->type = ShUwarp;
- as->x = igets(p+4);
- as->y = igets(p+6);
+ as->x = GSHORT(p+4);
+ as->y = GSHORT(p+6);
break;
}
}
@@ -306,7 +306,7 @@
/* 2.2.9.1.1.3.1.2.2 Bitmap Data (TS_BITMAP_DATA) */
int
-getimgupd(Imgupd* u, uchar* a, uint nb)
+getimgupd(Imgupd* iu, uchar* a, uint nb)
{uchar *p, *ep, *s;
int opt, len;
@@ -317,16 +317,16 @@
werrstr(Eshort);
return -1;
}
- u->type = Ubitmap;
- u->x = igets(p+0);
- u->y = igets(p+2);
- u->xm = igets(p+4);
- u->ym = igets(p+6);
- u->xsz = igets(p+8);
- u->ysz = igets(p+10);
- u->depth = igets(p+12);
- opt = igets(p+14);
- len = igets(p+16);
+ iu->type = Ubitmap;
+ iu->x = GSHORT(p+0);
+ iu->y = GSHORT(p+2);
+ iu->xm = GSHORT(p+4);
+ iu->ym = GSHORT(p+6);
+ iu->xsz = GSHORT(p+8);
+ iu->ysz = GSHORT(p+10);
+ iu->depth = GSHORT(p+12);
+ opt = GSHORT(p+14);
+ len = GSHORT(p+16);
p += 18;
s = p+len;
if(s > ep){@@ -333,11 +333,11 @@
werrstr(Eshort);
return -1;
}
- u->compressed = (opt&Bcompress);
+ iu->iscompr = (opt&Bcompress);
if(opt&Bcompress && !(opt&NoBitcomphdr))
p += 8;
- u->bytes = p;
- u->nbytes = s-p;
+ iu->bytes = p;
+ iu->nbytes = s-p;
return s-a;
}
@@ -351,7 +351,7 @@
werrstr(Eshort);
return -1;
}
- marker = igets(p);
+ marker = GSHORT(p);
return marker == 0x8000;
}
@@ -386,15 +386,15 @@
/* 2.2.8.1.1.1.1 Share Control Header */
/* totalLength[2] pduType[2] PDUSource[2] */
- iputs(p+0, ndata);
- iputs(p+2, PDUactivated | (1<<4));
- iputs(p+4, userchan);
+ PSHORT(p+0, ndata);
+ PSHORT(p+2, PDUactivated | (1<<4));
+ PSHORT(p+4, userchan);
/* shareId[4] originatorId[2] sdlen[2] caplen[2] srcdesc[sdlen] ncap[2] pad[2] */
- iputl(p+6, shareid);
- iputs(p+10, originid);
- iputs(p+12, nsrc);
- iputs(p+14, capsize);
+ PLONG(p+6, shareid);
+ PSHORT(p+10, originid);
+ PSHORT(p+12, nsrc);
+ PSHORT(p+14, capsize);
memcpy(p+16, srcDesc, nsrc);
p += nsrc+16;
if((n = putcaps(p, ep-p, &caps)) < 0)
@@ -467,13 +467,13 @@
usize = p+ndata-b;
q = p;
- iputl(q+0, 0); // codePage; langId when opt&InfUnicode
- iputl(q+4, opt);
- iputs(q+8, ndom-2);
- iputs(q+10, nusr-2);
- iputs(q+12, npw-2);
- iputs(q+14, nsh-2);
- iputs(q+16, nwd-2);
+ PLONG(q+0, 0); // codePage; langId when opt&InfUnicode
+ PLONG(q+4, opt);
+ PSHORT(q+8, ndom-2);
+ PSHORT(q+10, nusr-2);
+ PSHORT(q+12, npw-2);
+ PSHORT(q+14, nsh-2);
+ PSHORT(q+16, nwd-2);
q += 18;
memcpy(q, wdom, ndom);
q += ndom;
@@ -486,13 +486,13 @@
memcpy(q, wwd, nwd);
q += nwd;
- iputs(q+0, 2); // cbClientAddress
- iputs(q+2, 0); // clientAddress
- iputs(q+4, 2); // cbClientDir
- iputs(q+6, 0); // clientDir
+ PSHORT(q+0, 2); // cbClientAddress
+ PSHORT(q+2, 0); // clientAddress
+ PSHORT(q+4, 2); // cbClientDir
+ PSHORT(q+6, 0); // clientDir
memset(q+8, 172, 0); // clientTimeZone
- iputl(q+180, 0); // clientSessionId
- iputl(q+184, perfopt); // performanceFlags
+ PLONG(q+180, 0); // clientSessionId
+ PLONG(q+184, perfopt); // performanceFlags
q += 188;
assert(q == p+ndata);
@@ -512,15 +512,15 @@
{if(p+18>ep)
sysfatal(Eshort);
- iputs(p+0, ndata);
- iputs(p+2, (PDUdata | (1<<4)));
- iputs(p+4, originid);
- iputl(p+6, shareid);
+ PSHORT(p+0, ndata);
+ PSHORT(p+2, (PDUdata | (1<<4)));
+ PSHORT(p+4, originid);
+ PLONG(p+6, shareid);
p[10] = 0; // pad1
p[11] = 1; // streamId: 1=Low, 2=Medium, 4=High
- iputs(p+12, ndata);
+ PSHORT(p+12, ndata);
p[14] = pduType2;
p[15] = 0; // compressedType
- iputs(p+16, 0); // compressedLength
+ PSHORT(p+16, 0); // compressedLength
return p+18;
}
--- a/msg.c
+++ b/msg.c
@@ -29,8 +29,8 @@
}
b[0] = m->type;
b[1] = m->flags;
- iputs(b+2, len);
- iputl(b+4, m->proto);
+ PSHORT(b+2, len);
+ PLONG(b+4, m->proto);
return len;
}
@@ -46,8 +46,8 @@
}
m->type = b[0];
m->flags = b[1];
- len = igets(b+2);
- m->proto = igetl(b+4);
+ len = GSHORT(b+2);
+ m->proto = GLONG(b+4);
if(len != 8){ werrstr("bad length in RDP Nego Response");return -1;
@@ -94,7 +94,7 @@
p += 8;
if(shdsize > 0)
- iputl(p, secflags);
+ PLONG(p, secflags);
return p + shdsize;
}
@@ -139,8 +139,8 @@
return -1;
p = b+TPDATAFIXLEN;
p[0] = (Mcjr << 2);
- hnputs(p+1, m->mcsuid);
- hnputs(p+3, m->chanid);
+ PSHORTB(p+1, m->mcsuid);
+ PSHORTB(p+3, m->chanid);
return n;
case Merectdom:
@@ -149,8 +149,8 @@
return -1;
p = b+TPDATAFIXLEN;
p[0] = (Medr << 2);
- hnputs(p+1, 1);
- hnputs(p+3, 1);
+ PSHORTB(p+1, 1);
+ PSHORTB(p+3, 1);
return n;
case Mconnect:
@@ -188,8 +188,8 @@
p = txprep(b, nb, nld, m->chanid, m->originid, 0);
if(p == nil)
return -1;
- iputl(p+0, m->len);
- iputl(p+4, m->flags);
+ PLONG(p+0, m->len);
+ PLONG(p+4, m->flags);
memcpy(p+8, m->data, m->ndata);
len = p+nld-b;
return len;
@@ -201,8 +201,8 @@
return -1;
len = p+nld-b;
q = putsdh(p, p+nld, nld, ADsync, m->originid, m->shareid);
- iputs(q+0, 1); // sync message type
- iputs(q+2, m->mcsuid); // target MCS userId
+ PSHORT(q+0, 1); // sync message type
+ PSHORT(q+2, m->mcsuid); // target MCS userId
return len;
case Actl:
@@ -214,9 +214,9 @@
q = putsdh(p, p+nld, nld, ADctl, m->originid, m->shareid);
/* action[2] grantId[2] controlId[2] */
- iputs(q+0, m->action);
- iputs(q+2, 0);
- iputl(q+4, 0);
+ PSHORT(q+0, m->action);
+ PSHORT(q+2, 0);
+ PLONG(q+4, 0);
return len;
case Afontls:
@@ -227,10 +227,10 @@
len = p+nld-b;
q = putsdh(p, p+nld, nld, ADfontlist, m->originid, m->shareid);
- iputs(q+0, 0); // numberFonts
- iputs(q+2, 0); // totalNumFonts
- iputs(q+4, 2+1); // listFlags: 1=first, 2=last
- iputs(q+6, 50); // entrySize
+ PSHORT(q+0, 0); // numberFonts
+ PSHORT(q+2, 0); // totalNumFonts
+ PSHORT(q+4, 2+1); // listFlags: 1=first, 2=last
+ PSHORT(q+6, 50); // entrySize
return len;
case Ainput:
@@ -241,13 +241,13 @@
len = p+nld-b;
q = putsdh(p, p+nld, nld, ADinput, m->originid, m->shareid);
- iputs(q+0, 1); /* numEvents */
- iputs(q+2, 0);
- iputl(q+4, m->msec);
- iputs(q+8, m->mtype);
- iputs(q+10, m->flags);
- iputs(q+12, m->iarg[0]);
- iputs(q+14, m->iarg[1]);
+ PSHORT(q+0, 1); /* numEvents */
+ PSHORT(q+2, 0);
+ PLONG(q+4, m->msec);
+ PSHORT(q+8, m->mtype);
+ PSHORT(q+10, m->flags);
+ PSHORT(q+12, m->iarg[0]);
+ PSHORT(q+14, m->iarg[1]);
return len;
case Lreq:
@@ -274,10 +274,10 @@
q[0] = (m->allow?1:0);
memset(q+1, 3, 0);
if(m->allow){- iputs(q+4, 0); // left
- iputs(q+6, 0); // top
- iputs(q+8, m->xsz-1); // right
- iputs(q+10, m->ysz-1); // bottom
+ PSHORT(q+4, 0); // left
+ PSHORT(q+6, 0); // top
+ PSHORT(q+8, m->xsz-1); // right
+ PSHORT(q+10, m->ysz-1); // bottom
}
return len;
@@ -356,7 +356,7 @@
werrstr(Eshort);
return -1;
}
- m->mcsuid = nhgets(p+2);
+ m->mcsuid = GSHORTB(p+2);
}
return nb;
case Mcjc:
@@ -381,8 +381,8 @@
return -1;
if(m->chanid != GLOBALCHAN){m->type = Mvchan;
- m->len = igetl(p+0);
- m->flags = igetl(p+4);
+ m->len = GLONG(p+0);
+ m->flags = GLONG(p+4);
m->data = p+8;
m->ndata = ep-p-8;
if(m->len > 8*1024*1024){@@ -395,8 +395,8 @@
m->type = Aflow;
return nb;
}
- secflg = igets(p);
- sctlver = igets(p+2)>>4;
+ secflg = GSHORT(p);
+ sctlver = GSHORT(p+2)>>4;
if(secflg&Slicensepk && sctlver != 1)
return getlicensemsg(m, p+4, ep-(p+4));
--- a/rd-thread.c
+++ b/rd-thread.c
@@ -214,3 +214,8 @@
apply(c, &r);
}
}
+
+void
+playsound(Rdp*, uchar*, uint)
+{+}
--- a/rd.c
+++ b/rd.c
@@ -23,7 +23,7 @@
static void
usage(void)
{- fprint(2, "usage: rd [-0A] [-T title] [-a depth] [-c wdir] [-d dom] [-k keyspec] [-n term] [-s shell] [net!]server[!port]\n");
+ fprint(2, "usage: rd [-0A] [-T title] [-a depth] [-c wdir] [-d dom] [-k keyspec] [-s shell] [net!]server[!port]\n");
exits("usage");}
@@ -84,6 +84,45 @@
return 0;
}
+static int afd = -1;
+
+static void
+readaudiopipe(Rdp*, int fd)
+{+ int n, afd;
+ uchar buf[4];
+
+ afd = open("/dev/audio", OWRITE);+ for(;;){+ if((n = read(fd, buf, sizeof buf)) < 0)
+ break;
+ write(afd, buf, n);
+ }
+}
+
+static int
+startaudioproc(Rdp* c)
+{+ int pid, fd[2];
+
+ if(pipe(fd) < 0)
+ sysfatal("pipe: %r");+
+ switch(pid = rfork(RFPROC|RFMEM)){+ case -1:
+ sysfatal("rfork: %r");+ case 0:
+ break;
+ default:
+ close(fd[0]);
+ afd = fd[1];
+ return pid;
+ }
+ close(fd[1]);
+ readaudiopipe(c, fd[0]);
+ return 0;
+}
+
static int killpid[32];
static int nkillpid;
@@ -185,6 +224,7 @@
atexitkill(startmouseproc(c));
atexitkill(startkbdproc(c));
atexitkill(startsnarfproc(c));
+ //atexitkill(startaudioproc(c));
readnet(c);
@@ -269,4 +309,10 @@
return;
fprint(mfd, "m%d %d", x, y);
+}
+
+void
+playsound(Rdp*, uchar* a, uint n)
+{+ write(afd, a, n);
}
--- a/rle.c
+++ b/rle.c
@@ -104,8 +104,8 @@
we = d+nd;
wasbg = 0;
wasline1 = 1;
- iputl(pen, DWhite);
- iputl(wpen, DWhite);
+ PLONG(pen, DWhite);
+ PLONG(wpen, DWhite);
while(p < ep){hdr = *p++;
@@ -129,7 +129,7 @@
}else{code = hdr&Bits4;
if(code < 9){- len = igets(p);
+ len = GSHORT(p);
p += 2;
}else
len = 0;
@@ -138,7 +138,7 @@
len *= pixelsize;
if(wp+len > we){Overrun:
- werrstr("unrle: output buffer is %zd bytes short", (intptr)(wp+len-we));+ werrstr("unrle: output buffer is %uld bytes short", wp+len-we);return nil;
}
--- a/utf16.c
+++ b/utf16.c
@@ -28,7 +28,7 @@
if(*s == '\n'){if(b+2 > eb)
break;
- iputs(b, '\r');
+ PSHORT(b, '\r');
b+=2;
}
s += chartorune(&r, s);
@@ -35,20 +35,20 @@
if(b+2 > eb)
break;
if(r <= Bits16){- iputs(b, r);
+ PSHORT(b, r);
b+=2;
continue;
}
r -= Bits16+1;
if(r > Bits20){- iputs(b, Runeerror);
+ PSHORT(b, Runeerror);
b+=2;
continue;
}
if(b+4 > eb)
break;
- iputs(b+0, HHalfZoneS | (r >> 10));
- iputs(b+2, LHalfZoneS | (r & Bits10));
+ PSHORT(b+0, HHalfZoneS | (r >> 10));
+ PSHORT(b+2, LHalfZoneS | (r & Bits10));
b+=4;
}
return b-buf;
@@ -69,7 +69,7 @@
eq = ws + nw;
while(q+2 <= eq){- w1 = igets(q);
+ w1 = GSHORT(q);
q += 2;
if(w1<HHalfZoneS || w1>LHalfZoneE){r = w1;
@@ -83,7 +83,7 @@
r = Runeerror;
goto Convert;
}
- w2 = igets(q);
+ w2 = GSHORT(q);
q += 2;
if(w2<LHalfZoneS || w2>LHalfZoneE){r = Runeerror;
--- a/vchan.c
+++ b/vchan.c
@@ -31,6 +31,12 @@
},
{.mcsid = GLOBALCHAN+2,
+ .name = "RDPDR",
+ .fn = efsvcfn,
+ .flags = Inited,
+ },
+ {+ .mcsid = GLOBALCHAN+3,
.name = "RDPSND",
.fn = audiovcfn,
.flags = Inited,
--- a/x224.c
+++ b/x224.c
@@ -60,7 +60,7 @@
break;
default:
/* TPKT-encapsulated TPDU */
- len = nhgets(p+2);
+ len = GSHORTB(p+2);
}
if(len <= n || len > nbuf){@@ -111,13 +111,13 @@
/* TPKT header: version[1] unused[1] len[2] */
p[0] = 0x03;
p[1] = 0;
- hnputs(p+2, size);
+ PSHORTB(p+2, size);
/* ConReq: hdlen[1] type[1] dstref[2] srcref[2] class[1] */
p[4+0] = 7-1+ndata;
p[4+1] = ConReq;
- hnputs(p+4+2, 0);
- hnputs(p+4+4, 0);
+ PSHORTB(p+4+2, 0);
+ PSHORTB(p+4+4, 0);
p[4+6] = 0;
return size;
@@ -140,7 +140,7 @@
/* TPKT header: version[1] unused[1] len[2] */
p[0] = 0x03;
p[1] = 0;
- hnputs(p+2, size);
+ PSHORTB(p+2, size);
/* TPDU: hdlen[1] type[1] seqno[1] */
p[4] = 2;
@@ -167,7 +167,7 @@
/* TPKT header: version[1] unused[1] len[2] */
p[0] = 0x03;
p[1] = 0;
- hnputs(p+2, size);
+ PSHORTB(p+2, size);
/* HupReq: hdlen[1] type[1] seqno[1] */
p[4] = 2;
--
⑨