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);
}
}