6#include "libxr_mem.hpp"
7#include "libxr_type.hpp"
8#include "usb/core/bos.hpp"
9#include "usb/core/core.hpp"
11namespace LibXR::USB::WinUsbMsOs20
17static constexpr uint16_t MSOS20_DESCRIPTOR_INDEX = 0x0007;
18static constexpr uint16_t MSOS20_SET_ALT_ENUMERATION = 0x0008;
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;
28static constexpr uint16_t REG_MULTI_SZ = 0x0007;
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,
37static constexpr uint16_t GUID_CHARS_WITH_BRACES = 38;
38static constexpr uint16_t GUID_STR_UTF16_BYTES = (GUID_CHARS_WITH_BRACES + 1) * 2;
39static constexpr uint16_t GUID_MULTI_SZ_UTF16_BYTES =
40 static_cast<uint16_t
>(GUID_STR_UTF16_BYTES + 2u);
43static constexpr uint8_t PROP_NAME_DEVICE_INTERFACE_GUIDS_UTF16[] = {
44 'D', 0x00,
'e', 0x00,
'v', 0x00,
'i', 0x00,
'c', 0x00,
'e', 0x00,
'I', 0x00,
45 'n', 0x00,
't', 0x00,
'e', 0x00,
'r', 0x00,
'f', 0x00,
'a', 0x00,
'c', 0x00,
46 'e', 0x00,
'G', 0x00,
'U', 0x00,
'I', 0x00,
'D', 0x00,
's', 0x00, 0x00, 0x00};
47static constexpr uint16_t PROP_NAME_DEVICE_INTERFACE_GUIDS_BYTES =
48 static_cast<uint16_t
>(
sizeof(PROP_NAME_DEVICE_INTERFACE_GUIDS_UTF16));
57 uint16_t wLength = 0x000A;
58 uint16_t wDescriptorType = MS_OS_20_SET_HEADER_DESCRIPTOR;
59 uint32_t dwWindowsVersion = 0x06030000;
60 uint16_t wTotalLength = 0;
66 uint16_t wLength = 0x0008;
67 uint16_t wDescriptorType = MS_OS_20_SUBSET_HEADER_CONFIGURATION;
70 uint8_t bConfigurationValue = 0;
71 uint8_t bReserved = 0;
72 uint16_t wTotalLength = 0;
78 uint16_t wLength = 0x0008;
79 uint16_t wDescriptorType = MS_OS_20_SUBSET_HEADER_FUNCTION;
80 uint8_t bFirstInterface = 0;
81 uint8_t bReserved = 0;
82 uint16_t wTotalLength = 0;
88 uint16_t wLength = 0x0014;
89 uint16_t wDescriptorType = MS_OS_20_FEATURE_COMPATIBLE_ID;
92 uint8_t CompatibleID[8] = {
'W',
'I',
'N',
'U',
'S',
'B', 0x00, 0x00};
95 uint8_t SubCompatibleID[8] = {0};
101 uint16_t wLength = 0;
102 uint16_t wDescriptorType = MS_OS_20_FEATURE_REG_PROPERTY;
103 uint16_t wPropertyDataType = 0;
104 uint16_t wPropertyNameLength = 0;
113 uint8_t bLength = 0x1C;
114 uint8_t bDescriptorType = 0x10;
115 uint8_t bDevCapabilityType = 0x05;
116 uint8_t bReserved = 0x00;
118 uint8_t PlatformCapabilityUUID[16] = {
119 0xDF, 0x60, 0xDD, 0xD8, 0x89, 0x45, 0xC7, 0x4C,
120 0x9C, 0xD2, 0x65, 0x9D, 0x9E, 0x64, 0x8A, 0x9F,
123 uint32_t dwWindowsVersion = 0x06030000;
124 uint16_t wMSOSDescriptorSetTotalLength = 0;
125 uint8_t bMS_VendorCode = 0x20;
126 uint8_t bAltEnumCode = 0x00;
129template <u
int16_t PropertyDataBytes>
132 static_assert(PropertyDataBytes >= 4u,
133 "REG_MULTI_SZ property data must fit the double-NUL terminator");
136 uint8_t name[PROP_NAME_DEVICE_INTERFACE_GUIDS_BYTES];
137 uint16_t wPropertyDataLength = 0;
138 uint8_t data[PropertyDataBytes] = {};
140 void Init(
const char* guid)
143 header.wDescriptorType = MS_OS_20_FEATURE_REG_PROPERTY;
144 header.wPropertyDataType = REG_MULTI_SZ;
145 header.wPropertyNameLength = PROP_NAME_DEVICE_INTERFACE_GUIDS_BYTES;
147 PROP_NAME_DEVICE_INTERFACE_GUIDS_BYTES);
149 const size_t max_guid_chars =
150 (PropertyDataBytes >= 4u) ? ((PropertyDataBytes - 4u) / 2u) : 0u;
151 size_t guid_len = 0u;
154 while (guid[guid_len] !=
'\0' && guid_len < GUID_CHARS_WITH_BRACES &&
155 guid_len < max_guid_chars)
157 data[guid_len * 2u] =
static_cast<uint8_t
>(guid[guid_len]);
158 data[guid_len * 2u + 1u] = 0x00u;
163 if (PropertyDataBytes >= 4u)
165 data[guid_len * 2u] = 0x00u;
166 data[guid_len * 2u + 1u] = 0x00u;
167 data[guid_len * 2u + 2u] = 0x00u;
168 data[guid_len * 2u + 3u] = 0x00u;
171 wPropertyDataLength =
static_cast<uint16_t
>((guid_len * 2u) + 4u);
172 header.wLength =
static_cast<uint16_t
>(
sizeof(*this));
176template <u
int16_t PropertyDataBytes>
183 void Init(
const char* guid, uint32_t windows_version = 0x06030000)
188 set.wDescriptorType = MS_OS_20_SET_HEADER_DESCRIPTOR;
189 set.dwWindowsVersion = windows_version;
190 set.wTotalLength =
static_cast<uint16_t
>(
sizeof(*this));
193 compat.wDescriptorType = MS_OS_20_FEATURE_COMPATIBLE_ID;
199template <u
int16_t PropertyDataBytes>
208 void Init(uint8_t configuration_index, uint8_t first_interface,
const char* guid,
209 uint32_t windows_version = 0x06030000)
214 set.wDescriptorType = MS_OS_20_SET_HEADER_DESCRIPTOR;
215 set.dwWindowsVersion = windows_version;
216 set.wTotalLength =
static_cast<uint16_t
>(
sizeof(*this));
218 cfg.wLength =
static_cast<uint16_t
>(
sizeof(cfg));
219 cfg.wDescriptorType = MS_OS_20_SUBSET_HEADER_CONFIGURATION;
220 cfg.bConfigurationValue = configuration_index;
222 cfg.wTotalLength =
static_cast<uint16_t
>(
226 func.wLength =
static_cast<uint16_t
>(
sizeof(func));
227 func.wDescriptorType = MS_OS_20_SUBSET_HEADER_FUNCTION;
228 func.bFirstInterface = first_interface;
230 func.wTotalLength =
static_cast<uint16_t
>(
235 compat.wDescriptorType = MS_OS_20_FEATURE_COMPATIBLE_ID;
240 void SetFirstInterface(uint8_t first_interface)
242 func.bFirstInterface = first_interface;
249static_assert(
sizeof(
MsOs20SetHeader) == 10,
"SetHeader size mismatch");
256 "Device-scoped WinUSB MS OS 2.0 set size mismatch");
259 "Function-scoped WinUSB MS OS 2.0 set size mismatch");
264 uint16_t msos_descriptor_set_total_length,
265 uint8_t vendor_code = 0x20,
266 uint32_t windows_version = 0x06030000)
269 Memory::FastCopy(cap.PlatformCapabilityUUID, MSOS20_PLATFORM_CAPABILITY_UUID,
270 sizeof(MSOS20_PLATFORM_CAPABILITY_UUID));
271 cap.dwWindowsVersion = windows_version;
272 cap.wMSOSDescriptorSetTotalLength = msos_descriptor_set_total_length;
273 cap.bMS_VendorCode = vendor_code;
274 cap.bAltEnumCode = 0x00;
288 uint8_t vendor_code = 0x20,
289 uint32_t windows_version = 0x06030000)
290 : descriptor_set_(descriptor_set),
291 vendor_code_(vendor_code),
292 windows_version_(windows_version)
294 RefreshPlatformCap();
299 descriptor_set_ = descriptor_set;
300 RefreshPlatformCap();
303 void SetVendorCode(uint8_t vendor_code)
305 vendor_code_ = vendor_code;
306 platform_cap_.bMS_VendorCode = vendor_code_;
317 if (setup ==
nullptr)
325 if ((BM & 0x60) != 0x40)
331 if ((BM & 0x1F) != 0x00)
337 if (setup->
bRequest != vendor_code_)
343 if (setup->
wIndex == MSOS20_DESCRIPTOR_INDEX)
346 if ((BM & 0x80) == 0)
351 if (descriptor_set_.
addr_ ==
nullptr || descriptor_set_.
size_ == 0 ||
352 descriptor_set_.
size_ > 0xFFFF)
364 result.
in_data = descriptor_set_;
371 if (setup->
wIndex == MSOS20_SET_ALT_ENUMERATION)
374 if ((BM & 0x80) != 0)
397 void RefreshPlatformCap()
399 const uint16_t total_length = (descriptor_set_.
size_ <= 0xFFFF)
400 ?
static_cast<uint16_t
>(descriptor_set_.
size_)
402 init_msos20_platform_capability(platform_cap_, total_length, vendor_code_,
410 uint8_t vendor_code_ = 0x20;
413 uint32_t windows_version_ = 0x06030000;
416 MsOs20PlatformCapability platform_cap_{};
只读原始数据视图 / Immutable raw data view
size_t size_
数据字节数 / Data size in bytes
const void * addr_
数据起始地址 / Data start address
static void FastCopy(void *dst, const void *src, size_t size)
快速内存拷贝 / Fast memory copy
BOS 能力接口 / BOS capability interface.
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).
@ NOT_SUPPORT
不支持 | Not supported
@ OK
操作成功 | Operation successful
@ ARG_ERR
参数错误 | Argument error
Vendor 请求处理结果(EP0 控制传输) Vendor request handling result for EP0 control transfers.
bool handled
已处理该请求 / Request consumed by capability
ConstRawData in_data
IN 数据阶段返回数据 / IN data stage payload.
bool write_zlp
状态阶段发送 ZLP / Send ZLP at status stage
bool early_read_zlp
提前准备 OUT 以适配主机短读 / Arm OUT early for short-read tolerance
USB 标准请求 SETUP 包(固定8字节) Standard USB setup packet (8 bytes)
uint16_t wIndex
对象索引,如接口号或端点号 / Index (e.g., interface or endpoint)
uint16_t wLength
数据阶段长度 / Number of bytes in data stage
uint8_t bRequest
请求码 / Request code (e.g., GET_DESCRIPTOR)