This commit is contained in:
2026-04-17 14:55:32 -04:00
commit bc3ac1d4c9
18017 changed files with 4371742 additions and 0 deletions

View File

@@ -0,0 +1,128 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>9.0.21022</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{30F9A58B-6808-4C93-A294-7267C3D2E7EB}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>DTS.DASLib.Connection.USBFramework</RootNamespace>
<AssemblyName>HIDFramework</AssemblyName>
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<FileUpgradeFlags>
</FileUpgradeFlags>
<UpgradeBackupLocation>
</UpgradeBackupLocation>
<OldToolsVersion>3.5</OldToolsVersion>
<TargetFrameworkProfile />
<PublishUrl>publish\</PublishUrl>
<Install>true</Install>
<InstallFrom>Disk</InstallFrom>
<UpdateEnabled>false</UpdateEnabled>
<UpdateMode>Foreground</UpdateMode>
<UpdateInterval>7</UpdateInterval>
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
<UpdatePeriodically>false</UpdatePeriodically>
<UpdateRequired>false</UpdateRequired>
<MapFileExtensions>true</MapFileExtensions>
<ApplicationRevision>0</ApplicationRevision>
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
<IsWebBootstrapper>false</IsWebBootstrapper>
<UseApplicationTrust>false</UseApplicationTrust>
<BootstrapperEnabled>true</BootstrapperEnabled>
<SccProjectName>
</SccProjectName>
<SccLocalPath>
</SccLocalPath>
<SccAuxPath>
</SccAuxPath>
<SccProvider>
</SccProvider>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\x86\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DebugType>full</DebugType>
<PlatformTarget>x86</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
<OutputPath>bin\x86\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x86</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\x64\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DebugType>full</DebugType>
<PlatformTarget>x64</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
<OutputPath>bin\x64\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x64</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Windows.Forms" />
</ItemGroup>
<ItemGroup>
<Compile Include="DeviceManagement.cs" />
<Compile Include="DeviceManagementDeclarations.cs" />
<Compile Include="FileIODeclarations.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<BootstrapperPackage Include="Microsoft.Net.Client.3.5">
<Visible>False</Visible>
<ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
<Install>false</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
<Visible>False</Visible>
<ProductName>.NET Framework 3.5 SP1</ProductName>
<Install>true</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Windows.Installer.3.1">
<Visible>False</Visible>
<ProductName>Windows Installer 3.1</ProductName>
<Install>true</Install>
</BootstrapperPackage>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\DTS.Common.Utilities\DTS.Common.Utilities.csproj">
<Project>{d6da1b74-c711-43c2-91b1-1908a8d04dbf}</Project>
<Name>DTS.Common.Utilities</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="Design\DTS.Common.USBFrameworkClassDiagram.cd" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View File

@@ -0,0 +1,33 @@
<?xml version="1.0" encoding="utf-8"?>
<ClassDiagram MajorVersion="1" MinorVersion="1">
<Class Name="DTS.Common.USBFramework.DeviceManagement" Collapsed="true" BaseTypeListCollapsed="true">
<Position X="0.5" Y="0.5" Width="1.5" />
<TypeIdentifier>
<HashCode>AAAAIQAAACAAEBAAAAAAAAAgAAAAAAAAAAAAAAAAACA=</HashCode>
<FileName>DeviceManagement.cs</FileName>
</TypeIdentifier>
<Lollipop Position="0.2" Collapsed="true" />
</Class>
<Class Name="DTS.Common.USBFramework.DeviceManagementDeclarations" Collapsed="true">
<Position X="2.25" Y="0.5" Width="1.5" />
<TypeIdentifier>
<HashCode>ABEIgAAAAAwKACABAAGAAEAABnIgAoAQCEIBgBkIgAA=</HashCode>
<FileName>DeviceManagementDeclarations.cs</FileName>
</TypeIdentifier>
</Class>
<Class Name="DTS.Common.USBFramework.FileIODeclarations" Collapsed="true">
<Position X="2.25" Y="1.5" Width="1.5" />
<TypeIdentifier>
<HashCode>AAQDgAgAAQBAQEAAgAQAgCgAAAAAQAAAAIABCCAgAAQ=</HashCode>
<FileName>FileIODeclarations.cs</FileName>
</TypeIdentifier>
</Class>
<Class Name="DTS.Common.USBFramework.FileIO" Collapsed="true">
<Position X="0.5" Y="1.5" Width="1.5" />
<TypeIdentifier>
<HashCode>AAQAAAAAAAAAAAAAgAQAgCgAAAAAAAAAAAAFACAAAAQ=</HashCode>
<FileName>FileIODeclarations.cs</FileName>
</TypeIdentifier>
</Class>
<Font Name="Segoe UI" Size="9" />
</ClassDiagram>

View File

