217 lines
13 KiB
Markdown
217 lines
13 KiB
Markdown
|
|
---
|
||
|
|
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
|