1

当我将 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。我错过了什么吗?有没有其他方法可以为无法识别的设备选择通用驱动程序?

4

0 回答 0