13 KiB
13 KiB
source_files, generated_at, model, schema_version, sha256
| source_files | generated_at | model | schema_version | sha256 | ||||
|---|---|---|---|---|---|---|---|---|
|
2026-04-16T02:09:55.521694+00:00 | Qwen/Qwen3-Coder-Next-FP8 | 1 | 8939bee008e13a9a |
Documentation: USBFramework Module
1. Purpose
This module provides low-level Windows API interop declarations and high-level device management utilities for USB device communication, specifically targeting HID-class devices and generic file I/O operations. It serves as the foundational layer for USB device enumeration, notification handling, and raw communication in the DTS system. The module exposes P/Invoke signatures for Windows kernel32.dll, hid.dll, setupapi.dll, and advapi32.dll functions, alongside managed wrappers (e.g., DeviceManagement) that abstract device discovery, registration for plug-and-play events, and property retrieval. Its role is to enable reliable detection, connection, and interaction with USB devices without relying on higher-level .NET USB libraries.
2. Public Interface
FileIODeclarations class (namespace DTS.Common.USBFramework)
const uint GENERIC_READ = 0x80000000
Access mask for read operations inCreateFile.const uint GENERIC_WRITE = 0x40000000
Access mask for write operations inCreateFile.const uint FILE_SHARE_READ = 0x00000001
Share mode flag for read sharing.const uint FILE_SHARE_WRITE = 0x00000002
Share mode flag for write sharing.const uint FILE_FLAG_OVERLAPPED = 0x40000000
Flag for asynchronous I/O inCreateFile.const int INVALID_HANDLE_VALUE = -1
Sentinel value for invalid handle.const short OPEN_EXISTING = 3
Creation disposition for opening existing files/devices.const int WAIT_TIMEOUT = 0x102,WAIT_OBJECT_0 = 0,WAIT_FAILED = 0xFFFFFFFF,WAIT_ABANDONED = 0x00000080
Return codes forWaitForSingleObject.const int FSCTL_SET_COMPRESSION = 0x9C040
I/O control code for compression (unused in current context).struct OVERLAPPED
Unmanaged structure for asynchronous I/O (note:hEventisint, notIntPtr).struct SECURITY_ATTRIBUTES
Unmanaged structure for security descriptor handling (note:lpSecurityDescriptorisint, notIntPtr).int CancelIo(int hFile)
Cancels pending I/O operations on the specified file handle.int CloseHandle(int hObject)
Closes an open object handle.int CreateEvent(ref SECURITY_ATTRIBUTES SecurityAttributes, int bManualReset, int bInitialState, string lpName)
Creates or opens a named or unnamed event object.int CreateFile(string lpFileName, uint dwDesiredAccess, uint dwShareMode, ref SECURITY_ATTRIBUTES lpSecurityAttributes, int dwCreationDisposition, uint dwFlagsAndAttributes, int hTemplateFile)
Creates or opens a file or I/O device (e.g., USB device).int GetLastError()
Retrieves the calling thread’s last-error code.int ReadFile(int hFile, ref byte lpBuffer, int nNumberOfBytesToRead, ref int lpNumberOfBytesRead, int lpOverlapped)
Reads from a file or device (note:lpOverlappedisint, notref OVERLAPPED).uint WaitForSingleObject(int hHandle, int dwMilliseconds)
Waits until the specified object is in the signaled state or the time-out interval elapses.int WriteFile(int hFile, ref byte lpBuffer, int nNumberOfBytesToWrite, ref int lpNumberOfBytesWritten, int lpOverlapped)
Writes to a file or device.int DeviceIoControl(IntPtr hDevice, int dwIoControlCode, ref short lpInBuffer, int nInBufferSize, IntPtr lpOutBuffer, int nOutBufferSize, ref int lpBytesReturned, IntPtr lpOverlapped)
Sends a control code directly to a device driver.
FileIO class (namespace DTS.Common.USBFramework)
const short FILE_ATTRIBUTE_NORMAL = 0x80,FILE_FLAG_OVERLAPPED = 0x40000000, etc.
Duplicate constants (with different types) fromFileIODeclarations.struct SECURITY_ATTRIBUTES
Alternate definition withlpSecurityDescriptorasIntPtr(inconsistent withFileIODeclarations).bool CloseHandle(SafeFileHandle hObject)
Managed wrapper for closing aSafeFileHandle.SafeFileHandle CreateFile(string lpFileName, uint dwDesiredAccess, int dwShareMode, ref SECURITY_ATTRIBUTES lpSecurityAttributes, int dwCreationDisposition, int dwFlagsAndAttributes, int hTemplateFile)
Managed wrapper returningSafeFileHandle.
HIDDeclarations class (namespace DTS.DASLib.Connection.USBFramework)
const short HidP_Input = 0,HidP_Output = 1,HidP_Feature = 2
Report types for HID operations.struct HIDD_ATTRIBUTES
Contains vendor ID, product ID, and version number.struct HIDP_CAPS
Contains HID device capabilities (report sizes, usage pages, etc.).struct HidP_Value_Caps
Describes value capabilities (e.g., range, usage, min/max).bool HidD_FlushQueue(int HidDeviceObject)
Flushes the input buffer of an HID device.bool HidD_FreePreparsedData(ref IntPtr PreparsedData)
Frees preparsed data allocated byHidD_GetPreparsedData.int HidD_GetAttributes(int HidDeviceObject, ref HIDD_ATTRIBUTES Attributes)
Retrieves device attributes (VID, PID, version).bool HidD_GetFeature(int HidDeviceObject, ref byte lpReportBuffer, int ReportBufferLength)
Retrieves a feature report from the device.bool HidD_GetInputReport(int HidDeviceObject, ref byte lpReportBuffer, int ReportBufferLength)
Retrieves an input report from the device.void HidD_GetHidGuid(ref Guid HidGuid)
Retrieves the system-defined GUID for HID devices.bool HidD_GetNumInputBuffers(int HidDeviceObject, ref int NumberBuffers)
Gets the number of input buffers allocated for the device.bool HidD_GetPreparsedData(int HidDeviceObject, ref IntPtr PreparsedData)
Retrieves preparsed data for HID device.bool HidD_SetFeature(int HidDeviceObject, ref byte lpReportBuffer, int ReportBufferLength)
Sends a feature report to the device.bool HidD_SetNumInputBuffers(int HidDeviceObject, int NumberBuffers)
Sets the number of input buffers.bool HidD_SetOutputReport(int HidDeviceObject, ref byte lpReportBuffer, int ReportBufferLength)
Sends an output report to the device.int HidP_GetCaps(IntPtr PreparsedData, ref HIDP_CAPS Capabilities)
Retrieves HID capabilities from preparsed data.int HidP_GetValueCaps(short ReportType, ref byte ValueCaps, ref short ValueCapsLength, IntPtr PreparsedData)
Retrieves value capability information.
DeviceManagement class (namespace DTS.Common.USBFramework)
bool DeviceNameMatch(Message m, string mydevicePathName)
Compares the device path in aWM_DEVICECHANGEmessage withmydevicePathName. Returnstrueif they match (case-insensitive). UsesDEV_BROADCAST_DEVICEINTERFACE_1to extract the device name from the message’sLParam.bool FindDeviceFromGuid(Guid myGuid, ref string[] devicePathName)
Enumerates devices in the interface class specified bymyGuidand populatesdevicePathNamewith their device paths. Returnstrueif at least one device is found. UsesSetupDiGetClassDevs,SetupDiEnumDeviceInterfaces, andSetupDiGetDeviceInterfaceDetail.bool RegisterForDeviceNotifications(IntPtr formHandle, Guid classGuid, ref IntPtr deviceNotificationHandle)
Registers a window (formHandle) to receiveWM_DEVICECHANGEnotifications for devices inclassGuid. Returnstrueon success. Allocates unmanaged memory forDEV_BROADCAST_DEVICEINTERFACEand callsRegisterDeviceNotification.void StopReceivingDeviceNotifications(IntPtr deviceNotificationHandle)
Unregisters device notifications usingUnregisterDeviceNotification. Ignores failures.bool GetDeviceRegistryProperty(Guid myGuid)
Enumerates devices inmyGuid’s class and retrieves theSPDRP_DRIVERregistry property for each device. Logs results viaAPILogger. Returnstrueon success (even if no devices found).
3. Invariants
- Handle Validity: All handle-based APIs (
CreateFile,RegisterDeviceNotification) returnINVALID_HANDLE_VALUE(-1) orIntPtr.Zeroon failure. Callers must check return values before use. - Memory Management: Unmanaged memory allocated via
Marshal.AllocHGlobal(e.g., inFindDeviceFromGuid,RegisterForDeviceNotifications) must be freed withMarshal.FreeHGlobal. TheDeviceManagementclass handles this intry/finallyblocks. - Structure Size Consistency: The
cbSizefield ofSP_DEVICE_INTERFACE_DETAIL_DATAmust be set toMarshal.SizeOf()before callingSetupDiGetDeviceInterfaceDetail. The implementation writescbSizemanually to the unmanaged buffer, with logic to handle 32/64-bit alignment. - 64-bit Compatibility:
IS64_BIT_PROCESS(set viaIntPtr.Size == 8) is used to adjust pointer arithmetic (e.g.,cbSizeoffset, handle comparison). This is critical forFindDeviceFromGuidandRegisterForDeviceNotifications. - HID Report Buffer Size:
HidD_GetFeature,HidD_SetFeature, etc., require the report buffer to be exactlyInputReportByteLength/OutputReportByteLength/FeatureReportByteLengthbytes (fromHIDP_CAPS), including the report ID byte. - GUID Consistency: The
HidD_GetHidGuidfunction populates aGuidby reference; callers must pass a validGuidinstance (notGuid.Empty).
4. Dependencies
Imports/References:
- System.Runtime.InteropServices: Required for P/Invoke,
Marshal,StructLayout. - Microsoft.Win32.SafeHandles: Used in
FileIO.CloseHandle(viaSafeFileHandle). - System.Windows.Forms: Required for
Messagetype inDeviceNameMatch. - DTS.Common.Utilities.Logging: Used for
APILogger.LoginGetDeviceRegistryProperty. - hid.dll, setupapi.dll, kernel32.dll, advapi32.dll: Native libraries for HID, device setup, and registry operations.
Dependencies on Other Modules:
DeviceManagementdepends onDeviceManagementDeclarationsfor unmanaged API declarations.FileIOandFileIODeclarationsprovide overlapping declarations (likely legacy duplication).HIDDeclarationsis in a different namespace (DTS.DASLib.Connection.USBFramework) and is used by HID-specific communication logic (not shown here).
Used By:
- Higher-level USB connection classes (e.g.,
USBConnection,HIDConnection) that consumeDeviceManagementfor device discovery andHIDDeclarationsfor HID I/O.
5. Gotchas
- Duplicate Constants:
FileIOandFileIODeclarationsdefine identical constants (e.g.,GENERIC_READ,FILE_FLAG_OVERLAPPED) with inconsistent types (uintvsshort/int). This may cause confusion or errors if mixed. - Inconsistent Structure Definitions:
SECURITY_ATTRIBUTESis defined twice inFileIODeclarationsandFileIOwith different field types (intvsIntPtr). This is unsafe and may cause crashes on 64-bit systems. OVERLAPPEDStructure: TheOVERLAPPEDstruct usesintforhEventinstead ofIntPtr, which is incorrect for 64-bit compatibility. This will fail on 64-bit processes.CreateFileOverloads:FileIODeclarations.CreateFilereturnsint(unmanaged handle), whileFileIO.CreateFilereturnsSafeFileHandle. Using the wrong overload may lead to resource leaks or handle misuse.RegisterForDeviceNotificationsMemory Leak Risk: Thebufferallocated viaMarshal.AllocHGlobalis freed afterRegisterDeviceNotification, but ifRegisterDeviceNotificationfails, the handle isIntPtr.Zero, and the buffer is still freed. This is safe, but the comment// Set fDeleteOld True to prevent memory leaksis misleading—thetrueflag inStructureToPtroverwrites the old pointer, butAllocHGlobal/FreeHGlobalis still required.FindDeviceFromGuidBuffer Size Calculation: ThecbSizeoffset calculation(IntPtr.Size == 4) ? (4 + Marshal.SystemDefaultCharSize) : 8assumescbSizeis 4 bytes on 32-bit and 8 on 64-bit, butSP_DEVICE_INTERFACE_DETAIL_DATA.cbSizeisint(4 bytes) regardless of platform. This may cause misalignment on 64-bit.DeviceNameMatchString Size Calculation: Assumesdbcc_nameis Unicode (2 bytes/char) and subtracts 28 bytes for fixed fields. This is correct forDEV_BROADCAST_DEVICEINTERFACE_1but may break if structure layout changes.GetDeviceRegistryPropertyRegistry Key Access: UsesSetupDiOpenDevRegKeybut does not show its usage; the implementation only retrievesSPDRP_DRIVERviaSetupDiGetDeviceRegistryPropertyA. Registry access may fail without elevated privileges.HIDP_*Functions: Return codes (e.g.,HidP_GetCaps) areintbut not documented. Callers must check for success (typically0for success, non-zero for error codes likeHIDP_STATUS_BUFFER_TOO_SMALL).- No Async Support: Despite
FILE_FLAG_OVERLAPPEDbeing defined, theReadFile/WriteFiledeclarations use synchronous signatures (noOVERLAPPEDpointer). Asynchronous I/O is not implemented.