@@ -0,0 +1,416 @@
using System;
using System.Diagnostics;
using System.Text;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using DTS.Common.Utilities.Logging;
namespace DTS.Common.USBFramework
{
public class DeviceManagement : IDisposable
{
public void Dispose()
{
}
public bool DeviceNameMatch(Message m, string mydevicePathName)
{
// Purpose : Compares two device path names. Used to find out if the device name
// : of a recently attached or removed device matches the name of a
// : device the application is communicating with.
// Accepts : m - a WM_DEVICECHANGE message. A call to RegisterDeviceNotification
// : causes WM_DEVICECHANGE messages to be passed to an OnDeviceChange routine.
// : mydevicePathName - a device pathname returned by SetupDiGetDeviceInterfaceDetail
// : in an SP_DEVICE_INTERFACE_DETAIL_DATA structure.
// Returns : True if the names match, False if not.
var devBroadcastDeviceInterface = new DeviceManagementDeclarations.DEV_BROADCAST_DEVICEINTERFACE_1();
var devBroadcastHeader = new DeviceManagementDeclarations.DEV_BROADCAST_HDR();
// The LParam parameter of Message is a pointer to a DEV_BROADCAST_HDR structure.
Marshal.PtrToStructure(m.LParam, devBroadcastHeader);
if (devBroadcastHeader.dbch_devicetype != DeviceManagementDeclarations.DBT_DEVTYP_DEVICEINTERFACE) return false;
// The dbch_devicetype parameter indicates that the event applies to a device interface.
// So the structure in LParam is actually a DEV_BROADCAST_INTERFACE structure,
// which begins with a DEV_BROADCAST_HDR.
// Obtain the number of characters in dbch_name by subtracting the 28 bytes
// in the other members of the structure and dividing by 2 because there are
// 2 bytes per character.
var stringSize = Convert.ToInt32((devBroadcastHeader.dbch_size - 28) / 2);
// The dbcc_name parameter of DevBroadcastDeviceInterface contains the device name.
// Trim dbcc_name to match the size of the string.
devBroadcastDeviceInterface.dbcc_name = new char[stringSize + 1];
// Marshal data from the unmanaged block pointed to by m.LParam
// to the managed object DevBroadcastDeviceInterface.
Marshal.PtrToStructure(m.LParam, devBroadcastDeviceInterface);
// Store the device name in a String.
var deviceNameString = new string(devBroadcastDeviceInterface.dbcc_name, 0, stringSize);
//Debug.WriteLine("Device Name = " + DeviceNameString);
//Debug.WriteLine("");
// Compare the name of the newly attached device with the name of the device
// the application is accessing (mydevicePathName).
// Set ignorecase True.
if (string.Compare(deviceNameString, mydevicePathName, true) == 0)
{
// The name matches.
return true;
}
// It's a different device.
return false;
}
public bool FindDeviceFromGuid(System.Guid myGuid, ref string[] devicePathName)
{
// Purpose : Uses SetupDi API functions to retrieve the device path name of an
// : attached device that belongs to an interface class.
// Accepts : myGuid - an interface class GUID.
// : devicePathName - a pointer to an array of strings that will contain
// : the device path names of attached devices.
// Returns : True if at least one device is found, False if not.
var lastDevice = false;
var bufferSize = 0;
var myDeviceInterfaceDetailData = new DeviceManagementDeclarations.SP_DEVICE_INTERFACE_DETAIL_DATA();
var myDeviceInterfaceData = new DeviceManagementDeclarations.SP_DEVICE_INTERFACE_DATA();
int result;
var detailDataBuffer = IntPtr.Zero;
// ***
// API function: SetupDiGetClassDevs
// Purpose:
// Retrieves a device information set for a specified group of devices.
// SetupDiEnumDeviceInterfaces uses the device information set.
// Accepts:
// An interface class GUID
// Null to retrieve information for all device instances
// An optional handle to a top-level window (unused here)
// Flags to limit the returned information to currently present devices
// and devices that expose interfaces in the class specified by the GUID.
// Returns:
// A handle to a device information set for the devices.
// ***
var deviceInfoSet = DeviceManagementDeclarations.SetupDiGetClassDevs(ref myGuid,
null,
0,
DeviceManagementDeclarations.DIGCF_PRESENT | DeviceManagementDeclarations.DIGCF_DEVICEINTERFACE);
var deviceFound = false;
var memberIndex = 0;
try
{
do
{
// Begin with 0 and increment through the device information set until
// no more devices are available.
// The cbSize element of the MyDeviceInterfaceData structure must be set to
// the structure's size in bytes.
// The size is 28 bytes for 32-bit code and 32 bits for 64-bit code.
myDeviceInterfaceData.cbSize = Marshal.SizeOf(myDeviceInterfaceData);
// ***
// API function:
// SetupDiEnumDeviceInterfaces()
// Purpose: Retrieves a handle to a SP_DEVICE_INTERFACE_DATA
// structure for a device.
// On return, MyDeviceInterfaceData contains the handle to a
// SP_DEVICE_INTERFACE_DATA structure for a detected device.
// Accepts:
// A DeviceInfoSet returned by SetupDiGetClassDevs.
// An interface class GUID.
// An index to specify a device in a device information set.
// A pointer to a handle to a SP_DEVICE_INTERFACE_DATA structure for a device.
// Returns:
// Non-zero on success, zero on True.
// ***
result = DeviceManagementDeclarations.SetupDiEnumDeviceInterfaces(deviceInfoSet,
IntPtr.Zero,
ref myGuid,
memberIndex,
ref myDeviceInterfaceData);
// Find out if a device information set was retrieved.
if (result == 0)
{
lastDevice = true;
}
else
{
// A device is present.
// ***
// API function:
// SetupDiGetDeviceInterfaceDetail()
// Purpose:
// Retrieves an SP_DEVICE_INTERFACE_DETAIL_DATA structure
// containing information about a device.
// To retrieve the information, call this function twice.
// The first time returns the size of the structure.
// The second time returns a pointer to the data.
// Accepts:
// A DeviceInfoSet returned by SetupDiGetClassDevs
// An SP_DEVICE_INTERFACE_DATA structure returned by SetupDiEnumDeviceInterfaces
// A pointer to an SP_DEVICE_INTERFACE_DETAIL_DATA structure to receive information
// about the specified interface.
// The size of the SP_DEVICE_INTERFACE_DETAIL_DATA structure.
// A pointer to a variable that will receive the returned required size of the
// SP_DEVICE_INTERFACE_DETAIL_DATA structure.
// A pointer to an SP_DEVINFO_DATA structure to receive information about the device.
// Returns:
// Non-zero on success, zero on failure.
// ***
DeviceManagementDeclarations.SetupDiGetDeviceInterfaceDetail(deviceInfoSet,
ref myDeviceInterfaceData,
IntPtr.Zero,
0,
ref bufferSize,
IntPtr.Zero);
// Store the structure's size.
myDeviceInterfaceDetailData.cbSize = Marshal.SizeOf(myDeviceInterfaceDetailData);
// Allocate memory for the MyDeviceInterfaceDetailData Structure using the returned buffer size.
detailDataBuffer = Marshal.AllocHGlobal(bufferSize);
// Store cbSize in the first 4 bytes of the array
if (IS64_BIT_PROCESS)
{
Marshal.WriteInt64(detailDataBuffer,
(IntPtr.Size == 4) ? (4 + Marshal.SystemDefaultCharSize) : 8);
}
else
{
Marshal.WriteInt32(detailDataBuffer,
(IntPtr.Size == 4) ? (4 + Marshal.SystemDefaultCharSize) : 8);
}
// Call SetupDiGetDeviceInterfaceDetail again.
// This time, pass a pointer to DetailDataBuffer
// and the returned required buffer size.
DeviceManagementDeclarations.SetupDiGetDeviceInterfaceDetail(deviceInfoSet,
ref myDeviceInterfaceData,
detailDataBuffer,
bufferSize,
ref bufferSize,
IntPtr.Zero);
// Skip over cbsize (4 bytes) to get the address of the devicePathName.
var pdevicePathName = IS64_BIT_PROCESS ? new IntPtr(detailDataBuffer.ToInt64() + 4) : new IntPtr(detailDataBuffer.ToInt32() + 4);
// Get the String containing the devicePathName.
var singledevicePathName = Marshal.PtrToStringAuto(pdevicePathName);
devicePathName[memberIndex] = singledevicePathName;
// Free the memory allocated previously by AllocHGlobal.
Marshal.FreeHGlobal(detailDataBuffer);
detailDataBuffer = IntPtr.Zero;
deviceFound = true;
}
memberIndex++;
} while (!lastDevice);
}
finally
{
if (detailDataBuffer != IntPtr.Zero)
{
// Free the memory allocated previously by AllocHGlobal.
Marshal.FreeHGlobal(detailDataBuffer);
}
if (deviceInfoSet != IntPtr.Zero)
{
// ***
// API function
// summary
// Frees the memory reserved for the DeviceInfoSet returned by SetupDiGetClassDevs.
// parameters
// DeviceInfoSet returned by SetupDiGetClassDevs.
// returns
// True on success.
// ***
// Trim the array to the number of devices found.
// ***
// API function:
// SetupDiDestroyDeviceInfoList
// Purpose:
// Frees the memory reserved for the DeviceInfoSet returned by SetupDiGetClassDevs.
// Accepts:
// A DeviceInfoSet returned by SetupDiGetClassDevs.
// Returns:
// True on success, False on failure.
// ***
DeviceManagementDeclarations.SetupDiDestroyDeviceInfoList(deviceInfoSet);
}
}
return deviceFound;
}
public bool RegisterForDeviceNotifications(IntPtr formHandle, Guid classGuid, ref IntPtr deviceNotificationHandle)
{
// Purpose : Request to receive a notification when a device is attached or removed.
// Accepts : devicePathName - a handle to a device.
// : formHandle - a handle to the window that will receive device events.
// : classGuid - an interface class GUID.
//
// Returns : True on success, False on failure.
// A DEV_BROADCAST_DEVICEINTERFACE header holds information about the request.
var dbdi = new DeviceManagementDeclarations.DEV_BROADCAST_DEVICEINTERFACE();
// Set the parameters in the DEV_BROADCAST_DEVICEINTERFACE structure.
// Set the size.
var size = Marshal.SizeOf(dbdi);
dbdi.dbcc_size = size;
// Request to receive notifications about a class of devices.
dbdi.dbcc_devicetype = DeviceManagementDeclarations.DBT_DEVTYP_DEVICEINTERFACE;
dbdi.dbcc_reserved = 0;
// Specify the interface class to receive notifications about.
dbdi.dbcc_classguid = classGuid;
dbdi.dbcc_name = "";
// Allocate memory for the buffer that holds the DEV_BROADCAST_DEVICEINTERFACE structure.
var buffer = Marshal.AllocHGlobal(size);
// Copy the DEV_BROADCAST_DEVICEINTERFACE structure to the buffer.
// Set fDeleteOld True to prevent memory leaks.
Marshal.StructureToPtr(dbdi, buffer, true);
// ***
// API function:
// RegisterDeviceNotification
// Purpose:
// Request to receive notification messages when a device in an interface class
// is attached or removed.
// Accepts:
// Aa handle to the window that will receive device events
// A pointer to a DEV_BROADCAST_DEVICEINTERFACE to specify the type of
// device to send notifications for,
// DEVICE_NOTIFY_WINDOW_HANDLE to indicate that Handle is a window handle.
// Returns:
// A device notification handle or NULL on failure.
// ***
deviceNotificationHandle = DeviceManagementDeclarations.RegisterDeviceNotification(formHandle,
buffer,
DeviceManagementDeclarations.DEVICE_NOTIFY_WINDOW_HANDLE);
// Marshal data from the unmanaged block DevBroadcastDeviceInterfaceBuffer to
// the managed object DevBroadcastDeviceInterface
//Marshal.PtrToStructure(buffer, dbdi);
// Free the memory allocated previously by AllocHGlobal.
Marshal.FreeHGlobal(buffer);
// Find out if RegisterDeviceNotification was successful.
if (IS64_BIT_PROCESS)
{
return deviceNotificationHandle.ToInt64() != IntPtr.Zero.ToInt64();
}
return deviceNotificationHandle.ToInt32() != IntPtr.Zero.ToInt32();
}
static readonly bool IS64_BIT_PROCESS = (IntPtr.Size == 8);
public void StopReceivingDeviceNotifications(IntPtr deviceNotificationHandle)
{
// Purpose : Requests to stop receiving notification messages when a device in an
// interface class is attached or removed.
// Accepts : deviceNotificationHandle - a handle returned previously by
// RegisterDeviceNotification
// ***
// API function: UnregisterDeviceNotification
// Purpose: Stop receiving notification messages.
// Accepts: a handle returned previously by RegisterDeviceNotification
// Returns: True on success, False on failure.
// ***
// Ignore failures.
DeviceManagementDeclarations.UnregisterDeviceNotification(deviceNotificationHandle);
}
public bool GetDeviceRegistryProperty(Guid myGuid)
{
const int maxDevLen = 1000;
// Create a HDEVINFO with all present devices.
var deviceInfoSet = DeviceManagementDeclarations.SetupDiGetClassDevs(ref myGuid, // null?
null, // Enumerator
0,
DeviceManagementDeclarations.DIGCF_PRESENT | DeviceManagementDeclarations.DIGCF_ALLCLASSES);
if ((int)deviceInfoSet == FileIODeclarations.INVALID_HANDLE_VALUE)
{
// Insert error handling here.
return false;
}
// Enumerate through all devices in Set.
DeviceManagementDeclarations.SP_DEVINFO_DATA deviceInfoData;
deviceInfoData.cbSize = Marshal.SizeOf(typeof(DeviceManagementDeclarations.SP_DEVINFO_DATA));
for (uint i = 0; DeviceManagementDeclarations.SetupDiEnumDeviceInfo(deviceInfoSet, i, out deviceInfoData); i++)
{
var deviceName = new StringBuilder(maxDevLen);
if (!DeviceManagementDeclarations.SetupDiGetDeviceRegistryPropertyA(deviceInfoSet,
deviceInfoData,
DeviceManagementDeclarations.SPDRP_DRIVER,
0,
deviceName,
maxDevLen,
IntPtr.Zero))
{
//incorrect device name:
DeviceManagementDeclarations.SetupDiDestroyDeviceInfoList(deviceInfoSet);
deviceName = new StringBuilder("");
return false;
}
APILogger.Log(deviceName.ToString());
}
if (DeviceManagementDeclarations.GetLastError() != DeviceManagementDeclarations.NO_ERROR &&
DeviceManagementDeclarations.GetLastError() != DeviceManagementDeclarations.ERROR_NO_MORE_ITEMS)
{
try
{
var theGuid = Guid.Empty;
if (null != myGuid) { theGuid = myGuid; }
var w32 = new System.ComponentModel.Win32Exception(Marshal.GetLastWin32Error());
APILogger.Log("GetDeviceRegistryProperty(", theGuid.ToString(), ") error - ", w32.Message);
}
catch { }
// Insert error handling here.
return false;
}
// Cleanup
DeviceManagementDeclarations.SetupDiDestroyDeviceInfoList(deviceInfoSet);
return true;
}
}
}

