Files
DP44/enriched-partialglm/Common/DTS.Common.IConnection/USBConnection/USBFramework.md

217 lines
13 KiB
Markdown
Raw Normal View History

2026-04-17 14:55:32 -04:00
---
source_files:
- Common/DTS.Common.IConnection/USBConnection/USBFramework/FileIODeclarations.cs
- Common/DTS.Common.IConnection/USBConnection/USBFramework/HIDDeclarations.cs
- Common/DTS.Common.IConnection/USBConnection/USBFramework/DeviceManagementDeclarations.cs
- Common/DTS.Common.IConnection/USBConnection/USBFramework/DeviceManagement.cs
generated_at: "2026-04-16T11:51:16.904126+00:00"
model: "zai-org/GLM-5-FP8"
schema_version: 1
sha256: "8939bee008e13a9a"
---
# USB Framework Module Documentation
## 1. Purpose
This module provides a .NET wrapper around Windows Win32 APIs for USB device communication and management. It enables applications to discover, monitor, and interact with HID-class USB devices through P/Invoke declarations for `kernel32.dll`, `hid.dll`, `setupapi.dll`, `user32.dll`, and `advapi32.dll`. The module handles device enumeration by GUID, device arrival/removal notifications, and low-level file I/O operations required for USB device communication.
---
## 2. Public Interface
### FileIODeclarations Class
**Namespace:** `DTS.Common.USBFramework`
A container for Win32 file I/O P/Invoke declarations.
**Constants:**
- `GENERIC_READ` (uint): `0x80000000`
- `GENERIC_WRITE` (uint): `0x40000000`
- `FILE_SHARE_READ` (uint): `0x00000001`
- `FILE_SHARE_WRITE` (uint): `0x00000002`
- `FILE_FLAG_OVERLAPPED` (uint): `0x40000000`
- `INVALID_HANDLE_VALUE` (int): `-1`
- `OPEN_EXISTING` (short): `3`
- `WAIT_TIMEOUT` (int): `0x102`
- `WAIT_OBJECT_0` (uint): `0`
- `WAIT_FAILED` (uint): `0xFFFFFFFF`
- `WAIT_ABANDONED` (uint): `0x00000080`
- `FSCTL_SET_COMPRESSION` (int): `0x9C040`
**Structures:**
- `OVERLAPPED` - Sequential layout structure with fields: `Internal`, `InternalHigh`, `Offset`, `OffsetHigh`, `hEvent` (all int)
- `SECURITY_ATTRIBUTES` - Sequential layout structure with fields: `nLength`, `lpSecurityDescriptor`, `bInheritHandle` (all int)
**Static Methods (DllImport kernel32.dll):**
- `int CancelIo(int hFile)`
- `int CloseHandle(int hObject)`
- `int CreateEvent(ref SECURITY_ATTRIBUTES SecurityAttributes, int bManualReset, int bInitialState, string lpName)`
- `int CreateFile(string lpFileName, uint dwDesiredAccess, uint dwShareMode, ref SECURITY_ATTRIBUTES lpSecurityAttributes, int dwCreationDisposition, uint dwFlagsAndAttributes, int hTemplateFile)`
- `int GetLastError()`
- `int ReadFile(int hFile, ref byte lpBuffer, int nNumberOfBytesToRead, ref int lpNumberOfBytesRead, int lpOverlapped)`
- `uint WaitForSingleObject(int hHandle, int dwMilliseconds)`
- `int WriteFile(int hFile, ref byte lpBuffer, int nNumberOfBytesToWrite, ref int lpNumberOfBytesWritten, int lpOverlapped)`
- `int DeviceIoControl(IntPtr hDevice, int dwIoControlCode, ref short lpInBuffer, int nInBufferSize, IntPtr lpOutBuffer, int nOutBufferSize, ref int lpBytesReturned, IntPtr lpOverlapped)`
---
### FileIO Class
**Namespace:** `DTS.Common.USBFramework`
Alternative file I/O declarations using `SafeFileHandle`.
**Constants:**
- `FILE_ATTRIBUTE_NORMAL` (short): `0x80`
- `FILE_FLAG_OVERLAPPED` (int): `0x40000000`
- `FILE_SHARE_READ` (short): `0x1`
- `FILE_SHARE_WRITE` (short): `0x2`
- `GENERIC_READ` (uint): `0x80000000`
- `GENERIC_WRITE` (uint): `0x40000000`
- `INVALID_HANDLE_VALUE` (int): `-1`
- `OPEN_EXISTING` (short): `3`
**Structure:**
- `SECURITY_ATTRIBUTES` - Sequential layout with `nLength` (int), `lpSecurityDescriptor` (IntPtr), `bInheritHandle` (int)
**Static Methods (DllImport kernel32.dll):**
- `bool CloseHandle(SafeFileHandle hObject)`
- `SafeFileHandle CreateFile(string lpFileName, uint dwDesiredAccess, int dwShareMode, ref SECURITY_ATTRIBUTES lpSecurityAttributes, int dwCreationDisposition, int dwFlagsAndAttributes, int hTemplateFile)`
---
### HIDDeclarations Class
**Namespace:** `DTS.DASLib.Connection.USBFramework` (Note: different namespace)
A container for HID device P/Invoke declarations.
**Constants:**
- `HidP_Input` (short): `0`
- `HidP_Output` (short): `1`
- `HidP_Feature` (short): `2`
**Structures:**
- `HIDD_ATTRIBUTES` - Fields: `Size` (int), `VendorID` (short), `ProductID` (short), `VersionNumber` (short)
- `HIDP_CAPS` - Fields: `Usage`, `UsagePage`, `InputReportByteLength`, `OutputReportByteLength`, `FeatureReportByteLength`, `Reserved[17]`, `NumberLinkCollectionNodes`, `NumberInputButtonCaps`, `NumberInputValueCaps`, `NumberInputDataIndices`, `NumberOutputButtonCaps`, `NumberOutputValueCaps`, `NumberOutputDataIndices`, `NumberFeatureButtonCaps`, `NumberFeatureValueCaps`, `NumberFeatureDataIndices`
- `HidP_Value_Caps` - Extensive structure with fields for usage page, report ID, bit field, link collection, logical/physical min/max, usage min/max, string min/max, designator min/max, data index min/max, and multiple reserved fields
**Static Methods (DllImport hid.dll):**
- `bool HidD_FlushQueue(int HidDeviceObject)`
- `bool HidD_FreePreparsedData(ref IntPtr PreparsedData)`
- `int HidD_GetAttributes(int HidDeviceObject, ref HIDD_ATTRIBUTES Attributes)`
- `bool HidD_GetFeature(int HidDeviceObject, ref byte lpReportBuffer, int ReportBufferLength)`
- `bool HidD_GetInputReport(int HidDeviceObject, ref byte lpReportBuffer, int ReportBufferLength)`
- `void HidD_GetHidGuid(ref System.Guid HidGuid)`
- `bool HidD_GetNumInputBuffers(int HidDeviceObject, ref int NumberBuffers)`
- `bool HidD_GetPreparsedData(int HidDeviceObject, ref IntPtr PreparsedData)`
- `bool HidD_SetFeature(int HidDeviceObject, ref byte lpReportBuffer, int ReportBufferLength)`
- `bool HidD_SetNumInputBuffers(int HidDeviceObject, int NumberBuffers)`
- `bool HidD_SetOutputReport(int HidDeviceObject, ref byte lpReportBuffer, int ReportBufferLength)`
- `int HidP_GetCaps(IntPtr PreparsedData, ref HIDP_CAPS Capabilities)`
- `int HidP_GetValueCaps(short ReportType, ref byte ValueCaps, ref short ValueCapsLength, IntPtr PreparsedData)`
---
### DeviceManagementDeclarations Class
**Namespace:** `DTS.Common.USBFramework`
A container for device management P/Invoke declarations.
**Constants:**
- Device event constants: `DBT_DEVICEARRIVAL` (`0x8000`), `DBT_DEVICEREMOVECOMPLETE` (`0x8004`), `DBT_DEVTYP_DEVICEINTERFACE` (`5`), `DBT_DEVTYP_HANDLE` (`6`)
- Notification constants: `DEVICE_NOTIFY_ALL_INTERFACE_CLASSES` (`4`), `DEVICE_NOTIFY_SERVICE_HANDLE` (`1`), `DEVICE_NOTIFY_WINDOW_HANDLE` (`0`), `WM_DEVICECHANGE` (`0x219`)
- Error constants: `ERROR_INSUFFICIENT_BUFFER` (`122`), `NO_ERROR` (`0`), `ERROR_NO_MORE_ITEMS` (`259`)
- SetupAPI flags: `DIGCF_PRESENT` (`0x00000002`), `DIGCF_DEVICEINTERFACE` (`0x00000010`), `DIGCF_ALLCLASSES` (`0x00000004`)
- Registry property constants: `SPDRP_FRIENDLYNAME`, `SPDRP_DEVICEDESC`, `SPDRP_DRIVER`
**Structures:**
- `DEV_BROADCAST_DEVICEINTERFACE` - Fields: `dbcc_size`, `dbcc_devicetype`, `dbcc_reserved`, `dbcc_classguid` (Guid), `dbcc_name` (string, SizeConst=400)
- `DEV_BROADCAST_DEVICEINTERFACE_1` - Class variant with `dbcc_classguid` as byte[16] and `dbcc_name` as char[255]
- `DEV_BROADCAST_HANDLE` - Fields: `dbch_size`, `dbch_devicetype`, `dbch_reserved`, `dbch_handle`, `dbch_hdevnotify`
- `DEV_BROADCAST_HDR` - Fields: `dbch_size`, `dbch_devicetype`, `dbch_reserved`
- `SP_DEVICE_INTERFACE_DATA` - Fields: `cbSize`, `InterfaceClassGuid` (Guid), `Flags`, `Reserved` (IntPtr)
- `SP_DEVICE_INTERFACE_DETAIL_DATA` - Fields: `cbSize`, `DevicePath` (string)
- `SP_DEVINFO_DATA` - Fields: `cbSize`, `ClassGuid` (Guid), `DevInst`, `Reserved`
**Enum:**
- `RegSAM` - Flags enum with values: `QueryValue`, `SetValue`, `CreateSubKey`, `EnumerateSubKeys`, `Notify`, `CreateLink`, `WOW64_32Key`, `WOW64_64Key`, `WOW64_Res`, `Read`, `Write`, `Execute`, `AllAccess`
**Static Methods:**
- `IntPtr RegisterDeviceNotification(IntPtr hRecipient, IntPtr NotificationFilter, int Flags)` - user32.dll
- `int SetupDiCreateDeviceInfoList(ref System.Guid ClassGuid, int hwndParent)` - setupapi.dll
- `int SetupDiDestroyDeviceInfoList(IntPtr DeviceInfoSet)` - setupapi.dll
- `int SetupDiEnumDeviceInterfaces(IntPtr DeviceInfoSet, IntPtr DeviceInfoData, ref System.Guid InterfaceClassGuid, int MemberIndex, ref SP_DEVICE_INTERFACE_DATA DeviceInterfaceData)` - setupapi.dll
- `IntPtr SetupDiGetClassDevs(ref System.Guid ClassGuid, string Enumerator, int hwndParent, uint Flags)` - setupapi.dll
- `bool SetupDiGetDeviceInterfaceDetail(IntPtr DeviceInfoSet, ref SP_DEVICE_INTERFACE_DATA DeviceInterfaceData, IntPtr DeviceInterfaceDetailData, int DeviceInterfaceDetailDataSize, ref int RequiredSize, IntPtr DeviceInfoData)` - setupapi.dll
- `bool SetupDiEnumDeviceInfo(IntPtr DeviceInfoSet, uint MemberIndex, out SP_DEVINFO_DATA DeviceInfoData)` - setupapi.dll
- `IntPtr SetupDiGetClassDevsA(ref Guid ClassGuid, uint Enumerator, IntPtr hwndParent, uint Flags)` - setupapi.dll
- `bool SetupDiGetDeviceRegistryPropertyA(IntPtr DeviceInfoSet, SP_DEVINFO_DATA DeviceInfoData, uint Property, uint PropertyRegDataType, StringBuilder PropertyBuffer, uint PropertyBufferSize, IntPtr RequiredSize)` - setupapi.dll
- `int SetupDiOpenDevRegKey(IntPtr DeviceInfoSet, ref SP_DEVINFO_DATA DeviceInfoData, uint Scope, uint HwProfile, uint KeyType, RegSAM samDesired)` - setupapi.dll
- `uint RegQueryValueEx(int hKey, string lpValueName, uint lpReserved, out uint lpType, ref byte[] lpData, ref uint lpcbData)` - Advapi32.dll
- `bool UnregisterDeviceNotification(IntPtr Handle)` - user32.dll
- `int GetLastError()` - kernel32.dll
---
### DeviceManagement Class
**Namespace:** `DTS.Common.USBFramework`
Implements `IDisposable`. Provides high-level device management operations.
**Public Methods:**
- `void Dispose()` - Empty implementation; does not release resources.
- `bool DeviceNameMatch(Message m, string mydevicePathName)` - Compares the device path name from a `WM_DEVICECHANGE` message against a specified device path name. Returns `true` if names match (case-insensitive), `false` otherwise. Only processes messages where `dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE`.
- `bool FindDeviceFromGuid(System.Guid myGuid, ref string[] devicePathName)` - Enumerates all present devices matching the specified interface class GUID. Populates `devicePathName` array with device path names. Returns `true` if at least one device is found. Caller must pre-allocate the `devicePathName` array with sufficient size.
- `bool RegisterForDeviceNotifications(IntPtr formHandle, Guid classGuid, ref IntPtr deviceNotificationHandle)` - Registers a window to receive device arrival/removal notifications for a specific device interface class. Returns `true` on success. The `deviceNotificationHandle` is set to the registration handle on success.
- `void StopReceivingDeviceNotifications(IntPtr deviceNotificationHandle)` - Unregisters device notifications. Failures are silently ignored.
- `bool GetDeviceRegistryProperty(Guid myGuid)` - Enumerates devices and logs driver names via `APILogger.Log()`. Returns `true` on success, `false` on error or if no matching device found.
**Static Fields:**
- `IS64_BIT_PROCESS` (bool, readonly) - Computed as `(IntPtr.Size == 8)`
---
## 3. Invariants
- **Handle Validity:** All Win32 handles (`int` or `IntPtr` types) must be valid when passed to API functions. `INVALID_HANDLE_VALUE` (-1) indicates failure from `CreateFile` operations.
- **Structure Size Initialization:** Structures with `cbSize` fields (`SP_DEVICE_INTERFACE_DATA`, `SP_DEVICE_INTERFACE_DETAIL_DATA`, `SP_DEVINFO_DATA`) must have `cbSize` set to `Marshal.SizeOf()` before passing to API functions.
- **Memory Management:** Memory allocated via `Marshal.AllocHGlobal()` must be freed via `Marshal.FreeHGlobal()`. The `FindDeviceFromGuid` method allocates and frees `detailDataBuffer` within its scope.
- **Device Path Array Pre-allocation:** `FindDeviceFromGuid` requires the caller to pre-allocate the `devicePathName` string array; the method does not resize it.
- **32/64-bit Compatibility:** The code conditionally handles pointer arithmetic based on `IS64_BIT_PROCESS` for correct memory offset calculations.
- **Namespace Inconsistency:** `HIDDeclarations` resides in `DTS.DASLib.Connection.USBFramework` while all other classes are in `DTS.Common.USBFramework`.
---
## 4. Dependencies
**External Dependencies (DLL Imports):**
- `kernel32.dll` - File I/O, handles, synchronization
- `hid.dll` - HID device communication
- `setupapi.dll` - Device enumeration and management
- `user32.dll` - Device notification registration
- `Advapi32.dll` - Registry operations
**Internal Dependencies:**
- `Microsoft.Win32.SafeHandles` - Used by `FileIO` class for `SafeFileHandle`
- `System.Runtime.InteropServices` - P/Invoke and marshaling
- `System.Windows.Forms` - `Message` struct used in `DeviceNameMatch`
- `DTS.Common.Utilities.Logging` - `APILogger` used in `DeviceManagement.GetDeviceRegistryProperty`
**Consumers:**
- Not determinable from source alone; this module appears to be a low-level infrastructure layer for USB communication.
---
## 5. Gotchas
1. **Empty Dispose Implementation:** `DeviceManagement.Dispose()` is empty and does not release the `deviceNotificationHandle` or clean up any resources. Callers must explicitly call `StopReceivingDeviceNotifications()` before disposal.
2. **Namespace Mismatch:** `HIDDeclarations` is in `DTS.DASLib.Connection.USBFramework` namespace, while all other classes are in `DTS.Common.USBFramework`. This may cause compilation issues or require multiple using directives.
3. **Duplicate Constants:** `FileIODeclarations` and `FileIO` both define identical constants (`GENERIC_READ`, `GENERIC_WRITE`, `FILE_SHARE_READ`, `FILE_SHARE_WRITE`, `FILE_FLAG_OVERLAPPED`, `INVALID_HANDLE_VALUE`, `OPEN_EXISTING`) with slightly different