First drop from janaxelson.com
authorsl
Wed, 14 May 2014 07:52:21 +0200
changeset 0316364bd7d25
child 1 29c8c6738077
First drop from janaxelson.com
AssemblyInfo.cs
ClassDiagram1.cd
Debugging.cs
DebuggingDeclarations.cs
DeviceManagement.cs
DeviceManagementDeclarations.cs
FileIODeclarations.cs
FrmMain.cs
FrmMain.resX
GenericHid.cs
GenericHid.csproj
GenericHid.csproj.user
Generic_Hid_cs_v62.sln
Hid.cs
HidDeclarations.cs
Properties/Resources.Designer.cs
Properties/Resources.resx
Properties/Settings.Designer.cs
Properties/Settings.settings
app.config
publish/GenericHid.application
readme.txt
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/AssemblyInfo.cs	Wed May 14 07:52:21 2014 +0200
     1.3 @@ -0,0 +1,28 @@
     1.4 +using System.Reflection;
     1.5 +//  General Information about an assembly is controlled through the following
     1.6 +//  set of attributes. Change these attribute values to modify the information
     1.7 +//  associated with an assembly
     1.8 +
     1.9 +[ assembly: AssemblyTitle( "USB test application for HIDs" ) ]
    1.10 +[ assembly: AssemblyDescription( "www.Lvr.com" ) ]
    1.11 +[ assembly: AssemblyCompany( "Lakeview Research" ) ]
    1.12 +[ assembly: AssemblyProduct( "usbhidio" ) ]
    1.13 +[ assembly: AssemblyCopyright( "c. 1999-2005 by Jan Axelson" ) ]
    1.14 +[ assembly: AssemblyTrademark( "" ) ]
    1.15 +[ assembly: AssemblyCulture( "" ) ]
    1.16 +
    1.17 +//  Version information for an assembly consists of the following four values:
    1.18 +
    1.19 +// 	Major version
    1.20 +// 	Minor Version
    1.21 +// 	Revision
    1.22 +// 	Build Number
    1.23 +
    1.24 +//  You can specify all the values or you can default the Revision and Build Numbers
    1.25 +//  by using the '*' as shown below
    1.26 +
    1.27 +
    1.28 +[ assembly: AssemblyVersion( "2.2.*" ) ]
    1.29 +
    1.30 +
    1.31 +
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/ClassDiagram1.cd	Wed May 14 07:52:21 2014 +0200
     2.3 @@ -0,0 +1,65 @@
     2.4 +<?xml version="1.0" encoding="utf-8"?>
     2.5 +<ClassDiagram MajorVersion="1" MinorVersion="1">
     2.6 +  <Class Name="GenericHid.Debugging" Collapsed="true">
     2.7 +    <Position X="0.5" Y="0.5" Width="1.5" />
     2.8 +    <TypeIdentifier>
     2.9 +      <HashCode>AQAAAAAAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAI=</HashCode>
    2.10 +      <FileName>Debugging.cs</FileName>
    2.11 +    </TypeIdentifier>
    2.12 +  </Class>
    2.13 +  <Class Name="GenericHid.DeviceManagement" Collapsed="true">
    2.14 +    <Position X="2.25" Y="0.5" Width="1.5" />
    2.15 +    <TypeIdentifier>
    2.16 +      <HashCode>AAAAIQAAAAACEAABAAEAAEAgBDAgAIAQCEIAgBkAAAA=</HashCode>
    2.17 +      <FileName>DeviceManagement.cs</FileName>
    2.18 +    </TypeIdentifier>
    2.19 +  </Class>
    2.20 +  <Class Name="GenericHid.FileIO" Collapsed="true">
    2.21 +    <Position X="4" Y="0.5" Width="1.5" />
    2.22 +    <TypeIdentifier>
    2.23 +      <HashCode>AAQAAAAAAAAAAAAAgAQAgAgAAAAAAAAAAAABAAAAAAQ=</HashCode>
    2.24 +      <FileName>FileIODeclarations.cs</FileName>
    2.25 +    </TypeIdentifier>
    2.26 +  </Class>
    2.27 +  <Class Name="GenericHid.FrmMain">
    2.28 +    <Position X="0.5" Y="1.5" Width="1.5" />
    2.29 +    <NestedTypes>
    2.30 +      <Delegate Name="GenericHid.FrmMain.MarshalToForm" Collapsed="true">
    2.31 +        <TypeIdentifier>
    2.32 +          <NewMemberFileName>FrmMain.cs</NewMemberFileName>
    2.33 +        </TypeIdentifier>
    2.34 +      </Delegate>
    2.35 +    </NestedTypes>
    2.36 +    <TypeIdentifier>
    2.37 +      <HashCode>ICUA1BAQNaMYBREAgFCQgUIDUERCJwAKCDHCxEEQUEA=</HashCode>
    2.38 +      <FileName>FrmMain.cs</FileName>
    2.39 +    </TypeIdentifier>
    2.40 +  </Class>
    2.41 +  <Class Name="GenericHid.GenericHid" Collapsed="true">
    2.42 +    <Position X="2.25" Y="1.5" Width="1.5" />
    2.43 +    <TypeIdentifier>
    2.44 +      <HashCode>AAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAABAAAAAA=</HashCode>
    2.45 +      <FileName>GenericHid.cs</FileName>
    2.46 +    </TypeIdentifier>
    2.47 +  </Class>
    2.48 +  <Class Name="GenericHid.Hid" Collapsed="true">
    2.49 +    <Position X="4" Y="1.5" Width="1.5" />
    2.50 +    <TypeIdentifier>
    2.51 +      <HashCode>ADSAUARIUAAAgAQAAAAJAFEAAEgAAAAAACgVABgAACE=</HashCode>
    2.52 +      <FileName>Hid.cs</FileName>
    2.53 +    </TypeIdentifier>
    2.54 +  </Class>
    2.55 +  <Class Name="GenericHid.Properties.Resources" Collapsed="true">
    2.56 +    <Position X="0.5" Y="2.5" Width="1.5" />
    2.57 +    <TypeIdentifier>
    2.58 +      <HashCode>AAAAAAAAAAAAAAAAAAABEAAAAQAAAAAAAAAAAAAAAIA=</HashCode>
    2.59 +    </TypeIdentifier>
    2.60 +  </Class>
    2.61 +  <Class Name="GenericHid.Properties.Settings" Collapsed="true">
    2.62 +    <Position X="2.25" Y="2.5" Width="1.5" />
    2.63 +    <TypeIdentifier>
    2.64 +      <HashCode>AAAAAAAAAAAAAAAAAAAAIAAAAAABAAAAAAAAAAAAAAA=</HashCode>
    2.65 +    </TypeIdentifier>
    2.66 +  </Class>
    2.67 +  <Font Name="Tahoma" Size="10" />
    2.68 +</ClassDiagram>
    2.69 \ No newline at end of file
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/Debugging.cs	Wed May 14 07:52:21 2014 +0200
     3.3 @@ -0,0 +1,47 @@
     3.4 +using System;
     3.5 + 
     3.6 +namespace GenericHid
     3.7 +{
     3.8 +	/// <summary>
     3.9 +	/// Used only in Debug.Write statements.
    3.10 +	/// </summary>
    3.11 +	/// 
    3.12 +	internal sealed partial class Debugging
    3.13 +    {         
    3.14 +        ///  <summary>
    3.15 +        ///  Get text that describes the result of an API call.
    3.16 +        ///  </summary>
    3.17 +        ///  
    3.18 +        ///  <param name="functionName"> the name of the API function. </param>
    3.19 +        ///  
    3.20 +        ///  <returns>
    3.21 +        ///  The text.
    3.22 +        ///  </returns>
    3.23 +          
    3.24 +        internal String ResultOfApiCall( String functionName ) 
    3.25 +        {
    3.26 +	        var resultString = new String(Convert.ToChar( 0 ), 129 ); 
    3.27 +            
    3.28 +            // Returns the result code for the last API call.
    3.29 +            
    3.30 +            Int32 resultCode = System.Runtime.InteropServices.Marshal.GetLastWin32Error(); 
    3.31 +            
    3.32 +            // Get the result message that corresponds to the code.
    3.33 +
    3.34 +            Int64 temp = 0;
    3.35 +			Int32 bytes = NativeMethods.FormatMessage(NativeMethods.FormatMessageFromSystem, ref temp, resultCode, 0, resultString, 128, 0); 
    3.36 +            
    3.37 +            // Subtract two characters from the message to strip the CR and LF.
    3.38 +            
    3.39 +            if ( bytes > 2 ) 
    3.40 +            { 
    3.41 +                resultString = resultString.Remove( bytes - 2, 2 ); 
    3.42 +            }             
    3.43 +            // Create the String to return.
    3.44 +
    3.45 +            resultString = Environment.NewLine + functionName + Environment.NewLine + "Result = " + resultString + Environment.NewLine; 
    3.46 +            
    3.47 +            return resultString;             
    3.48 +        }         
    3.49 +    }  
    3.50 +} 
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/DebuggingDeclarations.cs	Wed May 14 07:52:21 2014 +0200
     4.3 @@ -0,0 +1,21 @@
     4.4 +using System;
     4.5 +using System.Runtime.InteropServices; 
     4.6 +
     4.7 +namespace GenericHid
     4.8 +{   
     4.9 +	/// <summary>
    4.10 +	/// Win32 API declarations for Debug.Write statements.
    4.11 +	/// </summary>
    4.12 +	/// 
    4.13 +    internal sealed partial class Debugging  
    4.14 +    {
    4.15 +		internal static class NativeMethods
    4.16 +		{
    4.17 +			internal const Int16 FormatMessageFromSystem = 0X1000;
    4.18 +
    4.19 +			[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    4.20 +			internal static extern Int32 FormatMessage(Int32 dwFlags, ref Int64 lpSource, Int32 dwMessageId, Int32 dwLanguageZId,
    4.21 +			                                           String lpBuffer, Int32 nSize, Int32 arguments);
    4.22 +		}
    4.23 +    } 
    4.24 +} 
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/DeviceManagement.cs	Wed May 14 07:52:21 2014 +0200
     5.3 @@ -0,0 +1,252 @@
     5.4 +using System;
     5.5 +using System.Diagnostics;
     5.6 +using System.Runtime.InteropServices; 
     5.7 +using System.Windows.Forms;
     5.8 +
     5.9 +namespace GenericHid
    5.10 +{
    5.11 +	/// <summary>
    5.12 +	/// Routine for detecting devices using Win32 SetupDi functions.
    5.13 +	/// </summary>
    5.14 +	/// 
    5.15 +	sealed internal partial class DeviceManagement
    5.16 +	{
    5.17 +		private const String ModuleName = "Device Management";
    5.18 +
    5.19 +		///  <summary>
    5.20 +		///  Provides a central mechanism for exception handling.
    5.21 +		///  Displays a message box that describes the exception.
    5.22 +		///  </summary>
    5.23 +		///  
    5.24 +		///  <param name="name"> the module where the exception occurred. </param>
    5.25 +		///  <param name="e"> the exception </param>
    5.26 +
    5.27 +		internal static void DisplayException(String name, Exception e)
    5.28 +		{
    5.29 +			try
    5.30 +			{
    5.31 +				//  Create an error message.
    5.32 +
    5.33 +				String message = "Exception: " + e.Message + Environment.NewLine + "Module: " + name + Environment.NewLine + "Method: " +
    5.34 +						  e.TargetSite.Name;
    5.35 +
    5.36 +				const String caption = "Unexpected Exception";
    5.37 +
    5.38 +				MessageBox.Show(message, caption, MessageBoxButtons.OK);
    5.39 +				Debug.Write(message);
    5.40 +			}
    5.41 +			catch (Exception ex)
    5.42 +			{
    5.43 +				DisplayException(ModuleName, ex);
    5.44 +				throw;
    5.45 +			}
    5.46 +		}
    5.47 +
    5.48 +		///  <summary>
    5.49 +		///  Use SetupDi API functions to retrieve the device path name of an
    5.50 +		///  attached device that belongs to a device interface class.
    5.51 +		///  </summary>
    5.52 +		///  
    5.53 +		///  <param name="myGuid"> an interface class GUID. </param>
    5.54 +		///  <param name="devicePathName"> a pointer to the device path name 
    5.55 +		///  of an attached device. </param>
    5.56 +		///  
    5.57 +		///  <returns>
    5.58 +		///   True if a device is found, False if not. 
    5.59 +		///  </returns>
    5.60 +
    5.61 +		internal Boolean FindDeviceFromGuid(Guid myGuid, ref String[] devicePathName)
    5.62 +		{
    5.63 +			Int32 bufferSize = 0;
    5.64 +			var deviceInfoSet = new IntPtr();
    5.65 +			Boolean lastDevice = false;
    5.66 +			var myDeviceInterfaceData = new NativeMethods.SP_DEVICE_INTERFACE_DATA();
    5.67 +
    5.68 +			try
    5.69 +			{
    5.70 +				Int32 memberIndex;
    5.71 +
    5.72 +				// ***
    5.73 +				//  API function
    5.74 +
    5.75 +				//  summary 
    5.76 +				//  Retrieves a device information set for a specified group of devices.
    5.77 +				//  SetupDiEnumDeviceInterfaces uses the device information set.
    5.78 +
    5.79 +				//  parameters 
    5.80 +				//  Interface class GUID.
    5.81 +				//  Null to retrieve information for all device instances.
    5.82 +				//  Optional handle to a top-level window (unused here).
    5.83 +				//  Flags to limit the returned information to currently present devices 
    5.84 +				//  and devices that expose interfaces in the class specified by the GUID.
    5.85 +
    5.86 +				//  Returns
    5.87 +				//  Handle to a device information set for the devices.
    5.88 +				// ***
    5.89 +
    5.90 +				deviceInfoSet = NativeMethods.SetupDiGetClassDevs(ref myGuid, IntPtr.Zero, IntPtr.Zero, NativeMethods.DIGCF_PRESENT | NativeMethods.DIGCF_DEVICEINTERFACE);
    5.91 +
    5.92 +				bool deviceFound = false;
    5.93 +				memberIndex = 0;
    5.94 +
    5.95 +				// The cbSize element of the MyDeviceInterfaceData structure must be set to
    5.96 +				// the structure's size in bytes. 
    5.97 +				// The size is 28 bytes for 32-bit code and 32 bits for 64-bit code.
    5.98 +
    5.99 +				myDeviceInterfaceData.cbSize = Marshal.SizeOf(myDeviceInterfaceData);
   5.100 +
   5.101 +				do
   5.102 +				{
   5.103 +					// Begin with 0 and increment through the device information set until
   5.104 +					// no more devices are available.
   5.105 +				
   5.106 +					// ***
   5.107 +					//  API function
   5.108 +
   5.109 +					//  summary
   5.110 +					//  Retrieves a handle to a SP_DEVICE_INTERFACE_DATA structure for a device.
   5.111 +					//  On return, MyDeviceInterfaceData contains the handle to a
   5.112 +					//  SP_DEVICE_INTERFACE_DATA structure for a detected device.
   5.113 +
   5.114 +					//  parameters
   5.115 +					//  DeviceInfoSet returned by SetupDiGetClassDevs.
   5.116 +					//  Optional SP_DEVINFO_DATA structure that defines a device instance 
   5.117 +					//  that is a member of a device information set.
   5.118 +					//  Device interface GUID.
   5.119 +					//  Index to specify a device in a device information set.
   5.120 +					//  Pointer to a handle to a SP_DEVICE_INTERFACE_DATA structure for a device.
   5.121 +
   5.122 +					//  Returns
   5.123 +					//  True on success.
   5.124 +					// ***
   5.125 +
   5.126 +					Boolean success = NativeMethods.SetupDiEnumDeviceInterfaces
   5.127 +						(deviceInfoSet,
   5.128 +						 IntPtr.Zero,
   5.129 +						 ref myGuid,
   5.130 +						 memberIndex,
   5.131 +						 ref myDeviceInterfaceData);
   5.132 +
   5.133 +					// Find out if a device information set was retrieved.
   5.134 +
   5.135 +					if (!success)
   5.136 +					{
   5.137 +						lastDevice = true;
   5.138 +					}
   5.139 +					else
   5.140 +					{
   5.141 +						// A device is present.
   5.142 +
   5.143 +						// ***
   5.144 +						//  API function: 
   5.145 +
   5.146 +						//  summary:
   5.147 +						//  Retrieves an SP_DEVICE_INTERFACE_DETAIL_DATA structure
   5.148 +						//  containing information about a device.
   5.149 +						//  To retrieve the information, call this function twice.
   5.150 +						//  The first time returns the size of the structure.
   5.151 +						//  The second time returns a pointer to the data.
   5.152 +
   5.153 +						//  parameters
   5.154 +						//  DeviceInfoSet returned by SetupDiGetClassDevs
   5.155 +						//  SP_DEVICE_INTERFACE_DATA structure returned by SetupDiEnumDeviceInterfaces
   5.156 +						//  A returned pointer to an SP_DEVICE_INTERFACE_DETAIL_DATA 
   5.157 +						//  Structure to receive information about the specified interface.
   5.158 +						//  The size of the SP_DEVICE_INTERFACE_DETAIL_DATA structure.
   5.159 +						//  Pointer to a variable that will receive the returned required size of the 
   5.160 +						//  SP_DEVICE_INTERFACE_DETAIL_DATA structure.
   5.161 +						//  Returned pointer to an SP_DEVINFO_DATA structure to receive information about the device.
   5.162 +
   5.163 +						//  Returns
   5.164 +						//  True on success.
   5.165 +						// ***                     
   5.166 +
   5.167 +						NativeMethods.SetupDiGetDeviceInterfaceDetail
   5.168 +							(deviceInfoSet,
   5.169 +							 ref myDeviceInterfaceData,
   5.170 +							 IntPtr.Zero,
   5.171 +							 0,
   5.172 +							 ref bufferSize,
   5.173 +							 IntPtr.Zero);
   5.174 +
   5.175 +						// Allocate memory for the SP_DEVICE_INTERFACE_DETAIL_DATA structure using the returned buffer size.
   5.176 +
   5.177 +						IntPtr detailDataBuffer = Marshal.AllocHGlobal(bufferSize);
   5.178 +
   5.179 +						// Store cbSize in the first bytes of the array. Adjust for 32- and 64-bit systems.
   5.180 +
   5.181 +                        Int32 cbsize;
   5.182 +
   5.183 +                        if (IntPtr.Size == 4)
   5.184 +                        {
   5.185 +                            cbsize = 4 + Marshal.SystemDefaultCharSize;
   5.186 +                        }
   5.187 +                        else
   5.188 +                        {
   5.189 +                            cbsize = 8;
   5.190 +                        }
   5.191 +
   5.192 +						Marshal.WriteInt32(detailDataBuffer, cbsize);                        
   5.193 +
   5.194 +						// Call SetupDiGetDeviceInterfaceDetail again.
   5.195 +						// This time, pass a pointer to DetailDataBuffer
   5.196 +						// and the returned required buffer size.
   5.197 +
   5.198 +						NativeMethods.SetupDiGetDeviceInterfaceDetail
   5.199 +							(deviceInfoSet,
   5.200 +							 ref myDeviceInterfaceData,
   5.201 +							 detailDataBuffer,
   5.202 +							 bufferSize,
   5.203 +							 ref bufferSize,
   5.204 +							 IntPtr.Zero);
   5.205 +
   5.206 +						// Get the address of the devicePathName.
   5.207 +
   5.208 +						var pDevicePathName = new IntPtr(detailDataBuffer.ToInt64() + 4);
   5.209 +
   5.210 +						// Get the String containing the devicePathName.
   5.211 +
   5.212 +						devicePathName[memberIndex] = Marshal.PtrToStringAuto(pDevicePathName);
   5.213 +
   5.214 +						if (detailDataBuffer != IntPtr.Zero)
   5.215 +						{
   5.216 +							// Free the memory allocated previously by AllocHGlobal.
   5.217 +
   5.218 +							Marshal.FreeHGlobal(detailDataBuffer);
   5.219 +						}
   5.220 +						deviceFound = true;
   5.221 +					}
   5.222 +					memberIndex = memberIndex + 1;
   5.223 +				}
   5.224 +				while (!lastDevice);
   5.225 +
   5.226 +				return deviceFound;
   5.227 +			}
   5.228 +			finally
   5.229 +			{
   5.230 +				// ***
   5.231 +				//  API function
   5.232 +
   5.233 +				//  summary
   5.234 +				//  Frees the memory reserved for the DeviceInfoSet returned by SetupDiGetClassDevs.
   5.235 +
   5.236 +				//  parameters
   5.237 +				//  DeviceInfoSet returned by SetupDiGetClassDevs.
   5.238 +
   5.239 +				//  returns
   5.240 +				//  True on success.
   5.241 +				// ***
   5.242 +
   5.243 +				if (deviceInfoSet != IntPtr.Zero)
   5.244 +				{
   5.245 +					NativeMethods.SetupDiDestroyDeviceInfoList(deviceInfoSet);
   5.246 +				}
   5.247 +			}
   5.248 +		}
   5.249 +	}
   5.250 +}
   5.251 +
   5.252 +
   5.253 +
   5.254 +
   5.255 +
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/DeviceManagementDeclarations.cs	Wed May 14 07:52:21 2014 +0200
     6.3 @@ -0,0 +1,58 @@
     6.4 +using System;
     6.5 +using System.Runtime.InteropServices; 
     6.6 +
     6.7 +namespace GenericHid
     6.8 +{
     6.9 +	internal sealed partial class DeviceManagement
    6.10 +	{
    6.11 +		internal static class NativeMethods
    6.12 +		{
    6.13 +			///<summary >
    6.14 +			// API declarations relating to device management (SetupDixxx and 
    6.15 +			// RegisterDeviceNotification functions).   
    6.16 +			/// </summary>
    6.17 +
    6.18 +			// from setupapi.h
    6.19 +
    6.20 +			internal const Int32 DIGCF_PRESENT = 2;
    6.21 +			internal const Int32 DIGCF_DEVICEINTERFACE = 0X10;
    6.22 +
    6.23 +			internal struct SP_DEVICE_INTERFACE_DATA
    6.24 +			{
    6.25 +				internal Int32 cbSize;
    6.26 +				internal Guid InterfaceClassGuid;
    6.27 +				internal Int32 Flags;
    6.28 +				internal IntPtr Reserved;
    6.29 +			}
    6.30 +
    6.31 +			internal struct SP_DEVICE_INTERFACE_DETAIL_DATA
    6.32 +			{
    6.33 +				internal Int32 cbSize;
    6.34 +				internal String DevicePath;
    6.35 +			}
    6.36 +
    6.37 +			internal struct SP_DEVINFO_DATA
    6.38 +			{
    6.39 +				internal Int32 cbSize;
    6.40 +				internal Guid ClassGuid;
    6.41 +				internal Int32 DevInst;
    6.42 +				internal Int32 Reserved;
    6.43 +			}
    6.44 +
    6.45 +			[DllImport("setupapi.dll", SetLastError = true)]
    6.46 +			internal static extern IntPtr SetupDiCreateDeviceInfoList(ref Guid ClassGuid, IntPtr hwndParent);
    6.47 +
    6.48 +			[DllImport("setupapi.dll", SetLastError = true)]
    6.49 +			internal static extern Int32 SetupDiDestroyDeviceInfoList(IntPtr DeviceInfoSet);
    6.50 +
    6.51 +			[DllImport("setupapi.dll", SetLastError = true)]
    6.52 +			internal static extern Boolean SetupDiEnumDeviceInterfaces(IntPtr DeviceInfoSet, IntPtr DeviceInfoData, ref Guid InterfaceClassGuid, Int32 MemberIndex, ref SP_DEVICE_INTERFACE_DATA DeviceInterfaceData);
    6.53 +
    6.54 +			[DllImport("setupapi.dll", SetLastError = true, CharSet = CharSet.Auto)]
    6.55 +			internal static extern IntPtr SetupDiGetClassDevs(ref Guid ClassGuid, IntPtr Enumerator, IntPtr hwndParent, Int32 Flags);
    6.56 +
    6.57 +			[DllImport("setupapi.dll", SetLastError = true, CharSet = CharSet.Auto)]
    6.58 +			internal static extern Boolean SetupDiGetDeviceInterfaceDetail(IntPtr DeviceInfoSet, ref SP_DEVICE_INTERFACE_DATA DeviceInterfaceData, IntPtr DeviceInterfaceDetailData, Int32 DeviceInterfaceDetailDataSize, ref Int32 RequiredSize, IntPtr DeviceInfoData);
    6.59 +		}
    6.60 +	}
    6.61 +}
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/FileIODeclarations.cs	Wed May 14 07:52:21 2014 +0200
     7.3 @@ -0,0 +1,23 @@
     7.4 +using Microsoft.Win32.SafeHandles; 
     7.5 +using System.Runtime.InteropServices;
     7.6 +using System;
     7.7 +
     7.8 +namespace GenericHid
     7.9 +{
    7.10 +	/// <summary>
    7.11 +	/// Win32 API declarations relating to file I/O.
    7.12 +	/// </summary>
    7.13 +	/// 
    7.14 +	internal sealed class FileIo
    7.15 +	{
    7.16 +		internal const Int32 FileShareRead = 1;
    7.17 +		internal const Int32 FileShareWrite = 2;
    7.18 +		internal const uint GenericRead = 0X80000000U;
    7.19 +		internal const Int32 GenericWrite = 0X40000000;
    7.20 +		internal const Int32 InvalidHandleValue = -1;
    7.21 +		internal const Int32 OpenExisting = 3;
    7.22 +
    7.23 +		[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    7.24 +		internal static extern SafeFileHandle CreateFile(String lpFileName, UInt32 dwDesiredAccess, Int32 dwShareMode, IntPtr lpSecurityAttributes, Int32 dwCreationDisposition, Int32 dwFlagsAndAttributes, IntPtr hTemplateFile);
    7.25 +	}
    7.26 +} 
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/FrmMain.cs	Wed May 14 07:52:21 2014 +0200
     8.3 @@ -0,0 +1,2582 @@
     8.4 +using Microsoft.Win32.SafeHandles;
     8.5 +using System;
     8.6 +using System.Diagnostics;
     8.7 +using System.Globalization;
     8.8 +using System.IO;
     8.9 +using System.Management;
    8.10 +using System.Runtime.InteropServices;
    8.11 +using System.Threading;
    8.12 +using System.Timers;
    8.13 +using System.Windows.Forms;
    8.14 +
    8.15 +namespace GenericHid
    8.16 +{
    8.17 +	///<summary>
    8.18 +	/// Project: GenericHid
    8.19 +	/// 
    8.20 +	/// ***********************************************************************
    8.21 +	/// Software License Agreement
    8.22 +	///
    8.23 +	/// Licensor grants any person obtaining a copy of this software ("You") 
    8.24 +	/// a worldwide, royalty-free, non-exclusive license, for the duration of 
    8.25 +	/// the copyright, free of charge, to store and execute the Software in a 
    8.26 +	/// computer system and to incorporate the Software or any portion of it 
    8.27 +	/// in computer programs You write.   
    8.28 +	/// 
    8.29 +	/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    8.30 +	/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    8.31 +	/// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    8.32 +	/// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    8.33 +	/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    8.34 +	/// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    8.35 +	/// THE SOFTWARE.
    8.36 +	/// ***********************************************************************
    8.37 +	/// 
    8.38 +	/// Author             
    8.39 +	/// Jan Axelson        
    8.40 +	/// 
    8.41 +	/// This software was written using Visual Studio Express 2012 for Windows
    8.42 +	/// Desktop building for the .NET Framework v4.5.
    8.43 +	/// 
    8.44 +	/// Purpose: 
    8.45 +	/// Demonstrates USB communications with a generic HID-class device
    8.46 +	/// 
    8.47 +	/// Requirements:
    8.48 +	/// Windows Vista or later and an attached USB generic Human Interface Device (HID).
    8.49 +	/// (Does not run on Windows XP or earlier because .NET Framework 4.5 will not install on these OSes.) 
    8.50 +	/// 
    8.51 +	/// Description:
    8.52 +	/// Finds an attached device that matches the vendor and product IDs in the form's 
    8.53 +	/// text boxes.
    8.54 +	/// 
    8.55 +	/// Retrieves the device's capabilities.
    8.56 +	/// Sends and requests HID reports.
    8.57 +	/// 
    8.58 +	/// Uses the System.Management class and Windows Management Instrumentation (WMI) to detect 
    8.59 +	/// when a device is attached or removed.
    8.60 +	/// 
    8.61 +	/// A list box displays the data sent and received along with error and status messages.
    8.62 +	/// You can select data to send and 1-time or periodic transfers.
    8.63 +	/// 
    8.64 +	/// You can change the size of the host's Input report buffer and request to use control
    8.65 +	/// transfers only to exchange Input and Output reports.
    8.66 +	/// 
    8.67 +	/// To view additional debugging messages, in the Visual Studio development environment,
    8.68 +	/// from the main menu, select Build > Configuration Manager > Active Solution Configuration 
    8.69 +	/// and select Configuration > Debug and from the main menu, select View > Output.
    8.70 +	/// 
    8.71 +	/// The application uses asynchronous FileStreams to read Input reports and write Output 
    8.72 +	/// reports so the application's main thread doesn't have to wait for the device to retrieve a 
    8.73 +	/// report when the HID driver's buffer is empty or send a report when the device's endpoint is busy. 
    8.74 +	/// 
    8.75 +	/// For code that finds a device and opens handles to it, see the FindTheHid routine in frmMain.cs.
    8.76 +	/// For code that reads from the device, see GetInputReportViaInterruptTransfer, 
    8.77 +	/// GetInputReportViaControlTransfer, and GetFeatureReport in Hid.cs.
    8.78 +	/// For code that writes to the device, see SendInputReportViaInterruptTransfer, 
    8.79 +	/// SendInputReportViaControlTransfer, and SendFeatureReport in Hid.cs.
    8.80 +	/// 
    8.81 +	/// This project includes the following modules:
    8.82 +	/// 
    8.83 +	/// GenericHid.cs - runs the application.
    8.84 +	/// FrmMain.cs - routines specific to the form.
    8.85 +	/// Hid.cs - routines specific to HID communications.
    8.86 +	/// DeviceManagement.cs - routine for obtaining a handle to a device from its GUID.
    8.87 +	/// Debugging.cs - contains a routine for displaying API error messages.
    8.88 +	/// HidDeclarations.cs - Declarations for API functions used by Hid.cs.
    8.89 +	/// FileIODeclarations.cs - Declarations for file-related API functions.
    8.90 +	/// DeviceManagementDeclarations.cs - Declarations for API functions used by DeviceManagement.cs.
    8.91 +	/// DebuggingDeclarations.cs - Declarations for API functions used by Debugging.cs.
    8.92 +	/// 
    8.93 +	/// Companion device firmware for several device CPUs is available from www.Lvr.com/hidpage.htm
    8.94 +	/// You can use any generic HID (not a system mouse or keyboard) that sends and receives reports.
    8.95 +	/// This application will not detect or communicate with non-HID-class devices.
    8.96 +	/// 
    8.97 +	/// For more information about HIDs and USB, and additional example device firmware to use
    8.98 +	/// with this application, visit Lakeview Research at http://Lvr.com 
    8.99 +	/// Send comments, bug reports, etc. to jan@Lvr.com or post on my PORTS forum: http://www.lvr.com/forum 
   8.100 +	/// 
   8.101 +	/// V6.2
   8.102 +	/// 11/12/13
   8.103 +	/// Disabled form buttons when a transfer is in progress.
   8.104 +	/// Other minor edits for clarity and readability.
   8.105 +	/// Will NOT run on Windows XP or earlier, see below.
   8.106 +	/// 
   8.107 +	/// V6.1
   8.108 +	/// 10/28/13
   8.109 +	/// Uses the .NET System.Management class to detect device arrival and removal with WMI instead of Win32 RegisterDeviceNotification.
   8.110 +	/// Other minor edits.
   8.111 +	/// Will NOT run on Windows XP or earlier, see below.
   8.112 +	///  
   8.113 +	/// V6.0
   8.114 +	/// 2/8/13
   8.115 +	/// This version will NOT run on Windows XP or earlier because the code uses .NET Framework 4.5 to support asynchronous FileStreams.
   8.116 +	/// The .NET Framework 4.5 redistributable is compatible with Windows 8, Windows 7 SP1, Windows Server 2008 R2 SP1, 
   8.117 +	/// Windows Server 2008 SP2, Windows Vista SP2, and Windows Vista SP3.
   8.118 +	/// For compatibility, replaced ToInt32 with ToInt64 here:
   8.119 +	/// IntPtr pDevicePathName = new IntPtr(detailDataBuffer.ToInt64() + 4);
   8.120 +	/// and here:
   8.121 +	/// if ((deviceNotificationHandle.ToInt64() == IntPtr.Zero.ToInt64()))
   8.122 +	/// For compatibility if the charset isn't English, added System.Globalization.CultureInfo.InvariantCulture here:
   8.123 +	/// if ((String.Compare(DeviceNameString, mydevicePathName, true, System.Globalization.CultureInfo.InvariantCulture) == 0))
   8.124 +	/// Replaced all Microsoft.VisualBasic namespace code with other .NET equivalents.
   8.125 +	/// Revised user interface for more flexibility.
   8.126 +	/// Moved interrupt-transfer and other HID-specific code to Hid.cs.
   8.127 +	/// Used JetBrains ReSharper to clean up the code: http://www.jetbrains.com/resharper/
   8.128 +	/// 
   8.129 +	/// V5.0
   8.130 +	/// 3/30/11
   8.131 +	/// Replaced ReadFile and WriteFile with FileStreams. Thanks to Joe Dunne and John on my Ports forum for tips on this.
   8.132 +	/// Simplified Hid.cs.
   8.133 +	/// Replaced the form timer with a system timer.
   8.134 +	/// 
   8.135 +	/// V4.6
   8.136 +	/// 1/12/10
   8.137 +	/// Supports Vendor IDs and Product IDs up to FFFFh.
   8.138 +	///
   8.139 +	/// V4.52
   8.140 +	/// 11/10/09
   8.141 +	/// Changed HIDD_ATTRIBUTES to use UInt16
   8.142 +	/// 
   8.143 +	/// V4.51
   8.144 +	/// 2/11/09
   8.145 +	/// Moved Free_ and similar to Finally blocks to ensure they execute.
   8.146 +	/// 
   8.147 +	/// V4.5
   8.148 +	/// 2/9/09
   8.149 +	/// Changes to support 64-bit systems, memory management, and other corrections. 
   8.150 +	/// Big thanks to Peter Nielsen.
   8.151 +	///  
   8.152 +	/// </summary>
   8.153 +
   8.154 +	internal class FrmMain
   8.155 +		: Form
   8.156 +	{
   8.157 +		#region '"Windows Form Designer generated code "'
   8.158 +		public FrmMain()
   8.159 +		//: base()
   8.160 +		{
   8.161 +			// This call is required by the Windows Form Designer.
   8.162 +			InitializeComponent();
   8.163 +		}
   8.164 +		// Form overrides dispose to clean up the component list.
   8.165 +		protected override void Dispose(bool Disposing1)
   8.166 +		{
   8.167 +			if (Disposing1)
   8.168 +			{
   8.169 +				if (components != null)
   8.170 +				{
   8.171 +					components.Dispose();
   8.172 +				}
   8.173 +			}
   8.174 +			base.Dispose(Disposing1);
   8.175 +		}
   8.176 +
   8.177 +		// Required by the Windows Form Designer
   8.178 +		private System.ComponentModel.IContainer components;
   8.179 +		public System.Windows.Forms.ToolTip ToolTip1;
   8.180 +		public System.Windows.Forms.TextBox TxtBytesReceived;
   8.181 +		public System.Windows.Forms.GroupBox FraBytesReceived;
   8.182 +		public System.Windows.Forms.CheckBox ChkAutoincrement;
   8.183 +		public System.Windows.Forms.ComboBox CboByte1;
   8.184 +		public System.Windows.Forms.ComboBox CboByte0;
   8.185 +		public System.Windows.Forms.GroupBox FraBytesToSend;
   8.186 +		public System.Windows.Forms.ListBox LstResults;
   8.187 +		// NOTE: The following procedure is required by the Windows Form Designer
   8.188 +		// It can be modified using the Windows Form Designer.
   8.189 +		// Do not modify it using the code editor.   
   8.190 +		internal System.Windows.Forms.GroupBox fraInputReportBufferSize;
   8.191 +		internal System.Windows.Forms.TextBox txtInputReportBufferSize;
   8.192 +		internal System.Windows.Forms.Button cmdInputReportBufferSize;
   8.193 +		internal System.Windows.Forms.GroupBox fraDeviceIdentifiers;
   8.194 +		internal System.Windows.Forms.Label lblVendorID;
   8.195 +		internal System.Windows.Forms.TextBox txtVendorID;
   8.196 +		internal System.Windows.Forms.Label lblProductID;
   8.197 +		internal System.Windows.Forms.TextBox txtProductID;
   8.198 +		internal System.Windows.Forms.Button cmdFindDevice;
   8.199 +		private Button cmdGetInputReportInterrupt;
   8.200 +		public GroupBox fraInterruptTransfers;
   8.201 +		private Button cmdSendOutputReportControl;
   8.202 +		private Button cmdGetInputReportControl;
   8.203 +		public GroupBox fraControlTransfers;
   8.204 +		private Button cmdGetFeatureReport;
   8.205 +		private Button cmdSendFeatureReport;
   8.206 +		private Button cmdPeriodicTransfers;
   8.207 +		public GroupBox fraSendAndGetContinuous;
   8.208 +		private RadioButton radFeature;
   8.209 +		private RadioButton radInputOutputControl;
   8.210 +		private RadioButton radInputOutputInterrupt;
   8.211 +		private Button cmdSendOutputReportInterrupt;
   8.212 +
   8.213 +		[System.Diagnostics.DebuggerStepThrough()]
   8.214 +		private void InitializeComponent()
   8.215 +		{
   8.216 +			this.components = new System.ComponentModel.Container();
   8.217 +			this.ToolTip1 = new System.Windows.Forms.ToolTip(this.components);
   8.218 +			this.FraBytesReceived = new System.Windows.Forms.GroupBox();
   8.219 +			this.TxtBytesReceived = new System.Windows.Forms.TextBox();
   8.220 +			this.FraBytesToSend = new System.Windows.Forms.GroupBox();
   8.221 +			this.ChkAutoincrement = new System.Windows.Forms.CheckBox();
   8.222 +			this.CboByte1 = new System.Windows.Forms.ComboBox();
   8.223 +			this.CboByte0 = new System.Windows.Forms.ComboBox();
   8.224 +			this.LstResults = new System.Windows.Forms.ListBox();
   8.225 +			this.fraInputReportBufferSize = new System.Windows.Forms.GroupBox();
   8.226 +			this.cmdInputReportBufferSize = new System.Windows.Forms.Button();
   8.227 +			this.txtInputReportBufferSize = new System.Windows.Forms.TextBox();
   8.228 +			this.fraDeviceIdentifiers = new System.Windows.Forms.GroupBox();
   8.229 +			this.txtProductID = new System.Windows.Forms.TextBox();
   8.230 +			this.lblProductID = new System.Windows.Forms.Label();
   8.231 +			this.txtVendorID = new System.Windows.Forms.TextBox();
   8.232 +			this.lblVendorID = new System.Windows.Forms.Label();
   8.233 +			this.cmdFindDevice = new System.Windows.Forms.Button();
   8.234 +			this.cmdSendOutputReportInterrupt = new System.Windows.Forms.Button();
   8.235 +			this.cmdGetInputReportInterrupt = new System.Windows.Forms.Button();
   8.236 +			this.fraInterruptTransfers = new System.Windows.Forms.GroupBox();
   8.237 +			this.cmdPeriodicTransfers = new System.Windows.Forms.Button();
   8.238 +			this.cmdSendOutputReportControl = new System.Windows.Forms.Button();
   8.239 +			this.cmdGetInputReportControl = new System.Windows.Forms.Button();
   8.240 +			this.fraControlTransfers = new System.Windows.Forms.GroupBox();
   8.241 +			this.cmdGetFeatureReport = new System.Windows.Forms.Button();
   8.242 +			this.cmdSendFeatureReport = new System.Windows.Forms.Button();
   8.243 +			this.fraSendAndGetContinuous = new System.Windows.Forms.GroupBox();
   8.244 +			this.radInputOutputInterrupt = new System.Windows.Forms.RadioButton();
   8.245 +			this.radInputOutputControl = new System.Windows.Forms.RadioButton();
   8.246 +			this.radFeature = new System.Windows.Forms.RadioButton();
   8.247 +			this.FraBytesReceived.SuspendLayout();
   8.248 +			this.FraBytesToSend.SuspendLayout();
   8.249 +			this.fraInputReportBufferSize.SuspendLayout();
   8.250 +			this.fraDeviceIdentifiers.SuspendLayout();
   8.251 +			this.fraInterruptTransfers.SuspendLayout();
   8.252 +			this.fraControlTransfers.SuspendLayout();
   8.253 +			this.fraSendAndGetContinuous.SuspendLayout();
   8.254 +			this.SuspendLayout();
   8.255 +			// 
   8.256 +			// fraBytesReceived
   8.257 +			// 
   8.258 +			this.FraBytesReceived.BackColor = System.Drawing.SystemColors.Control;
   8.259 +			this.FraBytesReceived.Controls.Add(this.TxtBytesReceived);
   8.260 +			this.FraBytesReceived.Font = new System.Drawing.Font("Arial", 8F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
   8.261 +			this.FraBytesReceived.ForeColor = System.Drawing.SystemColors.ControlText;
   8.262 +			this.FraBytesReceived.Location = new System.Drawing.Point(16, 272);
   8.263 +			this.FraBytesReceived.Name = "FraBytesReceived";
   8.264 +			this.FraBytesReceived.RightToLeft = System.Windows.Forms.RightToLeft.No;
   8.265 +			this.FraBytesReceived.Size = new System.Drawing.Size(112, 136);
   8.266 +			this.FraBytesReceived.TabIndex = 4;
   8.267 +			this.FraBytesReceived.TabStop = false;
   8.268 +			this.FraBytesReceived.Text = "Bytes Received";
   8.269 +			// 
   8.270 +			// txtBytesReceived
   8.271 +			// 
   8.272 +			this.TxtBytesReceived.AcceptsReturn = true;
   8.273 +			this.TxtBytesReceived.BackColor = System.Drawing.SystemColors.Window;
   8.274 +			this.TxtBytesReceived.Cursor = System.Windows.Forms.Cursors.IBeam;
   8.275 +			this.TxtBytesReceived.Font = new System.Drawing.Font("Arial", 8F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
   8.276 +			this.TxtBytesReceived.ForeColor = System.Drawing.SystemColors.WindowText;
   8.277 +			this.TxtBytesReceived.Location = new System.Drawing.Point(18, 24);
   8.278 +			this.TxtBytesReceived.MaxLength = 0;
   8.279 +			this.TxtBytesReceived.Multiline = true;
   8.280 +			this.TxtBytesReceived.Name = "TxtBytesReceived";
   8.281 +			this.TxtBytesReceived.RightToLeft = System.Windows.Forms.RightToLeft.No;
   8.282 +			this.TxtBytesReceived.Size = new System.Drawing.Size(72, 96);
   8.283 +			this.TxtBytesReceived.TabIndex = 5;
   8.284 +			// 
   8.285 +			// fraBytesToSend
   8.286 +			// 
   8.287 +			this.FraBytesToSend.BackColor = System.Drawing.SystemColors.Control;
   8.288 +			this.FraBytesToSend.Controls.Add(this.ChkAutoincrement);
   8.289 +			this.FraBytesToSend.Controls.Add(this.CboByte1);
   8.290 +			this.FraBytesToSend.Controls.Add(this.CboByte0);
   8.291 +			this.FraBytesToSend.Font = new System.Drawing.Font("Arial", 8F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
   8.292 +			this.FraBytesToSend.ForeColor = System.Drawing.SystemColors.ControlText;
   8.293 +			this.FraBytesToSend.Location = new System.Drawing.Point(16, 128);
   8.294 +			this.FraBytesToSend.Name = "FraBytesToSend";
   8.295 +			this.FraBytesToSend.RightToLeft = System.Windows.Forms.RightToLeft.No;
   8.296 +			this.FraBytesToSend.Size = new System.Drawing.Size(160, 136);
   8.297 +			this.FraBytesToSend.TabIndex = 1;
   8.298 +			this.FraBytesToSend.TabStop = false;
   8.299 +			this.FraBytesToSend.Text = "Bytes to Send";
   8.300 +			// 
   8.301 +			// chkAutoincrement
   8.302 +			// 
   8.303 +			this.ChkAutoincrement.BackColor = System.Drawing.SystemColors.Control;
   8.304 +			this.ChkAutoincrement.Cursor = System.Windows.Forms.Cursors.Default;
   8.305 +			this.ChkAutoincrement.Font = new System.Drawing.Font("Arial", 8F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
   8.306 +			this.ChkAutoincrement.ForeColor = System.Drawing.SystemColors.ControlText;
   8.307 +			this.ChkAutoincrement.Location = new System.Drawing.Point(8, 96);
   8.308 +			this.ChkAutoincrement.Name = "ChkAutoincrement";
   8.309 +			this.ChkAutoincrement.RightToLeft = System.Windows.Forms.RightToLeft.No;
   8.310 +			this.ChkAutoincrement.Size = new System.Drawing.Size(201, 35);
   8.311 +			this.ChkAutoincrement.TabIndex = 6;
   8.312 +			this.ChkAutoincrement.Text = "Autoincrement values";
   8.313 +			this.ChkAutoincrement.UseVisualStyleBackColor = false;
   8.314 +			// 
   8.315 +			// cboByte1
   8.316 +			// 
   8.317 +			this.CboByte1.BackColor = System.Drawing.SystemColors.Window;
   8.318 +			this.CboByte1.Cursor = System.Windows.Forms.Cursors.Default;
   8.319 +			this.CboByte1.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
   8.320 +			this.CboByte1.Font = new System.Drawing.Font("Arial", 8F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
   8.321 +			this.CboByte1.ForeColor = System.Drawing.SystemColors.WindowText;
   8.322 +			this.CboByte1.Location = new System.Drawing.Point(8, 64);
   8.323 +			this.CboByte1.Name = "CboByte1";
   8.324 +			this.CboByte1.RightToLeft = System.Windows.Forms.RightToLeft.No;
   8.325 +			this.CboByte1.Size = new System.Drawing.Size(101, 22);
   8.326 +			this.CboByte1.TabIndex = 3;
   8.327 +			// 
   8.328 +			// cboByte0
   8.329 +			// 
   8.330 +			this.CboByte0.BackColor = System.Drawing.SystemColors.Window;
   8.331 +			this.CboByte0.Cursor = System.Windows.Forms.Cursors.Default;
   8.332 +			this.CboByte0.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
   8.333 +			this.CboByte0.Font = new System.Drawing.Font("Arial", 8F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
   8.334 +			this.CboByte0.ForeColor = System.Drawing.SystemColors.WindowText;
   8.335 +			this.CboByte0.Location = new System.Drawing.Point(8, 24);
   8.336 +			this.CboByte0.Name = "CboByte0";
   8.337 +			this.CboByte0.RightToLeft = System.Windows.Forms.RightToLeft.No;
   8.338 +			this.CboByte0.Size = new System.Drawing.Size(101, 22);
   8.339 +			this.CboByte0.TabIndex = 2;
   8.340 +			// 
   8.341 +			// lstResults
   8.342 +			// 
   8.343 +			this.LstResults.BackColor = System.Drawing.SystemColors.Window;
   8.344 +			this.LstResults.Cursor = System.Windows.Forms.Cursors.Default;
   8.345 +			this.LstResults.Font = new System.Drawing.Font("Arial", 8F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
   8.346 +			this.LstResults.ForeColor = System.Drawing.SystemColors.WindowText;
   8.347 +			this.LstResults.HorizontalScrollbar = true;
   8.348 +			this.LstResults.ItemHeight = 14;
   8.349 +			this.LstResults.Location = new System.Drawing.Point(12, 424);
   8.350 +			this.LstResults.Name = "LstResults";
   8.351 +			this.LstResults.RightToLeft = System.Windows.Forms.RightToLeft.No;
   8.352 +			this.LstResults.Size = new System.Drawing.Size(760, 326);
   8.353 +			this.LstResults.TabIndex = 0;
   8.354 +			// 
   8.355 +			// fraInputReportBufferSize
   8.356 +			// 
   8.357 +			this.fraInputReportBufferSize.Controls.Add(this.cmdInputReportBufferSize);
   8.358 +			this.fraInputReportBufferSize.Controls.Add(this.txtInputReportBufferSize);
   8.359 +			this.fraInputReportBufferSize.Location = new System.Drawing.Point(248, 16);
   8.360 +			this.fraInputReportBufferSize.Name = "fraInputReportBufferSize";
   8.361 +			this.fraInputReportBufferSize.Size = new System.Drawing.Size(208, 96);
   8.362 +			this.fraInputReportBufferSize.TabIndex = 9;
   8.363 +			this.fraInputReportBufferSize.TabStop = false;
   8.364 +			this.fraInputReportBufferSize.Text = "Input Report Buffer Size";
   8.365 +			// 
   8.366 +			// cmdInputReportBufferSize
   8.367 +			// 
   8.368 +			this.cmdInputReportBufferSize.Location = new System.Drawing.Point(96, 32);
   8.369 +			this.cmdInputReportBufferSize.Name = "cmdInputReportBufferSize";
   8.370 +			this.cmdInputReportBufferSize.Size = new System.Drawing.Size(96, 56);
   8.371 +			this.cmdInputReportBufferSize.TabIndex = 1;
   8.372 +			this.cmdInputReportBufferSize.Text = "Change Buffer Size";
   8.373 +			this.cmdInputReportBufferSize.Click += new System.EventHandler(this.cmdInputReportBufferSize_Click);
   8.374 +			// 
   8.375 +			// txtInputReportBufferSize
   8.376 +			// 
   8.377 +			this.txtInputReportBufferSize.Location = new System.Drawing.Point(16, 40);
   8.378 +			this.txtInputReportBufferSize.Name = "txtInputReportBufferSize";
   8.379 +			this.txtInputReportBufferSize.Size = new System.Drawing.Size(56, 20);
   8.380 +			this.txtInputReportBufferSize.TabIndex = 0;
   8.381 +			// 
   8.382 +			// fraDeviceIdentifiers
   8.383 +			// 
   8.384 +			this.fraDeviceIdentifiers.Controls.Add(this.txtProductID);
   8.385 +			this.fraDeviceIdentifiers.Controls.Add(this.lblProductID);
   8.386 +			this.fraDeviceIdentifiers.Controls.Add(this.txtVendorID);
   8.387 +			this.fraDeviceIdentifiers.Controls.Add(this.lblVendorID);
   8.388 +			this.fraDeviceIdentifiers.Location = new System.Drawing.Point(16, 16);
   8.389 +			this.fraDeviceIdentifiers.Name = "fraDeviceIdentifiers";
   8.390 +			this.fraDeviceIdentifiers.Size = new System.Drawing.Size(208, 96);
   8.391 +			this.fraDeviceIdentifiers.TabIndex = 10;
   8.392 +			this.fraDeviceIdentifiers.TabStop = false;
   8.393 +			this.fraDeviceIdentifiers.Text = "Device Identifiers";
   8.394 +			// 
   8.395 +			// txtProductID
   8.396 +			// 
   8.397 +			this.txtProductID.Location = new System.Drawing.Point(120, 56);
   8.398 +			this.txtProductID.Name = "txtProductID";
   8.399 +			this.txtProductID.Size = new System.Drawing.Size(72, 20);
   8.400 +			this.txtProductID.TabIndex = 3;
   8.401 +			this.txtProductID.Text = "1299";
   8.402 +			this.txtProductID.TextChanged += new System.EventHandler(this.txtProductID_TextChanged);
   8.403 +			// 
   8.404 +			// lblProductID
   8.405 +			// 
   8.406 +			this.lblProductID.Location = new System.Drawing.Point(16, 56);
   8.407 +			this.lblProductID.Name = "lblProductID";
   8.408 +			this.lblProductID.Size = new System.Drawing.Size(112, 23);
   8.409 +			this.lblProductID.TabIndex = 2;
   8.410 +			this.lblProductID.Text = "Product ID (hex):";
   8.411 +			// 
   8.412 +			// txtVendorID
   8.413 +			// 
   8.414 +			this.txtVendorID.Location = new System.Drawing.Point(120, 24);
   8.415 +			this.txtVendorID.Name = "txtVendorID";
   8.416 +			this.txtVendorID.Size = new System.Drawing.Size(72, 20);
   8.417 +			this.txtVendorID.TabIndex = 1;
   8.418 +			this.txtVendorID.Text = "0925";
   8.419 +			this.txtVendorID.TextChanged += new System.EventHandler(this.txtVendorID_TextChanged);
   8.420 +			// 
   8.421 +			// lblVendorID
   8.422 +			// 
   8.423 +			this.lblVendorID.Location = new System.Drawing.Point(16, 24);
   8.424 +			this.lblVendorID.Name = "lblVendorID";
   8.425 +			this.lblVendorID.Size = new System.Drawing.Size(112, 23);
   8.426 +			this.lblVendorID.TabIndex = 0;
   8.427 +			this.lblVendorID.Text = "Vendor ID (hex):";
   8.428 +			// 
   8.429 +			// cmdFindDevice
   8.430 +			// 
   8.431 +			this.cmdFindDevice.Location = new System.Drawing.Point(483, 37);
   8.432 +			this.cmdFindDevice.Name = "cmdFindDevice";
   8.433 +			this.cmdFindDevice.Size = new System.Drawing.Size(136, 55);
   8.434 +			this.cmdFindDevice.TabIndex = 11;
   8.435 +			this.cmdFindDevice.Text = "Find My Device";
   8.436 +			this.cmdFindDevice.Click += new System.EventHandler(this.cmdFindDevice_Click);
   8.437 +			// 
   8.438 +			// cmdSendOutputReportInterrupt
   8.439 +			// 
   8.440 +			this.cmdSendOutputReportInterrupt.Location = new System.Drawing.Point(10, 27);
   8.441 +			this.cmdSendOutputReportInterrupt.Name = "cmdSendOutputReportInterrupt";
   8.442 +			this.cmdSendOutputReportInterrupt.Size = new System.Drawing.Size(118, 50);
   8.443 +			this.cmdSendOutputReportInterrupt.TabIndex = 12;
   8.444 +			this.cmdSendOutputReportInterrupt.Text = "Send Output Report";
   8.445 +			this.cmdSendOutputReportInterrupt.UseVisualStyleBackColor = true;
   8.446 +			this.cmdSendOutputReportInterrupt.Click += new System.EventHandler(this.cmdSendOutputReportInterrupt_Click);
   8.447 +			// 
   8.448 +			// cmdGetInputReportInterrupt
   8.449 +			// 
   8.450 +			this.cmdGetInputReportInterrupt.Location = new System.Drawing.Point(10, 83);
   8.451 +			this.cmdGetInputReportInterrupt.Name = "cmdGetInputReportInterrupt";
   8.452 +			this.cmdGetInputReportInterrupt.Size = new System.Drawing.Size(118, 50);
   8.453 +			this.cmdGetInputReportInterrupt.TabIndex = 13;
   8.454 +			this.cmdGetInputReportInterrupt.Text = "Get Input Report";
   8.455 +			this.cmdGetInputReportInterrupt.UseVisualStyleBackColor = true;
   8.456 +			this.cmdGetInputReportInterrupt.Click += new System.EventHandler(this.cmdGetInputReportInterrupt_Click);
   8.457 +			// 
   8.458 +			// fraInterruptTransfers
   8.459 +			// 
   8.460 +			this.fraInterruptTransfers.BackColor = System.Drawing.SystemColors.Control;
   8.461 +			this.fraInterruptTransfers.Controls.Add(this.cmdSendOutputReportInterrupt);
   8.462 +			this.fraInterruptTransfers.Controls.Add(this.cmdGetInputReportInterrupt);
   8.463 +			this.fraInterruptTransfers.Font = new System.Drawing.Font("Arial", 8F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
   8.464 +			this.fraInterruptTransfers.ForeColor = System.Drawing.SystemColors.ControlText;
   8.465 +			this.fraInterruptTransfers.Location = new System.Drawing.Point(194, 128);
   8.466 +			this.fraInterruptTransfers.Name = "fraInterruptTransfers";
   8.467 +			this.fraInterruptTransfers.RightToLeft = System.Windows.Forms.RightToLeft.No;
   8.468 +			this.fraInterruptTransfers.Size = new System.Drawing.Size(145, 152);
   8.469 +			this.fraInterruptTransfers.TabIndex = 14;
   8.470 +			this.fraInterruptTransfers.TabStop = false;
   8.471 +			this.fraInterruptTransfers.Text = "Interrupt Transfers";
   8.472 +			// 
   8.473 +			// cmdPeriodicTransfers
   8.474 +			// 
   8.475 +			this.cmdPeriodicTransfers.Location = new System.Drawing.Point(153, 36);
   8.476 +			this.cmdPeriodicTransfers.Name = "cmdPeriodicTransfers";
   8.477 +			this.cmdPeriodicTransfers.Size = new System.Drawing.Size(118, 51);
   8.478 +			this.cmdPeriodicTransfers.TabIndex = 16;
   8.479 +			this.cmdPeriodicTransfers.Text = "Start";
   8.480 +			this.cmdPeriodicTransfers.UseVisualStyleBackColor = true;
   8.481 +			this.cmdPeriodicTransfers.Click += new System.EventHandler(this.cmdPeriodicTransfers_Click);
   8.482 +			// 
   8.483 +			// cmdSendOutputReportControl
   8.484 +			// 
   8.485 +			this.cmdSendOutputReportControl.Location = new System.Drawing.Point(10, 27);
   8.486 +			this.cmdSendOutputReportControl.Name = "cmdSendOutputReportControl";
   8.487 +			this.cmdSendOutputReportControl.Size = new System.Drawing.Size(118, 50);
   8.488 +			this.cmdSendOutputReportControl.TabIndex = 12;
   8.489 +			this.cmdSendOutputReportControl.Text = "Send Output Report";
   8.490 +			this.cmdSendOutputReportControl.UseVisualStyleBackColor = true;
   8.491 +			this.cmdSendOutputReportControl.Click += new System.EventHandler(this.cmdSendOutputReportControl_Click);
   8.492 +			// 
   8.493 +			// cmdGetInputReportControl
   8.494 +			// 
   8.495 +			this.cmdGetInputReportControl.Location = new System.Drawing.Point(10, 83);
   8.496 +			this.cmdGetInputReportControl.Name = "cmdGetInputReportControl";
   8.497 +			this.cmdGetInputReportControl.Size = new System.Drawing.Size(118, 50);
   8.498 +			this.cmdGetInputReportControl.TabIndex = 13;
   8.499 +			this.cmdGetInputReportControl.Text = "Get Input Report";
   8.500 +			this.cmdGetInputReportControl.UseVisualStyleBackColor = true;
   8.501 +			this.cmdGetInputReportControl.Click += new System.EventHandler(this.cmdGetInputReportControl_Click);
   8.502 +			// 
   8.503 +			// fraControlTransfers
   8.504 +			// 
   8.505 +			this.fraControlTransfers.BackColor = System.Drawing.SystemColors.Control;
   8.506 +			this.fraControlTransfers.Controls.Add(this.cmdGetFeatureReport);
   8.507 +			this.fraControlTransfers.Controls.Add(this.cmdSendFeatureReport);
   8.508 +			this.fraControlTransfers.Controls.Add(this.cmdSendOutputReportControl);
   8.509 +			this.fraControlTransfers.Controls.Add(this.cmdGetInputReportControl);
   8.510 +			this.fraControlTransfers.Font = new System.Drawing.Font("Arial", 8F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
   8.511 +			this.fraControlTransfers.ForeColor = System.Drawing.SystemColors.ControlText;
   8.512 +			this.fraControlTransfers.Location = new System.Drawing.Point(359, 128);
   8.513 +			this.fraControlTransfers.Name = "fraControlTransfers";
   8.514 +			this.fraControlTransfers.RightToLeft = System.Windows.Forms.RightToLeft.No;
   8.515 +			this.fraControlTransfers.Size = new System.Drawing.Size(277, 152);
   8.516 +			this.fraControlTransfers.TabIndex = 15;
   8.517 +			this.fraControlTransfers.TabStop = false;
   8.518 +			this.fraControlTransfers.Text = "Control Transfers";
   8.519 +			// 
   8.520 +			// cmdGetFeatureReport
   8.521 +			// 
   8.522 +			this.cmdGetFeatureReport.Location = new System.Drawing.Point(141, 83);
   8.523 +			this.cmdGetFeatureReport.Name = "cmdGetFeatureReport";
   8.524 +			this.cmdGetFeatureReport.Size = new System.Drawing.Size(118, 50);
   8.525 +			this.cmdGetFeatureReport.TabIndex = 15;
   8.526 +			this.cmdGetFeatureReport.Text = "Get Feature Report";
   8.527 +			this.cmdGetFeatureReport.UseVisualStyleBackColor = true;
   8.528 +			this.cmdGetFeatureReport.Click += new System.EventHandler(this.cmdGetFeatureReport_Click);
   8.529 +			// 
   8.530 +			// cmdSendFeatureReport
   8.531 +			// 
   8.532 +			this.cmdSendFeatureReport.Location = new System.Drawing.Point(141, 27);
   8.533 +			this.cmdSendFeatureReport.Name = "cmdSendFeatureReport";
   8.534 +			this.cmdSendFeatureReport.Size = new System.Drawing.Size(118, 50);
   8.535 +			this.cmdSendFeatureReport.TabIndex = 14;
   8.536 +			this.cmdSendFeatureReport.Text = "Send Feature Report";
   8.537 +			this.cmdSendFeatureReport.UseVisualStyleBackColor = true;
   8.538 +			this.cmdSendFeatureReport.Click += new System.EventHandler(this.cmdSendFeatureReport_Click);
   8.539 +			// 
   8.540 +			// fraSendAndGetContinuous
   8.541 +			// 
   8.542 +			this.fraSendAndGetContinuous.BackColor = System.Drawing.SystemColors.Control;
   8.543 +			this.fraSendAndGetContinuous.Controls.Add(this.radFeature);
   8.544 +			this.fraSendAndGetContinuous.Controls.Add(this.radInputOutputControl);
   8.545 +			this.fraSendAndGetContinuous.Controls.Add(this.radInputOutputInterrupt);
   8.546 +			this.fraSendAndGetContinuous.Controls.Add(this.cmdPeriodicTransfers);
   8.547 +			this.fraSendAndGetContinuous.Font = new System.Drawing.Font("Arial", 8F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
   8.548 +			this.fraSendAndGetContinuous.ForeColor = System.Drawing.SystemColors.ControlText;
   8.549 +			this.fraSendAndGetContinuous.Location = new System.Drawing.Point(194, 296);
   8.550 +			this.fraSendAndGetContinuous.Name = "fraSendAndGetContinuous";
   8.551 +			this.fraSendAndGetContinuous.RightToLeft = System.Windows.Forms.RightToLeft.No;
   8.552 +			this.fraSendAndGetContinuous.Size = new System.Drawing.Size(295, 112);
   8.553 +			this.fraSendAndGetContinuous.TabIndex = 17;
   8.554 +			this.fraSendAndGetContinuous.TabStop = false;
   8.555 +			this.fraSendAndGetContinuous.Text = "Send and Get Continuous";
   8.556 +			// 
   8.557 +			// radInputOutputInterrupt
   8.558 +			// 
   8.559 +			this.radInputOutputInterrupt.AutoSize = true;
   8.560 +			this.radInputOutputInterrupt.Location = new System.Drawing.Point(17, 28);
   8.561 +			this.radInputOutputInterrupt.Name = "radInputOutputInterrupt";
   8.562 +			this.radInputOutputInterrupt.Size = new System.Drawing.Size(126, 18);
   8.563 +			this.radInputOutputInterrupt.TabIndex = 17;
   8.564 +			this.radInputOutputInterrupt.TabStop = true;
   8.565 +			this.radInputOutputInterrupt.Text = "Input Output Interrupt";
   8.566 +			this.radInputOutputInterrupt.UseVisualStyleBackColor = true;
   8.567 +			this.radInputOutputInterrupt.CheckedChanged += new System.EventHandler(this.radInputOutputInterrupt_CheckedChanged);
   8.568 +			// 
   8.569 +			// radInputOutputControl
   8.570 +			// 
   8.571 +			this.radInputOutputControl.AutoSize = true;
   8.572 +			this.radInputOutputControl.Location = new System.Drawing.Point(17, 52);
   8.573 +			this.radInputOutputControl.Name = "radInputOutputControl";
   8.574 +			this.radInputOutputControl.Size = new System.Drawing.Size(120, 18);
   8.575 +			this.radInputOutputControl.TabIndex = 18;
   8.576 +			this.radInputOutputControl.TabStop = true;
   8.577 +			this.radInputOutputControl.Text = "Input Output Control";
   8.578 +			this.radInputOutputControl.UseVisualStyleBackColor = true;
   8.579 +			this.radInputOutputControl.CheckedChanged += new System.EventHandler(this.radInputOutputControl_CheckedChanged);
   8.580 +			// 
   8.581 +			// radFeature
   8.582 +			// 
   8.583 +			this.radFeature.AutoSize = true;
   8.584 +			this.radFeature.Location = new System.Drawing.Point(17, 76);
   8.585 +			this.radFeature.Name = "radFeature";
   8.586 +			this.radFeature.Size = new System.Drawing.Size(62, 18);
   8.587 +			this.radFeature.TabIndex = 19;
   8.588 +			this.radFeature.TabStop = true;
   8.589 +			this.radFeature.Text = "Feature";
   8.590 +			this.radFeature.UseVisualStyleBackColor = true;
   8.591 +			this.radFeature.CheckedChanged += new System.EventHandler(this.radFeature_CheckedChanged);
   8.592 +			// 
   8.593 +			// FrmMain
   8.594 +			// 
   8.595 +			this.ClientSize = new System.Drawing.Size(784, 756);
   8.596 +			this.Controls.Add(this.fraSendAndGetContinuous);
   8.597 +			this.Controls.Add(this.fraControlTransfers);
   8.598 +			this.Controls.Add(this.fraInterruptTransfers);
   8.599 +			this.Controls.Add(this.cmdFindDevice);
   8.600 +			this.Controls.Add(this.fraDeviceIdentifiers);
   8.601 +			this.Controls.Add(this.fraInputReportBufferSize);
   8.602 +			this.Controls.Add(this.FraBytesReceived);
   8.603 +			this.Controls.Add(this.FraBytesToSend);
   8.604 +			this.Controls.Add(this.LstResults);
   8.605 +			this.Font = new System.Drawing.Font("Arial", 8F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
   8.606 +			this.Location = new System.Drawing.Point(21, 28);
   8.607 +			this.Name = "FrmMain";
   8.608 +			this.StartPosition = System.Windows.Forms.FormStartPosition.Manual;
   8.609 +			this.Text = "Generic HID Tester";
   8.610 +			this.Closed += new System.EventHandler(this.frmMain_Closed);
   8.611 +			this.Load += new System.EventHandler(this.frmMain_Load);
   8.612 +			this.FraBytesReceived.ResumeLayout(false);
   8.613 +			this.FraBytesReceived.PerformLayout();
   8.614 +			this.FraBytesToSend.ResumeLayout(false);
   8.615 +			this.fraInputReportBufferSize.ResumeLayout(false);
   8.616 +			this.fraInputReportBufferSize.PerformLayout();
   8.617 +			this.fraDeviceIdentifiers.ResumeLayout(false);
   8.618 +			this.fraDeviceIdentifiers.PerformLayout();
   8.619 +			this.fraInterruptTransfers.ResumeLayout(false);
   8.620 +			this.fraControlTransfers.ResumeLayout(false);
   8.621 +			this.fraSendAndGetContinuous.ResumeLayout(false);
   8.622 +			this.fraSendAndGetContinuous.PerformLayout();
   8.623 +			this.ResumeLayout(false);
   8.624 +
   8.625 +		}
   8.626 +		#endregion
   8.627 +
   8.628 +		private Boolean _deviceDetected;
   8.629 +		private IntPtr _deviceNotificationHandle;
   8.630 +		private FileStream _deviceData;
   8.631 +		private FormActions _formActions;
   8.632 +		private SafeFileHandle _hidHandle;
   8.633 +		private String _hidUsage;
   8.634 +		private ManagementEventWatcher _deviceArrivedWatcher;
   8.635 +		private Boolean _deviceHandleObtained;
   8.636 +		private ManagementEventWatcher _deviceRemovedWatcher;
   8.637 +		private Int32 _myProductId;
   8.638 +		private Int32 _myVendorId;
   8.639 +		private Boolean _periodicTransfersRequested;
   8.640 +		private ReportReadOrWritten _readOrWritten;
   8.641 +		private ReportTypes _reportType;
   8.642 +		private SendOrGet _sendOrGet;
   8.643 +		private Boolean _transferInProgress;
   8.644 +		private TransferTypes _transferType;
   8.645 +
   8.646 +		private static System.Timers.Timer _periodicTransfers;
   8.647 +
   8.648 +		private readonly Debugging _myDebugging = new Debugging(); //  For viewing results of API calls via Debug.Write.
   8.649 +		private readonly DeviceManagement _myDeviceManagement = new DeviceManagement();
   8.650 +		private Hid _myHid = new Hid();
   8.651 +
   8.652 +		private enum FormActions
   8.653 +		{
   8.654 +			AddItemToListBox,
   8.655 +			DisableInputReportBufferSize,
   8.656 +			EnableGetInputReportInterruptTransfer,
   8.657 +			EnableInputReportBufferSize,
   8.658 +			EnableSendOutputReportInterrupt,
   8.659 +			ScrollToBottomOfListBox,
   8.660 +			SetInputReportBufferSize
   8.661 +		}
   8.662 +
   8.663 +		private enum ReportReadOrWritten
   8.664 +		{
   8.665 +			Read,
   8.666 +			Written
   8.667 +		}
   8.668 +
   8.669 +		private enum ReportTypes
   8.670 +		{
   8.671 +			Input,
   8.672 +			Output,
   8.673 +			Feature
   8.674 +		}
   8.675 +
   8.676 +		private enum SendOrGet
   8.677 +		{
   8.678 +			Send,
   8.679 +			Get
   8.680 +		}
   8.681 +
   8.682 +		private enum TransferTypes
   8.683 +		{
   8.684 +			Control,
   8.685 +			Interrupt
   8.686 +		}
   8.687 +
   8.688 +		private enum WmiDeviceProperties
   8.689 +		{
   8.690 +			Name,
   8.691 +			Caption,
   8.692 +			Description,
   8.693 +			Manufacturer,
   8.694 +			PNPDeviceID,
   8.695 +			DeviceID,
   8.696 +			ClassGUID
   8.697 +		}
   8.698 +
   8.699 +		internal FrmMain FrmMy;
   8.700 +
   8.701 +		//  This delegate has the same parameters as AccessForm.
   8.702 +		//  Used in accessing the application's form from a different thread.
   8.703 +
   8.704 +		private delegate void MarshalDataToForm(FormActions action, String textToAdd);
   8.705 +
   8.706 +		///  <summary>
   8.707 +		///  Performs various application-specific functions that
   8.708 +		///  involve accessing the application's form.
   8.709 +		///  </summary>
   8.710 +		///  
   8.711 +		///  <param name="action"> a FormActions member that names the action to perform on the form</param>
   8.712 +		///  <param name="formText"> text that the form displays or the code uses for 
   8.713 +		///  another purpose. Actions that don't use text ignore this parameter. </param>
   8.714 +
   8.715 +		private void AccessForm(FormActions action, String formText)
   8.716 +		{
   8.717 +			try
   8.718 +			{
   8.719 +				//  Select an action to perform on the form:
   8.720 +
   8.721 +				switch (action)
   8.722 +				{
   8.723 +					case FormActions.AddItemToListBox:
   8.724 +
   8.725 +						LstResults.Items.Add(formText);
   8.726 +						break;
   8.727 +
   8.728 +					case FormActions.DisableInputReportBufferSize:
   8.729 +
   8.730 +						cmdInputReportBufferSize.Enabled = false;
   8.731 +						break;
   8.732 +
   8.733 +					case FormActions.EnableGetInputReportInterruptTransfer:
   8.734 +
   8.735 +						cmdGetInputReportInterrupt.Enabled = true;
   8.736 +						break;
   8.737 +
   8.738 +					case FormActions.EnableInputReportBufferSize:
   8.739 +
   8.740 +						cmdInputReportBufferSize.Enabled = true;
   8.741 +						break;
   8.742 +
   8.743 +					case FormActions.EnableSendOutputReportInterrupt:
   8.744 +
   8.745 +						cmdSendOutputReportInterrupt.Enabled = true;
   8.746 +						break;
   8.747 +
   8.748 +					case FormActions.ScrollToBottomOfListBox:
   8.749 +
   8.750 +						LstResults.SelectedIndex = LstResults.Items.Count - 1;
   8.751 +						break;
   8.752 +
   8.753 +					case FormActions.SetInputReportBufferSize:
   8.754 +
   8.755 +						txtInputReportBufferSize.Text = formText;
   8.756 +						break;
   8.757 +				}
   8.758 +			}
   8.759 +			catch (Exception ex)
   8.760 +			{
   8.761 +				DisplayException(Name, ex);
   8.762 +				throw;
   8.763 +			}
   8.764 +		}
   8.765 +
   8.766 +		///  <summary>
   8.767 +		///  Add a handler to detect arrival of devices using WMI.
   8.768 +		///  </summary>
   8.769 +
   8.770 +		private void AddDeviceArrivedHandler()
   8.771 +		{
   8.772 +			const Int32 pollingIntervalSeconds = 3;
   8.773 +			var scope = new ManagementScope("root\\CIMV2");
   8.774 +			scope.Options.EnablePrivileges = true;
   8.775 +
   8.776 +			try
   8.777 +			{
   8.778 +				var q = new WqlEventQuery();
   8.779 +				q.EventClassName = "__InstanceCreationEvent";
   8.780 +				q.WithinInterval = new TimeSpan(0, 0, pollingIntervalSeconds);
   8.781 +				q.Condition = @"TargetInstance ISA 'Win32_USBControllerdevice'";
   8.782 +				_deviceArrivedWatcher = new ManagementEventWatcher(scope, q);
   8.783 +				_deviceArrivedWatcher.EventArrived += DeviceAdded;
   8.784 +
   8.785 +				_deviceArrivedWatcher.Start();
   8.786 +			}
   8.787 +			catch (Exception e)
   8.788 +			{
   8.789 +				Debug.WriteLine(e.Message);
   8.790 +				if (_deviceArrivedWatcher != null)
   8.791 +					_deviceArrivedWatcher.Stop();
   8.792 +			}
   8.793 +		}
   8.794 +
   8.795 +		///  <summary>
   8.796 +		///  Add a handler to detect removal of devices using WMI.
   8.797 +		///  </summary>
   8.798 +
   8.799 +		private void AddDeviceRemovedHandler()
   8.800 +		{
   8.801 +			const Int32 pollingIntervalSeconds = 3;
   8.802 +			var scope = new ManagementScope("root\\CIMV2");
   8.803 +			scope.Options.EnablePrivileges = true;
   8.804 +
   8.805 +			try
   8.806 +			{
   8.807 +				var q = new WqlEventQuery();
   8.808 +				q.EventClassName = "__InstanceDeletionEvent";
   8.809 +				q.WithinInterval = new TimeSpan(0, 0, pollingIntervalSeconds);
   8.810 +				q.Condition = @"TargetInstance ISA 'Win32_USBControllerdevice'";
   8.811 +				_deviceRemovedWatcher = new ManagementEventWatcher(scope, q);
   8.812 +				_deviceRemovedWatcher.EventArrived += DeviceRemoved;
   8.813 +				_deviceRemovedWatcher.Start();
   8.814 +			}
   8.815 +			catch (Exception e)
   8.816 +			{
   8.817 +				Debug.WriteLine(e.Message);
   8.818 +				if (_deviceRemovedWatcher != null)
   8.819 +					_deviceRemovedWatcher.Stop();
   8.820 +			}
   8.821 +		}
   8.822 +
   8.823 +		/// <summary>
   8.824 +		/// Close the handle and FileStreams for a device.
   8.825 +		/// </summary>
   8.826 +		/// 
   8.827 +		private void CloseCommunications()
   8.828 +		{
   8.829 +			if (_deviceData != null)
   8.830 +			{
   8.831 +				_deviceData.Close();
   8.832 +			}
   8.833 +
   8.834 +			if ((_hidHandle != null) && (!(_hidHandle.IsInvalid)))
   8.835 +			{
   8.836 +				_hidHandle.Close();
   8.837 +			}
   8.838 +
   8.839 +			// The next attempt to communicate will get a new handle and FileStreams.
   8.840 +
   8.841 +			_deviceHandleObtained = false;
   8.842 +		}
   8.843 +
   8.844 +		///  <summary>
   8.845 +		///  Search for a specific device.
   8.846 +		///  </summary>
   8.847 +
   8.848 +		private void cmdFindDevice_Click(Object sender, EventArgs e)
   8.849 +		{
   8.850 +			try
   8.851 +			{
   8.852 +				if (_transferInProgress)
   8.853 +				{
   8.854 +					DisplayTransferInProgressMessage();
   8.855 +				}
   8.856 +				else
   8.857 +				{
   8.858 +					_deviceDetected = FindDeviceUsingWmi();
   8.859 +					if (_deviceDetected)
   8.860 +					{
   8.861 +						FindTheHid();
   8.862 +					}
   8.863 +				}
   8.864 +			}
   8.865 +			catch (Exception ex)
   8.866 +			{
   8.867 +				DisplayException(Name, ex);
   8.868 +				throw;
   8.869 +			}
   8.870 +		}
   8.871 +
   8.872 +		/// <summary>
   8.873 +		/// Request to get a Feature report from the device.
   8.874 +		/// </summary>
   8.875 +		/// <param name="sender"></param>
   8.876 +		/// <param name="e"></param>
   8.877 +
   8.878 +		private void cmdGetFeatureReport_Click(object sender, EventArgs e)
   8.879 +		{
   8.880 +			try
   8.881 +			{
   8.882 +				if (_transferInProgress)
   8.883 +				{
   8.884 +					DisplayTransferInProgressMessage();
   8.885 +				}
   8.886 +				else
   8.887 +				{
   8.888 +					//  Don't allow another transfer request until this one completes.
   8.889 +					//  Move the focus away from the button to prevent the focus from 
   8.890 +					//  switching to the next control in the tab order on disabling the button.
   8.891 +
   8.892 +					fraControlTransfers.Focus();
   8.893 +					cmdGetFeatureReport.Enabled = false;
   8.894 +					_transferType = TransferTypes.Control;
   8.895 +					RequestToGetFeatureReport();
   8.896 +				}
   8.897 +			}
   8.898 +			catch (Exception ex)
   8.899 +			{
   8.900 +				DisplayException(Name, ex);
   8.901 +				throw;
   8.902 +			}
   8.903 +		}
   8.904 +
   8.905 +		/// <summary>
   8.906 +		/// Request to get an Input report from the device using a control transfer.
   8.907 +		/// </summary>
   8.908 +		/// <param name="sender"></param>
   8.909 +		/// <param name="e"></param>
   8.910 +
   8.911 +		private void cmdGetInputReportControl_Click(object sender, EventArgs e)
   8.912 +		{
   8.913 +			try
   8.914 +			{
   8.915 +				//  Don't allow another transfer request until this one completes.
   8.916 +				//  Move the focus away from the button to prevent the focus from 
   8.917 +				//  switching to the next control in the tab order on disabling the button.
   8.918 +
   8.919 +				if (_transferInProgress)
   8.920 +				{
   8.921 +					DisplayTransferInProgressMessage();
   8.922 +				}
   8.923 +				else
   8.924 +				{
   8.925 +					fraControlTransfers.Focus();
   8.926 +					cmdGetInputReportControl.Enabled = false;
   8.927 +					_transferType = TransferTypes.Control;
   8.928 +					RequestToGetInputReport();
   8.929 +				}
   8.930 +			}
   8.931 +			catch (Exception ex)
   8.932 +			{
   8.933 +				DisplayException(Name, ex);
   8.934 +				throw;
   8.935 +			}
   8.936 +		}
   8.937 +
   8.938 +		/// <summary>
   8.939 +		/// Request to get an Input report retrieved using interrupt transfers.
   8.940 +		/// </summary>
   8.941 +		/// <param name="sender"></param>
   8.942 +		/// <param name="e"></param>
   8.943 +		/// 
   8.944 +		private void cmdGetInputReportInterrupt_Click(object sender, EventArgs e)
   8.945 +		{
   8.946 +			try
   8.947 +			{
   8.948 +				if (_transferInProgress)
   8.949 +				{
   8.950 +					DisplayTransferInProgressMessage();
   8.951 +				}
   8.952 +				else
   8.953 +				{
   8.954 +					//  Don't allow another transfer request until this one completes.
   8.955 +					//  Move the focus away from the button to prevent the focus from 
   8.956 +					//  switching to the next control in the tab order on disabling the button.
   8.957 +
   8.958 +					fraInterruptTransfers.Focus();
   8.959 +					cmdGetInputReportInterrupt.Enabled = false;
   8.960 +					_transferType = TransferTypes.Interrupt;
   8.961 +					RequestToGetInputReport();
   8.962 +				}
   8.963 +			}
   8.964 +			catch (Exception ex)
   8.965 +			{
   8.966 +				DisplayException(Name, ex);
   8.967 +				throw;
   8.968 +			}
   8.969 +		}
   8.970 +
   8.971 +		///  <summary>
   8.972 +		///  Set the number of Input reports the HID driver will store.
   8.973 +		///  </summary>
   8.974 +
   8.975 +		private void cmdInputReportBufferSize_Click(Object sender, EventArgs e)
   8.976 +		{
   8.977 +			try
   8.978 +			{
   8.979 +				if (_transferInProgress)
   8.980 +				{
   8.981 +					DisplayTransferInProgressMessage();
   8.982 +				}
   8.983 +				else
   8.984 +				{
   8.985 +					SetInputReportBufferSize();
   8.986 +				}
   8.987 +			}
   8.988 +			catch
   8.989 +				(Exception ex)
   8.990 +			{
   8.991 +				DisplayException(Name, ex);
   8.992 +				throw;
   8.993 +			}
   8.994 +		}
   8.995 +
   8.996 +		/// <summary>
   8.997 +		/// Alternate sending and getting a report.
   8.998 +		/// </summary>
   8.999 +		/// <param name="sender"></param>
  8.1000 +		/// <param name="e"></param>
  8.1001 +
  8.1002 +		private void cmdPeriodicTransfers_Click(object sender, EventArgs e)
  8.1003 +		{
  8.1004 +			try
  8.1005 +			{
  8.1006 +				if (cmdPeriodicTransfers.Text == "Start")
  8.1007 +				{
  8.1008 +					if (_transferInProgress)
  8.1009 +					{
  8.1010 +						DisplayTransferInProgressMessage();
  8.1011 +					}
  8.1012 +					else
  8.1013 +					{
  8.1014 +						_sendOrGet = SendOrGet.Send;
  8.1015 +						PeriodicTransfersStart();
  8.1016 +					}
  8.1017 +				}
  8.1018 +				else
  8.1019 +				{
  8.1020 +					PeriodicTransfersStop();
  8.1021 +				}
  8.1022 +			}
  8.1023 +			catch (Exception ex)
  8.1024 +			{
  8.1025 +				DisplayException(Name, ex);
  8.1026 +				throw;
  8.1027 +			}
  8.1028 +		}
  8.1029 +
  8.1030 +		/// <summary>
  8.1031 +		/// Request to send a Feature report using a control transfer.
  8.1032 +		/// </summary>
  8.1033 +		/// <param name="sender"></param>
  8.1034 +		/// <param name="e"></param>
  8.1035 +
  8.1036 +		private void cmdSendFeatureReport_Click(object sender, EventArgs e)
  8.1037 +		{
  8.1038 +			try
  8.1039 +			{
  8.1040 +				if (_transferInProgress)
  8.1041 +				{
  8.1042 +					DisplayTransferInProgressMessage();
  8.1043 +				}
  8.1044 +				else
  8.1045 +				{
  8.1046 +					//  Don't allow another transfer request until this one completes.
  8.1047 +					//  Move the focus away from the button to prevent the focus from 
  8.1048 +					//  switching to the next control in the tab order on disabling the button.
  8.1049 +
  8.1050 +					fraControlTransfers.Focus();
  8.1051 +					cmdSendFeatureReport.Enabled = false;
  8.1052 +					_transferType = TransferTypes.Control;
  8.1053 +					RequestToSendFeatureReport();
  8.1054 +				}
  8.1055 +			}
  8.1056 +			catch (Exception ex)
  8.1057 +			{
  8.1058 +				DisplayException(Name, ex);
  8.1059 +				throw;
  8.1060 +			}
  8.1061 +		}
  8.1062 +
  8.1063 +		/// <summary>
  8.1064 +		/// Request to send an Output report using a control transfer.
  8.1065 +		/// </summary>
  8.1066 +		/// <param name="sender"></param>
  8.1067 +		/// <param name="e"></param>
  8.1068 +		/// 
  8.1069 +		private void cmdSendOutputReportControl_Click(object sender, EventArgs e)
  8.1070 +		{
  8.1071 +			try
  8.1072 +			{
  8.1073 +				if (_transferInProgress)
  8.1074 +				{
  8.1075 +					DisplayTransferInProgressMessage();
  8.1076 +				}
  8.1077 +				else
  8.1078 +				{
  8.1079 +					//  Don't allow another transfer request until this one completes.
  8.1080 +					//  Move the focus away from the button to prevent the focus from 
  8.1081 +					//  switching to the next control in the tab order on disabling the button.
  8.1082 +
  8.1083 +					fraControlTransfers.Focus();
  8.1084 +					cmdSendOutputReportControl.Enabled = false;
  8.1085 +					_transferType = TransferTypes.Control;
  8.1086 +					RequestToSendOutputReport();
  8.1087 +				}
  8.1088 +			}
  8.1089 +			catch (Exception ex)
  8.1090 +			{
  8.1091 +				DisplayException(Name, ex);
  8.1092 +				throw;
  8.1093 +			}
  8.1094 +		}
  8.1095 +
  8.1096 +		/// <summary>
  8.1097 +		/// Request to send an Output report using an interrupt transfer.		
  8.1098 +		/// </summary>
  8.1099 +		/// <param name="sender"></param>
  8.1100 +		/// <param name="e"></param>
  8.1101 +
  8.1102 +		private void cmdSendOutputReportInterrupt_Click(object sender, EventArgs e)
  8.1103 +		{
  8.1104 +			try
  8.1105 +			{
  8.1106 +				if (_transferInProgress)
  8.1107 +				{
  8.1108 +					DisplayTransferInProgressMessage();
  8.1109 +				}
  8.1110 +				else
  8.1111 +				{
  8.1112 +					//  Don't allow another transfer request until this one completes.
  8.1113 +					//  Move the focus away from the button to prevent the focus from 
  8.1114 +					//  switching to the next control in the tab order on disabling the button.
  8.1115 +
  8.1116 +					fraInterruptTransfers.Focus();
  8.1117 +					cmdSendOutputReportInterrupt.Enabled = false;
  8.1118 +					_transferType = TransferTypes.Interrupt;
  8.1119 +					RequestToSendOutputReport();
  8.1120 +				}
  8.1121 +			}
  8.1122 +			catch (Exception ex)
  8.1123 +			{
  8.1124 +				DisplayException(Name, ex);
  8.1125 +				throw;
  8.1126 +			}
  8.1127 +		}
  8.1128 +
  8.1129 +		///  <summary>
  8.1130 +		///  Called on arrival of any device.
  8.1131 +		///  Calls a routine that searches to see if the desired device is present.
  8.1132 +		///  </summary>
  8.1133 +
  8.1134 +		private void DeviceAdded(object sender, EventArrivedEventArgs e)
  8.1135 +		{
  8.1136 +			try
  8.1137 +			{
  8.1138 +				Debug.WriteLine("A USB device has been inserted");
  8.1139 +
  8.1140 +				_deviceDetected = FindDeviceUsingWmi();
  8.1141 +			}
  8.1142 +			catch (Exception ex)
  8.1143 +			{
  8.1144 +				DisplayException(Name, ex);
  8.1145 +				throw;
  8.1146 +			}
  8.1147 +		}
  8.1148 +
  8.1149 +		///  <summary>
  8.1150 +		///  Called if the user changes the Vendor ID or Product ID in the text box.
  8.1151 +		///  </summary>
  8.1152 +
  8.1153 +		private void DeviceHasChanged()
  8.1154 +		{
  8.1155 +			try
  8.1156 +			{
  8.1157 +				//  If a device was previously detected, stop receiving notifications about it.
  8.1158 +
  8.1159 +				if (_deviceHandleObtained)
  8.1160 +				{
  8.1161 +					DeviceNotificationsStop();
  8.1162 +
  8.1163 +					CloseCommunications();
  8.1164 +				}
  8.1165 +				// Look for a device that matches the Vendor ID and Product ID in the text boxes.
  8.1166 +
  8.1167 +				FindTheHid();
  8.1168 +			}
  8.1169 +			catch (Exception ex)
  8.1170 +			{
  8.1171 +				DisplayException(Name, ex);
  8.1172 +				throw;
  8.1173 +			}
  8.1174 +		}
  8.1175 +
  8.1176 +		///  <summary>
  8.1177 +		///  Add handlers to detect device arrival and removal.
  8.1178 +		///  </summary>
  8.1179 +
  8.1180 +		private void DeviceNotificationsStart()
  8.1181 +		{
  8.1182 +			AddDeviceArrivedHandler();
  8.1183 +			AddDeviceRemovedHandler();
  8.1184 +		}
  8.1185 +
  8.1186 +		///  <summary>
  8.1187 +		///  Stop receiving notifications about device arrival and removal
  8.1188 +		///  </summary>
  8.1189 +
  8.1190 +		private void DeviceNotificationsStop()
  8.1191 +		{
  8.1192 +			try
  8.1193 +			{
  8.1194 +				if (_deviceArrivedWatcher != null)
  8.1195 +					_deviceArrivedWatcher.Stop();
  8.1196 +				if (_deviceRemovedWatcher != null)
  8.1197 +					_deviceRemovedWatcher.Stop();
  8.1198 +			}
  8.1199 +			catch (Exception ex)
  8.1200 +			{
  8.1201 +				DisplayException(Name, ex);
  8.1202 +				throw;
  8.1203 +			}
  8.1204 +		}
  8.1205 +
  8.1206 +		///  <summary>
  8.1207 +		///  Called on removal of any device.
  8.1208 +		///  Calls a routine that searches to see if the desired device is still present.
  8.1209 +		///  </summary>
  8.1210 +		/// 
  8.1211 +		private void DeviceRemoved(object sender, EventArgs e)
  8.1212 +		{
  8.1213 +			try
  8.1214 +			{
  8.1215 +				Debug.WriteLine("A USB device has been removed");
  8.1216 +
  8.1217 +				_deviceDetected = FindDeviceUsingWmi();
  8.1218 +
  8.1219 +				if (!_deviceDetected)
  8.1220 +				{
  8.1221 +					_deviceHandleObtained = false;
  8.1222 +					CloseCommunications();
  8.1223 +				}
  8.1224 +			}
  8.1225 +			catch (Exception ex)
  8.1226 +			{
  8.1227 +				DisplayException(Name, ex);
  8.1228 +				throw;
  8.1229 +			}
  8.1230 +		}
  8.1231 +
  8.1232 +		///  <summary>
  8.1233 +		///  Displays received or written report data.
  8.1234 +		///  </summary>
  8.1235 +		///  
  8.1236 +		///  <param name="buffer"> contains the report data. </param>			
  8.1237 +		///  <param name="currentReportType" > "Input", "Output", or "Feature"</param>
  8.1238 +		///  <param name="currentReadOrWritten" > "read" for Input and IN Feature reports, "written" for Output and OUT Feature reports.</param>
  8.1239 +
  8.1240 +		private void DisplayReportData(Byte[] buffer, ReportTypes currentReportType, ReportReadOrWritten currentReadOrWritten)
  8.1241 +		{
  8.1242 +			try
  8.1243 +			{
  8.1244 +				Int32 count;
  8.1245 +
  8.1246 +				LstResults.Items.Add(currentReportType.ToString() + " report has been " + currentReadOrWritten.ToString().ToLower() + ".");
  8.1247 +
  8.1248 +				//  Display the report data received in the form's list box.
  8.1249 +
  8.1250 +				LstResults.Items.Add(" Report ID: " + String.Format("{0:X2} ", buffer[0]));
  8.1251 +				LstResults.Items.Add(" Report Data:");
  8.1252 +
  8.1253 +				TxtBytesReceived.Text = "";
  8.1254 +
  8.1255 +				for (count = 1; count <= buffer.Length - 1; count++)
  8.1256 +				{
  8.1257 +					//  Display bytes as 2-character Hex strings.
  8.1258 +
  8.1259 +					String byteValue = String.Format("{0:X2} ", buffer[count]);
  8.1260 +
  8.1261 +					LstResults.Items.Add(" " + byteValue);
  8.1262 +
  8.1263 +					//  Display the received bytes in the text box.
  8.1264 +
  8.1265 +					TxtBytesReceived.SelectionStart = TxtBytesReceived.Text.Length;
  8.1266 +					TxtBytesReceived.SelectedText = byteValue + Environment.NewLine;
  8.1267 +				}
  8.1268 +				ScrollToBottomOfListBox();
  8.1269 +			}
  8.1270 +			catch (Exception ex)
  8.1271 +			{
  8.1272 +				DisplayException(Name, ex);
  8.1273 +				throw;
  8.1274 +			}
  8.1275 +		}
  8.1276 +
  8.1277 +		///  <summary>
  8.1278 +		///  Display a message if the user clicks a button when a transfer is in progress.
  8.1279 +		///  </summary>
  8.1280 +		/// 
  8.1281 +		private void DisplayTransferInProgressMessage()
  8.1282 +		{
  8.1283 +			AccessForm(FormActions.AddItemToListBox, "Command not executed because a transfer is in progress.");
  8.1284 +			ScrollToBottomOfListBox();
  8.1285 +		}
  8.1286 +
  8.1287 +		///  <summary>
  8.1288 +		///  Do periodic transfers.
  8.1289 +		///  </summary>
  8.1290 +		/// <param name="source"></param>
  8.1291 +		/// <param name="e"></param>
  8.1292 +		///  <remarks>
  8.1293 +		///  The timer is enabled only if continuous (periodic) transfers have been requested.
  8.1294 +		///  </remarks>		  
  8.1295 +
  8.1296 +		private void DoPeriodicTransfers(object source, ElapsedEventArgs e)
  8.1297 +		{
  8.1298 +			try
  8.1299 +			{
  8.1300 +				PeriodicTransfers();
  8.1301 +			}
  8.1302 +			catch (Exception ex)
  8.1303 +			{
  8.1304 +				DisplayException(Name, ex);
  8.1305 +				throw;
  8.1306 +			}
  8.1307 +		}
  8.1308 +
  8.1309 +		/// <summary>
  8.1310 +		/// Enable the command buttons on the form.
  8.1311 +		/// Needed after attempting a transfer and device not found.
  8.1312 +		/// </summary>
  8.1313 +		/// 
  8.1314 +		private void EnableFormControls()
  8.1315 +		{
  8.1316 +			cmdGetInputReportInterrupt.Enabled = true;
  8.1317 +			cmdSendOutputReportControl.Enabled = true;
  8.1318 +			cmdGetInputReportControl.Enabled = true;
  8.1319 +			cmdGetFeatureReport.Enabled = true;
  8.1320 +			cmdSendFeatureReport.Enabled = true;
  8.1321 +			cmdPeriodicTransfers.Enabled = true;
  8.1322 +			cmdSendOutputReportInterrupt.Enabled = true;
  8.1323 +		}
  8.1324 +
  8.1325 +		///  <summary>
  8.1326 +		///  Use the System.Management class to find a device by Vendor ID and Product ID using WMI. If found, display device properties.
  8.1327 +		///  </summary>
  8.1328 +		/// <remarks> 
  8.1329 +		/// During debugging, if you stop the firmware but leave the device attached, the device may still be detected as present
  8.1330 +		/// but will be unable to communicate. The device will show up in Windows Device Manager as well. 
  8.1331 +		/// This situation is unlikely to occur with a final product.
  8.1332 +		/// </remarks>
  8.1333 +
  8.1334 +		private Boolean FindDeviceUsingWmi()
  8.1335 +		{
  8.1336 +			try
  8.1337 +			{
  8.1338 +				// Prepend "@" to string below to treat backslash as a normal character (not escape character):
  8.1339 +
  8.1340 +				String deviceIdString = @"USB\VID_" + _myVendorId.ToString("X4") + "&PID_" + _myProductId.ToString("X4");
  8.1341 +
  8.1342 +				_deviceDetected = false;
  8.1343 +				var searcher = new ManagementObjectSearcher("root\\CIMV2", "SELECT * FROM Win32_PnPEntity");
  8.1344 +
  8.1345 +				foreach (ManagementObject queryObj in searcher.Get())
  8.1346 +				{
  8.1347 +					if (queryObj["PNPDeviceID"].ToString().Contains(deviceIdString))
  8.1348 +					{
  8.1349 +						_deviceDetected = true;
  8.1350 +						MyMarshalDataToForm(FormActions.AddItemToListBox, "--------");
  8.1351 +						MyMarshalDataToForm(FormActions.AddItemToListBox, "My device found (WMI):");
  8.1352 +
  8.1353 +						// Display device properties.
  8.1354 +
  8.1355 +						foreach (WmiDeviceProperties wmiDeviceProperty in Enum.GetValues(typeof(WmiDeviceProperties)))
  8.1356 +						{
  8.1357 +							MyMarshalDataToForm(FormActions.AddItemToListBox, (wmiDeviceProperty.ToString() + ": " + queryObj[wmiDeviceProperty.ToString()]));
  8.1358 +							Debug.WriteLine(wmiDeviceProperty.ToString() + ": {0}", queryObj[wmiDeviceProperty.ToString()]);
  8.1359 +						}
  8.1360 +						MyMarshalDataToForm(FormActions.AddItemToListBox, "--------");
  8.1361 +						MyMarshalDataToForm(FormActions.ScrollToBottomOfListBox, "");
  8.1362 +					}
  8.1363 +				}
  8.1364 +				if (!_deviceDetected)
  8.1365 +				{
  8.1366 +					MyMarshalDataToForm(FormActions.AddItemToListBox, "My device not found (WMI)");
  8.1367 +					MyMarshalDataToForm(FormActions.ScrollToBottomOfListBox, "");
  8.1368 +				}
  8.1369 +				return _deviceDetected;
  8.1370 +			}
  8.1371 +			catch (Exception ex)
  8.1372 +			{
  8.1373 +				DisplayException(Name, ex);
  8.1374 +				throw;
  8.1375 +			}
  8.1376 +		}
  8.1377 +
  8.1378 +		///  <summary>
  8.1379 +		///  Call HID functions that use Win32 API functions to locate a HID-class device
  8.1380 +		///  by its Vendor ID and Product ID. Open a handle to the device.
  8.1381 +		///  </summary>
  8.1382 +		///          
  8.1383 +		///  <returns>
  8.1384 +		///   True if the device is detected, False if not detected.
  8.1385 +		///  </returns>
  8.1386 +
  8.1387 +		private Boolean FindTheHid()
  8.1388 +		{
  8.1389 +			var devicePathName = new String[128];
  8.1390 +			String myDevicePathName = "";
  8.1391 +
  8.1392 +			try
  8.1393 +			{
  8.1394 +				_deviceHandleObtained = false;
  8.1395 +				CloseCommunications();
  8.1396 +
  8.1397 +				//  Get the device's Vendor ID and Product ID from the form's text boxes.
  8.1398 +
  8.1399 +				GetVendorAndProductIDsFromTextBoxes(ref _myVendorId, ref _myProductId);
  8.1400 +
  8.1401 +				// Get the HID-class GUID.
  8.1402 +
  8.1403 +				Guid hidGuid = _myHid.GetHidGuid();
  8.1404 +
  8.1405 +				String functionName = "GetHidGuid";
  8.1406 +				Debug.WriteLine(_myDebugging.ResultOfApiCall(functionName));
  8.1407 +				Debug.WriteLine("  GUID for system HIDs: " + hidGuid.ToString());
  8.1408 +
  8.1409 +				//  Fill an array with the device path names of all attached HIDs.
  8.1410 +
  8.1411 +				Boolean availableHids = _myDeviceManagement.FindDeviceFromGuid(hidGuid, ref devicePathName);
  8.1412 +
  8.1413 +				//  If there is at least one HID, attempt to read the Vendor ID and Product ID
  8.1414 +				//  of each device until there is a match or all devices have been examined.
  8.1415 +
  8.1416 +				if (availableHids)
  8.1417 +				{
  8.1418 +					Int32 memberIndex = 0;
  8.1419 +
  8.1420 +					do
  8.1421 +					{
  8.1422 +						// Open the handle without read/write access to enable getting information about any HID, even system keyboards and mice.
  8.1423 +
  8.1424 +						_hidHandle = _myHid.OpenHandle(devicePathName[memberIndex], false);
  8.1425 +
  8.1426 +						functionName = "CreateFile";
  8.1427 +						Debug.WriteLine(_myDebugging.ResultOfApiCall(functionName));
  8.1428 +						Debug.WriteLine("  Returned handle: " + _hidHandle);
  8.1429 +
  8.1430 +						if (!_hidHandle.IsInvalid)
  8.1431 +						{
  8.1432 +							// The returned handle is valid, 
  8.1433 +							// so find out if this is the device we're looking for.
  8.1434 +
  8.1435 +							_myHid.DeviceAttributes.Size = Marshal.SizeOf(_myHid.DeviceAttributes);
  8.1436 +
  8.1437 +							Boolean success = _myHid.GetAttributes(_hidHandle, ref _myHid.DeviceAttributes);
  8.1438 +
  8.1439 +							if (success)
  8.1440 +							{
  8.1441 +								Debug.WriteLine("  HIDD_ATTRIBUTES structure filled without error.");
  8.1442 +								Debug.WriteLine("  Structure size: " + _myHid.DeviceAttributes.Size);
  8.1443 +								Debug.WriteLine("  Vendor ID: " + Convert.ToString(_myHid.DeviceAttributes.VendorID, 16));
  8.1444 +								Debug.WriteLine("  Product ID: " + Convert.ToString(_myHid.DeviceAttributes.ProductID, 16));
  8.1445 +								Debug.WriteLine("  Version Number: " + Convert.ToString(_myHid.DeviceAttributes.VersionNumber, 16));
  8.1446 +
  8.1447 +								if ((_myHid.DeviceAttributes.VendorID == _myVendorId) && (_myHid.DeviceAttributes.ProductID == _myProductId))
  8.1448 +								{
  8.1449 +									Debug.WriteLine("  Handle obtained to my device");
  8.1450 +
  8.1451 +									//  Display the information in form's list box.
  8.1452 +
  8.1453 +									MyMarshalDataToForm(FormActions.AddItemToListBox, "Handle obtained to my device:");
  8.1454 +									MyMarshalDataToForm(FormActions.AddItemToListBox, "  Vendor ID= " + Convert.ToString(_myHid.DeviceAttributes.VendorID, 16));
  8.1455 +									MyMarshalDataToForm(FormActions.AddItemToListBox, "  Product ID = " + Convert.ToString(_myHid.DeviceAttributes.ProductID, 16));
  8.1456 +									MyMarshalDataToForm(FormActions.ScrollToBottomOfListBox, "");
  8.1457 +
  8.1458 +									_deviceHandleObtained = true;
  8.1459 +
  8.1460 +									myDevicePathName = devicePathName[memberIndex];
  8.1461 +								}
  8.1462 +								else
  8.1463 +								{
  8.1464 +									//  It's not a match, so close the handle.
  8.1465 +
  8.1466 +									_deviceHandleObtained = false;
  8.1467 +									_hidHandle.Close();
  8.1468 +								}
  8.1469 +							}
  8.1470 +							else
  8.1471 +							{
  8.1472 +								//  There was a problem retrieving the information.
  8.1473 +
  8.1474 +								Debug.WriteLine("  Error in filling HIDD_ATTRIBUTES structure.");
  8.1475 +								_deviceHandleObtained = false;
  8.1476 +								_hidHandle.Close();
  8.1477 +							}
  8.1478 +						}
  8.1479 +
  8.1480 +						//  Keep looking until we find the device or there are no devices left to examine.
  8.1481 +
  8.1482 +						memberIndex = memberIndex + 1;
  8.1483 +					}
  8.1484 +					while (!((_deviceHandleObtained || (memberIndex == devicePathName.Length))));
  8.1485 +				}
  8.1486 +
  8.1487 +				if (_deviceHandleObtained)
  8.1488 +				{
  8.1489 +					//  The device was detected.
  8.1490 +					//  Learn the capabilities of the device.
  8.1491 +
  8.1492 +					_myHid.Capabilities = _myHid.GetDeviceCapabilities(_hidHandle);
  8.1493 +
  8.1494 +					//  Find out if the device is a system mouse or keyboard.
  8.1495 +
  8.1496 +					_hidUsage = _myHid.GetHidUsage(_myHid.Capabilities);
  8.1497 +
  8.1498 +					//  Get the Input report buffer size.
  8.1499 +
  8.1500 +					GetInputReportBufferSize();
  8.1501 +					MyMarshalDataToForm(FormActions.EnableInputReportBufferSize, "");
  8.1502 +
  8.1503 +					//Close the handle and reopen it with read/write access.
  8.1504 +
  8.1505 +					_hidHandle.Close();
  8.1506 +
  8.1507 +					_hidHandle = _myHid.OpenHandle(myDevicePathName, true);
  8.1508 +
  8.1509 +					if (_hidHandle.IsInvalid)
  8.1510 +					{
  8.1511 +						MyMarshalDataToForm(FormActions.AddItemToListBox, "The device is a system " + _hidUsage + ".");
  8.1512 +						MyMarshalDataToForm(FormActions.AddItemToListBox, "Windows 2000 and later obtain exclusive access to Input and Output reports for this devices.");
  8.1513 +						MyMarshalDataToForm(FormActions.AddItemToListBox, "Windows 8 also obtains exclusive access to Feature reports.");
  8.1514 +						MyMarshalDataToForm(FormActions.ScrollToBottomOfListBox, "");
  8.1515 +					}
  8.1516 +					else
  8.1517 +					{
  8.1518 +						if (_myHid.Capabilities.InputReportByteLength > 0)
  8.1519 +						{
  8.1520 +							//  Set the size of the Input report buffer. 
  8.1521 +
  8.1522 +							var inputReportBuffer = new Byte[_myHid.Capabilities.InputReportByteLength];
  8.1523 +
  8.1524 +							_deviceData = new FileStream(_hidHandle, FileAccess.Read | FileAccess.Write, inputReportBuffer.Length, false);
  8.1525 +						}
  8.1526 +
  8.1527 +						if (_myHid.Capabilities.OutputReportByteLength > 0)
  8.1528 +						{
  8.1529 +							Byte[] outputReportBuffer = null;
  8.1530 +						}
  8.1531 +						//  Flush any waiting reports in the input buffer. (optional)
  8.1532 +
  8.1533 +						_myHid.FlushQueue(_hidHandle);
  8.1534 +					}
  8.1535 +				}
  8.1536 +				else
  8.1537 +				{
  8.1538 +					MyMarshalDataToForm(FormActions.AddItemToListBox, "Device not found.");
  8.1539 +					MyMarshalDataToForm(FormActions.DisableInputReportBufferSize, "");
  8.1540 +					EnableFormControls();
  8.1541 +					MyMarshalDataToForm(FormActions.ScrollToBottomOfListBox, "");
  8.1542 +				}
  8.1543 +				return _deviceHandleObtained;
  8.1544 +			}
  8.1545 +			catch (Exception ex)
  8.1546 +			{
  8.1547 +				DisplayException(Name, ex);
  8.1548 +				throw;
  8.1549 +			}
  8.1550 +		}
  8.1551 +
  8.1552 +		///  <summary>
  8.1553 +		///  Perform shutdown operations.
  8.1554 +		///  </summary>
  8.1555 +
  8.1556 +		private void frmMain_Closed(Object eventSender, EventArgs eventArgs)
  8.1557 +		{
  8.1558 +			try
  8.1559 +			{
  8.1560 +				Shutdown();
  8.1561 +			}
  8.1562 +			catch (Exception ex)
  8.1563 +			{
  8.1564 +				DisplayException(Name, ex);
  8.1565 +				throw;
  8.1566 +			}
  8.1567 +		}
  8.1568 +
  8.1569 +		///  <summary>
  8.1570 +		///  Perform startup operations.
  8.1571 +		///  </summary>
  8.1572 +
  8.1573 +		private void frmMain_Load(Object eventSender, EventArgs eventArgs)
  8.1574 +		{
  8.1575 +			try
  8.1576 +			{
  8.1577 +				FrmMy = this;
  8.1578 +				Startup();
  8.1579 +			}
  8.1580 +			catch (Exception ex)
  8.1581 +			{
  8.1582 +				DisplayException(Name, ex);
  8.1583 +				throw;
  8.1584 +			}
  8.1585 +		}
  8.1586 +
  8.1587 +		private void GetBytesToSend()
  8.1588 +		{
  8.1589 +			try
  8.1590 +			{
  8.1591 +				//  Get the bytes to send in a report from the combo boxes.
  8.1592 +				//  Increment the values if the autoincrement check box is selected.
  8.1593 +
  8.1594 +				if (ChkAutoincrement.Checked)
  8.1595 +				{
  8.1596 +					if (CboByte0.SelectedIndex < 255)
  8.1597 +					{
  8.1598 +						CboByte0.SelectedIndex = CboByte0.SelectedIndex + 1;
  8.1599 +					}
  8.1600 +					else
  8.1601 +					{
  8.1602 +						CboByte0.SelectedIndex = 0;
  8.1603 +					}
  8.1604 +					if (CboByte1.SelectedIndex < 255)
  8.1605 +					{
  8.1606 +						CboByte1.SelectedIndex = CboByte1.SelectedIndex + 1;
  8.1607 +					}
  8.1608 +					else
  8.1609 +					{
  8.1610 +						CboByte1.SelectedIndex = 0;
  8.1611 +					}
  8.1612 +				}
  8.1613 +			}
  8.1614 +			catch (Exception ex)
  8.1615 +			{
  8.1616 +				DisplayException(Name, ex);
  8.1617 +				throw;
  8.1618 +			}
  8.1619 +		}
  8.1620 +
  8.1621 +		///  <summary>
  8.1622 +		///  Find and display the number of Input buffers
  8.1623 +		///  (the number of Input reports the HID driver will store). 
  8.1624 +		///  </summary>
  8.1625 +
  8.1626 +		private void GetInputReportBufferSize()
  8.1627 +		{
  8.1628 +			Int32 numberOfInputBuffers = 0;
  8.1629 +			Boolean success;
  8.1630 +
  8.1631 +			try
  8.1632 +			{
  8.1633 +				//  Get the number of input buffers.
  8.1634 +
  8.1635 +				_myHid.GetNumberOfInputBuffers(_hidHandle, ref numberOfInputBuffers);
  8.1636 +
  8.1637 +				//  Display the result in the text box.
  8.1638 +
  8.1639 +				MyMarshalDataToForm(FormActions.SetInputReportBufferSize, Convert.ToString(numberOfInputBuffers));
  8.1640 +			}
  8.1641 +			catch (Exception ex)
  8.1642 +			{
  8.1643 +				DisplayException(Name, ex);
  8.1644 +				throw;
  8.1645 +			}
  8.1646 +		}
  8.1647 +
  8.1648 +		///  <summary>
  8.1649 +		///  Retrieve a Vendor ID and Product ID in hexadecimal 
  8.1650 +		///  from the form's text boxes and convert the text to Int32s.
  8.1651 +		///  </summary>
  8.1652 +		///  
  8.1653 +		///  <param name="myVendorId"> the Vendor ID</param>
  8.1654 +		///  <param name="myProductId"> the Product ID</param>
  8.1655 +
  8.1656 +		private void GetVendorAndProductIDsFromTextBoxes(ref Int32 myVendorId, ref Int32 myProductId)
  8.1657 +		{
  8.1658 +			try
  8.1659 +			{
  8.1660 +				myVendorId = Int32.Parse(txtVendorID.Text, NumberStyles.AllowHexSpecifier);
  8.1661 +				myProductId = Int32.Parse(txtProductID.Text, NumberStyles.AllowHexSpecifier);
  8.1662 +			}
  8.1663 +			catch (Exception ex)
  8.1664 +			{
  8.1665 +				DisplayException(Name, ex);
  8.1666 +				throw;
  8.1667 +			}
  8.1668 +		}
  8.1669 +
  8.1670 +		///  <summary>
  8.1671 +		///  Initialize the elements on the form.
  8.1672 +		///  </summary>
  8.1673 +
  8.1674 +		private void InitializeDisplay()
  8.1675 +		{
  8.1676 +			try
  8.1677 +			{
  8.1678 +				//  Create a dropdown list box for each byte to send in a report.
  8.1679 +				//  Display the values as 2-character hex strings.
  8.1680 +
  8.1681 +				Int16 count;
  8.1682 +				for (count = 0; count <= 255; count++)
  8.1683 +				{
  8.1684 +					String byteValue = String.Format("{0:X2} ", count);
  8.1685 +					FrmMy.CboByte0.Items.Insert(count, byteValue);
  8.1686 +					FrmMy.CboByte1.Items.Insert(count, byteValue);
  8.1687 +				}
  8.1688 +
  8.1689 +				//  Select a default value for each box
  8.1690 +
  8.1691 +				FrmMy.CboByte0.SelectedIndex = 0;
  8.1692 +				FrmMy.CboByte1.SelectedIndex = 128;
  8.1693 +				FrmMy.radInputOutputInterrupt.Checked = true;
  8.1694 +
  8.1695 +				//  Check the autoincrement box to increment the values each time a report is sent.
  8.1696 +
  8.1697 +				ChkAutoincrement.CheckState = CheckState.Checked;
  8.1698 +
  8.1699 +				//  Don't allow the user to select an input report buffer size until there is
  8.1700 +				//  a handle to a HID.
  8.1701 +
  8.1702 +				cmdInputReportBufferSize.Focus();
  8.1703 +				cmdInputReportBufferSize.Enabled = false;
  8.1704 +
  8.1705 +				LstResults.Items.Add("For a more detailed event log, view debug statements in Visual Studio's Output window:");
  8.1706 +				LstResults.Items.Add("Click Build > Configuration Manager > Active Solution Configuration > Debug > Close.");
  8.1707 +				LstResults.Items.Add("Then click View > Output.");
  8.1708 +				LstResults.Items.Add("");
  8.1709 +			}
  8.1710 +			catch (Exception ex)
  8.1711 +			{
  8.1712 +				DisplayException(Name, ex);
  8.1713 +				throw;
  8.1714 +			}
  8.1715 +		}
  8.1716 +
  8.1717 +		///  <summary>
  8.1718 +		///  Enables accessing a form's controls from another thread 
  8.1719 +		///  </summary>
  8.1720 +		///  
  8.1721 +		///  <param name="action"> a FormActions member that names the action to perform on the form </param>
  8.1722 +		///  <param name="textToDisplay"> text that the form displays or the code uses for 
  8.1723 +		///  another purpose. Actions that don't use text ignore this parameter.  </param>
  8.1724 +
  8.1725 +		private void MyMarshalDataToForm(FormActions action, String textToDisplay)
  8.1726 +		{
  8.1727 +			try
  8.1728 +			{
  8.1729 +				object[] args = { action, textToDisplay };
  8.1730 +
  8.1731 +				//  The AccessForm routine contains the code that accesses the form.
  8.1732 +
  8.1733 +				MarshalDataToForm marshalDataToFormDelegate = AccessForm;
  8.1734 +
  8.1735 +				//  Execute AccessForm, passing the parameters in args.
  8.1736 +
  8.1737 +				Invoke(marshalDataToFormDelegate, args);
  8.1738 +			}
  8.1739 +			catch (Exception ex)
  8.1740 +			{
  8.1741 +				DisplayException(Name, ex);
  8.1742 +				throw;
  8.1743 +			}
  8.1744 +		}
  8.1745 +
  8.1746 +		/// <summary>
  8.1747 +		/// Timeout if read via interrupt transfer doesn't return.
  8.1748 +		/// </summary>
  8.1749 +
  8.1750 +		private void OnReadTimeout()
  8.1751 +		{
  8.1752 +			try
  8.1753 +			{
  8.1754 +				MyMarshalDataToForm(FormActions.AddItemToListBox, "The attempt to read a report timed out.");
  8.1755 +				MyMarshalDataToForm(FormActions.ScrollToBottomOfListBox, "");
  8.1756 +				CloseCommunications();
  8.1757 +				MyMarshalDataToForm(FormActions.EnableGetInputReportInterruptTransfer, "");
  8.1758 +				_transferInProgress = false;
  8.1759 +				_sendOrGet = SendOrGet.Send;
  8.1760 +			}
  8.1761 +			catch (Exception ex)
  8.1762 +			{
  8.1763 +				DisplayException(Name, ex);
  8.1764 +				throw;
  8.1765 +			}
  8.1766 +		}
  8.1767 +
  8.1768 +		/// <summary>
  8.1769 +		/// Timeout if write via interrupt transfer doesn't return.
  8.1770 +		/// </summary>
  8.1771 +
  8.1772 +		private void OnWriteTimeout()
  8.1773 +		{
  8.1774 +			try
  8.1775 +			{
  8.1776 +				MyMarshalDataToForm(FormActions.AddItemToListBox, "The attempt to write a report timed out.");
  8.1777 +				MyMarshalDataToForm(FormActions.ScrollToBottomOfListBox, "");
  8.1778 +				CloseCommunications();
  8.1779 +				MyMarshalDataToForm(FormActions.EnableSendOutputReportInterrupt, "");
  8.1780 +				_transferInProgress = false;
  8.1781 +				_sendOrGet = SendOrGet.Get;
  8.1782 +			}
  8.1783 +			catch (Exception ex)
  8.1784 +			{
  8.1785 +				DisplayException(Name, ex);
  8.1786 +				throw;
  8.1787 +			}
  8.1788 +		}
  8.1789 +
  8.1790 +		/// <summary>
  8.1791 +		/// Alternat sending and getting a report.
  8.1792 +		/// </summary>
  8.1793 +
  8.1794 +		private void PeriodicTransfers()
  8.1795 +		{
  8.1796 +			try
  8.1797 +			{
  8.1798 +				if (!_transferInProgress)
  8.1799 +				{
  8.1800 +					if (_reportType == ReportTypes.Feature)
  8.1801 +					{
  8.1802 +						SendOrGetFeatureReport();
  8.1803 +					}
  8.1804 +					else
  8.1805 +					{
  8.1806 +						// Output and Input reports
  8.1807 +
  8.1808 +						SendOutputReportOrGetInputReport();
  8.1809 +					}
  8.1810 +				}
  8.1811 +			}
  8.1812 +			catch (Exception ex)
  8.1813 +			{
  8.1814 +				DisplayException(Name, ex);
  8.1815 +				throw;
  8.1816 +			}
  8.1817 +		}
  8.1818 +
  8.1819 +		/// <summary>
  8.1820 +		/// Start doing periodic transfers.
  8.1821 +		/// </summary>
  8.1822 +
  8.1823 +		private void PeriodicTransfersStart()
  8.1824 +		{
  8.1825 +			// Don't allow changing the transfer type while transfers are in progress.
  8.1826 +
  8.1827 +			if (radFeature.Checked)
  8.1828 +			{
  8.1829 +				radInputOutputControl.Enabled = false;
  8.1830 +				radInputOutputInterrupt.Enabled = false;
  8.1831 +			}
  8.1832 +			else if (radInputOutputControl.Checked)
  8.1833 +			{
  8.1834 +				radFeature.Enabled = false;
  8.1835 +				radInputOutputInterrupt.Enabled = false;
  8.1836 +			}
  8.1837 +			else if (radInputOutputInterrupt.Checked)
  8.1838 +			{
  8.1839 +				radFeature.Enabled = false;
  8.1840 +				radInputOutputControl.Enabled = false;
  8.1841 +			}
  8.1842 +
  8.1843 +			//  Change the command button's text.
  8.1844 +
  8.1845 +			cmdPeriodicTransfers.Text = "Stop";
  8.1846 +
  8.1847 +			//  Enable the timer event to trigger a set of transfers.
  8.1848 +
  8.1849 +			_periodicTransfers.Start();
  8.1850 +
  8.1851 +			cmdPeriodicTransfers.Enabled = true;
  8.1852 +
  8.1853 +			if (radInputOutputInterrupt.Checked)
  8.1854 +			{
  8.1855 +				_transferType = TransferTypes.Interrupt;
  8.1856 +				_reportType = ReportTypes.Output;
  8.1857 +			}
  8.1858 +			else if (radInputOutputControl.Checked)
  8.1859 +			{
  8.1860 +				_transferType = TransferTypes.Control;
  8.1861 +				_reportType = ReportTypes.Output;
  8.1862 +			}
  8.1863 +			else if (radFeature.Checked)
  8.1864 +			{
  8.1865 +				_transferType = TransferTypes.Control;
  8.1866 +				_reportType = ReportTypes.Feature;
  8.1867 +			}
  8.1868 +			_periodicTransfersRequested = true;
  8.1869 +			PeriodicTransfers();
  8.1870 +		}
  8.1871 +
  8.1872 +		/// <summary>
  8.1873 +		/// Stop doing periodic transfers.
  8.1874 +		/// </summary>
  8.1875 +
  8.1876 +		private void PeriodicTransfersStop()
  8.1877 +		{
  8.1878 +			//  Stop doing continuous transfers.
  8.1879 +
  8.1880 +			_periodicTransfersRequested = false;
  8.1881 +
  8.1882 +			// Disable the timer that triggers the transfers.	
  8.1883 +
  8.1884 +			_periodicTransfers.Stop();
  8.1885 +			cmdPeriodicTransfers.Enabled = true;
  8.1886 +
  8.1887 +			//  Change the command button's text.
  8.1888 +
  8.1889 +			cmdPeriodicTransfers.Text = "Start";
  8.1890 +
  8.1891 +			// Re-allow changing the transfer type.
  8.1892 +
  8.1893 +			radFeature.Enabled = true;
  8.1894 +			radInputOutputControl.Enabled = true;
  8.1895 +			radInputOutputInterrupt.Enabled = true;
  8.1896 +		}
  8.1897 +
  8.1898 +		private void radInputOutputControl_CheckedChanged(object sender, EventArgs e)
  8.1899 +		{
  8.1900 +		}
  8.1901 +
  8.1902 +		private void radInputOutputInterrupt_CheckedChanged(object sender, EventArgs e)
  8.1903 +		{
  8.1904 +		}
  8.1905 +
  8.1906 +		private void radFeature_CheckedChanged(object sender, EventArgs e)
  8.1907 +		{
  8.1908 +		}
  8.1909 +
  8.1910 +		///  <summary>
  8.1911 +		///  Request a Feature report.
  8.1912 +		///  Assumes report ID = 0.
  8.1913 +		///  </summary>
  8.1914 +
  8.1915 +		private void RequestToGetFeatureReport()
  8.1916 +		{
  8.1917 +			String byteValue = null;
  8.1918 +
  8.1919 +			try
  8.1920 +			{
  8.1921 +				//  If the device hasn't been detected, was removed, or timed out on a previous attempt
  8.1922 +				//  to access it, look for the device.
  8.1923 +
  8.1924 +				if (!_deviceHandleObtained)
  8.1925 +				{
  8.1926 +					_deviceHandleObtained = FindTheHid();
  8.1927 +				}
  8.1928 +
  8.1929 +				if (_deviceHandleObtained)
  8.1930 +				{
  8.1931 +					Byte[] inFeatureReportBuffer = null;
  8.1932 +
  8.1933 +					if ((_myHid.Capabilities.FeatureReportByteLength > 0))
  8.1934 +					{
  8.1935 +						//  The HID has a Feature report.	
  8.1936 +						//  Read a report from the device.
  8.1937 +
  8.1938 +						//  Set the size of the Feature report buffer. 
  8.1939 +
  8.1940 +						if ((_myHid.Capabilities.FeatureReportByteLength > 0))
  8.1941 +						{
  8.1942 +							inFeatureReportBuffer = new Byte[_myHid.Capabilities.FeatureReportByteLength];
  8.1943 +						}
  8.1944 +
  8.1945 +						//  Read a report.
  8.1946 +
  8.1947 +						Boolean success = _myHid.GetFeatureReport(_hidHandle, ref inFeatureReportBuffer);
  8.1948 +
  8.1949 +						if (success)
  8.1950 +						{
  8.1951 +							DisplayReportData(inFeatureReportBuffer, ReportTypes.Feature, ReportReadOrWritten.Read);
  8.1952 +						}
  8.1953 +						else
  8.1954 +						{
  8.1955 +							CloseCommunications();
  8.1956 +							MyMarshalDataToForm(FormActions.AddItemToListBox, "The attempt to read a Feature report failed.");
  8.1957 +							ScrollToBottomOfListBox();
  8.1958 +						}
  8.1959 +					}
  8.1960 +					else
  8.1961 +					{
  8.1962 +						MyMarshalDataToForm(FormActions.AddItemToListBox, "The HID doesn't have a Feature report.");
  8.1963 +						ScrollToBottomOfListBox();
  8.1964 +					}
  8.1965 +				}
  8.1966 +				_transferInProgress = false;
  8.1967 +				cmdGetFeatureReport.Enabled = true;
  8.1968 +			}
  8.1969 +			catch (Exception ex)
  8.1970 +			{
  8.1971 +				DisplayException(Name, ex);
  8.1972 +				throw;
  8.1973 +			}
  8.1974 +		}
  8.1975 +
  8.1976 +		///  <summary>
  8.1977 +		///  Request an Input report.
  8.1978 +		///  Assumes report ID = 0.
  8.1979 +		///  </summary>
  8.1980 +
  8.1981 +		private async void RequestToGetInputReport()
  8.1982 +		{
  8.1983 +			const Int32 readTimeout = 5000;
  8.1984 +
  8.1985 +			String byteValue = null;
  8.1986 +			Byte[] inputReportBuffer = null;
  8.1987 +
  8.1988 +			try
  8.1989 +			{
  8.1990 +				Boolean success = false;
  8.1991 +
  8.1992 +				//  If the device hasn't been detected, was removed, or timed out on a previous attempt
  8.1993 +				//  to access it, look for the device.
  8.1994 +
  8.1995 +				if (!_deviceHandleObtained)
  8.1996 +				{
  8.1997 +					_deviceHandleObtained = FindTheHid();
  8.1998 +				}
  8.1999 +
  8.2000 +				if (_deviceHandleObtained)
  8.2001 +				{
  8.2002 +					//  Don't attempt to exchange reports if valid handles aren't available
  8.2003 +					//  (as for a mouse or keyboard under Windows 2000 and later.)
  8.2004 +
  8.2005 +					if (!_hidHandle.IsInvalid)
  8.2006 +					{
  8.2007 +						//  Read an Input report.
  8.2008 +
  8.2009 +						//  Don't attempt to send an Input report if the HID has no Input report.
  8.2010 +						//  (The HID spec requires all HIDs to have an interrupt IN endpoint,
  8.2011 +						//  which suggests that all HIDs must support Input reports.)
  8.2012 +
  8.2013 +						if (_myHid.Capabilities.InputReportByteLength > 0)
  8.2014 +						{
  8.2015 +							//  Set the size of the Input report buffer. 
  8.2016 +
  8.2017 +							inputReportBuffer = new Byte[_myHid.Capabilities.InputReportByteLength];
  8.2018 +
  8.2019 +							if (_transferType.Equals(TransferTypes.Control))
  8.2020 +							{
  8.2021 +								{
  8.2022 +									_transferInProgress = true;
  8.2023 +
  8.2024 +									//  Read a report using a control transfer.
  8.2025 +
  8.2026 +									success = _myHid.GetInputReportViaControlTransfer(_hidHandle, ref inputReportBuffer);
  8.2027 +									cmdGetInputReportControl.Enabled = true;
  8.2028 +									_transferInProgress = false;
  8.2029 +								}
  8.2030 +							}
  8.2031 +							else
  8.2032 +							{
  8.2033 +								{
  8.2034 +									_transferInProgress = true;
  8.2035 +
  8.2036 +									//  Read a report using interrupt transfers. 
  8.2037 +									//  Timeout if no report available.
  8.2038 +									//  To enable reading a report without blocking the calling thread, uses Filestream's ReadAsync method.                                               
  8.2039 +
  8.2040 +									// Create a delegate to execute on a timeout.
  8.2041 +
  8.2042 +									Action onReadTimeoutAction = OnReadTimeout;
  8.2043 +
  8.2044 +									// The CancellationTokenSource specifies the timeout value and the action to take on a timeout.
  8.2045 +
  8.2046 +									var cts = new CancellationTokenSource();
  8.2047 +
  8.2048 +									// Cancel the read if it hasn't completed after a timeout.
  8.2049 +
  8.2050 +									cts.CancelAfter(readTimeout);
  8.2051 +
  8.2052 +									// Specify the function to call on a timeout.
  8.2053 +
  8.2054 +									cts.Token.Register(onReadTimeoutAction);
  8.2055 +
  8.2056 +									// Stops waiting when data is available or on timeout:
  8.2057 +
  8.2058 +									Int32 bytesRead = await _myHid.GetInputReportViaInterruptTransfer(_deviceData, inputReportBuffer, cts);
  8.2059 +
  8.2060 +									// Arrive here only if the operation completed.
  8.2061 +
  8.2062 +									// Dispose to stop the timeout timer. 
  8.2063 +
  8.2064 +									cts.Dispose();
  8.2065 +
  8.2066 +									_transferInProgress = false;
  8.2067 +									cmdGetInputReportInterrupt.Enabled = true;
  8.2068 +
  8.2069 +									if (bytesRead > 0)
  8.2070 +									{
  8.2071 +										success = true;
  8.2072 +										Debug.Print("bytes read (includes report ID) = " + Convert.ToString(bytesRead));
  8.2073 +									}
  8.2074 +								}
  8.2075 +							}
  8.2076 +						}
  8.2077 +						else
  8.2078 +						{
  8.2079 +							MyMarshalDataToForm(FormActions.AddItemToListBox, "No attempt to read an Input report was made.");
  8.2080 +							MyMarshalDataToForm(FormActions.AddItemToListBox, "The HID doesn't have an Input report.");
  8.2081 +						}
  8.2082 +					}
  8.2083 +					else
  8.2084 +					{
  8.2085 +						MyMarshalDataToForm(FormActions.AddItemToListBox, "Invalid handle.");
  8.2086 +						MyMarshalDataToForm(FormActions.AddItemToListBox,
  8.2087 +											"No attempt to write an Output report or read an Input report was made.");
  8.2088 +					}
  8.2089 +
  8.2090 +					if (success)
  8.2091 +					{
  8.2092 +						DisplayReportData(inputReportBuffer, ReportTypes.Input, ReportReadOrWritten.Read);
  8.2093 +					}
  8.2094 +					else
  8.2095 +					{
  8.2096 +						CloseCommunications();
  8.2097 +						MyMarshalDataToForm(FormActions.AddItemToListBox, "The attempt to read an Input report has failed.");
  8.2098 +						ScrollToBottomOfListBox();
  8.2099 +					}
  8.2100 +				}
  8.2101 +			}
  8.2102 +
  8.2103 +			catch (Exception ex)
  8.2104 +			{
  8.2105 +				DisplayException(Name, ex);
  8.2106 +				throw;
  8.2107 +			}
  8.2108 +		}
  8.2109 +
  8.2110 +		///  <summary>
  8.2111 +		///  Sends a Feature report.
  8.2112 +		///  Assumes report ID = 0.
  8.2113 +		///  </summary>
  8.2114 +
  8.2115 +		private void RequestToSendFeatureReport()
  8.2116 +		{
  8.2117 +			String byteValue = null;
  8.2118 +
  8.2119 +			try
  8.2120 +			{
  8.2121 +				_transferInProgress = true;
  8.2122 +
  8.2123 +				//  If the device hasn't been detected, was removed, or timed out on a previous attempt
  8.2124 +				//  to access it, look for the device.
  8.2125 +
  8.2126 +				if (!_deviceHandleObtained)
  8.2127 +				{
  8.2128 +					_deviceHandleObtained = FindTheHid();
  8.2129 +				}
  8.2130 +
  8.2131 +				if (_deviceHandleObtained)
  8.2132 +				{
  8.2133 +					GetBytesToSend();
  8.2134 +
  8.2135 +					if ((_myHid.Capabilities.FeatureReportByteLength > 0))
  8.2136 +					{
  8.2137 +						//  The HID has a Feature report.
  8.2138 +						//  Set the size of the Feature report buffer. 
  8.2139 +
  8.2140 +						var outFeatureReportBuffer = new Byte[_myHid.Capabilities.FeatureReportByteLength];
  8.2141 +
  8.2142 +						//  Store the report ID in the buffer.
  8.2143 +
  8.2144 +						outFeatureReportBuffer[0] = 0;
  8.2145 +
  8.2146 +						//  Store the report data following the report ID.
  8.2147 +						//  Use the data in the combo boxes on the form.
  8.2148 +
  8.2149 +						outFeatureReportBuffer[1] = Convert.ToByte(CboByte0.SelectedIndex);
  8.2150 +
  8.2151 +						if (outFeatureReportBuffer.GetUpperBound(0) > 1)
  8.2152 +						{
  8.2153 +							outFeatureReportBuffer[2] = Convert.ToByte(CboByte1.SelectedIndex);
  8.2154 +						}
  8.2155 +
  8.2156 +						//  Write a report to the device
  8.2157 +
  8.2158 +						Boolean success = _myHid.SendFeatureReport(_hidHandle, outFeatureReportBuffer);
  8.2159 +
  8.2160 +						if (success)
  8.2161 +						{
  8.2162 +							DisplayReportData(outFeatureReportBuffer, ReportTypes.Feature, ReportReadOrWritten.Written);
  8.2163 +						}
  8.2164 +						else
  8.2165 +						{
  8.2166 +							CloseCommunications();
  8.2167 +							AccessForm(FormActions.AddItemToListBox, "The attempt to send a Feature report failed.");
  8.2168 +							ScrollToBottomOfListBox();
  8.2169 +						}
  8.2170 +					}
  8.2171 +
  8.2172 +					else
  8.2173 +					{
  8.2174 +						AccessForm(FormActions.AddItemToListBox, "The HID doesn't have a Feature report.");
  8.2175 +						ScrollToBottomOfListBox();
  8.2176 +					}
  8.2177 +
  8.2178 +				}
  8.2179 +				_transferInProgress = false;
  8.2180 +				cmdSendFeatureReport.Enabled = true;
  8.2181 +				ScrollToBottomOfListBox();
  8.2182 +
  8.2183 +			}
  8.2184 +			catch (Exception ex)
  8.2185 +			{
  8.2186 +				DisplayException(Name, ex);
  8.2187 +				throw;
  8.2188 +			}
  8.2189 +		}
  8.2190 +
  8.2191 +		///  <summary>
  8.2192 +		///  Sends an Output report.
  8.2193 +		///  Assumes report ID = 0.
  8.2194 +		///  </summary>
  8.2195 +
  8.2196 +		private async void RequestToSendOutputReport()
  8.2197 +		{
  8.2198 +			const Int32 writeTimeout = 5000;
  8.2199 +			String byteValue = null;
  8.2200 +
  8.2201 +			try
  8.2202 +			{
  8.2203 +				//  If the device hasn't been detected, was removed, or timed out on a previous attempt
  8.2204 +				//  to access it, look for the device.
  8.2205 +
  8.2206 +				if (!_deviceHandleObtained)
  8.2207 +				{
  8.2208 +					_deviceHandleObtained = FindTheHid();
  8.2209 +				}
  8.2210 +
  8.2211 +				if (_deviceHandleObtained)
  8.2212 +				{
  8.2213 +					GetBytesToSend();
  8.2214 +				}
  8.2215 +				//  Don't attempt to exchange reports if valid handles aren't available
  8.2216 +				//  (as for a mouse or keyboard.)
  8.2217 +
  8.2218 +				if (!_hidHandle.IsInvalid)
  8.2219 +				{
  8.2220 +					//  Don't attempt to send an Output report if the HID has no Output report.
  8.2221 +
  8.2222 +					if (_myHid.Capabilities.OutputReportByteLength > 0)
  8.2223 +					{
  8.2224 +						//  Set the size of the Output report buffer.   
  8.2225 +
  8.2226 +						var outputReportBuffer = new Byte[_myHid.Capabilities.OutputReportByteLength];
  8.2227 +
  8.2228 +						//  Store the report ID in the first byte of the buffer:
  8.2229 +
  8.2230 +						outputReportBuffer[0] = 0;
  8.2231 +
  8.2232 +						//  Store the report data following the report ID.
  8.2233 +						//  Use the data in the combo boxes on the form.
  8.2234 +
  8.2235 +						outputReportBuffer[1] = Convert.ToByte(CboByte0.SelectedIndex);
  8.2236 +
  8.2237 +						if (outputReportBuffer.GetUpperBound(0) > 1)
  8.2238 +						{
  8.2239 +							outputReportBuffer[2] = Convert.ToByte(CboByte1.SelectedIndex);
  8.2240 +						}
  8.2241 +
  8.2242 +						//  Write a report.
  8.2243 +
  8.2244 +						Boolean success;
  8.2245 +
  8.2246 +						if (_transferType.Equals(TransferTypes.Control))
  8.2247 +						{
  8.2248 +							{
  8.2249 +								_transferInProgress = true;
  8.2250 +
  8.2251 +								//  Use a control transfer to send the report,
  8.2252 +								//  even if the HID has an interrupt OUT endpoint.
  8.2253 +
  8.2254 +								success = _myHid.SendOutputReportViaControlTransfer(_hidHandle, outputReportBuffer);
  8.2255 +
  8.2256 +								_transferInProgress = false;
  8.2257 +								cmdSendOutputReportControl.Enabled = true;
  8.2258 +							}
  8.2259 +						}
  8.2260 +						else
  8.2261 +						{
  8.2262 +							Debug.Print("interrupt");
  8.2263 +							_transferInProgress = true;
  8.2264 +
  8.2265 +							// The CancellationTokenSource specifies the timeout value and the action to take on a timeout.
  8.2266 +
  8.2267 +							var cts = new CancellationTokenSource();
  8.2268 +
  8.2269 +							// Create a delegate to execute on a timeout.
  8.2270 +
  8.2271 +							Action onWriteTimeoutAction = OnWriteTimeout;
  8.2272 +
  8.2273 +							// Cancel the read if it hasn't completed after a timeout.
  8.2274 +
  8.2275 +							cts.CancelAfter(writeTimeout);
  8.2276 +
  8.2277 +							// Specify the function to call on a timeout.
  8.2278 +
  8.2279 +							cts.Token.Register(onWriteTimeoutAction);
  8.2280 +
  8.2281 +							// Send an Output report and wait for completion or timeout.
  8.2282 +
  8.2283 +							success = await _myHid.SendOutputReportViaInterruptTransfer(_deviceData, _hidHandle, outputReportBuffer, cts);
  8.2284 +
  8.2285 +							// Get here only if the operation completes without a timeout.
  8.2286 +
  8.2287 +							_transferInProgress = false;
  8.2288 +							cmdSendOutputReportInterrupt.Enabled = true;
  8.2289 +
  8.2290 +							// Dispose to stop the timeout timer.
  8.2291 +
  8.2292 +							cts.Dispose();
  8.2293 +						}
  8.2294 +						if (success)
  8.2295 +						{
  8.2296 +							DisplayReportData(outputReportBuffer, ReportTypes.Output, ReportReadOrWritten.Written);
  8.2297 +						}
  8.2298 +						else
  8.2299 +						{
  8.2300 +							CloseCommunications();
  8.2301 +							AccessForm(FormActions.AddItemToListBox, "The attempt to write an Output report failed.");
  8.2302 +							ScrollToBottomOfListBox();
  8.2303 +						}
  8.2304 +					}
  8.2305 +				}
  8.2306 +				else
  8.2307 +				{
  8.2308 +					AccessForm(FormActions.AddItemToListBox, "The HID doesn't have an Output report.");
  8.2309 +				}
  8.2310 +			}
  8.2311 +
  8.2312 +			catch (Exception ex)
  8.2313 +			{
  8.2314 +				DisplayException(Name, ex);
  8.2315 +				throw;
  8.2316 +			}
  8.2317 +		}
  8.2318 +
  8.2319 +		///  <summary>
  8.2320 +		///  Scroll to the bottom of the list box and trim as needed.
  8.2321 +		///  </summary>
  8.2322 +
  8.2323 +		private void ScrollToBottomOfListBox()
  8.2324 +		{
  8.2325 +			try
  8.2326 +			{
  8.2327 +				LstResults.SelectedIndex = LstResults.Items.Count - 1;
  8.2328 +
  8.2329 +				//  If the list box is getting too large, trim its contents by removing the earliest data.
  8.2330 +
  8.2331 +				if (LstResults.Items.Count > 1000)
  8.2332 +				{
  8.2333 +					Int32 count;
  8.2334 +					for (count = 1; count <= 500; count++)
  8.2335 +					{
  8.2336 +						LstResults.Items.RemoveAt(4);
  8.2337 +					}
  8.2338 +				}
  8.2339 +			}
  8.2340 +			catch (Exception ex)
  8.2341 +			{
  8.2342 +				DisplayException(Name, ex);
  8.2343 +				throw;
  8.2344 +			}
  8.2345 +		}
  8.2346 +
  8.2347 +		/// <summary>
  8.2348 +		/// Request to send or get a Feature report.
  8.2349 +		/// </summary>
  8.2350 +
  8.2351 +		private void SendOrGetFeatureReport()
  8.2352 +		{
  8.2353 +			try
  8.2354 +			{
  8.2355 +				//  If the device hasn't been detected, was removed, or timed out on a previous attempt
  8.2356 +				//  to access it, look for the device.
  8.2357 +
  8.2358 +				if (!_deviceHandleObtained)
  8.2359 +				{
  8.2360 +					_deviceHandleObtained = FindTheHid();
  8.2361 +				}
  8.2362 +
  8.2363 +				if (_deviceHandleObtained)
  8.2364 +				{
  8.2365 +					switch (_sendOrGet)
  8.2366 +					{
  8.2367 +						case SendOrGet.Send:
  8.2368 +							RequestToSendFeatureReport();
  8.2369 +							_sendOrGet = SendOrGet.Get;
  8.2370 +							break;
  8.2371 +						case SendOrGet.Get:
  8.2372 +							RequestToGetFeatureReport();
  8.2373 +							_sendOrGet = SendOrGet.Send;
  8.2374 +							break;
  8.2375 +					}
  8.2376 +				}
  8.2377 +			}
  8.2378 +			catch (Exception ex)
  8.2379 +			{
  8.2380 +				DisplayException(Name, ex);
  8.2381 +				throw;
  8.2382 +			}
  8.2383 +		}
  8.2384 +
  8.2385 +		/// <summary>
  8.2386 +		/// Request to send an Output report or get an Input report.
  8.2387 +		/// </summary>
  8.2388 +
  8.2389 +		private void SendOutputReportOrGetInputReport()
  8.2390 +		{
  8.2391 +			try
  8.2392 +			{
  8.2393 +				//  If the device hasn't been detected, was removed, or timed out on a previous attempt
  8.2394 +				//  to access it, look for the device.
  8.2395 +
  8.2396 +				if (!_deviceHandleObtained)
  8.2397 +				{
  8.2398 +					_deviceHandleObtained = FindTheHid();
  8.2399 +				}
  8.2400 +
  8.2401 +				if (_deviceHandleObtained)
  8.2402 +				{
  8.2403 +					if (_sendOrGet == SendOrGet.Send)
  8.2404 +					{
  8.2405 +						RequestToSendOutputReport();
  8.2406 +						_sendOrGet = SendOrGet.Get;
  8.2407 +					}
  8.2408 +					else
  8.2409 +					{
  8.2410 +						RequestToGetInputReport();
  8.2411 +						_sendOrGet = SendOrGet.Send;
  8.2412 +					}
  8.2413 +				}
  8.2414 +			}
  8.2415 +			catch (Exception ex)
  8.2416 +			{
  8.2417 +				DisplayException(Name, ex);
  8.2418 +				throw;
  8.2419 +			}
  8.2420 +		}
  8.2421 +
  8.2422 +		///  <summary>
  8.2423 +		///  Set the number of Input buffers (the number of Input reports 
  8.2424 +		///  the host will store) from the value in the text box.
  8.2425 +		///  </summary>
  8.2426 +
  8.2427 +		private void SetInputReportBufferSize()
  8.2428 +		{
  8.2429 +			try
  8.2430 +			{
  8.2431 +				if (!_transferInProgress)
  8.2432 +				{
  8.2433 +					//  Get the number of buffers from the text box.
  8.2434 +
  8.2435 +					Int32 numberOfInputBuffers = Convert.ToInt32(txtInputReportBufferSize.Text);
  8.2436 +
  8.2437 +					//  Set the number of buffers.
  8.2438 +
  8.2439 +					_myHid.SetNumberOfInputBuffers(_hidHandle, numberOfInputBuffers);
  8.2440 +
  8.2441 +					//  Verify and display the result.
  8.2442 +
  8.2443 +					GetInputReportBufferSize();
  8.2444 +				}
  8.2445 +				else
  8.2446 +				{
  8.2447 +					DisplayTransferInProgressMessage();
  8.2448 +				}
  8.2449 +			}
  8.2450 +			catch (Exception ex)
  8.2451 +			{
  8.2452 +				DisplayException(Name, ex);
  8.2453 +				throw;
  8.2454 +			}
  8.2455 +		}
  8.2456 +
  8.2457 +		///  <summary>
  8.2458 +		///  Perform actions that must execute when the program ends.
  8.2459 +		///  </summary>
  8.2460 +
  8.2461 +		private void Shutdown()
  8.2462 +		{
  8.2463 +			try
  8.2464 +			{
  8.2465 +				CloseCommunications();
  8.2466 +				DeviceNotificationsStop();
  8.2467 +			}
  8.2468 +			catch (Exception ex)
  8.2469 +			{
  8.2470 +				DisplayException(Name, ex);
  8.2471 +				throw;
  8.2472 +			}
  8.2473 +		}
  8.2474 +
  8.2475 +		///  <summary>
  8.2476 +		///  Perform actions that must execute when the program starts.
  8.2477 +		///  </summary>
  8.2478 +
  8.2479 +		private void Startup()
  8.2480 +		{
  8.2481 +			const Int32 periodicTransferInterval = 1000;
  8.2482 +			try
  8.2483 +			{
  8.2484 +				_myHid = new Hid();
  8.2485 +				InitializeDisplay();
  8.2486 +
  8.2487 +				_periodicTransfers = new System.Timers.Timer(periodicTransferInterval);
  8.2488 +				_periodicTransfers.Elapsed += DoPeriodicTransfers;
  8.2489 +				_periodicTransfers.Stop();
  8.2490 +				_periodicTransfers.SynchronizingObject = this;
  8.2491 +
  8.2492 +				//  Default USB Vendor ID and Product ID:
  8.2493 +
  8.2494 +				txtVendorID.Text = "0925";
  8.2495 +				txtProductID.Text = "7001";
  8.2496 +
  8.2497 +				GetVendorAndProductIDsFromTextBoxes(ref _myVendorId, ref _myProductId);
  8.2498 +
  8.2499 +				DeviceNotificationsStart();
  8.2500 +				FindDeviceUsingWmi();
  8.2501 +				FindTheHid();
  8.2502 +			}
  8.2503 +			catch (Exception ex)
  8.2504 +			{
  8.2505 +				DisplayException(Name, ex);
  8.2506 +				throw;
  8.2507 +			}
  8.2508 +		}
  8.2509 +
  8.2510 +		///  <summary>
  8.2511 +		///  The Product ID has changed in the text box. Call a routine to handle it.
  8.2512 +		///  </summary>
  8.2513 +
  8.2514 +		private void txtProductID_TextChanged(Object sender, EventArgs e)
  8.2515 +		{
  8.2516 +			try
  8.2517 +			{
  8.2518 +				DeviceHasChanged();
  8.2519 +			}
  8.2520 +			catch (Exception ex)
  8.2521 +			{
  8.2522 +				DisplayException(Name, ex);
  8.2523 +				throw;
  8.2524 +			}
  8.2525 +		}
  8.2526 +
  8.2527 +		///  <summary>
  8.2528 +		///  The Vendor ID has changed in the text box. Call a routine to handle it.
  8.2529 +		///  </summary>
  8.2530 +
  8.2531 +		private void txtVendorID_TextChanged(Object sender, EventArgs e)
  8.2532 +		{
  8.2533 +			try
  8.2534 +			{
  8.2535 +				DeviceHasChanged();
  8.2536 +			}
  8.2537 +			catch (Exception ex)
  8.2538 +			{
  8.2539 +				DisplayException(Name, ex);
  8.2540 +				throw;
  8.2541 +			}
  8.2542 +		}
  8.2543 +
  8.2544 +		///  <summary>
  8.2545 +		///  Provides a central mechanism for exception handling.
  8.2546 +		///  Displays a message box that describes the exception.
  8.2547 +		///  </summary>
  8.2548 +		///  
  8.2549 +		///  <param name="moduleName"> the module where the exception occurred. </param>
  8.2550 +		///  <param name="e"> the exception </param>
  8.2551 +
  8.2552 +		internal static void DisplayException(String moduleName, Exception e)
  8.2553 +		{
  8.2554 +			//  Create an error message.
  8.2555 +
  8.2556 +			String message = "Exception: " + e.Message + Environment.NewLine + "Module: " + moduleName + Environment.NewLine + "Method: " + e.TargetSite.Name;
  8.2557 +
  8.2558 +			const String caption = "Unexpected Exception";
  8.2559 +
  8.2560 +			MessageBox.Show(message, caption, MessageBoxButtons.OK);
  8.2561 +			Debug.Write(message);
  8.2562 +
  8.2563 +			// Get the last error and display it. 
  8.2564 +
  8.2565 +			Int32 error = Marshal.GetLastWin32Error();
  8.2566 +
  8.2567 +			Debug.WriteLine("The last Win32 Error was: " + error);
  8.2568 +		}
  8.2569 +
  8.2570 +		[STAThread]
  8.2571 +		internal static void Main() { Application.Run(new FrmMain()); }
  8.2572 +		private static FrmMain _transDefaultFormFrmMain;
  8.2573 +		internal static FrmMain TransDefaultFormFrmMain
  8.2574 +		{
  8.2575 +			get
  8.2576 +			{
  8.2577 +				if (_transDefaultFormFrmMain == null)
  8.2578 +				{
  8.2579 +					_transDefaultFormFrmMain = new FrmMain();
  8.2580 +				}
  8.2581 +				return _transDefaultFormFrmMain;
  8.2582 +			}
  8.2583 +		}
  8.2584 +	}
  8.2585 +}
     9.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.2 +++ b/FrmMain.resX	Wed May 14 07:52:21 2014 +0200
     9.3 @@ -0,0 +1,126 @@
     9.4 +<?xml version="1.0" encoding="utf-8"?>
     9.5 +<root>
     9.6 +  <!-- 
     9.7 +    Microsoft ResX Schema 
     9.8 +    
     9.9 +    Version 2.0
    9.10 +    
    9.11 +    The primary goals of this format is to allow a simple XML format 
    9.12 +    that is mostly human readable. The generation and parsing of the 
    9.13 +    various data types are done through the TypeConverter classes 
    9.14 +    associated with the data types.
    9.15 +    
    9.16 +    Example:
    9.17 +    
    9.18 +    ... ado.net/XML headers & schema ...
    9.19 +    <resheader name="resmimetype">text/microsoft-resx</resheader>
    9.20 +    <resheader name="version">2.0</resheader>
    9.21 +    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
    9.22 +    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
    9.23 +    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
    9.24 +    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
    9.25 +    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
    9.26 +        <value>[base64 mime encoded serialized .NET Framework object]</value>
    9.27 +    </data>
    9.28 +    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
    9.29 +        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
    9.30 +        <comment>This is a comment</comment>
    9.31 +    </data>
    9.32 +                
    9.33 +    There are any number of "resheader" rows that contain simple 
    9.34 +    name/value pairs.
    9.35 +    
    9.36 +    Each data row contains a name, and value. The row also contains a 
    9.37 +    type or mimetype. Type corresponds to a .NET class that support 
    9.38 +    text/value conversion through the TypeConverter architecture. 
    9.39 +    Classes that don't support this are serialized and stored with the 
    9.40 +    mimetype set.
    9.41 +    
    9.42 +    The mimetype is used for serialized objects, and tells the 
    9.43 +    ResXResourceReader how to depersist the object. This is currently not 
    9.44 +    extensible. For a given mimetype the value must be set accordingly:
    9.45 +    
    9.46 +    Note - application/x-microsoft.net.object.binary.base64 is the format 
    9.47 +    that the ResXResourceWriter will generate, however the reader can 
    9.48 +    read any of the formats listed below.
    9.49 +    
    9.50 +    mimetype: application/x-microsoft.net.object.binary.base64
    9.51 +    value   : The object must be serialized with 
    9.52 +            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
    9.53 +            : and then encoded with base64 encoding.
    9.54 +    
    9.55 +    mimetype: application/x-microsoft.net.object.soap.base64
    9.56 +    value   : The object must be serialized with 
    9.57 +            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
    9.58 +            : and then encoded with base64 encoding.
    9.59 +
    9.60 +    mimetype: application/x-microsoft.net.object.bytearray.base64
    9.61 +    value   : The object must be serialized into a byte array 
    9.62 +            : using a System.ComponentModel.TypeConverter
    9.63 +            : and then encoded with base64 encoding.
    9.64 +    -->
    9.65 +  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
    9.66 +    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
    9.67 +    <xsd:element name="root" msdata:IsDataSet="true">
    9.68 +      <xsd:complexType>
    9.69 +        <xsd:choice maxOccurs="unbounded">
    9.70 +          <xsd:element name="metadata">
    9.71 +            <xsd:complexType>
    9.72 +              <xsd:sequence>
    9.73 +                <xsd:element name="value" type="xsd:string" minOccurs="0" />
    9.74 +              </xsd:sequence>
    9.75 +              <xsd:attribute name="name" use="required" type="xsd:string" />
    9.76 +              <xsd:attribute name="type" type="xsd:string" />
    9.77 +              <xsd:attribute name="mimetype" type="xsd:string" />
    9.78 +              <xsd:attribute ref="xml:space" />
    9.79 +            </xsd:complexType>
    9.80 +          </xsd:element>
    9.81 +          <xsd:element name="assembly">
    9.82 +            <xsd:complexType>
    9.83 +              <xsd:attribute name="alias" type="xsd:string" />
    9.84 +              <xsd:attribute name="name" type="xsd:string" />
    9.85 +            </xsd:complexType>
    9.86 +          </xsd:element>
    9.87 +          <xsd:element name="data">
    9.88 +            <xsd:complexType>
    9.89 +              <xsd:sequence>
    9.90 +                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
    9.91 +                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
    9.92 +              </xsd:sequence>
    9.93 +              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
    9.94 +              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
    9.95 +              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
    9.96 +              <xsd:attribute ref="xml:space" />
    9.97 +            </xsd:complexType>
    9.98 +          </xsd:element>
    9.99 +          <xsd:element name="resheader">
   9.100 +            <xsd:complexType>
   9.101 +              <xsd:sequence>
   9.102 +                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
   9.103 +              </xsd:sequence>
   9.104 +              <xsd:attribute name="name" type="xsd:string" use="required" />
   9.105 +            </xsd:complexType>
   9.106 +          </xsd:element>
   9.107 +        </xsd:choice>
   9.108 +      </xsd:complexType>
   9.109 +    </xsd:element>
   9.110 +  </xsd:schema>
   9.111 +  <resheader name="resmimetype">
   9.112 +    <value>text/microsoft-resx</value>
   9.113 +  </resheader>
   9.114 +  <resheader name="version">
   9.115 +    <value>2.0</value>
   9.116 +  </resheader>
   9.117 +  <resheader name="reader">
   9.118 +    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
   9.119 +  </resheader>
   9.120 +  <resheader name="writer">
   9.121 +    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
   9.122 +  </resheader>
   9.123 +  <metadata name="ToolTip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
   9.124 +    <value>17, 17</value>
   9.125 +  </metadata>
   9.126 +  <metadata name="$this.TrayHeight" type="System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
   9.127 +    <value>25</value>
   9.128 +  </metadata>
   9.129 +</root>
   9.130 \ No newline at end of file
    10.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.2 +++ b/GenericHid.cs	Wed May 14 07:52:21 2014 +0200
    10.3 @@ -0,0 +1,24 @@
    10.4 +
    10.5 +using System.Windows.Forms;
    10.6 +
    10.7 +namespace GenericHid
    10.8 +{
    10.9 +	/// <summary>
   10.10 +	///  Runs the application and provides access to the instance of the form.
   10.11 +	/// </summary> 
   10.12 +	  
   10.13 +	public class GenericHid  
   10.14 +	{ 
   10.15 +		internal static FrmMain FrmMy; 
   10.16 +		
   10.17 +		/// <summary>
   10.18 +		///  Displays the application's main form.
   10.19 +		/// </summary> 
   10.20 +		
   10.21 +		public static void Main() 
   10.22 +		{ 
   10.23 +			FrmMy = new FrmMain(); 
   10.24 +			Application.Run(FrmMy); 
   10.25 +		} 
   10.26 +	} 
   10.27 +} 
    11.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.2 +++ b/GenericHid.csproj	Wed May 14 07:52:21 2014 +0200
    11.3 @@ -0,0 +1,194 @@
    11.4 +<?xml version="1.0" encoding="utf-8"?>
    11.5 +<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
    11.6 +  <PropertyGroup>
    11.7 +    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
    11.8 +    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
    11.9 +    <ProductVersion>9.0.30729</ProductVersion>
   11.10 +    <SchemaVersion>2.0</SchemaVersion>
   11.11 +    <ProjectGuid>{A6E0F52F-4599-4758-B956-9E8420FD28A8}</ProjectGuid>
   11.12 +    <OutputType>WinExe</OutputType>
   11.13 +    <AppDesignerFolder>Properties</AppDesignerFolder>
   11.14 +    <RootNamespace>GenericHid</RootNamespace>
   11.15 +    <AssemblyName>GenericHid</AssemblyName>
   11.16 +    <StartupObject>GenericHid.FrmMain</StartupObject>
   11.17 +    <FileUpgradeFlags>
   11.18 +    </FileUpgradeFlags>
   11.19 +    <OldToolsVersion>3.5</OldToolsVersion>
   11.20 +    <UpgradeBackupLocation>
   11.21 +    </UpgradeBackupLocation>
   11.22 +    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
   11.23 +    <TargetFrameworkProfile />
   11.24 +    <IsWebBootstrapper>false</IsWebBootstrapper>
   11.25 +    <PublishUrl>publish\</PublishUrl>
   11.26 +    <Install>true</Install>
   11.27 +    <InstallFrom>Disk</InstallFrom>
   11.28 +    <UpdateEnabled>false</UpdateEnabled>
   11.29 +    <UpdateMode>Foreground</UpdateMode>
   11.30 +    <UpdateInterval>7</UpdateInterval>
   11.31 +    <UpdateIntervalUnits>Days</UpdateIntervalUnits>
   11.32 +    <UpdatePeriodically>false</UpdatePeriodically>
   11.33 +    <UpdateRequired>false</UpdateRequired>
   11.34 +    <MapFileExtensions>true</MapFileExtensions>
   11.35 +    <ApplicationRevision>0</ApplicationRevision>
   11.36 +    <ApplicationVersion>6.2.0.0</ApplicationVersion>
   11.37 +    <UseApplicationTrust>false</UseApplicationTrust>
   11.38 +    <PublishWizardCompleted>true</PublishWizardCompleted>
   11.39 +    <BootstrapperEnabled>true</BootstrapperEnabled>
   11.40 +  </PropertyGroup>
   11.41 +  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
   11.42 +    <DebugSymbols>true</DebugSymbols>
   11.43 +    <DebugType>full</DebugType>
   11.44 +    <Optimize>false</Optimize>
   11.45 +    <OutputPath>bin\Debug\</OutputPath>
   11.46 +    <DefineConstants>DEBUG;TRACE</DefineConstants>
   11.47 +    <ErrorReport>prompt</ErrorReport>
   11.48 +    <WarningLevel>2</WarningLevel>
   11.49 +    <BaseAddress>285212672</BaseAddress>
   11.50 +    <Prefer32Bit>false</Prefer32Bit>
   11.51 +  </PropertyGroup>
   11.52 +  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
   11.53 +    <DebugType>pdbonly</DebugType>
   11.54 +    <Optimize>false</Optimize>
   11.55 +    <OutputPath>bin\Release\</OutputPath>
   11.56 +    <DefineConstants>TRACE</DefineConstants>
   11.57 +    <ErrorReport>prompt</ErrorReport>
   11.58 +    <WarningLevel>2</WarningLevel>
   11.59 +    <BaseAddress>285212672</BaseAddress>
   11.60 +    <Prefer32Bit>false</Prefer32Bit>
   11.61 +  </PropertyGroup>
   11.62 +  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
   11.63 +    <DebugSymbols>true</DebugSymbols>
   11.64 +    <OutputPath>bin\x86\Debug\</OutputPath>
   11.65 +    <DefineConstants>DEBUG;TRACE</DefineConstants>
   11.66 +    <BaseAddress>285212672</BaseAddress>
   11.67 +    <WarningLevel>2</WarningLevel>
   11.68 +    <DebugType>full</DebugType>
   11.69 +    <PlatformTarget>x86</PlatformTarget>
   11.70 +    <ErrorReport>prompt</ErrorReport>
   11.71 +    <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
   11.72 +  </PropertyGroup>
   11.73 +  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
   11.74 +    <OutputPath>bin\x86\Release\</OutputPath>
   11.75 +    <DefineConstants>TRACE</DefineConstants>
   11.76 +    <BaseAddress>285212672</BaseAddress>
   11.77 +    <WarningLevel>2</WarningLevel>
   11.78 +    <DebugType>pdbonly</DebugType>
   11.79 +    <PlatformTarget>x86</PlatformTarget>
   11.80 +    <ErrorReport>prompt</ErrorReport>
   11.81 +    <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
   11.82 +  </PropertyGroup>
   11.83 +  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
   11.84 +    <DebugSymbols>true</DebugSymbols>
   11.85 +    <OutputPath>bin\x64\Debug\</OutputPath>
   11.86 +    <DefineConstants>DEBUG;TRACE</DefineConstants>
   11.87 +    <BaseAddress>285212672</BaseAddress>
   11.88 +    <WarningLevel>2</WarningLevel>
   11.89 +    <DebugType>full</DebugType>
   11.90 +    <PlatformTarget>x64</PlatformTarget>
   11.91 +    <ErrorReport>prompt</ErrorReport>
   11.92 +    <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
   11.93 +  </PropertyGroup>
   11.94 +  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
   11.95 +    <OutputPath>bin\x64\Release\</OutputPath>
   11.96 +    <DefineConstants>TRACE</DefineConstants>
   11.97 +    <BaseAddress>285212672</BaseAddress>
   11.98 +    <WarningLevel>2</WarningLevel>
   11.99 +    <DebugType>pdbonly</DebugType>
  11.100 +    <PlatformTarget>x64</PlatformTarget>
  11.101 +    <ErrorReport>prompt</ErrorReport>
  11.102 +    <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
  11.103 +  </PropertyGroup>
  11.104 +  <PropertyGroup>
  11.105 +    <ManifestCertificateThumbprint>74AEA279A1F2ABCF00D2AB2668EE07AB57384C56</ManifestCertificateThumbprint>
  11.106 +  </PropertyGroup>
  11.107 +  <PropertyGroup>
  11.108 +    <ManifestKeyFile>GenericHid_TemporaryKey.pfx</ManifestKeyFile>
  11.109 +  </PropertyGroup>
  11.110 +  <PropertyGroup>
  11.111 +    <GenerateManifests>true</GenerateManifests>
  11.112 +  </PropertyGroup>
  11.113 +  <PropertyGroup>
  11.114 +    <SignManifests>true</SignManifests>
  11.115 +  </PropertyGroup>
  11.116 +  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
  11.117 +  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
  11.118 +       Other similar extension points exist, see Microsoft.Common.targets.
  11.119 +  <Target Name="BeforeBuild">
  11.120 +  </Target>
  11.121 +  <Target Name="AfterBuild">
  11.122 +  </Target>
  11.123 +  -->
  11.124 +  <ItemGroup>
  11.125 +    <Reference Include="microsoft.visualbasic" />
  11.126 +    <Reference Include="System" />
  11.127 +    <Reference Include="System.Data" />
  11.128 +    <Reference Include="System.Drawing" />
  11.129 +    <Reference Include="System.Management" />
  11.130 +    <Reference Include="System.Windows.Forms" />
  11.131 +    <Reference Include="System.Xml" />
  11.132 +  </ItemGroup>
  11.133 +  <ItemGroup>
  11.134 +    <Compile Include="AssemblyInfo.cs" />
  11.135 +    <Compile Include="Debugging.cs" />
  11.136 +    <Compile Include="DebuggingDeclarations.cs" />
  11.137 +    <Compile Include="DeviceManagement.cs" />
  11.138 +    <Compile Include="DeviceManagementDeclarations.cs" />
  11.139 +    <Compile Include="FileIODeclarations.cs" />
  11.140 +    <Compile Include="FrmMain.cs">
  11.141 +      <SubType>Form</SubType>
  11.142 +    </Compile>
  11.143 +    <Compile Include="GenericHid.cs" />
  11.144 +    <Compile Include="Hid.cs" />
  11.145 +    <Compile Include="HidDeclarations.cs" />
  11.146 +    <Compile Include="Properties\Resources.Designer.cs">
  11.147 +      <AutoGen>True</AutoGen>
  11.148 +      <DesignTime>True</DesignTime>
  11.149 +      <DependentUpon>Resources.resx</DependentUpon>
  11.150 +    </Compile>
  11.151 +    <Compile Include="Properties\Settings.Designer.cs">
  11.152 +      <AutoGen>True</AutoGen>
  11.153 +      <DesignTimeSharedInput>True</DesignTimeSharedInput>
  11.154 +      <DependentUpon>Settings.settings</DependentUpon>
  11.155 +    </Compile>
  11.156 +  </ItemGroup>
  11.157 +  <ItemGroup>
  11.158 +    <EmbeddedResource Include="FrmMain.resX">
  11.159 +      <SubType>Designer</SubType>
  11.160 +      <DependentUpon>FrmMain.cs</DependentUpon>
  11.161 +    </EmbeddedResource>
  11.162 +    <EmbeddedResource Include="Properties\Resources.resx">
  11.163 +      <SubType>Designer</SubType>
  11.164 +      <Generator>ResXFileCodeGenerator</Generator>
  11.165 +      <LastGenOutput>Resources.Designer.cs</LastGenOutput>
  11.166 +    </EmbeddedResource>
  11.167 +  </ItemGroup>
  11.168 +  <ItemGroup>
  11.169 +    <None Include="app.config" />
  11.170 +    <None Include="ClassDiagram1.cd" />
  11.171 +    <None Include="GenericHid_TemporaryKey.pfx" />
  11.172 +    <None Include="Properties\Settings.settings">
  11.173 +      <Generator>SettingsSingleFileGenerator</Generator>
  11.174 +      <LastGenOutput>Settings.Designer.cs</LastGenOutput>
  11.175 +    </None>
  11.176 +  </ItemGroup>
  11.177 +  <ItemGroup>
  11.178 +    <Content Include="readme.txt" />
  11.179 +  </ItemGroup>
  11.180 +  <ItemGroup>
  11.181 +    <BootstrapperPackage Include=".NETFramework,Version=v4.5">
  11.182 +      <Visible>False</Visible>
  11.183 +      <ProductName>Microsoft .NET Framework 4.5 %28x86 and x64%29</ProductName>
  11.184 +      <Install>true</Install>
  11.185 +    </BootstrapperPackage>
  11.186 +    <BootstrapperPackage Include="Microsoft.Net.Client.3.5">
  11.187 +      <Visible>False</Visible>
  11.188 +      <ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
  11.189 +      <Install>false</Install>
  11.190 +    </BootstrapperPackage>
  11.191 +    <BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
  11.192 +      <Visible>False</Visible>
  11.193 +      <ProductName>.NET Framework 3.5 SP1</ProductName>
  11.194 +      <Install>false</Install>
  11.195 +    </BootstrapperPackage>
  11.196 +  </ItemGroup>
  11.197 +</Project>
  11.198 \ No newline at end of file
    12.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    12.2 +++ b/GenericHid.csproj.user	Wed May 14 07:52:21 2014 +0200
    12.3 @@ -0,0 +1,31 @@
    12.4 +<?xml version="1.0" encoding="utf-8"?>
    12.5 +<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
    12.6 +  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
    12.7 +    <StartWithIE>true</StartWithIE>
    12.8 +  </PropertyGroup>
    12.9 +  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
   12.10 +    <StartWithIE>true</StartWithIE>
   12.11 +  </PropertyGroup>
   12.12 +  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
   12.13 +    <StartWithIE>true</StartWithIE>
   12.14 +  </PropertyGroup>
   12.15 +  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
   12.16 +    <StartWithIE>true</StartWithIE>
   12.17 +  </PropertyGroup>
   12.18 +  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
   12.19 +    <StartWithIE>true</StartWithIE>
   12.20 +  </PropertyGroup>
   12.21 +  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
   12.22 +    <StartWithIE>true</StartWithIE>
   12.23 +  </PropertyGroup>
   12.24 +  <PropertyGroup>
   12.25 +    <PublishUrlHistory>publish\</PublishUrlHistory>
   12.26 +    <InstallUrlHistory />
   12.27 +    <SupportUrlHistory />
   12.28 +    <UpdateUrlHistory />
   12.29 +    <BootstrapperUrlHistory />
   12.30 +    <ErrorReportUrlHistory />
   12.31 +    <FallbackCulture>en-US</FallbackCulture>
   12.32 +    <VerifyUploadedFiles>false</VerifyUploadedFiles>
   12.33 +  </PropertyGroup>
   12.34 +</Project>
   12.35 \ No newline at end of file
    13.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.2 +++ b/Generic_Hid_cs_v62.sln	Wed May 14 07:52:21 2014 +0200
    13.3 @@ -0,0 +1,32 @@
    13.4 +
    13.5 +Microsoft Visual Studio Solution File, Format Version 12.00
    13.6 +# Visual Studio 2012
    13.7 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GenericHid", "GenericHid.csproj", "{A6E0F52F-4599-4758-B956-9E8420FD28A8}"
    13.8 +EndProject
    13.9 +Global
   13.10 +	GlobalSection(SolutionConfigurationPlatforms) = preSolution
   13.11 +		Debug|Any CPU = Debug|Any CPU
   13.12 +		Debug|x64 = Debug|x64
   13.13 +		Debug|x86 = Debug|x86
   13.14 +		Release|Any CPU = Release|Any CPU
   13.15 +		Release|x64 = Release|x64
   13.16 +		Release|x86 = Release|x86
   13.17 +	EndGlobalSection
   13.18 +	GlobalSection(ProjectConfigurationPlatforms) = postSolution
   13.19 +		{A6E0F52F-4599-4758-B956-9E8420FD28A8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
   13.20 +		{A6E0F52F-4599-4758-B956-9E8420FD28A8}.Debug|Any CPU.Build.0 = Debug|Any CPU
   13.21 +		{A6E0F52F-4599-4758-B956-9E8420FD28A8}.Debug|x64.ActiveCfg = Debug|x64
   13.22 +		{A6E0F52F-4599-4758-B956-9E8420FD28A8}.Debug|x64.Build.0 = Debug|x64
   13.23 +		{A6E0F52F-4599-4758-B956-9E8420FD28A8}.Debug|x86.ActiveCfg = Debug|x86
   13.24 +		{A6E0F52F-4599-4758-B956-9E8420FD28A8}.Debug|x86.Build.0 = Debug|x86
   13.25 +		{A6E0F52F-4599-4758-B956-9E8420FD28A8}.Release|Any CPU.ActiveCfg = Release|Any CPU
   13.26 +		{A6E0F52F-4599-4758-B956-9E8420FD28A8}.Release|Any CPU.Build.0 = Release|Any CPU
   13.27 +		{A6E0F52F-4599-4758-B956-9E8420FD28A8}.Release|x64.ActiveCfg = Debug|x64
   13.28 +		{A6E0F52F-4599-4758-B956-9E8420FD28A8}.Release|x64.Build.0 = Debug|x64
   13.29 +		{A6E0F52F-4599-4758-B956-9E8420FD28A8}.Release|x86.ActiveCfg = Release|x86
   13.30 +		{A6E0F52F-4599-4758-B956-9E8420FD28A8}.Release|x86.Build.0 = Release|x86
   13.31 +	EndGlobalSection
   13.32 +	GlobalSection(SolutionProperties) = preSolution
   13.33 +		HideSolutionNode = FALSE
   13.34 +	EndGlobalSection
   13.35 +EndGlobal
    14.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    14.2 +++ b/Hid.cs	Wed May 14 07:52:21 2014 +0200
    14.3 @@ -0,0 +1,739 @@
    14.4 +using Microsoft.Win32.SafeHandles;
    14.5 +using System;
    14.6 +using System.Diagnostics;
    14.7 +using System.IO;
    14.8 +using System.Runtime.InteropServices;
    14.9 +using System.Threading;
   14.10 +using System.Threading.Tasks;
   14.11 +using System.Windows.Forms;
   14.12 +
   14.13 +namespace GenericHid
   14.14 +{
   14.15 +	///  <summary>
   14.16 +	///  Supports Windows API functions for accessing HID-class USB devices.
   14.17 +	///  Includes routines for retrieving information about the configuring a HID and 
   14.18 +	///  sending and receiving reports via control and interrupt transfers. 
   14.19 +	///  </summary>
   14.20 +
   14.21 +	internal sealed partial class Hid
   14.22 +	{
   14.23 +		//  Used in error messages.
   14.24 +
   14.25 +		private const String ModuleName = "Hid";
   14.26 +
   14.27 +		internal NativeMethods.HIDP_CAPS Capabilities;
   14.28 +		internal NativeMethods.HIDD_ATTRIBUTES DeviceAttributes;
   14.29 +
   14.30 +		//  For viewing results of API calls in debug.write statements:
   14.31 +
   14.32 +		internal static Debugging MyDebugging = new Debugging();
   14.33 +
   14.34 +		///  <summary>
   14.35 +		///  Provides a central mechanism for exception handling.
   14.36 +		///  Displays a message box that describes the exception.
   14.37 +		///  </summary>
   14.38 +		///  
   14.39 +		///  <param name="moduleName">  the module where the exception occurred. </param>
   14.40 +		///  <param name="e"> the exception </param>
   14.41 +
   14.42 +		internal static void DisplayException(String moduleName, Exception e)
   14.43 +		{
   14.44 +			//  Create an error message.
   14.45 +
   14.46 +			String message = "Exception: " + e.Message + Environment.NewLine + "Module: " + moduleName + Environment.NewLine + "Method: " + e.TargetSite.Name;
   14.47 +
   14.48 +			const String caption = "Unexpected Exception";
   14.49 +
   14.50 +			MessageBox.Show(message, caption, MessageBoxButtons.OK);
   14.51 +			Debug.Write(message);
   14.52 +
   14.53 +			// Get the last error and display it. 
   14.54 +			Int32 error = Marshal.GetLastWin32Error();
   14.55 +
   14.56 +			Debug.WriteLine("The last Win32 Error was: " + error);
   14.57 +		}
   14.58 +
   14.59 +		///  <summary>
   14.60 +		///  Remove any Input reports waiting in the buffer.
   14.61 +		///  </summary>
   14.62 +		///  <param name="hidHandle"> a handle to a device.   </param>
   14.63 +		///  <returns>
   14.64 +		///  True on success, False on failure.
   14.65 +		///  </returns>
   14.66 +
   14.67 +		internal Boolean FlushQueue(SafeFileHandle hidHandle)
   14.68 +		{
   14.69 +			try
   14.70 +			{
   14.71 +				//  ***
   14.72 +				//  API function: HidD_FlushQueue
   14.73 +
   14.74 +				//  Purpose: Removes any Input reports waiting in the buffer.
   14.75 +
   14.76 +				//  Accepts: a handle to the device.
   14.77 +
   14.78 +				//  Returns: True on success, False on failure.
   14.79 +				//  ***
   14.80 +
   14.81 +				Boolean success = NativeMethods.HidD_FlushQueue(hidHandle);
   14.82 +
   14.83 +				return success;
   14.84 +			}
   14.85 +
   14.86 +			catch (Exception ex)
   14.87 +			{
   14.88 +				DisplayException(ModuleName, ex);
   14.89 +				throw;
   14.90 +			}
   14.91 +		}
   14.92 +
   14.93 +		/// <summary>
   14.94 +		/// Get HID attributes.
   14.95 +		/// </summary>
   14.96 +		/// <param name="hidHandle"> HID handle retrieved with CreateFile </param>
   14.97 +		/// <param name="deviceAttributes"> HID attributes structure </param>
   14.98 +		/// <returns> true on success </returns>
   14.99 +
  14.100 +		internal Boolean GetAttributes(SafeFileHandle hidHandle, ref NativeMethods.HIDD_ATTRIBUTES deviceAttributes)
  14.101 +		{
  14.102 +			Boolean success;
  14.103 +			try
  14.104 +			{
  14.105 +				//  ***
  14.106 +				//  API function:
  14.107 +				//  HidD_GetAttributes
  14.108 +
  14.109 +				//  Purpose:
  14.110 +				//  Retrieves a HIDD_ATTRIBUTES structure containing the Vendor ID, 
  14.111 +				//  Product ID, and Product Version Number for a device.
  14.112 +
  14.113 +				//  Accepts:
  14.114 +				//  A handle returned by CreateFile.
  14.115 +				//  A pointer to receive a HIDD_ATTRIBUTES structure.
  14.116 +
  14.117 +				//  Returns:
  14.118 +				//  True on success, False on failure.
  14.119 +				//  ***                            
  14.120 +
  14.121 +				success = NativeMethods.HidD_GetAttributes(hidHandle, ref deviceAttributes);
  14.122 +			}
  14.123 +
  14.124 +			catch (Exception ex)
  14.125 +			{
  14.126 +				DisplayException(ModuleName, ex);
  14.127 +				throw;
  14.128 +			}
  14.129 +			return success;
  14.130 +		}
  14.131 +
  14.132 +		///  <summary>
  14.133 +		///  Retrieves a structure with information about a device's capabilities. 
  14.134 +		///  </summary>
  14.135 +		///  
  14.136 +		///  <param name="hidHandle"> a handle to a device. </param>
  14.137 +		///  
  14.138 +		///  <returns>
  14.139 +		///  An HIDP_CAPS structure.
  14.140 +		///  </returns>
  14.141 +
  14.142 +		internal NativeMethods.HIDP_CAPS GetDeviceCapabilities(SafeFileHandle hidHandle)
  14.143 +		{
  14.144 +			var preparsedData = new IntPtr();
  14.145 +
  14.146 +			try
  14.147 +			{
  14.148 +				//  ***
  14.149 +				//  API function: HidD_GetPreparsedData
  14.150 +
  14.151 +				//  Purpose: retrieves a pointer to a buffer containing information about the device's capabilities.
  14.152 +				//  HidP_GetCaps and other API functions require a pointer to the buffer.
  14.153 +
  14.154 +				//  Requires: 
  14.155 +				//  A handle returned by CreateFile.
  14.156 +				//  A pointer to a buffer.
  14.157 +
  14.158 +				//  Returns:
  14.159 +				//  True on success, False on failure.
  14.160 +				//  ***
  14.161 +
  14.162 +				NativeMethods.HidD_GetPreparsedData(hidHandle, ref preparsedData);
  14.163 +
  14.164 +				//  ***
  14.165 +				//  API function: HidP_GetCaps
  14.166 +
  14.167 +				//  Purpose: find out a device's capabilities.
  14.168 +				//  For standard devices such as joysticks, you can find out the specific
  14.169 +				//  capabilities of the device.
  14.170 +				//  For a custom device where the software knows what the device is capable of,
  14.171 +				//  this call may be unneeded.
  14.172 +
  14.173 +				//  Accepts:
  14.174 +				//  A pointer returned by HidD_GetPreparsedData
  14.175 +				//  A pointer to a HIDP_CAPS structure.
  14.176 +
  14.177 +				//  Returns: True on success, False on failure.
  14.178 +				//  ***
  14.179 +
  14.180 +				Int32 result = NativeMethods.HidP_GetCaps(preparsedData, ref Capabilities);
  14.181 +				if ((result != 0))
  14.182 +				{
  14.183 +					Debug.WriteLine("");
  14.184 +					Debug.WriteLine("  Usage: " + Convert.ToString(Capabilities.Usage, 16));
  14.185 +					Debug.WriteLine("  Usage Page: " + Convert.ToString(Capabilities.UsagePage, 16));
  14.186 +					Debug.WriteLine("  Input Report Byte Length: " + Capabilities.InputReportByteLength);
  14.187 +					Debug.WriteLine("  Output Report Byte Length: " + Capabilities.OutputReportByteLength);
  14.188 +					Debug.WriteLine("  Feature Report Byte Length: " + Capabilities.FeatureReportByteLength);
  14.189 +					Debug.WriteLine("  Number of Link Collection Nodes: " + Capabilities.NumberLinkCollectionNodes);
  14.190 +					Debug.WriteLine("  Number of Input Button Caps: " + Capabilities.NumberInputButtonCaps);
  14.191 +					Debug.WriteLine("  Number of Input Value Caps: " + Capabilities.NumberInputValueCaps);
  14.192 +					Debug.WriteLine("  Number of Input Data Indices: " + Capabilities.NumberInputDataIndices);
  14.193 +					Debug.WriteLine("  Number of Output Button Caps: " + Capabilities.NumberOutputButtonCaps);
  14.194 +					Debug.WriteLine("  Number of Output Value Caps: " + Capabilities.NumberOutputValueCaps);
  14.195 +					Debug.WriteLine("  Number of Output Data Indices: " + Capabilities.NumberOutputDataIndices);
  14.196 +					Debug.WriteLine("  Number of Feature Button Caps: " + Capabilities.NumberFeatureButtonCaps);
  14.197 +					Debug.WriteLine("  Number of Feature Value Caps: " + Capabilities.NumberFeatureValueCaps);
  14.198 +					Debug.WriteLine("  Number of Feature Data Indices: " + Capabilities.NumberFeatureDataIndices);
  14.199 +
  14.200 +					//  ***
  14.201 +					//  API function: HidP_GetValueCaps
  14.202 +
  14.203 +					//  Purpose: retrieves a buffer containing an array of HidP_ValueCaps structures.
  14.204 +					//  Each structure defines the capabilities of one value.
  14.205 +					//  This application doesn't use this data.
  14.206 +
  14.207 +					//  Accepts:
  14.208 +					//  A report type enumerator from hidpi.h,
  14.209 +					//  A pointer to a buffer for the returned array,
  14.210 +					//  The NumberInputValueCaps member of the device's HidP_Caps structure,
  14.211 +					//  A pointer to the PreparsedData structure returned by HidD_GetPreparsedData.
  14.212 +
  14.213 +					//  Returns: True on success, False on failure.
  14.214 +					//  ***                    
  14.215 +
  14.216 +					Int32 vcSize = Capabilities.NumberInputValueCaps;
  14.217 +					var valueCaps = new Byte[vcSize];
  14.218 +
  14.219 +					NativeMethods.HidP_GetValueCaps(NativeMethods.HidP_Input, valueCaps, ref vcSize, preparsedData);
  14.220 +
  14.221 +					// (To use this data, copy the ValueCaps byte array into an array of structures.)              
  14.222 +				}
  14.223 +			}
  14.224 +
  14.225 +			catch (Exception ex)
  14.226 +			{
  14.227 +				DisplayException(ModuleName, ex);
  14.228 +				throw;
  14.229 +			}
  14.230 +			finally
  14.231 +			{
  14.232 +				//  ***
  14.233 +				//  API function: HidD_FreePreparsedData
  14.234 +
  14.235 +				//  Purpose: frees the buffer reserved by HidD_GetPreparsedData.
  14.236 +
  14.237 +				//  Accepts: A pointer to the PreparsedData structure returned by HidD_GetPreparsedData.
  14.238 +
  14.239 +				//  Returns: True on success, False on failure.
  14.240 +				//  ***
  14.241 +
  14.242 +				if (preparsedData != IntPtr.Zero)
  14.243 +				{
  14.244 +					NativeMethods.HidD_FreePreparsedData(preparsedData);
  14.245 +				}
  14.246 +			}
  14.247 +			return Capabilities;
  14.248 +		}
  14.249 +
  14.250 +		///  <summary>
  14.251 +		///  reads a Feature report from the device.
  14.252 +		///  </summary>
  14.253 +		///  
  14.254 +		///  <param name="hidHandle"> the handle for learning about the device and exchanging Feature reports. </param>	
  14.255 +		///  <param name="inFeatureReportBuffer"> contains the requested report.</param>
  14.256 +
  14.257 +		internal Boolean GetFeatureReport(SafeFileHandle hidHandle, ref Byte[] inFeatureReportBuffer)
  14.258 +		{
  14.259 +			try
  14.260 +			{
  14.261 +				Boolean success = false;
  14.262 +
  14.263 +				//  ***
  14.264 +				//  API function: HidD_GetFeature
  14.265 +				//  Attempts to read a Feature report from the device.
  14.266 +
  14.267 +				//  Requires:
  14.268 +				//  A handle to a HID
  14.269 +				//  A pointer to a buffer containing the report ID and report
  14.270 +				//  The size of the buffer. 
  14.271 +
  14.272 +				//  Returns: true on success, false on failure.
  14.273 +				//  ***                    
  14.274 +
  14.275 +				if (!hidHandle.IsInvalid && !hidHandle.IsClosed)
  14.276 +				{
  14.277 +					success = NativeMethods.HidD_GetFeature(hidHandle, inFeatureReportBuffer, inFeatureReportBuffer.Length);
  14.278 +
  14.279 +					Debug.Print("HidD_GetFeature success = " + success);
  14.280 +				}
  14.281 +				return success;
  14.282 +			}
  14.283 +
  14.284 +			catch (Exception ex)
  14.285 +			{
  14.286 +				DisplayException(ModuleName, ex);
  14.287 +				throw;
  14.288 +			}
  14.289 +		}
  14.290 +
  14.291 +		/// <summary>
  14.292 +		/// Get the HID-class GUID
  14.293 +		/// </summary>
  14.294 +		/// <returns> the GUID </returns>
  14.295 +
  14.296 +		internal Guid GetHidGuid()
  14.297 +		{
  14.298 +			Guid hidGuid = Guid.Empty;
  14.299 +			try
  14.300 +			{
  14.301 +				//  ***
  14.302 +				//  API function: 'HidD_GetHidGuid
  14.303 +
  14.304 +				//  Purpose: Retrieves the interface class GUID for the HID class.
  14.305 +
  14.306 +				//  Accepts: A System.Guid object for storing the GUID.
  14.307 +				//  ***
  14.308 +
  14.309 +				NativeMethods.HidD_GetHidGuid(ref hidGuid);
  14.310 +			}
  14.311 +
  14.312 +			catch (Exception ex)
  14.313 +			{
  14.314 +				DisplayException(ModuleName, ex);
  14.315 +				throw;
  14.316 +			}
  14.317 +			return hidGuid;
  14.318 +		}
  14.319 +
  14.320 +		///  <summary>
  14.321 +		///  Creates a 32-bit Usage from the Usage Page and Usage ID. 
  14.322 +		///  Determines whether the Usage is a system mouse or keyboard.
  14.323 +		///  Can be modified to detect other Usages.
  14.324 +		///  </summary>
  14.325 +		///  
  14.326 +		///  <param name="myCapabilities"> a HIDP_CAPS structure retrieved with HidP_GetCaps. </param>
  14.327 +		///  
  14.328 +		///  <returns>
  14.329 +		///  A String describing the Usage.
  14.330 +		///  </returns>
  14.331 +
  14.332 +		internal String GetHidUsage(NativeMethods.HIDP_CAPS myCapabilities)
  14.333 +		{
  14.334 +			String usageDescription = "";
  14.335 +
  14.336 +			try
  14.337 +			{
  14.338 +				//  Create32-bit Usage from Usage Page and Usage ID.
  14.339 +
  14.340 +				Int32 usage = myCapabilities.UsagePage * 256 + myCapabilities.Usage;
  14.341 +
  14.342 +				if (usage == Convert.ToInt32(0X102))
  14.343 +				{
  14.344 +					usageDescription = "mouse";
  14.345 +				}
  14.346 +				if (usage == Convert.ToInt32(0X106))
  14.347 +				{
  14.348 +					usageDescription = "keyboard";
  14.349 +				}
  14.350 +			}
  14.351 +
  14.352 +			catch (Exception ex)
  14.353 +			{
  14.354 +				DisplayException(ModuleName, ex);
  14.355 +				throw;
  14.356 +			}
  14.357 +
  14.358 +			return usageDescription;
  14.359 +		}
  14.360 +
  14.361 +		///  <summary>
  14.362 +		///  reads an Input report from the device using a control transfer.
  14.363 +		///  </summary>  
  14.364 +		///  <param name="hidHandle"> the handle for learning about the device and exchanging Feature reports. </param>
  14.365 +		/// <param name="inputReportBuffer"> contains the requested report. </param>
  14.366 +
  14.367 +		internal Boolean GetInputReportViaControlTransfer(SafeFileHandle hidHandle, ref Byte[] inputReportBuffer)
  14.368 +		{
  14.369 +			var success = false;
  14.370 +
  14.371 +			try
  14.372 +			{
  14.373 +				//  ***
  14.374 +				//  API function: HidD_GetInputReport
  14.375 +
  14.376 +				//  Purpose: Attempts to read an Input report from the device using a control transfer.
  14.377 +
  14.378 +				//  Requires:
  14.379 +				//  A handle to a HID
  14.380 +				//  A pointer to a buffer containing the report ID and report
  14.381 +				//  The size of the buffer. 
  14.382 +
  14.383 +				//  Returns: true on success, false on failure.
  14.384 +				//  ***
  14.385 +
  14.386 +				if (!hidHandle.IsInvalid && !hidHandle.IsClosed)
  14.387 +				{
  14.388 +					success = NativeMethods.HidD_GetInputReport(hidHandle, inputReportBuffer, inputReportBuffer.Length + 1);
  14.389 +					Debug.Print("HidD_GetInputReport success = " + success);
  14.390 +				}
  14.391 +				return success;
  14.392 +			}
  14.393 +
  14.394 +			catch (Exception ex)
  14.395 +			{
  14.396 +				DisplayException(ModuleName, ex);
  14.397 +				throw;
  14.398 +			}
  14.399 +		}
  14.400 +
  14.401 +		///  <summary>
  14.402 +		///  Reads an Input report from the device using an interrupt transfer.
  14.403 +		///  </summary>
  14.404 +		///  
  14.405 +		///  <param name="deviceData"> the Filestream for writing data. </param> 
  14.406 +		///  <param name="inputReportBuffer"> contains the report ID and report data. </param>
  14.407 +		/// <returns>
  14.408 +		///   True on success. False on failure.
  14.409 +		///  </returns>  
  14.410 +
  14.411 +		internal async Task<Int32> GetInputReportViaInterruptTransfer(FileStream deviceData, Byte[] inputReportBuffer, CancellationTokenSource cts)
  14.412 +		{
  14.413 +			try
  14.414 +			{
  14.415 +				Int32 bytesRead = 0;
  14.416 +				
  14.417 +					// Begin reading an Input report. 
  14.418 +
  14.419 +					Task<Int32> t = deviceData.ReadAsync(inputReportBuffer, 0, inputReportBuffer.Length, cts.Token);
  14.420 +
  14.421 +					bytesRead = await t;
  14.422 +
  14.423 +					// Gets to here only if the read operation completed before a timeout.
  14.424 +
  14.425 +					Debug.Print("Asynchronous read completed. Bytes read = " + Convert.ToString(bytesRead));
  14.426 +
  14.427 +					// The operation has one of these completion states:
  14.428 +
  14.429 +					switch (t.Status)
  14.430 +					{
  14.431 +						case TaskStatus.RanToCompletion:
  14.432 +							Debug.Print("Input report received from device");
  14.433 +							break;
  14.434 +						case TaskStatus.Canceled:
  14.435 +							Debug.Print("Task canceled");
  14.436 +							break;
  14.437 +						case TaskStatus.Faulted:
  14.438 +							Debug.Print("Unhandled exception");
  14.439 +							break;
  14.440 +					}
  14.441 +				return bytesRead;
  14.442 +			}
  14.443 +			catch (Exception ex)
  14.444 +			{
  14.445 +				DisplayException(ModuleName, ex);
  14.446 +				throw;
  14.447 +			}
  14.448 +		}
  14.449 +
  14.450 +		///  <summary>
  14.451 +		///  Retrieves the number of Input reports the HID driver will store.
  14.452 +		///  </summary>
  14.453 +		///  
  14.454 +		///  <param name="hidDeviceObject"> a handle to a device  </param>
  14.455 +		///  <param name="numberOfInputBuffers"> an integer to hold the returned value. </param>
  14.456 +		///  
  14.457 +		///  <returns>
  14.458 +		///  True on success, False on failure.
  14.459 +		///  </returns>
  14.460 +
  14.461 +		internal Boolean GetNumberOfInputBuffers(SafeFileHandle hidDeviceObject, ref Int32 numberOfInputBuffers)
  14.462 +		{
  14.463 +			try
  14.464 +			{
  14.465 +				//  ***
  14.466 +				//  API function: HidD_GetNumInputBuffers
  14.467 +
  14.468 +				//  Purpose: retrieves the number of Input reports the host can store.
  14.469 +				//  Not supported by Windows 98 Gold.
  14.470 +				//  If the buffer is full and another report arrives, the host drops the 
  14.471 +				//  ldest report.
  14.472 +
  14.473 +				//  Accepts: a handle to a device and an integer to hold the number of buffers. 
  14.474 +
  14.475 +				//  Returns: True on success, False on failure.
  14.476 +				//  ***
  14.477 +
  14.478 +				Boolean success = NativeMethods.HidD_GetNumInputBuffers(hidDeviceObject, ref numberOfInputBuffers);
  14.479 +
  14.480 +				return success;
  14.481 +			}
  14.482 +
  14.483 +			catch (Exception ex)
  14.484 +			{
  14.485 +				DisplayException(ModuleName, ex);
  14.486 +				throw;
  14.487 +			}
  14.488 +		}
  14.489 +
  14.490 +		/// <summary>
  14.491 +		/// Timeout if read or write via interrupt transfer doesn't return.
  14.492 +		/// </summary>
  14.493 +
  14.494 +		internal void OnTimeout()
  14.495 +		{
  14.496 +			try
  14.497 +			{
  14.498 +				// No action required.
  14.499 +
  14.500 +				Debug.Print("timeout");
  14.501 +			}
  14.502 +			catch (Exception ex)
  14.503 +			{
  14.504 +				DisplayException(ModuleName, ex);
  14.505 +				throw;
  14.506 +			}
  14.507 +		}
  14.508 +
  14.509 +		/// <summary>
  14.510 +		/// Attempts to open a handle to a HID.
  14.511 +		/// </summary>
  14.512 +		/// <param name="devicePathName"> device path name returned by SetupDiGetDeviceInterfaceDetail </param>
  14.513 +		/// <param name="readAndWrite"> true if requesting read/write access for Input and Output reports </param>
  14.514 +		/// <returns> hidHandle - a handle to the HID </returns>
  14.515 +
  14.516 +		internal SafeFileHandle OpenHandle(String devicePathName, Boolean readAndWrite)
  14.517 +		{
  14.518 +			SafeFileHandle hidHandle;
  14.519 +
  14.520 +			try
  14.521 +			{
  14.522 +				if (readAndWrite)
  14.523 +				{
  14.524 +					//  ***
  14.525 +					//  API function:
  14.526 +					//  CreateFile
  14.527 +
  14.528 +					//  Purpose:
  14.529 +					//  Retrieves a handle to a device.
  14.530 +
  14.531 +					//  Accepts:
  14.532 +					//  A device path name returned by SetupDiGetDeviceInterfaceDetail
  14.533 +					//  The type of access requested (read/write).
  14.534 +					//  FILE_SHARE attributes to allow other processes to access the device while this handle is open.
  14.535 +					//  A Security structure or IntPtr.Zero. 
  14.536 +					//  A creation disposition value. Use OPEN_EXISTING for devices.
  14.537 +					//  Flags and attributes for files. Not used for devices.
  14.538 +					//  Handle to a template file. Not used.
  14.539 +
  14.540 +					//  Returns: a handle without read or write access.
  14.541 +					//  This enables obtaining information about all HIDs, even system
  14.542 +					//  keyboards and mice. 
  14.543 +					//  Separate handles are used for reading and writing.
  14.544 +					//  ***
  14.545 +
  14.546 +					hidHandle = FileIo.CreateFile(devicePathName, FileIo.GenericRead | FileIo.GenericWrite, FileIo.FileShareRead | FileIo.FileShareWrite, IntPtr.Zero, FileIo.OpenExisting, 0, IntPtr.Zero);
  14.547 +				}
  14.548 +				else
  14.549 +				{
  14.550 +					hidHandle = FileIo.CreateFile(devicePathName, 0, FileIo.FileShareRead | FileIo.FileShareWrite, IntPtr.Zero, FileIo.OpenExisting, 0, IntPtr.Zero);
  14.551 +				}
  14.552 +			}
  14.553 +
  14.554 +			catch (Exception ex)
  14.555 +			{
  14.556 +				DisplayException(ModuleName, ex);
  14.557 +				throw;
  14.558 +			}
  14.559 +			return hidHandle;
  14.560 +		}
  14.561 +
  14.562 +		///  <summary>
  14.563 +		///  Writes a Feature report to the device.
  14.564 +		///  </summary>
  14.565 +		///  
  14.566 +		///  <param name="outFeatureReportBuffer"> contains the report ID and report data. </param>
  14.567 +		///  <param name="hidHandle"> handle to the device.  </param>
  14.568 +		///  
  14.569 +		///  <returns>
  14.570 +		///   True on success. False on failure.
  14.571 +		///  </returns>            
  14.572 +
  14.573 +		internal Boolean SendFeatureReport(SafeFileHandle hidHandle, Byte[] outFeatureReportBuffer)
  14.574 +		{
  14.575 +			try
  14.576 +			{
  14.577 +				//  ***
  14.578 +				//  API function: HidD_SetFeature
  14.579 +
  14.580 +				//  Purpose: Attempts to send a Feature report to the device.
  14.581 +
  14.582 +				//  Accepts:
  14.583 +				//  A handle to a HID
  14.584 +				//  A pointer to a buffer containing the report ID and report
  14.585 +				//  The size of the buffer. 
  14.586 +
  14.587 +				//  Returns: true on success, false on failure.
  14.588 +				//  ***
  14.589 +
  14.590 +				Boolean success = NativeMethods.HidD_SetFeature(hidHandle, outFeatureReportBuffer, outFeatureReportBuffer.Length);
  14.591 +
  14.592 +				Debug.Print("HidD_SetFeature success = " + success);
  14.593 +
  14.594 +				return success;
  14.595 +			}
  14.596 +
  14.597 +			catch (Exception ex)
  14.598 +			{
  14.599 +				DisplayException(ModuleName, ex);
  14.600 +				throw;
  14.601 +			}
  14.602 +		}
  14.603 +
  14.604 +		///  <summary>
  14.605 +		///  Writes an Output report to the device using a control transfer.
  14.606 +		///  </summary>
  14.607 +		///  
  14.608 +		///  <param name="outputReportBuffer"> contains the report ID and report data. </param>
  14.609 +		///  <param name="hidHandle"> handle to the device.  </param>
  14.610 +		///  
  14.611 +		///  <returns>
  14.612 +		///   True on success. False on failure.
  14.613 +		///  </returns>            
  14.614 +
  14.615 +		internal Boolean SendOutputReportViaControlTransfer(SafeFileHandle hidHandle, Byte[] outputReportBuffer)
  14.616 +		{
  14.617 +			try
  14.618 +			{
  14.619 +				//  ***
  14.620 +				//  API function: HidD_SetOutputReport
  14.621 +
  14.622 +				//  Purpose: 
  14.623 +				//  Attempts to send an Output report to the device using a control transfer.
  14.624 +
  14.625 +				//  Accepts:
  14.626 +				//  A handle to a HID
  14.627 +				//  A pointer to a buffer containing the report ID and report
  14.628 +				//  The size of the buffer. 
  14.629 +
  14.630 +				//  Returns: true on success, false on failure.
  14.631 +				//  ***                    
  14.632 +
  14.633 +				Boolean success = NativeMethods.HidD_SetOutputReport(hidHandle, outputReportBuffer, outputReportBuffer.Length + 1);
  14.634 +
  14.635 +				Debug.Print("HidD_SetOutputReport success = " + success);
  14.636 +
  14.637 +				return success;
  14.638 +			}
  14.639 +
  14.640 +			catch (Exception ex)
  14.641 +			{
  14.642 +				DisplayException(ModuleName, ex);
  14.643 +				throw;
  14.644 +			}
  14.645 +		}
  14.646 +
  14.647 +		///  <summary>
  14.648 +		///  Writes an Output report to the device using an interrupt transfer.
  14.649 +		///  </summary>
  14.650 +		///  
  14.651 +		///  <param name="fileStreamDeviceData"> the Filestream for writing data. </param> 
  14.652 +		///  <param name="hidHandle"> SafeFileHandle to the device.  </param>
  14.653 +		///  <param name="outputReportBuffer"> contains the report ID and report data. </param>
  14.654 +		///  <param name="cts"> CancellationTokenSource </param>
  14.655 +		///  
  14.656 +		///  <returns>
  14.657 +		///   1 on success. 0 on failure.
  14.658 +		///  </returns>            
  14.659 +
  14.660 +		internal async Task<Boolean> SendOutputReportViaInterruptTransfer
  14.661 +			(FileStream fileStreamDeviceData, SafeFileHandle hidHandle, Byte[] outputReportBuffer, CancellationTokenSource cts)
  14.662 +		{
  14.663 +			try
  14.664 +			{
  14.665 +				var success = false;
  14.666 +				
  14.667 +					// Begin writing the Output report. 
  14.668 +
  14.669 +					Task t = fileStreamDeviceData.WriteAsync(outputReportBuffer, 0, outputReportBuffer.Length, cts.Token);
  14.670 +
  14.671 +					await t;
  14.672 +
  14.673 +					// Gets to here only if the write operation completed before a timeout.
  14.674 +
  14.675 +					Debug.Print("Asynchronous write completed");
  14.676 +
  14.677 +					// The operation has one of these completion states:
  14.678 +
  14.679 +					switch (t.Status)
  14.680 +					{
  14.681 +						case TaskStatus.RanToCompletion:
  14.682 +							success = true;
  14.683 +							Debug.Print("Output report written to device");
  14.684 +							break;
  14.685 +						case TaskStatus.Canceled:
  14.686 +							Debug.Print("Task canceled");
  14.687 +							break;
  14.688 +						case TaskStatus.Faulted:
  14.689 +							Debug.Print("Unhandled exception");
  14.690 +							break;
  14.691 +					}
  14.692 +
  14.693 +				return success;
  14.694 +			}
  14.695 +			catch (Exception ex)
  14.696 +			{
  14.697 +				DisplayException(ModuleName, ex);
  14.698 +				throw;
  14.699 +			}
  14.700 +		}
  14.701 +
  14.702 +		///  <summary>
  14.703 +		///  sets the number of input reports the host HID driver store.
  14.704 +		///  </summary>
  14.705 +		///  
  14.706 +		///  <param name="hidDeviceObject"> a handle to the device.</param>
  14.707 +		///  <param name="numberBuffers"> the requested number of input reports.  </param>
  14.708 +		///  
  14.709 +		///  <returns>
  14.710 +		///  True on success. False on failure.
  14.711 +		///  </returns>
  14.712 +
  14.713 +		internal Boolean SetNumberOfInputBuffers(SafeFileHandle hidDeviceObject, Int32 numberBuffers)
  14.714 +		{
  14.715 +			try
  14.716 +			{
  14.717 +				//  ***
  14.718 +				//  API function: HidD_SetNumInputBuffers
  14.719 +
  14.720 +				//  Purpose: Sets the number of Input reports the host can store.
  14.721 +				//  If the buffer is full and another report arrives, the host drops the 
  14.722 +				//  oldest report.
  14.723 +
  14.724 +				//  Requires:
  14.725 +				//  A handle to a HID
  14.726 +				//  An integer to hold the number of buffers. 
  14.727 +
  14.728 +				//  Returns: true on success, false on failure.
  14.729 +				//  ***
  14.730 +
  14.731 +				NativeMethods.HidD_SetNumInputBuffers(hidDeviceObject, numberBuffers);
  14.732 +				return true;
  14.733 +			}
  14.734 +
  14.735 +			catch (Exception ex)
  14.736 +			{
  14.737 +				DisplayException(ModuleName, ex);
  14.738 +				throw;
  14.739 +			}
  14.740 +		}
  14.741 +	}
  14.742 +}
    15.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    15.2 +++ b/HidDeclarations.cs	Wed May 14 07:52:21 2014 +0200
    15.3 @@ -0,0 +1,135 @@
    15.4 +using Microsoft.Win32.SafeHandles; 
    15.5 +using System;
    15.6 +using System.Runtime.InteropServices; 
    15.7 +
    15.8 +namespace GenericHid
    15.9 +{    
   15.10 +	/// <summary>
   15.11 +	/// API declarations for HID communications.
   15.12 +	/// </summary>
   15.13 +    internal sealed partial class Hid  
   15.14 +    {
   15.15 +		internal static class NativeMethods
   15.16 +		{
   15.17 +			//  from hidpi.h
   15.18 +			//  Typedef enum defines a set of integer constants for HidP_Report_Type
   15.19 +
   15.20 +			internal const Int16 HidP_Input = 0;
   15.21 +			internal const Int16 HidP_Output = 1;
   15.22 +			internal const Int16 HidP_Feature = 2;
   15.23 +
   15.24 +			[StructLayout(LayoutKind.Sequential)]
   15.25 +			internal struct HIDD_ATTRIBUTES
   15.26 +			{
   15.27 +				internal Int32 Size;
   15.28 +				internal UInt16 VendorID;
   15.29 +				internal UInt16 ProductID;
   15.30 +				internal UInt16 VersionNumber;
   15.31 +			}
   15.32 +
   15.33 +			internal struct HIDP_CAPS
   15.34 +			{
   15.35 +				internal Int16 Usage;
   15.36 +				internal Int16 UsagePage;
   15.37 +				internal Int16 InputReportByteLength;
   15.38 +				internal Int16 OutputReportByteLength;
   15.39 +				internal Int16 FeatureReportByteLength;
   15.40 +				[MarshalAs(UnmanagedType.ByValArray, SizeConst = 17)] internal Int16[] Reserved;
   15.41 +				internal Int16 NumberLinkCollectionNodes;
   15.42 +				internal Int16 NumberInputButtonCaps;
   15.43 +				internal Int16 NumberInputValueCaps;
   15.44 +				internal Int16 NumberInputDataIndices;
   15.45 +				internal Int16 NumberOutputButtonCaps;
   15.46 +				internal Int16 NumberOutputValueCaps;
   15.47 +				internal Int16 NumberOutputDataIndices;
   15.48 +				internal Int16 NumberFeatureButtonCaps;
   15.49 +				internal Int16 NumberFeatureValueCaps;
   15.50 +				internal Int16 NumberFeatureDataIndices;
   15.51 +			}
   15.52 +
   15.53 +			//  If IsRange is false, UsageMin is the Usage and UsageMax is unused.
   15.54 +			//  If IsStringRange is false, StringMin is the String index and StringMax is unused.
   15.55 +			//  If IsDesignatorRange is false, DesignatorMin is the designator index and DesignatorMax is unused.
   15.56 +
   15.57 +			internal struct HidP_Value_Caps
   15.58 +			{
   15.59 +				internal Int16 UsagePage;
   15.60 +				internal Byte ReportID;
   15.61 +				internal Int32 IsAlias;
   15.62 +				internal Int16 BitField;
   15.63 +				internal Int16 LinkCollection;
   15.64 +				internal Int16 LinkUsage;
   15.65 +				internal Int16 LinkUsagePage;
   15.66 +				internal Int32 IsRange;
   15.67 +				internal Int32 IsStringRange;
   15.68 +				internal Int32 IsDesignatorRange;
   15.69 +				internal Int32 IsAbsolute;
   15.70 +				internal Int32 HasNull;
   15.71 +				internal Byte Reserved;
   15.72 +				internal Int16 BitSize;
   15.73 +				internal Int16 ReportCount;
   15.74 +				internal Int16 Reserved2;
   15.75 +				internal Int16 Reserved3;
   15.76 +				internal Int16 Reserved4;
   15.77 +				internal Int16 Reserved5;
   15.78 +				internal Int16 Reserved6;
   15.79 +				internal Int32 LogicalMin;
   15.80 +				internal Int32 LogicalMax;
   15.81 +				internal Int32 PhysicalMin;
   15.82 +				internal Int32 PhysicalMax;
   15.83 +				internal Int16 UsageMin;
   15.84 +				internal Int16 UsageMax;
   15.85 +				internal Int16 StringMin;
   15.86 +				internal Int16 StringMax;
   15.87 +				internal Int16 DesignatorMin;
   15.88 +				internal Int16 DesignatorMax;
   15.89 +				internal Int16 DataIndexMin;
   15.90 +				internal Int16 DataIndexMax;
   15.91 +			}
   15.92 +
   15.93 +			[DllImport("hid.dll", SetLastError = true)]
   15.94 +			internal static extern Boolean HidD_FlushQueue(SafeFileHandle HidDeviceObject);
   15.95 +
   15.96 +			[DllImport("hid.dll", SetLastError = true)]
   15.97 +			internal static extern Boolean HidD_FreePreparsedData(IntPtr PreparsedData);
   15.98 +
   15.99 +			[DllImport("hid.dll", SetLastError = true)]
  15.100 +			internal static extern Boolean HidD_GetAttributes(SafeFileHandle HidDeviceObject, ref HIDD_ATTRIBUTES Attributes);
  15.101 +
  15.102 +			[DllImport("hid.dll", SetLastError = true)]
  15.103 +			internal static extern Boolean HidD_GetFeature(SafeFileHandle HidDeviceObject, Byte[] lpReportBuffer,
  15.104 +			                                               Int32 ReportBufferLength);
  15.105 +
  15.106 +			[DllImport("hid.dll", SetLastError = true)]
  15.107 +			internal static extern Boolean HidD_GetInputReport(SafeFileHandle HidDeviceObject, Byte[] lpReportBuffer,
  15.108 +			                                                   Int32 ReportBufferLength);
  15.109 +
  15.110 +			[DllImport("hid.dll", SetLastError = true)]
  15.111 +			internal static extern void HidD_GetHidGuid(ref Guid HidGuid);
  15.112 +
  15.113 +			[DllImport("hid.dll", SetLastError = true)]
  15.114 +			internal static extern Boolean HidD_GetNumInputBuffers(SafeFileHandle HidDeviceObject, ref Int32 NumberBuffers);
  15.115 +
  15.116 +			[DllImport("hid.dll", SetLastError = true)]
  15.117 +			internal static extern Boolean HidD_GetPreparsedData(SafeFileHandle HidDeviceObject, ref IntPtr PreparsedData);
  15.118 +
  15.119 +			[DllImport("hid.dll", SetLastError = true)]
  15.120 +			internal static extern Boolean HidD_SetFeature(SafeFileHandle HidDeviceObject, Byte[] lpReportBuffer,
  15.121 +			                                               Int32 ReportBufferLength);
  15.122 +
  15.123 +			[DllImport("hid.dll", SetLastError = true)]
  15.124 +			internal static extern Boolean HidD_SetNumInputBuffers(SafeFileHandle HidDeviceObject, Int32 NumberBuffers);
  15.125 +
  15.126 +			[DllImport("hid.dll", SetLastError = true)]
  15.127 +			internal static extern Boolean HidD_SetOutputReport(SafeFileHandle HidDeviceObject, Byte[] lpReportBuffer,
  15.128 +			                                                    Int32 ReportBufferLength);
  15.129 +
  15.130 +			[DllImport("hid.dll", SetLastError = true)]
  15.131 +			internal static extern Int32 HidP_GetCaps(IntPtr PreparsedData, ref HIDP_CAPS Capabilities);
  15.132 +
  15.133 +			[DllImport("hid.dll", SetLastError = true)]
  15.134 +			internal static extern Int32 HidP_GetValueCaps(Int32 ReportType, Byte[] ValueCaps, ref Int32 ValueCapsLength,
  15.135 +			                                               IntPtr PreparsedData);
  15.136 +		}
  15.137 +    } 
  15.138 +} 
    16.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    16.2 +++ b/Properties/Resources.Designer.cs	Wed May 14 07:52:21 2014 +0200
    16.3 @@ -0,0 +1,63 @@
    16.4 +//------------------------------------------------------------------------------
    16.5 +// <auto-generated>
    16.6 +//     This code was generated by a tool.
    16.7 +//     Runtime Version:4.0.30319.18010
    16.8 +//
    16.9 +//     Changes to this file may cause incorrect behavior and will be lost if
   16.10 +//     the code is regenerated.
   16.11 +// </auto-generated>
   16.12 +//------------------------------------------------------------------------------
   16.13 +
   16.14 +namespace GenericHid.Properties {
   16.15 +    using System;
   16.16 +    
   16.17 +    
   16.18 +    /// <summary>
   16.19 +    ///   A strongly-typed resource class, for looking up localized strings, etc.
   16.20 +    /// </summary>
   16.21 +    // This class was auto-generated by the StronglyTypedResourceBuilder
   16.22 +    // class via a tool like ResGen or Visual Studio.
   16.23 +    // To add or remove a member, edit your .ResX file then rerun ResGen
   16.24 +    // with the /str option, or rebuild your VS project.
   16.25 +    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
   16.26 +    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
   16.27 +    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
   16.28 +    internal class Resources {
   16.29 +        
   16.30 +        private static global::System.Resources.ResourceManager resourceMan;
   16.31 +        
   16.32 +        private static global::System.Globalization.CultureInfo resourceCulture;
   16.33 +        
   16.34 +        [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
   16.35 +        internal Resources() {
   16.36 +        }
   16.37 +        
   16.38 +        /// <summary>
   16.39 +        ///   Returns the cached ResourceManager instance used by this class.
   16.40 +        /// </summary>
   16.41 +        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
   16.42 +        internal static global::System.Resources.ResourceManager ResourceManager {
   16.43 +            get {
   16.44 +                if (object.ReferenceEquals(resourceMan, null)) {
   16.45 +                    global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("GenericHid.Properties.Resources", typeof(Resources).Assembly);
   16.46 +                    resourceMan = temp;
   16.47 +                }
   16.48 +                return resourceMan;
   16.49 +            }
   16.50 +        }
   16.51 +        
   16.52 +        /// <summary>
   16.53 +        ///   Overrides the current thread's CurrentUICulture property for all
   16.54 +        ///   resource lookups using this strongly typed resource class.
   16.55 +        /// </summary>
   16.56 +        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
   16.57 +        internal static global::System.Globalization.CultureInfo Culture {
   16.58 +            get {
   16.59 +                return resourceCulture;
   16.60 +            }
   16.61 +            set {
   16.62 +                resourceCulture = value;
   16.63 +            }
   16.64 +        }
   16.65 +    }
   16.66 +}
    17.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    17.2 +++ b/Properties/Resources.resx	Wed May 14 07:52:21 2014 +0200
    17.3 @@ -0,0 +1,110 @@
    17.4 +<?xml version="1.0" encoding="utf-8"?>
    17.5 +<root>
    17.6 +  <!-- 
    17.7 +    Microsoft ResX Schema 
    17.8 +    
    17.9 +    Version 2.0
   17.10 +    
   17.11 +    The primary goals of this format is to allow a simple XML format 
   17.12 +    that is mostly human readable. The generation and parsing of the 
   17.13 +    various data types are done through the TypeConverter classes 
   17.14 +    associated with the data types.
   17.15 +    
   17.16 +    Example:
   17.17 +    
   17.18 +    ... ado.net/XML headers & schema ...
   17.19 +    <resheader name="resmimetype">text/microsoft-resx</resheader>
   17.20 +    <resheader name="version">2.0</resheader>
   17.21 +    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
   17.22 +    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
   17.23 +    <data name="Name1">this is my long string</data>
   17.24 +    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
   17.25 +    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
   17.26 +        [base64 mime encoded serialized .NET Framework object]
   17.27 +    </data>
   17.28 +    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
   17.29 +        [base64 mime encoded string representing a byte array form of the .NET Framework object]
   17.30 +    </data>
   17.31 +                
   17.32 +    There are any number of "resheader" rows that contain simple 
   17.33 +    name/value pairs.
   17.34 +    
   17.35 +    Each data row contains a name, and value. The row also contains a 
   17.36 +    type or mimetype. Type corresponds to a .NET class that support 
   17.37 +    text/value conversion through the TypeConverter architecture. 
   17.38 +    Classes that don't support this are serialized and stored with the 
   17.39 +    mimetype set.
   17.40 +    
   17.41 +    The mimetype is used for serialized objects, and tells the 
   17.42 +    ResXResourceReader how to depersist the object. This is currently not 
   17.43 +    extensible. For a given mimetype the value must be set accordingly:
   17.44 +    
   17.45 +    Note - application/x-microsoft.net.object.binary.base64 is the format 
   17.46 +    that the ResXResourceWriter will generate, however the reader can 
   17.47 +    read any of the formats listed below.
   17.48 +    
   17.49 +    mimetype: application/x-microsoft.net.object.binary.base64
   17.50 +    value   : The object must be serialized with 
   17.51 +            : System.Serialization.Formatters.Binary.BinaryFormatter
   17.52 +            : and then encoded with base64 encoding.
   17.53 +    
   17.54 +    mimetype: application/x-microsoft.net.object.soap.base64
   17.55 +    value   : The object must be serialized with 
   17.56 +            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
   17.57 +            : and then encoded with base64 encoding.
   17.58 +
   17.59 +    mimetype: application/x-microsoft.net.object.bytearray.base64
   17.60 +    value   : The object must be serialized into a byte array 
   17.61 +            : using a System.ComponentModel.TypeConverter
   17.62 +            : and then encoded with base64 encoding.
   17.63 +    -->
   17.64 +  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
   17.65 +    <xsd:element name="root" msdata:IsDataSet="true">
   17.66 +      <xsd:complexType>
   17.67 +        <xsd:choice maxOccurs="unbounded">
   17.68 +          <xsd:element name="metadata">
   17.69 +            <xsd:complexType>
   17.70 +              <xsd:sequence>
   17.71 +                <xsd:element name="value" type="xsd:string" minOccurs="0" />
   17.72 +              </xsd:sequence>
   17.73 +              <xsd:attribute name="name" type="xsd:string" />
   17.74 +              <xsd:attribute name="type" type="xsd:string" />
   17.75 +              <xsd:attribute name="mimetype" type="xsd:string" />
   17.76 +            </xsd:complexType>
   17.77 +          </xsd:element>
   17.78 +          <xsd:element name="data">
   17.79 +            <xsd:complexType>
   17.80 +              <xsd:sequence>
   17.81 +                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
   17.82 +                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
   17.83 +              </xsd:sequence>
   17.84 +              <xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
   17.85 +              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
   17.86 +              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
   17.87 +            </xsd:complexType>
   17.88 +          </xsd:element>
   17.89 +          <xsd:element name="resheader">
   17.90 +            <xsd:complexType>
   17.91 +              <xsd:sequence>
   17.92 +                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
   17.93 +              </xsd:sequence>
   17.94 +              <xsd:attribute name="name" type="xsd:string" use="required" />
   17.95 +            </xsd:complexType>
   17.96 +          </xsd:element>
   17.97 +        </xsd:choice>
   17.98 +      </xsd:complexType>
   17.99 +    </xsd:element>
  17.100 +  </xsd:schema>
  17.101 +  <resheader name="resmimetype">
  17.102 +    <value>text/microsoft-resx</value>
  17.103 +  </resheader>
  17.104 +  <resheader name="version">
  17.105 +    <value>2.0</value>
  17.106 +  </resheader>
  17.107 +  <resheader name="reader">
  17.108 +    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
  17.109 +  </resheader>
  17.110 +  <resheader name="writer">
  17.111 +    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
  17.112 +  </resheader>
  17.113 +</root>
  17.114 \ No newline at end of file
    18.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    18.2 +++ b/Properties/Settings.Designer.cs	Wed May 14 07:52:21 2014 +0200
    18.3 @@ -0,0 +1,26 @@
    18.4 +//------------------------------------------------------------------------------
    18.5 +// <auto-generated>
    18.6 +//     This code was generated by a tool.
    18.7 +//     Runtime Version:4.0.30319.18010
    18.8 +//
    18.9 +//     Changes to this file may cause incorrect behavior and will be lost if
   18.10 +//     the code is regenerated.
   18.11 +// </auto-generated>
   18.12 +//------------------------------------------------------------------------------
   18.13 +
   18.14 +namespace GenericHid.Properties {
   18.15 +    
   18.16 +    
   18.17 +    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
   18.18 +    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")]
   18.19 +    internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
   18.20 +        
   18.21 +        private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
   18.22 +        
   18.23 +        public static Settings Default {
   18.24 +            get {
   18.25 +                return defaultInstance;
   18.26 +            }
   18.27 +        }
   18.28 +    }
   18.29 +}
    19.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    19.2 +++ b/Properties/Settings.settings	Wed May 14 07:52:21 2014 +0200
    19.3 @@ -0,0 +1,6 @@
    19.4 +<?xml version='1.0' encoding='utf-8'?>
    19.5 +<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)">
    19.6 +  <Profiles>
    19.7 +    <Profile Name="(Default)" />
    19.8 +  </Profiles>
    19.9 +</SettingsFile>
    20.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    20.2 +++ b/app.config	Wed May 14 07:52:21 2014 +0200
    20.3 @@ -0,0 +1,3 @@
    20.4 +<?xml version="1.0"?>
    20.5 +<configuration>
    20.6 +<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5"/></startup></configuration>
    21.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    21.2 +++ b/publish/GenericHid.application	Wed May 14 07:52:21 2014 +0200
    21.3 @@ -0,0 +1,21 @@
    21.4 +<?xml version="1.0" encoding="utf-8"?>
    21.5 +<asmv1:assembly xsi:schemaLocation="urn:schemas-microsoft-com:asm.v1 assembly.adaptive.xsd" manifestVersion="1.0" xmlns:asmv1="urn:schemas-microsoft-com:asm.v1" xmlns="urn:schemas-microsoft-com:asm.v2" xmlns:asmv2="urn:schemas-microsoft-com:asm.v2" xmlns:xrml="urn:mpeg:mpeg21:2003:01-REL-R-NS" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3" xmlns:dsig="http://www.w3.org/2000/09/xmldsig#" xmlns:co.v1="urn:schemas-microsoft-com:clickonce.v1" xmlns:co.v2="urn:schemas-microsoft-com:clickonce.v2">
    21.6 +  <assemblyIdentity name="GenericHid.application" version="6.2.0.0" publicKeyToken="e912df4371957e61" language="neutral" processorArchitecture="msil" xmlns="urn:schemas-microsoft-com:asm.v1" />
    21.7 +  <description asmv2:publisher="GenericHid" asmv2:product="GenericHid" xmlns="urn:schemas-microsoft-com:asm.v1" />
    21.8 +  <deployment install="true" mapFileExtensions="true" />
    21.9 +  <compatibleFrameworks xmlns="urn:schemas-microsoft-com:clickonce.v2">
   21.10 +    <framework targetVersion="4.5" profile="Full" supportedRuntime="4.0.30319" />
   21.11 +  </compatibleFrameworks>
   21.12 +  <dependency>
   21.13 +    <dependentAssembly dependencyType="install" codebase="Application Files\GenericHid_6_2_0_0\GenericHid.exe.manifest" size="7558">
   21.14 +      <assemblyIdentity name="GenericHid.exe" version="6.2.0.0" publicKeyToken="e912df4371957e61" language="neutral" processorArchitecture="msil" type="win32" />
   21.15 +      <hash>
   21.16 +        <dsig:Transforms>
   21.17 +          <dsig:Transform Algorithm="urn:schemas-microsoft-com:HashTransforms.Identity" />
   21.18 +        </dsig:Transforms>
   21.19 +        <dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha256" />
   21.20 +        <dsig:DigestValue>oQgb8A8n+lzj+3t+OgYSWwxoRg2BjZwoA6qP23iuoq0=</dsig:DigestValue>
   21.21 +      </hash>
   21.22 +    </dependentAssembly>
   21.23 +  </dependency>
   21.24 +<publisherIdentity name="CN=LVR2012\jan" issuerKeyHash="70f83b2370f422d4e3355b5c66f809cda26371c5" /><Signature Id="StrongNameSignature" xmlns="http://www.w3.org/2000/09/xmldsig#"><SignedInfo><CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" /><SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha256" /><Reference URI=""><Transforms><Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" /><Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" /></Transforms><DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha256" /><DigestValue>Lq11Sw3U1N8vRticxZzSjoQ6oqyNni1fUjnATzMnmvE=</DigestValue></Reference></SignedInfo><SignatureValue>RaX+F7wItRwo1xWOj5oNucSLJAEG+ZMa+gP92gUY2DeHBZJ3xl+8UYF/kuuSOf4DBNquvXRHyLXeegzkFttrqtO704gxqcIbXBcZi7w0PXZNmw+kN/8ykkWCShQiz8f3IYjqjQV199fxw3NAciCpWCLNSAMRYtVX6VyIEQCI6ns=</SignatureValue><KeyInfo Id="StrongNameKeyInfo"><KeyValue><RSAKeyValue><Modulus>vZK+hjF855eH6ywa/BZBvxkMJFFIIFjX0riqpVp0M088+99Ygevu3AGL1ajEdjQwry8w4ZXnz4jUfHSC2nhBKONyLrzV2dQH+RwonfAW8ExhueAb7u/pG77yb3T+kRbiHNPuRP8nlFTzm+riq/k1A1EqAK2n6MeVFUyk85S3xtU=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue></KeyValue><msrel:RelData xmlns:msrel="http://schemas.microsoft.com/windows/rel/2005/reldata"><r:license xmlns:r="urn:mpeg:mpeg21:2003:01-REL-R-NS" xmlns:as="http://schemas.microsoft.com/windows/pki/2005/Authenticode"><r:grant><as:ManifestInformation Hash="f19a27334fc039525f2d9e8daca23a848ed29cc59cd8462fdfd4d40d4b75ad2e" Description="" Url=""><as:assemblyIdentity name="GenericHid.application" version="6.2.0.0" publicKeyToken="e912df4371957e61" language="neutral" processorArchitecture="msil" xmlns="urn:schemas-microsoft-com:asm.v1" /></as:ManifestInformation><as:SignedBy /><as:AuthenticodePublisher><as:X509SubjectName>CN=LVR2012\jan</as:X509SubjectName></as:AuthenticodePublisher></r:grant><r:issuer><Signature Id="AuthenticodeSignature" xmlns="http://www.w3.org/2000/09/xmldsig#"><SignedInfo><CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" /><SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha256" /><Reference URI=""><Transforms><Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" /><Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" /></Transforms><DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha256" /><DigestValue>Nr/7DS53yGSNQxZA8cHgQphhjotTpOqFPw/G1Vh1qZI=</DigestValue></Reference></SignedInfo><SignatureValue>VEtiDTr4D9sGpmtS0wEej0Kmlx+zXyxZglD+CUVKbqW6YbPgfVbgZTRPtps+asBMqCusZUVUqtnwIvFJ89GwlKr+59nMUMlxiPuHFrnM8LJqWTMT05lJFO9P1h3t2U0pkCkbD+tFIpcLUxuVJmG+Lx9SH+nYnxY90QbhgAR43eg=</SignatureValue><KeyInfo><KeyValue><RSAKeyValue><Modulus>vZK+hjF855eH6ywa/BZBvxkMJFFIIFjX0riqpVp0M088+99Ygevu3AGL1ajEdjQwry8w4ZXnz4jUfHSC2nhBKONyLrzV2dQH+RwonfAW8ExhueAb7u/pG77yb3T+kRbiHNPuRP8nlFTzm+riq/k1A1EqAK2n6MeVFUyk85S3xtU=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue></KeyValue><X509Data><X509Certificate>MIIBxTCCAS6gAwIBAgIQG1z/tZx30LZKDzrL/KUXPjANBgkqhkiG9w0BAQsFADAhMR8wHQYDVQQDHhYATABWAFIAMgAwADEAMgBcAGoAYQBuMB4XDTEzMTAzMDAxMzYxNloXDTE0MTAzMDA3MzYxNlowITEfMB0GA1UEAx4WAEwAVgBSADIAMAAxADIAXABqAGEAbjCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAvZK+hjF855eH6ywa/BZBvxkMJFFIIFjX0riqpVp0M088+99Ygevu3AGL1ajEdjQwry8w4ZXnz4jUfHSC2nhBKONyLrzV2dQH+RwonfAW8ExhueAb7u/pG77yb3T+kRbiHNPuRP8nlFTzm+riq/k1A1EqAK2n6MeVFUyk85S3xtUCAwEAATANBgkqhkiG9w0BAQsFAAOBgQB5WjMIunQoSYZTqVnK1+emQt2+v/SzZc1oYY1G5ikE/t92Phyu0E9PgA6nXavF2IMrzOnmnNasTO9ygFQ+ck96TyD1FsQW9XRYxYdCn5oC+Caelwm5CPHRI2PKnw15IRDT9hHFj4AxYMSnN7uPXO+7eOjAbtRnynn0KAq+1PsFAA==</X509Certificate></X509Data></KeyInfo></Signature></r:issuer></r:license></msrel:RelData></KeyInfo></Signature></asmv1:assembly>
   21.25 \ No newline at end of file
    22.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    22.2 +++ b/readme.txt	Wed May 14 07:52:21 2014 +0200
    22.3 @@ -0,0 +1,136 @@
    22.4 +	///<summary>
    22.5 +	/// Project: GenericHid
    22.6 +	/// 
    22.7 +	/// ***********************************************************************
    22.8 +	/// Software License Agreement
    22.9 +	///
   22.10 +	/// Licensor grants any person obtaining a copy of this software ("You") 
   22.11 +	/// a worldwide, royalty-free, non-exclusive license, for the duration of 
   22.12 +	/// the copyright, free of charge, to store and execute the Software in a 
   22.13 +	/// computer system and to incorporate the Software or any portion of it 
   22.14 +	/// in computer programs You write.   
   22.15 +	/// 
   22.16 +	/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   22.17 +	/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   22.18 +	/// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
   22.19 +	/// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   22.20 +	/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
   22.21 +	/// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
   22.22 +	/// THE SOFTWARE.
   22.23 +	/// ***********************************************************************
   22.24 +	/// 
   22.25 +	/// Author             
   22.26 +	/// Jan Axelson        
   22.27 +	/// 
   22.28 +	/// This software was written using Visual Studio Express 2012 for Windows
   22.29 +	/// Desktop building for the .NET Framework v4.5.
   22.30 +	/// 
   22.31 +	/// Purpose: 
   22.32 +	/// Demonstrates USB communications with a generic HID-class device
   22.33 +	/// 
   22.34 +	/// Requirements:
   22.35 +	/// Windows Vista or later and an attached USB generic Human Interface Device (HID).
   22.36 +	/// (Does not run on Windows XP or earlier because .NET Framework 4.5 will not install on these OSes.) 
   22.37 +	/// 
   22.38 +	/// Description:
   22.39 +	/// Finds an attached device that matches the vendor and product IDs in the form's 
   22.40 +	/// text boxes.
   22.41 +	/// 
   22.42 +	/// Retrieves the device's capabilities.
   22.43 +	/// Sends and requests HID reports.
   22.44 +	/// 
   22.45 +	/// Uses the System.Management class and Windows Management Instrumentation (WMI) to detect 
   22.46 +	/// when a device is attached or removed.
   22.47 +	/// 
   22.48 +	/// A list box displays the data sent and received along with error and status messages.
   22.49 +	/// You can select data to send and 1-time or periodic transfers.
   22.50 +	/// 
   22.51 +	/// You can change the size of the host's Input report buffer and request to use control
   22.52 +	/// transfers only to exchange Input and Output reports.
   22.53 +	/// 
   22.54 +	/// To view additional debugging messages, in the Visual Studio development environment,
   22.55 +	/// from the main menu, select Build > Configuration Manager > Active Solution Configuration 
   22.56 +	/// and select Configuration > Debug and from the main menu, select View > Output.
   22.57 +	/// 
   22.58 +	/// The application uses asynchronous FileStreams to read Input reports and write Output 
   22.59 +	/// reports so the application's main thread doesn't have to wait for the device to retrieve a 
   22.60 +	/// report when the HID driver's buffer is empty or send a report when the device's endpoint is busy. 
   22.61 +	/// 
   22.62 +	/// For code that finds a device and opens handles to it, see the FindTheHid routine in frmMain.cs.
   22.63 +	/// For code that reads from the device, see GetInputReportViaInterruptTransfer, 
   22.64 +	/// GetInputReportViaControlTransfer, and GetFeatureReport in Hid.cs.
   22.65 +	/// For code that writes to the device, see SendInputReportViaInterruptTransfer, 
   22.66 +	/// SendInputReportViaControlTransfer, and SendFeatureReport in Hid.cs.
   22.67 +	/// 
   22.68 +	/// This project includes the following modules:
   22.69 +	/// 
   22.70 +	/// GenericHid.cs - runs the application.
   22.71 +	/// FrmMain.cs - routines specific to the form.
   22.72 +	/// Hid.cs - routines specific to HID communications.
   22.73 +	/// DeviceManagement.cs - routine for obtaining a handle to a device from its GUID.
   22.74 +	/// Debugging.cs - contains a routine for displaying API error messages.
   22.75 +	/// HidDeclarations.cs - Declarations for API functions used by Hid.cs.
   22.76 +	/// FileIODeclarations.cs - Declarations for file-related API functions.
   22.77 +	/// DeviceManagementDeclarations.cs - Declarations for API functions used by DeviceManagement.cs.
   22.78 +	/// DebuggingDeclarations.cs - Declarations for API functions used by Debugging.cs.
   22.79 +	/// 
   22.80 +	/// Companion device firmware for several device CPUs is available from www.Lvr.com/hidpage.htm
   22.81 +	/// You can use any generic HID (not a system mouse or keyboard) that sends and receives reports.
   22.82 +	/// This application will not detect or communicate with non-HID-class devices.
   22.83 +	/// 
   22.84 +	/// For more information about HIDs and USB, and additional example device firmware to use
   22.85 +	/// with this application, visit Lakeview Research at http://Lvr.com 
   22.86 +	/// Send comments, bug reports, etc. to jan@Lvr.com or post on my PORTS forum: http://www.lvr.com/forum 
   22.87 +	/// 
   22.88 +	/// V6.2
   22.89 +	/// 11/12/13
   22.90 +	/// Disabled form buttons when a transfer is in progress.
   22.91 +	/// Other minor edits for clarity and readability.
   22.92 +	/// Will NOT run on Windows XP or earlier, see below.
   22.93 +	/// 
   22.94 +	/// V6.1
   22.95 +	/// 10/28/13
   22.96 +	/// Uses the .NET System.Management class to detect device arrival and removal with WMI instead of Win32 RegisterDeviceNotification.
   22.97 +	/// Other minor edits.
   22.98 +	/// Will NOT run on Windows XP or earlier, see below.
   22.99 +	///  
  22.100 +	/// V6.0
  22.101 +	/// 2/8/13
  22.102 +	/// This version will NOT run on Windows XP or earlier because the code uses .NET Framework 4.5 to support asynchronous FileStreams.
  22.103 +	/// The .NET Framework 4.5 redistributable is compatible with Windows 8, Windows 7 SP1, Windows Server 2008 R2 SP1, 
  22.104 +	/// Windows Server 2008 SP2, Windows Vista SP2, and Windows Vista SP3.
  22.105 +	/// For compatibility, replaced ToInt32 with ToInt64 here:
  22.106 +	/// IntPtr pDevicePathName = new IntPtr(detailDataBuffer.ToInt64() + 4);
  22.107 +	/// and here:
  22.108 +	/// if ((deviceNotificationHandle.ToInt64() == IntPtr.Zero.ToInt64()))
  22.109 +	/// For compatibility if the charset isn't English, added System.Globalization.CultureInfo.InvariantCulture here:
  22.110 +	/// if ((String.Compare(DeviceNameString, mydevicePathName, true, System.Globalization.CultureInfo.InvariantCulture) == 0))
  22.111 +	/// Replaced all Microsoft.VisualBasic namespace code with other .NET equivalents.
  22.112 +	/// Revised user interface for more flexibility.
  22.113 +	/// Moved interrupt-transfer and other HID-specific code to Hid.cs.
  22.114 +	/// Used JetBrains ReSharper to clean up the code: http://www.jetbrains.com/resharper/
  22.115 +	/// 
  22.116 +	/// V5.0
  22.117 +	/// 3/30/11
  22.118 +	/// Replaced ReadFile and WriteFile with FileStreams. Thanks to Joe Dunne and John on my Ports forum for tips on this.
  22.119 +	/// Simplified Hid.cs.
  22.120 +	/// Replaced the form timer with a system timer.
  22.121 +	/// 
  22.122 +	/// V4.6
  22.123 +	/// 1/12/10
  22.124 +	/// Supports Vendor IDs and Product IDs up to FFFFh.
  22.125 +	///
  22.126 +	/// V4.52
  22.127 +	/// 11/10/09
  22.128 +	/// Changed HIDD_ATTRIBUTES to use UInt16
  22.129 +	/// 
  22.130 +	/// V4.51
  22.131 +	/// 2/11/09
  22.132 +	/// Moved Free_ and similar to Finally blocks to ensure they execute.
  22.133 +	/// 
  22.134 +	/// V4.5
  22.135 +	/// 2/9/09
  22.136 +	/// Changes to support 64-bit systems, memory management, and other corrections. 
  22.137 +	/// Big thanks to Peter Nielsen.
  22.138 +	///  
  22.139 +	/// </summary>