Initial commit - from Precise source
[freerdp-ubuntu-pcb-backport.git] / cunit / test_rail.c
1 /*
2    FreeRDP: A Remote Desktop Protocol client.
3    RAIL(TS RemoteApp) Virtual Channel Unit Tests
4
5    Copyright 2011 Vic Lee
6    Copyright 2011 Roman Barabanov <romanbarabanov@gmail.com>
7
8    Licensed under the Apache License, Version 2.0 (the "License");
9    you may not use this file except in compliance with the License.
10    You may obtain a copy of the License at
11
12        http://www.apache.org/licenses/LICENSE-2.0
13
14    Unless required by applicable law or agreed to in writing, software
15    distributed under the License is distributed on an "AS IS" BASIS,
16    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17    See the License for the specific language governing permissions and
18    limitations under the License.
19 */
20
21 #include <stdio.h>
22 #include <string.h>
23 #include <stdlib.h>
24 #include <unistd.h>
25 #include <pthread.h>
26
27 #include <freerdp/freerdp.h>
28 #include <freerdp/constants.h>
29 #include <freerdp/channels/channels.h>
30 #include <freerdp/utils/event.h>
31 #include <freerdp/utils/hexdump.h>
32 #include <freerdp/utils/memory.h>
33 #include <freerdp/utils/rail.h>
34 #include <freerdp/rail.h>
35
36
37 #include "test_rail.h"
38
39 #define HCF_HIGHCONTRASTON  0x00000001
40 #define HCF_AVAILABLE       0x00000002
41 #define HCF_HOTKEYACTIVE    0x00000004
42 #define HCF_CONFIRMHOTKEY   0x00000008
43 #define HCF_HOTKEYSOUND     0x00000010
44 #define HCF_INDICATOR       0x00000020
45 #define HCF_HOTKEYAVAILABLE 0x00000040
46
47
48 int init_rail_suite(void)
49 {
50         freerdp_channels_global_init();
51         return 0;
52 }
53
54 int clean_rail_suite(void)
55 {
56         freerdp_channels_global_uninit();
57         return 0;
58 }
59
60 int add_rail_suite(void)
61 {
62         add_test_suite(rail);
63
64         add_test_function(rail_plugin);
65
66         return 0;
67 }
68
69
70 static uint8 client_handshake[] =
71 {
72 0x05, 0x00, 0x08, 0x00, 0xb0, 0x1d, 0x00, 0x00
73 };
74
75 static uint8 client_info_pdu[] =
76 {
77 0x0b, 0x00, 0x08, 0x00, 0x01, 0x00, 0x00, 0x00
78 };
79
80 // Flags: TS_RAIL_EXEC_FLAG_EXPAND_ARGUMENTS
81 // ExeOrFile : ||iexplore
82 // WorkingDir: f:\windows\system32
83 // Arguments: www.bing.com
84
85 static uint8 client_execute_pdu[] =
86 {
87 0x01,0x00,0x5e,0x00,0x08,0x00,0x14,0x00,0x26,0x00,0x18,0x00,0x7c,0x00,
88 0x7c,0x00,0x69,0x00,0x65,0x00,0x78,0x00,0x70,0x00,0x6c,0x00,0x6f,0x00,
89 0x72,0x00,0x65,0x00,0x66,0x00,0x3a,0x00,0x5c,0x00,0x77,0x00,0x69,0x00,
90 0x6e,0x00,0x64,0x00,0x6f,0x00,0x77,0x00,0x73,0x00,0x5c,0x00,0x73,0x00,
91 0x79,0x00,0x73,0x00,0x74,0x00,0x65,0x00,0x6d,0x00,0x33,0x00,0x32,0x00,
92 0x77,0x00,0x77,0x00,0x77,0x00,0x2e,0x00,0x62,0x00,0x69,0x00,0x6e,0x00,
93 0x67,0x00,0x2e,0x00,0x63,0x00,0x6f,0x00,0x6d,0x00
94 };
95
96 static uint8 client_activate_pdu[] =
97 {
98 0x02,0x00,
99 0x09,0x00,
100 0x8e,0x00,0x07,0x00,
101 0x01
102 };
103
104
105
106 static uint8 client_sysparam_highcontrast_pdu[] =
107 {
108 0x03,0x00,
109 0x12,0x00,
110 0x43,0x00,0x00,0x00, // SPI_SETHIGHCONTRAST
111 0x7e,0x00,0x00,0x00, // HCF_AVAILABLE | HCF_HOTKEYACTIVE | HCF_CONFIRMHOTKEY
112                      // HCF_HOTKEYSOUND | HCF_INDICATOR | HCF_HOTKEYAVAILABLE
113 0x02,0x00,0x00,0x00, // Minimum length 2
114 0x00,0x00 // Unicode String
115 };
116
117
118 static uint8 client_sysparam_taskbarpos_pdu[] =
119 {
120 0x03,0x00,
121 0x10,0x00,
122 0x00,0xf0,0x00,0x00, // RAIL_SPI_TASKBARPOS
123 0x00,0x00, // 0
124 0x9a,0x03, // 0x039a
125 0x90,0x06, // 0x0690
126 0xc2,0x03  // 0x03c2
127 };
128
129 static uint8 client_sysparam_mousebuttonswap_pdu[] =
130 {
131 0x03,0x00,
132 0x09,0x00,
133 0x21,0x00,0x00,0x00, // SPI_SETMOUSEBUTTONSWAP
134 0x00 // false
135 };
136
137
138 static uint8 client_sysparam_keyboardpref_pdu[] =
139 {
140 0x03,0x00,
141 0x09,0x00,
142 0x45,0x00,0x00,0x00, // SPI_SETKEYBOARDPREF
143 0x00 // false
144 };
145
146
147 static uint8 client_sysparam_dragfullwindow_pdu[] =
148 {
149 0x03,0x00,
150 0x09,0x00,
151 0x25,0x00,0x00,0x00, // SPI_SETDRAGFULLWINDOWS
152 0x01 // true
153 };
154
155
156 static uint8 client_sysparam_keyboardcues_pdu[] =
157 {
158 0x03,0x00,
159 0x09,0x00,
160 0x0b,0x10,0x00,0x00, //SPI_SETKEYBOARDCUES
161 0x00 // false
162 };
163
164 static uint8 client_sysparam_setworkarea_pdu[] =
165 {
166 0x03,0x00,
167 0x10,0x00,
168 0x2f,0x00,0x00,0x00, //SPI_SETWORKAREA
169 0x00,0x00, // 0
170 0x00,0x00, // 0
171 0x90,0x06, // 0x0690
172 0x9a,0x03  // 0x039a
173 };
174
175 static uint8 client_syscommand_pdu[] =
176 {
177 0x04,0x00,
178 0x0a,0x00,
179 0x52,0x00,0x02,0x00,
180 0x20,0xf0
181 };
182
183 static uint8 client_notify_pdu[] =
184 {
185 0x06,0x00,
186 0x10,0x00,
187 0xaa,0x01,0x02,0x00,
188 0x02,0x00,0x00,0x00,
189 0x04,0x02,0x00,0x00
190 };
191
192 static uint8 client_windowmove_pdu[] =
193 {
194 0x08,0x00,
195 0x10,0x00,
196 0x20,0x00,0x02,0x00,
197 0x09,0x03,
198 0x00,0x01,
199 0xdb,0x05,
200 0x88,0x01
201 };
202
203 static uint8 client_system_menu_pdu[] =
204 {
205 0x0c,0x00,
206 0x0c,0x00,
207 0x22,0x01,0x09,0x00,
208 0xa4,0xff,
209 0x4a,0x02
210 };
211
212 static uint8 client_langbar_pdu[] =
213 {
214 0x0D,0x00,0x08,0x00,0x01,0x00,0x00,0x00
215 };
216
217 static uint8 client_get_app_id_req_pdu[] =
218 {
219 0x0E,0x00,0x08,0x00,0x52,0x00,0x02,0x00
220 };
221
222 static uint8 server_handshake[] =
223 {
224         0x05, 0x00, 0x08, 0x00, 0xb0, 0x1d, 0x00, 0x00
225 };
226
227 static uint8 server_exec_result_pdu[] =
228 {
229 0x80,0x00,0x24,0x00,0x08,0x00,0x03,0x00,0x15,0x00,0x00,0x00,0x00,0x00,
230 0x14,0x00,0x7c,0x00,0x7c,0x00,0x57,0x00,0x72,0x00,0x6f,0x00,0x6e,0x00,
231 0x67,0x00,0x41,0x00,0x70,0x00,0x70,0x00
232 };
233
234 static uint8 server_exec_result_exe_or_file[] =
235 {
236 0x7c,0x00,0x7c,0x00,0x57,0x00,0x72,0x00,0x6f,0x00,0x6e,0x00,
237 0x67,0x00,0x41,0x00,0x70,0x00,0x70,0x00
238 };
239
240 static uint8 server_sysparam1_pdu[] =
241 {
242 0x03,0x00,
243 0x09,0x00,
244 0x77,0x00,0x00,0x00,
245 0x00
246 };
247
248 static uint8 server_sysparam2_pdu[] =
249 {
250 0x03,0x00,
251 0x09,0x00,
252 0x11,0x00,0x00,0x00,
253 0x00
254 };
255
256 static uint8 server_localmovesize_start_pdu[] =
257 {
258 0x09,0x00,0x10,0x00,0x8e,0x00,0x07,0x00,0x01,0x00,0x09,0x00,0x7e,0x01,
259 0x0a,0x00
260 };
261
262 static uint8 server_localmovesize_stop_pdu[] =
263 {
264 0x09,0x00,0x10,0x00,0x8e,0x00,0x07,0x00,0x00,0x00,0x09,0x00,0xa6,0x00,
265 0x44,0x00
266 };
267
268 static uint8 server_minmaxinfo_pdu[] =
269 {
270 0x0a,0x00,0x18,0x00,0x8e,0x00,0x07,0x00,0x08,0x04,0xd6,0x02,0x00,0x00,
271 0x00,0x00,0x70,0x00,0x1b,0x00,0x0c,0x04,0x0c,0x03
272 };
273
274 static uint8 server_langbar_pdu[] =
275 {
276 0x0D,0x00,0x08,0x00,0x01,0x00,0x00,0x00
277 };
278
279
280 static uint8 server_app_get_resp_pdu[] =
281 {
282 0x0F,0x00,0x08,0x02,0x52,0x00,0x02,0x00,0x6d,0x00,0x69,0x00,0x63,0x00,
283 0x72,0x00,0x6f,0x00,0x73,0x00,0x6f,0x00,0x66,0x00,0x74,0x00,0x2e,0x00,
284 0x77,0x00,0x69,0x00,0x6e,0x6f,0x00,0x77,0x00,0x73,0x00,0x2e,0x00,0x6e,
285 0x00,0x6f,0x00,0x74,0x00,0x65,0x00,0x70,0x00,0x61,0x00,0x64,0x00,0x00,
286 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
287 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
288 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
289 0x00,0x00,
290
291 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
292 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
293 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
294 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
295 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
296 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
297 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
298 0x00,0x00,
299
300 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
301 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
302 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
303 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
304 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
305 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
306 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
307 0x00,0x00,
308
309 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
310 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
311 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
312 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
313 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
314 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
315 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
316 0x00,0x00,
317
318 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
319 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
320 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
321 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
322 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
323 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
324 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
325 0x00,0x00,
326
327 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
328 0x00,0x00,0x00,0x00,0x00,0x00
329 };
330
331 static uint8 server_app_get_resp_app_id[] =
332 {
333 0x6d,0x00,0x69,0x00,0x63,0x00,0x72,0x00,0x6f,0x00,0x73,0x00,0x6f,0x00,
334 0x66,0x00,0x74,0x00,0x2e,0x00,0x77,0x00,0x69,0x00,0x6e,0x6f,0x00,0x77,
335 0x00,0x73,0x00,0x2e,0x00,0x6e,0x00,0x6f,0x00,0x74,0x00,0x65,0x00,0x70,
336 0x00,0x61,0x00,0x64,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
337 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
338 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
339 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
340
341 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
342 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
343 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
344 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
345 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
346 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
347 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
348 0x00,0x00,
349
350 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
351 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
352 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
353 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
354 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
355 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
356 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
357 0x00,0x00,
358
359 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
360 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
361 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
362 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
363 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
364 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
365 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
366 0x00,0x00,
367
368 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
369 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
370 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
371 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
372 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
373 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
374 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
375 0x00,0x00,
376
377 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
378 0x00,0x00,0x00,0x00,0x00,0x00
379 };
380
381
382 #define EMULATE_SERVER_SEND_CHANNEL_DATA(inst, byte_array) \
383         emulate_server_send_channel_data(inst, byte_array, RAIL_ARRAY_SIZE(byte_array))
384
385 #define STREAM_EQUAL_TO_DUMP(stream, dump) \
386         (stream_equal_dump((stream)->data, (stream)->size, dump, RAIL_ARRAY_SIZE(dump)))
387
388 #define UNICODE_STRING_EQUAL_TO_DUMP(ustring, dump) \
389         (stream_equal_dump((ustring)->string, (ustring)->length, dump, RAIL_ARRAY_SIZE(dump)))
390
391 typedef struct
392 {
393         RAIL_HANDSHAKE_ORDER handshake;
394         RAIL_CLIENT_STATUS_ORDER client_status;
395         RAIL_EXEC_ORDER exec;
396         RAIL_EXEC_RESULT_ORDER exec_result;
397         RAIL_SYSPARAM_ORDER sysparam;
398         RAIL_ACTIVATE_ORDER activate;
399         RAIL_SYSMENU_ORDER sysmenu;
400         RAIL_SYSCOMMAND_ORDER syscommand;
401         RAIL_NOTIFY_EVENT_ORDER notify_event;
402         RAIL_MINMAXINFO_ORDER minmaxinfo;
403         RAIL_LOCALMOVESIZE_ORDER localmovesize;
404         RAIL_WINDOW_MOVE_ORDER window_move;
405         RAIL_LANGBAR_INFO_ORDER langbar_info;
406         RAIL_GET_APPID_REQ_ORDER get_appid_req;
407         RAIL_GET_APPID_RESP_ORDER get_appid_resp;
408
409 } RAIL_ORDERS;
410
411 typedef struct
412 {
413         RAIL_ORDERS order_info;
414         uint32 event_type;
415 }
416 RAIL_EVENT;
417
418 typedef struct
419 {
420         rdpChannels* chan_man;
421         freerdp*    instance;
422         int         th_count;
423         int         th_to_finish;
424
425         RAIL_ORDERS out_rail_orders;
426
427         RAIL_EVENT  in_events[20];
428         size_t      in_events_number;
429
430         STREAM      in_streams[20];
431         size_t      in_streams_number;
432
433         RDP_PLUGIN_DATA plugin_data;
434
435
436 } thread_param;
437
438 static thread_param* global_thread_params = NULL;
439
440 //-----------------------------------------------------------------------------
441 int stream_equal_dump(void * dataS, size_t sizeS, void * data, size_t size)
442 {
443         size_t i;
444         if (sizeS != size)
445         {
446                 printf("----------------- stream_equal_dump -----------------\n");
447                 printf("Stream and dump have different length (%d != %d)\n",
448                         (int) sizeS, (int) size);
449                 printf("Stream hexdump:\n");
450                 freerdp_hexdump(dataS, sizeS);
451
452                 printf("Dump hexdump:\n");
453                 freerdp_hexdump(data, size);
454
455                 printf("----------------- stream_equal_dump -----------------\n");
456                 return 0;
457         }
458
459
460         for (i=0; i < size; i++)
461         {
462                 if (((uint8*)dataS)[i] != ((uint8*)data)[i])
463                 {
464                         printf("----------------- stream_equal_dump -----------------\n");
465                         printf("Stream and dump have different content from %d offset.\n", (int) i);
466                         printf("Stream hexdump:\n");
467                         freerdp_hexdump(dataS, sizeS);
468
469                         printf("Dump hexdump:\n");
470                         freerdp_hexdump(data, size);
471                         printf("----------------- stream_equal_dump -----------------\n");
472                         return 0;
473                 }
474         }
475
476         return 1;
477 }
478 //-----------------------------------------------------------------------------
479 static void test_on_free_rail_client_event(RDP_EVENT* event)
480 {
481         if (event->event_class == RDP_EVENT_CLASS_RAIL)
482         {
483                 rail_free_cloned_order(event->event_type, event->user_data);
484         }
485 }
486 //-----------------------------------------------------------------------------
487 static void send_ui_event2plugin(
488         rdpChannels* chan_man,
489         uint16 event_type,
490         void * data
491         )
492 {
493         RDP_EVENT* out_event = NULL;
494         void * payload = NULL;
495
496         payload = rail_clone_order(event_type, data);
497         if (payload != NULL)
498         {
499                 out_event = freerdp_event_new(RDP_EVENT_CLASS_RAIL, event_type,
500                                 test_on_free_rail_client_event, payload);
501                 freerdp_channels_send_event(chan_man, out_event);
502         }
503 }
504 //-----------------------------------------------------------------------------
505 static void emulate_server_send_channel_data(
506         freerdp* instance,
507         void* data,
508         size_t size
509         )
510 {
511         static int counter = 0;
512         counter++;
513
514         printf("Emulate server packet (%d packet):\n", counter);
515         freerdp_hexdump(data, size);
516
517         freerdp_channels_data(instance, 0, (char*)data, size,
518                         CHANNEL_FLAG_FIRST | CHANNEL_FLAG_LAST, size);
519         usleep(10*1000);
520 }
521 static void save_dump(void* data, size_t size)
522 {
523         thread_param * p = global_thread_params;
524         if (p->in_streams_number < RAIL_ARRAY_SIZE(p->in_streams))
525         {
526                 STREAM* s = &p->in_streams[p->in_streams_number];
527                 s->data = malloc(size);
528                 s->size = size;
529
530                 memcpy(s->data, data, size);
531                 p->in_streams_number++;
532         }
533 }
534 //-----------------------------------------------------------------------------
535 static int emulate_client_send_channel_data(
536         freerdp* freerdp, int channelId, uint8* data, int size
537         )
538 {
539         static int counter = 0;
540         counter++;
541
542         printf("Client send to server (%d packet):\n", counter);
543         freerdp_hexdump(data, size);
544
545         // add to global dumps list
546         save_dump(data, size);
547
548         return 0;
549 }
550 //-----------------------------------------------------------------------------
551 void save_event(RDP_EVENT* event, RAIL_EVENT* rail_event)
552 {
553         rail_event->event_type = event->event_type;
554
555         switch (event->event_type)
556         {
557                 case RDP_EVENT_TYPE_RAIL_CHANNEL_GET_SYSPARAMS:
558                         printf("UI receive Get Sysparams Event\n");
559                         break;
560
561                 case RDP_EVENT_TYPE_RAIL_CHANNEL_EXEC_RESULTS:
562                         {
563                                 RAIL_EXEC_RESULT_ORDER* exec_result = (RAIL_EXEC_RESULT_ORDER*)event->user_data;
564                                 printf("UI receive Exec Results Event\n");
565                                 memcpy(&rail_event->order_info.exec_result, event->user_data,
566                                         sizeof(RAIL_EXEC_RESULT_ORDER));
567
568                                 rail_unicode_string_alloc(&rail_event->order_info.exec_result.exeOrFile,
569                                                 exec_result->exeOrFile.length);
570
571                                 memcpy(rail_event->order_info.exec_result.exeOrFile.string,
572                                         exec_result->exeOrFile.string,
573                                         exec_result->exeOrFile.length);
574                         }
575                         break;
576
577                 case RDP_EVENT_TYPE_RAIL_CHANNEL_SERVER_SYSPARAM:
578                         printf("UI receive Server Sysparam Event\n");
579                         memcpy(&rail_event->order_info.sysparam, event->user_data,
580                                 sizeof(RAIL_SYSPARAM_ORDER));
581                         break;
582
583                 case RDP_EVENT_TYPE_RAIL_CHANNEL_SERVER_MINMAXINFO:
584                         printf("UI receive Server Minmax Info Event\n");
585                         memcpy(&rail_event->order_info.minmaxinfo, event->user_data,
586                                 sizeof(RAIL_MINMAXINFO_ORDER));
587                         break;
588
589                 case RDP_EVENT_TYPE_RAIL_CHANNEL_SERVER_LOCALMOVESIZE:
590                         printf("UI receive Server Local Movesize Event\n");
591                         memcpy(&rail_event->order_info.localmovesize, event->user_data,
592                                 sizeof(RAIL_LOCALMOVESIZE_ORDER));
593                         break;
594
595                 case RDP_EVENT_TYPE_RAIL_CHANNEL_APPID_RESP:
596                         printf("UI receive AppId Response Event\n");
597                         memcpy(&rail_event->order_info.get_appid_resp, event->user_data,
598                                 sizeof(RAIL_GET_APPID_RESP_ORDER));
599
600                         rail_event->order_info.get_appid_resp.applicationId.string =
601                                 &rail_event->order_info.get_appid_resp.applicationIdBuffer[0];
602                         break;
603
604                 case RDP_EVENT_TYPE_RAIL_CHANNEL_LANGBARINFO:
605                         printf("UI receive Language Info Event\n");
606                         memcpy(&rail_event->order_info.langbar_info, event->user_data,
607                                 sizeof(RAIL_LANGBAR_INFO_ORDER));
608                         break;
609         }
610 }
611 //-----------------------------------------------------------------------------
612 static void process_events_and_channel_data_from_plugin(thread_param* param)
613 {
614         RDP_EVENT* event;
615
616         param->th_count++;
617         while (param->th_to_finish == 0)
618         {
619                 freerdp_channels_check_fds(param->chan_man, param->instance);
620
621                 while (1)
622                 {
623                         event = freerdp_channels_pop_event(param->chan_man);
624                         if (event == NULL) break;
625
626                         static int counter = 0;
627                         counter++;
628
629                         printf("UI receive event. (type=%d counter=%d).\n",
630                                         event->event_type,
631                                         counter);
632
633                         // add to global event list
634                         if (param->in_events_number < RAIL_ARRAY_SIZE(param->in_events))
635                         {
636                                 save_event(event, &param->in_events[param->in_events_number]);
637                                 param->in_events_number++;
638                         }
639                         freerdp_event_free(event);
640                 }
641
642                 usleep(1000);
643         }
644         param->th_count--;
645 }
646 //-----------------------------------------------------------------------------
647 void* thread_func(void* param)
648 {
649         thread_param* th_param = (thread_param*)param;
650         process_events_and_channel_data_from_plugin(th_param);
651         pthread_detach(pthread_self());
652
653         return NULL;
654 }
655 //-----------------------------------------------------------------------------
656 void test_rail_plugin(void)
657 {
658         thread_param param;
659         pthread_t thread;
660
661         rdpChannels* chan_man;
662         rdpSettings settings = { 0 };
663         freerdp s_inst = { 0 };
664         freerdp* inst = &s_inst;
665         size_t sn = 0;
666         size_t en = 0;
667         STREAM* ss = NULL;
668         RAIL_EVENT* ee = NULL;
669
670         printf("\n");
671
672         settings.hostname = "testhost";
673         inst->settings = &settings;
674         inst->SendChannelData = emulate_client_send_channel_data;
675
676         chan_man = freerdp_channels_new();
677
678         freerdp_channels_load_plugin(chan_man, &settings, "../channels/rail/rail.so", NULL);
679         freerdp_channels_pre_connect(chan_man, inst);
680         freerdp_channels_post_connect(chan_man, inst);
681
682         memset(&param, 0, sizeof(param));
683
684         param.chan_man = chan_man;
685         param.instance = inst;
686         param.th_count = 0;
687         param.th_to_finish = 0;
688
689         global_thread_params = &param;
690
691         pthread_create(&thread, 0, thread_func, &param);
692
693         // 1. Emulate server handshake binary
694         EMULATE_SERVER_SEND_CHANNEL_DATA(inst, server_handshake);
695         EMULATE_SERVER_SEND_CHANNEL_DATA(inst, server_exec_result_pdu);
696         EMULATE_SERVER_SEND_CHANNEL_DATA(inst, server_sysparam1_pdu);
697         EMULATE_SERVER_SEND_CHANNEL_DATA(inst, server_sysparam2_pdu);
698         EMULATE_SERVER_SEND_CHANNEL_DATA(inst, server_localmovesize_start_pdu);
699         EMULATE_SERVER_SEND_CHANNEL_DATA(inst, server_localmovesize_stop_pdu);
700         EMULATE_SERVER_SEND_CHANNEL_DATA(inst, server_minmaxinfo_pdu);
701         EMULATE_SERVER_SEND_CHANNEL_DATA(inst, server_langbar_pdu);
702         EMULATE_SERVER_SEND_CHANNEL_DATA(inst, server_app_get_resp_pdu);
703
704         // 2. Send UI events
705
706         param.out_rail_orders.sysparam.params = 0;
707
708         param.out_rail_orders.sysparam.params |= SPI_MASK_SET_HIGH_CONTRAST;
709         param.out_rail_orders.sysparam.highContrast.flags = 0x7e;
710         param.out_rail_orders.sysparam.highContrast.colorScheme.length = 0;
711         param.out_rail_orders.sysparam.highContrast.colorScheme.string = NULL;
712
713         param.out_rail_orders.sysparam.params |= SPI_MASK_TASKBAR_POS;
714         param.out_rail_orders.sysparam.taskbarPos.left = 0;
715         param.out_rail_orders.sysparam.taskbarPos.top = 0x039a;
716         param.out_rail_orders.sysparam.taskbarPos.right = 0x0690;
717         param.out_rail_orders.sysparam.taskbarPos.bottom = 0x03c2;
718
719         param.out_rail_orders.sysparam.params |= SPI_MASK_SET_MOUSE_BUTTON_SWAP;
720         param.out_rail_orders.sysparam.mouseButtonSwap = false;
721
722         param.out_rail_orders.sysparam.params |= SPI_MASK_SET_KEYBOARD_PREF;
723         param.out_rail_orders.sysparam.keyboardPref = false;
724
725         param.out_rail_orders.sysparam.params |= SPI_MASK_SET_DRAG_FULL_WINDOWS;
726         param.out_rail_orders.sysparam.dragFullWindows = true;
727
728         param.out_rail_orders.sysparam.params |= SPI_MASK_SET_KEYBOARD_CUES;
729         param.out_rail_orders.sysparam.keyboardCues = false;
730
731         param.out_rail_orders.sysparam.params |= SPI_MASK_SET_WORK_AREA;
732         param.out_rail_orders.sysparam.workArea.left = 0;
733         param.out_rail_orders.sysparam.workArea.top = 0;
734         param.out_rail_orders.sysparam.workArea.right = 0x0690;
735         param.out_rail_orders.sysparam.workArea.bottom = 0x039a;
736
737         send_ui_event2plugin(chan_man, RDP_EVENT_TYPE_RAIL_CLIENT_SET_SYSPARAMS,
738                 &param.out_rail_orders.sysparam);
739
740         param.plugin_data.size = sizeof(RDP_PLUGIN_DATA);
741         param.plugin_data.data[0] = "||iexplore";
742         param.plugin_data.data[1] = "f:\\windows\\system32";
743         param.plugin_data.data[2] = "www.bing.com";
744         send_ui_event2plugin(chan_man, RDP_EVENT_TYPE_RAIL_CLIENT_EXEC_REMOTE_APP,
745                 &param.plugin_data);
746
747         param.out_rail_orders.activate.enabled = true;
748         param.out_rail_orders.activate.windowId = 0x0007008e;
749         send_ui_event2plugin(chan_man, RDP_EVENT_TYPE_RAIL_CLIENT_ACTIVATE,
750                 &param.out_rail_orders.activate);
751
752         param.out_rail_orders.syscommand.windowId = 0x00020052;
753         param.out_rail_orders.syscommand.command  = 0xf020;
754         send_ui_event2plugin(chan_man, RDP_EVENT_TYPE_RAIL_CLIENT_SYSCOMMAND,
755                 &param.out_rail_orders.syscommand);
756
757         param.out_rail_orders.notify_event.windowId = 0x000201aa;
758         param.out_rail_orders.notify_event.notifyIconId = 0x02;
759         param.out_rail_orders.notify_event.message = 0x0204;
760         send_ui_event2plugin(chan_man, RDP_EVENT_TYPE_RAIL_CLIENT_NOTIFY_EVENT,
761                 &param.out_rail_orders.notify_event);
762
763
764         param.out_rail_orders.window_move.windowId = 0x00020020;
765         param.out_rail_orders.window_move.left = 0x0309;
766         param.out_rail_orders.window_move.top = 0x0100;
767         param.out_rail_orders.window_move.right = 0x05db;
768         param.out_rail_orders.window_move.bottom = 0x0188;
769         send_ui_event2plugin(chan_man, RDP_EVENT_TYPE_RAIL_CLIENT_WINDOW_MOVE,
770                 &param.out_rail_orders.window_move);
771
772         param.out_rail_orders.sysmenu.windowId = 0x00090122;
773         param.out_rail_orders.sysmenu.left = 0xffa4; // TODO: possible negative values?
774         param.out_rail_orders.sysmenu.top = 0x024a;
775         send_ui_event2plugin(chan_man, RDP_EVENT_TYPE_RAIL_CLIENT_SYSMENU,
776                 &param.out_rail_orders.sysmenu);
777
778         param.out_rail_orders.langbar_info.languageBarStatus = 0x00000001;
779         send_ui_event2plugin(chan_man, RDP_EVENT_TYPE_RAIL_CLIENT_LANGBARINFO,
780                 &param.out_rail_orders.langbar_info);
781
782         param.out_rail_orders.get_appid_req.windowId = 0x00020052;
783         send_ui_event2plugin(chan_man, RDP_EVENT_TYPE_RAIL_CLIENT_APPID_REQ,
784                 &param.out_rail_orders.get_appid_req);
785
786         // Waiting for possible events or data
787         sleep(1);
788
789         // Finishing thread and wait for it
790         param.th_to_finish = 1;
791         while (param.th_count > 0)
792         {
793                 usleep(1000);
794         }
795
796         // We need to collected all events and data dumps and then to.
797         // create CU_ASSERT series here!
798         sn = param.in_streams_number;
799         en = param.in_events_number;
800         ss = &param.in_streams[0];
801         ee = &param.in_events[0];
802
803         CU_ASSERT(sn > 0 && STREAM_EQUAL_TO_DUMP(&ss[ 0], client_handshake));
804         CU_ASSERT(sn > 1 && STREAM_EQUAL_TO_DUMP(&ss[ 1], client_info_pdu));
805         CU_ASSERT(sn > 2 && STREAM_EQUAL_TO_DUMP(&ss[ 2], client_sysparam_highcontrast_pdu));
806         CU_ASSERT(sn > 3 && STREAM_EQUAL_TO_DUMP(&ss[ 3], client_sysparam_taskbarpos_pdu));
807         CU_ASSERT(sn > 4 && STREAM_EQUAL_TO_DUMP(&ss[ 4], client_sysparam_mousebuttonswap_pdu));
808         CU_ASSERT(sn > 5 && STREAM_EQUAL_TO_DUMP(&ss[ 5], client_sysparam_keyboardpref_pdu));
809         CU_ASSERT(sn > 6 && STREAM_EQUAL_TO_DUMP(&ss[ 6], client_sysparam_dragfullwindow_pdu));
810         CU_ASSERT(sn > 7 && STREAM_EQUAL_TO_DUMP(&ss[ 7], client_sysparam_keyboardcues_pdu));
811         CU_ASSERT(sn > 8 && STREAM_EQUAL_TO_DUMP(&ss[ 8], client_sysparam_setworkarea_pdu));
812         CU_ASSERT(sn > 9 && STREAM_EQUAL_TO_DUMP(&ss[ 9], client_execute_pdu));
813         CU_ASSERT(sn >10 && STREAM_EQUAL_TO_DUMP(&ss[10], client_activate_pdu));
814         CU_ASSERT(sn >11 && STREAM_EQUAL_TO_DUMP(&ss[11], client_syscommand_pdu));
815         CU_ASSERT(sn >12 && STREAM_EQUAL_TO_DUMP(&ss[12], client_notify_pdu));
816         CU_ASSERT(sn >13 && STREAM_EQUAL_TO_DUMP(&ss[13], client_windowmove_pdu));
817         CU_ASSERT(sn >14 && STREAM_EQUAL_TO_DUMP(&ss[14], client_system_menu_pdu));
818         CU_ASSERT(sn >15 && STREAM_EQUAL_TO_DUMP(&ss[15], client_langbar_pdu));
819         CU_ASSERT(sn >16 && STREAM_EQUAL_TO_DUMP(&ss[16], client_get_app_id_req_pdu));
820
821         CU_ASSERT(en >  0 && ee[ 0].event_type == RDP_EVENT_TYPE_RAIL_CHANNEL_GET_SYSPARAMS);
822         CU_ASSERT(en >  1 &&
823                 ee[ 1].event_type == RDP_EVENT_TYPE_RAIL_CHANNEL_EXEC_RESULTS &&
824                 ee[ 1].order_info.exec_result.flags == 0x08 &&
825                 ee[ 1].order_info.exec_result.execResult == 0x03 &&
826                 UNICODE_STRING_EQUAL_TO_DUMP(
827                         &ee[ 1].order_info.exec_result.exeOrFile,
828                         server_exec_result_exe_or_file)
829                 );
830         CU_ASSERT(en >  2 &&
831                 ee[ 2].event_type == RDP_EVENT_TYPE_RAIL_CHANNEL_SERVER_SYSPARAM &&
832                 ee[ 2].order_info.sysparam.setScreenSaveSecure == false
833                 );
834
835         CU_ASSERT(en >  3 &&
836                 ee[ 3].event_type == RDP_EVENT_TYPE_RAIL_CHANNEL_SERVER_SYSPARAM &&
837                 ee[ 3].order_info.sysparam.setScreenSaveActive == false
838                 );
839
840         CU_ASSERT(en >  4 &&
841                 ee[ 4].event_type == RDP_EVENT_TYPE_RAIL_CHANNEL_SERVER_LOCALMOVESIZE &&
842                 ee[ 4].order_info.localmovesize.windowId == 0x0007008e &&
843                 ee[ 4].order_info.localmovesize.isMoveSizeStart == true &&
844                 ee[ 4].order_info.localmovesize.moveSizeType == RAIL_WMSZ_MOVE &&
845                 ee[ 4].order_info.localmovesize.posX == 0x017e &&
846                 ee[ 4].order_info.localmovesize.posY == 0x000a
847                 );
848
849         CU_ASSERT(en >  5 &&
850                 ee[ 5].event_type == RDP_EVENT_TYPE_RAIL_CHANNEL_SERVER_LOCALMOVESIZE &&
851                 ee[ 5].order_info.localmovesize.windowId == 0x0007008e &&
852                 ee[ 5].order_info.localmovesize.isMoveSizeStart == false &&
853                 ee[ 5].order_info.localmovesize.moveSizeType == RAIL_WMSZ_MOVE &&
854                 ee[ 5].order_info.localmovesize.posX == 0x00a6 &&
855                 ee[ 5].order_info.localmovesize.posY == 0x0044
856                 );
857
858         CU_ASSERT(en >  6 &&
859                 ee[ 6].event_type == RDP_EVENT_TYPE_RAIL_CHANNEL_SERVER_MINMAXINFO &&
860                 ee[ 6].order_info.minmaxinfo.windowId == 0x0007008e &&
861                 ee[ 6].order_info.minmaxinfo.maxWidth == 0x0408 &&
862                 ee[ 6].order_info.minmaxinfo.maxHeight == 0x02d6 &&
863                 ee[ 6].order_info.minmaxinfo.maxPosX ==  0x0000 &&
864                 ee[ 6].order_info.minmaxinfo.maxPosY ==  0x0000 &&
865                 ee[ 6].order_info.minmaxinfo.minTrackWidth ==  0x0070 &&
866                 ee[ 6].order_info.minmaxinfo.minTrackHeight ==  0x001b &&
867                 ee[ 6].order_info.minmaxinfo.maxTrackWidth ==  0x040c &&
868                 ee[ 6].order_info.minmaxinfo.maxTrackHeight ==  0x030c
869                 );
870
871         CU_ASSERT(en >  7 &&
872                 ee[ 7].event_type == RDP_EVENT_TYPE_RAIL_CHANNEL_LANGBARINFO &&
873                 ee[ 7].order_info.langbar_info.languageBarStatus == TF_SFT_SHOWNORMAL
874                 );
875
876         CU_ASSERT(en >  8 &&
877                 ee[ 8].event_type == RDP_EVENT_TYPE_RAIL_CHANNEL_APPID_RESP &&
878                 ee[ 8].order_info.get_appid_resp.windowId == 0x00020052 &&
879                 UNICODE_STRING_EQUAL_TO_DUMP(
880                         &ee[ 8].order_info.get_appid_resp.applicationId,
881                         server_app_get_resp_app_id
882                         )
883                 );
884
885         freerdp_channels_close(chan_man, inst);
886         freerdp_channels_free(chan_man);
887 }
888
889
890
891