private static WdiErrorCode InstallDeviceDriver(string deviceId, string deviceGuid, string driverPath, string infName, IntPtr hwnd, bool force, WdiDriverType driverType) { // default return value is no matching device found var result = WdiErrorCode.WDI_ERROR_NO_DEVICE; // pointer to write device list to var pList = IntPtr.Zero; // list all Usb devices, not only driverless ones var listOpts = new wdi_options_create_list { list_all = true, list_hubs = false, trim_whitespaces = true }; // use WinUSB and override device GUID var prepOpts = new wdi_options_prepare_driver { driver_type = driverType, device_guid = deviceGuid, vendor_name = "ScpToolkit compatible device" }; // set parent window handle (may be IntPtr.Zero) var intOpts = new wdi_options_install_driver { hWnd = hwnd }; // receive Usb device list wdi_create_list(ref pList, ref listOpts); // save original pointer to free list var devices = pList; // loop through linked list until last element while (pList != IntPtr.Zero) { // translate device info to managed object var info = (wdi_device_info)Marshal.PtrToStructure(pList, typeof(wdi_device_info)); var deviceInfo = NativeToManagedWdiUsbDevice(info); // does the HID of the current device match the desired HID if (deviceInfo.DeviceId.Equals(deviceId)) { var driverName = driverType.ToDescription(); // skip installation if device is currently using the desired driver if (string.CompareOrdinal(deviceInfo.CurrentDriver, driverName) == 0 && !force) { result = WdiErrorCode.WDI_ERROR_EXISTS; Log.DebugFormat("Device \"{0}\" ({1}) is already using {2}, installation aborted", deviceInfo.Description, deviceId, driverName); break; } Log.InfoFormat("Device {0} found, preparing driver installation...", deviceId); // prepare driver installation (generates the signed driver and installation helpers) if ((result = wdi_prepare_driver(pList, driverPath, infName, ref prepOpts)) == WdiErrorCode.WDI_SUCCESS) { Log.InfoFormat("Driver \"{0}\" successfully created in directory \"{1}\"", infName, driverPath); Log.InfoFormat("Starting driver installation, this might take up to five minutes..."); // install/replace the current devices driver result = wdi_install_driver(pList, driverPath, infName, ref intOpts); var resultLog = string.Format("Installation result: {0}", Enum.GetName(typeof(WdiErrorCode), result)); if (result == WdiErrorCode.WDI_SUCCESS) { Log.Info(resultLog); } else { Log.Warn(resultLog); } } break; } // continue with next device pList = info.next; } // free used memory wdi_destroy_list(devices); return(result); }
private static WdiErrorCode InstallDeviceDriver(string hardwareId, string deviceGuid, string driverPath, string infName, IntPtr hwnd, bool force, WdiDriverType driverType) { // regex to extract vendor ID and product ID from hardware ID string var regex = new Regex("VID_([0-9A-Z]{4})&PID_([0-9A-Z]{4})", RegexOptions.IgnoreCase); // matched groups var matches = regex.Match(hardwareId).Groups; // very basic check if (matches.Count < 3) { throw new ArgumentException("Supplied Hardware-ID is malformed"); } // get values var vid = matches[1].Value.ToUpper(); var pid = matches[2].Value.ToUpper(); // default return value is no matching device found var result = WdiErrorCode.WDI_ERROR_NO_DEVICE; // pointer to write device list to var pList = IntPtr.Zero; // list all USB devices, not only driverless ones var listOpts = new wdi_options_create_list { list_all = true, list_hubs = false, trim_whitespaces = false }; // use WinUSB and overrride device GUID var prepOpts = new wdi_options_prepare_driver { driver_type = driverType, device_guid = deviceGuid, vendor_name = "ScpToolkit compatible device" }; // set parent window handle (may be IntPtr.Zero) var intOpts = new wdi_options_install_driver { hWnd = hwnd }; // receive USB device list wdi_create_list(ref pList, ref listOpts); // save original pointer to free list var devices = pList; // loop through linked list until last element while (pList != IntPtr.Zero) { // translate device info to managed object var info = (wdi_device_info)Marshal.PtrToStructure(pList, typeof(wdi_device_info)); // get current driver name var currentDriver = Marshal.PtrToStringAnsi(info.driver); // extract VID and PID var currentMatches = regex.Match(info.hardware_id).Groups; var currentVid = currentMatches[1].Value.ToUpper(); var currentPid = currentMatches[2].Value.ToUpper(); // does the HID of the current device match the desired HID if (vid == currentVid && pid == currentPid) { var driverName = driverType.ToDescription(); // skip installation if device is currently using the desired driver if (string.CompareOrdinal(currentDriver, driverName) == 0 && !force) { result = WdiErrorCode.WDI_ERROR_EXISTS; Log.WarnFormat("Device \"{0}\" ({1}) is already using {2}, installation aborted", info.desc, hardwareId, driverName); break; } Log.InfoFormat( "Device with specified VID ({0}) and PID ({1}) found, preparing driver installation...", vid, pid); // prepare driver installation (generates the signed driver and installation helpers) if ((result = wdi_prepare_driver(pList, driverPath, infName, ref prepOpts)) == WdiErrorCode.WDI_SUCCESS) { Log.InfoFormat("Driver \"{0}\" successfully created in directory \"{1}\"", infName, driverPath); // install/replace the current devices driver result = wdi_install_driver(pList, driverPath, infName, ref intOpts); var resultLog = string.Format("Installation result: {0}", Enum.GetName(typeof(WdiErrorCode), result)); if (result == WdiErrorCode.WDI_SUCCESS) { Log.Info(resultLog); } else { Log.Warn(resultLog); } } break; } // continue with next device pList = info.next; } // free used memory wdi_destroy_list(devices); return(result); }