21
|
1 ???using System; |
|
2 using System.Collections.Generic; |
|
3 using System.Text; |
|
4 using System.Runtime.InteropServices; |
|
5 using UCIS.USBLib.Communication; |
|
6 |
|
7 namespace UCIS.USBLib.Descriptor { |
|
8 [StructLayout(LayoutKind.Sequential, Pack = 1)] |
|
9 public struct UsbDescriptor { |
|
10 byte bmLength; |
|
11 byte bType; |
|
12 public Byte Length { get { return bmLength; } } |
|
13 public UsbDescriptorType Type { get { return (UsbDescriptorType)bType; } } |
|
14 internal static short FromLittleEndian(short value) { |
|
15 if (BitConverter.IsLittleEndian) return value; |
|
16 return (short)(((value & 0xFF) << 8) | ((value >> 8) & 0xFF)); |
|
17 } |
|
18 public unsafe static UsbDescriptor FromByteArray(Byte[] buffer, int offset, int length) { |
|
19 if (length < Marshal.SizeOf(typeof(UsbDescriptor))) throw new ArgumentOutOfRangeException("length", "The data length is smaller than the descriptor length"); |
|
20 if (offset < 0 || length < 0 || offset + length > buffer.Length) throw new ArgumentOutOfRangeException("length", "The specified offset and length exceed the buffer dimensions"); |
|
21 fixed (Byte* ptr = buffer) return *(UsbDescriptor*)(ptr + offset); |
|
22 } |
|
23 } |
|
24 [StructLayout(LayoutKind.Sequential, Pack = 1)] |
|
25 public struct UsbStringDescriptor { |
|
26 public static String GetString(Byte[] buffer, int offset, int length) { |
|
27 if (length < 2) throw new ArgumentOutOfRangeException("length", "The data length is smaller than the descriptor length"); |
|
28 if (offset < 0 || length < 0 || offset + length > buffer.Length) throw new ArgumentOutOfRangeException("length", "The specified offset and length exceed the buffer dimensions"); |
|
29 if (buffer[offset + 1] != (Byte)UsbDescriptorType.String) throw new InvalidOperationException("The descriptor is not a string descriptor"); |
|
30 int slen = buffer[offset]; |
|
31 if (slen > length) throw new InvalidOperationException("The string has been truncated"); |
|
32 return Encoding.Unicode.GetString(buffer, offset + 2, slen - 2); |
|
33 } |
|
34 } |
|
35 [StructLayout(LayoutKind.Sequential, Pack = 1)] |
|
36 public struct UsbDeviceDescriptor { |
|
37 byte bmLength; |
|
38 byte bType; |
|
39 short bcdUSB; |
|
40 byte bDeviceClass; |
|
41 byte bDeviceSubClass; |
|
42 byte bDeviceProtocol; |
|
43 byte bMaxControlPacketSize; |
|
44 short idVendor; |
|
45 short idProduct; |
|
46 short bcdDevice; |
|
47 byte iManufacturer; |
|
48 byte iProduct; |
|
49 byte iSerialNumber; |
|
50 byte numConfigurations; |
|
51 public Byte Length { get { return bmLength; } } |
|
52 public UsbDescriptorType Type { get { return (UsbDescriptorType)bType; }} |
|
53 public short USBVersion { get { return UsbDescriptor.FromLittleEndian(bcdUSB); } } |
|
54 public Byte DeviceClass { get { return bDeviceClass; } } |
|
55 public Byte DeviceSubClass { get { return bDeviceSubClass; } } |
|
56 public Byte DeviceProtocol { get { return bDeviceProtocol; } } |
|
57 public short DeviceVersion { get { return UsbDescriptor.FromLittleEndian(bcdDevice); } } |
|
58 public Byte MaxControlPacketSize { get { return bMaxControlPacketSize; } } |
|
59 public short VendorID { get { return UsbDescriptor.FromLittleEndian(idVendor); } } |
|
60 public short ProductID { get { return UsbDescriptor.FromLittleEndian(idProduct); } } |
|
61 public Byte ManufacturerStringID { get { return iManufacturer; } } |
|
62 public Byte ProductStringID { get { return iProduct; } } |
|
63 public Byte SerialNumberStringID { get { return iSerialNumber; } } |
|
64 public Byte NumConfigurations { get { return numConfigurations; } } |
|
65 public unsafe static UsbDeviceDescriptor FromByteArray(Byte[] buffer, int offset, int length) { |
|
66 if (length < Size) throw new ArgumentOutOfRangeException("length", "The data length is smaller than the descriptor length"); |
|
67 if (offset < 0 || length < 0 || offset + length > buffer.Length) throw new ArgumentOutOfRangeException("length", "The specified offset and length exceed the buffer dimensions"); |
|
68 fixed (Byte* ptr = buffer) return *(UsbDeviceDescriptor*)(ptr + offset); |
|
69 } |
|
70 public static unsafe int Size { get { return sizeof(UsbDeviceDescriptor); } } |
|
71 } |
|
72 [StructLayout(LayoutKind.Sequential, Pack = 1)] |
|
73 public struct UsbConfigurationDescriptor { |
|
74 byte bmLength; |
|
75 byte bType; |
|
76 short wTotalLength; |
|
77 byte bNumInterfaces; |
|
78 byte bConfigurationValue; |
|
79 byte bConfigurationStringID; |
|
80 byte bmAttributes; |
|
81 byte bMaxPower; |
|
82 public Byte Length { get { return bmLength; } } |
|
83 public UsbDescriptorType Type { get { return (UsbDescriptorType)bType; } } |
|
84 public short TotalLength { get { return UsbDescriptor.FromLittleEndian(wTotalLength); } } |
|
85 public Byte NumInterfaces { get { return bNumInterfaces; } } |
|
86 public Byte ConfigurationValue { get { return bConfigurationValue; } } |
|
87 public Byte ConfigurationStringID { get { return bConfigurationStringID; } } |
|
88 public Boolean SelfPowered { get { return 0 != (bmAttributes & (1 << 6)); } } |
|
89 public Boolean RemoteWakeup { get { return 0 != (bmAttributes & (1 << 5)); } } |
|
90 public int MaxPowerMA { get { return bMaxPower * 2; } } |
|
91 public unsafe static UsbConfigurationDescriptor FromByteArray(Byte[] buffer, int offset, int length) { |
|
92 if (length < Size) throw new ArgumentOutOfRangeException("length", "The data length is smaller than the descriptor length"); |
|
93 if (offset < 0 || length < 0 || offset + length > buffer.Length) throw new ArgumentOutOfRangeException("length", "The specified offset and length exceed the buffer dimensions"); |
|
94 fixed (Byte* ptr = buffer) return *(UsbConfigurationDescriptor*)(ptr + offset); |
|
95 } |
|
96 public static unsafe int Size { get { return sizeof(UsbConfigurationDescriptor); } } |
|
97 } |
|
98 [StructLayout(LayoutKind.Sequential, Pack = 1)] |
|
99 public struct UsbInterfaceDescriptor { |
|
100 byte bmLength; |
|
101 byte bType; |
|
102 byte bInterfaceNumber; |
|
103 byte bAlternateSetting; |
|
104 byte bNumEndpoints; |
|
105 byte bInterfaceClass; |
|
106 byte bInterfaceSubClass; |
|
107 byte bInterfaceProtocol; |
|
108 byte bInterfaceStringID; |
|
109 public Byte Length { get { return bmLength; } } |
|
110 public UsbDescriptorType Type { get { return (UsbDescriptorType)bType; } } |
|
111 public Byte InterfaceNumber { get { return bInterfaceNumber; } } |
|
112 public Byte AlternateSetting { get { return bAlternateSetting; } } |
|
113 public Byte NumEndpoints { get { return bNumEndpoints; } } |
|
114 public Byte InterfaceClass { get { return bInterfaceClass; } } |
|
115 public Byte InterfaceSubClass { get { return bInterfaceSubClass; } } |
|
116 public Byte InterfaceProtocol { get { return bInterfaceProtocol; } } |
|
117 public Byte InterfaceStringID { get { return bInterfaceStringID; } } |
|
118 public unsafe static UsbInterfaceDescriptor FromByteArray(Byte[] buffer, int offset, int length) { |
|
119 if (length < Size) throw new ArgumentOutOfRangeException("length", "The data length is smaller than the descriptor length"); |
|
120 if (offset < 0 || length < 0 || offset + length > buffer.Length) throw new ArgumentOutOfRangeException("length", "The specified offset and length exceed the buffer dimensions"); |
|
121 fixed (Byte* ptr = buffer) return *(UsbInterfaceDescriptor*)(ptr + offset); |
|
122 } |
|
123 public static unsafe int Size { get { return sizeof(UsbInterfaceDescriptor); } } |
|
124 } |
|
125 [StructLayout(LayoutKind.Sequential, Pack = 1)] |
|
126 public struct UsbEndpointDescriptor { |
|
127 byte bmLength; |
|
128 byte bType; |
|
129 byte bEndpointAddress; |
|
130 Byte bmAttributes; |
|
131 short wMaxPacketSize; |
|
132 byte bInterval; |
|
133 public Byte Length { get { return bmLength; } } |
|
134 public UsbDescriptorType Type { get { return (UsbDescriptorType)bType; } } |
|
135 public Byte EndpointAddress { get { return bEndpointAddress; } } |
|
136 public Boolean IsInput { get { return 0 != (EndpointAddress & (1 << 7)); } } |
|
137 public int EndpointNumber { get { return EndpointAddress & 0xF; } } |
|
138 public int TransferType { get { return bmAttributes & 3; } } |
|
139 public Boolean IsControl { get { return TransferType == 0; } } |
|
140 public Boolean IsIsochronous { get { return TransferType == 1; } } |
|
141 public Boolean IsBulk { get { return TransferType == 2; } } |
|
142 public Boolean IsInterrupt { get { return TransferType == 3; } } |
|
143 public int MaxPacketSize { get { return UsbDescriptor.FromLittleEndian(wMaxPacketSize) & 0x7FF; } } |
|
144 public Byte Interval { get { return bInterval; } } |
|
145 public unsafe static UsbEndpointDescriptor FromByteArray(Byte[] buffer, int offset, int length) { |
|
146 if (length < Size) throw new ArgumentOutOfRangeException("length", "The data length is smaller than the descriptor length"); |
|
147 if (offset < 0 || length < 0 || offset + length > buffer.Length) throw new ArgumentOutOfRangeException("length", "The specified offset and length exceed the buffer dimensions"); |
|
148 fixed (Byte* ptr = buffer) return *(UsbEndpointDescriptor*)(ptr + offset); |
|
149 } |
|
150 public static unsafe int Size { get { return sizeof(UsbEndpointDescriptor); } } |
|
151 } |
|
152 [StructLayout(LayoutKind.Sequential, Pack = 1)] |
|
153 public struct UsbHIDDescriptor { |
|
154 byte bmLength; |
|
155 byte bType; |
|
156 short bcdHID; |
|
157 byte bCountryCode; |
|
158 byte bNumDescriptors; |
|
159 byte bDescriptorType; |
|
160 short wDescriptorLength; |
|
161 public Byte Length { get { return bmLength; } } |
|
162 public UsbDescriptorType Type { get { return (UsbDescriptorType)bType; } } |
|
163 public short HIDVersion { get { return UsbDescriptor.FromLittleEndian(bcdHID); } } |
|
164 public Byte CountryCode { get { return bCountryCode; } } |
|
165 public Byte NumDescriptors { get { return bNumDescriptors; } } |
|
166 public UsbDescriptorType DescriptorType { get { return (UsbDescriptorType)bDescriptorType; } } |
|
167 public short DescriptorLength { get { return UsbDescriptor.FromLittleEndian(wDescriptorLength); } } |
|
168 public unsafe static UsbHIDDescriptor FromByteArray(Byte[] buffer, int offset, int length) { |
|
169 if (length < Size) throw new ArgumentOutOfRangeException("length", "The data length is smaller than the descriptor length"); |
|
170 if (offset < 0 || length < 0 || offset + length > buffer.Length) throw new ArgumentOutOfRangeException("length", "The specified offset and length exceed the buffer dimensions"); |
|
171 fixed (Byte* ptr = buffer) return *(UsbHIDDescriptor*)(ptr + offset); |
|
172 } |
|
173 public static unsafe int Size { get { return sizeof(UsbHIDDescriptor); } } |
|
174 } |
|
175 [StructLayout(LayoutKind.Sequential, Pack = 1)] |
|
176 public struct UsbHubDescriptor { |
|
177 byte bmLength; |
|
178 byte bType; |
|
179 byte bNumPorts; |
|
180 short wHubCharacteristics; |
|
181 byte bPwrOn2PwrGood; //2ms intervals |
|
182 byte bHubControllerCurrent; |
|
183 public Byte Length { get { return bmLength; } } |
|
184 public UsbDescriptorType Type { get { return (UsbDescriptorType)bType; } } |
|
185 public Byte NumPorts { get { return bNumPorts; } } |
|
186 public Boolean IsCompoundDevice { get { return 0 != (wHubCharacteristics & (1 << 2)); } } |
|
187 public Byte HubControllerCurrent { get { return bHubControllerCurrent; } } |
|
188 public unsafe static UsbHubDescriptor FromByteArray(Byte[] buffer, int offset, int length) { |
|
189 if (length < Marshal.SizeOf(typeof(UsbHubDescriptor))) throw new ArgumentOutOfRangeException("length", "The data length is smaller than the descriptor length"); |
|
190 if (offset < 0 || length < 0 || offset + length > buffer.Length) throw new ArgumentOutOfRangeException("length", "The specified offset and length exceed the buffer dimensions"); |
|
191 fixed (Byte* ptr = buffer) return *(UsbHubDescriptor*)(ptr + offset); |
|
192 } |
|
193 } |
|
194 } |