242 lines
9.5 KiB
C#
242 lines
9.5 KiB
C#
using System;
|
|
using System.Runtime.InteropServices;
|
|
|
|
namespace MiController.DriverUtils
|
|
{
|
|
public class Devcon
|
|
{
|
|
public static bool Find(Guid target, ref string path, ref string instanceId, int instance = 0)
|
|
{
|
|
var deviceInfoSet = IntPtr.Zero;
|
|
|
|
try
|
|
{
|
|
SP_DEVINFO_DATA deviceInterfaceData = new SP_DEVINFO_DATA(), da = new SP_DEVINFO_DATA();
|
|
int 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);
|
|
{
|
|
var 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))
|
|
{
|
|
var pDevicePathName = detailDataBuffer + 4;
|
|
|
|
path = Marshal.PtrToStringAuto(pDevicePathName).ToUpper();
|
|
|
|
if (memberIndex == instance)
|
|
{
|
|
var nBytes = 256;
|
|
var ptrInstanceBuf = Marshal.AllocHGlobal(nBytes);
|
|
|
|
CM_Get_Device_ID(da.Flags, ptrInstanceBuf, nBytes, 0);
|
|
instanceId = Marshal.PtrToStringAuto(ptrInstanceBuf).ToUpper();
|
|
|
|
Marshal.FreeHGlobal(ptrInstanceBuf);
|
|
return true;
|
|
}
|
|
}
|
|
else Marshal.FreeHGlobal(detailDataBuffer);
|
|
}
|
|
|
|
memberIndex++;
|
|
}
|
|
}
|
|
finally
|
|
{
|
|
if (deviceInfoSet != IntPtr.Zero)
|
|
{
|
|
SetupDiDestroyDeviceInfoList(deviceInfoSet);
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
public static bool Create(string className, Guid classGuid, string node)
|
|
{
|
|
var deviceInfoSet = (IntPtr)(-1);
|
|
var deviceInfoData = new SP_DEVINFO_DATA();
|
|
|
|
try
|
|
{
|
|
deviceInfoSet = SetupDiCreateDeviceInfoList(ref classGuid, IntPtr.Zero);
|
|
|
|
if (deviceInfoSet == (IntPtr)(-1))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
deviceInfoData.cbSize = Marshal.SizeOf(deviceInfoData);
|
|
|
|
if (
|
|
!SetupDiCreateDeviceInfo(deviceInfoSet, className, ref classGuid, null, IntPtr.Zero,
|
|
DICD_GENERATE_ID, ref deviceInfoData))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if (
|
|
!SetupDiSetDeviceRegistryProperty(deviceInfoSet, ref deviceInfoData, SPDRP_HARDWAREID, node,
|
|
node.Length * 2))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if (!SetupDiCallClassInstaller(DIF_REGISTERDEVICE, deviceInfoSet, ref deviceInfoData))
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
finally
|
|
{
|
|
if (deviceInfoSet != (IntPtr)(-1))
|
|
{
|
|
SetupDiDestroyDeviceInfoList(deviceInfoSet);
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
public static bool Remove(Guid classGuid, string path, string instanceId)
|
|
{
|
|
var deviceInfoSet = IntPtr.Zero;
|
|
|
|
try
|
|
{
|
|
var deviceInterfaceData = new SP_DEVINFO_DATA();
|
|
|
|
deviceInterfaceData.cbSize = Marshal.SizeOf(deviceInterfaceData);
|
|
deviceInfoSet = SetupDiGetClassDevs(ref classGuid, IntPtr.Zero, IntPtr.Zero,
|
|
DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
|
|
|
|
if (SetupDiOpenDeviceInfo(deviceInfoSet, instanceId, IntPtr.Zero, 0, ref deviceInterfaceData))
|
|
{
|
|
var props = new SP_REMOVEDEVICE_PARAMS {ClassInstallHeader = new SP_CLASSINSTALL_HEADER()};
|
|
|
|
props.ClassInstallHeader.cbSize = Marshal.SizeOf(props.ClassInstallHeader);
|
|
props.ClassInstallHeader.InstallFunction = DIF_REMOVE;
|
|
|
|
props.Scope = DI_REMOVEDEVICE_GLOBAL;
|
|
props.HwProfile = 0x00;
|
|
|
|
if (SetupDiSetClassInstallParams(deviceInfoSet, ref deviceInterfaceData, ref props,
|
|
Marshal.SizeOf(props)))
|
|
{
|
|
return SetupDiCallClassInstaller(DIF_REMOVE, deviceInfoSet, ref deviceInterfaceData);
|
|
}
|
|
}
|
|
}
|
|
finally
|
|
{
|
|
if (deviceInfoSet != IntPtr.Zero)
|
|
{
|
|
SetupDiDestroyDeviceInfoList(deviceInfoSet);
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
#region Constant and Structure Definitions
|
|
|
|
protected const int DIGCF_PRESENT = 0x0002;
|
|
protected const int DIGCF_DEVICEINTERFACE = 0x0010;
|
|
|
|
protected const int DICD_GENERATE_ID = 0x0001;
|
|
protected const int SPDRP_HARDWAREID = 0x0001;
|
|
|
|
protected const int DIF_REMOVE = 0x0005;
|
|
protected const int DIF_REGISTERDEVICE = 0x0019;
|
|
|
|
protected const int DI_REMOVEDEVICE_GLOBAL = 0x0001;
|
|
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
protected struct SP_DEVINFO_DATA
|
|
{
|
|
internal int cbSize;
|
|
internal Guid ClassGuid;
|
|
internal int Flags;
|
|
internal IntPtr Reserved;
|
|
}
|
|
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
protected struct SP_CLASSINSTALL_HEADER
|
|
{
|
|
internal int cbSize;
|
|
internal int InstallFunction;
|
|
}
|
|
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
protected struct SP_REMOVEDEVICE_PARAMS
|
|
{
|
|
internal SP_CLASSINSTALL_HEADER ClassInstallHeader;
|
|
internal int Scope;
|
|
internal int HwProfile;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Interop Definitions
|
|
|
|
[DllImport("setupapi.dll", SetLastError = true, CharSet = CharSet.Auto)]
|
|
protected static extern IntPtr SetupDiCreateDeviceInfoList(ref Guid ClassGuid, IntPtr hwndParent);
|
|
|
|
[DllImport("setupapi.dll", SetLastError = true, CharSet = CharSet.Auto)]
|
|
protected static extern bool SetupDiDestroyDeviceInfoList(IntPtr DeviceInfoSet);
|
|
|
|
[DllImport("setupapi.dll", SetLastError = true, CharSet = CharSet.Auto)]
|
|
protected static extern bool SetupDiCreateDeviceInfo(IntPtr DeviceInfoSet, string DeviceName, ref Guid ClassGuid,
|
|
string DeviceDescription, IntPtr hwndParent, int CreationFlags, ref SP_DEVINFO_DATA DeviceInfoData);
|
|
|
|
[DllImport("setupapi.dll", SetLastError = true, CharSet = CharSet.Auto)]
|
|
protected static extern bool SetupDiSetDeviceRegistryProperty(IntPtr DeviceInfoSet,
|
|
ref SP_DEVINFO_DATA DeviceInfoData, int Property, [MarshalAs(UnmanagedType.LPWStr)] string PropertyBuffer,
|
|
int PropertyBufferSize);
|
|
|
|
[DllImport("setupapi.dll", SetLastError = true, CharSet = CharSet.Auto)]
|
|
protected static extern bool SetupDiCallClassInstaller(int InstallFunction, IntPtr DeviceInfoSet,
|
|
ref SP_DEVINFO_DATA DeviceInfoData);
|
|
|
|
[DllImport("setupapi.dll", SetLastError = true, CharSet = CharSet.Auto)]
|
|
protected static extern IntPtr SetupDiGetClassDevs(ref Guid ClassGuid, IntPtr Enumerator, IntPtr hwndParent,
|
|
int Flags);
|
|
|
|
[DllImport("setupapi.dll", SetLastError = true, CharSet = CharSet.Auto)]
|
|
protected static extern bool SetupDiEnumDeviceInterfaces(IntPtr DeviceInfoSet, IntPtr DeviceInfoData,
|
|
ref Guid InterfaceClassGuid, int MemberIndex, ref SP_DEVINFO_DATA DeviceInterfaceData);
|
|
|
|
[DllImport("setupapi.dll", SetLastError = true, CharSet = CharSet.Auto)]
|
|
protected static extern bool SetupDiGetDeviceInterfaceDetail(IntPtr DeviceInfoSet,
|
|
ref SP_DEVINFO_DATA DeviceInterfaceData, IntPtr DeviceInterfaceDetailData, int DeviceInterfaceDetailDataSize,
|
|
ref int RequiredSize, ref SP_DEVINFO_DATA DeviceInfoData);
|
|
|
|
[DllImport("setupapi.dll", SetLastError = true, CharSet = CharSet.Auto)]
|
|
protected static extern int CM_Get_Device_ID(int DevInst, IntPtr Buffer, int BufferLen, int Flags);
|
|
|
|
[DllImport("setupapi.dll", SetLastError = true, CharSet = CharSet.Auto)]
|
|
protected static extern bool SetupDiOpenDeviceInfo(IntPtr DeviceInfoSet, string DeviceInstanceId,
|
|
IntPtr hwndParent, int Flags, ref SP_DEVINFO_DATA DeviceInfoData);
|
|
|
|
[DllImport("setupapi.dll", SetLastError = true, CharSet = CharSet.Auto)]
|
|
protected static extern bool SetupDiSetClassInstallParams(IntPtr DeviceInfoSet,
|
|
ref SP_DEVINFO_DATA DeviceInterfaceData, ref SP_REMOVEDEVICE_PARAMS ClassInstallParams,
|
|
int ClassInstallParamsSize);
|
|
|
|
#endregion
|
|
}
|
|
} |