当我将 USB RNDIS 设备(Linux 小工具)插入 Windows PC 时,被视为“RNDIS”设备,没有驱动程序。为了让它工作,我去设备管理器,手动选择微软通用远程 RNDIS 驱动程序。
我的最终目标是从代码 (C#) 强制安装该通用 Microsoft 驱动程序,以避免用户手动执行此操作。我尝试了 devcon、pnputil 和其他方式,但没有任何效果。最后,我为DiInstallDevice Windows SetupAPI 实现了一个 pinvoke。
[DllImport("setupapi.dll", CharSet = CharSet.Auto, SetLastError = true)]
static extern IntPtr SetupDiGetClassDevs(ref Guid ClassGuid, [MarshalAs(UnmanagedType.LPTStr)] string Enumerator, IntPtr hwndParent, uint Flags);
[DllImport("setupapi.dll", SetLastError = true)]
static extern bool SetupDiEnumDeviceInfo(IntPtr DeviceInfoSet, uint MemberIndex, ref SP_DEVINFO_DATA DeviceInfoData);
[DllImport("setupapi.dll", SetLastError = true)]
static extern bool SetupDiEnumDriverInfo(IntPtr DeviceInfoSet, ref SP_DEVINFO_DATA DeviceInfoData, int driverType, int MemberIndex, ref SP_DRVINFO_DATA drvinfo);
[DllImport("newdev.dll", SetLastError = true)]
public static extern bool DiInstallDevice(
IntPtr hwndParent,
IntPtr deviceInfoSet,
ref SP_DEVINFO_DATA DeviceInfoData,
ref SP_DRVINFO_DATA DriverInfoData,
DiFlags Flags,
ref bool NeedReboot);
[DllImport("setupapi.dll", SetLastError = true)]
static extern bool SetupDiBuildDriverInfoList(
IntPtr deviceInfoSet,
ref SP_DEVINFO_DATA deviceInfoData,
int DriverType);
...
public static void ForceRNDISDriver(IntPtr hwndParent)
{
var nullguid = Guid.Empty;
IntPtr deviceInfoSet = SetupDiGetClassDevs(ref nullguid, null, IntPtr.Zero, (uint)(DiGetClassFlags.DIGCF_ALLCLASSES)); //all devices
if (deviceInfoSet.ToInt64() != -1 && deviceInfoSet.ToInt64() != 0)
{
uint BUFFER_SIZE = 32000;
byte[] ptrBuf = new byte[BUFFER_SIZE];
SP_DEVINFO_DATA deviceInfoData = new SP_DEVINFO_DATA();
deviceInfoData.cbSize = (uint)Marshal.SizeOf(deviceInfoData);
SP_DRVINFO_DATA driverInfoData = new SP_DRVINFO_DATA();
driverInfoData.cbSize = Marshal.SizeOf(driverInfoData);
bool Success = true;
uint i = 0;
while (Success)
{
// start the enumeration searching for hardware ID
Success = SetupDiEnumDeviceInfo(deviceInfoSet, i, ref deviceInfoData);
if (Success)
{
if (SetupDiGetDeviceRegistryProperty(deviceInfoSet, ref deviceInfoData, (uint)SetupDiGetDeviceRegistryPropertyEnum.SPDRP_HARDWAREID, out uint RegType, ptrBuf, BUFFER_SIZE, out uint RequiredSize))
{
string hwid = Encoding.Unicode.GetString(ptrBuf, 0, (int)RequiredSize - 2);
if (hwid.ToUpper().Contains("HARDWAREIDEXAMPLE"))
{
int SPDIT_NODRIVER = 0x00000000;
int SPDIT_CLASSDRIVER = 0x00000001;
int SPDIT_COMPATDRIVER = 0x00000002;
bool built = SetupDiBuildDriverInfoList(deviceInfoSet, ref deviceInfoData, SPDIT_CLASSDRIVER);
if (built)
{
int di = 0;
while (true)
{
bool enumed = SetupDiEnumDriverInfo(deviceInfoSet, ref deviceInfoData, SPDIT_CLASSDRIVER, di++, ref driverInfoData);
if (enumed)
{
if (driverInfoData.Description.ToUpper().Contains("NDIS"))
{
break;
}
}
else
break;
}
}
break;
}
}
}
i++;
}
bool reboot = true;
bool dii = DiInstallDevice(hwndParent,
deviceInfoSet,
ref deviceInfoData,
ref driverInfoData,
DiFlags.DIIDFLAG_INSTALLNULLDRIVER,
ref reboot);
int le = GetLastError();//87: INVALID_PARAMETER
}
}
我可以同时检索 deviceInfoData 和 driverInfoData,其中包含有意义的数据。
对 DiInstallDevice 的最终调用总是失败并出现最后一个错误 87:ERROR_INVALID_PARAMETER。我错过了什么吗?有没有其他方法可以为无法识别的设备选择通用驱动程序?