|
3 | 3 | using static FirmwareKit.Comm.Fastboot.Usb.Windows.Win32API; |
4 | 4 |
|
5 | 5 | namespace FirmwareKit.Comm.Fastboot.Usb.Windows; |
6 | | - public class LegacyUsbDevice : UsbDevice |
7 | | - { |
8 | | - private const int IoTimeoutMs = 30000; |
9 | | - public static uint IoGetSerialCode => CTL_CODE(FILE_DEVICE_UNKNOWN, 0x801, METHOD_BUFFERED, FILE_READ_ACCESS); |
10 | | - public static uint IoGetDescriptorCode => CTL_CODE(FILE_DEVICE_UNKNOWN, 0x802, METHOD_BUFFERED, FILE_READ_ACCESS); |
11 | | - |
12 | | - private IntPtr fileHandle = INVALID_HANDLE_VALUE; |
13 | 6 |
|
14 | | - public IntPtr Handle => fileHandle; |
| 7 | +public class LegacyUsbDevice : UsbDevice |
| 8 | +{ |
| 9 | + private const int IoTimeoutMs = 30000; |
| 10 | + public static uint IoGetSerialCode => CTL_CODE(FILE_DEVICE_UNKNOWN, 0x801, METHOD_BUFFERED, FILE_READ_ACCESS); |
| 11 | + public static uint IoGetDescriptorCode => CTL_CODE(FILE_DEVICE_UNKNOWN, 0x802, METHOD_BUFFERED, FILE_READ_ACCESS); |
15 | 12 |
|
16 | | - public override int CreateHandle() |
17 | | - { |
18 | | - fileHandle = SimpleCreateHandle(DevicePath); |
19 | | - if (fileHandle == INVALID_HANDLE_VALUE) |
20 | | - return Marshal.GetLastWin32Error(); |
| 13 | + private IntPtr fileHandle = INVALID_HANDLE_VALUE; |
21 | 14 |
|
22 | | - if (!CheckInterface()) |
23 | | - { |
24 | | - CloseHandle(fileHandle); |
25 | | - fileHandle = INVALID_HANDLE_VALUE; |
26 | | - return -1; |
27 | | - } |
| 15 | + public IntPtr Handle => fileHandle; |
28 | 16 |
|
29 | | - GetSerialNumber(); |
30 | | - return 0; |
31 | | - } |
| 17 | + public override int CreateHandle() |
| 18 | + { |
| 19 | + fileHandle = SimpleCreateHandle(DevicePath); |
| 20 | + if (fileHandle == INVALID_HANDLE_VALUE) |
| 21 | + return Marshal.GetLastWin32Error(); |
32 | 22 |
|
33 | | - private bool CheckInterface() |
| 23 | + if (!CheckInterface()) |
34 | 24 | { |
35 | | - byte[] buffer = new byte[256]; |
36 | | - int returned; |
37 | | - return DeviceIoControl(fileHandle, IoGetSerialCode, null, 0, buffer, buffer.Length, out returned, IntPtr.Zero); |
| 25 | + CloseHandle(fileHandle); |
| 26 | + fileHandle = INVALID_HANDLE_VALUE; |
| 27 | + return -1; |
38 | 28 | } |
39 | 29 |
|
40 | | - public override int GetSerialNumber() |
| 30 | + GetSerialNumber(); |
| 31 | + return 0; |
| 32 | + } |
| 33 | + |
| 34 | + private bool CheckInterface() |
| 35 | + { |
| 36 | + byte[] buffer = new byte[256]; |
| 37 | + int returned; |
| 38 | + return DeviceIoControl(fileHandle, IoGetSerialCode, null, 0, buffer, buffer.Length, out returned, IntPtr.Zero); |
| 39 | + } |
| 40 | + |
| 41 | + public override int GetSerialNumber() |
| 42 | + { |
| 43 | + byte[] buffer = new byte[256]; |
| 44 | + int returned; |
| 45 | + if (DeviceIoControl(fileHandle, IoGetSerialCode, null, 0, buffer, buffer.Length, out returned, IntPtr.Zero)) |
41 | 46 | { |
42 | | - byte[] buffer = new byte[256]; |
43 | | - int returned; |
44 | | - if (DeviceIoControl(fileHandle, IoGetSerialCode, null, 0, buffer, buffer.Length, out returned, IntPtr.Zero)) |
45 | | - { |
46 | | - SerialNumber = System.Text.Encoding.Unicode.GetString(buffer, 0, returned).TrimEnd('\0'); |
47 | | - return 0; |
48 | | - } |
49 | | - return Marshal.GetLastWin32Error(); |
| 47 | + SerialNumber = System.Text.Encoding.Unicode.GetString(buffer, 0, returned).TrimEnd('\0'); |
| 48 | + return 0; |
50 | 49 | } |
| 50 | + return Marshal.GetLastWin32Error(); |
| 51 | + } |
51 | 52 |
|
52 | | - public override byte[] Read(int length) |
| 53 | + public override byte[] Read(int length) |
| 54 | + { |
| 55 | + var readTask = Task.Run(() => |
53 | 56 | { |
54 | | - var readTask = Task.Run(() => |
55 | | - { |
56 | | - byte[] buffer = new byte[length]; |
57 | | - uint read; |
58 | | - if (ReadFile(fileHandle, buffer, (uint)length, out read, IntPtr.Zero)) |
59 | | - { |
60 | | - byte[] result = new byte[read]; |
61 | | - Array.Copy(buffer, result, (int)read); |
62 | | - return result; |
63 | | - } |
64 | | - throw new Win32Exception(Marshal.GetLastWin32Error()); |
65 | | - }); |
66 | | - |
67 | | - if (!readTask.Wait(IoTimeoutMs)) |
| 57 | + byte[] buffer = new byte[length]; |
| 58 | + uint read; |
| 59 | + if (ReadFile(fileHandle, buffer, (uint)length, out read, IntPtr.Zero)) |
68 | 60 | { |
69 | | - throw new TimeoutException($"Legacy USB read timed out after {IoTimeoutMs} ms."); |
| 61 | + byte[] result = new byte[read]; |
| 62 | + Array.Copy(buffer, result, (int)read); |
| 63 | + return result; |
70 | 64 | } |
| 65 | + throw new Win32Exception(Marshal.GetLastWin32Error()); |
| 66 | + }); |
71 | 67 |
|
72 | | - return readTask.GetAwaiter().GetResult(); |
| 68 | + if (!readTask.Wait(IoTimeoutMs)) |
| 69 | + { |
| 70 | + throw new TimeoutException($"Legacy USB read timed out after {IoTimeoutMs} ms."); |
73 | 71 | } |
74 | 72 |
|
75 | | - public override long Write(byte[] data, int length) |
| 73 | + return readTask.GetAwaiter().GetResult(); |
| 74 | + } |
| 75 | + |
| 76 | + public override long Write(byte[] data, int length) |
| 77 | + { |
| 78 | + var writeTask = Task.Run(() => |
76 | 79 | { |
77 | | - var writeTask = Task.Run(() => |
| 80 | + uint written; |
| 81 | + if (WriteFile(fileHandle, data, (uint)length, out written, IntPtr.Zero)) |
78 | 82 | { |
79 | | - uint written; |
80 | | - if (WriteFile(fileHandle, data, (uint)length, out written, IntPtr.Zero)) |
81 | | - { |
82 | | - return (long)written; |
83 | | - } |
84 | | - throw new Win32Exception(Marshal.GetLastWin32Error()); |
85 | | - }); |
86 | | - |
87 | | - if (!writeTask.Wait(IoTimeoutMs)) |
88 | | - { |
89 | | - throw new TimeoutException($"Legacy USB write timed out after {IoTimeoutMs} ms."); |
| 83 | + return (long)written; |
90 | 84 | } |
| 85 | + throw new Win32Exception(Marshal.GetLastWin32Error()); |
| 86 | + }); |
91 | 87 |
|
92 | | - return writeTask.GetAwaiter().GetResult(); |
93 | | - } |
94 | | - |
95 | | - public override void Reset() |
| 88 | + if (!writeTask.Wait(IoTimeoutMs)) |
96 | 89 | { |
97 | | - // Legacy 驱动通常不支持软重置 |
| 90 | + throw new TimeoutException($"Legacy USB write timed out after {IoTimeoutMs} ms."); |
98 | 91 | } |
99 | 92 |
|
100 | | - public override void Dispose() |
| 93 | + return writeTask.GetAwaiter().GetResult(); |
| 94 | + } |
| 95 | + |
| 96 | + public override void Reset() |
| 97 | + { |
| 98 | + // Legacy 驱动通常不支持软重置 |
| 99 | + } |
| 100 | + |
| 101 | + public override void Dispose() |
| 102 | + { |
| 103 | + if (fileHandle != INVALID_HANDLE_VALUE) |
101 | 104 | { |
102 | | - if (fileHandle != INVALID_HANDLE_VALUE) |
103 | | - { |
104 | | - CloseHandle(fileHandle); |
105 | | - fileHandle = INVALID_HANDLE_VALUE; |
106 | | - } |
107 | | - GC.SuppressFinalize(this); |
| 105 | + CloseHandle(fileHandle); |
| 106 | + fileHandle = INVALID_HANDLE_VALUE; |
108 | 107 | } |
| 108 | + GC.SuppressFinalize(this); |
109 | 109 | } |
| 110 | +} |
110 | 111 |
|
111 | 112 |
|
112 | 113 |
|
0 commit comments