FreeRDP
Loading...
Searching...
No Matches
TestMsUsb.c
1#include <winpr/crt.h>
2#include <winpr/stream.h>
3
4#include <msusb.h>
5
6/* One MSUSB interface descriptor with NumberOfPipes == 0 (12 bytes) followed by
7 * the 6 byte configuration descriptor trailer that msusb_msconfig_read reads. */
8static const BYTE config_one_iface[] = {
9 /* interface[0] */
10 0x12, 0x00, /* Length */
11 0x00, 0x00, /* NumberOfPipesExpected */
12 0x00, /* InterfaceNumber */
13 0x00, /* AlternateSetting */
14 0x00, 0x00, /* padding */
15 0x00, 0x00, 0x00, 0x00, /* NumberOfPipes = 0 */
16 /* configuration descriptor trailer */
17 0x09, /* lenConfiguration */
18 0x02, /* typeConfiguration */
19 0xef, 0xbe, /* wTotalLength = 0xBEEF */
20 0x00, /* padding */
21 0x42 /* bConfigurationValue */
22};
23
24static int test_full_config(void)
25{
26 wStream sbuffer = { 0 };
27 wStream* s = Stream_StaticConstInit(&sbuffer, config_one_iface, sizeof(config_one_iface));
28
29 MSUSB_CONFIG_DESCRIPTOR* cfg = msusb_msconfig_read(s, 1);
30 if (!cfg)
31 {
32 (void)fprintf(stderr, "msusb_msconfig_read rejected a complete descriptor\n");
33 return -1;
34 }
35
36 int rc = 0;
37 if ((cfg->wTotalLength != 0xBEEF) || (cfg->bConfigurationValue != 0x42) ||
38 (cfg->NumInterfaces != 1))
39 {
40 (void)fprintf(stderr, "msusb_msconfig_read parsed wrong values\n");
41 rc = -1;
42 }
43 msusb_msconfig_free(cfg);
44 return rc;
45}
46
47/* The descriptor data ends right after the interface list: the 6 byte
48 * configuration trailer is missing. The reader must not walk past the end of
49 * the received data. */
50static int test_truncated_trailer(void)
51{
52 wStream sbuffer = { 0 };
53 wStream* s = Stream_StaticConstInit(&sbuffer, config_one_iface, 12);
54
55 MSUSB_CONFIG_DESCRIPTOR* cfg = msusb_msconfig_read(s, 1);
56 if (cfg)
57 {
58 (void)fprintf(stderr, "msusb_msconfig_read accepted a truncated trailer\n");
59 msusb_msconfig_free(cfg);
60 return -1;
61 }
62 return 0;
63}
64
65/* Capacity larger than the sealed length must not let the reader consume the
66 * unused tail of the (recycled) buffer. */
67static int test_capacity_exceeds_length(void)
68{
69 BYTE buffer[64] = { 0 };
70 CopyMemory(buffer, config_one_iface, sizeof(config_one_iface));
71
72 wStream sbuffer = { 0 };
73 wStream* s = Stream_StaticInit(&sbuffer, buffer, sizeof(buffer));
74 if (!Stream_SetLength(s, 12))
75 return -1;
76
77 MSUSB_CONFIG_DESCRIPTOR* cfg = msusb_msconfig_read(s, 1);
78 if (cfg)
79 {
80 (void)fprintf(stderr, "msusb_msconfig_read read past the sealed length\n");
81 msusb_msconfig_free(cfg);
82 return -1;
83 }
84 return 0;
85}
86
87/* msusb_msinterface_read claims NumberOfPipes pipes whose data is not present. */
88static int test_interface_truncated_pipes(void)
89{
90 const BYTE iface[] = {
91 0x10, 0x00, /* Length */
92 0x01, 0x00, /* NumberOfPipesExpected */
93 0x00, /* InterfaceNumber */
94 0x00, /* AlternateSetting */
95 0x00, 0x00, /* padding */
96 0x04, 0x00, 0x00, 0x00 /* NumberOfPipes = 4, but no pipe data follows */
97 };
98 wStream sbuffer = { 0 };
99 wStream* s = Stream_StaticConstInit(&sbuffer, iface, sizeof(iface));
100
101 MSUSB_INTERFACE_DESCRIPTOR* desc = msusb_msinterface_read(s);
102 if (desc)
103 {
104 (void)fprintf(stderr, "msusb_msinterface_read accepted missing pipe data\n");
105 msusb_msinterface_free(desc);
106 return -1;
107 }
108 return 0;
109}
110
111int TestMsUsb(int argc, char* argv[])
112{
113 WINPR_UNUSED(argc);
114 WINPR_UNUSED(argv);
115
116 if (test_full_config() != 0)
117 return -1;
118 if (test_truncated_trailer() != 0)
119 return -1;
120 if (test_capacity_exceeds_length() != 0)
121 return -1;
122 if (test_interface_truncated_pipes() != 0)
123 return -1;
124 return 0;
125}