init
This commit is contained in:
@@ -0,0 +1,147 @@
|
||||
---
|
||||
source_files:
|
||||
- Common/DTS.Common.IConnection/USBConnection/HIDUSBConnection/HIDUSBConnection.cs
|
||||
generated_at: "2026-04-16T02:10:22.619594+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "4a9eeb7b8043999a"
|
||||
---
|
||||
|
||||
# Documentation: `HIDUSBConnection` Class
|
||||
|
||||
## 1. Purpose
|
||||
`HIDUSBConnection` is a concrete implementation of the `IConnection` interface that enables communication with a specific HID-class USB device (identified by Vendor ID `0x1CB9` and Product ID `0x0003`, named *HIDSLICE*) using Windows file I/O APIs (`CreateFile`, `ReadFile`, `WriteFile` via overlapped I/O). It abstracts low-level HID report handling (input/output reports) over USB, providing asynchronous send/receive semantics consistent with .NET’s `IAsyncResult` pattern. This module exists to support direct, low-latency data transfer to/from embedded hardware (e.g., a data acquisition recorder) where standard socket-based communication is not applicable.
|
||||
|
||||
---
|
||||
|
||||
## 2. Public Interface
|
||||
|
||||
### Constructors & Finalizer
|
||||
- **`HIDUSBConnection()`**
|
||||
Initializes the instance, sets up `SECURITY_ATTRIBUTES` for `CreateFile`, and initializes `_Connected = false`.
|
||||
|
||||
- **`~HIDUSBConnection()`**
|
||||
Finalizer that invokes `Dispose(false)` to release unmanaged resources.
|
||||
|
||||
### Disposal
|
||||
- **`void Dispose()`**
|
||||
Performs deterministic cleanup: calls `Dispose(true)` and suppresses finalization.
|
||||
|
||||
- **`protected virtual void Dispose(bool disposing)`**
|
||||
Releases all handles (`_HIDHandle`, `_ReadHandle`, `_WriteHandle`) via `FileIODeclarations.CloseHandle`, disposes `_MyHID`, and sets `_Connected = false`. Idempotent (`disposed` flag prevents double-disposal).
|
||||
|
||||
### Connection Management
|
||||
- **`void Create(string ConnectString)`**
|
||||
Stores the device path (`ConnectString`) for later use in `EndConnect`. Does *not* open the device.
|
||||
|
||||
- **`IAsyncResult BeginConnect(AsyncCallback cb, object state)`**
|
||||
Initiates asynchronous connection. Enqueues a work item to invoke `NetCallbackFix`, which in turn invokes the callback on the thread pool. *Actual device opening occurs in `EndConnect`*.
|
||||
|
||||
- **`void EndConnect(IAsyncResult ar)`**
|
||||
Opens the device using `ConnectString` (set via `Create`) via three `CreateFile` calls:
|
||||
- `_HIDHandle`: for attribute queries (no access rights)
|
||||
- `_ReadHandle`: for reading input reports (`GENERIC_READ`)
|
||||
- `_WriteHandle`: for writing output reports (`GENERIC_WRITE`)
|
||||
Retrieves device attributes (`HidD_GetAttributes`), capabilities (`GetDeviceCapabilities`), and input report buffer size (`GetInputReportBufferSize`). Flushes the input queue. Sets `_Connected = true`. Throws on handle failure or attribute retrieval failure.
|
||||
|
||||
- **`IAsyncResult BeginDisconnect(bool reuseSocket, AsyncCallback cb, object state)`**
|
||||
Asynchronous disconnect. Enqueues a work item to invoke the callback. *Actual cleanup is deferred to `EndDisconnect`*.
|
||||
|
||||
- **`void EndDisconnect(IAsyncResult asyncResult)`**
|
||||
Closes all three handles (`_HIDHandle`, `_ReadHandle`, `_WriteHandle`) and sets `_Connected = false`.
|
||||
|
||||
### Properties
|
||||
- **`bool Connected { get; }`**
|
||||
Returns `_Connected`.
|
||||
|
||||
- **`string ConnectString { get; }`**
|
||||
Returns `Device_Name` (set via `Create`).
|
||||
|
||||
- **`System.Net.Sockets.SocketFlags Flags { get; set; }`**
|
||||
Property required by `IConnection` interface; unused in this implementation.
|
||||
|
||||
- **`string GetConnectionData()`**
|
||||
Returns `""` (empty string). No meaningful data exposed.
|
||||
|
||||
- **`double GetCurrentDownloadRate()`**
|
||||
Returns `0D`. Rate tracking not implemented.
|
||||
|
||||
- **`double GetCurrentUploadRate()`**
|
||||
Returns `0D`. Rate tracking not implemented.
|
||||
|
||||
### Static Utility
|
||||
- **`static string GetFirstConnectString()`**
|
||||
Scans all HID devices on the system to find the first device matching `DTS_VID` (`0x1CB9`) and `HIDSLICE_PID` (`0x0003`). Returns the device’s path string (e.g., `\\?\hid#vid_1cb9&pid_0003#...`) or `string.Empty` if not found. Uses `HIDDeclarations.HidD_GetHidGuid`, `DeviceManagement.FindDeviceFromGuid`, and `HIDDeclarations.HidD_GetAttributes`.
|
||||
|
||||
### I/O Operations
|
||||
- **`IAsyncResult BeginSend(byte[] buffer, int offset, int size, AsyncCallback cb, object state)`**
|
||||
Initiates asynchronous send. Validates `_ReadHandle` and `_WriteHandle` are valid. Enqueues callback via `ThreadPool.QueueUserWorkItem`. *Actual transmission occurs in `EndSend`*.
|
||||
|
||||
- **`int EndSend(IAsyncResult ar)`**
|
||||
Writes `buffer[offset..offset+size)` to the device in chunks, respecting `OutputReportByteLength`.
|
||||
- Prepends each chunk with report ID `0x00` at index `0`.
|
||||
- Uses `HIDevice.OutputReport.Write` for each chunk.
|
||||
Returns `size` (number of bytes sent). Throws on invalid handles or write failure.
|
||||
|
||||
- **`IAsyncResult BeginReceive(byte[] buffer, int offset, int size, AsyncCallback cb, object state)`**
|
||||
Initiates asynchronous receive. Validates handles. Enqueues callback. *Actual read occurs in `EndReceive`*.
|
||||
|
||||
- **`int EndReceive(IAsyncResult ar)`**
|
||||
Reads one input report into `InputReportBuffer` via `HIDevice.InputReport.Read`. Copies data (skipping report ID at index `0`) into `buffer[offset..]`. Returns `size` if successful, `0` otherwise. Sets `IsCompleted = true` and signals `AsyncWaitHandle`.
|
||||
|
||||
### Unsupported Operations (Throw `NotSupportedException`)
|
||||
- `BeginAccept`, `EndAccept`, `Bind(int)`, `Listen(int)`
|
||||
These methods are implemented only to satisfy `IConnection` but are not applicable to HID device communication.
|
||||
|
||||
---
|
||||
|
||||
## 3. Invariants
|
||||
|
||||
- **Device Identity**: Only devices with `VendorID == 0x1CB9` and `ProductID == 0x0003` are accepted.
|
||||
- **Handle State**: `_HIDHandle`, `_ReadHandle`, and `_WriteHandle` must be valid (non-`INVALID_HANDLE_VALUE`) before `BeginSend`/`BeginReceive` succeeds.
|
||||
- **Connection State**: `_Connected` is `true` only after successful completion of `EndConnect`, and `false` otherwise (including after `EndDisconnect` or disposal).
|
||||
- **Report Structure**:
|
||||
- Input reports: Data starts at index `1`; index `0` is the report ID (ignored).
|
||||
- Output reports: Data starts at index `1`; index `0` is report ID (set to `0`).
|
||||
- **Buffer Size**: `InputReportBuffer` is sized to `_MyHID.Capabilities.InputReportByteLength` during `EndConnect`.
|
||||
- **Disposal Safety**: `Dispose` is idempotent (`disposed` flag prevents re-entry).
|
||||
- **Asynchronous Pattern**: All async operations (`BeginConnect`, `BeginSend`, etc.) use `HIDUSBRecAsyncResult` and delegate callback invocation to `NetCallbackFix`, which runs on a thread pool thread.
|
||||
|
||||
---
|
||||
|
||||
## 4. Dependencies
|
||||
|
||||
### External Dependencies
|
||||
- **Windows API (via interop)**:
|
||||
- `FileIODeclarations.CreateFile`, `CloseHandle`, `FILE_SHARE_*`, `GENERIC_*`, `INVALID_HANDLE_VALUE`, `OPEN_EXISTING`
|
||||
- `HIDDeclarations.HidD_GetHidGuid`, `HidD_GetAttributes`
|
||||
- **`DTS.DASLib.Connection.USBFramework`**:
|
||||
- `HIDevice` class (used for device attributes, capabilities, input/output report handling)
|
||||
- `DeviceManagement` class (used in `GetFirstConnectString`)
|
||||
- **`DTS.DASLib.DASResource`**:
|
||||
- `Strings` resource class (for localized error messages, e.g., `Strings.HIDUSBConnection_EndConnect_Err1`)
|
||||
- **.NET Framework Core**:
|
||||
- `System.Runtime.InteropServices` (for `Marshal.SizeOf`, `SECURITY_ATTRIBUTES`)
|
||||
- `System.Threading` (for `ThreadPool`, `ManualResetEvent`)
|
||||
- `System.Windows.Forms.MessageBox` (used in `NetCallbackFix` for exception reporting—*potential runtime dependency on WinForms*).
|
||||
|
||||
### Implemented Interfaces
|
||||
- `IConnection` (interface defining the contract; not shown in source but referenced).
|
||||
|
||||
### Inferred Consumers
|
||||
- Any code requiring `IConnection` to communicate with the *HIDSLICE* device (e.g., data acquisition logic, device enumeration UI).
|
||||
- `GetFirstConnectString` is likely called by device discovery components.
|
||||
|
||||
---
|
||||
|
||||
## 5. Gotchas
|
||||
|
||||
- **Misleading Async Pattern**: `BeginConnect`/`BeginSend`/`BeginReceive` do *not* perform actual I/O; they only enqueue a callback. All work happens in `End*` methods. This deviates from typical .NET async patterns where `Begin*` initiates the operation.
|
||||
- **No Overlapped I/O**: Despite using `CreateFile` with overlapped semantics (implied by `_ReadHandle`/`_WriteHandle`), the code does *not* use `OVERLAPPED` structures or `ReadFile`/`WriteFile` with completion callbacks. Instead, it relies on synchronous `HIDevice.InputReport.Read`/`Write`, which may block the thread pool thread.
|
||||
- **Hardcoded Report ID**: Output reports always use `0x00` as the report ID. This assumes the device expects report ID `0`; mismatched IDs will cause silent failures or device errors.
|
||||
- **WinForms Dependency in Error Handling**: `NetCallbackFix` shows a `MessageBox` on exceptions—a severe anti-pattern for non-UI threads or server environments.
|
||||
- **`GetFirstConnectString` Hack**: The method scans *all* HID devices and stops at the first match. If multiple *HIDSLICE* devices are connected, behavior is undefined (first found wins).
|
||||
- **Buffer Size Mismatch in `EndReceive`**: `EndReceive` copies `InputReportBuffer.Length - 1` bytes into the user buffer, but returns `rar.size` regardless. If `rar.size < InputReportBuffer.Length - 1`, the caller may read uninitialized buffer data beyond the actual received payload.
|
||||
- **No Timeout Handling**: No mechanism for read/write timeouts; operations may block indefinitely.
|
||||
- **`Flags` Property Unused**: The `SocketFlags` property is implemented but never used.
|
||||
- **`BeginAccept`/`EndAccept` Misuse**: Throwing `NotSupportedException` for connection-oriented methods suggests this class was adapted from a socket-based `IConnection` implementation without full refactoring.
|
||||
@@ -0,0 +1,33 @@
|
||||
---
|
||||
source_files:
|
||||
- Common/DTS.Common.IConnection/USBConnection/HIDUSBConnection/Properties/AssemblyInfo.cs
|
||||
generated_at: "2026-04-16T02:10:22.587640+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "1fcf58774b015c19"
|
||||
---
|
||||
|
||||
# Properties
|
||||
|
||||
## 1. Purpose
|
||||
This file is an assembly-level metadata configuration file (`AssemblyInfo.cs`) for the `DTS.Common.IConnection.USBConnection.HIDUSBConnection` .NET assembly. Its purpose is to define assembly-wide attributes such as title, version, COM visibility, and GUID—used for identification, versioning, and interoperability—but it does *not* contain any executable logic, interfaces, or types. It serves as infrastructure metadata required by the .NET build system and COM interop layer, with no runtime behavior or public API surface.
|
||||
|
||||
## 2. Public Interface
|
||||
**None.**
|
||||
This file contains only assembly-level attributes and no public types (classes, structs, interfaces, enums), methods, properties, or fields. All content is metadata declarations via `Assembly*` attributes.
|
||||
|
||||
## 3. Invariants
|
||||
- The assembly is **not visible to COM** (`ComVisible(false)`), meaning its types cannot be accessed via COM unless explicitly exposed elsewhere.
|
||||
- The assembly’s version is fixed at **1.06.0081** for both `AssemblyVersion` and `AssemblyFileVersion`.
|
||||
- The assembly’s GUID is **`9127ae79-928b-4187-a425-97f49034c5ad`**, used for COM type library identification (though irrelevant here due to `ComVisible(false)`).
|
||||
- No runtime invariants apply, as this file contributes no executable code.
|
||||
|
||||
## 4. Dependencies
|
||||
- **Dependencies**: None (this file has no external dependencies beyond the .NET Framework’s `System.Reflection`, `System.Runtime.CompilerServices`, and `System.Runtime.InteropServices` namespaces, which are implicitly available).
|
||||
- **Depended upon**: None directly—this file is consumed by the build system and runtime metadata infrastructure, not by application code. Other modules in the `DTS.Common.IConnection` hierarchy may reference this assembly, but they do not depend on its metadata content.
|
||||
|
||||
## 5. Gotchas
|
||||
- **Versioning nuance**: `AssemblyVersion` (`1.06.0081`) controls binding redirects and assembly identity at runtime, while `AssemblyFileVersion` is informational (used for file properties in Windows). Changing only `AssemblyFileVersion` does *not* affect runtime binding.
|
||||
- **COM irrelevance**: Despite the explicit `Guid` attribute, `ComVisible(false)` renders the GUID unused for COM registration. If COM interop is needed, `ComVisible(true)` must be set *and* types must be explicitly marked with `ComVisible(true)`.
|
||||
- **No functional impact**: Modifying or deleting this file will not break runtime logic but may cause build warnings or break COM registration tooling (e.g., `regasm`) if used.
|
||||
- **Historical date**: Copyright year is set to 2008; verify if this reflects current ownership or is legacy.
|
||||
@@ -0,0 +1,158 @@
|
||||
---
|
||||
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-16T02:09:55.521694+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "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 in `CreateFile`.
|
||||
- **`const uint GENERIC_WRITE = 0x40000000`**
|
||||
Access mask for write operations in `CreateFile`.
|
||||
- **`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 in `CreateFile`.
|
||||
- **`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 for `WaitForSingleObject`.
|
||||
- **`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: `hEvent` is `int`, not `IntPtr`).
|
||||
- **`struct SECURITY_ATTRIBUTES`**
|
||||
Unmanaged structure for security descriptor handling (note: `lpSecurityDescriptor` is `int`, not `IntPtr`).
|
||||
- **`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: `lpOverlapped` is `int`, not `ref 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) from `FileIODeclarations`.
|
||||
- **`struct SECURITY_ATTRIBUTES`**
|
||||
Alternate definition with `lpSecurityDescriptor` as `IntPtr` (inconsistent with `FileIODeclarations`).
|
||||
- **`bool CloseHandle(SafeFileHandle hObject)`**
|
||||
Managed wrapper for closing a `SafeFileHandle`.
|
||||
- **`SafeFileHandle CreateFile(string lpFileName, uint dwDesiredAccess, int dwShareMode, ref SECURITY_ATTRIBUTES lpSecurityAttributes, int dwCreationDisposition, int dwFlagsAndAttributes, int hTemplateFile)`**
|
||||
Managed wrapper returning `SafeFileHandle`.
|
||||
|
||||
### `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 by `HidD_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 a `WM_DEVICECHANGE` message with `mydevicePathName`. Returns `true` if they match (case-insensitive). Uses `DEV_BROADCAST_DEVICEINTERFACE_1` to extract the device name from the message’s `LParam`.
|
||||
- **`bool FindDeviceFromGuid(Guid myGuid, ref string[] devicePathName)`**
|
||||
Enumerates devices in the interface class specified by `myGuid` and populates `devicePathName` with their device paths. Returns `true` if at least one device is found. Uses `SetupDiGetClassDevs`, `SetupDiEnumDeviceInterfaces`, and `SetupDiGetDeviceInterfaceDetail`.
|
||||
- **`bool RegisterForDeviceNotifications(IntPtr formHandle, Guid classGuid, ref IntPtr deviceNotificationHandle)`**
|
||||
Registers a window (`formHandle`) to receive `WM_DEVICECHANGE` notifications for devices in `classGuid`. Returns `true` on success. Allocates unmanaged memory for `DEV_BROADCAST_DEVICEINTERFACE` and calls `RegisterDeviceNotification`.
|
||||
- **`void StopReceivingDeviceNotifications(IntPtr deviceNotificationHandle)`**
|
||||
Unregisters device notifications using `UnregisterDeviceNotification`. Ignores failures.
|
||||
- **`bool GetDeviceRegistryProperty(Guid myGuid)`**
|
||||
Enumerates devices in `myGuid`’s class and retrieves the `SPDRP_DRIVER` registry property for each device. Logs results via `APILogger`. Returns `true` on success (even if no devices found).
|
||||
|
||||
## 3. Invariants
|
||||
|
||||
- **Handle Validity**: All handle-based APIs (`CreateFile`, `RegisterDeviceNotification`) return `INVALID_HANDLE_VALUE` (-1) or `IntPtr.Zero` on failure. Callers must check return values before use.
|
||||
- **Memory Management**: Unmanaged memory allocated via `Marshal.AllocHGlobal` (e.g., in `FindDeviceFromGuid`, `RegisterForDeviceNotifications`) must be freed with `Marshal.FreeHGlobal`. The `DeviceManagement` class handles this in `try/finally` blocks.
|
||||
- **Structure Size Consistency**: The `cbSize` field of `SP_DEVICE_INTERFACE_DETAIL_DATA` must be set to `Marshal.SizeOf()` *before* calling `SetupDiGetDeviceInterfaceDetail`. The implementation writes `cbSize` manually to the unmanaged buffer, with logic to handle 32/64-bit alignment.
|
||||
- **64-bit Compatibility**: `IS64_BIT_PROCESS` (set via `IntPtr.Size == 8`) is used to adjust pointer arithmetic (e.g., `cbSize` offset, handle comparison). This is critical for `FindDeviceFromGuid` and `RegisterForDeviceNotifications`.
|
||||
- **HID Report Buffer Size**: `HidD_GetFeature`, `HidD_SetFeature`, etc., require the report buffer to be exactly `InputReportByteLength`/`OutputReportByteLength`/`FeatureReportByteLength` bytes (from `HIDP_CAPS`), including the report ID byte.
|
||||
- **GUID Consistency**: The `HidD_GetHidGuid` function populates a `Guid` by reference; callers must pass a valid `Guid` instance (not `Guid.Empty`).
|
||||
|
||||
## 4. Dependencies
|
||||
|
||||
### Imports/References:
|
||||
- **System.Runtime.InteropServices**: Required for P/Invoke, `Marshal`, `StructLayout`.
|
||||
- **Microsoft.Win32.SafeHandles**: Used in `FileIO.CloseHandle` (via `SafeFileHandle`).
|
||||
- **System.Windows.Forms**: Required for `Message` type in `DeviceNameMatch`.
|
||||
- **DTS.Common.Utilities.Logging**: Used for `APILogger.Log` in `GetDeviceRegistryProperty`.
|
||||
- **hid.dll**, **setupapi.dll**, **kernel32.dll**, **advapi32.dll**: Native libraries for HID, device setup, and registry operations.
|
||||
|
||||
### Dependencies on Other Modules:
|
||||
- **`DeviceManagement`** depends on `DeviceManagementDeclarations` for unmanaged API declarations.
|
||||
- **`FileIO`** and **`FileIODeclarations`** provide overlapping declarations (likely legacy duplication).
|
||||
- **`HIDDeclarations`** is 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 consume `DeviceManagement` for device discovery and `HIDDeclarations` for HID I/O.
|
||||
|
||||
## 5. Gotchas
|
||||
|
||||
- **Duplicate Constants**: `FileIO` and `FileIODeclarations` define identical constants (e.g., `GENERIC_READ`, `FILE_FLAG_OVERLAPPED`) with inconsistent types (`uint` vs `short`/`int`). This may cause confusion or errors if mixed.
|
||||
- **Inconsistent Structure Definitions**: `SECURITY_ATTRIBUTES` is defined twice in `FileIODeclarations` and `FileIO` with different field types (`int` vs `IntPtr`). This is unsafe and may cause crashes on 64-bit systems.
|
||||
- **`OVERLAPPED` Structure**: The `OVERLAPPED` struct uses `int` for `hEvent` instead of `IntPtr`, which is incorrect for 64-bit compatibility. This will fail on 64-bit processes.
|
||||
- **`CreateFile` Overloads**: `FileIODeclarations.CreateFile` returns `int` (unmanaged handle), while `FileIO.CreateFile` returns `SafeFileHandle`. Using the wrong overload may lead to resource leaks or handle misuse.
|
||||
- **`RegisterForDeviceNotifications` Memory Leak Risk**: The `buffer` allocated via `Marshal.AllocHGlobal` is freed *after* `RegisterDeviceNotification`, but if `RegisterDeviceNotification` fails, the handle is `IntPtr.Zero`, and the buffer is still freed. This is safe, but the comment `// Set fDeleteOld True to prevent memory leaks` is misleading—the `true` flag in `StructureToPtr` overwrites the old pointer, but `AllocHGlobal`/`FreeHGlobal` is still required.
|
||||
- **`FindDeviceFromGuid` Buffer Size Calculation**: The `cbSize` offset calculation `(IntPtr.Size == 4) ? (4 + Marshal.SystemDefaultCharSize) : 8` assumes `cbSize` is 4 bytes on 32-bit and 8 on 64-bit, but `SP_DEVICE_INTERFACE_DETAIL_DATA.cbSize` is `int` (4 bytes) regardless of platform. This may cause misalignment on 64-bit.
|
||||
- **`DeviceNameMatch` String Size Calculation**: Assumes `dbcc_name` is Unicode (2 bytes/char) and subtracts 28 bytes for fixed fields. This is correct for `DEV_BROADCAST_DEVICEINTERFACE_1` but may break if structure layout changes.
|
||||
- **`GetDeviceRegistryProperty` Registry Key Access**: Uses `SetupDiOpenDevRegKey` but does not show its usage; the implementation only retrieves `SPDRP_DRIVER` via `SetupDiGetDeviceRegistryPropertyA`. Registry access may fail without elevated privileges.
|
||||
- **`HIDP_*` Functions**: Return codes (e.g., `HidP_GetCaps`) are `int` but not documented. Callers must check for success (typically `0` for success, non-zero for error codes like `HIDP_STATUS_BUFFER_TOO_SMALL`).
|
||||
- **No Async Support**: Despite `FILE_FLAG_OVERLAPPED` being defined, the `ReadFile`/`WriteFile` declarations use synchronous signatures (no `OVERLAPPED` pointer). Asynchronous I/O is not implemented.
|
||||
@@ -0,0 +1,36 @@
|
||||
---
|
||||
source_files:
|
||||
- Common/DTS.Common.IConnection/USBConnection/USBFramework/Properties/AssemblyInfo.cs
|
||||
generated_at: "2026-04-16T02:10:14.603636+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "f8e1fde835545ec4"
|
||||
---
|
||||
|
||||
# Properties
|
||||
|
||||
## 1. Purpose
|
||||
This module is the `DTS.Common.IConnection.USBConnection.USBFramework` assembly (internally titled *HIDFramework*), a .NET class library component responsible for providing USB communication capabilities—specifically targeting Human Interface Device (HID) protocols—within the DTS (presumably *Digital Training Systems* or similar domain) ecosystem. It serves as a foundational layer for establishing and managing connections to USB HID devices, likely abstracting low-level OS interactions (e.g., Windows HID API) into higher-level .NET interfaces used by other connection-handling modules (e.g., `IConnection` implementations). Its existence enables standardized, reusable USB device integration across the codebase.
|
||||
|
||||
## 2. Public Interface
|
||||
**No public types (classes, interfaces, structs, or methods) are declared in this file.**
|
||||
This file (`AssemblyInfo.cs`) contains only assembly-level metadata attributes (e.g., title, version, COM visibility) and does not define any executable code or public API surface. Therefore, there are **no public functions, classes, or methods** documented here. Public interfaces would reside in other source files within the `USBFramework` project (e.g., `HIDDevice.cs`, `USBConnection.cs`), which are not provided.
|
||||
|
||||
## 3. Invariants
|
||||
- The assembly is **not COM-visible** (`ComVisible(false)`), meaning its types cannot be directly consumed by COM clients without explicit interop wrappers.
|
||||
- The assembly version is fixed at `1.06.0081` (both `AssemblyVersion` and `AssemblyFileVersion`).
|
||||
- The assembly GUID (`c655f31f-ca6c-4e9b-9480-934762d20a8c`) uniquely identifies the typelib for COM interop *if* `ComVisible` were enabled (though it is not).
|
||||
- No runtime invariants (e.g., state constraints, validation rules) are expressible in this file, as it contains no logic.
|
||||
|
||||
## 4. Dependencies
|
||||
- **Framework Dependencies**: Requires core .NET Framework assemblies (implicitly via `System.Reflection`, `System.Runtime.CompilerServices`, `System.Runtime.InteropServices`).
|
||||
- **No explicit external dependencies** are declared in this file.
|
||||
- **Inferred consumers**: Other modules in the `DTS.Common.IConnection` hierarchy (e.g., `USBConnection` implementations) likely depend on types defined in this assembly, but those types are not visible here.
|
||||
- **Inferred producers**: This assembly is likely built as part of a larger solution where `USBFramework` is a referenced library for USB-specific connection logic.
|
||||
|
||||
## 5. Gotchas
|
||||
- **Misleading assembly title**: The `AssemblyTitle` is `"HIDFramework"`, but the namespace/path is `USBFramework`. This may cause confusion during debugging, logging, or reflection-based discovery (e.g., `Assembly.GetExecutingAssembly().Title` returns `"HIDFramework"`).
|
||||
- **No versioning strategy in source**: The version `1.06.0081` is hardcoded; no build-time auto-increment or CI integration is evident.
|
||||
- **COM interop disabled**: While `ComVisible(false)` is appropriate for pure .NET usage, it precludes direct COM consumption without additional interop layers (e.g., `RegAsm` with `/tlb` and `/codebase`).
|
||||
- **No documentation comments**: The file lacks XML documentation (`<summary>`, etc.), consistent with typical `AssemblyInfo.cs` but contributing to low discoverability of assembly-level intent.
|
||||
- **None identified from source alone** regarding runtime behavior, logic, or usage patterns—these would require inspecting the actual implementation files (not provided).
|
||||
@@ -0,0 +1,284 @@
|
||||
---
|
||||
source_files:
|
||||
- Common/DTS.Common.IConnection/USBConnection/WINUSBConnection/WINUSBDeviceApi.cs
|
||||
- Common/DTS.Common.IConnection/USBConnection/WINUSBConnection/CDCUSBConnection.cs
|
||||
- Common/DTS.Common.IConnection/USBConnection/WINUSBConnection/WINUSBConnection.cs
|
||||
generated_at: "2026-04-16T02:09:52.794052+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "2043cd8e3c0f04ef"
|
||||
---
|
||||
|
||||
# Documentation: USB Connection Modules
|
||||
|
||||
## 1. Purpose
|
||||
|
||||
This module provides two distinct USB-based connection implementations (`CDCUSBConnection` and `WINUSBConnection`) that implement the `IConnection` interface for communicating with DTS hardware devices. `CDCUSBConnection` emulates a serial port over USB using the Windows `SerialPort` class (CDC–Communication Device Class), while `WINUSBConnection` uses the native Windows WinUSB API (`winusb.dll`) for direct USB communication. Both modules support asynchronous I/O operations (`BeginConnect`, `EndConnect`, `BeginSend`, `EndSend`, etc.), resource disposal, and registry-based device enumeration for the DTS vendor ID `0x1CB9` and specific product IDs.
|
||||
|
||||
## 2. Public Interface
|
||||
|
||||
### `CDCUSBConnection`
|
||||
|
||||
- **`public bool IsSoftDisconnected { get; }`**
|
||||
Always returns `false`. Soft disconnect is not supported for CDCUSB.
|
||||
|
||||
- **`public void SoftConnect()`**
|
||||
No-op. Soft connect is not supported.
|
||||
|
||||
- **`public void SoftDisconnect()`**
|
||||
No-op. Soft disconnect is not supported.
|
||||
|
||||
- **`public double GetCurrentUploadRate()`**
|
||||
Returns `0.0`. Upload rate is not tracked.
|
||||
|
||||
- **`public double GetCurrentDownloadRate()`**
|
||||
Returns `0.0`. Download rate is not tracked.
|
||||
|
||||
- **`public string PortName { get; set; }`**
|
||||
Gets or sets the COM port name (e.g., `"COM3"`) used for serial communication.
|
||||
|
||||
- **`public string ConnectString { get; }`**
|
||||
Returns the `_devicePathname` passed to `Create`. Used as a device identifier.
|
||||
|
||||
- **`public bool Connected { get; }`**
|
||||
Returns `_Connected`, indicating whether the underlying `SerialPort` is open.
|
||||
|
||||
- **`public event EventHandler OnDisconnected`**
|
||||
Event raised on disconnection (currently unused in this implementation).
|
||||
|
||||
- **`public static IList<string> RegKeys { get; }`**
|
||||
Lazily-initialized list of registry subkey names under the DTS CDCUSB device path (`USB\VID_1CB9&PID_001A`). Used to locate device-specific COM port names.
|
||||
|
||||
- **`public CDCUSBConnection()`**
|
||||
Constructor initializing internal state (`_Connected = false`, `Disposed = false`, `Disposing = false`).
|
||||
|
||||
- **`public void Create(string connectString, string hostIPAddress)`**
|
||||
Parses `connectString` to match a registry key in `RegKeys`, then reads the `"PortName"` value from the device’s registry `"Device Parameters"` subkey and assigns it to `PortName`. Sets `_devicePathname = connectString`.
|
||||
|
||||
- **`public IAsyncResult BeginConnect(AsyncCallback cb, object state)`**
|
||||
Returns an `IAsyncResult` (`UsbRecAsyncResult`) and queues a callback via `ThreadPool.QueueUserWorkItem`. Does *not* perform the actual connection.
|
||||
|
||||
- **`public void EndConnect(IAsyncResult ar)`**
|
||||
Opens the `SerialPort` using configured `_baudRate`, `_parity`, `_stopBits`, `DATA_BITS`, and `PortName`. Sets `_Connected = true` on success.
|
||||
|
||||
- **`public IAsyncResult BeginSend(byte[] buffer, int offset, int size, AsyncCallback cb, object state)`**
|
||||
Returns `UsbRecAsyncResult` with buffer metadata. Actual write occurs in `EndSend`.
|
||||
|
||||
- **`public int EndSend(IAsyncResult ar)`**
|
||||
Writes `buffer` (using `size` and `offset` from `UsbRecAsyncResult`) to `_comPort.Write(...)`. Returns `size`.
|
||||
|
||||
- **`public Task<int> SendAsync(...)`**
|
||||
Wraps `BeginSend`/`EndSend` in a `Task<int>`.
|
||||
|
||||
- **`public IAsyncResult BeginReceive(byte[] buffer, int offset, int size, AsyncCallback cb, object state)`**
|
||||
Returns `UsbRecAsyncResult` with buffer metadata.
|
||||
|
||||
- **`public int EndReceive(IAsyncResult ar)`**
|
||||
Reads from `_comPort.Read(...)` in a loop until at least one byte is read (sleeps 1 ms between retries). Returns number of bytes read.
|
||||
|
||||
- **`public IAsyncResult BeginDisconnect(...)`**
|
||||
Returns `UsbRecAsyncResult`. Actual disconnect occurs in `EndDisconnect`.
|
||||
|
||||
- **`public void EndDisconnect(IAsyncResult ar)`**
|
||||
Closes and disposes `_comPort`, sets `_Connected = false`.
|
||||
|
||||
- **`public void Dispose()` / `protected virtual void Dispose(bool)`**
|
||||
Implements `IDisposable`. Closes `_comPort` if open, sets `Disposed = true`.
|
||||
|
||||
- **`public void Bind(int port)` / `public void Listen(int backlog)` / `public IAsyncResult BeginAccept(...)` / `public IConnection EndAccept(...)`**
|
||||
All throw `NotSupportedException`.
|
||||
|
||||
### `WINUSBConnection`
|
||||
|
||||
- **`public bool IsSoftDisconnected { get; }`**
|
||||
Always returns `false`. Soft disconnect is not supported.
|
||||
|
||||
- **`public void SoftConnect()` / `public void SoftDisconnect()`**
|
||||
No-op.
|
||||
|
||||
- **`public double GetCurrentUploadRate()` / `public double GetCurrentDownloadRate()`**
|
||||
Return `0.0`.
|
||||
|
||||
- **`public bool Connected { get; private set; }`**
|
||||
Indicates whether the device is connected via WinUSB.
|
||||
|
||||
- **`public string ConnectString { get; private set; }`**
|
||||
Stores the device path passed to `Create`.
|
||||
|
||||
- **`public event EventHandler OnDisconnected`**
|
||||
Event for disconnection notifications (currently unused).
|
||||
|
||||
- **`public void Create(string connectString, string hostIPAddress)`**
|
||||
Stores `connectString` in `ConnectString`.
|
||||
|
||||
- **`public IAsyncResult BeginConnect(AsyncCallback cb, object state)`**
|
||||
Validates `_sliceDev == null && !Connected`. Returns `WinUSBRecAsyncResult`, waits synchronously on `AsyncWaitHandle` before returning.
|
||||
|
||||
- **`public void EndConnect(IAsyncResult ar)`**
|
||||
Instantiates `_sliceDev = new WinUsbDevice()`, calls `_sliceDev.GetDeviceHandle(ConnectString)` and `_sliceDev.InitializeDevice()`. Sets `Connected = true` on success. Logs and throws `NotConnectedException` on failure.
|
||||
|
||||
- **`public IAsyncResult BeginSend(byte[] buffer, int offset, int size, AsyncCallback cb, object state)`**
|
||||
Validates connection and buffer parameters. Returns `WinUSBRecAsyncResult`.
|
||||
|
||||
- **`public int EndSend(IAsyncResult ar)`**
|
||||
Copies buffer data, then calls `_sliceDev.SendViaInterruptTransfer(...)` or `_sliceDev.SendViaBulkTransfer(...)` depending on `MyDevInfo.UseHybridBulkIntMode`. Throws on failure.
|
||||
|
||||
- **`public Task<int> SendAsync(...)`**
|
||||
Wraps `BeginSend`/`EndSend`.
|
||||
|
||||
- **`public IAsyncResult BeginReceive(byte[] buffer, int offset, int size, AsyncCallback cb, object state)`**
|
||||
Validates connection and buffer parameters. Returns `WinUSBRecAsyncResult`.
|
||||
|
||||
- **`public int EndReceive(IAsyncResult ar)`**
|
||||
Calls `_sliceDev.ReadViaBulkTransfer(...)` in a loop until `bytesRead > 0` or failure. Copies data into `rar.Buffer`. Returns bytes read.
|
||||
|
||||
- **`public IAsyncResult BeginDisconnect(...)`**
|
||||
Validates `_sliceDev != null`. Sets `Connected = false`, returns `WinUSBRecAsyncResult`.
|
||||
|
||||
- **`public void EndDisconnect(IAsyncResult ar)`**
|
||||
Calls `DisposeSliceDev()` to release WinUSB handle.
|
||||
|
||||
- **`public void Dispose()` / `protected virtual void Dispose(bool)`**
|
||||
Implements `IDisposable`. Disposes `_wusbDeviceManagement` and calls `DisposeSliceDev()`. Uses `Mutex _usbConnectionMutex` for thread safety.
|
||||
|
||||
- **`public void Bind(int port)` / `public void Listen(int backlog)` / `public IAsyncResult BeginAccept(...)` / `public IConnection EndAccept(...)`**
|
||||
All throw `NotSupportedException`.
|
||||
|
||||
### `WinUsbDevice` (internal)
|
||||
|
||||
- **`internal const uint DEVICE_SPEED = 1`**
|
||||
Used with `WinUsb_QueryDeviceInformation`.
|
||||
|
||||
- **`internal const byte USB_ENDPOINT_DIRECTION_MASK = 0x80`**
|
||||
Mask to determine endpoint direction (IN/OUT).
|
||||
|
||||
- **`internal enum PolicyType`**
|
||||
Defines WinUSB pipe policies: `ShortPacketTerminate`, `AutoClearStall`, `PipeTransferTimeout`, etc.
|
||||
|
||||
- **`internal enum USBDPipeTypes`**
|
||||
Pipe types: `UsbdPipeTypeControl`, `UsbdPipeTypeIsochronous`, `UsbdPipeTypeBulk`, `UsbdPipeTypeInterrupt`.
|
||||
|
||||
- **`internal enum USBDeviceSpeeds`**
|
||||
Device speeds: `UsbLowSpeed`, `UsbFullSpeed`, `UsbHighSpeed`.
|
||||
|
||||
- **`internal struct USBConfigurationDescriptor`**
|
||||
P/Invoke struct for USB configuration descriptor.
|
||||
|
||||
- **`internal struct USBInterfaceDescriptor`**
|
||||
P/Invoke struct for USB interface descriptor.
|
||||
|
||||
- **`internal struct WinUSBPipeInformation`**
|
||||
P/Invoke struct for pipe info: `PipeTypes`, `PipeId`, `MaximumPacketSize`, `Interval`.
|
||||
|
||||
- **`internal struct WinUSBSetupPacket`**
|
||||
P/Invoke struct for control transfer setup packet.
|
||||
|
||||
- **`internal static extern bool WinUsb_ControlTransfer(...)`**
|
||||
Sends control transfers.
|
||||
|
||||
- **`internal static extern bool WinUsb_Initialize(...)`**
|
||||
Initializes WinUSB interface handle.
|
||||
|
||||
- **`internal static extern bool WinUsb_Free(...)`**
|
||||
Frees WinUSB interface handle.
|
||||
|
||||
- **`internal static extern bool WinUsb_QueryDeviceInformation(...)`**
|
||||
Retrieves device info (e.g., speed) using `DEVICE_SPEED`.
|
||||
|
||||
- **`internal static extern bool WinUsb_QueryInterfaceSettings(...)`**
|
||||
Queries interface settings.
|
||||
|
||||
- **`internal static extern bool WinUsb_QueryPipe(...)`**
|
||||
Queries pipe info.
|
||||
|
||||
- **`internal static extern bool WinUsb_ReadPipe(...)`**
|
||||
Reads from a pipe.
|
||||
|
||||
- **`internal static extern bool WinUsb_WritePipe(...)`**
|
||||
Writes to a pipe.
|
||||
|
||||
- **`internal static extern bool WinUsb_SetPipePolicy(...)`**
|
||||
Sets pipe policy (byte value).
|
||||
**Alias**: `WinUsb_SetPipePolicy1` for `PIPE_TRANSFER_TIMEOUT` (uses `uint` value).
|
||||
|
||||
## 3. Invariants
|
||||
|
||||
- **`Connected` state**
|
||||
- `CDCUSBConnection`: `_Connected` is `true` only when `_comPort.IsOpen == true`.
|
||||
- `WINUSBConnection`: `Connected` is `true` only after `_sliceDev.GetDeviceHandle(...)` and `_sliceDev.InitializeDevice()` both succeed.
|
||||
|
||||
- **`ConnectString` usage**
|
||||
- `CDCUSBConnection`: Used to match registry keys for COM port lookup.
|
||||
- `WINUSBConnection`: Passed to `_sliceDev.GetDeviceHandle(...)` to locate device.
|
||||
|
||||
- **Thread safety**
|
||||
- `WINUSBConnection` uses `_usbConnectionMutex` around `WinUsbDevice` disposal.
|
||||
- `CDCUSBConnection.RegKeys` uses `KEY_LOCK` for lazy initialization.
|
||||
|
||||
- **Asynchronous pattern**
|
||||
- `Begin*` methods queue work to `ThreadPool` via `NetCallbackFix`, which invokes the callback.
|
||||
- `End*` methods perform actual I/O and signal `AsyncWaitHandle.Set()`.
|
||||
|
||||
- **No soft disconnect**
|
||||
Both `CDCUSBConnection` and `WINUSBConnection` have no-op `SoftConnect`/`SoftDisconnect`.
|
||||
|
||||
- **No socket operations**
|
||||
`Bind`, `Listen`, `BeginAccept`, `EndAccept` throw `NotSupportedException` in both classes.
|
||||
|
||||
## 4. Dependencies
|
||||
|
||||
### Imports / External Dependencies
|
||||
- **Windows API**: `winusb.dll` (for `WINUSBConnection` via P/Invoke in `WinUsbDevice`).
|
||||
- **.NET Framework**:
|
||||
- `System.IO.Ports.SerialPort` (for `CDCUSBConnection`).
|
||||
- `System.Threading`, `System.Threading.Tasks`, `System.Runtime.InteropServices`.
|
||||
- `Microsoft.Win32.Registry` (for registry enumeration).
|
||||
- **Internal DTS modules** (from namespace imports):
|
||||
- `DTS.Common.DASResource` (string resources, e.g., `DASResource.Strings.*`).
|
||||
- `DTS.Common.Interface.Connection` (`IConnection` interface).
|
||||
- `DTS.Common.Utilities.Logging` (`APILogger`).
|
||||
- `DTS.Common.USBFramework` (likely contains `DeviceManagement`).
|
||||
- `DTS.Common.Classes.Connection` (likely contains `NotConnectedException`).
|
||||
|
||||
### Dependencies on Other Modules
|
||||
- `WINUSBConnection` depends on `DeviceManagement` and `WinUsbDevice` (defined in same namespace).
|
||||
- `CDCUSBConnection` depends on `DASResource.Strings` for exception messages.
|
||||
|
||||
### Dependencies *by* This Module
|
||||
- `IConnection` interface (consumed by higher layers).
|
||||
- `DeviceManagement` (used by `WINUSBConnection` for device lifecycle management).
|
||||
|
||||
## 5. Gotchas
|
||||
|
||||
- **`Create` recursion**
|
||||
Both `CDCUSBConnection.Create(string)` and `WINUSBConnection.Create(string)` contain commented-out recursive calls (`//Create(connectString); - this is recursive!`). This suggests a historical bug or incomplete refactoring.
|
||||
|
||||
- **`BeginConnect` blocking in `WINUSBConnection`**
|
||||
`WINUSBConnection.BeginConnect` calls `rar.AsyncWaitHandle.WaitOne()` *before returning*, making it effectively synchronous despite being an "Async" pattern. This violates the expected non-blocking behavior of `Begin*` methods.
|
||||
|
||||
- **`EndConnect` in `WINUSBConnection` throws if already connected**
|
||||
`EndConnect` checks `if (_sliceDev != null || Connected)` and throws `NotConnectedException`, but `BeginConnect` already sets `Connected = false` *before* the async work. This is inconsistent and may cause confusion.
|
||||
|
||||
- **`EndReceive` busy-waits**
|
||||
`CDCUSBConnection.EndReceive` and `WINUSBConnection.EndReceive` both use tight loops with `Thread.Sleep(1)` when no data is available. This can cause high CPU usage.
|
||||
|
||||
- **`WinUSB_SetPipePolicy` vs `WinUsb_SetPipePolicy1`**
|
||||
Two separate P/Invoke declarations exist for `WinUsb_SetPipePolicy`, with `WinUsb_SetPipePolicy1` used *only* for `PIPE_TRANSFER_TIMEOUT` (which requires a `uint` instead of `byte`). This is error-prone and not enforced by the API.
|
||||
|
||||
- **`RegKeys` is static and lazily initialized**
|
||||
`CDCUSBConnection.RegKeys` is a static property. If the registry changes after first access, the list will be stale until app restart.
|
||||
|
||||
- **No error propagation in `NetCallbackFix`**
|
||||
Exceptions in `NetCallbackFix` are caught and logged, but the callback is still invoked. This may leave callers expecting an exception to be thrown in `End*`.
|
||||
|
||||
- **`IsSoftDisconnected` always false**
|
||||
Both classes report `IsSoftDisconnected = false`, but the interface contract may expect it to reflect a real state. This could mislead callers.
|
||||
|
||||
- **`GetConnectionData()` returns `""`**
|
||||
Both classes return empty strings. This may indicate incomplete implementation.
|
||||
|
||||
- **`Flags` property unused**
|
||||
`System.Net.Sockets.SocketFlags Flags { get; set; }` is exposed but never used in either class.
|
||||
|
||||
- **`USB_ENDPOINT_DIRECTION_MASK` is internal**
|
||||
While defined, it is not used in the provided source. May be used elsewhere in the codebase.
|
||||
@@ -0,0 +1,35 @@
|
||||
---
|
||||
source_files:
|
||||
- Common/DTS.Common.IConnection/USBConnection/WINUSBConnection/Properties/AssemblyInfo.cs
|
||||
generated_at: "2026-04-16T02:10:04.213580+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "8875c5ea92f3aea7"
|
||||
---
|
||||
|
||||
# Properties
|
||||
|
||||
## 1. Purpose
|
||||
This module is an assembly metadata definition for the `WINUSBConnection` component, part of the `DTS.Common.IConnection` namespace. It does not contain executable logic or implementation code; its sole purpose is to declare assembly-level attributes—such as title, version, and COM visibility settings—that identify and configure the compiled .NET assembly for deployment and interoperation. It serves as a static configuration layer for the WINUSB-based USB communication module within the larger device connectivity framework.
|
||||
|
||||
## 2. Public Interface
|
||||
**No public types, functions, classes, or methods are defined in this file.**
|
||||
This file (`AssemblyInfo.cs`) contains only assembly-level attributes and does not declare any runtime-visible members. All public APIs (e.g., connection handling, USB I/O) reside in other source files (e.g., `WINUSBConnection.cs`, `IConnection.cs`) not included here.
|
||||
|
||||
## 3. Invariants
|
||||
- The assembly is **not visible to COM** (`ComVisible(false)`), meaning external COM clients cannot directly instantiate types from this assembly unless explicitly exposed via other mechanisms (e.g., COM-visible wrapper assemblies).
|
||||
- The assembly version is strictly `1.06.0081` (both `AssemblyVersion` and `AssemblyFileVersion`), enforcing version consistency for binding and deployment.
|
||||
- The GUID `F3C369E6-BFFB-41bc-B8E8-A31094CED447` is reserved for the type library ID (if exposed to COM in the future), and must remain unchanged to preserve type identity across builds.
|
||||
|
||||
## 4. Dependencies
|
||||
- **No runtime dependencies** are declared in this file.
|
||||
- **Build-time dependency**: Requires the .NET Framework (or .NET Standard/Core with compatible attributes) to process `System.Reflection`, `System.Runtime.CompilerServices`, and `System.Runtime.InteropServices`.
|
||||
- **Logical dependency**: This assembly (`WINUSBConnection`) is part of the `DTS.Common.IConnection` hierarchy, implying it implements or references interfaces defined in `DTS.Common.IConnection` (e.g., `IConnection`), though those interfaces are not defined here.
|
||||
|
||||
## 5. Gotchas
|
||||
- **Misleading file location**: The path `Common/DTS.Common.IConnection/USBConnection/WINUSBConnection/Properties/AssemblyInfo.cs` suggests this assembly contains WINUSB-specific logic, but this file *only* defines metadata—no actual USB communication code resides here. Developers must look elsewhere (e.g., `WINUSBConnection.cs`) for implementation.
|
||||
- **Hardcoded version**: Version `1.06.0081` is fixed in source; automated versioning (e.g., via CI) would require modifying this file or overriding via build scripts.
|
||||
- **COM visibility**: `ComVisible(false)` prevents accidental COM exposure, but if COM interop is needed, additional attributes (e.g., `[ComVisible(true)]` on specific types) must be added in *other* files—this file alone does not enable COM support.
|
||||
- **No functional behavior**: This file cannot be tested for correctness beyond verifying attribute values; runtime behavior is entirely absent here.
|
||||
|
||||
None identified beyond the above.
|
||||
Reference in New Issue
Block a user