View File

@@ -0,0 +1,214 @@
using System;
using System.Text;
using System.Runtime.InteropServices;
namespace DTS.Common.USBFramework
{
public class DeviceManagementDeclarations
{
// API declarations relating to device management (SetupDixxx and
// RegisterDeviceNotification functions).
// ******************************************************************************
// API constants
// ******************************************************************************
// from dbt.h
public const int DBT_DEVICEARRIVAL = 0x8000;
public const int DBT_DEVICEREMOVECOMPLETE = 0x8004;
public const int DBT_DEVTYP_DEVICEINTERFACE = 5;
public const int DBT_DEVTYP_HANDLE = 6;
public const int DEVICE_NOTIFY_ALL_INTERFACE_CLASSES = 4;
public const int DEVICE_NOTIFY_SERVICE_HANDLE = 1;
public const int DEVICE_NOTIFY_WINDOW_HANDLE = 0;
public const int WM_DEVICECHANGE = 0x219;
public const int ERROR_INSUFFICIENT_BUFFER = 122;
public const int NO_ERROR = 0;
public const int ERROR_NO_MORE_ITEMS = 259;
public const int DICS_FLAG_GLOBAL = 1;
public const int DICS_FLAG_CONFIGSPECIFIC = 2;
public const int DICS_FLAG_CONFIGGENERAL = 4;
public const int DIREG_DEV = 1;
public const int DIREG_DRV = 2;
public const int DIREG_BOTH = 4;
public const int SPDRP_FRIENDLYNAME = (0x0000000C);
public const int SPDRP_DEVICEDESC = (0x00000000);
public const int SPDRP_DRIVER = (0x00000009);
// from setupapi.h
public const int DIGCF_PRESENT = 0x00000002;
public const int DIGCF_DEVICEINTERFACE = 0x00000010;
public const int DIGCF_ALLCLASSES = 0x00000004;
// ******************************************************************************
// Structures and classes for API calls, listed alphabetically
// ******************************************************************************
// There are two declarations for the DEV_BROADCAST_DEVICEINTERFACE structure.
// Use this in the call to RegisterDeviceNotification() and
// in checking dbch_devicetype in a DEV_BROADCAST_HDR structure.
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct DEV_BROADCAST_DEVICEINTERFACE
{
public int dbcc_size;
public int dbcc_devicetype;
public int dbcc_reserved;
public Guid dbcc_classguid;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 400)]
public string dbcc_name;
}
// Use this to read the dbcc_name string and classguid.
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public class DEV_BROADCAST_DEVICEINTERFACE_1
{
public int dbcc_size;
public int dbcc_devicetype;
public int dbcc_reserved;
[MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.U1, SizeConst = 16)]
public byte[] dbcc_classguid;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 255)]
public char[] dbcc_name;
}
[StructLayout(LayoutKind.Sequential)]
public class DEV_BROADCAST_HANDLE
{
public int dbch_size;
public int dbch_devicetype;
public int dbch_reserved;
public int dbch_handle;
public int dbch_hdevnotify;
}
[StructLayout(LayoutKind.Sequential)]
public class DEV_BROADCAST_HDR
{
public int dbch_size;
public int dbch_devicetype;
public int dbch_reserved;
}
[StructLayout(LayoutKind.Sequential)]
public struct SP_DEVICE_INTERFACE_DATA
{
public int cbSize;
public System.Guid InterfaceClassGuid;
public int Flags;
public IntPtr Reserved;
}
[StructLayout(LayoutKind.Sequential)]
public struct SP_DEVICE_INTERFACE_DETAIL_DATA
{
public int cbSize;
public string DevicePath;
}
[StructLayout(LayoutKind.Sequential)]
public struct SP_DEVINFO_DATA
{
public int cbSize;
public System.Guid ClassGuid;
public int DevInst;
public int Reserved;
}
[Flags]
public enum RegSAM
{
QueryValue = 0x0001,
SetValue = 0x0002,
CreateSubKey = 0x0004,
EnumerateSubKeys = 0x0008,
Notify = 0x0010,
CreateLink = 0x0020,
WOW64_32Key = 0x0200,
WOW64_64Key = 0x0100,
WOW64_Res = 0x0300,
Read = 0x00020019,
Write = 0x00020006,
Execute = 0x00020019,
AllAccess = 0x000f003f
}
// ******************************************************************************
// API functions, listed alphabetically
// ******************************************************************************
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr RegisterDeviceNotification(IntPtr hRecipient,
IntPtr NotificationFilter,
int Flags);
[DllImport("setupapi.dll")]
public static extern int SetupDiCreateDeviceInfoList(ref System.Guid ClassGuid,
int hwndParent);
[DllImport("setupapi.dll")]
public static extern int SetupDiDestroyDeviceInfoList(IntPtr DeviceInfoSet);
[DllImport("setupapi.dll")]
public static extern int SetupDiEnumDeviceInterfaces(IntPtr DeviceInfoSet,
IntPtr DeviceInfoData,
ref System.Guid InterfaceClassGuid,
int MemberIndex,
ref SP_DEVICE_INTERFACE_DATA DeviceInterfaceData);
[DllImport("setupapi.dll", CharSet = CharSet.Auto)]
public static extern IntPtr SetupDiGetClassDevs(ref System.Guid ClassGuid,
string Enumerator,
int hwndParent,
uint Flags);
[DllImport("setupapi.dll", CharSet = CharSet.Auto)]
public static extern bool SetupDiGetDeviceInterfaceDetail(IntPtr DeviceInfoSet,
ref SP_DEVICE_INTERFACE_DATA DeviceInterfaceData,
IntPtr DeviceInterfaceDetailData,
int DeviceInterfaceDetailDataSize,
ref int RequiredSize,
IntPtr DeviceInfoData);
[DllImport("setupapi.dll", SetLastError = true)]
public static extern bool SetupDiEnumDeviceInfo(IntPtr DeviceInfoSet, uint MemberIndex, out SP_DEVINFO_DATA DeviceInfoData);
[DllImport("setupapi.dll")] //result HDEVINFO
public static extern IntPtr SetupDiGetClassDevsA(ref Guid ClassGuid,
uint Enumerator,
IntPtr hwndParent,
uint Flags);
[DllImport("setupapi.dll")]
public static extern bool SetupDiGetDeviceRegistryPropertyA(IntPtr DeviceInfoSet,
SP_DEVINFO_DATA DeviceInfoData,
uint Property,
uint PropertyRegDataType,
StringBuilder PropertyBuffer,
uint PropertyBufferSize,
IntPtr RequiredSize);
// http://msdn.microsoft.com/en-us/library/ms791236.aspx
[DllImport("setupapi.dll", SetLastError = true)]
public static extern int SetupDiOpenDevRegKey(IntPtr DeviceInfoSet,
ref SP_DEVINFO_DATA DeviceInfoData,
uint Scope,
uint HwProfile,
uint KeyType,
RegSAM samDesired);
[DllImport("Advapi32.dll")]
public static extern uint RegQueryValueEx(int hKey,
string lpValueName,
uint lpReserved, // must be 0
out uint lpType,
ref byte[] lpData,
ref uint lpcbData);
[DllImport("user32.dll")]
public static extern bool UnregisterDeviceNotification(IntPtr Handle);
[DllImport("kernel32.dll")]
public static extern int GetLastError();
}
}

