1 |
Overview |
2 |
======== |
3 |
|
4 |
The RDPSND protocol is a binary, packet based protocol that maps |
5 |
Microsoft's legacy wave API to a RDP channel. |
6 |
|
7 |
All values are in little endian ordering. |
8 |
|
9 |
Responses are sent with the same opcode as the request, and usually |
10 |
also with the same packet structure. |
11 |
|
12 |
The basic structure of a packet is: |
13 |
|
14 |
0 1 2 3 |
15 |
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 |
16 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
17 |
| Opcode | Unknown | Payload size | |
18 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
19 |
| ... | |
20 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
21 |
|
22 |
Opcode |
23 |
|
24 |
Command or response type. Known values: |
25 |
|
26 |
0x01 RDPSND_CLOSE |
27 |
0x02 RDPSND_WRITE |
28 |
0x03 RDPSND_SET_VOLUME |
29 |
0x04 Unknown (4 bytes payload, no response) |
30 |
0x05 RDPSND_COMPLETION |
31 |
0x06 RDPSND_PING |
32 |
0x07 RDPSND_NEGOTIATE |
33 |
|
34 |
Unknown |
35 |
|
36 |
Usage not known. Not valid when message comes from server |
37 |
|
38 |
Payload size |
39 |
|
40 |
Number of bytes following the header. |
41 |
|
42 |
Opcodes |
43 |
======= |
44 |
|
45 |
Following is a list of all known opcodes and the contents in their |
46 |
payloads. |
47 |
|
48 |
RDPSND_CLOSE |
49 |
------------ |
50 |
|
51 |
Tells the client that all applications on the server have released |
52 |
control of the sound system, allowing the client to free any local |
53 |
resources. |
54 |
|
55 |
No payload and no response. |
56 |
|
57 |
RDPSND_WRITE |
58 |
------------ |
59 |
|
60 |
Request to play a chunk of data. The client is expected to queue up |
61 |
the data and send a RDPSND_COMPLETION when playback has finished. |
62 |
|
63 |
No response. |
64 |
|
65 |
0 1 2 3 |
66 |
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 |
67 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
68 |
| Tick | Format index | |
69 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
70 |
| Packet index | Pad | |
71 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
72 |
| Waveform data | |
73 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
74 |
| ... | |
75 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
76 |
|
77 |
Tick |
78 |
|
79 |
Low 16 bits of clock tick count when packet was scheduled for |
80 |
playback. |
81 |
|
82 |
Format index |
83 |
|
84 |
Waveform data format in the form of an index to the previously |
85 |
negotiated format list. |
86 |
|
87 |
Packet index |
88 |
|
89 |
Index number of this packet. |
90 |
|
91 |
Pad |
92 |
|
93 |
Unused padding. |
94 |
|
95 |
Waveform data |
96 |
|
97 |
Binary waveform data in the format specified by the format index. |
98 |
Size defined by the packet boundary. |
99 |
|
100 |
Because of a strange design in Microsoft's server, the length of |
101 |
the packet will be 4 bytes short and bytes 12 to 15 (4 bytes) of |
102 |
the payload should be removed. |
103 |
|
104 |
RDPSND_SET_VOLUME |
105 |
----------------- |
106 |
|
107 |
Request from the server to the client to change the output volume. |
108 |
No response. |
109 |
|
110 |
0 1 2 3 |
111 |
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 |
112 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
113 |
| Left channel | Right channel | |
114 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
115 |
|
116 |
Left channel |
117 |
|
118 |
Volume of left channel in the range [0, 65535]. |
119 |
|
120 |
Right channel |
121 |
|
122 |
Volume of right channel in the range [0, 65535]. |
123 |
|
124 |
RDPSND_COMPLETION |
125 |
----------------- |
126 |
|
127 |
Sent by the client to the server when a packet, queued by |
128 |
RDPSND_WRITE, has finished playing. |
129 |
|
130 |
No response is sent by the server. |
131 |
|
132 |
0 1 2 3 |
133 |
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 |
134 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
135 |
| Tick | Packet index | Reserved | |
136 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
137 |
|
138 |
Tick |
139 |
|
140 |
Clock tick count when packet finished playing on device. |
141 |
|
142 |
Packet index |
143 |
|
144 |
Index number of packet played. |
145 |
|
146 |
Reserved |
147 |
|
148 |
Reserved. Always 0. |
149 |
|
150 |
RDPSND_PING |
151 |
----------- |
152 |
|
153 |
Sent by the server to the client to determine transport latency. |
154 |
The client must respond by echoing the first four bytes of this |
155 |
packet. |
156 |
|
157 |
0 1 2 3 |
158 |
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 |
159 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
160 |
| Tick | Reserved | |
161 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
162 |
| Garbage | |
163 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
164 |
| ... | |
165 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
166 |
|
167 |
Tick |
168 |
|
169 |
Clock tick count when sent from server. |
170 |
|
171 |
Reserved |
172 |
|
173 |
Reserved. Always 0. |
174 |
|
175 |
Garbage |
176 |
|
177 |
1016 optional bytes of random data. Purpose unknown. |
178 |
Only sent from server. |
179 |
|
180 |
RDPSND_NEGOTIATE |
181 |
---------------- |
182 |
|
183 |
Initial packet sent by server when the client [re]connects. Allows |
184 |
the server to determine the capabilities of the client. |
185 |
|
186 |
The client should reply with an identical packet, with the relevant |
187 |
fields filled in, and a filtered list of formats (based on what the |
188 |
client supports). |
189 |
|
190 |
0 1 2 3 |
191 |
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 |
192 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
193 |
| Flags | |
194 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
195 |
| Left channel | Right channel | |
196 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
197 |
| Pitch | |
198 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
199 |
| UDP port | Format count | |
200 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
201 |
| Initial idx | Version | Padding | |
202 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
203 |
| ... | |
204 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
205 |
| Format tag | Channels | |
206 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
207 |
| Frames per sec. | |
208 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
209 |
| Bytes per sec. | |
210 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
211 |
| Block align | Bits per sample | |
212 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
213 |
| Extra size | Extra data ... | |
214 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
215 |
| ... | |
216 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
217 |
|
218 |
Flags |
219 |
|
220 |
Flags for client capabilities. Data not valid when from server. |
221 |
|
222 |
0000 0001 Do UDP song and dance (details unknown). Must be |
223 |
set for sound to work. |
224 |
0000 0002 Volume control support. Indicates that volume |
225 |
fields are valid and that the client understands |
226 |
RDPSND_SET_VOLUME. |
227 |
0000 0004 Pitch field is valid. |
228 |
|
229 |
Left channel |
230 |
|
231 |
Initial volume for left channel. Data not valid when from server. |
232 |
|
233 |
Right channel |
234 |
|
235 |
Initial volume for right channel. Data not valid when from server. |
236 |
|
237 |
Pitch |
238 |
|
239 |
Initial pitch of the sound device. Data not valid when from server. |
240 |
|
241 |
UDP port |
242 |
|
243 |
Port used for UDP transfers. Sent in network (big endian) order. |
244 |
Data not valid when from server. |
245 |
|
246 |
Format count |
247 |
|
248 |
Number of format structures following the header. |
249 |
|
250 |
Initial index |
251 |
|
252 |
Initial packet index. The first RDPSND_WRITE will have a packet |
253 |
index one larger than this value. Data not valid when from client. |
254 |
|
255 |
Version |
256 |
|
257 |
Software version. Server (XP & 2K3) sets this to 5. Client (XP) |
258 |
also sets this to 5. |
259 |
|
260 |
Padding |
261 |
|
262 |
Unused. |
263 |
|
264 |
Format tag |
265 |
|
266 |
Audio format type as registered at Microsoft. |
267 |
|
268 |
Channels |
269 |
|
270 |
Number of channels per frame. |
271 |
|
272 |
Frames per sec. |
273 |
|
274 |
Frames per second in Hz. |
275 |
|
276 |
Bytes per sec. |
277 |
|
278 |
Number of bytes per second. Should be the product of |
279 |
"Frames per sec." and "Block align". |
280 |
|
281 |
Block align |
282 |
|
283 |
The size of each frame. Note that not all bytes may contain |
284 |
useful data. |
285 |
|
286 |
Bits per sample |
287 |
|
288 |
Number of bits per sample. Commonly 8 or 16. |
289 |
|
290 |
Extra size |
291 |
|
292 |
Number of bytes of extra information following this format |
293 |
description. |
294 |
|
295 |
Extra data |
296 |
|
297 |
Optional extra format data. Contents specific to each format |
298 |
type. |