1#include <freerdp/config.h>
7#include <winpr/windows.h>
9#include <winpr/crypto.h>
11#include <freerdp/client/file.h>
12#include <freerdp/channels/rdpecam.h>
14static const BYTE testRdpFileUTF16[] = {
15 0xff, 0xfe, 0x73, 0x00, 0x63, 0x00, 0x72, 0x00, 0x65, 0x00, 0x65, 0x00, 0x6e, 0x00, 0x20, 0x00,
16 0x6d, 0x00, 0x6f, 0x00, 0x64, 0x00, 0x65, 0x00, 0x20, 0x00, 0x69, 0x00, 0x64, 0x00, 0x3a, 0x00,
17 0x69, 0x00, 0x3a, 0x00, 0x32, 0x00, 0x0d, 0x00, 0x0a, 0x00, 0x75, 0x00, 0x73, 0x00, 0x65, 0x00,
18 0x20, 0x00, 0x6d, 0x00, 0x75, 0x00, 0x6c, 0x00, 0x74, 0x00, 0x69, 0x00, 0x6d, 0x00, 0x6f, 0x00,
19 0x6e, 0x00, 0x3a, 0x00, 0x69, 0x00, 0x3a, 0x00, 0x30, 0x00, 0x0d, 0x00, 0x0a, 0x00, 0x64, 0x00,
20 0x65, 0x00, 0x73, 0x00, 0x6b, 0x00, 0x74, 0x00, 0x6f, 0x00, 0x70, 0x00, 0x77, 0x00, 0x69, 0x00,
21 0x64, 0x00, 0x74, 0x00, 0x68, 0x00, 0x3a, 0x00, 0x69, 0x00, 0x3a, 0x00, 0x31, 0x00, 0x39, 0x00,
22 0x32, 0x00, 0x30, 0x00, 0x0d, 0x00, 0x0a, 0x00, 0x64, 0x00, 0x65, 0x00, 0x73, 0x00, 0x6b, 0x00,
23 0x74, 0x00, 0x6f, 0x00, 0x70, 0x00, 0x68, 0x00, 0x65, 0x00, 0x69, 0x00, 0x67, 0x00, 0x68, 0x00,
24 0x74, 0x00, 0x3a, 0x00, 0x69, 0x00, 0x3a, 0x00, 0x31, 0x00, 0x30, 0x00, 0x38, 0x00, 0x30, 0x00,
25 0x0d, 0x00, 0x0a, 0x00, 0x73, 0x00, 0x65, 0x00, 0x73, 0x00, 0x73, 0x00, 0x69, 0x00, 0x6f, 0x00,
26 0x6e, 0x00, 0x20, 0x00, 0x62, 0x00, 0x70, 0x00, 0x70, 0x00, 0x3a, 0x00, 0x69, 0x00, 0x3a, 0x00,
27 0x33, 0x00, 0x32, 0x00, 0x0d, 0x00, 0x0a, 0x00, 0x77, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x70, 0x00,
28 0x6f, 0x00, 0x73, 0x00, 0x73, 0x00, 0x74, 0x00, 0x72, 0x00, 0x3a, 0x00, 0x73, 0x00, 0x3a, 0x00,
29 0x30, 0x00, 0x2c, 0x00, 0x31, 0x00, 0x2c, 0x00, 0x35, 0x00, 0x35, 0x00, 0x33, 0x00, 0x2c, 0x00,
30 0x32, 0x00, 0x31, 0x00, 0x31, 0x00, 0x2c, 0x00, 0x31, 0x00, 0x33, 0x00, 0x35, 0x00, 0x33, 0x00,
31 0x2c, 0x00, 0x38, 0x00, 0x31, 0x00, 0x31, 0x00, 0x0d, 0x00, 0x0a, 0x00, 0x63, 0x00, 0x6f, 0x00,
32 0x6d, 0x00, 0x70, 0x00, 0x72, 0x00, 0x65, 0x00, 0x73, 0x00, 0x73, 0x00, 0x69, 0x00, 0x6f, 0x00,
33 0x6e, 0x00, 0x3a, 0x00, 0x69, 0x00, 0x3a, 0x00, 0x31, 0x00, 0x0d, 0x00, 0x0a, 0x00, 0x6b, 0x00,
34 0x65, 0x00, 0x79, 0x00, 0x62, 0x00, 0x6f, 0x00, 0x61, 0x00, 0x72, 0x00, 0x64, 0x00, 0x68, 0x00,
35 0x6f, 0x00, 0x6f, 0x00, 0x6b, 0x00, 0x3a, 0x00, 0x69, 0x00, 0x3a, 0x00, 0x32, 0x00, 0x0d, 0x00,
36 0x0a, 0x00, 0x61, 0x00, 0x75, 0x00, 0x64, 0x00, 0x69, 0x00, 0x6f, 0x00, 0x63, 0x00, 0x61, 0x00,
37 0x70, 0x00, 0x74, 0x00, 0x75, 0x00, 0x72, 0x00, 0x65, 0x00, 0x6d, 0x00, 0x6f, 0x00, 0x64, 0x00,
38 0x65, 0x00, 0x3a, 0x00, 0x69, 0x00, 0x3a, 0x00, 0x30, 0x00, 0x0d, 0x00, 0x0a, 0x00, 0x76, 0x00,
39 0x69, 0x00, 0x64, 0x00, 0x65, 0x00, 0x6f, 0x00, 0x70, 0x00, 0x6c, 0x00, 0x61, 0x00, 0x79, 0x00,
40 0x62, 0x00, 0x61, 0x00, 0x63, 0x00, 0x6b, 0x00, 0x6d, 0x00, 0x6f, 0x00, 0x64, 0x00, 0x65, 0x00,
41 0x3a, 0x00, 0x69, 0x00, 0x3a, 0x00, 0x31, 0x00, 0x0d, 0x00, 0x0a, 0x00, 0x63, 0x00, 0x6f, 0x00,
42 0x6e, 0x00, 0x6e, 0x00, 0x65, 0x00, 0x63, 0x00, 0x74, 0x00, 0x69, 0x00, 0x6f, 0x00, 0x6e, 0x00,
43 0x20, 0x00, 0x74, 0x00, 0x79, 0x00, 0x70, 0x00, 0x65, 0x00, 0x3a, 0x00, 0x69, 0x00, 0x3a, 0x00,
44 0x37, 0x00, 0x0d, 0x00, 0x0a, 0x00, 0x6e, 0x00, 0x65, 0x00, 0x74, 0x00, 0x77, 0x00, 0x6f, 0x00,
45 0x72, 0x00, 0x6b, 0x00, 0x61, 0x00, 0x75, 0x00, 0x74, 0x00, 0x6f, 0x00, 0x64, 0x00, 0x65, 0x00,
46 0x74, 0x00, 0x65, 0x00, 0x63, 0x00, 0x74, 0x00, 0x3a, 0x00, 0x69, 0x00, 0x3a, 0x00, 0x31, 0x00,
47 0x0d, 0x00, 0x0a, 0x00, 0x62, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x64, 0x00, 0x77, 0x00, 0x69, 0x00,
48 0x64, 0x00, 0x74, 0x00, 0x68, 0x00, 0x61, 0x00, 0x75, 0x00, 0x74, 0x00, 0x6f, 0x00, 0x64, 0x00,
49 0x65, 0x00, 0x74, 0x00, 0x65, 0x00, 0x63, 0x00, 0x74, 0x00, 0x3a, 0x00, 0x69, 0x00, 0x3a, 0x00,
50 0x31, 0x00, 0x0d, 0x00, 0x0a, 0x00, 0x64, 0x00, 0x69, 0x00, 0x73, 0x00, 0x70, 0x00, 0x6c, 0x00,
51 0x61, 0x00, 0x79, 0x00, 0x63, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x6e, 0x00, 0x65, 0x00, 0x63, 0x00,
52 0x74, 0x00, 0x69, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x62, 0x00, 0x61, 0x00, 0x72, 0x00, 0x3a, 0x00,
53 0x69, 0x00, 0x3a, 0x00, 0x31, 0x00, 0x0d, 0x00, 0x0a, 0x00, 0x65, 0x00, 0x6e, 0x00, 0x61, 0x00,
54 0x62, 0x00, 0x6c, 0x00, 0x65, 0x00, 0x77, 0x00, 0x6f, 0x00, 0x72, 0x00, 0x6b, 0x00, 0x73, 0x00,
55 0x70, 0x00, 0x61, 0x00, 0x63, 0x00, 0x65, 0x00, 0x72, 0x00, 0x65, 0x00, 0x63, 0x00, 0x6f, 0x00,
56 0x6e, 0x00, 0x6e, 0x00, 0x65, 0x00, 0x63, 0x00, 0x74, 0x00, 0x3a, 0x00, 0x69, 0x00, 0x3a, 0x00,
57 0x30, 0x00, 0x0d, 0x00, 0x0a, 0x00, 0x64, 0x00, 0x69, 0x00, 0x73, 0x00, 0x61, 0x00, 0x62, 0x00,
58 0x6c, 0x00, 0x65, 0x00, 0x20, 0x00, 0x77, 0x00, 0x61, 0x00, 0x6c, 0x00, 0x6c, 0x00, 0x70, 0x00,
59 0x61, 0x00, 0x70, 0x00, 0x65, 0x00, 0x72, 0x00, 0x3a, 0x00, 0x69, 0x00, 0x3a, 0x00, 0x30, 0x00,
60 0x0d, 0x00, 0x0a, 0x00, 0x61, 0x00, 0x6c, 0x00, 0x6c, 0x00, 0x6f, 0x00, 0x77, 0x00, 0x20, 0x00,
61 0x66, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x74, 0x00, 0x20, 0x00, 0x73, 0x00, 0x6d, 0x00, 0x6f, 0x00,
62 0x6f, 0x00, 0x74, 0x00, 0x68, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x67, 0x00, 0x3a, 0x00, 0x69, 0x00,
63 0x3a, 0x00, 0x30, 0x00, 0x0d, 0x00, 0x0a, 0x00, 0x61, 0x00, 0x6c, 0x00, 0x6c, 0x00, 0x6f, 0x00,
64 0x77, 0x00, 0x20, 0x00, 0x64, 0x00, 0x65, 0x00, 0x73, 0x00, 0x6b, 0x00, 0x74, 0x00, 0x6f, 0x00,
65 0x70, 0x00, 0x20, 0x00, 0x63, 0x00, 0x6f, 0x00, 0x6d, 0x00, 0x70, 0x00, 0x6f, 0x00, 0x73, 0x00,
66 0x69, 0x00, 0x74, 0x00, 0x69, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x3a, 0x00, 0x69, 0x00, 0x3a, 0x00,
67 0x30, 0x00, 0x0d, 0x00, 0x0a, 0x00, 0x64, 0x00, 0x69, 0x00, 0x73, 0x00, 0x61, 0x00, 0x62, 0x00,
68 0x6c, 0x00, 0x65, 0x00, 0x20, 0x00, 0x66, 0x00, 0x75, 0x00, 0x6c, 0x00, 0x6c, 0x00, 0x20, 0x00,
69 0x77, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x64, 0x00, 0x6f, 0x00, 0x77, 0x00, 0x20, 0x00, 0x64, 0x00,
70 0x72, 0x00, 0x61, 0x00, 0x67, 0x00, 0x3a, 0x00, 0x69, 0x00, 0x3a, 0x00, 0x31, 0x00, 0x0d, 0x00,
71 0x0a, 0x00, 0x64, 0x00, 0x69, 0x00, 0x73, 0x00, 0x61, 0x00, 0x62, 0x00, 0x6c, 0x00, 0x65, 0x00,
72 0x20, 0x00, 0x6d, 0x00, 0x65, 0x00, 0x6e, 0x00, 0x75, 0x00, 0x20, 0x00, 0x61, 0x00, 0x6e, 0x00,
73 0x69, 0x00, 0x6d, 0x00, 0x73, 0x00, 0x3a, 0x00, 0x69, 0x00, 0x3a, 0x00, 0x31, 0x00, 0x0d, 0x00,
74 0x0a, 0x00, 0x64, 0x00, 0x69, 0x00, 0x73, 0x00, 0x61, 0x00, 0x62, 0x00, 0x6c, 0x00, 0x65, 0x00,
75 0x20, 0x00, 0x74, 0x00, 0x68, 0x00, 0x65, 0x00, 0x6d, 0x00, 0x65, 0x00, 0x73, 0x00, 0x3a, 0x00,
76 0x69, 0x00, 0x3a, 0x00, 0x30, 0x00, 0x0d, 0x00, 0x0a, 0x00, 0x64, 0x00, 0x69, 0x00, 0x73, 0x00,
77 0x61, 0x00, 0x62, 0x00, 0x6c, 0x00, 0x65, 0x00, 0x20, 0x00, 0x63, 0x00, 0x75, 0x00, 0x72, 0x00,
78 0x73, 0x00, 0x6f, 0x00, 0x72, 0x00, 0x20, 0x00, 0x73, 0x00, 0x65, 0x00, 0x74, 0x00, 0x74, 0x00,
79 0x69, 0x00, 0x6e, 0x00, 0x67, 0x00, 0x3a, 0x00, 0x69, 0x00, 0x3a, 0x00, 0x30, 0x00, 0x0d, 0x00,
80 0x0a, 0x00, 0x62, 0x00, 0x69, 0x00, 0x74, 0x00, 0x6d, 0x00, 0x61, 0x00, 0x70, 0x00, 0x63, 0x00,
81 0x61, 0x00, 0x63, 0x00, 0x68, 0x00, 0x65, 0x00, 0x70, 0x00, 0x65, 0x00, 0x72, 0x00, 0x73, 0x00,
82 0x69, 0x00, 0x73, 0x00, 0x74, 0x00, 0x65, 0x00, 0x6e, 0x00, 0x61, 0x00, 0x62, 0x00, 0x6c, 0x00,
83 0x65, 0x00, 0x3a, 0x00, 0x69, 0x00, 0x3a, 0x00, 0x31, 0x00, 0x0d, 0x00, 0x0a, 0x00, 0x66, 0x00,
84 0x75, 0x00, 0x6c, 0x00, 0x6c, 0x00, 0x20, 0x00, 0x61, 0x00, 0x64, 0x00, 0x64, 0x00, 0x72, 0x00,
85 0x65, 0x00, 0x73, 0x00, 0x73, 0x00, 0x3a, 0x00, 0x73, 0x00, 0x3a, 0x00, 0x4c, 0x00, 0x41, 0x00,
86 0x42, 0x00, 0x31, 0x00, 0x2d, 0x00, 0x57, 0x00, 0x37, 0x00, 0x2d, 0x00, 0x44, 0x00, 0x4d, 0x00,
87 0x2d, 0x00, 0x30, 0x00, 0x31, 0x00, 0x2e, 0x00, 0x6c, 0x00, 0x61, 0x00, 0x62, 0x00, 0x31, 0x00,
88 0x2e, 0x00, 0x61, 0x00, 0x77, 0x00, 0x61, 0x00, 0x6b, 0x00, 0x65, 0x00, 0x2e, 0x00, 0x6c, 0x00,
89 0x6f, 0x00, 0x63, 0x00, 0x61, 0x00, 0x6c, 0x00, 0x0d, 0x00, 0x0a, 0x00, 0x61, 0x00, 0x75, 0x00,
90 0x64, 0x00, 0x69, 0x00, 0x6f, 0x00, 0x6d, 0x00, 0x6f, 0x00, 0x64, 0x00, 0x65, 0x00, 0x3a, 0x00,
91 0x69, 0x00, 0x3a, 0x00, 0x30, 0x00, 0x0d, 0x00, 0x0a, 0x00, 0x72, 0x00, 0x65, 0x00, 0x64, 0x00,
92 0x69, 0x00, 0x72, 0x00, 0x65, 0x00, 0x63, 0x00, 0x74, 0x00, 0x70, 0x00, 0x72, 0x00, 0x69, 0x00,
93 0x6e, 0x00, 0x74, 0x00, 0x65, 0x00, 0x72, 0x00, 0x73, 0x00, 0x3a, 0x00, 0x69, 0x00, 0x3a, 0x00,
94 0x31, 0x00, 0x0d, 0x00, 0x0a, 0x00, 0x72, 0x00, 0x65, 0x00, 0x64, 0x00, 0x69, 0x00, 0x72, 0x00,
95 0x65, 0x00, 0x63, 0x00, 0x74, 0x00, 0x63, 0x00, 0x6f, 0x00, 0x6d, 0x00, 0x70, 0x00, 0x6f, 0x00,
96 0x72, 0x00, 0x74, 0x00, 0x73, 0x00, 0x3a, 0x00, 0x69, 0x00, 0x3a, 0x00, 0x30, 0x00, 0x0d, 0x00,
97 0x0a, 0x00, 0x72, 0x00, 0x65, 0x00, 0x64, 0x00, 0x69, 0x00, 0x72, 0x00, 0x65, 0x00, 0x63, 0x00,
98 0x74, 0x00, 0x73, 0x00, 0x6d, 0x00, 0x61, 0x00, 0x72, 0x00, 0x74, 0x00, 0x63, 0x00, 0x61, 0x00,
99 0x72, 0x00, 0x64, 0x00, 0x73, 0x00, 0x3a, 0x00, 0x69, 0x00, 0x3a, 0x00, 0x31, 0x00, 0x0d, 0x00,
100 0x0a, 0x00, 0x72, 0x00, 0x65, 0x00, 0x64, 0x00, 0x69, 0x00, 0x72, 0x00, 0x65, 0x00, 0x63, 0x00,
101 0x74, 0x00, 0x63, 0x00, 0x6c, 0x00, 0x69, 0x00, 0x70, 0x00, 0x62, 0x00, 0x6f, 0x00, 0x61, 0x00,
102 0x72, 0x00, 0x64, 0x00, 0x3a, 0x00, 0x69, 0x00, 0x3a, 0x00, 0x31, 0x00, 0x0d, 0x00, 0x0a, 0x00,
103 0x72, 0x00, 0x65, 0x00, 0x64, 0x00, 0x69, 0x00, 0x72, 0x00, 0x65, 0x00, 0x63, 0x00, 0x74, 0x00,
104 0x70, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x64, 0x00, 0x65, 0x00, 0x76, 0x00, 0x69, 0x00, 0x63, 0x00,
105 0x65, 0x00, 0x73, 0x00, 0x3a, 0x00, 0x69, 0x00, 0x3a, 0x00, 0x30, 0x00, 0x0d, 0x00, 0x0a, 0x00,
106 0x61, 0x00, 0x75, 0x00, 0x74, 0x00, 0x6f, 0x00, 0x72, 0x00, 0x65, 0x00, 0x63, 0x00, 0x6f, 0x00,
107 0x6e, 0x00, 0x6e, 0x00, 0x65, 0x00, 0x63, 0x00, 0x74, 0x00, 0x69, 0x00, 0x6f, 0x00, 0x6e, 0x00,
108 0x20, 0x00, 0x65, 0x00, 0x6e, 0x00, 0x61, 0x00, 0x62, 0x00, 0x6c, 0x00, 0x65, 0x00, 0x64, 0x00,
109 0x3a, 0x00, 0x69, 0x00, 0x3a, 0x00, 0x31, 0x00, 0x0d, 0x00, 0x0a, 0x00, 0x61, 0x00, 0x75, 0x00,
110 0x74, 0x00, 0x68, 0x00, 0x65, 0x00, 0x6e, 0x00, 0x74, 0x00, 0x69, 0x00, 0x63, 0x00, 0x61, 0x00,
111 0x74, 0x00, 0x69, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x20, 0x00, 0x6c, 0x00, 0x65, 0x00, 0x76, 0x00,
112 0x65, 0x00, 0x6c, 0x00, 0x3a, 0x00, 0x69, 0x00, 0x3a, 0x00, 0x32, 0x00, 0x0d, 0x00, 0x0a, 0x00,
113 0x70, 0x00, 0x72, 0x00, 0x6f, 0x00, 0x6d, 0x00, 0x70, 0x00, 0x74, 0x00, 0x20, 0x00, 0x66, 0x00,
114 0x6f, 0x00, 0x72, 0x00, 0x20, 0x00, 0x63, 0x00, 0x72, 0x00, 0x65, 0x00, 0x64, 0x00, 0x65, 0x00,
115 0x6e, 0x00, 0x74, 0x00, 0x69, 0x00, 0x61, 0x00, 0x6c, 0x00, 0x73, 0x00, 0x3a, 0x00, 0x69, 0x00,
116 0x3a, 0x00, 0x30, 0x00, 0x0d, 0x00, 0x0a, 0x00, 0x6e, 0x00, 0x65, 0x00, 0x67, 0x00, 0x6f, 0x00,
117 0x74, 0x00, 0x69, 0x00, 0x61, 0x00, 0x74, 0x00, 0x65, 0x00, 0x20, 0x00, 0x73, 0x00, 0x65, 0x00,
118 0x63, 0x00, 0x75, 0x00, 0x72, 0x00, 0x69, 0x00, 0x74, 0x00, 0x79, 0x00, 0x20, 0x00, 0x6c, 0x00,
119 0x61, 0x00, 0x79, 0x00, 0x65, 0x00, 0x72, 0x00, 0x3a, 0x00, 0x69, 0x00, 0x3a, 0x00, 0x31, 0x00,
120 0x0d, 0x00, 0x0a, 0x00, 0x72, 0x00, 0x65, 0x00, 0x6d, 0x00, 0x6f, 0x00, 0x74, 0x00, 0x65, 0x00,
121 0x61, 0x00, 0x70, 0x00, 0x70, 0x00, 0x6c, 0x00, 0x69, 0x00, 0x63, 0x00, 0x61, 0x00, 0x74, 0x00,
122 0x69, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x6d, 0x00, 0x6f, 0x00, 0x64, 0x00, 0x65, 0x00, 0x3a, 0x00,
123 0x69, 0x00, 0x3a, 0x00, 0x30, 0x00, 0x0d, 0x00, 0x0a, 0x00, 0x61, 0x00, 0x6c, 0x00, 0x74, 0x00,
124 0x65, 0x00, 0x72, 0x00, 0x6e, 0x00, 0x61, 0x00, 0x74, 0x00, 0x65, 0x00, 0x20, 0x00, 0x73, 0x00,
125 0x68, 0x00, 0x65, 0x00, 0x6c, 0x00, 0x6c, 0x00, 0x3a, 0x00, 0x73, 0x00, 0x3a, 0x00, 0x0d, 0x00,
126 0x0a, 0x00, 0x73, 0x00, 0x68, 0x00, 0x65, 0x00, 0x6c, 0x00, 0x6c, 0x00, 0x20, 0x00, 0x77, 0x00,
127 0x6f, 0x00, 0x72, 0x00, 0x6b, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x67, 0x00, 0x20, 0x00, 0x64, 0x00,
128 0x69, 0x00, 0x72, 0x00, 0x65, 0x00, 0x63, 0x00, 0x74, 0x00, 0x6f, 0x00, 0x72, 0x00, 0x79, 0x00,
129 0x3a, 0x00, 0x73, 0x00, 0x3a, 0x00, 0x0d, 0x00, 0x0a, 0x00, 0x67, 0x00, 0x61, 0x00, 0x74, 0x00,
130 0x65, 0x00, 0x77, 0x00, 0x61, 0x00, 0x79, 0x00, 0x68, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x74, 0x00,
131 0x6e, 0x00, 0x61, 0x00, 0x6d, 0x00, 0x65, 0x00, 0x3a, 0x00, 0x73, 0x00, 0x3a, 0x00, 0x4c, 0x00,
132 0x41, 0x00, 0x42, 0x00, 0x31, 0x00, 0x2d, 0x00, 0x57, 0x00, 0x32, 0x00, 0x4b, 0x00, 0x38, 0x00,
133 0x52, 0x00, 0x32, 0x00, 0x2d, 0x00, 0x47, 0x00, 0x57, 0x00, 0x2e, 0x00, 0x6c, 0x00, 0x61, 0x00,
134 0x62, 0x00, 0x31, 0x00, 0x2e, 0x00, 0x61, 0x00, 0x77, 0x00, 0x61, 0x00, 0x6b, 0x00, 0x65, 0x00,
135 0x2e, 0x00, 0x6c, 0x00, 0x6f, 0x00, 0x63, 0x00, 0x61, 0x00, 0x6c, 0x00, 0x0d, 0x00, 0x0a, 0x00,
136 0x67, 0x00, 0x61, 0x00, 0x74, 0x00, 0x65, 0x00, 0x77, 0x00, 0x61, 0x00, 0x79, 0x00, 0x75, 0x00,
137 0x73, 0x00, 0x61, 0x00, 0x67, 0x00, 0x65, 0x00, 0x6d, 0x00, 0x65, 0x00, 0x74, 0x00, 0x68, 0x00,
138 0x6f, 0x00, 0x64, 0x00, 0x3a, 0x00, 0x69, 0x00, 0x3a, 0x00, 0x31, 0x00, 0x0d, 0x00, 0x0a, 0x00,
139 0x67, 0x00, 0x61, 0x00, 0x74, 0x00, 0x65, 0x00, 0x77, 0x00, 0x61, 0x00, 0x79, 0x00, 0x63, 0x00,
140 0x72, 0x00, 0x65, 0x00, 0x64, 0x00, 0x65, 0x00, 0x6e, 0x00, 0x74, 0x00, 0x69, 0x00, 0x61, 0x00,
141 0x6c, 0x00, 0x73, 0x00, 0x73, 0x00, 0x6f, 0x00, 0x75, 0x00, 0x72, 0x00, 0x63, 0x00, 0x65, 0x00,
142 0x3a, 0x00, 0x69, 0x00, 0x3a, 0x00, 0x30, 0x00, 0x0d, 0x00, 0x0a, 0x00, 0x67, 0x00, 0x61, 0x00,
143 0x74, 0x00, 0x65, 0x00, 0x77, 0x00, 0x61, 0x00, 0x79, 0x00, 0x70, 0x00, 0x72, 0x00, 0x6f, 0x00,
144 0x66, 0x00, 0x69, 0x00, 0x6c, 0x00, 0x65, 0x00, 0x75, 0x00, 0x73, 0x00, 0x61, 0x00, 0x67, 0x00,
145 0x65, 0x00, 0x6d, 0x00, 0x65, 0x00, 0x74, 0x00, 0x68, 0x00, 0x6f, 0x00, 0x64, 0x00, 0x3a, 0x00,
146 0x69, 0x00, 0x3a, 0x00, 0x31, 0x00, 0x0d, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x72, 0x00, 0x6f, 0x00,
147 0x6d, 0x00, 0x70, 0x00, 0x74, 0x00, 0x63, 0x00, 0x72, 0x00, 0x65, 0x00, 0x64, 0x00, 0x65, 0x00,
148 0x6e, 0x00, 0x74, 0x00, 0x69, 0x00, 0x61, 0x00, 0x6c, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x63, 0x00,
149 0x65, 0x00, 0x3a, 0x00, 0x69, 0x00, 0x3a, 0x00, 0x31, 0x00, 0x0d, 0x00, 0x0a, 0x00, 0x75, 0x00,
150 0x73, 0x00, 0x65, 0x00, 0x20, 0x00, 0x72, 0x00, 0x65, 0x00, 0x64, 0x00, 0x69, 0x00, 0x72, 0x00,
151 0x65, 0x00, 0x63, 0x00, 0x74, 0x00, 0x69, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x20, 0x00, 0x73, 0x00,
152 0x65, 0x00, 0x72, 0x00, 0x76, 0x00, 0x65, 0x00, 0x72, 0x00, 0x20, 0x00, 0x6e, 0x00, 0x61, 0x00,
153 0x6d, 0x00, 0x65, 0x00, 0x3a, 0x00, 0x69, 0x00, 0x3a, 0x00, 0x30, 0x00, 0x0d, 0x00, 0x0a, 0x00,
154 0x72, 0x00, 0x64, 0x00, 0x67, 0x00, 0x69, 0x00, 0x73, 0x00, 0x6b, 0x00, 0x64, 0x00, 0x63, 0x00,
155 0x70, 0x00, 0x72, 0x00, 0x6f, 0x00, 0x78, 0x00, 0x79, 0x00, 0x3a, 0x00, 0x69, 0x00, 0x3a, 0x00,
156 0x30, 0x00, 0x0d, 0x00, 0x0a, 0x00, 0x6b, 0x00, 0x64, 0x00, 0x63, 0x00, 0x70, 0x00, 0x72, 0x00,
157 0x6f, 0x00, 0x78, 0x00, 0x79, 0x00, 0x6e, 0x00, 0x61, 0x00, 0x6d, 0x00, 0x65, 0x00, 0x3a, 0x00,
158 0x73, 0x00, 0x3a, 0x00, 0x0d, 0x00, 0x0a, 0x00, 0x64, 0x00, 0x72, 0x00, 0x69, 0x00, 0x76, 0x00,
159 0x65, 0x00, 0x73, 0x00, 0x74, 0x00, 0x6f, 0x00, 0x72, 0x00, 0x65, 0x00, 0x64, 0x00, 0x69, 0x00,
160 0x72, 0x00, 0x65, 0x00, 0x63, 0x00, 0x74, 0x00, 0x3a, 0x00, 0x73, 0x00, 0x3a, 0x00, 0x2a, 0x00,
161 0x0d, 0x00, 0x0a, 0x00, 0x75, 0x00, 0x73, 0x00, 0x65, 0x00, 0x72, 0x00, 0x6e, 0x00, 0x61, 0x00,
162 0x6d, 0x00, 0x65, 0x00, 0x3a, 0x00, 0x73, 0x00, 0x3a, 0x00, 0x4c, 0x00, 0x41, 0x00, 0x42, 0x00,
163 0x31, 0x00, 0x5c, 0x00, 0x4a, 0x00, 0x6f, 0x00, 0x68, 0x00, 0x6e, 0x00, 0x44, 0x00, 0x6f, 0x00,
164 0x65, 0x00, 0x0d, 0x00, 0x0a, 0x00
167#if defined(CHANNEL_RDPECAM_CLIENT)
168static const char* camera_args[] = { RDPECAM_DVC_CHANNEL_NAME,
170 "device:\\?\\usb#vid_0bda&pid_58b0&mi",
171 "device:-\\?\\usb#vid_0bdc&pid_58b1&mi",
176#if defined(CHANNEL_URBDRC_CLIENT)
177static const char* urbdrc_args[] = {
"urbdrc",
"device:*",
"device:USBInstanceID:someid",
178 "device:{72631e54-78a4-11d0-bcf7-00aa00b7b32a}" };
181static char testRdpFileUTF8[] =
182 "screen mode id:i:2\n"
184 "desktopwidth:i:1920\n"
185 "desktopheight:i:1080\n"
186 "dynamic resolution:i:1080\n"
187 "desktopscalefactor:i:1080\n"
188 "redirected video capture encoding quality:i:2\n"
189 "encode redirected video capture:i:1\n"
190 "camerastoredirect:s:*,\\?\\usb#vid_0bda&pid_58b0&mi,-\\?\\usb#vid_0bdc&pid_58b1&mi\n"
191 "usbdevicestoredirect:s:*,USBInstanceID:someid,{72631e54-78a4-11d0-bcf7-00aa00b7b32a}\n"
192 "selectedmonitors:s:3,2,42,23"
194 "winposstr:s:0,1,553,211,1353,811\n"
197 "audiocapturemode:i:0\n"
198 "videoplaybackmode:i:2\n"
199 "connection type:i:7\n"
200 "networkautodetect:i:1\n"
201 "bandwidthautodetect:i:1\n"
202 "displayconnectionbar:i:1\n"
203 "enableworkspacereconnect:i:0\n"
204 "disable wallpaper:i:0\n"
205 "allow font smoothing:i:0\n"
206 "allow desktop composition:i:0\n"
207 "disable full window drag:i:1\n"
208 "disable menu anims:i:1\n"
209 "disable themes:i:0\n"
210 "disable cursor setting:i:0\n"
211 "bitmapcachepersistenable:i:1\n"
212 "full address:s:LAB1-W7-DM-01.lab1.awake.local\n"
213 "alternate full address:s:LAB1-W7-DM-01.lab1.awake.global\n"
215 "redirectprinters:i:1\n"
216 "redirectcomports:i:0\n"
217 "redirectsmartcards:i:1\n"
218 "redirectclipboard:i:1\n"
219 "redirectposdevices:i:0\n"
220 "autoreconnection enabled:i:1\n"
221 "authentication level:i:2\n"
222 "prompt for credentials:i:0\n"
223 "negotiate security layer:i:1\n"
224 "remoteapplicationmode:i:0\n"
225 "alternate shell:s:\n"
226 "shell working directory:s:\n"
227 "gatewayhostname:s:LAB1-W2K8R2-GW.lab1.awake.local\n"
228 "gatewayusagemethod:i:1\n"
229 "gatewaycredentialssource:i:0\n"
230 "gatewayprofileusagemethod:i:1\n"
231 "promptcredentialonce:i:1\n"
232 "use redirection server name:i:0\n"
233 "rdgiskdcproxy:i:0\n"
235 "drivestoredirect:s:*\n"
236 "username:s:LAB1\\JohnDoe\n"
237 "vendor integer:i:123\n"
238 "vendor string:s:microsoft\n";
240static char* append(
const char* fmt, ...)
244 va_list ap = WINPR_C_ARRAY_INIT;
247 rc = vsnprintf(
nullptr, 0, fmt, ap);
251 dst = malloc((
size_t)rc + 1);
256 rc = vsnprintf(dst, (
size_t)rc + 1, fmt, ap);
266static FILE* test_fopen(
const char* name,
const char* mode)
268#ifndef TEST_SOURCE_DIR
269#error "TEST_SOURCE_DIR must be defined to the test source directory"
272 char* path = GetCombinedPath(TEST_SOURCE_DIR, name);
273 FILE* fp = winpr_fopen(path, mode);
278static void* read_rdp_data(
const char* name,
size_t* plen)
280 BOOL success = FALSE;
281 char* json =
nullptr;
282 FILE* fp = test_fopen(name,
"r");
286 if (fseek(fp, 0, SEEK_END) != 0)
289 const INT64 pos = _ftelli64(fp);
293 if (fseek(fp, 0, SEEK_SET) != 0)
296 const size_t upos = WINPR_CXX_COMPAT_CAST(
size_t, pos);
297 json = calloc(1ULL + upos,
sizeof(
char));
300 if (fread(json, 1, pos, fp) != pos)
308 char buffer[128] = WINPR_C_ARRAY_INIT;
309 WLog_ERR(__func__,
"failed to read data from '%s': %s", name,
310 winpr_strerror(errno, buffer,
sizeof(buffer)));
320static bool save_settings(
const rdpSettings* settings,
const char* name)
328 FILE* fp = test_fopen(name,
"w");
331 const size_t res = fwrite(data, 1, datalen, fp);
340static char* get_json_name(
const char* base,
bool unchecked)
343 char* name =
nullptr;
344 winpr_asprintf(&name, &namelen,
"%s%s.json", base, unchecked ?
".unchecked" :
"");
348static rdpSettings* read_json(
const char* name)
351 void* data = read_rdp_data(name, &datalen);
358static rdpSettings* load_from(
const void* data,
size_t len,
bool unchecked)
361 rdpFile* file = freerdp_client_rdp_file_new();
362 rdpSettings* settings = read_json(
"default-settings.json");
368 save_settings(settings,
"default-settings.json");
371 if (!file || !settings)
374 if (!freerdp_client_parse_rdp_file_buffer(file, data, len))
379 if (!freerdp_client_populate_settings_from_rdp_file_unchecked(file, settings))
384 if (!freerdp_client_populate_settings_from_rdp_file(file, settings))
390 freerdp_client_rdp_file_free(file);
399static rdpSettings* load_from_file(
const char* name,
bool unchecked)
402 void* data = read_rdp_data(name, &datalen);
405 rdpSettings* settings = load_from(data, datalen, unchecked);
410static bool test_data(
const char* json,
const void* data,
size_t len,
bool unchecked)
414 wLog* log = WLog_Get(__func__);
415 rdpSettings* settings = load_from(data, len, unchecked);
416 rdpSettings* expect = read_json(json);
417 if (!settings || !expect)
419 WLog_Print(log, WLOG_ERROR,
"Test case '%s': settings=%p, expect=%p", json, settings,
430 WLog_Print(log, WLOG_INFO,
"Test case '%s'", json);
440static HANDLE FindFirstFileUTF8(LPCSTR pszSearchPath,
WIN32_FIND_DATAW* FindData)
442 HANDLE hdl = INVALID_HANDLE_VALUE;
445 WCHAR* wpath = ConvertUtf8ToWCharAlloc(pszSearchPath,
nullptr);
449 hdl = FindFirstFileW(wpath, FindData);
455static bool test_rdp_file(
const char* base,
bool allowCreate,
bool unchecked)
461 winpr_asprintf(&rdp, &rdplen,
"%s.rdp", base);
462 char* json = get_json_name(base, unchecked);
464 void* data = read_rdp_data(rdp, &datalen);
469 rc = test_data(json, data, datalen, unchecked);
470 if (!rc && allowCreate)
472 rdpSettings* expect = read_json(json);
479 rdpSettings* settings = load_from_file(rdp, unchecked);
483 rc = save_settings(settings, json);
492static bool test_rdp_files(
bool allowCreate)
498#ifndef TEST_SOURCE_DIR
499#error "TEST_SOURCE_DIR must be defined to the test source directory"
502 HANDLE hdl = INVALID_HANDLE_VALUE;
503 char* path = GetCombinedPath(TEST_SOURCE_DIR,
"rdp-testcases/*.rdp");
508 hdl = FindFirstFileUTF8(path, &FindData);
510 if (hdl == INVALID_HANDLE_VALUE)
514 "no RDP files found in %s. Add RDP files to generate settings JSON for comparison.",
522 if ((FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0)
524 char cFileName[6 * MAX_PATH] = WINPR_C_ARRAY_INIT;
525 char rdp[6 * MAX_PATH] = WINPR_C_ARRAY_INIT;
526 ConvertWCharToUtf8(FindData.cFileName, cFileName,
sizeof(cFileName));
527 const size_t len = strnlen(cFileName,
sizeof(cFileName));
530 strcpy(rdp,
"rdp-testcases/");
531 strncpy(&rdp[14], cFileName, len - 4);
533 if (!test_rdp_file(rdp, allowCreate,
false))
535 if (!test_rdp_file(rdp, allowCreate,
true))
538 }
while (FindNextFileW(hdl, &FindData));
549static BOOL test_ascii(rdpSettings* settings)
551 WINPR_ASSERT(settings);
555 rdpFile* file = freerdp_client_rdp_file_new();
558 printf(
"rdp_file_new failed\n");
562 if (!freerdp_client_parse_rdp_file_buffer(file, (BYTE*)testRdpFileUTF8,
563 sizeof(testRdpFileUTF8)))
566 if (!freerdp_client_populate_settings_from_rdp_file(file, settings))
571 printf(
"UseMultiMon mismatch: Actual: %" PRIu32
", Expected: 0\n",
578 printf(
"ScreenModeId mismatch: Actual: %" PRIu32
", Expected: TRUE\n",
584 "LAB1-W7-DM-01.lab1.awake.global") != 0)
586 printf(
"ServerHostname mismatch: Actual: %s, Expected: %s\n",
588 "LAB1-W7-DM-01.lab1.awake.global");
593 "LAB1-W2K8R2-GW.lab1.awake.local") != 0)
595 printf(
"GatewayHostname mismatch: Actual: %s, Expected: %s\n",
597 "LAB1-W2K8R2-GW.lab1.awake.local");
602 const int iValue = freerdp_client_rdp_file_get_integer_option(file,
"dynamic resolution");
605 printf(
"dynamic resolution uses invalid default value %d", iValue);
611 printf(
"FreeRDP_DynamicResolutionUpdate has invalid value");
615 const int iValue = freerdp_client_rdp_file_get_integer_option(file,
"desktopscalefactor");
618 printf(
"desktopscalefactor uses invalid default value %d", iValue);
623 printf(
"FreeRDP_DesktopScaleFactor has invalid value");
629#if defined(CHANNEL_RDPECAM_CLIENT)
634 freerdp_client_rdp_file_get_integer_option(file,
"encode redirected video capture");
637 printf(
"encode redirected video capture uses invalid default value %d", iValue);
643 const int iValue = freerdp_client_rdp_file_get_integer_option(
644 file,
"redirected video capture encoding quality");
647 printf(
"redirected video capture encoding quality uses invalid default value %d",
652 args = freerdp_dynamic_channel_collection_find(settings, RDPECAM_DVC_CHANNEL_NAME);
655 printf(
"rdpecam channel was not loaded");
660 printf(
"rdpecam channel was not loaded");
664 for (
int x = 0; x < args->argc; x++)
666 if (strcmp(args->argv[x], camera_args[x]) != 0)
668 printf(
"rdpecam invalid argument argv[%d]: %s", x, args->argv[x]);
676#if defined(CHANNEL_URBDRC_CLIENT)
678 ADDIN_ARGV* args = freerdp_dynamic_channel_collection_find(settings,
"urbdrc");
681 printf(
"urbdrc channel was not loaded");
686 printf(
"urbdrc channel was not loaded");
690 for (
int x = 0; x < args->argc; x++)
692 if (strcmp(args->argv[x], urbdrc_args[x]) != 0)
694 printf(
"urbdrc invalid argument argv[%d]: %s", x, args->argv[x]);
705 printf(
"FreeRDP_NumMonitorIds has invalid value %" PRIu32, uValue);
708 const UINT32* puValue =
709 (
const UINT32*)freerdp_settings_get_pointer_array(settings, FreeRDP_MonitorIds, 0);
712 printf(
"FreeRDP_MonitorIds has invalid value %p", (
const void*)puValue);
715 if ((puValue[0] != 3) || (puValue[1] != 2) || (puValue[2] != 42) || (puValue[3] != 23))
717 printf(
"FreeRDP_MonitorIds has invalid values: [%" PRIu32
",%" PRIu32
",%" PRIu32
719 puValue[0], puValue[1], puValue[2], puValue[3]);
724 const int iValue = freerdp_client_rdp_file_get_integer_option(file,
"videoplaybackmode");
727 printf(
"videoplaybackmode uses invalid default value %d", iValue);
733 printf(
"FreeRDP_SupportVideoOptimized has invalid value");
738 printf(
"FreeRDP_SupportGeometryTracking has invalid value");
743 const int iValue = freerdp_client_rdp_file_get_integer_option(file,
"vendor integer");
748 if (freerdp_client_rdp_file_set_integer_option(file,
"vendor integer", 456) == -1)
750 printf(
"failed to set integer: vendor integer");
755 const int iValue = freerdp_client_rdp_file_get_integer_option(file,
"vendor integer");
761 const char microsoft[] =
"microsoft";
762 char* sValue = freerdp_client_rdp_file_get_string_option(file,
"vendor string");
763 if (strncmp(sValue, microsoft,
sizeof(microsoft)) != 0)
767 const char apple[] =
"apple";
768 if (freerdp_client_rdp_file_set_string_option(file,
"vendor string",
"apple") == 0)
770 const char* sValue = freerdp_client_rdp_file_get_string_option(file,
"vendor string");
771 if (strncmp(sValue, apple,
sizeof(apple)) != 0)
774 if (freerdp_client_rdp_file_set_string_option(file,
"fruits",
"banana,oranges") == 0)
777 if (freerdp_client_rdp_file_set_integer_option(file,
"numbers", 123456789) == -1)
779 printf(
"failed to set integer: numbers");
785 freerdp_client_rdp_file_free(file);
790static BOOL test_foo(
const rdpSettings* settings)
792 WINPR_ASSERT(settings);
797 if (winpr_RAND(&
id,
sizeof(
id)) < 0)
800 rdpFile* file =
nullptr;
801 char* base =
nullptr;
802 char* utfname =
nullptr;
803 char* uniname =
nullptr;
804 char* tmp = GetKnownPath(KNOWN_PATH_TEMP);
808 base = append(
"%s/rdp-file-test-%" PRIx64, tmp,
id);
811 if (!CreateDirectoryA(base,
nullptr))
813 utfname = append(
"%s/utfname", base);
814 uniname = append(
"%s/uniname", base);
815 file = freerdp_client_rdp_file_new();
816 if (!file || !utfname || !uniname)
819 if (!freerdp_client_populate_rdp_file_from_settings(file, settings))
822 if (!freerdp_client_write_rdp_file(file, utfname, FALSE))
825 if (!freerdp_client_write_rdp_file(file, uniname, TRUE))
831 winpr_DeleteFile(utfname);
833 winpr_DeleteFile(uniname);
835 winpr_RemoveDirectory(base);
840 freerdp_client_rdp_file_free(file);
844int TestClientRdpFile(
int argc,
char* argv[])
850#if defined(CHANNEL_URBDRC_CLIENT) && defined(CHANNEL_RDPECAM_CLIENT)
851 if (!test_data(
"testRdpFileUTF8.json", testRdpFileUTF8,
sizeof(testRdpFileUTF8),
false))
853 if (!test_data(
"testRdpFileUTF8.unchecked.json", testRdpFileUTF8,
sizeof(testRdpFileUTF8),
859#if defined(CHANNEL_URBDRC_CLIENT)
860 if (!test_data(
"testRdpFileUTF16.json", testRdpFileUTF16,
sizeof(testRdpFileUTF16),
false))
862 if (!test_data(
"testRdpFileUTF16.unchecked.json", testRdpFileUTF16,
sizeof(testRdpFileUTF16),
867#if defined(CHANNEL_URBDRC_CLIENT) && defined(CHANNEL_RDPECAM_CLIENT)
868 if (!test_rdp_files(argc > 1))
877 if (!test_ascii(settings))
879 else if (!test_foo(settings))
FREERDP_API rdpSettings * freerdp_settings_new(DWORD flags)
creates a new setting struct
WINPR_ATTR_NODISCARD FREERDP_API const char * freerdp_settings_get_string(const rdpSettings *settings, FreeRDP_Settings_Keys_String id)
Returns a immutable string settings value.
WINPR_ATTR_NODISCARD FREERDP_API BOOL freerdp_settings_set_bool(rdpSettings *settings, FreeRDP_Settings_Keys_Bool id, BOOL val)
Sets a BOOL settings value.
WINPR_ATTR_NODISCARD FREERDP_API rdpSettings * freerdp_settings_deserialize(const char *jstr, size_t length)
A function that converts a JSON string to a rdpSettings struct.
FREERDP_API void freerdp_settings_free(rdpSettings *settings)
Free a settings struct with all data in it.
WINPR_ATTR_NODISCARD FREERDP_API UINT32 freerdp_settings_get_uint32(const rdpSettings *settings, FreeRDP_Settings_Keys_UInt32 id)
Returns a UINT32 settings value.
WINPR_ATTR_NODISCARD FREERDP_API char * freerdp_settings_serialize(const rdpSettings *settings, BOOL pretty, size_t *plength)
A function that converts a rdpSettings struct to a JSON serialized string.
WINPR_ATTR_NODISCARD FREERDP_API BOOL freerdp_settings_get_bool(const rdpSettings *settings, FreeRDP_Settings_Keys_Bool id)
Returns a boolean settings value.
WINPR_ATTR_NODISCARD FREERDP_API BOOL freerdp_settings_print_diff(wLog *log, DWORD level, const rdpSettings *settings, const rdpSettings *other)
Dumps the difference between two settings structs to a WLog.