View File

@@ -0,0 +1,123 @@
using System;
using Microsoft.Win32.SafeHandles;
using System.Runtime.InteropServices;
namespace DTS.Common.USBFramework
{
public class FileIODeclarations
{
// API declarations relating to file I/O.
// ******************************************************************************
// API constants
// ******************************************************************************
public const uint GENERIC_READ = 0x80000000;
public const uint GENERIC_WRITE = 0x40000000;
public const uint FILE_SHARE_READ = 0x00000001;
public const uint FILE_SHARE_WRITE = 0x00000002;
public const uint FILE_FLAG_OVERLAPPED = 0x40000000;
public const int INVALID_HANDLE_VALUE = -1;
public const short OPEN_EXISTING = 3;
public const int WAIT_TIMEOUT = 0x102;
public const uint WAIT_OBJECT_0 = 0;
public const uint WAIT_FAILED = 0xFFFFFFFF;
public const uint WAIT_ABANDONED = 0x00000080;
public const int FSCTL_SET_COMPRESSION = 0x9C040;
// ******************************************************************************
// Structures and classes for API calls, listed alphabetically
// ******************************************************************************
[StructLayout(LayoutKind.Sequential)]
public struct OVERLAPPED
{
public int Internal;
public int InternalHigh;
public int Offset;
public int OffsetHigh;
public int hEvent;
}
[StructLayout(LayoutKind.Sequential)]
public struct SECURITY_ATTRIBUTES
{
public int nLength;
public int lpSecurityDescriptor;
public int bInheritHandle;
}
// ******************************************************************************
// API functions, listed alphabetically
// ******************************************************************************
[DllImport("kernel32.dll")]
public static extern int CancelIo(int hFile);
[DllImport("kernel32.dll")]
public static extern int CloseHandle(int hObject);
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
public static extern int CreateEvent(ref SECURITY_ATTRIBUTES SecurityAttributes, int bManualReset, int bInitialState, string lpName);
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
public static extern int CreateFile(string lpFileName,
uint dwDesiredAccess,
uint dwShareMode,
ref SECURITY_ATTRIBUTES lpSecurityAttributes,
int dwCreationDisposition,
uint dwFlagsAndAttributes,
int hTemplateFile);
[DllImport("kernel32.dll")]
public static extern int GetLastError();
[DllImport("kernel32.dll")]
// static public extern int ReadFile(int hFile, ref byte lpBuffer, int nNumberOfBytesToRead, ref int lpNumberOfBytesRead, ref OVERLAPPED lpOverlapped);
public static extern int ReadFile(int hFile, ref byte lpBuffer, int nNumberOfBytesToRead, ref int lpNumberOfBytesRead, int lpOverlapped);
[DllImport("kernel32.dll")]
public static extern uint WaitForSingleObject(int hHandle, int dwMilliseconds);
[DllImport("kernel32.dll")]
public static extern int WriteFile(int hFile, ref byte lpBuffer, int nNumberOfBytesToWrite, ref int lpNumberOfBytesWritten, int lpOverlapped);
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
public static extern int DeviceIoControl(IntPtr hDevice,
int dwIoControlCode,
ref short lpInBuffer,
int nInBufferSize,
IntPtr lpOutBuffer,
int nOutBufferSize,
ref int lpBytesReturned,
IntPtr lpOverlapped);
}
public class FileIO
{
public const short FILE_ATTRIBUTE_NORMAL = 0X80;
public const int FILE_FLAG_OVERLAPPED = 0X40000000;
public const short FILE_SHARE_READ = 0X1;
public const short FILE_SHARE_WRITE = 0X2;
public const uint GENERIC_READ = 0X80000000;
public const uint GENERIC_WRITE = 0X40000000;
public const int INVALID_HANDLE_VALUE = -1;
public const short OPEN_EXISTING = 3;
[StructLayout(LayoutKind.Sequential)]
public struct SECURITY_ATTRIBUTES
{
public int nLength;
public IntPtr lpSecurityDescriptor;
public int bInheritHandle;
}
[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool CloseHandle(SafeFileHandle hObject);
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
public static extern SafeFileHandle CreateFile(string lpFileName, uint dwDesiredAccess, int dwShareMode, ref SECURITY_ATTRIBUTES lpSecurityAttributes, int dwCreationDisposition, int dwFlagsAndAttributes, int hTemplateFile);
}
}

View File

@@ -0,0 +1,633 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
namespace DTS.DASLib.Connection.USBFramework
{
public class HIDevice: IDisposable
{
// Used in error messages.
const string ModuleName = "Hid";
public HIDDeclarations.HIDP_CAPS Capabilities;
public HIDDeclarations.HIDD_ATTRIBUTES DeviceAttributes;
public void Dispose()
{
}
// For viewing results of API calls in debug.write statements:
//static Debugging MyDebugging = new Debugging();
public abstract class DeviceReport
{
// For reports that the device sends to the host.
internal int Result;
// Each DeviceReport class defines a ProtectedRead method for reading a type of report.
// ProtectedRead and Read are declared as Subs rather than as Functions because
// asynchronous reads use a callback method that can access parameters passed by ByRef
// but not Function return values.
protected abstract void ProtectedRead(int readHandle, int hidHandle, int writeHandle,
ref bool myDeviceDetected, ref byte[] readBuffer, ref bool success);
public void Read(int readHandle, int hidHandle, int writeHandle,
ref bool myDeviceDetected, ref byte[] readBuffer, ref bool success)
{
// Purpose : Calls the overridden ProtectedRead routine.
// Enables other classes to override ProtectedRead
// while limiting access as Friend.
// (Directly declaring Write as Friend MustOverride causes the
// compiler warning : "Other languages may permit Friend
// Overridable members to be overridden.")
// Accepts : readHandle - a handle for reading from the device.
// hidHandle - a handle for other device communications.
// myDeviceDetected - tells whether the device is currently
// attached and communicating.
// readBuffer - a byte array to hold the report ID and report data.
// success - read success
{
// Request the report.
ProtectedRead(readHandle, hidHandle, writeHandle, ref myDeviceDetected, ref readBuffer, ref success);
}
}
}
internal class InFeatureReport: DeviceReport
{
// For reading Feature reports.
protected override void ProtectedRead(int readHandle, int hidHandle, int writeHandle, ref bool myDeviceDetected, ref byte[] inFeatureReportBuffer, ref bool success)
{
// Purpose : reads a Feature report from the device.
// Accepts : readHandle - the handle for reading from the device.
// hidHandle - the handle for other device communications.
// myDeviceDetected - tells whether the device is currently attached.
// readBuffer - contains the requested report.
// success - read success
try
{
// ***
// API function: HidD_GetFeature
// Attempts to read a Feature report from the device.
// Requires:
// A handle to a HID
// A pointer to a buffer containing the report ID and report
// The size of the buffer.
// Returns: true on success, false on failure.
// ***
success = HIDDeclarations.HidD_GetFeature(hidHandle, ref inFeatureReportBuffer[0], inFeatureReportBuffer.Length);
}
catch(System.Exception ex)
{
HandleException(ModuleName + ":" + System.Reflection.MethodBase.GetCurrentMethod(), ex);
}
}
}
public class InputReport: DeviceReport
{
// For reading Input reports.
bool ReadyForOverlappedTransfer; // initialize to false
internal void CancelTransfer(int readHandle, int hidHandle)
{
// Purpose : closes open handles to a device.
// Accepts : ReadHandle - the handle for reading from the device.
// HIDHandle - the handle for other device communications.
try
{
// ***
// API function: CancelIo
// Purpose: Cancels a call to ReadFile
// Accepts: the device handle.
// Returns: True on success, False on failure.
// ***
Result = FileIODeclarations.CancelIo(readHandle);
// The failure may have been because the device was removed,
// so close any open handles and
// set myDeviceDetected=False to cause the application to
// look for the device on the next attempt.
if(hidHandle != 0)
{
FileIODeclarations.CloseHandle(hidHandle);
}
if(hidHandle != 0)
{
FileIODeclarations.CloseHandle(readHandle);
}
}
catch(System.Exception ex)
{
HandleException(ModuleName + ":" + System.Reflection.MethodBase.GetCurrentMethod(), ex);
}
}
internal void PrepareForOverlappedTransfer(ref FileIODeclarations.OVERLAPPED hidOverlapped, ref int eventObject)
{
// Purpose : Creates an event object for the overlapped structure used with
// : ReadFile.
// ; Called before the first call to ReadFile.
FileIODeclarations.SECURITY_ATTRIBUTES Security = new FileIODeclarations.SECURITY_ATTRIBUTES();
try
{
// Values for the SECURITY_ATTRIBUTES structure:
Security.lpSecurityDescriptor = 0;
Security.bInheritHandle = System.Convert.ToInt32(true);
Security.nLength = Marshal.SizeOf(Security);
// ***
// API function: CreateEvent
// Purpose: Creates an event object for the overlapped structure used with ReadFile.
// Accepts:
// A security attributes structure.
// Manual Reset = False (The system automatically resets the state to nonsignaled
// after a waiting thread has been released.)
// Initial state = True (signaled)
// An event object name (optional)
// Returns: a handle to the event object
// ***
eventObject = FileIODeclarations.CreateEvent(ref Security, System.Convert.ToInt32(false), System.Convert.ToInt32(true), "");
// Set the members of the overlapped structure.
hidOverlapped.Offset = 0;
hidOverlapped.OffsetHigh = 0;
hidOverlapped.hEvent = eventObject;
ReadyForOverlappedTransfer = true;
}
catch(System.Exception ex)
{
HandleException(ModuleName + ":" + System.Reflection.MethodBase.GetCurrentMethod(), ex);
}
}
protected override void ProtectedRead(int readHandle,
int hidHandle,
int writeHandle,
ref bool myDeviceDetected,
ref byte[] inputReportBuffer,
ref bool success)
{
// Purpose : reads an Input report from the device using interrupt transfers.
// Accepts : readHandle - the handle for reading from the device.
// hidHandle - the handle for other device communications.
// myDeviceDetected - tells whether the device is currently attached.
// readBuffer - contains the requested report.
// success - read success
// FileIOApiDeclarations.OVERLAPPED HIDOverlapped = new HID.FileIOApiDeclarations.OVERLAPPED();
{
int NumberOfBytesRead = 0;
int TotalBytesRead = 0;
long Result = 1;
while(Result != 0 && TotalBytesRead < inputReportBuffer.Length)
{
uint ret = FileIODeclarations.WaitForSingleObject(readHandle, 200);
switch(ret)
{
case FileIODeclarations.WAIT_OBJECT_0:
Result = FileIODeclarations.ReadFile(readHandle,
ref inputReportBuffer[TotalBytesRead],
inputReportBuffer.Length,
ref NumberOfBytesRead,
0);
TotalBytesRead += NumberOfBytesRead;
break;
case FileIODeclarations.WAIT_TIMEOUT:
Result = 0;
break;
case FileIODeclarations.WAIT_ABANDONED:
case FileIODeclarations.WAIT_FAILED:
default:
// throw new SliceRecorder.Recorder.RecorderException("InputReport.ProtectedRead WaitForSingleObject failed");
break;
}
}
if(0 == Result)
{
}
// If it's the first attempt to read, set up the overlapped structure for ReadFile.
if(!ReadyForOverlappedTransfer)
{
// PrepareForOverlappedTransfer(ref HIDOverlapped, ref EventObject);
}
success = Result == 1;
}
}
}
internal class InputReportViaControlTransfer: DeviceReport
{
protected override void ProtectedRead(int readHandle, int hidHandle, int writeHandle, ref bool myDeviceDetected, ref byte[] inputReportBuffer, ref bool success)
{
// Purpose : reads an Input report from the device using a control transfer.
// Accepts : readHandle - the handle for reading from the device.
// hidHandle - the handle for other device communications.
// myDeviceDetected - tells whether the device is currently attached.
// readBuffer - contains the requested report.
// success - read success
try
{
// API function: HidD_GetInputReport
// Purpose: Attempts to read an Input report from the device using a control transfer.
// Supported under Windows XP and later only.
// Requires:
// A handle to a HID
// A pointer to a buffer containing the report ID and report
// The size of the buffer.
// Returns: true on success, false on failure.
success = HIDDeclarations.HidD_GetInputReport(hidHandle, ref inputReportBuffer[0], inputReportBuffer.Length);
}
catch(System.Exception ex)
{
HandleException(ModuleName + ":" + System.Reflection.MethodBase.GetCurrentMethod(), ex);
}
}
}
public abstract class HostReport
{
// For reports the host sends to the device.
// Each report class defines a ProtectedWrite method for writing a type of report.
protected abstract bool ProtectedWrite(int deviceHandle, byte[] reportBuffer);
public bool Write(byte[] reportBuffer, int deviceHandle)
{
bool Success = false;
// Purpose : Calls the overridden ProtectedWrite routine.
// : This method enables other classes to override ProtectedWrite
// : while limiting access as Friend.
// : (Directly declaring Write as Friend MustOverride causes the
// : compiler(warning) "Other languages may permit Friend
// : Overridable members to be overridden.")
// Accepts : reportBuffer - contains the report ID and report data.
// : deviceHandle - handle to the device. '
// Returns : True on success. False on failure.
try
{
Success = ProtectedWrite(deviceHandle, reportBuffer);
}
catch(System.Exception ex)
{
HandleException(ModuleName + ":" + System.Reflection.MethodBase.GetCurrentMethod(), ex);
}
return Success;
}
}
internal class OutFeatureReport: HostReport
{
// For Feature reports the host sends to the device.
protected override bool ProtectedWrite(int hidHandle, byte[] outFeatureReportBuffer)
{
// Purpose : writes a Feature report to the device.
// Accepts : hidHandle - a handle to the device.
// featureReportBuffer - contains the report ID and report to send.
// Returns : True on success. False on failure.
bool Success = false;
try
{
// API function: HidD_SetFeature
// Purpose: Attempts to send a Feature report to the device.
// Accepts:
// A handle to a HID
// A pointer to a buffer containing the report ID and report
// The size of the buffer.
// Returns: true on success, false on failure.
Success = HIDDeclarations.HidD_SetFeature(hidHandle, ref outFeatureReportBuffer[0], outFeatureReportBuffer.Length);
}
catch(System.Exception ex)
{
HandleException(ModuleName + ":" + System.Reflection.MethodBase.GetCurrentMethod(), ex);
}
return Success;
}
}
public class OutputReport: HostReport
{
// For Output reports the host sends to the device.
// Uses interrupt or control transfers depending on the device and OS.
protected override bool ProtectedWrite(int hidHandle, byte[] outputReportBuffer)
{
// Purpose : writes an Output report to the device.
// Accepts : HIDHandle - a handle to the device.
// OutputReportBuffer - contains the report ID and report to send.
// Returns : True on success. False on failure.
int NumberOfBytesWritten = 0;
int Result;
bool Success = false;
try
{
// The host will use an interrupt transfer if the the HID has an interrupt OUT
// endpoint (requires USB 1.1 or later) AND the OS is NOT Windows 98 Gold (original version).
// Otherwise the the host will use a control transfer.
// The application doesn't have to know or care which type of transfer is used.
// Purpose: writes an Output report to the device.
// Accepts:
// A handle returned by CreateFile
// The output report byte length returned by HidP_GetCaps.
// An integer to hold the number of bytes written.
// Returns: True on success, False on failure.
Result = FileIODeclarations.WriteFile(hidHandle, ref outputReportBuffer[0], outputReportBuffer.Length, ref NumberOfBytesWritten, 0);
// Return True on success, False on failure.
Success = (Result == 0) ? false : true;
}
catch(System.Exception ex)
{
HandleException(ModuleName + ":" + System.Reflection.MethodBase.GetCurrentMethod(), ex);
}
return Success;
}
}
internal class OutputReportViaControlTransfer: HostReport
{
protected override bool ProtectedWrite(int hidHandle, byte[] outputReportBuffer)
{
// Purpose : writes an Output report to the device using a control transfer.
// Accepts : hidHandle - a handle to the device.
// outputReportBuffer - contains the report ID and report to send.
// Returns : True on success. False on failure.
bool Success = false;
try
{
// API function: HidD_SetOutputReport
// Purpose:
// Attempts to send an Output report to the device using a control transfer.
// Requires Windows XP or later.
// Accepts:
// A handle to a HID
// A pointer to a buffer containing the report ID and report
// The size of the buffer.
// Returns: true on success, false on failure.
Success = HIDDeclarations.HidD_SetOutputReport(hidHandle, ref outputReportBuffer[0], outputReportBuffer.Length);
}
catch(System.Exception ex)
{
HandleException(ModuleName + ":" + System.Reflection.MethodBase.GetCurrentMethod(), ex);
}
return Success;
}
}
public bool FlushQueue(int hidHandle)
{
// Purpose : Remove any Input reports waiting in the buffer.
// Accepts : hidHandle - a handle to a device.
// Returns : True on success, False on failure.
bool Result = false;
try
{
// ***
// API function: HidD_FlushQueue
// Purpose: Removes any Input reports waiting in the buffer.
// Accepts: a handle to the device.
// Returns: True on success, False on failure.
// ***
Result = HIDDeclarations.HidD_FlushQueue(hidHandle);
//Debug.WriteLine(MyDebugging.ResultOfAPICall("HidD_FlushQueue, ReadHandle"));
//Debug.WriteLine("Result = " + Result.ToString());
}
catch(System.Exception ex)
{
HandleException(ModuleName + ":" + System.Reflection.MethodBase.GetCurrentMethod(), ex);
}
return Result;
}
public HIDDeclarations.HIDP_CAPS GetDeviceCapabilities(int hidHandle)
{
// Purpose : Retrieves a structure with information about a device's capabilities.
// Accepts : HIDHandle - a handle to a device.
// Returns : An HIDP_CAPS structure.
byte[] PreparsedDataBytes = new byte[30];
string PreparsedDataString;
IntPtr PreparsedDataPointer = new IntPtr();
int Result;
bool Success = false;
byte[] ValueCaps = new byte[1024]; // (the array size is a guess)
try
{
// ***
// API function: HidD_GetPreparsedData
// Purpose: retrieves a pointer to a buffer containing information about the device's capabilities.
// HidP_GetCaps and other API functions require a pointer to the buffer.
// Requires:
// A handle returned by CreateFile.
// A pointer to a buffer.
// Returns:
// True on success, False on failure.
// ***
Success = HIDDeclarations.HidD_GetPreparsedData(hidHandle, ref PreparsedDataPointer);
//Debug.WriteLine(MyDebugging.ResultOfAPICall("HidD_GetPreparsedData"));
//Debug.WriteLine("");
// Copy the data at PreparsedDataPointer into a byte array.
PreparsedDataString = System.Convert.ToBase64String(PreparsedDataBytes);
// ***
// API function: HidP_GetCaps
// Purpose: find out a device's capabilities.
// For standard devices such as joysticks, you can find out the specific
// capabilities of the device.
// For a custom device where the software knows what the device is capable of,
// this call may be unneeded.
// Accepts:
// A pointer returned by HidD_GetPreparsedData
// A pointer to a HIDP_CAPS structure.
// Returns: True on success, False on failure.
// ***
Result = HIDDeclarations.HidP_GetCaps(PreparsedDataPointer, ref Capabilities);
if(Result != 0)
{
// ***
// API function: HidP_GetValueCaps
// Purpose: retrieves a buffer containing an array of HidP_ValueCaps structures.
// Each structure defines the capabilities of one value.
// This application doesn't use this data.
// Accepts:
// A report type enumerator from hidpi.h,
// A pointer to a buffer for the returned array,
// The NumberInputValueCaps member of the device's HidP_Caps structure,
// A pointer to the PreparsedData structure returned by HidD_GetPreparsedData.
// Returns: True on success, False on failure.
// ***
Result = HIDDeclarations.HidP_GetValueCaps(HIDDeclarations.HidP_Input, ref ValueCaps[0], ref Capabilities.NumberInputValueCaps, PreparsedDataPointer);
// (To use this data, copy the ValueCaps byte array into an array of structures.)
// ***
// API function: HidD_FreePreparsedData
// Purpose: frees the buffer reserved by HidD_GetPreparsedData.
// Accepts: A pointer to the PreparsedData structure returned by HidD_GetPreparsedData.
// Returns: True on success, False on failure.
// ***
Success = HIDDeclarations.HidD_FreePreparsedData(ref PreparsedDataPointer);
}
}
catch(System.Exception ex)
{
HandleException(ModuleName + ":" + System.Reflection.MethodBase.GetCurrentMethod(), ex);
}
return Capabilities;
}
public string GetHIDUsage(HIDDeclarations.HIDP_CAPS MyCapabilities)
{
//'Purpose : Creates a 32-bit Usage from the Usage Page and Usage ID.
// ' : Determines whether the Usage is a system mouse or keyboard.
// ' : Can be modified to detect other Usages.
//Accepts : MyCapabilities - a HIDP_CAPS structure retrieved with HidP_GetCaps.
//'Returns : A string describing the Usage.
string UsageDescription= "";
try
{
//Create32-bit Usage from Usage Page and Usage ID.
int Usage = MyCapabilities.UsagePage * 256 + MyCapabilities.Usage;
if(Usage == 0x102)
UsageDescription = "mouse";
if(Usage == 0x106)
UsageDescription = "keyboard";
}
catch(System.Exception ex)
{
HandleException(ModuleName + ":" + System.Reflection.MethodBase.GetCurrentMethod(), ex);
}
return UsageDescription;
}
public bool GetNumberOfInputBuffers(int hidDeviceObject, ref int numberOfInputBuffers)
{
// Purpose : Retrieves the number of Input reports the host can store.
// Accepts : hidDeviceObject - a handle to a device
// : numberBuffers - an integer to hold the returned value.
// Returns : True on success, False on failure.
bool Success = false;
try
{
// ***
// API function: HidD_GetNumInputBuffers
// Purpose: retrieves the number of Input reports the host can store.
// Not supported by Windows 98 Gold.
// If the buffer is full and another report arrives, the host drops the
// oldest report.
// Accepts: a handle to a device and an integer to hold the number of buffers.
// Returns: True on success, False on failure.
// ***
Success = HIDDeclarations.HidD_GetNumInputBuffers(hidDeviceObject, ref numberOfInputBuffers);
}
catch(System.Exception ex)
{
HandleException(ModuleName + ":" + System.Reflection.MethodBase.GetCurrentMethod(), ex);
}
return Success;
}
internal bool SetNumberOfInputBuffers(int hidDeviceObject, int numberBuffers)
{
// Purpose : sets the number of input reports the host will store.
// : Requires Windows XP or later.
// Accepts : hidDeviceObject - a handle to the device.
// : numberBuffers - the requested number of input reports.
// Returns : True on success. False on failure.
bool Success = false;
try
{
// ***
// API function: HidD_SetNumInputBuffers
// Purpose: Sets the number of Input reports the host can store.
// If the buffer is full and another report arrives, the host drops the
// oldest report.
// Requires:
// A handle to a HID
// An integer to hold the number of buffers.
// Returns: true on success, false on failure.
// ***
Success = HIDDeclarations.HidD_SetNumInputBuffers(hidDeviceObject, numberBuffers);
}
catch(System.Exception ex)
{
HandleException(ModuleName + ":" + System.Reflection.MethodBase.GetCurrentMethod(), ex);
}
return Success;
}
static public void HandleException(string moduleName, System.Exception e)
{
string Message = "Exception: " + e.Message + Environment.NewLine + "Module: " + moduleName + Environment.NewLine + "Method: " + e.TargetSite.Name;
}
}
}

View File

@@ -0,0 +1,145 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
namespace DTS.DASLib.Connection.USBFramework
{
public sealed class HIDDeclarations
{
// API Declarations for communicating with HID-class devices.
// ******************************************************************************
// API constants
// ******************************************************************************
// from hidpi.h
// Typedef enum defines a set of integer constants for HidP_Report_Type
public const short HidP_Input = 0;
public const short HidP_Output = 1;
public const short HidP_Feature = 2;
// ******************************************************************************
// Structures and classes for API calls, listed alphabetically
// ******************************************************************************
[StructLayout(LayoutKind.Sequential)]
public struct HIDD_ATTRIBUTES
{
public int Size;
public short VendorID;
public short ProductID;
public short VersionNumber;
}
[StructLayout(LayoutKind.Sequential)]
public struct HIDP_CAPS
{
public short Usage;
public short UsagePage;
public short InputReportByteLength;
public short OutputReportByteLength;
public short FeatureReportByteLength;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 17)]
public short[] Reserved;
public short NumberLinkCollectionNodes;
public short NumberInputButtonCaps;
public short NumberInputValueCaps;
public short NumberInputDataIndices;
public short NumberOutputButtonCaps;
public short NumberOutputValueCaps;
public short NumberOutputDataIndices;
public short NumberFeatureButtonCaps;
public short NumberFeatureValueCaps;
public short NumberFeatureDataIndices;
}
// If IsRange is false, UsageMin is the Usage and UsageMax is unused.
// If IsStringRange is false, StringMin is the string index and StringMax is unused.
// If IsDesignatorRange is false, DesignatorMin is the designator index and DesignatorMax is unused.
[StructLayout(LayoutKind.Sequential)]
public struct HidP_Value_Caps
{
public short UsagePage;
public byte ReportID;
public int IsAlias;
public short BitField;
public short LinkCollection;
public short LinkUsage;
public short LinkUsagePage;
public int IsRange;
public int IsStringRange;
public int IsDesignatorRange;
public int IsAbsolute;
public int HasNull;
public byte Reserved;
public short BitSize;
public short ReportCount;
public short Reserved2;
public short Reserved3;
public short Reserved4;
public short Reserved5;
public short Reserved6;
public int LogicalMin;
public int LogicalMax;
public int PhysicalMin;
public int PhysicalMax;
public short UsageMin;
public short UsageMax;
public short StringMin;
public short StringMax;
public short DesignatorMin;
public short DesignatorMax;
public short DataIndexMin;
public short DataIndexMax;
}
// ******************************************************************************
// API functions, listed alphabetically
// ******************************************************************************
[DllImport("hid.dll")]
static public extern bool HidD_FlushQueue(int HidDeviceObject);
[DllImport("hid.dll")]
static public extern bool HidD_FreePreparsedData(ref IntPtr PreparsedData);
[DllImport("hid.dll")]
static public extern int HidD_GetAttributes(int HidDeviceObject, ref HIDD_ATTRIBUTES Attributes);
[DllImport("hid.dll")]
static public extern bool HidD_GetFeature(int HidDeviceObject, ref byte lpReportBuffer, int ReportBufferLength);
[DllImport("hid.dll")]
static public extern bool HidD_GetInputReport(int HidDeviceObject, ref byte lpReportBuffer, int ReportBufferLength);
[DllImport("hid.dll")]
static public extern void HidD_GetHidGuid(ref System.Guid HidGuid);
[DllImport("hid.dll")]
static public extern bool HidD_GetNumInputBuffers(int HidDeviceObject, ref int NumberBuffers);
[DllImport("hid.dll")]
static public extern bool HidD_GetPreparsedData(int HidDeviceObject, ref IntPtr PreparsedData);
[DllImport("hid.dll")]
static public extern bool HidD_SetFeature(int HidDeviceObject, ref byte lpReportBuffer, int ReportBufferLength);
[DllImport("hid.dll")]
static public extern bool HidD_SetNumInputBuffers(int HidDeviceObject, int NumberBuffers);
[DllImport("hid.dll")]
static public extern bool HidD_SetOutputReport(int HidDeviceObject, ref byte lpReportBuffer, int ReportBufferLength);
[DllImport("hid.dll")]
static public extern int HidP_GetCaps(IntPtr PreparsedData, ref HIDP_CAPS Capabilities);
[DllImport("hid.dll")]
static public extern int HidP_GetValueCaps(short ReportType, ref byte ValueCaps, ref short ValueCapsLength, IntPtr PreparsedData);
}
}

View File

@@ -0,0 +1,35 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("HIDFramework")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("HIDFramework")]
[assembly: AssemblyCopyright("Copyright © 2008")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("c655f31f-ca6c-4e9b-9480-934762d20a8c")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
[assembly: AssemblyVersion("1.06.0081")]
[assembly: AssemblyFileVersion("1.06.0081")]

View File

@@ -0,0 +1,4 @@
// <autogenerated />
using System;
using System.Reflection;
[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETFramework,Version=v4.8", FrameworkDisplayName = "")]

View File

@@ -0,0 +1,4 @@
// <autogenerated />
using System;
using System.Reflection;
[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]