cemu-DS4Windows/DS4Windows/DS4Control/ScpDevice.cs
Travis Nickles 2029cc5531 Register for more specific device change events
This should make the WndProc method execution leaner
2018-10-16 14:35:41 -05:00

710 lines
28 KiB
C#

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Runtime.InteropServices;
using System.Security;
using Microsoft.Win32.SafeHandles;
namespace DS4Windows
{
[SuppressUnmanagedCodeSecurity]
public partial class ScpDevice : Component
{
public virtual Boolean IsActive
{
get { return m_IsActive; }
}
public virtual String Path
{
get { return m_Path; }
}
public ScpDevice()
{
InitializeComponent();
}
public ScpDevice(IContainer container)
{
container.Add(this);
InitializeComponent();
}
public ScpDevice(String Class)
{
InitializeComponent();
this.m_Class = new Guid(Class);
}
public virtual Boolean Open(Int32 Instance = 0)
{
String DevicePath = String.Empty;
m_WinUsbHandle = (IntPtr) INVALID_HANDLE_VALUE;
if (Find(m_Class, ref DevicePath, Instance))
{
Open(DevicePath);
}
return m_IsActive;
}
public virtual Boolean Open(String DevicePath)
{
m_Path = DevicePath.ToUpper();
m_WinUsbHandle = (IntPtr) INVALID_HANDLE_VALUE;
if (GetDeviceHandle(m_Path))
{
if (WinUsb_Initialize(m_FileHandle, ref m_WinUsbHandle))
{
if (InitializeDevice())
{
m_IsActive = true;
}
else
{
WinUsb_Free(m_WinUsbHandle);
m_WinUsbHandle = (IntPtr) INVALID_HANDLE_VALUE;
}
}
else
{
m_FileHandle.Close();
}
}
return m_IsActive;
}
public virtual Boolean Start()
{
return m_IsActive;
}
public virtual Boolean Stop()
{
m_IsActive = false;
if (!(m_WinUsbHandle == (IntPtr) INVALID_HANDLE_VALUE))
{
WinUsb_AbortPipe(m_WinUsbHandle, m_IntIn);
WinUsb_AbortPipe(m_WinUsbHandle, m_BulkIn);
WinUsb_AbortPipe(m_WinUsbHandle, m_BulkOut);
WinUsb_Free(m_WinUsbHandle);
m_WinUsbHandle = (IntPtr) INVALID_HANDLE_VALUE;
}
if (m_FileHandle != null && !m_FileHandle.IsInvalid && !m_FileHandle.IsClosed)
{
m_FileHandle.Close();
m_FileHandle = null;
}
return true;
}
public virtual Boolean Close()
{
return Stop();
}
public virtual Boolean ReadIntPipe (Byte[] Buffer, Int32 Length, ref Int32 Transfered)
{
if (!m_IsActive) return false;
return WinUsb_ReadPipe(m_WinUsbHandle, m_IntIn, Buffer, Length, ref Transfered, IntPtr.Zero);
}
public virtual Boolean ReadBulkPipe (Byte[] Buffer, Int32 Length, ref Int32 Transfered)
{
if (!m_IsActive) return false;
return WinUsb_ReadPipe(m_WinUsbHandle, m_BulkIn, Buffer, Length, ref Transfered, IntPtr.Zero);
}
public virtual Boolean WriteIntPipe (Byte[] Buffer, Int32 Length, ref Int32 Transfered)
{
if (!m_IsActive) return false;
return WinUsb_WritePipe(m_WinUsbHandle, m_IntOut, Buffer, Length, ref Transfered, IntPtr.Zero);
}
public virtual Boolean WriteBulkPipe(Byte[] Buffer, Int32 Length, ref Int32 Transfered)
{
if (!m_IsActive) return false;
return WinUsb_WritePipe(m_WinUsbHandle, m_BulkOut, Buffer, Length, ref Transfered, IntPtr.Zero);
}
public virtual Boolean SendTransfer(Byte RequestType, Byte Request, UInt16 Value, Byte[] Buffer, ref Int32 Transfered)
{
if (!m_IsActive) return false;
WINUSB_SETUP_PACKET Setup = new WINUSB_SETUP_PACKET();
Setup.RequestType = RequestType;
Setup.Request = Request;
Setup.Value = Value;
Setup.Index = 0;
Setup.Length = (UInt16) Buffer.Length;
return WinUsb_ControlTransfer(m_WinUsbHandle, Setup, Buffer, Buffer.Length, ref Transfered, IntPtr.Zero);
}
#region Constant and Structure Definitions
public const Int32 SERVICE_CONTROL_STOP = 0x00000001;
public const Int32 SERVICE_CONTROL_SHUTDOWN = 0x00000005;
public const Int32 SERVICE_CONTROL_DEVICEEVENT = 0x0000000B;
public const Int32 SERVICE_CONTROL_POWEREVENT = 0x0000000D;
public const Int32 DBT_DEVICEARRIVAL = 0x8000;
public const Int32 DBT_DEVICEQUERYREMOVE = 0x8001;
public const Int32 DBT_DEVICEREMOVECOMPLETE = 0x8004;
public const Int32 DBT_DEVTYP_DEVICEINTERFACE = 0x0005;
public const Int32 DBT_DEVTYP_HANDLE = 0x0006;
public const Int32 PBT_APMRESUMEAUTOMATIC = 0x0012;
public const Int32 PBT_APMSUSPEND = 0x0004;
public const Int32 DEVICE_NOTIFY_WINDOW_HANDLE = 0x0000;
public const Int32 DEVICE_NOTIFY_SERVICE_HANDLE = 0x0001;
public const Int32 DEVICE_NOTIFY_ALL_INTERFACE_CLASSES = 0x0004;
public const Int32 WM_CREATE = 0x0001;
public const Int32 WM_DEVICECHANGE = 0x0219;
public const Int32 DIGCF_PRESENT = 0x0002;
public const Int32 DIGCF_DEVICEINTERFACE = 0x0010;
public delegate Int32 ServiceControlHandlerEx(Int32 Control, Int32 Type, IntPtr Data, IntPtr Context);
[StructLayout(LayoutKind.Sequential)]
public class DEV_BROADCAST_DEVICEINTERFACE
{
internal Int32 dbcc_size;
internal Int32 dbcc_devicetype;
internal Int32 dbcc_reserved;
internal Guid dbcc_classguid;
internal Int16 dbcc_name;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public class DEV_BROADCAST_DEVICEINTERFACE_M
{
public Int32 dbcc_size;
public Int32 dbcc_devicetype;
public Int32 dbcc_reserved;
[MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.U1, SizeConst = 16)]
public Byte[] dbcc_classguid;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 255)]
public Char[] dbcc_name;
}
[StructLayout(LayoutKind.Sequential)]
public class DEV_BROADCAST_HDR
{
public Int32 dbch_size;
public Int32 dbch_devicetype;
public Int32 dbch_reserved;
}
[StructLayout(LayoutKind.Sequential)]
protected struct SP_DEVICE_INTERFACE_DATA
{
internal Int32 cbSize;
internal Guid InterfaceClassGuid;
internal Int32 Flags;
internal IntPtr Reserved;
}
protected const UInt32 FILE_ATTRIBUTE_NORMAL = 0x80;
protected const UInt32 FILE_FLAG_OVERLAPPED = 0x40000000;
protected const UInt32 FILE_SHARE_READ = 1;
protected const UInt32 FILE_SHARE_WRITE = 2;
protected const UInt32 GENERIC_READ = 0x80000000;
protected const UInt32 GENERIC_WRITE = 0x40000000;
protected const Int32 INVALID_HANDLE_VALUE = -1;
protected const UInt32 OPEN_EXISTING = 3;
protected const UInt32 DEVICE_SPEED = 1;
protected const Byte USB_ENDPOINT_DIRECTION_MASK = 0x80;
protected enum POLICY_TYPE
{
SHORT_PACKET_TERMINATE = 1,
AUTO_CLEAR_STALL = 2,
PIPE_TRANSFER_TIMEOUT = 3,
IGNORE_SHORT_PACKETS = 4,
ALLOW_PARTIAL_READS = 5,
AUTO_FLUSH = 6,
RAW_IO = 7,
}
protected enum USBD_PIPE_TYPE
{
UsbdPipeTypeControl = 0,
UsbdPipeTypeIsochronous = 1,
UsbdPipeTypeBulk = 2,
UsbdPipeTypeInterrupt = 3,
}
protected enum USB_DEVICE_SPEED
{
UsbLowSpeed = 1,
UsbFullSpeed = 2,
UsbHighSpeed = 3,
}
[StructLayout(LayoutKind.Sequential)]
protected struct USB_CONFIGURATION_DESCRIPTOR
{
internal Byte bLength;
internal Byte bDescriptorType;
internal UInt16 wTotalLength;
internal Byte bNumInterfaces;
internal Byte bConfigurationValue;
internal Byte iConfiguration;
internal Byte bmAttributes;
internal Byte MaxPower;
}
[StructLayout(LayoutKind.Sequential)]
protected struct USB_INTERFACE_DESCRIPTOR
{
internal Byte bLength;
internal Byte bDescriptorType;
internal Byte bInterfaceNumber;
internal Byte bAlternateSetting;
internal Byte bNumEndpoints;
internal Byte bInterfaceClass;
internal Byte bInterfaceSubClass;
internal Byte bInterfaceProtocol;
internal Byte iInterface;
}
[StructLayout(LayoutKind.Sequential)]
protected struct WINUSB_PIPE_INFORMATION
{
internal USBD_PIPE_TYPE PipeType;
internal Byte PipeId;
internal UInt16 MaximumPacketSize;
internal Byte Interval;
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
protected struct WINUSB_SETUP_PACKET
{
internal Byte RequestType;
internal Byte Request;
internal UInt16 Value;
internal UInt16 Index;
internal UInt16 Length;
}
protected const Int32 DIF_PROPERTYCHANGE = 0x12;
protected const Int32 DICS_ENABLE = 1;
protected const Int32 DICS_DISABLE = 2;
protected const Int32 DICS_PROPCHANGE = 3;
protected const Int32 DICS_FLAG_GLOBAL = 1;
[StructLayout(LayoutKind.Sequential)]
protected struct SP_CLASSINSTALL_HEADER
{
internal Int32 cbSize;
internal Int32 InstallFunction;
}
[StructLayout(LayoutKind.Sequential)]
protected struct SP_PROPCHANGE_PARAMS
{
internal SP_CLASSINSTALL_HEADER ClassInstallHeader;
internal Int32 StateChange;
internal Int32 Scope;
internal Int32 HwProfile;
}
#endregion
#region Protected Data Members
protected Guid m_Class = Guid.Empty;
protected String m_Path = String.Empty;
protected SafeFileHandle m_FileHandle = null;
protected IntPtr m_WinUsbHandle = IntPtr.Zero;
protected Byte m_IntIn = 0xFF;
protected Byte m_IntOut = 0xFF;
protected Byte m_BulkIn = 0xFF;
protected Byte m_BulkOut = 0xFF;
protected Boolean m_IsActive = false;
#endregion
#region Static Helper Methods
public enum Notified { Ignore = 0x0000, Arrival = 0x8000, QueryRemove = 0x8001, Removal = 0x8004 };
public static Boolean RegisterNotify(IntPtr Form, Guid Class, ref IntPtr Handle, Boolean Window = true)
{
IntPtr devBroadcastDeviceInterfaceBuffer = IntPtr.Zero;
try
{
DEV_BROADCAST_DEVICEINTERFACE devBroadcastDeviceInterface = new DEV_BROADCAST_DEVICEINTERFACE();
Int32 Size = Marshal.SizeOf(devBroadcastDeviceInterface);
devBroadcastDeviceInterface.dbcc_size = Size;
devBroadcastDeviceInterface.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
devBroadcastDeviceInterface.dbcc_reserved = 0;
devBroadcastDeviceInterface.dbcc_classguid = Class;
devBroadcastDeviceInterfaceBuffer = Marshal.AllocHGlobal(Size);
Marshal.StructureToPtr(devBroadcastDeviceInterface, devBroadcastDeviceInterfaceBuffer, true);
Handle = RegisterDeviceNotification(Form, devBroadcastDeviceInterfaceBuffer, Window ? DEVICE_NOTIFY_WINDOW_HANDLE : DEVICE_NOTIFY_SERVICE_HANDLE);
Marshal.PtrToStructure(devBroadcastDeviceInterfaceBuffer, devBroadcastDeviceInterface);
return Handle != IntPtr.Zero;
}
catch (Exception ex)
{
Console.WriteLine("{0} {1}", ex.HelpLink, ex.Message);
throw;
}
finally
{
if (devBroadcastDeviceInterfaceBuffer != IntPtr.Zero)
{
Marshal.FreeHGlobal(devBroadcastDeviceInterfaceBuffer);
}
}
}
public static Boolean UnregisterNotify(IntPtr Handle)
{
try
{
return UnregisterDeviceNotification(Handle);
}
catch (Exception ex)
{
Console.WriteLine("{0} {1}", ex.HelpLink, ex.Message);
throw;
}
}
#endregion
#region Protected Methods
protected virtual Boolean Find(Guid Target, ref String Path, Int32 Instance = 0)
{
IntPtr detailDataBuffer = IntPtr.Zero;
IntPtr deviceInfoSet = IntPtr.Zero;
try
{
SP_DEVICE_INTERFACE_DATA DeviceInterfaceData = new SP_DEVICE_INTERFACE_DATA(), da = new SP_DEVICE_INTERFACE_DATA();
Int32 bufferSize = 0, memberIndex = 0;
deviceInfoSet = SetupDiGetClassDevs(ref Target, IntPtr.Zero, IntPtr.Zero, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
DeviceInterfaceData.cbSize = da.cbSize = Marshal.SizeOf(DeviceInterfaceData);
while (SetupDiEnumDeviceInterfaces(deviceInfoSet, IntPtr.Zero, ref Target, memberIndex, ref DeviceInterfaceData))
{
SetupDiGetDeviceInterfaceDetail(deviceInfoSet, ref DeviceInterfaceData, IntPtr.Zero, 0, ref bufferSize, ref da);
{
detailDataBuffer = Marshal.AllocHGlobal(bufferSize);
Marshal.WriteInt32(detailDataBuffer, (IntPtr.Size == 4) ? (4 + Marshal.SystemDefaultCharSize) : 8);
if (SetupDiGetDeviceInterfaceDetail(deviceInfoSet, ref DeviceInterfaceData, detailDataBuffer, bufferSize, ref bufferSize, ref da))
{
IntPtr pDevicePathName = new IntPtr(IntPtr.Size == 4 ? detailDataBuffer.ToInt32() + 4: detailDataBuffer.ToInt64() + 4);
Path = Marshal.PtrToStringAuto(pDevicePathName).ToUpper();
Marshal.FreeHGlobal(detailDataBuffer);
if (memberIndex == Instance) return true;
}
else Marshal.FreeHGlobal(detailDataBuffer);
}
memberIndex++;
}
}
catch (Exception ex)
{
Console.WriteLine("{0} {1}", ex.HelpLink, ex.Message);
throw;
}
finally
{
if (deviceInfoSet != IntPtr.Zero)
{
SetupDiDestroyDeviceInfoList(deviceInfoSet);
}
}
return false;
}
protected virtual Boolean GetDeviceInstance(ref String Instance)
{
IntPtr detailDataBuffer = IntPtr.Zero;
IntPtr deviceInfoSet = IntPtr.Zero;
try
{
SP_DEVICE_INTERFACE_DATA DeviceInterfaceData = new SP_DEVICE_INTERFACE_DATA(), da = new SP_DEVICE_INTERFACE_DATA();
Int32 bufferSize = 0, memberIndex = 0;
deviceInfoSet = SetupDiGetClassDevs(ref m_Class, IntPtr.Zero, IntPtr.Zero, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
DeviceInterfaceData.cbSize = da.cbSize = Marshal.SizeOf(DeviceInterfaceData);
while (SetupDiEnumDeviceInterfaces(deviceInfoSet, IntPtr.Zero, ref m_Class, memberIndex, ref DeviceInterfaceData))
{
SetupDiGetDeviceInterfaceDetail(deviceInfoSet, ref DeviceInterfaceData, IntPtr.Zero, 0, ref bufferSize, ref da);
{
detailDataBuffer = Marshal.AllocHGlobal(bufferSize);
Marshal.WriteInt32(detailDataBuffer, (IntPtr.Size == 4) ? (4 + Marshal.SystemDefaultCharSize) : 8);
if (SetupDiGetDeviceInterfaceDetail(deviceInfoSet, ref DeviceInterfaceData, detailDataBuffer, bufferSize, ref bufferSize, ref da))
{
IntPtr pDevicePathName = new IntPtr(IntPtr.Size == 4 ? detailDataBuffer.ToInt32() + 4 : detailDataBuffer.ToInt64() + 4);
String Current = Marshal.PtrToStringAuto(pDevicePathName).ToUpper();
Marshal.FreeHGlobal(detailDataBuffer);
if (Current == Path)
{
Int32 nBytes = 256;
IntPtr ptrInstanceBuf = Marshal.AllocHGlobal(nBytes);
CM_Get_Device_ID(da.Flags, ptrInstanceBuf, nBytes, 0);
Instance = Marshal.PtrToStringAuto(ptrInstanceBuf).ToUpper();
Marshal.FreeHGlobal(ptrInstanceBuf);
return true;
}
}
else Marshal.FreeHGlobal(detailDataBuffer);
}
memberIndex++;
}
}
catch (Exception ex)
{
Console.WriteLine("{0} {1}", ex.HelpLink, ex.Message);
throw;
}
finally
{
if (deviceInfoSet != IntPtr.Zero)
{
SetupDiDestroyDeviceInfoList(deviceInfoSet);
}
}
return false;
}
protected virtual Boolean GetDeviceHandle(String Path)
{
m_FileHandle = CreateFile(Path, (GENERIC_WRITE | GENERIC_READ), FILE_SHARE_READ | FILE_SHARE_WRITE, IntPtr.Zero, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED | 0x20000000 | 0x80000000, 0);
return !m_FileHandle.IsInvalid;
}
protected virtual Boolean UsbEndpointDirectionIn(Int32 addr)
{
return (addr & 0x80) == 0x80;
}
protected virtual Boolean UsbEndpointDirectionOut(Int32 addr)
{
return (addr & 0x80) == 0x00;
}
protected virtual Boolean InitializeDevice()
{
try
{
USB_INTERFACE_DESCRIPTOR ifaceDescriptor = new USB_INTERFACE_DESCRIPTOR();
WINUSB_PIPE_INFORMATION pipeInfo = new WINUSB_PIPE_INFORMATION();
if (WinUsb_QueryInterfaceSettings(m_WinUsbHandle, 0, ref ifaceDescriptor))
{
for (Int32 i = 0; i < ifaceDescriptor.bNumEndpoints; i++)
{
WinUsb_QueryPipe(m_WinUsbHandle, 0, System.Convert.ToByte(i), ref pipeInfo);
if (((pipeInfo.PipeType == USBD_PIPE_TYPE.UsbdPipeTypeBulk) & UsbEndpointDirectionIn(pipeInfo.PipeId)))
{
m_BulkIn = pipeInfo.PipeId;
WinUsb_FlushPipe(m_WinUsbHandle, m_BulkIn);
}
else if (((pipeInfo.PipeType == USBD_PIPE_TYPE.UsbdPipeTypeBulk) & UsbEndpointDirectionOut(pipeInfo.PipeId)))
{
m_BulkOut = pipeInfo.PipeId;
WinUsb_FlushPipe(m_WinUsbHandle, m_BulkOut);
}
else if ((pipeInfo.PipeType == USBD_PIPE_TYPE.UsbdPipeTypeInterrupt) & UsbEndpointDirectionIn(pipeInfo.PipeId))
{
m_IntIn = pipeInfo.PipeId;
WinUsb_FlushPipe(m_WinUsbHandle, m_IntIn);
}
else if ((pipeInfo.PipeType == USBD_PIPE_TYPE.UsbdPipeTypeInterrupt) & UsbEndpointDirectionOut(pipeInfo.PipeId))
{
m_IntOut = pipeInfo.PipeId;
WinUsb_FlushPipe(m_WinUsbHandle, m_IntOut);
}
}
return true;
}
return false;
}
catch (Exception ex)
{
Console.WriteLine("{0} {1}", ex.HelpLink, ex.Message);
throw;
}
}
protected virtual Boolean RestartDevice(String InstanceId)
{
IntPtr deviceInfoSet = IntPtr.Zero;
try
{
SP_DEVICE_INTERFACE_DATA deviceInterfaceData = new SP_DEVICE_INTERFACE_DATA();
deviceInterfaceData.cbSize = Marshal.SizeOf(deviceInterfaceData);
deviceInfoSet = SetupDiGetClassDevs(ref m_Class, IntPtr.Zero, IntPtr.Zero, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
if (SetupDiOpenDeviceInfo(deviceInfoSet, InstanceId, IntPtr.Zero, 0, ref deviceInterfaceData))
{
SP_PROPCHANGE_PARAMS props = new SP_PROPCHANGE_PARAMS();
props.ClassInstallHeader = new SP_CLASSINSTALL_HEADER();
props.ClassInstallHeader.cbSize = Marshal.SizeOf(props.ClassInstallHeader);
props.ClassInstallHeader.InstallFunction = DIF_PROPERTYCHANGE;
props.Scope = DICS_FLAG_GLOBAL;
props.StateChange = DICS_PROPCHANGE;
props.HwProfile = 0x00;
if (SetupDiSetClassInstallParams(deviceInfoSet, ref deviceInterfaceData, ref props, Marshal.SizeOf(props)))
{
return SetupDiChangeState(deviceInfoSet, ref deviceInterfaceData);
}
}
}
catch (Exception ex)
{
Console.WriteLine("{0} {1}", ex.HelpLink, ex.Message);
throw;
}
finally
{
if (deviceInfoSet != IntPtr.Zero)
{
SetupDiDestroyDeviceInfoList(deviceInfoSet);
}
}
return false;
}
#endregion
#region Interop Definitions
[DllImport("setupapi.dll", SetLastError = true)]
protected static extern Int32 SetupDiCreateDeviceInfoList(ref System.Guid ClassGuid, Int32 hwndParent);
[DllImport("setupapi.dll", SetLastError = true)]
protected static extern Int32 SetupDiDestroyDeviceInfoList(IntPtr DeviceInfoSet);
[DllImport("setupapi.dll", SetLastError = true)]
protected static extern Boolean SetupDiEnumDeviceInterfaces(IntPtr DeviceInfoSet, IntPtr DeviceInfoData, ref System.Guid InterfaceClassGuid, Int32 MemberIndex, ref SP_DEVICE_INTERFACE_DATA DeviceInterfaceData);
[DllImport("setupapi.dll", SetLastError = true, CharSet = CharSet.Auto)]
protected static extern IntPtr SetupDiGetClassDevs(ref System.Guid ClassGuid, IntPtr Enumerator, IntPtr hwndParent, Int32 Flags);
[DllImport("setupapi.dll", SetLastError = true, CharSet = CharSet.Auto)]
protected static extern Boolean SetupDiGetDeviceInterfaceDetail(IntPtr DeviceInfoSet, ref SP_DEVICE_INTERFACE_DATA DeviceInterfaceData, IntPtr DeviceInterfaceDetailData, Int32 DeviceInterfaceDetailDataSize, ref Int32 RequiredSize, IntPtr DeviceInfoData);
[DllImport("setupapi.dll", SetLastError = true, CharSet = CharSet.Auto)]
protected static extern Boolean SetupDiGetDeviceInterfaceDetail(IntPtr DeviceInfoSet, ref SP_DEVICE_INTERFACE_DATA DeviceInterfaceData, IntPtr DeviceInterfaceDetailData, Int32 DeviceInterfaceDetailDataSize, ref Int32 RequiredSize, ref SP_DEVICE_INTERFACE_DATA DeviceInfoData);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
protected static extern IntPtr RegisterDeviceNotification(IntPtr hRecipient, IntPtr NotificationFilter, Int32 Flags);
[DllImport("user32.dll", SetLastError = true)]
protected static extern Boolean UnregisterDeviceNotification(IntPtr Handle);
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
protected static extern SafeFileHandle CreateFile(String lpFileName, UInt32 dwDesiredAccess, UInt32 dwShareMode, IntPtr lpSecurityAttributes, UInt32 dwCreationDisposition, UInt32 dwFlagsAndAttributes, UInt32 hTemplateFile);
[DllImport("winusb.dll", SetLastError = true)]
protected static extern Boolean WinUsb_Initialize(SafeFileHandle DeviceHandle, ref IntPtr InterfaceHandle);
[DllImport("winusb.dll", SetLastError = true)]
protected static extern Boolean WinUsb_QueryInterfaceSettings(IntPtr InterfaceHandle, Byte AlternateInterfaceNumber, ref USB_INTERFACE_DESCRIPTOR UsbAltInterfaceDescriptor);
[DllImport("winusb.dll", SetLastError = true)]
protected static extern Boolean WinUsb_QueryPipe(IntPtr InterfaceHandle, Byte AlternateInterfaceNumber, Byte PipeIndex, ref WINUSB_PIPE_INFORMATION PipeInformation);
[DllImport("winusb.dll", SetLastError = true)]
protected static extern Boolean WinUsb_AbortPipe(IntPtr InterfaceHandle, Byte PipeID);
[DllImport("winusb.dll", SetLastError = true)]
protected static extern Boolean WinUsb_FlushPipe(IntPtr InterfaceHandle, Byte PipeID);
[DllImport("winusb.dll", SetLastError = true)]
protected static extern Boolean WinUsb_ControlTransfer(IntPtr InterfaceHandle, WINUSB_SETUP_PACKET SetupPacket, Byte[] Buffer, Int32 BufferLength, ref Int32 LengthTransferred, IntPtr Overlapped);
[DllImport("winusb.dll", SetLastError = true)]
protected static extern Boolean WinUsb_ReadPipe(IntPtr InterfaceHandle, Byte PipeID, Byte[] Buffer, Int32 BufferLength, ref Int32 LengthTransferred, IntPtr Overlapped);
[DllImport("winusb.dll", SetLastError = true)]
protected static extern Boolean WinUsb_WritePipe(IntPtr InterfaceHandle, Byte PipeID, Byte[] Buffer, Int32 BufferLength, ref Int32 LengthTransferred, IntPtr Overlapped);
[DllImport("winusb.dll", SetLastError = true)]
protected static extern Boolean WinUsb_Free(IntPtr InterfaceHandle);
[DllImport("advapi32.dll", SetLastError = true)]
public static extern IntPtr RegisterServiceCtrlHandlerEx(String ServiceName, ServiceControlHandlerEx Callback, IntPtr Context);
[DllImport("kernel32.dll", SetLastError = true)]
protected static extern Boolean DeviceIoControl(SafeFileHandle DeviceHandle, Int32 IoControlCode, Byte[] InBuffer, Int32 InBufferSize, Byte[] OutBuffer, Int32 OutBufferSize, ref Int32 BytesReturned, IntPtr Overlapped);
[DllImport("setupapi.dll", SetLastError = true, CharSet = CharSet.Auto)]
protected static extern Int32 CM_Get_Device_ID(Int32 dnDevInst, IntPtr Buffer, Int32 BufferLen, Int32 ulFlags);
[DllImport("setupapi.dll", SetLastError = true, CharSet = CharSet.Auto)]
protected static extern Boolean SetupDiOpenDeviceInfo(IntPtr DeviceInfoSet, String DeviceInstanceId, IntPtr hwndParent, Int32 Flags, ref SP_DEVICE_INTERFACE_DATA DeviceInfoData);
[DllImport("setupapi.dll", SetLastError = true, CharSet = CharSet.Auto)]
protected static extern Boolean SetupDiChangeState(IntPtr DeviceInfoSet, ref SP_DEVICE_INTERFACE_DATA DeviceInterfaceData);
[DllImport("setupapi.dll", SetLastError = true, CharSet = CharSet.Auto)]
protected static extern Boolean SetupDiSetClassInstallParams(IntPtr DeviceInfoSet, ref SP_DEVICE_INTERFACE_DATA DeviceInterfaceData, ref SP_PROPCHANGE_PARAMS ClassInstallParams, Int32 ClassInstallParamsSize);
#endregion
}
}