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, ...)
247 rc = vsnprintf(NULL, 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;
282 FILE* fp = test_fopen(name,
"r");
285 if (fseek(fp, 0, SEEK_END) != 0)
287 const size_t pos = WINPR_ASSERTING_INT_CAST(
size_t, _ftelli64(fp));
288 if (fseek(fp, 0, SEEK_SET) != 0)
291 json = calloc(1ULL + pos,
sizeof(
char));
294 if (fread(json, 1, pos, fp) != pos)
302 char buffer[128] = { 0 };
303 WLog_ERR(__func__,
"failed to read data from '%s': %s", name,
304 winpr_strerror(errno, buffer,
sizeof(buffer)));
314static bool save_settings(
const rdpSettings* settings,
const char* name)
322 FILE* fp = test_fopen(name,
"w");
325 const size_t res = fwrite(data, 1, datalen, fp);
334static char* get_json_name(
const char* base,
bool unchecked)
338 winpr_asprintf(&name, &namelen,
"%s%s.json", base, unchecked ?
".unchecked" :
"");
342static rdpSettings* read_json(
const char* name)
345 void* data = read_rdp_data(name, &datalen);
352static rdpSettings* load_from(
const void* data,
size_t len,
bool unchecked)
355 rdpFile* file = freerdp_client_rdp_file_new();
356 rdpSettings* settings = read_json(
"default-settings.json");
362 save_settings(settings,
"default-settings.json");
365 if (!file || !settings)
368 if (!freerdp_client_parse_rdp_file_buffer(file, data, len))
373 if (!freerdp_client_populate_settings_from_rdp_file_unchecked(file, settings))
378 if (!freerdp_client_populate_settings_from_rdp_file(file, settings))
384 freerdp_client_rdp_file_free(file);
393static rdpSettings* load_from_file(
const char* name,
bool unchecked)
396 void* data = read_rdp_data(name, &datalen);
399 rdpSettings* settings = load_from(data, datalen, unchecked);
404static bool test_data(
const char* json,
const void* data,
size_t len,
bool unchecked)
408 rdpSettings* settings = load_from(data, len, unchecked);
409 rdpSettings* expect = read_json(json);
410 if (!settings || !expect)
413 wLog* log = WLog_Get(__func__);
414 WLog_Print(log, WLOG_INFO,
"Test cast '%s'", json);
424static HANDLE FindFirstFileUTF8(LPCSTR pszSearchPath,
WIN32_FIND_DATAW* FindData)
426 HANDLE hdl = INVALID_HANDLE_VALUE;
429 WCHAR* wpath = ConvertUtf8ToWCharAlloc(pszSearchPath, NULL);
433 hdl = FindFirstFileW(wpath, FindData);
439static bool test_rdp_file(
const char* base,
bool allowCreate,
bool unchecked)
445 winpr_asprintf(&rdp, &rdplen,
"%s.rdp", base);
446 char* json = get_json_name(base, unchecked);
448 void* data = read_rdp_data(rdp, &datalen);
453 rc = test_data(json, data, datalen, unchecked);
454 if (!rc && allowCreate)
456 rdpSettings* expect = read_json(json);
463 rdpSettings* settings = load_from_file(rdp, unchecked);
467 rc = save_settings(settings, json);
476static bool test_rdp_files(
bool allowCreate)
482#ifndef TEST_SOURCE_DIR
483#error "TEST_SOURCE_DIR must be defined to the test source directory"
486 HANDLE hdl = INVALID_HANDLE_VALUE;
487 char* path = GetCombinedPath(TEST_SOURCE_DIR,
"rdp-testcases/*.rdp");
492 hdl = FindFirstFileUTF8(path, &FindData);
494 if (hdl == INVALID_HANDLE_VALUE)
498 "no RDP files found in %s. Add RDP files to generate settings JSON for comparison.",
506 if ((FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0)
508 char cFileName[6 * MAX_PATH] = { 0 };
509 char rdp[6 * MAX_PATH] = { 0 };
510 ConvertWCharToUtf8(FindData.cFileName, cFileName,
sizeof(cFileName));
511 const size_t len = strnlen(cFileName,
sizeof(cFileName));
514 strcpy(rdp,
"rdp-testcases/");
515 strncpy(&rdp[14], cFileName, len - 4);
517 if (!test_rdp_file(rdp, allowCreate,
false))
519 if (!test_rdp_file(rdp, allowCreate,
true))
522 }
while (FindNextFileW(hdl, &FindData));
532int TestClientRdpFile(
int argc,
char* argv[])
537 const UINT32* puValue = NULL;
538 const char* sValue = NULL;
539 char* utfname = NULL;
540 char* uniname = NULL;
544 rdpFile* file = NULL;
545 rdpSettings* settings = NULL;
549 winpr_RAND(&
id,
sizeof(
id));
552#if defined(CHANNEL_URBDRC_CLIENT) && defined(CHANNEL_RDPECAM_CLIENT)
553 if (!test_data(
"testRdpFileUTF8.json", testRdpFileUTF8,
sizeof(testRdpFileUTF8),
false))
555 if (!test_data(
"testRdpFileUTF8.unchecked.json", testRdpFileUTF8,
sizeof(testRdpFileUTF8),
561#if defined(CHANNEL_URBDRC_CLIENT)
562 if (!test_data(
"testRdpFileUTF16.json", testRdpFileUTF16,
sizeof(testRdpFileUTF16),
false))
564 if (!test_data(
"testRdpFileUTF16.unchecked.json", testRdpFileUTF16,
sizeof(testRdpFileUTF16),
569#if defined(CHANNEL_URBDRC_CLIENT) && defined(CHANNEL_RDPECAM_CLIENT)
570 if (!test_rdp_files(argc > 1))
575 file = freerdp_client_rdp_file_new();
577 if (!file || !settings)
579 printf(
"rdp_file_new failed\n");
583 if (!freerdp_client_parse_rdp_file_buffer(file, (BYTE*)testRdpFileUTF8,
584 sizeof(testRdpFileUTF8)))
587 if (!freerdp_client_populate_settings_from_rdp_file(file, settings))
592 printf(
"UseMultiMon mismatch: Actual: %" PRIu32
", Expected: 0\n",
599 printf(
"ScreenModeId mismatch: Actual: %" PRIu32
", Expected: TRUE\n",
605 "LAB1-W7-DM-01.lab1.awake.global") != 0)
607 printf(
"ServerHostname mismatch: Actual: %s, Expected: %s\n",
609 "LAB1-W7-DM-01.lab1.awake.global");
614 "LAB1-W2K8R2-GW.lab1.awake.local") != 0)
616 printf(
"GatewayHostname mismatch: Actual: %s, Expected: %s\n",
618 "LAB1-W2K8R2-GW.lab1.awake.local");
622 iValue = freerdp_client_rdp_file_get_integer_option(file,
"dynamic resolution");
625 printf(
"dynamic resolution uses invalid default value %d", iValue);
630 printf(
"FreeRDP_DynamicResolutionUpdate has invalid value");
633 iValue = freerdp_client_rdp_file_get_integer_option(file,
"desktopscalefactor");
636 printf(
"desktopscalefactor uses invalid default value %d", iValue);
641 printf(
"FreeRDP_DesktopScaleFactor has invalid value");
646#if defined(CHANNEL_RDPECAM_CLIENT)
650 freerdp_client_rdp_file_get_integer_option(file,
"encode redirected video capture");
653 printf(
"encode redirected video capture uses invalid default value %d", iValue);
656 iValue = freerdp_client_rdp_file_get_integer_option(
657 file,
"redirected video capture encoding quality");
660 printf(
"redirected video capture encoding quality uses invalid default value %d",
664 args = freerdp_dynamic_channel_collection_find(settings, RDPECAM_DVC_CHANNEL_NAME);
667 printf(
"rdpecam channel was not loaded");
672 printf(
"rdpecam channel was not loaded");
676 for (
int x = 0; x < args->argc; x++)
678 if (strcmp(args->argv[x], camera_args[x]) != 0)
680 printf(
"rdpecam invalid argument argv[%d]: %s", x, args->argv[x]);
688#if defined(CHANNEL_URBDRC_CLIENT)
690 ADDIN_ARGV* args = freerdp_dynamic_channel_collection_find(settings,
"urbdrc");
693 printf(
"urbdrc channel was not loaded");
698 printf(
"urbdrc channel was not loaded");
702 for (
int x = 0; x < args->argc; x++)
704 if (strcmp(args->argv[x], urbdrc_args[x]) != 0)
706 printf(
"urbdrc invalid argument argv[%d]: %s", x, args->argv[x]);
717 printf(
"FreeRDP_NumMonitorIds has invalid value %" PRIu32, uValue);
720 puValue = (
const UINT32*)freerdp_settings_get_pointer_array(settings, FreeRDP_MonitorIds, 0);
723 printf(
"FreeRDP_MonitorIds has invalid value %p", (
const void*)puValue);
726 if ((puValue[0] != 3) || (puValue[1] != 2) || (puValue[2] != 42) || (puValue[3] != 23))
728 printf(
"FreeRDP_MonitorIds has invalid values: [%" PRIu32
",%" PRIu32
",%" PRIu32
730 puValue[0], puValue[1], puValue[2], puValue[3]);
734 iValue = freerdp_client_rdp_file_get_integer_option(file,
"videoplaybackmode");
737 printf(
"videoplaybackmode uses invalid default value %d", iValue);
742 printf(
"FreeRDP_SupportVideoOptimized has invalid value");
747 printf(
"FreeRDP_SupportGeometryTracking has invalid value");
751 iValue = freerdp_client_rdp_file_get_integer_option(file,
"vendor integer");
755 if (freerdp_client_rdp_file_set_integer_option(file,
"vendor integer", 456) == -1)
757 printf(
"failed to set integer: vendor integer");
761 iValue = freerdp_client_rdp_file_get_integer_option(file,
"vendor integer");
765 const char microsoft[] =
"microsoft";
766 sValue = freerdp_client_rdp_file_get_string_option(file,
"vendor string");
767 if (strncmp(sValue, microsoft,
sizeof(microsoft)) != 0)
770 const char apple[] =
"apple";
771 freerdp_client_rdp_file_set_string_option(file,
"vendor string",
"apple");
772 sValue = freerdp_client_rdp_file_get_string_option(file,
"vendor string");
773 if (strncmp(sValue, apple,
sizeof(apple)) != 0)
776 freerdp_client_rdp_file_set_string_option(file,
"fruits",
"banana,oranges");
778 if (freerdp_client_rdp_file_set_integer_option(file,
"numbers", 123456789) == -1)
780 printf(
"failed to set integer: numbers");
784 freerdp_client_rdp_file_free(file);
786 tmp = GetKnownPath(KNOWN_PATH_TEMP);
790 base = append(
"%s/rdp-file-test-%" PRIx64, tmp,
id);
793 if (!CreateDirectoryA(base, NULL))
795 utfname = append(
"%s/utfname", base);
796 uniname = append(
"%s/uniname", base);
797 file = freerdp_client_rdp_file_new();
798 if (!file || !utfname || !uniname)
801 if (!freerdp_client_populate_rdp_file_from_settings(file, settings))
804 if (!freerdp_client_write_rdp_file(file, utfname, FALSE))
807 if (!freerdp_client_write_rdp_file(file, uniname, TRUE))
813 winpr_DeleteFile(utfname);
815 winpr_DeleteFile(uniname);
817 winpr_RemoveDirectory(base);
822 freerdp_client_rdp_file_free(file);
FREERDP_API UINT32 freerdp_settings_get_uint32(const rdpSettings *settings, FreeRDP_Settings_Keys_UInt32 id)
Returns a UINT32 settings value.
FREERDP_API BOOL freerdp_settings_get_bool(const rdpSettings *settings, FreeRDP_Settings_Keys_Bool id)
Returns a boolean settings value.
FREERDP_API rdpSettings * freerdp_settings_new(DWORD flags)
creates a new setting struct
FREERDP_API BOOL freerdp_settings_print_diff(wLog *log, DWORD level, const rdpSettings *src, const rdpSettings *other)
Dumps the difference between two settings structs to a WLog.
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.
FREERDP_API void freerdp_settings_free(rdpSettings *settings)
Free a settings struct with all data in it.
FREERDP_API const char * freerdp_settings_get_string(const rdpSettings *settings, FreeRDP_Settings_Keys_String id)
Returns a immutable string settings value.
FREERDP_API rdpSettings * freerdp_settings_deserialize(const char *json, size_t length)
A function that converts a JSON string to a rdpSettings struct.