Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/ClusterM/ibutton_client.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'iButtonLib/Win32Usb.cs')
-rw-r--r--iButtonLib/Win32Usb.cs288
1 files changed, 288 insertions, 0 deletions
diff --git a/iButtonLib/Win32Usb.cs b/iButtonLib/Win32Usb.cs
new file mode 100644
index 0000000..b55cdf0
--- /dev/null
+++ b/iButtonLib/Win32Usb.cs
@@ -0,0 +1,288 @@
+using System;
+using System.Text;
+using System.Runtime.InteropServices;
+
+namespace UsbLibrary
+{
+ /// <summary>
+ /// Class that wraps USB API calls and structures.
+ /// </summary>
+ public class Win32Usb
+ {
+ #region Structures
+ /// <summary>
+ /// An overlapped structure used for overlapped IO operations. The structure is
+ /// only used by the OS to keep state on pending operations. You don't need to fill anything in if you
+ /// unless you want a Windows event to fire when the operation is complete.
+ /// </summary>
+ [StructLayout(LayoutKind.Sequential, Pack = 1)]
+ protected struct Overlapped
+ {
+ public uint Internal;
+ public uint InternalHigh;
+ public uint Offset;
+ public uint OffsetHigh;
+ public IntPtr Event;
+ }
+ /// <summary>
+ /// Provides details about a single USB device
+ /// </summary>
+ [StructLayout(LayoutKind.Sequential, Pack = 1)]
+ protected struct DeviceInterfaceData
+ {
+ public int Size;
+ public Guid InterfaceClassGuid;
+ public int Flags;
+ public int Reserved;
+ }
+ /// <summary>
+ /// Provides the capabilities of a HID device
+ /// </summary>
+ [StructLayout(LayoutKind.Sequential, Pack = 1)]
+ protected struct HidCaps
+ {
+ public short Usage;
+ public short UsagePage;
+ public short InputReportByteLength;
+ public short OutputReportByteLength;
+ public short FeatureReportByteLength;
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 17)]
+ public short[] Reserved;
+ public short NumberLinkCollectionNodes;
+ public short NumberInputButtonCaps;
+ public short NumberInputValueCaps;
+ public short NumberInputDataIndices;
+ public short NumberOutputButtonCaps;
+ public short NumberOutputValueCaps;
+ public short NumberOutputDataIndices;
+ public short NumberFeatureButtonCaps;
+ public short NumberFeatureValueCaps;
+ public short NumberFeatureDataIndices;
+ }
+ /// <summary>
+ /// Access to the path for a device
+ /// </summary>
+ [StructLayout(LayoutKind.Sequential, Pack = 1)]
+ public struct DeviceInterfaceDetailData
+ {
+ public int Size;
+ [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
+ public string DevicePath;
+ }
+ /// <summary>
+ /// Used when registering a window to receive messages about devices added or removed from the system.
+ /// </summary>
+ [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode, Pack = 1)]
+ public class DeviceBroadcastInterface
+ {
+ public int Size;
+ public int DeviceType;
+ public int Reserved;
+ public Guid ClassGuid;
+ [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
+ public string Name;
+ }
+ #endregion
+
+ #region Constants
+ /// <summary>Windows message sent when a device is inserted or removed</summary>
+ public const int WM_DEVICECHANGE = 0x0219;
+ /// <summary>WParam for above : A device was inserted</summary>
+ public const int DEVICE_ARRIVAL = 0x8000;
+ /// <summary>WParam for above : A device was removed</summary>
+ public const int DEVICE_REMOVECOMPLETE = 0x8004;
+ /// <summary>Used in SetupDiClassDevs to get devices present in the system</summary>
+ protected const int DIGCF_PRESENT = 0x02;
+ /// <summary>Used in SetupDiClassDevs to get device interface details</summary>
+ protected const int DIGCF_DEVICEINTERFACE = 0x10;
+ /// <summary>Used when registering for device insert/remove messages : specifies the type of device</summary>
+ protected const int DEVTYP_DEVICEINTERFACE = 0x05;
+ /// <summary>Used when registering for device insert/remove messages : we're giving the API call a window handle</summary>
+ protected const int DEVICE_NOTIFY_WINDOW_HANDLE = 0;
+ /// <summary>Purges Win32 transmit buffer by aborting the current transmission.</summary>
+ protected const uint PURGE_TXABORT = 0x01;
+ /// <summary>Purges Win32 receive buffer by aborting the current receive.</summary>
+ protected const uint PURGE_RXABORT = 0x02;
+ /// <summary>Purges Win32 transmit buffer by clearing it.</summary>
+ protected const uint PURGE_TXCLEAR = 0x04;
+ /// <summary>Purges Win32 receive buffer by clearing it.</summary>
+ protected const uint PURGE_RXCLEAR = 0x08;
+ /// <summary>CreateFile : Open file for read</summary>
+ protected const uint GENERIC_READ = 0x80000000;
+ /// <summary>CreateFile : Open file for write</summary>
+ protected const uint GENERIC_WRITE = 0x40000000;
+ /// <summary>CreateFile : file share for write</summary>
+ protected const uint FILE_SHARE_WRITE = 0x2;
+ /// <summary>CreateFile : file share for read</summary>
+ protected const uint FILE_SHARE_READ = 0x1;
+ /// <summary>CreateFile : Open handle for overlapped operations</summary>
+ protected const uint FILE_FLAG_OVERLAPPED = 0x40000000;
+ /// <summary>CreateFile : Resource to be "created" must exist</summary>
+ protected const uint OPEN_EXISTING = 3;
+ /// <summary>CreateFile : Resource will be "created" or existing will be used</summary>
+ protected const uint OPEN_ALWAYS = 4;
+ /// <summary>ReadFile/WriteFile : Overlapped operation is incomplete.</summary>
+ protected const uint ERROR_IO_PENDING = 997;
+ /// <summary>Infinite timeout</summary>
+ protected const uint INFINITE = 0xFFFFFFFF;
+ /// <summary>Simple representation of a null handle : a closed stream will get this handle. Note it is public for comparison by higher level classes.</summary>
+ public static IntPtr NullHandle = IntPtr.Zero;
+ /// <summary>Simple representation of the handle returned when CreateFile fails.</summary>
+ protected static IntPtr InvalidHandleValue = new IntPtr(-1);
+ #endregion
+
+ #region P/Invoke
+ /// <summary>
+ /// Gets the GUID that Windows uses to represent HID class devices
+ /// </summary>
+ /// <param name="gHid">An out parameter to take the Guid</param>
+ [DllImport("hid.dll", SetLastError = true)] protected static extern void HidD_GetHidGuid(out Guid gHid);
+ /// <summary>
+ /// Allocates an InfoSet memory block within Windows that contains details of devices.
+ /// </summary>
+ /// <param name="gClass">Class guid (e.g. HID guid)</param>
+ /// <param name="strEnumerator">Not used</param>
+ /// <param name="hParent">Not used</param>
+ /// <param name="nFlags">Type of device details required (DIGCF_ constants)</param>
+ /// <returns>A reference to the InfoSet</returns>
+ [DllImport("setupapi.dll", SetLastError = true)] protected static extern IntPtr SetupDiGetClassDevs(ref Guid gClass, [MarshalAs(UnmanagedType.LPStr)] string strEnumerator, IntPtr hParent, uint nFlags);
+ /// <summary>
+ /// Frees InfoSet allocated in call to above.
+ /// </summary>
+ /// <param name="lpInfoSet">Reference to InfoSet</param>
+ /// <returns>true if successful</returns>
+ [DllImport("setupapi.dll", SetLastError = true)] protected static extern int SetupDiDestroyDeviceInfoList(IntPtr lpInfoSet);
+ /// <summary>
+ /// Gets the DeviceInterfaceData for a device from an InfoSet.
+ /// </summary>
+ /// <param name="lpDeviceInfoSet">InfoSet to access</param>
+ /// <param name="nDeviceInfoData">Not used</param>
+ /// <param name="gClass">Device class guid</param>
+ /// <param name="nIndex">Index into InfoSet for device</param>
+ /// <param name="oInterfaceData">DeviceInterfaceData to fill with data</param>
+ /// <returns>True if successful, false if not (e.g. when index is passed end of InfoSet)</returns>
+ [DllImport("setupapi.dll", SetLastError = true)] protected static extern bool SetupDiEnumDeviceInterfaces(IntPtr lpDeviceInfoSet, uint nDeviceInfoData, ref Guid gClass, uint nIndex, ref DeviceInterfaceData oInterfaceData);
+ /// <summary>
+ /// SetupDiGetDeviceInterfaceDetail
+ /// Gets the interface detail from a DeviceInterfaceData. This is pretty much the device path.
+ /// You call this twice, once to get the size of the struct you need to send (nDeviceInterfaceDetailDataSize=0)
+ /// and once again when you've allocated the required space.
+ /// </summary>
+ /// <param name="lpDeviceInfoSet">InfoSet to access</param>
+ /// <param name="oInterfaceData">DeviceInterfaceData to use</param>
+ /// <param name="lpDeviceInterfaceDetailData">DeviceInterfaceDetailData to fill with data</param>
+ /// <param name="nDeviceInterfaceDetailDataSize">The size of the above</param>
+ /// <param name="nRequiredSize">The required size of the above when above is set as zero</param>
+ /// <param name="lpDeviceInfoData">Not used</param>
+ /// <returns></returns>
+ [DllImport("setupapi.dll", SetLastError = true)] protected static extern bool SetupDiGetDeviceInterfaceDetail(IntPtr lpDeviceInfoSet, ref DeviceInterfaceData oInterfaceData, IntPtr lpDeviceInterfaceDetailData, uint nDeviceInterfaceDetailDataSize, ref uint nRequiredSize, IntPtr lpDeviceInfoData);
+ /// <summary>
+ /// SetupDiGetDeviceInterfaceDetail
+ /// Gets the interface detail from a DeviceInterfaceData. This is pretty much the device path.
+ /// You call this twice, once to get the size of the struct you need to send (nDeviceInterfaceDetailDataSize=0)
+ /// and once again when you've allocated the required space.
+ /// </summary>
+ /// <param name="lpDeviceInfoSet">InfoSet to access</param>
+ /// <param name="oInterfaceData">DeviceInterfaceData to use</param>
+ /// <param name="oDetailData">DeviceInterfaceDetailData to fill with data</param>
+ /// <param name="nDeviceInterfaceDetailDataSize">The size of the above</param>
+ /// <param name="nRequiredSize">The required size of the above when above is set as zero</param>
+ /// <param name="lpDeviceInfoData">Not used</param>
+ /// <returns></returns>
+ [DllImport("setupapi.dll", SetLastError = true)] protected static extern bool SetupDiGetDeviceInterfaceDetail(IntPtr lpDeviceInfoSet, ref DeviceInterfaceData oInterfaceData, ref DeviceInterfaceDetailData oDetailData, uint nDeviceInterfaceDetailDataSize, ref uint nRequiredSize, IntPtr lpDeviceInfoData);
+ /// <summary>
+ /// Registers a window for device insert/remove messages
+ /// </summary>
+ /// <param name="hwnd">Handle to the window that will receive the messages</param>
+ /// <param name="oInterface">DeviceBroadcastInterrface structure</param>
+ /// <param name="nFlags">set to DEVICE_NOTIFY_WINDOW_HANDLE</param>
+ /// <returns>A handle used when unregistering</returns>
+ [DllImport("user32.dll", SetLastError = true)] protected static extern IntPtr RegisterDeviceNotification(IntPtr hwnd, DeviceBroadcastInterface oInterface, uint nFlags);
+ /// <summary>
+ /// Unregister from above.
+ /// </summary>
+ /// <param name="hHandle">Handle returned in call to RegisterDeviceNotification</param>
+ /// <returns>True if success</returns>
+ [DllImport("user32.dll", SetLastError = true)] protected static extern bool UnregisterDeviceNotification(IntPtr hHandle);
+ /// <summary>
+ /// Gets details from an open device. Reserves a block of memory which must be freed.
+ /// </summary>
+ /// <param name="hFile">Device file handle</param>
+ /// <param name="lpData">Reference to the preparsed data block</param>
+ /// <returns></returns>
+ [DllImport("hid.dll", SetLastError = true)] protected static extern bool HidD_GetPreparsedData(IntPtr hFile, out IntPtr lpData);
+ /// <summary>
+ /// Frees the memory block reserved above.
+ /// </summary>
+ /// <param name="pData">Reference to preparsed data returned in call to GetPreparsedData</param>
+ /// <returns></returns>
+ [DllImport("hid.dll", SetLastError = true)] protected static extern bool HidD_FreePreparsedData(ref IntPtr pData);
+ /// <summary>
+ /// Gets a device's capabilities from the preparsed data.
+ /// </summary>
+ /// <param name="lpData">Preparsed data reference</param>
+ /// <param name="oCaps">HidCaps structure to receive the capabilities</param>
+ /// <returns>True if successful</returns>
+ [DllImport("hid.dll", SetLastError = true)] protected static extern int HidP_GetCaps(IntPtr lpData, out HidCaps oCaps);
+ /// <summary>
+ /// Creates/opens a file, serial port, USB device... etc
+ /// </summary>
+ /// <param name="strName">Path to object to open</param>
+ /// <param name="nAccess">Access mode. e.g. Read, write</param>
+ /// <param name="nShareMode">Sharing mode</param>
+ /// <param name="lpSecurity">Security details (can be null)</param>
+ /// <param name="nCreationFlags">Specifies if the file is created or opened</param>
+ /// <param name="nAttributes">Any extra attributes? e.g. open overlapped</param>
+ /// <param name="lpTemplate">Not used</param>
+ /// <returns></returns>
+ [DllImport("kernel32.dll", SetLastError = true)] protected static extern IntPtr CreateFile([MarshalAs(UnmanagedType.LPStr)] string strName, uint nAccess, uint nShareMode, IntPtr lpSecurity, uint nCreationFlags, uint nAttributes, IntPtr lpTemplate);
+ /// <summary>
+ /// Closes a window handle. File handles, event handles, mutex handles... etc
+ /// </summary>
+ /// <param name="hFile">Handle to close</param>
+ /// <returns>True if successful.</returns>
+ [DllImport("kernel32.dll", SetLastError = true)] protected static extern int CloseHandle(IntPtr hFile);
+ #endregion
+
+ #region Public methods
+ /// <summary>
+ /// Registers a window to receive windows messages when a device is inserted/removed. Need to call this
+ /// from a form when its handle has been created, not in the form constructor. Use form's OnHandleCreated override.
+ /// </summary>
+ /// <param name="hWnd">Handle to window that will receive messages</param>
+ /// <param name="gClass">Class of devices to get messages for</param>
+ /// <returns>A handle used when unregistering</returns>
+ public static IntPtr RegisterForUsbEvents(IntPtr hWnd, Guid gClass)
+ {
+ DeviceBroadcastInterface oInterfaceIn = new DeviceBroadcastInterface();
+ oInterfaceIn.Size = Marshal.SizeOf(oInterfaceIn);
+ oInterfaceIn.ClassGuid = gClass;
+ oInterfaceIn.DeviceType = DEVTYP_DEVICEINTERFACE;
+ oInterfaceIn.Reserved = 0;
+ return RegisterDeviceNotification(hWnd, oInterfaceIn, DEVICE_NOTIFY_WINDOW_HANDLE);
+ }
+ /// <summary>
+ /// Unregisters notifications. Can be used in form dispose
+ /// </summary>
+ /// <param name="hHandle">Handle returned from RegisterForUSBEvents</param>
+ /// <returns>True if successful</returns>
+ public static bool UnregisterForUsbEvents(IntPtr hHandle)
+ {
+ return UnregisterDeviceNotification(hHandle);
+ }
+ /// <summary>
+ /// Helper to get the HID guid.
+ /// </summary>
+ public static Guid HIDGuid
+ {
+ get
+ {
+ Guid gHid;
+ HidD_GetHidGuid(out gHid);
+ return gHid;
+ //return new Guid("A5DCBF10-6530-11D2-901F-00C04FB951ED"); //gHid;
+ }
+ }
+ #endregion
+ }
+}