libxr  1.0
Want to be the best embedded framework
Loading...
Searching...
No Matches
winusb_msos20.hpp
1#pragma once
2#include <cstddef>
3#include <cstdint>
4#include <cstring>
5
6#include "libxr_mem.hpp"
7#include "libxr_type.hpp"
8#include "usb/core/bos.hpp"
9#include "usb/core/core.hpp"
10
11namespace LibXR::USB::WinUsbMsOs20
12{
13
14// ---- constants ----
15
16// wIndex values for vendor request
17static constexpr uint16_t MSOS20_DESCRIPTOR_INDEX = 0x0007;
18static constexpr uint16_t MSOS20_SET_ALT_ENUMERATION = 0x0008;
19
20// MS OS 2.0 descriptor types
21static constexpr uint16_t MS_OS_20_SET_HEADER_DESCRIPTOR = 0x0000;
22static constexpr uint16_t MS_OS_20_SUBSET_HEADER_CONFIGURATION = 0x0001;
23static constexpr uint16_t MS_OS_20_SUBSET_HEADER_FUNCTION = 0x0002;
24static constexpr uint16_t MS_OS_20_FEATURE_COMPATIBLE_ID = 0x0003;
25static constexpr uint16_t MS_OS_20_FEATURE_REG_PROPERTY = 0x0004;
26
27// Registry property data type
28static constexpr uint16_t REG_MULTI_SZ = 0x0007;
29
30// MS OS 2.0 platform capability UUID: D8DD60DF-4589-4CC7-9CD2-659D9E648A9F
31static constexpr uint8_t MSOS20_PLATFORM_CAPABILITY_UUID[16] = {
32 0xDF, 0x60, 0xDD, 0xD8, 0x89, 0x45, 0xC7, 0x4C,
33 0x9C, 0xD2, 0x65, 0x9D, 0x9E, 0x64, 0x8A, 0x9F,
34};
35
36// "{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}" + UTF-16 NUL
37static constexpr uint16_t GUID_CHARS_WITH_BRACES = 38;
38static constexpr uint16_t GUID_STR_UTF16_BYTES = (GUID_CHARS_WITH_BRACES + 1) * 2; // 78
39
40// "DeviceInterfaceGUIDs" (UTF-16LE) + NUL terminator
41static constexpr uint8_t PROP_NAME_DEVICE_INTERFACE_GUIDS_UTF16[] = {
42 'D', 0x00, 'e', 0x00, 'v', 0x00, 'i', 0x00, 'c', 0x00, 'e', 0x00, 'I', 0x00,
43 'n', 0x00, 't', 0x00, 'e', 0x00, 'r', 0x00, 'f', 0x00, 'a', 0x00, 'c', 0x00,
44 'e', 0x00, 'G', 0x00, 'U', 0x00, 'I', 0x00, 'D', 0x00, 's', 0x00, 0x00, 0x00};
45static constexpr uint16_t PROP_NAME_DEVICE_INTERFACE_GUIDS_BYTES =
46 static_cast<uint16_t>(sizeof(PROP_NAME_DEVICE_INTERFACE_GUIDS_UTF16));
47
48#pragma pack(push, 1)
49
50// ---- MS OS 2.0 basic blocks ----
51
52// 9.22.1 MS OS 2.0 descriptor set header
54{
55 uint16_t wLength = 0x000A;
56 uint16_t wDescriptorType = MS_OS_20_SET_HEADER_DESCRIPTOR;
57 uint32_t dwWindowsVersion = 0x06030000; // 0x06030000 = Win 8.1
58 uint16_t wTotalLength = 0; // sizeof(whole set)
59};
60
61// 9.22.2 Configuration subset header
63{
64 uint16_t wLength = 0x0008;
65 uint16_t wDescriptorType = MS_OS_20_SUBSET_HEADER_CONFIGURATION;
66 uint8_t bConfigurationValue = 0;
67 uint8_t bReserved = 0;
68 uint16_t wTotalLength = 0; // sizeof(this cfg subset)
69};
70
71// 9.22.3 Function subset header
73{
74 uint16_t wLength = 0x0008;
75 uint16_t wDescriptorType = MS_OS_20_SUBSET_HEADER_FUNCTION;
76 uint8_t bFirstInterface = 0;
77 uint8_t bReserved = 0;
78 uint16_t wTotalLength = 0; // sizeof(this function subset)
79};
80
81// 9.22.4 Compatible ID descriptor
83{
84 uint16_t wLength = 0x0014;
85 uint16_t wDescriptorType = MS_OS_20_FEATURE_COMPATIBLE_ID;
86
87 // "WINUSB" + padding NULs
88 uint8_t CompatibleID[8] = {'W', 'I', 'N', 'U', 'S', 'B', 0x00, 0x00};
89
90 // Optional; usually all zeros
91 uint8_t SubCompatibleID[8] = {0};
92};
93
94// 9.22.5 Registry property descriptor header (common part)
96{
97 uint16_t wLength = 0; // sizeof(whole reg property feature)
98 uint16_t wDescriptorType = MS_OS_20_FEATURE_REG_PROPERTY;
99 uint16_t wPropertyDataType = 0; // e.g. REG_MULTI_SZ
100 uint16_t wPropertyNameLength = 0;
101};
102
103// ---- MS OS 2.0 Platform Capability (BOS Device Capability) ----
104//
105// Exposed via BOS Platform Capability. Host can query the MS OS 2.0 descriptor
106// set using a vendor request with matching bMS_VendorCode and wIndex=0x0007.
108{
109 uint8_t bLength = 0x1C;
110 uint8_t bDescriptorType = 0x10; // DEVICE_CAPABILITY
111 uint8_t bDevCapabilityType = 0x05; // PLATFORM
112 uint8_t bReserved = 0x00;
113
114 uint8_t PlatformCapabilityUUID[16] = {
115 0xDF, 0x60, 0xDD, 0xD8, 0x89, 0x45, 0xC7, 0x4C,
116 0x9C, 0xD2, 0x65, 0x9D, 0x9E, 0x64, 0x8A, 0x9F,
117 };
118
119 uint32_t dwWindowsVersion = 0x06030000; // Win 8.1+
120 uint16_t wMSOSDescriptorSetTotalLength = 0; // sizeof(MS OS 2.0 set)
121 uint8_t bMS_VendorCode = 0x20; // vendor request bRequest
122 uint8_t bAltEnumCode = 0x00; // optional, often 0
123};
124
125#pragma pack(pop)
126
127// ---- sanity checks ----
128static_assert(sizeof(MsOs20SetHeader) == 10, "SetHeader size mismatch");
129static_assert(sizeof(MsOs20SubsetHeaderConfiguration) == 8, "CfgHeader size mismatch");
130static_assert(sizeof(MsOs20SubsetHeaderFunction) == 8, "FuncHeader size mismatch");
131static_assert(sizeof(MsOs20FeatureCompatibleId) == 20, "CompatibleId size mismatch");
132static_assert(sizeof(MsOs20PlatformCapability) == 28, "PlatformCapability size mismatch");
133
134// ---- helpers ----
135
136// Initialize MsOs20PlatformCapability with given descriptor-set length / vendor code /
137// version.
138inline void init_msos20_platform_capability(MsOs20PlatformCapability& cap,
139 uint16_t msos_descriptor_set_total_length,
140 uint8_t vendor_code = 0x20,
141 uint32_t windows_version = 0x06030000)
142{
144 Memory::FastCopy(cap.PlatformCapabilityUUID, MSOS20_PLATFORM_CAPABILITY_UUID,
145 sizeof(MSOS20_PLATFORM_CAPABILITY_UUID));
146 cap.dwWindowsVersion = windows_version;
147 cap.wMSOSDescriptorSetTotalLength = msos_descriptor_set_total_length;
148 cap.bMS_VendorCode = vendor_code;
149 cap.bAltEnumCode = 0x00;
150}
151
152// ---- BOS capability wrapper ----
153//
154// Purpose:
155// - Register a BOS Platform Capability (MS OS 2.0) to BosManager.
156// - Handle vendor requests:
157// - wIndex=0x0007 (IN): return MS OS 2.0 descriptor set.
158// - wIndex=0x0008 (OUT): Set Alt Enumeration (usually no data stage).
160{
161 public:
162 explicit MsOs20BosCapability(LibXR::ConstRawData descriptor_set,
163 uint8_t vendor_code = 0x20,
164 uint32_t windows_version = 0x06030000)
165 : descriptor_set_(descriptor_set),
166 vendor_code_(vendor_code),
167 windows_version_(windows_version)
168 {
169 RefreshPlatformCap();
170 }
171
172 void SetDescriptorSet(LibXR::ConstRawData descriptor_set)
173 {
174 descriptor_set_ = descriptor_set;
175 RefreshPlatformCap();
176 }
177
178 void SetVendorCode(uint8_t vendor_code)
179 {
180 vendor_code_ = vendor_code;
181 platform_cap_.bMS_VendorCode = vendor_code_;
182 }
183
185 {
186 return LibXR::ConstRawData(&platform_cap_, sizeof(platform_cap_));
187 }
188
189 ErrorCode OnVendorRequest(bool /*in_isr*/, const SetupPacket* setup,
190 LibXR::USB::BosVendorResult& result) override
191 {
192 if (setup == nullptr)
193 {
194 return ErrorCode::ARG_ERR;
195 }
196
197 const uint8_t BM = setup->bmRequestType;
198
199 // type must be Vendor (bits[6:5] == 10)
200 if ((BM & 0x60) != 0x40)
201 {
203 }
204
205 // recipient must be Device (bits[4:0] == 00000)
206 if ((BM & 0x1F) != 0x00)
207 {
209 }
210
211 // vendor code must match
212 if (setup->bRequest != vendor_code_)
213 {
215 }
216
217 // wIndex == 0x0007: MS OS 2.0 descriptor set (Vendor IN)
218 if (setup->wIndex == MSOS20_DESCRIPTOR_INDEX)
219 {
220 // direction must be IN
221 if ((BM & 0x80) == 0)
222 {
224 }
225
226 if (descriptor_set_.addr_ == nullptr || descriptor_set_.size_ == 0 ||
227 descriptor_set_.size_ > 0xFFFF)
228 {
229 return ErrorCode::ARG_ERR;
230 }
231
232 // Host wLength==0 is meaningless here; reject.
233 if (setup->wLength == 0)
234 {
236 }
237
238 result.handled = true;
239 result.in_data = descriptor_set_; // USB stack truncates by wLength
240 result.write_zlp = false;
241 result.early_read_zlp = true;
242 return ErrorCode::OK;
243 }
244
245 // wIndex == 0x0008: Set Alt Enumeration (Vendor OUT, usually wLength==0)
246 if (setup->wIndex == MSOS20_SET_ALT_ENUMERATION)
247 {
248 // direction should be OUT
249 if ((BM & 0x80) != 0)
250 {
251 // Strict behavior: reject IN.
253 }
254
255 // Usually no data stage. If wLength != 0, we still ACK to keep flow smooth.
256 if (setup->wLength != 0)
257 {
258 // no-op
259 }
260
261 result.handled = true;
262 result.in_data = {nullptr, 0};
263 result.write_zlp = true; // complete status stage
264 result.early_read_zlp = true;
265 return ErrorCode::OK;
266 }
267
269 }
270
271 private:
272 void RefreshPlatformCap()
273 {
274 // Keep Platform Capability synchronized with descriptor set length / vendor code.
275 platform_cap_ = MsOs20PlatformCapability{};
276 Memory::FastCopy(platform_cap_.PlatformCapabilityUUID,
277 MSOS20_PLATFORM_CAPABILITY_UUID,
278 sizeof(MSOS20_PLATFORM_CAPABILITY_UUID));
279 platform_cap_.dwWindowsVersion = windows_version_;
280 platform_cap_.bMS_VendorCode = vendor_code_;
281 platform_cap_.bAltEnumCode = 0x00;
282
283 if (descriptor_set_.size_ <= 0xFFFF)
284 {
285 platform_cap_.wMSOSDescriptorSetTotalLength =
286 static_cast<uint16_t>(descriptor_set_.size_);
287 }
288 else
289 {
290 platform_cap_.wMSOSDescriptorSetTotalLength = 0;
291 }
292 }
293
294 // Cached MS OS 2.0 descriptor set bytes.
295 LibXR::ConstRawData descriptor_set_{nullptr, 0};
296
297 // Vendor request bRequest code used for MS OS 2.0 query.
298 uint8_t vendor_code_ = 0x20;
299
300 // Windows version field in Platform Capability.
301 uint32_t windows_version_ = 0x06030000;
302
303 // BOS Platform Capability descriptor block.
304 MsOs20PlatformCapability platform_cap_{};
305};
306
307} // namespace LibXR::USB::WinUsbMsOs20
常量原始数据封装类。 A class for encapsulating constant raw data.
size_t size_
数据大小(字节)。 The size of the data (in bytes).
const void * addr_
数据存储地址(常量)。 The storage address of the data (constant).
static void FastCopy(void *dst, const void *src, size_t size)
快速内存拷贝 / Fast memory copy
Definition libxr_mem.cpp:5
BOS 能力接口 / BOS capability interface.
Definition bos.hpp:57
ErrorCode OnVendorRequest(bool, const SetupPacket *setup, LibXR::USB::BosVendorResult &result) override
处理该能力相关 Vendor 请求 / Handle vendor request for this capability
LibXR::ConstRawData GetCapabilityDescriptor() const override
返回能力块(不含 BOS 头) Return capability block (without BOS header).
ErrorCode
定义错误码枚举
@ NOT_SUPPORT
不支持 | Not supported
@ OK
操作成功 | Operation successful
@ ARG_ERR
参数错误 | Argument error
Vendor 请求处理结果(EP0 控制传输) Vendor request handling result for EP0 control transfers.
Definition bos.hpp:45
bool handled
已处理该请求 / Request consumed by capability
Definition bos.hpp:46
ConstRawData in_data
IN 数据阶段返回数据 / IN data stage payload.
Definition bos.hpp:47
bool write_zlp
状态阶段发送 ZLP / Send ZLP at status stage
Definition bos.hpp:48
bool early_read_zlp
提前准备 OUT 以适配主机短读 / Arm OUT early for short-read tolerance
Definition bos.hpp:49
USB 标准请求 SETUP 包(固定8字节) Standard USB setup packet (8 bytes)
Definition core.hpp:57
uint16_t wIndex
对象索引,如接口号或端点号 / Index (e.g., interface or endpoint)
Definition core.hpp:63
uint16_t wLength
数据阶段长度 / Number of bytes in data stage
Definition core.hpp:64
uint8_t bRequest
请求码 / Request code (e.g., GET_DESCRIPTOR)
Definition core.hpp:60