using System; using System.Runtime.InteropServices; using static Vanara.PInvoke.SetupAPI; namespace Vanara.PInvoke { /// Items from the NewDev.dll public static partial class NewDev { private const string Lib_NewDev = "newdev.dll"; /// Flags for . [PInvokeData("newdev.h", MSDNShortId = "NF:newdev.DiInstallDevice")] [Flags] public enum DIID_FLAG : uint { /// /// If the caller does not specify a driver (DriverInfoData is set to NULL) and DiInstallDevice does not locate a /// preinstalled driver that matches the specified device. Instead, DiInstallDevice displays the Found New Hardware /// wizard for the device. /// DIIDFLAG_SHOWSEARCHUI = 0x00000001, /// /// DiInstallDevice does not start finish-install wizard pages or finish-install actions. The caller of /// DiInstallDevice must start these operations. The caller should only specify this flag if the caller requires that /// finish-install wizard pages be invoked in the context of a caller-supplied user interface component. /// DIIDFLAG_NOFINISHINSTALLUI = 0x00000002, /// /// DiInstallDevice attempts to install a null driver on the specified device. If this flag is set, /// DiInstallDevice does not use the DriverInfoData parameter. DiInstallDevice removes all device settings and, if /// the device cannot run in raw mode, the function sets the status of the device to CM_PROB_FAILED_INSTALL. If /// DiInstallDevice cannot install a null driver, the resulting state of the device is the same as if the device was /// connected for the first time to the computer and Windows did not locate a driver for the device. /// DIIDFLAG_INSTALLNULLDRIVER = 0x00000004, /// /// Any additional INF file specified via a CopyINF directive will be installed on any device it is applicable to. Any failure /// in installing an additional INF will not cause the primary INF's installation to fail. /// DIIDFLAG_INSTALLCOPYINFDRIVERS = 0x00000008, } /// Flags for [PInvokeData("newdev.h", MSDNShortId = "NF:newdev.DiInstallDriverA")] [Flags] public enum DIIRFLAG : uint { /// Don't copy inf, it has been published DIIRFLAG_INF_ALREADY_COPIED = 0x00000001, // Don't copy inf, it has been published /// /// Installs the specified driver on a matching device whether the driver is a better match for the device than the driver that /// is currently installed on the device. /// DIIRFLAG_FORCE_INF = 0x00000002, /// limit installs on hw using the inf DIIRFLAG_HW_USING_THE_INF = 0x00000004, // limit installs on hw using the inf /// Perform a hotpatch service pack install DIIRFLAG_HOTPATCH = 0x00000008, // Perform a hotpatch service pack install /// install w/o backup and no rollback DIIRFLAG_NOBACKUP = 0x00000010, // install w/o backup and no rollback /// Pre-install inf, if possible DIIRFLAG_PRE_CONFIGURE_INF = 0x00000020, // Pre-install inf, if possible /// DIIRFLAG_INSTALL_AS_SET = 0x00000040, } /// Flags for . [PInvokeData("newdev.h", MSDNShortId = "NF:newdev.DiUninstallDriverW")] [Flags] public enum DIURFLAG : uint { /// /// Removes the driver package from any devices it is installed on, but does not remove the drive package from the Driver Store. /// DIURFLAG_NO_REMOVE_INF = 0x00000001 } /// Flags for . [PInvokeData("newdev.h", MSDNShortId = "NF:newdev.UpdateDriverForPlugAndPlayDevicesA")] [Flags] public enum INSTALLFLAG { /// /// /// If this flag is set and the function finds a device that matches the HardwareId value, the function installs new drivers for /// the device whether better drivers already exist on the computer. /// /// /// Important Use this flag only with extreme caution. Setting this flag can cause an older driver to be installed over a /// newer driver, if a user runs the vendor's application after newer drivers are available. /// /// INSTALLFLAG_FORCE = 0x00000001, /// /// /// If this flag is set, the function will not copy, rename, or delete any installation files. Use of this flag should be /// limited to environments in which file access is restricted or impossible, such as an "embedded" operating system. /// /// INSTALLFLAG_READONLY = 0x00000002, /// /// /// If this flag is set, the function will return FALSE when any attempt to display UI is detected. Set this flag only if /// the function will be called from a component (such as a service) that cannot display UI. /// /// Note If this flag is set and a UI display is attempted, the device can be left in an indeterminate state. /// INSTALLFLAG_NONINTERACTIVE = 0x00000004, } /// Flags for [PInvokeData("newdev.h", MSDNShortId = "NF:newdev.DiRollbackDriver")] [Flags] public enum ROLLBACK_FLAG : uint { /// Suppresses the display of user interface components that are associated with a driver rollback. ROLLBACK_FLAG_NO_UI = 0x00000001 } /// /// The DiInstallDevice function installs a specified driver that is preinstalled in the driver store on a specified device /// that is present in the system. /// /// /// A handle to the top-level window that DiInstallDevice uses to display any user interface component that is associated /// with installing the device. This parameter is optional and can be set to NULL. /// /// /// A handle to a device information set that contains a device information element that represents the specified device. /// /// /// A pointer to an SP_DEVINFO_DATA structure that represents the specified device in the specified device information set. /// /// /// An pointer to an SP_DRVINFO_DATA structure that specifies the driver to install on the specified device. This parameter is /// optional and can be set to NULL. If this parameter is NULL, DiInstallDevice searches the drivers /// preinstalled in the driver store for the driver that is the best match to the specified device, and, if one is found, installs /// the driver on the specified device. /// /// /// A value of type DWORD that specifies zero or the following flag: /// DIIDFLAG_SHOWSEARCHUI /// /// If the caller does not specify a driver (DriverInfoData is set to NULL) and DiInstallDevice does not locate a /// preinstalled driver that matches the specified device. Instead, DiInstallDevice displays the Found New Hardware wizard /// for the device. /// /// DIIDFLAG_NOFINISHINSTALLUI /// /// DiInstallDevice does not start finish-install wizard pages or finish-install actions. The caller of /// DiInstallDevice must start these operations. The caller should only specify this flag if the caller requires that /// finish-install wizard pages be invoked in the context of a caller-supplied user interface component. /// /// DIIDFLAG_INSTALLNULLDRIVER /// /// DiInstallDevice attempts to install a null driver on the specified device. If this flag is set, DiInstallDevice /// does not use the DriverInfoData parameter. DiInstallDevice removes all device settings and, if the device cannot run in /// raw mode, the function sets the status of the device to CM_PROB_FAILED_INSTALL. If DiInstallDevice cannot install /// a null driver, the resulting state of the device is the same as if the device was connected for the first time to the computer /// and Windows did not locate a driver for the device. /// /// DIIDFLAG_INSTALLCOPYINFDRIVERS /// /// Any additional INF file specified via a CopyINF directive will be installed on any device it is applicable to. Any failure in /// installing an additional INF will not cause the primary INF's installation to fail. /// /// /// /// A pointer to a value of type BOOL that DiInstallDevice sets to indicate whether a system restart is required to /// complete the installation. This parameter is optional and can be set to NULL. If this parameter is supplied and a system /// restart is required to complete the installation, DiInstallDevice sets the value to TRUE. In this case, the caller /// is responsible for restarting the system. If this parameter is supplied and a system restart is not required, /// DiInstallDevice sets this parameter to FALSE. If this parameter is NULL and a system restart is required to /// complete the installation, DiInstallDevice displays a system restart dialog box. /// /// /// /// DiInstallDevice returns TRUE if the function successfully installed the specified driver on the specified device. /// Otherwise, DiInstallDevice returns FALSE and the logged error can be retrieved by making a call to /// GetLastError. Some of the more common error values that GetLastError might return are as follows: /// /// /// /// Return code /// Description /// /// /// ERROR_ACCESS_DENIED /// /// The caller does not have Administrator privileges. By default, Windows Vista and Windows Server 2008 require that a calling /// process have Administrator privileges to install a driver on a device. /// /// /// /// ERROR_INVALID_FLAGS /// The value that is specified for Flags is not zero or a bitwise OR of the valid flags. /// /// /// ERROR_IN_WOW64 /// /// The calling application is a 32-bit application that is attempting to execute in a 64-bit environment, which is not allowed. For /// more information, see Installing Devices on 64-Bit Systems. /// /// /// /// /// /// /// Only call DiInstallDevice if it is necessary to install a specific driver on a specific device. Otherwise, use /// UpdateDriverForPlugAndPlayDevices or DiInstallDriver to install a driver for a device. For more information about which of these /// functions to call to install a driver on a device, see SetupAPI Functions that Simplify Driver Installation. /// /// /// Before calling DiInstallDevice, the caller must obtain an SP_DEVINFO_DATA structure to specify the device and, /// optionally, an SP_DRVINFO_DATA structure to specify a driver for the device. /// /// /// To create a device information set that contains the specified device and to obtain an SP_DEVINFO_DATA structure for the device, /// do one of the following: /// /// /// /// /// Call SetupDiGetClassDevs to retrieve a device information set that contains the device and then call SetupDiEnumDeviceInfo to /// enumerate the devices in the device information set. On each call, SetupDiEnumDeviceInfo returns an SP_DEVINFO_DATA /// structure that represents the enumerated device in the device information set. To obtain specific information about the /// enumerated device, call SetupDiGetDeviceProperty and supply the SP_DEVINFO_DATA structure that is returned by SetupDiEnumDeviceInfo. /// /// /// /// /// Call SetupDiOpenDeviceInfo to add a device with a known device instance ID to the device information set. /// SetupDiOpenDeviceInfo returns an SP_DEVINFO_DATA structure that represents the device in the device information set. /// /// /// /// /// To retrieve an SP_DRVINFO_DATA structure for a selected driver, call SetupDiBuildDriverInfoList to build a list of drivers for /// the device and then call SetupDiEnumDriverInfo to enumerate the elements of the driver list for the device. For each enumerated /// driver, SetupDiEnumDriverInfo retrieves an SP_DRVINFO_DATA structure that identifies the driver. /// SetupDiGetDriverInfoDetail can also be called to retrieve additional detail about an enumerated driver. /// /// /// In general, an installation application should set NeedReboot to NULL. This ensures that DiInstallDevice prompts /// the user to restart the system if a restart is required to complete the installation. An application should supply a NeedReboot /// pointer only in the following cases: /// /// /// /// /// The application must call DiInstallDevice several times to complete an installation. In this case, the application should /// record whether a TRUE NeedReboot value is returned by any of the calls to DiInstallDevice and, if so, prompt the /// user to restart the system after the final call to DiInstallDevice returns. /// /// /// /// /// The application must perform required operations, other than calling DiInstallDevice, before a system restart should /// occur. If a system restart is required, the application should finish the required operations and then prompt the user to /// restart the system. /// /// /// /// /// The application is a class installer, in which case, the class installer should set the DI_NEEDREBOOT flag in the /// Flags member of the SP_DEVINSTALL_PARAMS structure for a device. /// /// /// /// // https://docs.microsoft.com/en-us/windows/win32/api/newdev/nf-newdev-diinstalldevice BOOL DiInstallDevice( HWND hwndParent, // HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, PSP_DRVINFO_DATA DriverInfoData, DWORD Flags, PBOOL NeedReboot ); [DllImport(Lib_NewDev, SetLastError = true, ExactSpelling = true)] [PInvokeData("newdev.h", MSDNShortId = "NF:newdev.DiInstallDevice")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool DiInstallDevice([In, Optional] HWND hwndParent, [In] HDEVINFO DeviceInfoSet, in SP_DEVINFO_DATA DeviceInfoData, in SP_DRVINFO_DATA_V2 DriverInfoData, DIID_FLAG Flags, [MarshalAs(UnmanagedType.Bool)] out bool NeedReboot); /// /// The DiInstallDevice function installs a specified driver that is preinstalled in the driver store on a specified device /// that is present in the system. /// /// /// A handle to the top-level window that DiInstallDevice uses to display any user interface component that is associated /// with installing the device. This parameter is optional and can be set to NULL. /// /// /// A handle to a device information set that contains a device information element that represents the specified device. /// /// /// A pointer to an SP_DEVINFO_DATA structure that represents the specified device in the specified device information set. /// /// /// An pointer to an SP_DRVINFO_DATA structure that specifies the driver to install on the specified device. This parameter is /// optional and can be set to NULL. If this parameter is NULL, DiInstallDevice searches the drivers /// preinstalled in the driver store for the driver that is the best match to the specified device, and, if one is found, installs /// the driver on the specified device. /// /// /// A value of type DWORD that specifies zero or the following flag: /// DIIDFLAG_SHOWSEARCHUI /// /// If the caller does not specify a driver (DriverInfoData is set to NULL) and DiInstallDevice does not locate a /// preinstalled driver that matches the specified device. Instead, DiInstallDevice displays the Found New Hardware wizard /// for the device. /// /// DIIDFLAG_NOFINISHINSTALLUI /// /// DiInstallDevice does not start finish-install wizard pages or finish-install actions. The caller of /// DiInstallDevice must start these operations. The caller should only specify this flag if the caller requires that /// finish-install wizard pages be invoked in the context of a caller-supplied user interface component. /// /// DIIDFLAG_INSTALLNULLDRIVER /// /// DiInstallDevice attempts to install a null driver on the specified device. If this flag is set, DiInstallDevice /// does not use the DriverInfoData parameter. DiInstallDevice removes all device settings and, if the device cannot run in /// raw mode, the function sets the status of the device to CM_PROB_FAILED_INSTALL. If DiInstallDevice cannot install /// a null driver, the resulting state of the device is the same as if the device was connected for the first time to the computer /// and Windows did not locate a driver for the device. /// /// DIIDFLAG_INSTALLCOPYINFDRIVERS /// /// Any additional INF file specified via a CopyINF directive will be installed on any device it is applicable to. Any failure in /// installing an additional INF will not cause the primary INF's installation to fail. /// /// /// /// A pointer to a value of type BOOL that DiInstallDevice sets to indicate whether a system restart is required to /// complete the installation. This parameter is optional and can be set to NULL. If this parameter is supplied and a system /// restart is required to complete the installation, DiInstallDevice sets the value to TRUE. In this case, the caller /// is responsible for restarting the system. If this parameter is supplied and a system restart is not required, /// DiInstallDevice sets this parameter to FALSE. If this parameter is NULL and a system restart is required to /// complete the installation, DiInstallDevice displays a system restart dialog box. /// /// /// /// DiInstallDevice returns TRUE if the function successfully installed the specified driver on the specified device. /// Otherwise, DiInstallDevice returns FALSE and the logged error can be retrieved by making a call to /// GetLastError. Some of the more common error values that GetLastError might return are as follows: /// /// /// /// Return code /// Description /// /// /// ERROR_ACCESS_DENIED /// /// The caller does not have Administrator privileges. By default, Windows Vista and Windows Server 2008 require that a calling /// process have Administrator privileges to install a driver on a device. /// /// /// /// ERROR_INVALID_FLAGS /// The value that is specified for Flags is not zero or a bitwise OR of the valid flags. /// /// /// ERROR_IN_WOW64 /// /// The calling application is a 32-bit application that is attempting to execute in a 64-bit environment, which is not allowed. For /// more information, see Installing Devices on 64-Bit Systems. /// /// /// /// /// /// /// Only call DiInstallDevice if it is necessary to install a specific driver on a specific device. Otherwise, use /// UpdateDriverForPlugAndPlayDevices or DiInstallDriver to install a driver for a device. For more information about which of these /// functions to call to install a driver on a device, see SetupAPI Functions that Simplify Driver Installation. /// /// /// Before calling DiInstallDevice, the caller must obtain an SP_DEVINFO_DATA structure to specify the device and, /// optionally, an SP_DRVINFO_DATA structure to specify a driver for the device. /// /// /// To create a device information set that contains the specified device and to obtain an SP_DEVINFO_DATA structure for the device, /// do one of the following: /// /// /// /// /// Call SetupDiGetClassDevs to retrieve a device information set that contains the device and then call SetupDiEnumDeviceInfo to /// enumerate the devices in the device information set. On each call, SetupDiEnumDeviceInfo returns an SP_DEVINFO_DATA /// structure that represents the enumerated device in the device information set. To obtain specific information about the /// enumerated device, call SetupDiGetDeviceProperty and supply the SP_DEVINFO_DATA structure that is returned by SetupDiEnumDeviceInfo. /// /// /// /// /// Call SetupDiOpenDeviceInfo to add a device with a known device instance ID to the device information set. /// SetupDiOpenDeviceInfo returns an SP_DEVINFO_DATA structure that represents the device in the device information set. /// /// /// /// /// To retrieve an SP_DRVINFO_DATA structure for a selected driver, call SetupDiBuildDriverInfoList to build a list of drivers for /// the device and then call SetupDiEnumDriverInfo to enumerate the elements of the driver list for the device. For each enumerated /// driver, SetupDiEnumDriverInfo retrieves an SP_DRVINFO_DATA structure that identifies the driver. /// SetupDiGetDriverInfoDetail can also be called to retrieve additional detail about an enumerated driver. /// /// /// In general, an installation application should set NeedReboot to NULL. This ensures that DiInstallDevice prompts /// the user to restart the system if a restart is required to complete the installation. An application should supply a NeedReboot /// pointer only in the following cases: /// /// /// /// /// The application must call DiInstallDevice several times to complete an installation. In this case, the application should /// record whether a TRUE NeedReboot value is returned by any of the calls to DiInstallDevice and, if so, prompt the /// user to restart the system after the final call to DiInstallDevice returns. /// /// /// /// /// The application must perform required operations, other than calling DiInstallDevice, before a system restart should /// occur. If a system restart is required, the application should finish the required operations and then prompt the user to /// restart the system. /// /// /// /// /// The application is a class installer, in which case, the class installer should set the DI_NEEDREBOOT flag in the /// Flags member of the SP_DEVINSTALL_PARAMS structure for a device. /// /// /// /// // https://docs.microsoft.com/en-us/windows/win32/api/newdev/nf-newdev-diinstalldevice BOOL DiInstallDevice( HWND hwndParent, // HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, PSP_DRVINFO_DATA DriverInfoData, DWORD Flags, PBOOL NeedReboot ); [DllImport(Lib_NewDev, SetLastError = true, ExactSpelling = true)] [PInvokeData("newdev.h", MSDNShortId = "NF:newdev.DiInstallDevice")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool DiInstallDevice([In, Optional] HWND hwndParent, [In] HDEVINFO DeviceInfoSet, in SP_DEVINFO_DATA DeviceInfoData, [In, Optional] IntPtr DriverInfoData, DIID_FLAG Flags, [MarshalAs(UnmanagedType.Bool)] out bool NeedReboot); /// /// The DiInstallDriver function preinstalls a driver in the driver store and then installs the driver on devices present in /// the system that the driver supports. /// /// /// A handle to the top-level window that DiInstallDriver uses to display any user interface component that is associated /// with installing the device. This parameter is optional and can be set to NULL. /// /// /// A pointer to a NULL-terminated string that supplies the fully qualified path of the INF file for the driver package. /// /// /// A value of type DWORD that specifies zero or DIIRFLAG_FORCE_INF. Typically, this flag should be set to zero. /// /// If this flag is zero, DiInstallDriver only installs the specified driver on a device if the driver is a better match for /// a device than the driver that is currently installed on a device. However, if this flag is set to DIIRFLAG_FORCE_INF, /// DiInstallDriver installs the specified driver on a matching device whether the driver is a better match for the device /// than the driver that is currently installed on the device. /// /// /// Caution Forcing the installation of the driver can result in replacing a more compatible or newer driver with a less /// compatible or older driver. /// /// For information about how Windows selects a driver for a device, see /// How Windows Selects Drivers /// . /// /// /// A pointer to a value of type BOOL that DiInstallDriver sets to indicate whether a system is restart is required to /// complete the installation. This parameter is optional and can be NULL. If the parameter is supplied and a system restart /// is required to complete the installation, DiInstallDriver sets the value to TRUE. In this case, the caller must /// prompt the user to restart the system. If this parameter is supplied and a system restart is not required to complete the /// installation, DiInstallDriver sets the value to FALSE. If the parameter is NULL and a system restart is /// required to complete the installation, DiInstallDriver displays a system restart dialog box. For more information about /// this parameter, see the following Remarks section. /// /// /// /// DiInstallDriver returns TRUE if the function successfully preinstalled the specified driver package in the driver /// store. DiInstallDriver also returns TRUE if the function successfully installed the driver on one or more devices /// in the system. If the driver package is not successfully installed in the driver store, DiInstallDriver returns /// FALSE and the logged error can be retrieved by making call to GetLastError. Some of the more common error values /// that GetLastError might return are as follows: /// /// /// /// Return code /// Description /// /// /// ERROR_ACCESS_DENIED /// /// The caller does not have Administrator privileges. By default, Windows requires that the caller have Administrator privileges to /// preinstall a driver package in the driver store. /// /// /// /// ERROR_FILE_NOT_FOUND /// The path of the specified INF file does not exist. /// /// /// ERROR_INVALID_FLAGS /// The value specified for Flags is not equal to zero or DIIRFLAG_FORCE_INF. /// /// /// ERROR_IN_WOW64 /// /// The calling application is a 32-bit application that is attempting to execute in a 64-bit environment, which is not allowed. For /// more information, see Installing Devices on 64-Bit Systems. /// /// /// /// /// /// DiInstallDriver performs the following operations: /// /// /// /// Preinstalls the driver package in the driver store. If there is an instance of the same driver package already preinstalled in /// the driver store, DiInstallDriver first removes that instance and then adds the new instance of the driver package to the /// driver store. /// /// /// /// Enumerates devices that are present in the system. /// /// /// /// If Flags is equal to zero, installs the driver on a device only if the specified driver is a better match for the device than /// the driver that is currently installed on the device. /// /// /// /// /// If Flags is equal to DIIRFLAG_FORCE_INF, installs the driver on a device regardless of whether the driver package is the better /// match to the device than the driver that is currently installed on the device. /// /// /// /// /// In general, an installation application should set NeedReboot to NULL to direct DiInstallDriver to prompt the user /// to restart the system if a restart is required to complete the installation. An application should supply a NeedReboot pointer /// only in the following cases: /// /// /// /// /// The application must call DiInstallDriver several times to complete an installation. In this case, the application should /// record whether a TRUE NeedReboot value is returned by any of the calls to DiInstallDriver and, if so, prompt the /// user to restart the system after the final call to DiInstallDriver returns. /// /// /// /// /// The application must perform required operations, other than calling DiInstallDriver, before a system restart should /// occur. If a system restart is required, the application should finish the required operations and then prompt the user to /// restart the system. /// /// /// /// /// The application is a class installer, in which case, the class installer should set the DI_NEEDREBOOT flag in the Flags /// member of the SP_DEVINSTALL_PARAMS structure for a device. /// /// /// /// /// To install a selected driver on a selected device, call DiInstallDevice. For more info, see SetupAPI Functions that Simplify /// Driver Installation. /// /// // https://docs.microsoft.com/en-us/windows/win32/api/newdev/nf-newdev-diinstalldrivera BOOL DiInstallDriverA( HWND hwndParent, // LPCSTR InfPath, DWORD Flags, PBOOL NeedReboot ); [DllImport(Lib_NewDev, SetLastError = true, CharSet = CharSet.Auto)] [PInvokeData("newdev.h", MSDNShortId = "NF:newdev.DiInstallDriverA")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool DiInstallDriver([In, Optional] HWND hwndParent, string InfPath, DIIRFLAG Flags, [MarshalAs(UnmanagedType.Bool)] out bool NeedReboot); /// The DiRollbackDriver function rolls back the driver that is installed on a specified device. /// /// A handle to the device information set that contains a device information element that represents the device for which driver /// rollback is performed. /// /// /// A pointer to an SP_DEVINFO_DATA structure that represents the specific device in the specified device information set for which /// driver rollback is performed. /// /// /// A handle to the top-level window that DiRollbackDriver uses to display any user interface component that is associated /// with a driver rollback for the specified device. This parameter is optional and can be set to NULL. /// /// /// A value of type DWORD that can be set to zero or ROLLBACK_FLAG_NO_UI. /// /// Typically, this flag should be set to zero, in which case DiRollbackDriver does not suppress the default user interface /// components that are associated with a driver rollback. However, if this flag is set to ROLLBACK_FLAG_NO_UI, /// DiRollbackDriver suppresses the display of user interface components that are associated with a driver rollback. /// /// /// /// /// A pointer to a value of type BOOL that DiRollbackDriver sets to indicate whether a system restart is required to complete /// the rollback. This parameter is optional and can be NULL. /// /// /// If the parameter is supplied and a system restart is required to complete the rollback, DiRollbackDriver sets the value /// to TRUE. In this case, the caller must prompt the user to restart the system. If this parameter is supplied and a system /// restart is not required to complete the installation, DiRollbackDriver sets the value to FALSE. /// /// /// If the parameter is NULL and a system restart is required to complete the rollback, DiRollbackDriver displays a /// system restart dialog box. /// /// For more information about this parameter, see the following Remarks section. /// /// /// /// DiRollbackDriver returns TRUE if the function successfully rolled back the driver for the device; otherwise, /// DiRollbackDriver returns FALSE and the logged error can be retrieved by making a call to GetLastError. Some /// of the more common error values that GetLastError might return are as follows: /// /// /// /// Return code /// Description /// /// /// ERROR_ACCESS_DENIED /// /// The caller does not have Administrator privileges. By default, Windows requires that the caller have Administrator privileges to /// roll back a driver package. /// /// /// /// ERROR_IN_WOW64 /// /// The calling application is a 32-bit application that is attempting to execute in a 64-bit environment, which is not allowed. For /// more information, see Installing Devices on 64-Bit Systems. /// /// /// /// ERROR_INVALID_FLAGS /// The value specified for Flags is not equal to zero or ROLLBACK_FLAG_NO_UI. /// /// /// ERROR_NO_MORE_ITEMS /// A backup driver is not set for the device. /// /// /// /// /// /// If a previously installed backup driver is set for a device, a driver rollback for the device replaces the driver that is /// currently installed on the device with the backup driver. Windows maintains at most one backup driver for a device. Windows sets /// a driver as the backup driver for a device immediately after the driver is successfully installed on the device and Windows /// determines that the device is functioning correctly. However, if a driver does not install successfully on a device or the /// device does not function correctly after the installation, Windows does not set the driver as the backup driver for the device. /// For more information about driver rollback, see information about Device Manager in Help and Support Center. /// /// If the specified device has a backup driver, DiRollbackDriver performs the following operations: /// /// /// /// If Flags is set to zero, DiRollbackDriver prompts the user to confirm whether the backup driver should be installed. /// Otherwise, if Flags is set to ROLLBACK_FLAG_NO_UI, DiRollbackDriver installs the backup driver without prompting the user /// to confirm the installation of the backup driver. /// /// /// /// /// DiRollbackDriver installs the backup driver. The driver is installed whether the backup driver is a better match for the /// device than the driver that is currently installed on the device. /// /// /// /// /// If the driver that is replaced by the backup driver is not an inbox driver and is not installed on any other devices in the /// system, DiRollbackDriver removes the driver from the system. DiRollbackDriver removes the driver from the system /// because it is assumed that a user will replace a driver only if there is a problem with the driver. /// /// /// /// /// If the specified device does not have a backup driver, DiRollbackDriver calls SetLastError to set the error /// ERROR_NO_MORE_ITEMS, does not remove the currently installed driver, and returns FALSE. /// /// /// In general, installation applications should set NeedReboot to NULL so that the system will automatically initiate a /// system restart if a restart is required to complete the rollback. An application should supply a NeedReboot pointer only in the /// following cases: /// /// /// /// /// The application must call DiRollbackDriver several times to complete an installation. In this case, the application /// should record whether a TRUE NeedReboot value is returned by any of the calls to DiRollbackDriver and, if so, /// prompt the user to restart the system after the final call to DiRollbackDriver returns. /// /// /// /// /// The application must perform required operations, other than calling DiRollbackDriver, before a system restart should /// occur. If a system restart is required, the application should finish the required operations and then prompt the user to /// restart the system. /// /// /// /// To install a new driver for a device instead of rolling back the driver for the device, call DiInstallDriver or UpdateDriverForPlugAndPlayDevices. /// // https://docs.microsoft.com/en-us/windows/win32/api/newdev/nf-newdev-dirollbackdriver BOOL DiRollbackDriver( HDEVINFO // DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, HWND hwndParent, DWORD Flags, PBOOL NeedReboot ); [DllImport(Lib_NewDev, SetLastError = true, ExactSpelling = true)] [PInvokeData("newdev.h", MSDNShortId = "NF:newdev.DiRollbackDriver")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool DiRollbackDriver([In] HDEVINFO DeviceInfoSet, in SP_DEVINFO_DATA DeviceInfoData, [In, Optional] HWND hwndParent, ROLLBACK_FLAG Flags, [MarshalAs(UnmanagedType.Bool)] out bool NeedReboot); /// The DiShowUpdateDevice function displays the Hardware Update wizard for a specified device. /// /// A handle to the top-level window that DiShowUpdateDevice uses to display any user interface components that are /// associated with updating the specified device. This parameter is optional and can be set to NULL. /// /// /// A handle to the device information set that contains a device information element that represents the device for which to show /// the Hardware Update wizard. /// /// /// A pointer to an SP_DEVINFO_DATA structure that represents the device for which to show the Hardware Update wizard. /// /// This parameter must be set to zero. /// /// A pointer to a value of type BOOL that DiShowUpdateDevice sets to indicate whether a system restart is required to /// complete the driver update. This parameter is optional and can be NULL. If the parameter is supplied and a system restart /// is required to complete the driver update, DiShowUpdateDevice sets the value to TRUE. In this case, the caller /// must prompt the user to restart the system. If this parameter is supplied and a system restart is not required to complete the /// installation, DiShowUpdateDevice sets the value to FALSE. If the parameter is NULL and a system restart is /// required to complete the driver update, DiShowUpdateDevice displays a system restart dialog box. For more information /// about this parameter, see the following Remarks section. /// /// /// /// DiShowUpdateDevice returns TRUE if the Hardware Update wizard successfully updated the driver for the specified /// device. Otherwise, DiShowUpdateDevice returns FALSE and the logged error can be retrieved by making a call to /// GetLastError. Some of the more common error values that GetLastError might return are as follows: /// /// /// /// Return code /// Description /// /// /// ERROR_ACCESS_DENIED /// /// The caller does not have Administrator privileges. By default, Windows requires that the calling process have Administrator /// privileges to update a driver package. /// /// /// /// ERROR_CANCELLED /// The user canceled the Hardware Update wizard. /// /// /// ERROR_IN_WOW64 /// /// The calling application is a 32-bit application that is attempting to execute in a 64-bit environment, which is not allowed. For /// more information, see Installing Devices on 64-Bit Systems. /// /// /// /// ERROR_INVALID_FLAGS /// The value specified for Flags is not equal to zero. /// /// /// /// /// /// DiShowUpdateDevice displays the Hardware Update wizard for the specified device instance. For information about how to /// update device drivers by using the Hardware Update wizard, see Help and Support Center. /// /// /// In general, installation applications should set NeedReboot to NULL so that the system will automatically initiate a /// system restart if a restart is required to complete a hardware update. An application should supply a NeedReboot pointer only in /// the following cases: /// /// /// /// /// The installation application must call DiShowUpdateDevice several times to complete hardware updates. In this case, the /// application should record whether a TRUE NeedReboot value is returned by any of the calls to DiShowUpdateDevice /// and, if so, prompt the user to restart the system after the final call to DiShowUpdateDevice returns. /// /// /// /// /// The application must perform required operations, other than calling DiShowUpdateDevice, before a system restart should /// occur. If a system restart is required, the application should finish the required operations and then prompt the user to /// restart the system. /// /// /// /// To roll back a driver for a device instead of invoking the Hardware Update wizard, call DiRollbackDriver. /// To install a new driver for a device instead of invoking the Hardware Update wizard, call DiInstallDriver or UpdateDriverForPlugAndPlayDevices. /// // https://docs.microsoft.com/en-us/windows/win32/api/newdev/nf-newdev-dishowupdatedevice BOOL DiShowUpdateDevice( HWND hwndParent, // HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, DWORD Flags, PBOOL NeedReboot ); [DllImport(Lib_NewDev, SetLastError = true, ExactSpelling = true)] [PInvokeData("newdev.h", MSDNShortId = "NF:newdev.DiShowUpdateDevice")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool DiShowUpdateDevice([In, Optional] HWND hwndParent, HDEVINFO DeviceInfoSet, in SP_DEVINFO_DATA DeviceInfoData, uint Flags, [MarshalAs(UnmanagedType.Bool)] out bool NeedReboot); /// The DiShowUpdateDriver function displays the Hardware Update wizard for a specified driver. /// /// A handle to the top-level window that DiShowUpdateDriver uses to display any user interface components that are /// associated with updating the specified device. This parameter is optional and can be set to NULL. /// /// /// A pointer to a NULL-terminated string that supplies the fully qualified path of the INF file for the driver package. /// /// This parameter must be set to zero. /// /// A pointer to a value of type BOOL that DiShowUpdateDriver sets to indicate whether a system restart is required to /// complete the driver update. This parameter is optional and can be NULL. If the parameter is supplied and a system restart /// is required to complete the driver update, DiShowUpdateDevice sets the value to TRUE. In this case, the caller /// must prompt the user to restart the system. If this parameter is supplied and a system restart is not required to complete the /// installation, DiShowUpdateDevice sets the value to FALSE. If the parameter is NULL and a system restart is /// required to complete the driver update, DiShowUpdateDevice displays a system restart dialog box. For more information /// about this parameter, see the following Remarks section. /// /// /// /// DiShowUpdateDriver returns TRUE if the Hardware Update wizard successfully updated the driver for the specified /// device. Otherwise, DiShowUpdateDevice returns FALSE and the logged error can be retrieved by making a call to /// GetLastError. Some of the more common error values that GetLastError might return are as follows: /// /// /// /// Return code /// Description /// /// /// ERROR_ACCESS_DENIED /// /// The caller does not have Administrator privileges. By default, Windows requires that the calling process have Administrator /// privileges to update a driver package. /// /// /// /// ERROR_CANCELLED /// The user canceled the Hardware Update wizard. /// /// /// ERROR_IN_WOW64 /// /// The calling application is a 32-bit application that is attempting to execute in a 64-bit environment, which is not allowed. For /// more information, see Installing Devices on 64-Bit Systems. /// /// /// /// ERROR_INVALID_FLAGS /// The value specified for Flags is not equal to zero. /// /// /// [DllImport(Lib_NewDev, SetLastError = true, ExactSpelling = true)] [PInvokeData("newdev.h", MSDNShortId = "NF:newdev.DiShowUpdateDriver")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool DiShowUpdateDriver([In, Optional] HWND hwndParent, [In, Optional, MarshalAs(UnmanagedType.LPWStr)] string FilePath, uint Flags, [MarshalAs(UnmanagedType.Bool)] out bool NeedReboot); /// /// /// The DiUninstallDevice function uninstalls a device and removes its device node (devnode) from the system. This differs /// from using SetupDiCallClassInstaller with the DIF_REMOVE code because it attempts to uninstall the device node in addition to /// child devnodes that are present at the time of the call. /// /// /// Prior to Windows 8 any child devices that are not present at the time of the call will not be uninstalled. However, beginning /// with Windows 8, any child devices that are not present at the time of the call will be uninstalled. /// /// /// /// A handle to the top-level window that is used to display any user interface component that is associated with the uninstallation /// request for the device. This parameter is optional and can be set to NULL. /// /// /// A handle to the device information set that contains a device information element. This element represents the device to be /// uninstalled through this call. /// /// /// A pointer to an SP_DEVINFO_DATA structure that represents the specified device in the specified device information set for which /// the uninstallation request is performed. /// /// /// A value of type DWORD that specifies device uninstallation flags. Starting with Windows 7, this parameter must be set to zero. /// /// /// /// A pointer to a value of type BOOL that DiUninstallDevice sets to indicate whether a system restart is required to /// complete the device uninstallation request. This parameter is optional and can be set to NULL. /// /// /// If the parameter is given and a system restart is required, DiUninstallDevice sets the value to TRUE. In this /// case, the application must prompt the user to restart the system. If this parameter is supplied and a system restart is not /// required, DiUninstallDevice sets the value to FALSE. /// /// /// If this parameter is NULL and a system restart is required to complete the device uninstallation, /// DiUninstallDevice displays a system restart dialog box. /// /// For more information about this parameter, see the Remarks section. /// /// /// /// DiUninstallDevice returns TRUE if the function successfully uninstalled the top-level device node that represents /// the device. Otherwise, DiUninstallDevice returns FALSE, and the logged error can be retrieved by making a call to /// GetLastError. The following list shows some of the more common error values that GetLastError might return for this API: /// /// /// /// Return code /// Description /// /// /// ERROR_ACCESS_DENIED /// /// The caller does not have Administrator privileges. By default, Windows requires that the caller have Administrator privileges to /// uninstall devices. /// /// /// /// ERROR_INVALID_FLAGS /// The value that is specified for the Flags parameter is not equal to zero. /// /// /// /// Note The return value does not indicate that the removal of all child devnodes has succeeded or failed. Starting with /// Windows Vista, information about the status of the removal of child devnodes is available in the Setupapi.dev.log file. For more /// information about this file, see SetupAPI Text Logs. /// /// /// /// /// DiUninstallDevice performs the same function as SetupDiCallClassInstaller when used with the DIF_REMOVE code. The key /// difference is that child devnodes for the top-level device are also deleted. DiUninstallDevice only returns failure if /// the top-level device node failed to be uninstalled, which is consistent with the behavior of SetupDiCallClassInstaller /// when used with the DIF_REMOVE code. Detailed information about whether child devnode uninstallation succeeded is /// available in the Setupapi.dev.log file. /// /// /// The device to be uninstalled is specified by providing a device information set that includes the referenced device, and a /// SP_DEVINFO_DATA structure for the specific device. These are provided in the DeviceInfoSet and DeviceInfoData parameters. /// /// /// To create a device information set that contains the specified device and to obtain an SP_DEVINFO_DATA structure for the device, /// complete one of the following tasks: /// /// /// /// /// Call SetupDiGetClassDevs to retrieve a device information set that contains the device and then call SetupDiEnumDeviceInfo to /// enumerate the devices in the device information set. On each call, SetupDiEnumDeviceInfo returns an SP_DEVINFO_DATA /// structure that represents the enumerated device in the device information set. /// /// /// /// /// Call SetupDiEnumDeviceInfo to add a device with a known device instance ID to the device information set. SetupDiOpenDeviceInfo /// returns an SP_DEVINFO_DATA structure that represents the device in the device information set. /// /// /// /// /// In case the device uninstallation request requires a restart of the computer, DiUninstallDevice prompts the user to /// restart the system if the NeedReboot parameter is set to NULL. If there is any user interface window that the application /// is using, the hwndParent parameter should be set to the value of that window's handle. /// /// /// However, if the application manages the notification of a required system restart, it must set the NeedReboot parameter to a /// non- NULL value. DiUninstallDevice sets the NeedReboot parameter to TRUE or FALSE, depending on /// whether a system restart is required. /// /// The following list shows examples of why the application might manage the system restart: /// /// /// /// The application has to uninstall several devices. After all the devices are uninstalled, the application should prompt the user /// to restart the system if any call to DiUninstallDevice returned TRUE in the NeedReboot parameter. /// /// /// /// /// The application requires some other operations to occur before the system can be restarted. If a system restart is required, the /// application should finish the required operations and then prompt the user to restart the system. /// /// /// /// /// The application is a class installer. In this case, the class installer should set the DI_NEEDREBOOT flag in the /// Flags member of the SP_DEVINSTALL_PARAMS structure for a device. /// /// /// /// // https://docs.microsoft.com/en-us/windows/win32/api/newdev/nf-newdev-diuninstalldevice BOOL DiUninstallDevice( HWND hwndParent, // HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, DWORD Flags, PBOOL NeedReboot ); [DllImport(Lib_NewDev, SetLastError = true, ExactSpelling = true)] [PInvokeData("newdev.h", MSDNShortId = "NF:newdev.DiUninstallDevice")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool DiUninstallDevice(HWND hwndParent, HDEVINFO DeviceInfoSet, in SP_DEVINFO_DATA DeviceInfoData, uint Flags, [MarshalAs(UnmanagedType.Bool)] out bool NeedReboot); /// /// The DiUninstallDriver function removes a driver from any devices it is installed on by installing those devices with /// another matching driver, if available, or the null driver if no other matching driver is available. Then the specified driver is /// removed from the driver store. /// /// /// A handle to the top-level window that DiUninstallDriver should use to display any user interface component that is /// associated with uninstalling the driver. This parameter is optional and can be set to NULL. /// /// /// A pointer to a NULL-terminated string that supplies the fully qualified path of the INF file for the driver package. /// /// /// /// A value of type DWORD that specifies zero or one or more of the following flags: DIURFLAG_NO_REMOVE_INF. Typically, this flag /// should be set to zero. /// /// /// If this flag is zero, DiUninstallDriver only uninstalls the specified driver from a device if the driver is a better /// match for a device than the driver that is currently installed on a device. However, if this flag is set to /// DIURFLAG_NO_REMOVE_INF, DiUninstallDriver removes the driver package from any devices it is installed on, but does not /// remove the drive package from the Driver Store. /// /// /// Caution: Forcing the uninstallation of the driver can result in replacing a more compatible or newer driver with a less /// compatible or older driver. /// /// For information about how Windows selects a driver for a device, see /// How Windows Selects Drivers /// . /// /// /// A pointer to a value of type BOOL that DiUninstallDriver sets to indicate whether a system restart is required to /// complete the uninstallation. This parameter is optional and can be NULL. If the parameter is supplied and a system /// restart is required to complete the uninstallation, DiUninstallDriver sets the value to TRUE. In this case, the /// caller must prompt the user to restart the system. If this parameter is supplied and a system restart is not required to /// complete the uninstallation, DiUninstallDriver sets the value to FALSE. If the parameter is NULL and a /// system restart is required to complete the uninstallation, DiUninstallDriver displays a system restart dialog box. For /// more information about this parameter, see the following Remarks section. /// /// /// /// DiUninstallDriver returns TRUE if the function successfully removes the driver package from any devices it is /// installed on and is successfully removed from the driver store of the system. If the driver package is not successfully /// uninstalled from the driver store, DiUninstallDriver returns FALSE and the logged error can be retrieved by making /// a call to GetLastError. Some of the more common error values that GetLastError might return are as follows: /// /// /// /// Return code /// Description /// /// /// ERROR_ACCESS_DENIED /// /// The caller does not have Administrator privileges. By default, Windows requires that the caller have Administrator privileges to /// uninstall a driver package from the driver store. /// /// /// /// ERROR_FILE_NOT_FOUND /// The path of the specified INF file does not exist. /// /// /// ERROR_INVALID_FLAGS /// The value specified for Flags is not equal to zero or DIURFLAG_NO_REMOVE_INF. /// /// /// ERROR_IN_WOW64 /// /// The calling application is a 32-bit application that is attempting to execute in a 64-bit environment, which is not allowed. For /// more information, see Installing Devices on 64-Bit Systems. /// /// /// /// /// /// /// In general, an uninstallation application should set NeedReboot to NULL to direct DiUninstallDriver to prompt the /// user to restart the system if a restart is required to complete the removal. An application should supply a NeedReboot pointer /// only in the following cases: /// /// /// /// /// The application must call DiUninstallDriver several times to complete an uninstallation. In this case, the application /// should record whether a TRUE NeedReboot value is returned by any of the calls to DiUninstallDriver and, if so, /// prompt the user to restart the system after the final call to DiUninstallDriver returns. /// /// /// /// /// The application must perform required operations, other than calling DiUninstallDriver, before a system restart should /// occur. If a system restart is required, the application should finish the required operations and then prompt the user to /// restart the system. /// /// /// /// // https://docs.microsoft.com/en-us/windows/win32/api/newdev/nf-newdev-diuninstalldriverw BOOL DiUninstallDriverW( HWND hwndParent, // LPCWSTR InfPath, DWORD Flags, PBOOL NeedReboot ); [DllImport(Lib_NewDev, SetLastError = true, CharSet = CharSet.Auto)] [PInvokeData("newdev.h", MSDNShortId = "NF:newdev.DiUninstallDriverW")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool DiUninstallDriver([In, Optional] HWND hwndParent, string InfPath, DIURFLAG Flags, [MarshalAs(UnmanagedType.Bool)] out bool NeedReboot); /// /// Given an INF file and a hardware ID, the UpdateDriverForPlugAndPlayDevices function installs updated drivers for devices /// that match the hardware ID. /// /// A handle to the top-level window to use for any UI related to installing devices. /// /// A pointer to a NULL-terminated string that supplies the hardware identifier to match existing devices on the computer. The /// maximum length of a NULL-terminated hardware identifier is MAX_DEVICE_ID_LEN. For more information about hardware identifiers, /// see Device Identification Strings. /// /// /// A pointer to a NULL-terminated string that supplies the full path file name of an INF file. The files should be on the /// distribution media or in a vendor-created directory, not in a system location such as %SystemRoot%\inf. /// UpdateDriverForPlugAndPlayDevices copies driver files to the appropriate system locations if the installation is successful. /// /// /// A caller-supplied value created by using OR to combine zero or more of the following bit flags: /// INSTALLFLAG_FORCE /// /// If this flag is set and the function finds a device that matches the HardwareId value, the function installs new drivers for the /// device whether better drivers already exist on the computer. /// /// /// Important Use this flag only with extreme caution. Setting this flag can cause an older driver to be installed over a /// newer driver, if a user runs the vendor's application after newer drivers are available. /// /// INSTALLFLAG_READONLY /// /// If this flag is set, the function will not copy, rename, or delete any installation files. Use of this flag should be limited to /// environments in which file access is restricted or impossible, such as an "embedded" operating system. /// /// INSTALLFLAG_NONINTERACTIVE /// /// If this flag is set, the function will return FALSE when any attempt to display UI is detected. Set this flag only if the /// function will be called from a component (such as a service) that cannot display UI. /// /// Note If this flag is set and a UI display is attempted, the device can be left in an indeterminate state. /// The InstallFlags parameter is typically zero. /// /// /// /// A pointer to a BOOL-typed variable that indicates whether a restart is required and who should prompt for it. This pointer is /// optional and can be NULL. /// /// /// If the pointer is NULL, UpdateDriverForPlugAndPlayDevices prompts for a restart after installing drivers, if /// necessary. If the pointer is supplied, the function returns a BOOLEAN value that is TRUE if the system should be /// restarted. It is then the caller's responsibility to prompt for a restart. /// /// For more information, see the following Remarks section. /// /// /// The function returns TRUE if a device was upgraded to the specified driver. /// /// Otherwise, it returns FALSE and the logged error can be retrieved with a call to GetLastError. Possible error /// values returned by GetLastError are included in the following table. /// /// /// /// Return code /// Description /// /// /// ERROR_FILE_NOT_FOUND /// The path that was specified for FullInfPath does not exist. /// /// /// ERROR_IN_WOW64 /// The calling application is a 32-bit application attempting to execute in a 64-bit environment, which is not allowed. /// /// /// ERROR_INVALID_FLAGS /// The value specified for InstallFlags is invalid. /// /// /// ERROR_NO_SUCH_DEVINST /// The value specified for HardwareId does not match any device on the system. That is, the device is not plugged in. /// /// /// ERROR_NO_MORE_ITEMS /// /// The function found a match for the HardwareId value, but the specified driver was not a better match than the current driver and /// the caller did not specify the INSTALLFLAG_FORCE flag. /// /// /// /// /// /// /// UpdateDriverForPlugAndPlayDevices scans the devices on the system and attempts to install the drivers specified by /// FullInfPath for any devices that match the specified HardwareId value. /// /// /// The default behavior is to only install the specified drivers if they are better match than the currently installed drivers and /// the specified drivers are also a better match than any drivers in %SystemRoot%\inf. For more information, see How Windows /// Selects Drivers. /// /// /// UpdateDriverForPlugAndPlayDevices can also be used to determine whether the device with the specified HardwareId value is /// plugged in. For more information, see Writing a Device Installation Application. /// /// /// UpdateDriverForPlugAndPlayDevices sends an IRP_MN_QUERY_REMOVE_DEVICE request to the specified device, all the children /// of the device, and all other devices that are recursively part of the removal relations for the device. If any of these devices /// fail a query remove request, UpdateDriverForPlugAndPlayDevices sets the DI_NEEDREBOOT flag in the Flags member of /// the SP_DEVINSTALL_PARAMS structure for the device. For information about removal relations, see the /// IRP_MN_QUERY_DEVICE_RELATIONS request. /// /// /// Generally, device installation applications should supply NULL for bRebootRequired. So, the system will initiate a /// restart if necessary. An application should specify a pointer value only in the following cases: /// /// /// /// The application must call UpdateDriverForPlugAndPlayDevices several times to complete an installation. /// /// /// The application must perform other operations before the restart (if required) occurs. /// /// /// The application is a class installer, which should set DI_NEEDREBOOT in SP_DEVINSTALL_PARAMS if a restart is needed. /// /// /// /// If the application must call UpdateDriverForPlugAndPlayDevices several times, it should save any TRUE restart /// status value received and then prompt for a restart after the final call has returned. /// /// /// If the function returns ERROR_IN_WOW64 in a 32-bit application, the application is executing on a 64-bit system, which is not /// allowed. For more information, see Installing Devices on 64-Bit Systems. /// /// // https://docs.microsoft.com/en-us/windows/win32/api/newdev/nf-newdev-updatedriverforplugandplaydevicesa BOOL // UpdateDriverForPlugAndPlayDevicesA( HWND hwndParent, LPCSTR HardwareId, LPCSTR FullInfPath, DWORD InstallFlags, PBOOL // bRebootRequired ); [DllImport(Lib_NewDev, SetLastError = true, CharSet = CharSet.Auto)] [PInvokeData("newdev.h", MSDNShortId = "NF:newdev.UpdateDriverForPlugAndPlayDevicesA")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool UpdateDriverForPlugAndPlayDevices([In, Optional] HWND hwndParent, string HardwareId, string FullInfPath, INSTALLFLAG InstallFlags, [MarshalAs(UnmanagedType.Bool)] out bool bRebootRequired); } }