using Microsoft.Win32.SafeHandles; using System; using System.Collections.Generic; using System.Runtime.InteropServices; using System.Text; using Vanara.InteropServices; namespace Vanara.PInvoke { /// Items from the SetupAPI.dll public static partial class SetupAPI { /// A comparison callback function to use in duplicate detection. /// /// A handle to a device information set that contains a device information element that represents the device to register. The /// device information set must not contain any remote elements. /// /// The new device data. /// The existing device data. /// /// A pointer to a caller-supplied context buffer that is passed into the callback function. This parameter is ignored if /// CompareProc is not specified. /// /// /// The compare function must return ERROR_DUPLICATE_FOUND if it finds that the two devices are duplicates. Otherwise, it should /// return NO_ERROR. If some other error is encountered, the callback function should return the appropriate ERROR_* code to /// indicate the failure. /// [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Auto)] public delegate Win32Error PSP_DETSIG_CMPPROC([In] HDEVINFO DeviceInfoSet, in SP_DEVINFO_DATA NewDeviceData, in SP_DEVINFO_DATA ExistingDeviceData, [In, Optional] IntPtr CompareContext); /// /// The SetupDiAskForOEMDisk function displays a dialog that asks the user for the path of an OEM installation disk. /// /// /// A handle to a device information set for the local computer. This set contains a device information element that represents the /// device that is being installed. /// /// /// A pointer to an SP_DEVINFO_DATA structure that specifies the device information element in DeviceInfoSet. This parameter is /// optional and can be NULL. If this parameter is specified, SetupDiAskForOEMDisk associates the driver with the /// device that is being installed. If this parameter is NULL, SetupDiAskForOEMDisk associates the driver with the /// global class driver list for DeviceInfoSet. /// /// /// The function returns TRUE if it is successful and the DriverPath field of the SP_DEVINSTALLPARAMS structure is /// updated to reflect the new path. If the user cancels the dialog, the function returns FALSE and a call to GetLastError /// returns ERROR_CANCELLED. /// /// /// /// SetupDiAskForOEMDisk allows the user to browse local and network drives for OEM installation files. However, /// SetupDiAskForOEMDisk is primarily designed to obtain the path of an OEM driver on a local computer before selecting and /// installing the driver for a device on that computer. /// /// /// Although this function will not fail if the device information set if for a remote computer, the result is of limited use /// because the device information set cannot subsequently be used with DIF_Xxx installation requests or SetupDi Xxx /// functions that do not support operations on a remote computer. /// /// /// In particular, the device information set cannot be used as input with a DIF_SELECTDEVICE installation request to select a /// driver for a device, followed by a DIF_INSTALLDEVICE installation request to install a device on a remote computer. /// /// // https://docs.microsoft.com/en-us/windows/win32/api/setupapi/nf-setupapi-setupdiaskforoemdisk WINSETUPAPI BOOL // SetupDiAskForOEMDisk( HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData ); [DllImport(Lib_SetupAPI, SetLastError = true, ExactSpelling = true)] [PInvokeData("setupapi.h", MSDNShortId = "NF:setupapi.SetupDiAskForOEMDisk")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool SetupDiAskForOEMDisk(HDEVINFO DeviceInfoSet, in SP_DEVINFO_DATA DeviceInfoData); /// /// The SetupDiAskForOEMDisk function displays a dialog that asks the user for the path of an OEM installation disk. /// /// /// A handle to a device information set for the local computer. This set contains a device information element that represents the /// device that is being installed. /// /// /// A pointer to an SP_DEVINFO_DATA structure that specifies the device information element in DeviceInfoSet. This parameter is /// optional and can be NULL. If this parameter is specified, SetupDiAskForOEMDisk associates the driver with the /// device that is being installed. If this parameter is NULL, SetupDiAskForOEMDisk associates the driver with the /// global class driver list for DeviceInfoSet. /// /// /// The function returns TRUE if it is successful and the DriverPath field of the SP_DEVINSTALLPARAMS structure is /// updated to reflect the new path. If the user cancels the dialog, the function returns FALSE and a call to GetLastError /// returns ERROR_CANCELLED. /// /// /// /// SetupDiAskForOEMDisk allows the user to browse local and network drives for OEM installation files. However, /// SetupDiAskForOEMDisk is primarily designed to obtain the path of an OEM driver on a local computer before selecting and /// installing the driver for a device on that computer. /// /// /// Although this function will not fail if the device information set if for a remote computer, the result is of limited use /// because the device information set cannot subsequently be used with DIF_Xxx installation requests or SetupDi Xxx /// functions that do not support operations on a remote computer. /// /// /// In particular, the device information set cannot be used as input with a DIF_SELECTDEVICE installation request to select a /// driver for a device, followed by a DIF_INSTALLDEVICE installation request to install a device on a remote computer. /// /// // https://docs.microsoft.com/en-us/windows/win32/api/setupapi/nf-setupapi-setupdiaskforoemdisk WINSETUPAPI BOOL // SetupDiAskForOEMDisk( HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData ); [DllImport(Lib_SetupAPI, SetLastError = true, ExactSpelling = true)] [PInvokeData("setupapi.h", MSDNShortId = "NF:setupapi.SetupDiAskForOEMDisk")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool SetupDiAskForOEMDisk(HDEVINFO DeviceInfoSet, [In, Optional] IntPtr DeviceInfoData); /// /// The SetupDiBuildClassInfoList function returns a list of setup class GUIDs that identify the classes that are installed /// on a local computer. /// /// /// /// Flags used to control exclusion of classes from the list. If no flags are specified, all setup classes are included in the list. /// Can be a combination of the following values: /// /// DIBCI_NOINSTALLCLASS /// Exclude a class if it has the NoInstallClass value entry in its registry key. /// DIBCI_NODISPLAYCLASS /// Exclude a class if it has the NoDisplayClass value entry in its registry key. /// /// /// A pointer to a GUID-typed array that receives a list of setup class GUIDs. This pointer is optional and can be NULL. /// /// /// The number of GUIDs in the array that is pointed to by the ClassGuildList parameter. If ClassGuidList is NULL, /// ClassGuidSize must be zero. /// /// /// /// A pointer to a DWORD-typed variable that receives the number of GUIDs that are returned (if the number is less than or equal to /// the size, in GUIDs, of the array that is pointed to by the ClassGuidList parameter). /// /// /// If this number is greater than the size of the ClassGuidList array, it indicates how large the ClassGuidList array must be in /// order to contain all the class GUIDs. /// /// /// /// The function returns TRUE if it is successful. Otherwise, it returns FALSE and the logged error can be retrieved /// by making a call to GetLastError. /// /// /// /// To retrieve the number of classes that are installed on a local computer, call SetupDiBuildClassInfoList with /// ClassGuidList set to NULL and ClassGuidSize set to zero. In response to such a call, the function returns the number of /// classes in * RequiredSize. /// /// /// SetupDiBuildClassInfoList does not return a class GUID for a class if the NoUseClass value entry exists in the /// registry key of the class. /// /// To retrieve the list of setup class GUIDs installed on a remote system use SetupDiBuildClassInfoListEx. /// // https://docs.microsoft.com/en-us/windows/win32/api/setupapi/nf-setupapi-setupdibuildclassinfolist WINSETUPAPI BOOL // SetupDiBuildClassInfoList( DWORD Flags, LPGUID ClassGuidList, DWORD ClassGuidListSize, PDWORD RequiredSize ); [DllImport(Lib_SetupAPI, SetLastError = true, ExactSpelling = true)] [PInvokeData("setupapi.h", MSDNShortId = "NF:setupapi.SetupDiBuildClassInfoList")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool SetupDiBuildClassInfoList(DIBCI Flags, [Out, Optional, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] Guid[] ClassGuidList, uint ClassGuidListSize, out uint RequiredSize); /// /// The SetupDiBuildClassInfoListEx function returns a list of setup class GUIDs that includes every class installed on the /// local system or a remote system. /// /// /// /// Flags used to control exclusion of classes from the list. If no flags are specified, all setup classes are included in the list. /// Can be a combination of the following values: /// /// DIBCI_NOINSTALLCLASS /// Exclude a class if it has the NoInstallClass value entry in its registry key. /// DIBCI_NODISPLAYCLASS /// Exclude a class if it has the NoDisplayClass value entry in its registry key. /// /// A pointer to a buffer that receives a list of setup class GUIDs. /// Supplies the number of GUIDs in the ClassGuildList array. /// /// A pointer to a variable that receives the number of GUIDs returned. If this number is greater than the size of the /// ClassGuidList, the number indicates how large the ClassGuidList array must be in order to contain the list. /// /// /// A pointer to a NULL-terminated string that contains the name of a remote computer from which to retrieve installed setup /// classes. This parameter is optional and can be NULL. If MachineName is NULL, this function builds a list of /// classes installed on the local computer. /// /// Must be NULL. /// /// The function returns TRUE if it is successful. Otherwise, it returns FALSE and the logged error can be retrieved /// by making a call to GetLastError. /// /// // https://docs.microsoft.com/en-us/windows/win32/api/setupapi/nf-setupapi-setupdibuildclassinfolistexa WINSETUPAPI BOOL // SetupDiBuildClassInfoListExA( DWORD Flags, LPGUID ClassGuidList, DWORD ClassGuidListSize, PDWORD RequiredSize, PCSTR MachineName, // PVOID Reserved ); [DllImport(Lib_SetupAPI, SetLastError = true, CharSet = CharSet.Auto)] [PInvokeData("setupapi.h", MSDNShortId = "NF:setupapi.SetupDiBuildClassInfoListExA")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool SetupDiBuildClassInfoListEx(DIBCI Flags, [Out, Optional, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] Guid[] ClassGuidList, uint ClassGuidListSize, out uint RequiredSize, [Optional, MarshalAs(UnmanagedType.LPTStr)] string MachineName, IntPtr Reserved = default); /// /// The SetupDiBuildDriverInfoList function builds a list of drivers that is associated with a specific device or with the /// global class driver list for a device information set. /// /// /// A handle to the device information set to contain the driver list, either globally for all device information elements or /// specifically for a single device information element. The device information set must not contain remote device information elements. /// /// /// /// A pointer to an SP_DEVINFO_DATA structure for the device information element in DeviceInfoSet that represents the device for /// which to build a driver list. This parameter is optional and can be NULL. If this parameter is specified, the list is /// associated with the specified device. If this parameter is NULL, the list is associated with the global class driver list /// for DeviceInfoSet. /// /// /// If the class of this device is updated because of building a compatible driver list, DeviceInfoData. ClassGuid is updated /// upon return. /// /// /// /// The type of driver list to build. Must be one of the following values: /// /// /// Value /// Meaning /// /// /// SPDIT_CLASSDRIVER /// Build a list of class drivers. If DeviceInfoData is NULL, this driver list type must be specified. /// /// /// SPDIT_COMPATDRIVER /// Build a list of compatible drivers. DeviceInfoData must not be NULL if this driver list type is specified. /// /// /// /// /// The function returns TRUE if it is successful. Otherwise, it returns FALSE and the logged error can be retrieved /// by making a call to GetLastError. /// /// /// /// The device information set should be for a local computer because SetupDiBuildDriverInfoList searches for drivers only on /// a local computer. If the device information set is for a remote computer, the function returns TRUE but does not actually /// update the existing driver list for the device information set or, if supplied, the driver list for the device information element. /// /// /// The caller can set Flags in the SP_DEVINSTALL_PARAMS that are associated with the device information set or with a /// specific device (DeviceInfoData) to control how the list is built. For example, the caller can set the /// DI_FLAGSEX_ALLOWEXCLUDEDDRVS flag to include drivers that are marked Exclude From Select. /// /// /// A driver is "Exclude From Select" if either it is marked ExcludeFromSelect in the INF file or it is a driver for a device /// whose whole setup class is marked NoInstallClass or NoUseClass in the class installer INF file. Drivers for PnP /// devices are typically "Exclude From Select"; PnP devices should not be manually installed. To build a list of driver files for a /// PnP device a caller of SetupDiBuildDriverInfoList must set this flag. /// /// /// The DriverPath in the SP_DEVINSTALL_PARAMS contains either a path of a directory that contain INF files or a path of a /// specific INF file. If DI_ENUMSINGLEINF is set, DriverPath contains a path of a single INF file. If /// DriverPath is NULL, this function builds the driver list from the default INF file location, %SystemRoot%\inf. /// /// /// After this function has built the specified driver list, the caller can enumerate the elements of the list by calling SetupDiEnumDriverInfo. /// /// /// If the driver list is associated with a device instance (that is, DeviceInfoData is specified), the resulting list is composed /// of drivers that have the same class as the device instance with which they are associated. If this is a global class driver list /// (that is, DriverType is SPDIT_CLASSDRIVER and DeviceInfoData is not specified), the class that is used when building the /// list is the class associated with the device information set. If the device information set has no associated class, drivers of /// all classes are used when building the list. /// /// Another thread can terminate the building of a driver list by a call to SetupDiCancelDriverInfoSearch. /// The DeviceInfoSet must only contain elements on the local computer. This function only searches for local drivers. /// // https://docs.microsoft.com/en-us/windows/win32/api/setupapi/nf-setupapi-setupdibuilddriverinfolist WINSETUPAPI BOOL // SetupDiBuildDriverInfoList( HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, DWORD DriverType ); [DllImport(Lib_SetupAPI, SetLastError = true, ExactSpelling = true)] [PInvokeData("setupapi.h", MSDNShortId = "NF:setupapi.SetupDiBuildDriverInfoList")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool SetupDiBuildDriverInfoList(HDEVINFO DeviceInfoSet, ref SP_DEVINFO_DATA DeviceInfoData, SPDIT DriverType); /// /// The SetupDiBuildDriverInfoList function builds a list of drivers that is associated with a specific device or with the /// global class driver list for a device information set. /// /// /// A handle to the device information set to contain the driver list, either globally for all device information elements or /// specifically for a single device information element. The device information set must not contain remote device information elements. /// /// /// /// A pointer to an SP_DEVINFO_DATA structure for the device information element in DeviceInfoSet that represents the device for /// which to build a driver list. This parameter is optional and can be NULL. If this parameter is specified, the list is /// associated with the specified device. If this parameter is NULL, the list is associated with the global class driver list /// for DeviceInfoSet. /// /// /// If the class of this device is updated because of building a compatible driver list, DeviceInfoData. ClassGuid is updated /// upon return. /// /// /// /// The type of driver list to build. Must be one of the following values: /// /// /// Value /// Meaning /// /// /// SPDIT_CLASSDRIVER /// Build a list of class drivers. If DeviceInfoData is NULL, this driver list type must be specified. /// /// /// SPDIT_COMPATDRIVER /// Build a list of compatible drivers. DeviceInfoData must not be NULL if this driver list type is specified. /// /// /// /// /// The function returns TRUE if it is successful. Otherwise, it returns FALSE and the logged error can be retrieved /// by making a call to GetLastError. /// /// /// /// The device information set should be for a local computer because SetupDiBuildDriverInfoList searches for drivers only on /// a local computer. If the device information set is for a remote computer, the function returns TRUE but does not actually /// update the existing driver list for the device information set or, if supplied, the driver list for the device information element. /// /// /// The caller can set Flags in the SP_DEVINSTALL_PARAMS that are associated with the device information set or with a /// specific device (DeviceInfoData) to control how the list is built. For example, the caller can set the /// DI_FLAGSEX_ALLOWEXCLUDEDDRVS flag to include drivers that are marked Exclude From Select. /// /// /// A driver is "Exclude From Select" if either it is marked ExcludeFromSelect in the INF file or it is a driver for a device /// whose whole setup class is marked NoInstallClass or NoUseClass in the class installer INF file. Drivers for PnP /// devices are typically "Exclude From Select"; PnP devices should not be manually installed. To build a list of driver files for a /// PnP device a caller of SetupDiBuildDriverInfoList must set this flag. /// /// /// The DriverPath in the SP_DEVINSTALL_PARAMS contains either a path of a directory that contain INF files or a path of a /// specific INF file. If DI_ENUMSINGLEINF is set, DriverPath contains a path of a single INF file. If /// DriverPath is NULL, this function builds the driver list from the default INF file location, %SystemRoot%\inf. /// /// /// After this function has built the specified driver list, the caller can enumerate the elements of the list by calling SetupDiEnumDriverInfo. /// /// /// If the driver list is associated with a device instance (that is, DeviceInfoData is specified), the resulting list is composed /// of drivers that have the same class as the device instance with which they are associated. If this is a global class driver list /// (that is, DriverType is SPDIT_CLASSDRIVER and DeviceInfoData is not specified), the class that is used when building the /// list is the class associated with the device information set. If the device information set has no associated class, drivers of /// all classes are used when building the list. /// /// Another thread can terminate the building of a driver list by a call to SetupDiCancelDriverInfoSearch. /// The DeviceInfoSet must only contain elements on the local computer. This function only searches for local drivers. /// // https://docs.microsoft.com/en-us/windows/win32/api/setupapi/nf-setupapi-setupdibuilddriverinfolist WINSETUPAPI BOOL // SetupDiBuildDriverInfoList( HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, DWORD DriverType ); [DllImport(Lib_SetupAPI, SetLastError = true, ExactSpelling = true)] [PInvokeData("setupapi.h", MSDNShortId = "NF:setupapi.SetupDiBuildDriverInfoList")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool SetupDiBuildDriverInfoList(HDEVINFO DeviceInfoSet, [In, Optional] IntPtr DeviceInfoData, SPDIT DriverType); /// /// The SetupDiCallClassInstaller function calls the appropriate class installer, and any registered co-installers, with the /// specified installation request (DIF code). /// /// /// /// The device installation request (DIF request) to pass to the co-installers and class installer. DIF codes have the format /// DIF_XXX and are defined in Setupapi.h. See Device Installation Function Codes for more information. /// /// /// Note For certain DIF requests, the caller must be a member of the Administrators group. For such DIF requests, this /// requirement is listed on the reference page for the associated default handler. /// /// /// /// A handle to a device information set for the local computer. This set contains a device installation element which represents /// the device for which to perform the specified installation function. /// /// /// A pointer to an SP_DEVINFO_DATA structure that specifies the device information element in the DeviceInfoSet that represents the /// device for which to perform the specified installation function. This parameter is optional and can be set to NULL. If /// this parameter is specified, SetupDiCallClassInstaller performs the specified function on the DeviceInfoData element. If /// DeviceInfoData is NULL, SetupDiCallClassInstaller calls the installers for the setup class that is associated with DeviceInfoSet. /// /// /// /// The function returns TRUE if it is successful. Otherwise, it returns FALSE and the logged error can be retrieved /// by making a call to GetLastError. /// /// /// When GetLastError returns ERROR_IN_WOW64, this means that the calling application is a 32-bit application attempting to /// execute in a 64-bit environment, which is not allowed. /// /// /// /// /// SetupDiCallClassInstaller calls the class installer and any co-installers that are registered for a device or a device /// setup class. This function loads the installers if they are not yet loaded. The function also calls the default handler for the /// DIF request, if there is a default handler and if the installers return a status indicating that the default handler should be called. /// /// /// Device installation applications call this function with a variety of device installation function codes (DIF codes). The /// function ensures that all the appropriate installers and default handlers are called, in the correct order, for a given DIF /// request. For more information, see Handling DIF Codes. /// /// /// After SetupDiCallClassInstaller returns TRUE, the device installation application must call /// SetupDiGetDeviceInstallParams to obtain an SP_DEVINSTALL_PARAMS structure. If the structure's DI_NEEDREBOOT or /// DI_NEEDRESTART flag is set, the caller must prompt the user to restart the system. For example, the caller can do this by /// calling SetupPromptReboot. /// /// /// However, be aware that a device installation application should request a system restart one time at most. Therefore, any device /// installation application that creates multiple calls to SetupDiCallClassInstaller and SetupDiGetDeviceInstallParams /// should save the DI_NEEDREBOOT and DI_NEEDRESTART flags after each call. However, it should prompt the user only /// after the last call returns. /// /// /// In response to a DIF code supplied by SetupDiCallClassInstaller, class installers and co-installers might perform /// operations that require the system to be restarted. In such situations, the installer or co-installer should do the following: /// /// /// /// Call SetupDiGetDeviceInstallParams to obtain the SP_DEVINSTALL_PARAMS structure. /// /// /// Set the DI_NEEDREBOOT or DI_NEEDRESTART flag in the structure's Flags member. /// /// /// Call SetupDiSetDeviceInstallParams, supplying the updated SP_DEVINSTALL_PARAMS structure, to save the revised Flags member. /// /// /// /// After SetupDiCallClassInstaller returns, the device installation application that called it should call /// SetupDiGetDeviceInstallParams, check the flags, and request a restart if necessary. /// /// The device information set specified by DeviceInfoSet must only contain elements for devices on the local computer. /// For information about the design and operation of co-installers, see Writing a Co-installer. /// // https://docs.microsoft.com/en-us/windows/win32/api/setupapi/nf-setupapi-setupdicallclassinstaller WINSETUPAPI BOOL // SetupDiCallClassInstaller( DI_FUNCTION InstallFunction, HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData ); [DllImport(Lib_SetupAPI, SetLastError = true, ExactSpelling = true)] [PInvokeData("setupapi.h", MSDNShortId = "NF:setupapi.SetupDiCallClassInstaller")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool SetupDiCallClassInstaller(DI_FUNCTION InstallFunction, HDEVINFO DeviceInfoSet, in SP_DEVINFO_DATA DeviceInfoData); /// /// The SetupDiCallClassInstaller function calls the appropriate class installer, and any registered co-installers, with the /// specified installation request (DIF code). /// /// /// /// The device installation request (DIF request) to pass to the co-installers and class installer. DIF codes have the format /// DIF_XXX and are defined in Setupapi.h. See Device Installation Function Codes for more information. /// /// /// Note For certain DIF requests, the caller must be a member of the Administrators group. For such DIF requests, this /// requirement is listed on the reference page for the associated default handler. /// /// /// /// A handle to a device information set for the local computer. This set contains a device installation element which represents /// the device for which to perform the specified installation function. /// /// /// A pointer to an SP_DEVINFO_DATA structure that specifies the device information element in the DeviceInfoSet that represents the /// device for which to perform the specified installation function. This parameter is optional and can be set to NULL. If /// this parameter is specified, SetupDiCallClassInstaller performs the specified function on the DeviceInfoData element. If /// DeviceInfoData is NULL, SetupDiCallClassInstaller calls the installers for the setup class that is associated with DeviceInfoSet. /// /// /// /// The function returns TRUE if it is successful. Otherwise, it returns FALSE and the logged error can be retrieved /// by making a call to GetLastError. /// /// /// When GetLastError returns ERROR_IN_WOW64, this means that the calling application is a 32-bit application attempting to /// execute in a 64-bit environment, which is not allowed. /// /// /// /// /// SetupDiCallClassInstaller calls the class installer and any co-installers that are registered for a device or a device /// setup class. This function loads the installers if they are not yet loaded. The function also calls the default handler for the /// DIF request, if there is a default handler and if the installers return a status indicating that the default handler should be called. /// /// /// Device installation applications call this function with a variety of device installation function codes (DIF codes). The /// function ensures that all the appropriate installers and default handlers are called, in the correct order, for a given DIF /// request. For more information, see Handling DIF Codes. /// /// /// After SetupDiCallClassInstaller returns TRUE, the device installation application must call /// SetupDiGetDeviceInstallParams to obtain an SP_DEVINSTALL_PARAMS structure. If the structure's DI_NEEDREBOOT or /// DI_NEEDRESTART flag is set, the caller must prompt the user to restart the system. For example, the caller can do this by /// calling SetupPromptReboot. /// /// /// However, be aware that a device installation application should request a system restart one time at most. Therefore, any device /// installation application that creates multiple calls to SetupDiCallClassInstaller and SetupDiGetDeviceInstallParams /// should save the DI_NEEDREBOOT and DI_NEEDRESTART flags after each call. However, it should prompt the user only /// after the last call returns. /// /// /// In response to a DIF code supplied by SetupDiCallClassInstaller, class installers and co-installers might perform /// operations that require the system to be restarted. In such situations, the installer or co-installer should do the following: /// /// /// /// Call SetupDiGetDeviceInstallParams to obtain the SP_DEVINSTALL_PARAMS structure. /// /// /// Set the DI_NEEDREBOOT or DI_NEEDRESTART flag in the structure's Flags member. /// /// /// Call SetupDiSetDeviceInstallParams, supplying the updated SP_DEVINSTALL_PARAMS structure, to save the revised Flags member. /// /// /// /// After SetupDiCallClassInstaller returns, the device installation application that called it should call /// SetupDiGetDeviceInstallParams, check the flags, and request a restart if necessary. /// /// The device information set specified by DeviceInfoSet must only contain elements for devices on the local computer. /// For information about the design and operation of co-installers, see Writing a Co-installer. /// // https://docs.microsoft.com/en-us/windows/win32/api/setupapi/nf-setupapi-setupdicallclassinstaller WINSETUPAPI BOOL // SetupDiCallClassInstaller( DI_FUNCTION InstallFunction, HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData ); [DllImport(Lib_SetupAPI, SetLastError = true, ExactSpelling = true)] [PInvokeData("setupapi.h", MSDNShortId = "NF:setupapi.SetupDiCallClassInstaller")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool SetupDiCallClassInstaller(DI_FUNCTION InstallFunction, HDEVINFO DeviceInfoSet, [In, Optional] IntPtr DeviceInfoData); /// /// The SetupDiCancelDriverInfoSearch function cancels a driver list search that is currently in progress in a different thread. /// /// A handle to the device information set for which a driver list is being built. /// /// If a driver list search is underway for the specified device information set when this function is called, the search is /// terminated. SetupDiCancelDriverInfoSearch returns TRUE when the termination is confirmed. Otherwise, it returns /// FALSE and a call to GetLastError returns ERROR_INVALID_HANDLE. /// /// /// SetupDiCancelDriverInfoSearch is a synchronous call. Therefore, it does not return until the driver search thread /// responds to the termination request. /// // https://docs.microsoft.com/en-us/windows/win32/api/setupapi/nf-setupapi-setupdicanceldriverinfosearch WINSETUPAPI BOOL // SetupDiCancelDriverInfoSearch( HDEVINFO DeviceInfoSet ); [DllImport(Lib_SetupAPI, SetLastError = true, ExactSpelling = true)] [PInvokeData("setupapi.h", MSDNShortId = "NF:setupapi.SetupDiCancelDriverInfoSearch")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool SetupDiCancelDriverInfoSearch(HDEVINFO DeviceInfoSet); /// The SetupDiChangeState function is the default handler for the DIF_PROPERTYCHANGE installation request. /// /// A handle to a device information set for the local computer. This set contains a device information element that represents the /// device whose state is to be changed. /// /// /// A pointer to an SP_DEVINFO_DATA structure that specifies the device information element in DeviceInfoSet. This is an IN-OUT /// parameter because DeviceInfoData. DevInst might be updated with a new handle value upon return. /// /// /// The function returns TRUE if it is successful. Otherwise, it returns FALSE and the logged error can be retrieved /// by making a call to GetLastError. /// /// /// SetupDiChangeState changes the state of an installed device. /// The caller of SetupDiChangeState must be a member of the Administrators group. /// /// Note Only a class installer should call SetupDiChangeState and only in those situations where the class installer /// must perform property change operations after SetupDiChangeState completes the default property change operation. In such /// situations, the class installer must directly call SetupDiChangeState when the installer processes a DIF_PROPERTYCHANGE /// request. For more information about calling the default handler, see Calling Default DIF Code Handlers. /// /// /// Callers of SetupDiChangeState must specify a DICS_XXX flag in the SP_PROPCHANGE_PARAMS for the device element that /// indicates the type of state change to perform on the device. Callers of this function must set the appropriate fields in the /// SP_PROPCHANGE_PARAMS and call SetupDiSetClassInstallParams before calling this function. /// /// /// If you specify the DICS_FLAG_CONFIGSPECIFIC flag in the SP_PROPCHANGE_PARAMS then you must fill in the HwProfile field. A /// value of zero for HwProfile indicates the current profile. /// /// /// To enable/disable a device in the current hardware profile, set the DICS_FLAG_CONFIGSPECIFIC flag in the SP_PROPCHANGE_PARAMS. /// To enable/disable a device globally, such as in both the docked and undocked hardware profiles, set the DICS_FLAG_GLOBAL flag. /// /// This function does the following: /// /// Callers of this function should not specify DICS_STOP or DICS_START in the SP_PROPCHANGE_PARAMS. Use DICS_PROPCHANGE to stop and /// restart a device to cause changes in the device's configuration to take effect. /// /// /// If DI_DONOTCALLCONFIGMG is set for a device, you should not call SetupDiChangeState for the device but should instead set /// the DI_NEEDREBOOT flag. /// /// // https://docs.microsoft.com/en-us/windows/win32/api/setupapi/nf-setupapi-setupdichangestate WINSETUPAPI BOOL SetupDiChangeState( // HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData ); [DllImport(Lib_SetupAPI, SetLastError = true, ExactSpelling = true)] [PInvokeData("setupapi.h", MSDNShortId = "NF:setupapi.SetupDiChangeState")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool SetupDiChangeState(HDEVINFO DeviceInfoSet, ref SP_DEVINFO_DATA DeviceInfoData); /// /// The SetupDiClassGuidsFromName function retrieves the GUID(s) associated with the specified class name. This list is built /// based on the classes currently installed on the system. /// /// The name of the class for which to retrieve the class GUID. /// A pointer to an array to receive the list of GUIDs associated with the specified class name. /// The number of GUIDs in the ClassGuidList array. /// /// Supplies a pointer to a variable that receives the number of GUIDs associated with the class name. If this number is greater /// than the size of the ClassGuidList buffer, the number indicates how large the array must be in order to store all the GUIDs. /// /// /// The function returns TRUE if it is successful. Otherwise, it returns FALSE and the logged error can be retrieved /// by making a call to GetLastError. /// /// Call SetupDiClassGuidsFromNameEx to retrieve the class GUIDs for a class on a remote computer. // https://docs.microsoft.com/en-us/windows/win32/api/setupapi/nf-setupapi-setupdiclassguidsfromnamea WINSETUPAPI BOOL // SetupDiClassGuidsFromNameA( PCSTR ClassName, LPGUID ClassGuidList, DWORD ClassGuidListSize, PDWORD RequiredSize ); [DllImport(Lib_SetupAPI, SetLastError = true, CharSet = CharSet.Auto)] [PInvokeData("setupapi.h", MSDNShortId = "NF:setupapi.SetupDiClassGuidsFromNameA")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool SetupDiClassGuidsFromName(string ClassName, [Out, Optional, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] Guid[] ClassGuidList, uint ClassGuidListSize, out uint RequiredSize); /// /// The SetupDiClassGuidsFromNameEx function retrieves the GUIDs associated with the specified class name. This resulting /// list contains the classes currently installed on a local or remote computer. /// /// The name of the class for which to retrieve the class GUIDs. /// A pointer to an array to receive the list of GUIDs associated with the specified class name. /// The number of GUIDs in the ClassGuidList array. /// /// A pointer to a variable that receives the number of GUIDs associated with the class name. If this number is greater than the /// size of the ClassGuidList buffer, the number indicates how large the array must be in order to store all the GUIDs. /// /// /// A pointer to a NULL-terminated string that contains the name of a remote system from which to retrieve the GUIDs. This parameter /// is optional and can be NULL. If MachineName is NULL, the local system name is used. /// /// Must be NULL. /// /// The function returns TRUE if it is successful. Otherwise, it returns FALSE and the logged error can be retrieved /// by making a call to GetLastError. /// /// /// Class names are not guaranteed to be unique; only GUIDs are unique. Therefore, one class name can return more than one GUID. /// // https://docs.microsoft.com/en-us/windows/win32/api/setupapi/nf-setupapi-setupdiclassguidsfromnameexa WINSETUPAPI BOOL // SetupDiClassGuidsFromNameExA( PCSTR ClassName, LPGUID ClassGuidList, DWORD ClassGuidListSize, PDWORD RequiredSize, PCSTR // MachineName, PVOID Reserved ); [DllImport(Lib_SetupAPI, SetLastError = true, CharSet = CharSet.Auto)] [PInvokeData("setupapi.h", MSDNShortId = "NF:setupapi.SetupDiClassGuidsFromNameExA")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool SetupDiClassGuidsFromNameEx(string ClassName, [Out, Optional, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] Guid[] ClassGuidList, uint ClassGuidListSize, out uint RequiredSize, [In, Optional, MarshalAs(UnmanagedType.LPTStr)] string MachineName, IntPtr Reserved = default); /// The SetupDiClassNameFromGuid function retrieves the class name associated with a class GUID. /// A pointer to the class GUID for the class name to retrieve. /// /// A pointer to a buffer that receives the NULL-terminated string that contains the name of the class that is specified by the /// pointer in the ClassGuid parameter. /// /// /// The size, in characters, of the buffer that is pointed to by the ClassName parameter. The maximum size, in characters, of a /// NULL-terminated class name is MAX_CLASS_NAME_LEN. For more information about the class name size, see the following /// Remarks section. /// /// /// A pointer to a variable that receives the number of characters that are required to store the requested NULL-terminated class /// name. This pointer is optional and can be NULL. /// /// /// The function returns TRUE if it is successful. Otherwise, it returns FALSE and the logged error can be retrieved /// with a call to GetLastError. /// /// /// Call SetupDiClassNameFromGuidEx to retrieve the name for a class on a remote computer. /// /// SetupDiClassNameFromGuid does not enforce a restriction on the length of the class name that it can return. This function /// returns the required size for a NULL-terminated class name even if it is greater than MAX_CLASS_NAME_LEN. However, /// MAX_CLASS_NAME_LEN is the maximum length of a valid NULL-terminated class name. A caller should never need a buffer that is /// larger than MAX_CLASS_NAME_LEN. For more information about class names, see the description of the Class entry of an INF /// Version section. /// /// // https://docs.microsoft.com/en-us/windows/win32/api/setupapi/nf-setupapi-setupdiclassnamefromguida WINSETUPAPI BOOL // SetupDiClassNameFromGuidA( const GUID *ClassGuid, PSTR ClassName, DWORD ClassNameSize, PDWORD RequiredSize ); [DllImport(Lib_SetupAPI, SetLastError = true, CharSet = CharSet.Auto)] [PInvokeData("setupapi.h", MSDNShortId = "NF:setupapi.SetupDiClassNameFromGuidA")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool SetupDiClassNameFromGuid(in Guid ClassGuid, StringBuilder ClassName, uint ClassNameSize, out uint RequiredSize); /// The SetupDiClassNameFromGuid function retrieves the class name associated with a class GUID. /// A pointer to the class GUID for the class name to retrieve. /// /// Receives the string that contains the name of the class that is specified by the pointer in the ClassGuid parameter. /// /// /// The function returns TRUE if it is successful. Otherwise, it returns FALSE and the logged error can be retrieved /// with a call to GetLastError. /// /// Call SetupDiClassNameFromGuidEx to retrieve the name for a class on a remote computer. [PInvokeData("setupapi.h", MSDNShortId = "NF:setupapi.SetupDiClassNameFromGuidA")] public static bool SetupDiClassNameFromGuid(Guid ClassGuid, out string ClassName) => FunctionHelper.CallMethodWithStrBuf((StringBuilder sb, ref uint sz) => SetupDiClassNameFromGuid(ClassGuid, sb, sz, out sz), out ClassName); /// /// The SetupDiClassNameFromGuidEx function retrieves the class name associated with a class GUID. The class can be installed /// on a local or remote computer. /// /// The class GUID of the class name to retrieve. /// /// A pointer to a string buffer that receives the NULL-terminated name of the class for the specified GUID. /// /// The size, in characters, of the ClassName buffer. /// /// The number of characters required to store the class name (including a terminating null). RequiredSize is always less than MAX_CLASS_NAME_LEN. /// /// /// A pointer to a NULL-terminated string that contains the name of a remote system on which the class is installed. This parameter /// is optional and can be NULL. If MachineName is NULL, the local system name is used. /// /// Must be NULL. /// /// The function returns TRUE if it is successful. Otherwise, it returns FALSE and the logged error can be retrieved /// with a call to GetLastError. /// /// // https://docs.microsoft.com/en-us/windows/win32/api/setupapi/nf-setupapi-setupdiclassnamefromguidexa WINSETUPAPI BOOL // SetupDiClassNameFromGuidExA( const GUID *ClassGuid, PSTR ClassName, DWORD ClassNameSize, PDWORD RequiredSize, PCSTR MachineName, // PVOID Reserved ); [DllImport(Lib_SetupAPI, SetLastError = true, CharSet = CharSet.Auto)] [PInvokeData("setupapi.h", MSDNShortId = "NF:setupapi.SetupDiClassNameFromGuidExA")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool SetupDiClassNameFromGuidEx(in Guid ClassGuid, [Out, MarshalAs(UnmanagedType.LPTStr)] StringBuilder ClassName, uint ClassNameSize, out uint RequiredSize, [In, Optional, MarshalAs(UnmanagedType.LPTStr)] string MachineName, IntPtr Reserved = default); /// /// The SetupDiCreateDeviceInfo function creates a new device information element and adds it as a new member to the /// specified device information set. /// /// A handle to the device information set for the local computer. /// /// A pointer to a NULL-terminated string that supplies either a full device instance ID (for example, "Root*PNP0500\0000") or a /// root-enumerated device ID without the enumerator prefix and instance identifier suffix (for example, "*PNP0500"). The /// root-enumerated device identifier can be used only if the DICD_GENERATE_ID flag is specified in the CreationFlags parameter. /// /// /// A pointer to the device setup class GUID for the device. If the device setup class of the device is not known, set *ClassGuid to /// a GUID_NULL structure. /// /// /// A pointer to a NULL-terminated string that supplies the text description of the device. This pointer is optional and can be NULL. /// /// /// A handle to the top-level window to use for any user interface that is related to installing the device. This handle is optional /// and can be NULL. /// /// /// /// A variable of type DWORD that controls how the device information element is created. Can be a combination of the following values: /// /// DICD_GENERATE_ID /// /// If this flag is specified, DeviceName contains only a Root-enumerated device ID and the system uses that ID to generate a full /// device instance ID for the new device information element. /// /// /// Call SetupDiGetDeviceInstanceId to retrieve the device instance ID that was generated for this device information element. /// /// DICD_INHERIT_CLASSDRVS /// /// If this flag is specified, the resulting device information element inherits the class driver list, if any, associated with the /// device information set. In addition, if there is a selected driver for the device information set, that same driver is selected /// for the new device information element. /// /// /// /// A pointer to a SP_DEVINFO_DATA structure that receives the new device information element. This pointer is optional and can be /// NULL. If the structure is supplied, the caller must set the cbSize member of this structure to sizeof( /// SP_DEVINFO_DATA ) before calling the function. For more information, see the following Remarks section. /// /// /// The function returns TRUE if it is successful. Otherwise, it returns FALSE and the logged error can be retrieved /// by making a call to GetLastError. /// /// /// The caller of this function must be a member of the Administrators group. /// /// If this device instance is being added to a set that has an associated class, the device class must be the same or the call /// fails. In this case, a call to GetLastError returns ERROR_CLASS_MISMATCH. /// /// /// If the specified device instance is the same as an existing device instance key in the registry, the call fails. In this case, a /// call to GetLastError returns ERROR_DEVINST_ALREADY_EXISTS. This occurs only if the DICD_GENERATE_ID flag is not set. /// /// /// If the new device information element was successfully created but the caller-supplied DeviceInfoData buffer is invalid, the /// function returns FALSE. In this case, a call to GetLastError returns ERROR_INVALID_USER_BUFFER. However, the device /// information element will have been added as a new member of the set already. /// /// The DeviceInfoSet must only contain elements on the local computer. /// // https://docs.microsoft.com/en-us/windows/win32/api/setupapi/nf-setupapi-setupdicreatedeviceinfoa WINSETUPAPI BOOL // SetupDiCreateDeviceInfoA( HDEVINFO DeviceInfoSet, PCSTR DeviceName, const GUID *ClassGuid, PCSTR DeviceDescription, HWND // hwndParent, DWORD CreationFlags, PSP_DEVINFO_DATA DeviceInfoData ); [DllImport(Lib_SetupAPI, SetLastError = true, CharSet = CharSet.Auto)] [PInvokeData("setupapi.h", MSDNShortId = "NF:setupapi.SetupDiCreateDeviceInfoA")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool SetupDiCreateDeviceInfo(HDEVINFO DeviceInfoSet, [In, MarshalAs(UnmanagedType.LPTStr)] string DeviceName, in Guid ClassGuid, [In, Optional, MarshalAs(UnmanagedType.LPTStr)] string DeviceDescription, [In, Optional] HWND hwndParent, DICD CreationFlags, ref SP_DEVINFO_DATA DeviceInfoData); /// /// The SetupDiCreateDeviceInfo function creates a new device information element and adds it as a new member to the /// specified device information set. /// /// A handle to the device information set for the local computer. /// /// A pointer to a NULL-terminated string that supplies either a full device instance ID (for example, "Root*PNP0500\0000") or a /// root-enumerated device ID without the enumerator prefix and instance identifier suffix (for example, "*PNP0500"). The /// root-enumerated device identifier can be used only if the DICD_GENERATE_ID flag is specified in the CreationFlags parameter. /// /// /// A pointer to the device setup class GUID for the device. If the device setup class of the device is not known, set *ClassGuid to /// a GUID_NULL structure. /// /// /// A pointer to a NULL-terminated string that supplies the text description of the device. This pointer is optional and can be NULL. /// /// /// A handle to the top-level window to use for any user interface that is related to installing the device. This handle is optional /// and can be NULL. /// /// /// /// A variable of type DWORD that controls how the device information element is created. Can be a combination of the following values: /// /// DICD_GENERATE_ID /// /// If this flag is specified, DeviceName contains only a Root-enumerated device ID and the system uses that ID to generate a full /// device instance ID for the new device information element. /// /// /// Call SetupDiGetDeviceInstanceId to retrieve the device instance ID that was generated for this device information element. /// /// DICD_INHERIT_CLASSDRVS /// /// If this flag is specified, the resulting device information element inherits the class driver list, if any, associated with the /// device information set. In addition, if there is a selected driver for the device information set, that same driver is selected /// for the new device information element. /// /// /// /// A pointer to a SP_DEVINFO_DATA structure that receives the new device information element. This pointer is optional and can be /// NULL. If the structure is supplied, the caller must set the cbSize member of this structure to sizeof( /// SP_DEVINFO_DATA ) before calling the function. For more information, see the following Remarks section. /// /// /// The function returns TRUE if it is successful. Otherwise, it returns FALSE and the logged error can be retrieved /// by making a call to GetLastError. /// /// /// The caller of this function must be a member of the Administrators group. /// /// If this device instance is being added to a set that has an associated class, the device class must be the same or the call /// fails. In this case, a call to GetLastError returns ERROR_CLASS_MISMATCH. /// /// /// If the specified device instance is the same as an existing device instance key in the registry, the call fails. In this case, a /// call to GetLastError returns ERROR_DEVINST_ALREADY_EXISTS. This occurs only if the DICD_GENERATE_ID flag is not set. /// /// /// If the new device information element was successfully created but the caller-supplied DeviceInfoData buffer is invalid, the /// function returns FALSE. In this case, a call to GetLastError returns ERROR_INVALID_USER_BUFFER. However, the device /// information element will have been added as a new member of the set already. /// /// The DeviceInfoSet must only contain elements on the local computer. /// // https://docs.microsoft.com/en-us/windows/win32/api/setupapi/nf-setupapi-setupdicreatedeviceinfoa WINSETUPAPI BOOL // SetupDiCreateDeviceInfoA( HDEVINFO DeviceInfoSet, PCSTR DeviceName, const GUID *ClassGuid, PCSTR DeviceDescription, HWND // hwndParent, DWORD CreationFlags, PSP_DEVINFO_DATA DeviceInfoData ); [DllImport(Lib_SetupAPI, SetLastError = true, CharSet = CharSet.Auto)] [PInvokeData("setupapi.h", MSDNShortId = "NF:setupapi.SetupDiCreateDeviceInfoA")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool SetupDiCreateDeviceInfo(HDEVINFO DeviceInfoSet, [In, MarshalAs(UnmanagedType.LPTStr)] string DeviceName, in Guid ClassGuid, [In, Optional, MarshalAs(UnmanagedType.LPTStr)] string DeviceDescription, [In, Optional] HWND hwndParent, DICD CreationFlags, IntPtr DeviceInfoData = default); /// /// The SetupDiCreateDeviceInfoList function creates an empty device information set and optionally associates the set with a /// device setup class and a top-level window. /// /// /// A pointer to the GUID of the device setup class to associate with the newly created device information set. If this /// parameter is specified, only devices of this class can be included in this device information set. If this parameter is set to /// NULL, the device information set is not associated with a specific device setup class. /// /// /// A handle to the top-level window to use for any user interface that is related to non-device-specific actions (such as a /// select-device dialog box that uses the global class driver list). This handle is optional and can be NULL. If a specific /// top-level window is not required, set hwndParent to NULL. /// /// /// The function returns a handle to an empty device information set if it is successful. Otherwise, it returns /// INVALID_HANDLE_VALUE. To get extended error information, call GetLastError. /// /// /// The caller of this function must delete the returned device information set when it is no longer needed by calling SetupDiDestroyDeviceInfoList. /// To create a device information list for a remote computer use SetupDiCreateDeviceInfoListEx. /// // https://docs.microsoft.com/en-us/windows/win32/api/setupapi/nf-setupapi-setupdicreatedeviceinfolist WINSETUPAPI HDEVINFO // SetupDiCreateDeviceInfoList( const GUID *ClassGuid, HWND hwndParent ); [DllImport(Lib_SetupAPI, SetLastError = true, ExactSpelling = true)] [PInvokeData("setupapi.h", MSDNShortId = "NF:setupapi.SetupDiCreateDeviceInfoList")] public static extern SafeHDEVINFO SetupDiCreateDeviceInfoList(in Guid ClassGuid, [In, Optional] HWND hwndParent); /// /// The SetupDiCreateDeviceInfoList function creates an empty device information set and optionally associates the set with a /// device setup class and a top-level window. /// /// /// A pointer to the GUID of the device setup class to associate with the newly created device information set. If this /// parameter is specified, only devices of this class can be included in this device information set. If this parameter is set to /// NULL, the device information set is not associated with a specific device setup class. /// /// /// A handle to the top-level window to use for any user interface that is related to non-device-specific actions (such as a /// select-device dialog box that uses the global class driver list). This handle is optional and can be NULL. If a specific /// top-level window is not required, set hwndParent to NULL. /// /// /// The function returns a handle to an empty device information set if it is successful. Otherwise, it returns /// INVALID_HANDLE_VALUE. To get extended error information, call GetLastError. /// /// /// The caller of this function must delete the returned device information set when it is no longer needed by calling SetupDiDestroyDeviceInfoList. /// To create a device information list for a remote computer use SetupDiCreateDeviceInfoListEx. /// // https://docs.microsoft.com/en-us/windows/win32/api/setupapi/nf-setupapi-setupdicreatedeviceinfolist WINSETUPAPI HDEVINFO // SetupDiCreateDeviceInfoList( const GUID *ClassGuid, HWND hwndParent ); [DllImport(Lib_SetupAPI, SetLastError = true, ExactSpelling = true)] [PInvokeData("setupapi.h", MSDNShortId = "NF:setupapi.SetupDiCreateDeviceInfoList")] public static extern SafeHDEVINFO SetupDiCreateDeviceInfoList([In, Optional] IntPtr ClassGuid, [In, Optional] HWND hwndParent); /// /// The SetupDiCreateDeviceInfoList function creates an empty device information set on a remote or a local computer and /// optionally associates the set with a device setup class . /// /// /// A pointer to the GUID of the device setup class to associate with the newly created device information set. If this parameter is /// specified, only devices of this class can be included in this device information set. If this parameter is set to NULL, /// the device information set is not associated with a specific device setup class. /// /// /// A handle to the top-level window to use for any user interface that is related to non-device-specific actions (such as a /// select-device dialog box that uses the global class driver list). This handle is optional and can be NULL. If a specific /// top-level window is not required, set hwndParent to NULL. /// /// /// A pointer to a NULL-terminated string that contains the name of a computer on a network. If a name is specified, only devices on /// that computer can be created and opened in this device information set. If this parameter is set to NULL, the device /// information set is for devices on the local computer. /// /// Must be NULL. /// /// The function returns a handle to an empty device information set if it is successful. Otherwise, it returns /// INVALID_HANDLE_VALUE. To get extended error information, call GetLastError. /// /// /// The caller of this function must delete the returned device information set when it is no longer needed by calling SetupDiDestroyDeviceInfoList. /// /// If the device information set is for devices on a remote computer (MachineName is not NULL), all subsequent operations on /// this set or any of its elements must use routines that support device information sets with remote elements. The SetupDi /// Xxx routines that do not provide this support, such as SetupDiCallClassInstaller, have a statement to that effect in their /// reference page. /// /// // https://docs.microsoft.com/en-us/windows/win32/api/setupapi/nf-setupapi-setupdicreatedeviceinfolistexa WINSETUPAPI HDEVINFO // SetupDiCreateDeviceInfoListExA( const GUID *ClassGuid, HWND hwndParent, PCSTR MachineName, PVOID Reserved ); [DllImport(Lib_SetupAPI, SetLastError = true, CharSet = CharSet.Auto)] [PInvokeData("setupapi.h", MSDNShortId = "NF:setupapi.SetupDiCreateDeviceInfoListExA")] public static extern SafeHDEVINFO SetupDiCreateDeviceInfoListEx(in Guid ClassGuid, [In, Optional] HWND hwndParent, [In, Optional, MarshalAs(UnmanagedType.LPTStr)] string MachineName, [In, Optional] IntPtr Reserved); /// /// The SetupDiCreateDeviceInfoList function creates an empty device information set on a remote or a local computer and /// optionally associates the set with a device setup class . /// /// /// A pointer to the GUID of the device setup class to associate with the newly created device information set. If this parameter is /// specified, only devices of this class can be included in this device information set. If this parameter is set to NULL, /// the device information set is not associated with a specific device setup class. /// /// /// A handle to the top-level window to use for any user interface that is related to non-device-specific actions (such as a /// select-device dialog box that uses the global class driver list). This handle is optional and can be NULL. If a specific /// top-level window is not required, set hwndParent to NULL. /// /// /// A pointer to a NULL-terminated string that contains the name of a computer on a network. If a name is specified, only devices on /// that computer can be created and opened in this device information set. If this parameter is set to NULL, the device /// information set is for devices on the local computer. /// /// Must be NULL. /// /// The function returns a handle to an empty device information set if it is successful. Otherwise, it returns /// INVALID_HANDLE_VALUE. To get extended error information, call GetLastError. /// /// /// The caller of this function must delete the returned device information set when it is no longer needed by calling SetupDiDestroyDeviceInfoList. /// /// If the device information set is for devices on a remote computer (MachineName is not NULL), all subsequent operations on /// this set or any of its elements must use routines that support device information sets with remote elements. The SetupDi /// Xxx routines that do not provide this support, such as SetupDiCallClassInstaller, have a statement to that effect in their /// reference page. /// /// // https://docs.microsoft.com/en-us/windows/win32/api/setupapi/nf-setupapi-setupdicreatedeviceinfolistexa WINSETUPAPI HDEVINFO // SetupDiCreateDeviceInfoListExA( const GUID *ClassGuid, HWND hwndParent, PCSTR MachineName, PVOID Reserved ); [DllImport(Lib_SetupAPI, SetLastError = true, CharSet = CharSet.Auto)] [PInvokeData("setupapi.h", MSDNShortId = "NF:setupapi.SetupDiCreateDeviceInfoListExA")] public static extern SafeHDEVINFO SetupDiCreateDeviceInfoListEx([In, Optional] IntPtr ClassGuid, [In, Optional] HWND hwndParent, [In, Optional, MarshalAs(UnmanagedType.LPTStr)] string MachineName, [In, Optional] IntPtr Reserved); /// The SetupDiCreateDeviceInterface function registers a device interface on a local system or a remote system. /// /// A handle to a device information set. This set contains a device information element that represents the device for which to /// register an interface. This handle is typically returned by SetupDiGetClassDevs. /// /// A pointer to an SP_DEVINFO_DATA structure that specifies the device information element in DeviceInfoSet. /// A pointer to a class GUID that specifies the interface class for the new interface. /// /// A pointer to a NULL-terminated string that supplies a reference string. This pointer is optional and can be NULL. /// Reference strings are used only by a few bus drivers that use device interfaces as placeholders for software devices that are /// created on demand. /// /// Reserved. Must be zero. /// /// A pointer to a caller-initialized SP_DEVICE_INTERFACE_DATA structure to receive information about the new device interface. This /// pointer is optional and can be NULL. If the structure is supplied, the caller must set the cbSize member of this /// structure to sizeof( SP_DEVICE_INTERFACE_DATA ) before calling this function. For more information, see the /// following Remarks section. /// /// /// SetupDiCreateDeviceInterface returns TRUE if the function completed without error. If the function completed with /// an error, it returns FALSE and the error code for the failure can be retrieved by calling GetLastError. /// /// /// The caller of this function must be a member of the Administrators group. /// /// SetupDiCreateDeviceInterface registers an interface for a device. If a device has more than one interface, call this /// function once for each interface being registered. /// /// /// If this function successfully registers an interface for the device that corresponds to the specified device information /// element, it also adds the interface to the interface list that is associated with the device information element in the /// specified device information set. /// /// /// Before a registered interface can be used by applications and other system components the interface must be enabled by the /// driver for the device. /// /// /// This function creates a registry key for the new device interface. Callers of this function can access nonvolatile storage under /// this key using SetupDiOpenDeviceInterfaceRegKey. /// /// /// If SetupDiCreateDeviceInterface successfully creates a new device interface, but the caller-supplied buffer in the /// DeviceInterfaceData parameter is invalid, this function will return FALSE and a subsequent call to GetLastError will /// return ERROR_INVALID_USER_BUFFER. However, the function does create and register the new device interface. /// /// // https://docs.microsoft.com/en-us/windows/win32/api/setupapi/nf-setupapi-setupdicreatedeviceinterfacea WINSETUPAPI BOOL // SetupDiCreateDeviceInterfaceA( HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, const GUID *InterfaceClassGuid, PCSTR // ReferenceString, DWORD CreationFlags, PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData ); [DllImport(Lib_SetupAPI, SetLastError = true, CharSet = CharSet.Auto)] [PInvokeData("setupapi.h", MSDNShortId = "NF:setupapi.SetupDiCreateDeviceInterfaceA")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool SetupDiCreateDeviceInterface(HDEVINFO DeviceInfoSet, in SP_DEVINFO_DATA DeviceInfoData, in Guid InterfaceClassGuid, [In, Optional, MarshalAs(UnmanagedType.LPTStr)] string ReferenceString, [In, Optional] uint CreationFlags, ref SP_DEVICE_INTERFACE_DATA DeviceInterfaceData); /// The SetupDiCreateDeviceInterface function registers a device interface on a local system or a remote system. /// /// A handle to a device information set. This set contains a device information element that represents the device for which to /// register an interface. This handle is typically returned by SetupDiGetClassDevs. /// /// A pointer to an SP_DEVINFO_DATA structure that specifies the device information element in DeviceInfoSet. /// A pointer to a class GUID that specifies the interface class for the new interface. /// /// A pointer to a NULL-terminated string that supplies a reference string. This pointer is optional and can be NULL. /// Reference strings are used only by a few bus drivers that use device interfaces as placeholders for software devices that are /// created on demand. /// /// Reserved. Must be zero. /// /// A pointer to a caller-initialized SP_DEVICE_INTERFACE_DATA structure to receive information about the new device interface. This /// pointer is optional and can be NULL. If the structure is supplied, the caller must set the cbSize member of this /// structure to sizeof( SP_DEVICE_INTERFACE_DATA ) before calling this function. For more information, see the /// following Remarks section. /// /// /// SetupDiCreateDeviceInterface returns TRUE if the function completed without error. If the function completed with /// an error, it returns FALSE and the error code for the failure can be retrieved by calling GetLastError. /// /// /// The caller of this function must be a member of the Administrators group. /// /// SetupDiCreateDeviceInterface registers an interface for a device. If a device has more than one interface, call this /// function once for each interface being registered. /// /// /// If this function successfully registers an interface for the device that corresponds to the specified device information /// element, it also adds the interface to the interface list that is associated with the device information element in the /// specified device information set. /// /// /// Before a registered interface can be used by applications and other system components the interface must be enabled by the /// driver for the device. /// /// /// This function creates a registry key for the new device interface. Callers of this function can access nonvolatile storage under /// this key using SetupDiOpenDeviceInterfaceRegKey. /// /// /// If SetupDiCreateDeviceInterface successfully creates a new device interface, but the caller-supplied buffer in the /// DeviceInterfaceData parameter is invalid, this function will return FALSE and a subsequent call to GetLastError will /// return ERROR_INVALID_USER_BUFFER. However, the function does create and register the new device interface. /// /// // https://docs.microsoft.com/en-us/windows/win32/api/setupapi/nf-setupapi-setupdicreatedeviceinterfacea WINSETUPAPI BOOL // SetupDiCreateDeviceInterfaceA( HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, const GUID *InterfaceClassGuid, PCSTR // ReferenceString, DWORD CreationFlags, PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData ); [DllImport(Lib_SetupAPI, SetLastError = true, CharSet = CharSet.Auto)] [PInvokeData("setupapi.h", MSDNShortId = "NF:setupapi.SetupDiCreateDeviceInterfaceA")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool SetupDiCreateDeviceInterface(HDEVINFO DeviceInfoSet, in SP_DEVINFO_DATA DeviceInfoData, in Guid InterfaceClassGuid, [In, Optional, MarshalAs(UnmanagedType.LPTStr)] string ReferenceString, uint CreationFlags = 0, IntPtr DeviceInterfaceData = default); /// /// The SetupDiCreateDeviceInterfaceRegKey function creates a registry key for storing information about a device interface /// and returns a handle to the key. /// /// /// A handle to a device information set that contains the interface for which to create a registry key. The device information set /// must not contain remote elements. /// /// /// A pointer to an SP_DEVICE_INTERFACE_DATA structure that specifies the device interface in DeviceInfoSet. This pointer is /// possibly returned by SetupDiCreateDeviceInterface. /// /// Reserved. Must be zero. /// /// The registry security access that the caller requests for the key that is being created. For information about registry security /// access values of type REGSAM, see the Microsoft Windows SDK documentation. /// /// /// The handle to an open INF file that contains a DDInstall section to be executed for the newly-created key. This parameter is /// optional and can be NULL. If this parameter is not NULL, InfSectionName must be specified as well. /// /// /// A pointer to the name of an INF DDInstall section in the INF file that is specified by InfHandle. This section is executed for /// the newly created key. This parameter is optional and can be NULL. If this parameter is specified, InfHandle must be /// specified as well. /// /// /// If SetupDiCreateDeviceInterfaceRegKey succeeds, the function returns a handle to the requested registry key in which /// interface information can be stored and retrieved. If SetupDiCreateDeviceInterfaceRegKey fails, the function returns /// INVALID_HANDLE_VALUE. Call GetLastError to get extended error information. /// /// /// The caller of this function must be a member of the Administrators group. /// /// If the requested key for the device interface already exists, SetupDiCreateDeviceInterfaceRegKey returns a handle to that /// key; otherwise, SetupDiCreateDeviceInterfaceRegKey creates a new nonvolatile registry key for the specified device /// interface. Callers of this function can store private configuration data for the device interface in this key. The driver for /// the device can access this key using Io Xxx routines. /// /// Close the handle returned from this function by calling RegCloseKey. /// /// For installations that use layout files (specified by the LayoutFile entry in an INF Version section), the layout file /// must be opened by a call to SetupOpenAppendInfFile (described in Windows SDK documentation) before /// SetupDiCreateDeviceInterfaceRegKey is called. /// /// The device information set specified by DeviceInfoSet must only contain elements on the local computer. /// // https://docs.microsoft.com/en-us/windows/win32/api/setupapi/nf-setupapi-setupdicreatedeviceinterfaceregkeya WINSETUPAPI HKEY // SetupDiCreateDeviceInterfaceRegKeyA( HDEVINFO DeviceInfoSet, PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData, DWORD Reserved, // REGSAM samDesired, HINF InfHandle, PCSTR InfSectionName ); [DllImport(Lib_SetupAPI, SetLastError = true, CharSet = CharSet.Auto)] [PInvokeData("setupapi.h", MSDNShortId = "NF:setupapi.SetupDiCreateDeviceInterfaceRegKeyA")] public static extern SafeRegistryHandle SetupDiCreateDeviceInterfaceRegKey(HDEVINFO DeviceInfoSet, in SP_DEVICE_INTERFACE_DATA DeviceInterfaceData, [Optional] uint Reserved, System.Security.AccessControl.RegistryRights samDesired, [In, Optional] HINF InfHandle, [In, Optional, MarshalAs(UnmanagedType.LPTStr)] string InfSectionName); /// /// The SetupDiCreateDevRegKey function creates a registry key for device-specific configuration information and returns a /// handle to the key. /// /// /// A handle to a device information set that contains a device information element that represents the device for which to create a /// registry key. /// /// A pointer to an SP_DEVINFO_DATA structure that specifies the device information element in DeviceInfoSet. /// /// /// The scope of the registry key to be created. The scope determines where the information is stored. The key created can be global /// or hardware profile-specific. Can be one of the following values: /// /// DICS_FLAG_GLOBAL /// /// Create a key to store global configuration information. This information is not specific to a particular hardware profile. On /// NT-based operating systems this creates a key that is rooted at HKEY_LOCAL_MACHINE. The exact key opened depends on the /// value of the KeyType parameter. /// /// DICS_FLAG_CONFIGSPECIFIC /// /// Create a key to store hardware profile-specific configuration information. This key is rooted at one of the hardware-profile /// specific branches, instead of HKEY_LOCAL_MACHINE. /// /// /// /// The hardware profile for which to create a key if HwProfileFlags is set to SPDICS_FLAG_CONFIGSPECIFIC. If HwProfile is 0, the /// key for the current hardware profile is created. If HwProfileFlags is SPDICS_FLAG_GLOBAL, HwProfile is ignored. /// /// /// The type of registry storage key to create. Can be one of the following values: /// DIREG_DEV /// Create a hardware key for the device. /// DIREG_DRV /// Create a software key for the device. /// /// /// The handle to an open INF file that contains an INF DDInstall section to be executed for the newly created key. This parameter /// is optional and can be NULL. If this parameter is specified, InfSectionName must be specified as well. /// /// /// The name of an INF DDInstall section in the INF file specified by InfHandle. This section is executed for the newly created key. /// This parameter is optional and can be NULL. If this parameter is specified, InfHandle must be specified as well. /// /// /// If SetupDiCreateDevRegKey succeeds, the function returns a handle to the specified registry key in which device-specific /// configuration data can be stored and retrieved. If SetupDiCreateDevRegKey fails, the function returns /// INVALID_HANDLE_VALUE. Call GetLastError to get extended error information. /// /// /// The caller of SetupDiCreateDevRegKey must be a member of the Administrators group. /// Close the handle returned from SetupDiCreateDevRegKey by calling RegCloseKey. /// /// If the specified key already exists, SetupDiCreateDevRegKey returns a handle to that key. Otherwise, /// SetupDiCreateDevRegKey creates the specified key and returns a handle to the new key. For Windows Server 2003 and later /// versions of Windows, the key handle has KEY_READ and KEY_WRITE access only. For previous Windows versions, this handle has /// KEY_ALL_ACCESS access. /// /// /// The specified device instance must be registered before SetupDiCreateDevRegKey is called. Note, however, that the /// operating system automatically registers PnP device instances. For information about how to register non-PnP device instances, /// see SetupDiRegisterDeviceInfo. /// /// /// For installations that use layout files (specified by the LayoutFile entry in an INF Version section), the layout file /// must be opened by a call to SetupOpenAppendInfFile (described in the Microsoft Windows SDK documentation) before /// SetupDiCreateDevRegKey is called. /// /// /// If the supplied device information set contains device information elements for a remote system, and InfHandle and /// InfSectionName are also specified, the create request will fail, and a subsequent call to GetLastError will return ERROR_REMOTE_REQUEST_UNSUPPORTED. /// /// // https://docs.microsoft.com/en-us/windows/win32/api/setupapi/nf-setupapi-setupdicreatedevregkeya WINSETUPAPI HKEY // SetupDiCreateDevRegKeyA( HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, DWORD Scope, DWORD HwProfile, DWORD KeyType, // HINF InfHandle, PCSTR InfSectionName ); [DllImport(Lib_SetupAPI, SetLastError = true, CharSet = CharSet.Auto)] [PInvokeData("setupapi.h", MSDNShortId = "NF:setupapi.SetupDiCreateDevRegKeyA")] public static extern SafeRegistryHandle SetupDiCreateDevRegKey(HDEVINFO DeviceInfoSet, in SP_DEVINFO_DATA DeviceInfoData, DICS_FLAG Scope, uint HwProfile, DIREG KeyType, [In, Optional] HINF InfHandle, [In, Optional, MarshalAs(UnmanagedType.LPTStr)] string InfSectionName); /// /// The SetupDiDeleteDeviceInfo function deletes a device information element from a device information set. This function /// does not delete the actual device. /// /// A handle to the device information set that contains the device information element to delete. /// /// A pointer to an SP_DEVINFO_DATA structure that represents the device information element in DeviceInfoSet to delete. /// /// /// The function returns TRUE if it is successful. Otherwise, it returns FALSE and the logged error can be retrieved /// with a call to GetLastError. /// /// /// If the specified device information element is in use (for example, by a wizard page), the function fails. In this case, a call /// to GetLastError returns ERROR_DEVINFO_DATA_LOCKED. This happens if a handle to a wizard page is retrieved with a call to /// SetupDiGetWizardPage with this device information element specified and the DIWP_FLAG_USE_DEVINFO_DATA flag set. To delete this /// device information element, you must first close the wizard's HPROPSHEETPAGE handle. /// // https://docs.microsoft.com/en-us/windows/win32/api/setupapi/nf-setupapi-setupdideletedeviceinfo WINSETUPAPI BOOL // SetupDiDeleteDeviceInfo( HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData ); [DllImport(Lib_SetupAPI, SetLastError = true, ExactSpelling = true)] [PInvokeData("setupapi.h", MSDNShortId = "NF:setupapi.SetupDiDeleteDeviceInfo")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool SetupDiDeleteDeviceInfo(HDEVINFO DeviceInfoSet, in SP_DEVINFO_DATA DeviceInfoData); /// The SetupDiDeleteDeviceInterfaceData function deletes a device interface from a device information set. /// /// A pointer to the device information set that contains the interface to delete. This handle is typically returned by SetupDiGetClassDevs. /// /// /// A pointer to an SP_DEVICE_INTERFACE_DATA structure that specifies the interface in DeviceInfoSet to delete. This structure is /// typically returned by SetupDiEnumDeviceInterfaces. /// /// /// SetupDiDeleteDeviceInterfaceData returns TRUE if the function completed without error. If the function completed /// with an error, it returns FALSE and the error code for the failure can be retrieved by calling GetLastError. /// /// /// SetupDiDeleteDeviceInterfaceData deletes a device interface element from a device information set. This function has no /// effect on the device interface or the underlying device. /// // https://docs.microsoft.com/en-us/windows/win32/api/setupapi/nf-setupapi-setupdideletedeviceinterfacedata WINSETUPAPI BOOL // SetupDiDeleteDeviceInterfaceData( HDEVINFO DeviceInfoSet, PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData ); [DllImport(Lib_SetupAPI, SetLastError = true, ExactSpelling = true)] [PInvokeData("setupapi.h", MSDNShortId = "NF:setupapi.SetupDiDeleteDeviceInterfaceData")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool SetupDiDeleteDeviceInterfaceData(HDEVINFO DeviceInfoSet, in SP_DEVICE_INTERFACE_DATA DeviceInterfaceData); /// /// The SetupDiDeleteDeviceInterfaceRegKey function deletes the registry subkey that is used by applications and drivers to /// store interface-specific information. /// /// /// A pointer to a device information set that contains the interface for which to delete interface-specific information in the /// registry. The device information set must not contain remote elements. /// /// /// A pointer to an SP_DEVICE_INTERFACE_DATA structure that specifies the device interface in DeviceInfoSet. This pointer is /// possibly returned by SetupDiCreateDeviceInterface or SetupDiEnumDeviceInterfaces. /// /// Reserved. Must be zero. /// /// SetupDiDeleteDeviceInterfaceRegKey returns TRUE if it is successful; otherwise, it returns FALSE and the /// logged error can be retrieved with a call to GetLastError. /// /// /// The caller of this function must be a member of the Administrators group. /// /// SetupDiDeleteDeviceInterfaceRegKey deletes the subkey used by drivers and applications to store information about the /// device interface instance. This subkey was created by SetupDiCreateDeviceInterfaceRegKey or by the driver's call to an /// associated I/O manager routine. SetupDiDeleteDeviceInterfaceRegKey does not affect the main registry key for the device /// interface instance nor any other subkeys that may have been created. /// /// The DeviceInfoSet must only contain elements on the local computer. /// // https://docs.microsoft.com/en-us/windows/win32/api/setupapi/nf-setupapi-setupdideletedeviceinterfaceregkey WINSETUPAPI BOOL // SetupDiDeleteDeviceInterfaceRegKey( HDEVINFO DeviceInfoSet, PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData, DWORD Reserved ); [DllImport(Lib_SetupAPI, SetLastError = true, ExactSpelling = true)] [PInvokeData("setupapi.h", MSDNShortId = "NF:setupapi.SetupDiDeleteDeviceInterfaceRegKey")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool SetupDiDeleteDeviceInterfaceRegKey(HDEVINFO DeviceInfoSet, in SP_DEVICE_INTERFACE_DATA DeviceInterfaceData, uint Reserved = 0); /// /// The SetupDiDeleteDevRegKey function deletes specified user-accessible registry keys that are associated with a device /// information element. /// /// /// A handle to the device information set that contains a device information element that represents the device for which to delete /// registry keys. The device information set must not contain remote elements. /// /// A pointer to an SP_DEVINFO_DATA structure that specifies the device information element in DeviceInfoSet. /// /// /// The scope of the registry key to delete. The scope indicates where the information is located. The key can be global or hardware /// profile-specific. Can be one of the following values: /// /// DICS_FLAG_GLOBAL /// Delete the key that stores global configuration information. /// DICS_FLAG_CONFIGSPECIFIC /// Delete the key that stores hardware profile-specific configuration information. /// /// /// If Scope is set to DICS_FLAG_CONFIGSPECIFIC, the HwProfile parameter specifies the hardware profile for which to delete the /// registry key. If HwProfile is 0, the key for the current hardware profile is deleted. If HwProfile is 0xFFFFFFFF, the registry /// key for all hardware profiles is deleted. /// /// /// The type of registry storage key to delete. Can be one of the following values: /// DIREG_DEV /// Delete the device's hardware key. /// DIREG_DRV /// Delete the device's software key. /// DIREG_BOTH /// Delete both the hardware and software keys for the device. /// /// /// The function returns TRUE if it is successful. Otherwise, it returns FALSE and the logged error can be retrieved /// with a call to GetLastError. /// /// /// The caller of this function must be a member of the Administrators group. /// The DeviceInfoSet must only contain elements on the local computer. /// // https://docs.microsoft.com/en-us/windows/win32/api/setupapi/nf-setupapi-setupdideletedevregkey WINSETUPAPI BOOL // SetupDiDeleteDevRegKey( HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, DWORD Scope, DWORD HwProfile, DWORD KeyType ); [DllImport(Lib_SetupAPI, SetLastError = true, ExactSpelling = true)] [PInvokeData("setupapi.h", MSDNShortId = "NF:setupapi.SetupDiDeleteDevRegKey")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool SetupDiDeleteDevRegKey(HDEVINFO DeviceInfoSet, in SP_DEVINFO_DATA DeviceInfoData, DICS_FLAG Scope, uint HwProfile, DIREG KeyType); /// /// The SetupDiDestroyClassImageList function destroys a class image list that was built by a call to /// SetupDiGetClassImageList or SetupDiGetClassImageListEx. /// /// A pointer to an SP_CLASSIMAGELIST_DATA structure that contains the class image list to destroy. /// /// The function returns TRUE if it is successful. Otherwise, it returns FALSE and the logged error can be retrieved /// by a call to GetLastError. /// // https://docs.microsoft.com/en-us/windows/win32/api/setupapi/nf-setupapi-setupdidestroyclassimagelist WINSETUPAPI BOOL // SetupDiDestroyClassImageList( PSP_CLASSIMAGELIST_DATA ClassImageListData ); [DllImport(Lib_SetupAPI, SetLastError = true, ExactSpelling = true)] [PInvokeData("setupapi.h", MSDNShortId = "NF:setupapi.SetupDiDestroyClassImageList")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool SetupDiDestroyClassImageList(in SP_CLASSIMAGELIST_DATA ClassImageListData); /// The SetupDiDestroyDeviceInfoList function deletes a device information set and frees all associated memory. /// A handle to the device information set to delete. /// /// The function returns TRUE if it is successful. Otherwise, it returns FALSE and the logged error can be retrieved /// with a call to GetLastError. /// // https://docs.microsoft.com/en-us/windows/win32/api/setupapi/nf-setupapi-setupdidestroydeviceinfolist WINSETUPAPI BOOL // SetupDiDestroyDeviceInfoList( HDEVINFO DeviceInfoSet ); [DllImport(Lib_SetupAPI, SetLastError = true, ExactSpelling = true)] [PInvokeData("setupapi.h", MSDNShortId = "NF:setupapi.SetupDiDestroyDeviceInfoList")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool SetupDiDestroyDeviceInfoList(HDEVINFO DeviceInfoSet); /// The SetupDiDestroyDriverInfoList function deletes a driver list. /// A handle to a device information set that contains the driver list to delete. /// /// A pointer to an SP_DEVINFO_DATA structure that specifies the device information element in DeviceInfoSet. This parameter is /// optional and can be set to NULL. If this parameter is specified, SetupDiDestroyDriverInfoList deletes the driver /// list for the specified device. If this parameter is NULL, SetupDiDestroyDriverInfoList deletes the global class /// driver list that is associated with DeviceInfoSet. /// /// /// The type of driver list to delete, which must be one of the following values: /// SPDIT_CLASSDRIVER /// Delete a list of class drivers. If DeviceInfoData is NULL, this driver list type must be specified. /// SPDIT_COMPATDRIVER /// /// Delete a list of compatible drivers for the specified device. DeviceInfoData must be specified if this driver list type is specified. /// /// /// /// The function returns TRUE if it is successful. Otherwise, it returns FALSE and the logged error can be retrieved /// with a call to GetLastError. /// /// /// If the currently selected driver is a member of the list being deleted, the selection is reset. /// /// If a class driver list is being deleted, the DI_FLAGSEX_DIDINFOLIST and DI_DIDCLASS flags are reset for the corresponding device /// information set or device information element. The DI_MULTMFGS flags is also reset. /// /// /// If a compatible driver list is being destroyed, the DI_FLAGSEX_DIDCOMPATINFO and DI_DIDCOMPAT flags are reset for the /// corresponding device information element. /// /// // https://docs.microsoft.com/en-us/windows/win32/api/setupapi/nf-setupapi-setupdidestroydriverinfolist WINSETUPAPI BOOL // SetupDiDestroyDriverInfoList( HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, DWORD DriverType ); [DllImport(Lib_SetupAPI, SetLastError = true, ExactSpelling = true)] [PInvokeData("setupapi.h", MSDNShortId = "NF:setupapi.SetupDiDestroyDriverInfoList")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool SetupDiDestroyDriverInfoList(HDEVINFO DeviceInfoSet, in SP_DEVINFO_DATA DeviceInfoData, SPDIT DriverType); /// The SetupDiDestroyDriverInfoList function deletes a driver list. /// A handle to a device information set that contains the driver list to delete. /// /// A pointer to an SP_DEVINFO_DATA structure that specifies the device information element in DeviceInfoSet. This parameter is /// optional and can be set to NULL. If this parameter is specified, SetupDiDestroyDriverInfoList deletes the driver /// list for the specified device. If this parameter is NULL, SetupDiDestroyDriverInfoList deletes the global class /// driver list that is associated with DeviceInfoSet. /// /// /// The type of driver list to delete, which must be one of the following values: /// SPDIT_CLASSDRIVER /// Delete a list of class drivers. If DeviceInfoData is NULL, this driver list type must be specified. /// SPDIT_COMPATDRIVER /// /// Delete a list of compatible drivers for the specified device. DeviceInfoData must be specified if this driver list type is specified. /// /// /// /// The function returns TRUE if it is successful. Otherwise, it returns FALSE and the logged error can be retrieved /// with a call to GetLastError. /// /// /// If the currently selected driver is a member of the list being deleted, the selection is reset. /// /// If a class driver list is being deleted, the DI_FLAGSEX_DIDINFOLIST and DI_DIDCLASS flags are reset for the corresponding device /// information set or device information element. The DI_MULTMFGS flags is also reset. /// /// /// If a compatible driver list is being destroyed, the DI_FLAGSEX_DIDCOMPATINFO and DI_DIDCOMPAT flags are reset for the /// corresponding device information element. /// /// // https://docs.microsoft.com/en-us/windows/win32/api/setupapi/nf-setupapi-setupdidestroydriverinfolist WINSETUPAPI BOOL // SetupDiDestroyDriverInfoList( HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, DWORD DriverType ); [DllImport(Lib_SetupAPI, SetLastError = true, ExactSpelling = true)] [PInvokeData("setupapi.h", MSDNShortId = "NF:setupapi.SetupDiDestroyDriverInfoList")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool SetupDiDestroyDriverInfoList(HDEVINFO DeviceInfoSet, [In, Optional] IntPtr DeviceInfoData, SPDIT DriverType); /// The SetupDiDrawMiniIcon function draws the specified mini-icon at the location requested. /// The handle to the device context in which the mini-icon will be drawn. /// The rectangle in the specified device context handle to draw the mini-icon in. /// /// /// The index of the mini-icon, as retrieved from SetupDiLoadClassIcon or SetupDiGetClassBitmapIndex. The following predefined /// indexes for devices can be used: /// /// /// /// Class /// Index /// /// /// Computer/System /// 0 /// /// /// Display/Monitor /// 2 /// /// /// Network Adapter /// 3 /// /// /// Mouse /// 5 /// /// /// Keyboard /// 6 /// /// /// Sound /// 8 /// /// /// FDC/HDC /// 9 /// /// /// Ports /// 10 /// /// /// Printer /// 14 /// /// /// Network Transport /// 15 /// /// /// Network Client /// 16 /// /// /// Network Service /// 17 /// /// /// Unknown /// 18 /// /// /// /// /// These flags control the drawing operation. The LOWORD contains the actual flags defined as follows: /// DMI_MASK /// Draw the mini-icon's mask into HDC. /// DMI_BKCOLOR /// /// Use the system color index specified in the HIWORD of Flags as the background color. If this flag is not set, COLOR_WINDOW is used. /// /// DMI_USERECT /// If set, SetupDiDrawMiniIcon uses the supplied rectangle and stretches the icon to fit. /// /// /// This function returns the offset from the left side of rc where the string should start. If the draw operation fails, the /// function returns zero. /// /// /// By default, the icon is centered vertically and forced against the left side of the specified rectangle. /// /// SetupDiDrawMiniIcon draws the 16-bit version of the icon that is specified by the MiniIconIndex parameter. Instead of /// SetupDiDrawMiniIcon, you should use SetupDiLoadClassIcon together with DrawIcon or DrawIconEx to draw the /// 32-bit version of the icon. The following is an example of how to use DrawIconEx to display an icon: /// /// /// HICON hIcon; if (SetupDiLoadClassIcon(&GUID_DEVCLASS_USB, &hIcon, NULL)) { DrawIconEx(hDC, 0, 0, hIcon, GetSystemMetrics(SM_CXSMICON),GetSystemMetrics(SM_CYSMICON), 0, NULL, DI_NORMAL); DestroyIcon(hIcon); } /// /// /// For more information about DrawIcon or DrawIconEx, refer to the Microsoft Windows Software Development Kit (SDK) for Windows 7 /// and .NET Framework 4.0 documentation. /// /// // https://docs.microsoft.com/en-us/windows/win32/api/setupapi/nf-setupapi-setupdidrawminiicon WINSETUPAPI INT SetupDiDrawMiniIcon( // HDC hdc, RECT rc, INT MiniIconIndex, DWORD Flags ); [DllImport(Lib_SetupAPI, SetLastError = false, ExactSpelling = true)] [PInvokeData("setupapi.h", MSDNShortId = "NF:setupapi.SetupDiDrawMiniIcon")] public static extern int SetupDiDrawMiniIcon(HDC hdc, RECT rc, int MiniIconIndex, DMI Flags); /// /// The SetupDiEnumDeviceInfo function returns a SP_DEVINFO_DATA structure that specifies a device information element in a /// device information set. /// /// /// A handle to the device information set for which to return an SP_DEVINFO_DATA structure that represents a device information element. /// /// A zero-based index of the device information element to retrieve. /// /// A pointer to an SP_DEVINFO_DATA structure to receive information about an enumerated device information element. The caller must /// set DeviceInfoData. cbSize to /// sizeof(SP_DEVINFO_DATA) /// . /// /// /// The function returns TRUE if it is successful. Otherwise, it returns FALSE and the logged error can be retrieved /// with a call to GetLastError. /// /// /// /// Repeated calls to this function return a device information element for a different device. This function can be called /// repeatedly to get information about all devices in the device information set. /// /// /// To enumerate device information elements, an installer should initially call SetupDiEnumDeviceInfo with the MemberIndex /// parameter set to 0. The installer should then increment MemberIndex and call SetupDiEnumDeviceInfo until there are no /// more values (the function fails and a call to GetLastError returns ERROR_NO_MORE_ITEMS). /// /// /// Call SetupDiEnumDeviceInterfaces to get a context structure for a device interface element (versus a device information element). /// /// // https://docs.microsoft.com/en-us/windows/win32/api/setupapi/nf-setupapi-setupdienumdeviceinfo WINSETUPAPI BOOL // SetupDiEnumDeviceInfo( HDEVINFO DeviceInfoSet, DWORD MemberIndex, PSP_DEVINFO_DATA DeviceInfoData ); [DllImport(Lib_SetupAPI, SetLastError = true, ExactSpelling = true)] [PInvokeData("setupapi.h", MSDNShortId = "NF:setupapi.SetupDiEnumDeviceInfo")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool SetupDiEnumDeviceInfo(HDEVINFO DeviceInfoSet, uint MemberIndex, ref SP_DEVINFO_DATA DeviceInfoData); /// /// The SetupDiEnumDeviceInfo function returns a sequence of SP_DEVINFO_DATA structures that specifies a device informations /// element in a device information set. /// /// /// A handle to the device information set for which to return the SP_DEVINFO_DATA structures that represents device information elements. /// /// A sequence of SP_DEVINFO_DATA structures with information about enumerated device information elements. [PInvokeData("setupapi.h", MSDNShortId = "NF:setupapi.SetupDiEnumDeviceInfo")] public static IEnumerable SetupDiEnumDeviceInfo(HDEVINFO DeviceInfoSet) { var data = StructHelper.InitWithSize(); for (uint i = 0; SetupDiEnumDeviceInfo(DeviceInfoSet, i, ref data); i++) yield return data; Win32Error.ThrowLastErrorUnless(Win32Error.ERROR_NO_MORE_ITEMS); } /// /// The SetupDiEnumDeviceInterfaces function enumerates the device interfaces that are contained in a device information set. /// /// /// A pointer to a device information set that contains the device interfaces for which to return information. This handle is /// typically returned by SetupDiGetClassDevs. /// /// /// A pointer to an SP_DEVINFO_DATA structure that specifies a device information element in DeviceInfoSet. This parameter is /// optional and can be NULL. If this parameter is specified, SetupDiEnumDeviceInterfaces constrains the enumeration /// to the interfaces that are supported by the specified device. If this parameter is NULL, repeated calls to /// SetupDiEnumDeviceInterfaces return information about the interfaces that are associated with all the device information /// elements in DeviceInfoSet. This pointer is typically returned by SetupDiEnumDeviceInfo. /// /// A pointer to a GUID that specifies the device interface class for the requested interface. /// /// /// A zero-based index into the list of interfaces in the device information set. The caller should call this function first with /// MemberIndex set to zero to obtain the first interface. Then, repeatedly increment MemberIndex and retrieve an interface until /// this function fails and GetLastError returns ERROR_NO_MORE_ITEMS. /// /// If DeviceInfoData specifies a particular device, the MemberIndex is relative to only the interfaces exposed by that device. /// /// /// A pointer to a caller-allocated buffer that contains, on successful return, a completed SP_DEVICE_INTERFACE_DATA structure that /// identifies an interface that meets the search parameters. The caller must set DeviceInterfaceData. cbSize to /// sizeof(SP_DEVICE_INTERFACE_DATA) before calling this function. /// /// /// SetupDiEnumDeviceInterfaces returns TRUE if the function completed without error. If the function completed with /// an error, FALSE is returned and the error code for the failure can be retrieved by calling GetLastError. /// /// /// /// Repeated calls to this function return an SP_DEVICE_INTERFACE_DATA structure for a different device interface. This function can /// be called repeatedly to get information about interfaces in a device information set that are associated with a particular /// device information element or that are associated with all device information elements. /// /// /// DeviceInterfaceData points to a structure that identifies a requested device interface. To get detailed information about an /// interface, call SetupDiGetDeviceInterfaceDetail. The detailed information includes the name of the device interface that can be /// passed to a Win32 function such as CreateFile (described in Microsoft Windows SDK documentation) to get a handle to the interface. /// /// See System Defined Device Interface Classes for a list of available device interface classes. /// // https://docs.microsoft.com/en-us/windows/win32/api/setupapi/nf-setupapi-setupdienumdeviceinterfaces WINSETUPAPI BOOL // SetupDiEnumDeviceInterfaces( HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, const GUID *InterfaceClassGuid, DWORD // MemberIndex, PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData ); [DllImport(Lib_SetupAPI, SetLastError = true, ExactSpelling = true)] [PInvokeData("setupapi.h", MSDNShortId = "NF:setupapi.SetupDiEnumDeviceInterfaces")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool SetupDiEnumDeviceInterfaces(HDEVINFO DeviceInfoSet, in SP_DEVINFO_DATA DeviceInfoData, in Guid InterfaceClassGuid, uint MemberIndex, ref SP_DEVICE_INTERFACE_DATA DeviceInterfaceData); /// /// The SetupDiEnumDeviceInterfaces function enumerates the device interfaces that are contained in a device information set. /// /// /// A pointer to a device information set that contains the device interfaces for which to return information. This handle is /// typically returned by SetupDiGetClassDevs. /// /// /// A pointer to an SP_DEVINFO_DATA structure that specifies a device information element in DeviceInfoSet. This parameter is /// optional and can be NULL. If this parameter is specified, SetupDiEnumDeviceInterfaces constrains the enumeration /// to the interfaces that are supported by the specified device. If this parameter is NULL, repeated calls to /// SetupDiEnumDeviceInterfaces return information about the interfaces that are associated with all the device information /// elements in DeviceInfoSet. This pointer is typically returned by SetupDiEnumDeviceInfo. /// /// A pointer to a GUID that specifies the device interface class for the requested interface. /// /// /// A zero-based index into the list of interfaces in the device information set. The caller should call this function first with /// MemberIndex set to zero to obtain the first interface. Then, repeatedly increment MemberIndex and retrieve an interface until /// this function fails and GetLastError returns ERROR_NO_MORE_ITEMS. /// /// If DeviceInfoData specifies a particular device, the MemberIndex is relative to only the interfaces exposed by that device. /// /// /// A pointer to a caller-allocated buffer that contains, on successful return, a completed SP_DEVICE_INTERFACE_DATA structure that /// identifies an interface that meets the search parameters. The caller must set DeviceInterfaceData. cbSize to /// sizeof(SP_DEVICE_INTERFACE_DATA) before calling this function. /// /// /// SetupDiEnumDeviceInterfaces returns TRUE if the function completed without error. If the function completed with /// an error, FALSE is returned and the error code for the failure can be retrieved by calling GetLastError. /// /// /// /// Repeated calls to this function return an SP_DEVICE_INTERFACE_DATA structure for a different device interface. This function can /// be called repeatedly to get information about interfaces in a device information set that are associated with a particular /// device information element or that are associated with all device information elements. /// /// /// DeviceInterfaceData points to a structure that identifies a requested device interface. To get detailed information about an /// interface, call SetupDiGetDeviceInterfaceDetail. The detailed information includes the name of the device interface that can be /// passed to a Win32 function such as CreateFile (described in Microsoft Windows SDK documentation) to get a handle to the interface. /// /// See System Defined Device Interface Classes for a list of available device interface classes. /// // https://docs.microsoft.com/en-us/windows/win32/api/setupapi/nf-setupapi-setupdienumdeviceinterfaces WINSETUPAPI BOOL // SetupDiEnumDeviceInterfaces( HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, const GUID *InterfaceClassGuid, DWORD // MemberIndex, PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData ); [DllImport(Lib_SetupAPI, SetLastError = true, ExactSpelling = true)] [PInvokeData("setupapi.h", MSDNShortId = "NF:setupapi.SetupDiEnumDeviceInterfaces")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool SetupDiEnumDeviceInterfaces(HDEVINFO DeviceInfoSet, [In, Optional] IntPtr DeviceInfoData, in Guid InterfaceClassGuid, uint MemberIndex, ref SP_DEVICE_INTERFACE_DATA DeviceInterfaceData); /// /// The SetupDiEnumDeviceInterfaces function enumerates the device interfaces that are contained in a device information set. /// /// /// A pointer to a device information set that contains the device interfaces for which to return information. This handle is /// typically returned by SetupDiGetClassDevs. /// /// A GUID that specifies the device interface class for the requested interface. /// /// A nullable reference to an SP_DEVINFO_DATA structure that specifies a device information element in DeviceInfoSet. This /// parameter is optional and can be . If this parameter is specified, SetupDiEnumDeviceInterfaces /// constrains the enumeration to the interfaces that are supported by the specified device, otherwise all interfaces are returned. /// /// A sequence of completed SP_DEVICE_INTERFACE_DATA structures that identify the interfaces that meets the search parameters. /// /// /// Each value returned is a structure that identifies a requested device interface. To get detailed information about an interface, /// call . The detailed information includes the name of the device interface that can be passed to a Win32 function /// such as CreateFile (described in Microsoft Windows SDK documentation) to get a handle to the interface. /// /// See System Defined Device Interface Classes for a list of available device interface classes. /// [PInvokeData("setupapi.h", MSDNShortId = "NF:setupapi.SetupDiEnumDeviceInterfaces")] public static IEnumerable SetupDiEnumDeviceInterfaces(HDEVINFO DeviceInfoSet, Guid InterfaceClassGuid, SP_DEVINFO_DATA? DeviceInfoData = null) { using var dvidata = DeviceInfoData.HasValue ? new SafeCoTaskMemStruct(DeviceInfoData.Value) : SafeCoTaskMemStruct.Null; var data = new SP_DEVICE_INTERFACE_DATA { cbSize = (uint)Marshal.SizeOf(typeof(SP_DEVICE_INTERFACE_DATA)) }; for (uint i = 0; true; i++) { if (!SetupDiEnumDeviceInterfaces(DeviceInfoSet, dvidata, InterfaceClassGuid, i, ref data)) { Win32Error.ThrowLastErrorUnless(Win32Error.ERROR_NO_MORE_ITEMS); yield break; } yield return data; } } /// The SetupDiEnumDriverInfo function enumerates the members of a driver list. /// A handle to the device information set that contains the driver list to enumerate. /// /// A pointer to an SP_DEVINFO_DATA structure that specifies a device information element in DeviceInfoSet. This parameter is /// optional and can be NULL. If this parameter is specified, SetupDiEnumDriverInfo enumerates a driver list for the /// specified device. If this parameter is NULL, SetupDiEnumDriverInfo enumerates the global class driver list that is /// associated with DeviceInfoSet (this list is of type SPDIT_CLASSDRIVER). /// /// /// The type of driver list to enumerate, which must be one of the following values: /// SPDIT_CLASSDRIVER /// Enumerate a class driver list. This driver list type must be specified if DeviceInfoData is not specified. /// SPDIT_COMPATDRIVER /// /// Enumerate a list of compatible drivers for the specified device. This driver list type can be specified only if DeviceInfoData /// is also specified. /// /// /// The zero-based index of the driver information member to retrieve. /// /// A pointer to a caller-initialized SP_DRVINFO_DATA structure that receives information about the enumerated driver. The caller /// must set DriverInfoData. cbSize to sizeof( SP_DRVINFO_DATA ) before calling SetupDiEnumDriverInfo. /// If the cbSize member is not properly set, SetupDiEnumDriverInfo will return FALSE. /// /// /// The function returns TRUE if it is successful. Otherwise, it returns FALSE and the logged error can be retrieved /// with a call to GetLastError. /// /// /// /// To enumerate driver information set members, an installer should first call SetupDiEnumDriverInfo with the MemberIndex /// parameter set to 0. It should then increment MemberIndex and call SetupDiEnumDriverInfo until there are no more values. /// When there are no more values, the function fails and a call to GetLastError returns ERROR_NO_MORE_ITEMS. /// /// /// If you do not properly initialize the cbSize member of the SP_DRVINFO_DATA structure that is supplied by the pointer /// DriverInfoData, the function will fail and log the error ERROR_INVALID_USER_BUFFER. /// /// /// To build a list of drivers associated with a specific device or with the global class driver list for a device information set /// first use SetupDiBuildDriverInfoList then pass that list to SetupDiEnumDriverInfo. /// /// // https://docs.microsoft.com/en-us/windows/win32/api/setupapi/nf-setupapi-setupdienumdriverinfoa WINSETUPAPI BOOL // SetupDiEnumDriverInfoA( HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, DWORD DriverType, DWORD MemberIndex, // PSP_DRVINFO_DATA_A DriverInfoData ); [DllImport(Lib_SetupAPI, SetLastError = true, CharSet = CharSet.Auto)] [PInvokeData("setupapi.h", MSDNShortId = "NF:setupapi.SetupDiEnumDriverInfoA")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool SetupDiEnumDriverInfo(HDEVINFO DeviceInfoSet, in SP_DEVINFO_DATA DeviceInfoData, SPDIT DriverType, uint MemberIndex, ref SP_DRVINFO_DATA_V2 DriverInfoData); /// The SetupDiEnumDriverInfo function enumerates the members of a driver list. /// A handle to the device information set that contains the driver list to enumerate. /// /// A pointer to an SP_DEVINFO_DATA structure that specifies a device information element in DeviceInfoSet. This parameter is /// optional and can be NULL. If this parameter is specified, SetupDiEnumDriverInfo enumerates a driver list for the /// specified device. If this parameter is NULL, SetupDiEnumDriverInfo enumerates the global class driver list that is /// associated with DeviceInfoSet (this list is of type SPDIT_CLASSDRIVER). /// /// /// The type of driver list to enumerate, which must be one of the following values: /// SPDIT_CLASSDRIVER /// Enumerate a class driver list. This driver list type must be specified if DeviceInfoData is not specified. /// SPDIT_COMPATDRIVER /// /// Enumerate a list of compatible drivers for the specified device. This driver list type can be specified only if DeviceInfoData /// is also specified. /// /// /// The zero-based index of the driver information member to retrieve. /// /// A pointer to a caller-initialized SP_DRVINFO_DATA structure that receives information about the enumerated driver. The caller /// must set DriverInfoData. cbSize to sizeof( SP_DRVINFO_DATA ) before calling SetupDiEnumDriverInfo. /// If the cbSize member is not properly set, SetupDiEnumDriverInfo will return FALSE. /// /// /// The function returns TRUE if it is successful. Otherwise, it returns FALSE and the logged error can be retrieved /// with a call to GetLastError. /// /// /// /// To enumerate driver information set members, an installer should first call SetupDiEnumDriverInfo with the MemberIndex /// parameter set to 0. It should then increment MemberIndex and call SetupDiEnumDriverInfo until there are no more values. /// When there are no more values, the function fails and a call to GetLastError returns ERROR_NO_MORE_ITEMS. /// /// /// If you do not properly initialize the cbSize member of the SP_DRVINFO_DATA structure that is supplied by the pointer /// DriverInfoData, the function will fail and log the error ERROR_INVALID_USER_BUFFER. /// /// /// To build a list of drivers associated with a specific device or with the global class driver list for a device information set /// first use SetupDiBuildDriverInfoList then pass that list to SetupDiEnumDriverInfo. /// /// // https://docs.microsoft.com/en-us/windows/win32/api/setupapi/nf-setupapi-setupdienumdriverinfoa WINSETUPAPI BOOL // SetupDiEnumDriverInfoA( HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, DWORD DriverType, DWORD MemberIndex, // PSP_DRVINFO_DATA_A DriverInfoData ); [DllImport(Lib_SetupAPI, SetLastError = true, CharSet = CharSet.Auto)] [PInvokeData("setupapi.h", MSDNShortId = "NF:setupapi.SetupDiEnumDriverInfoA")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool SetupDiEnumDriverInfo(HDEVINFO DeviceInfoSet, [In, Optional] IntPtr DeviceInfoData, SPDIT DriverType, uint MemberIndex, ref SP_DRVINFO_DATA_V2 DriverInfoData); /// /// The SetupDiGetActualModelsSection function retrieves the appropriate decorated INF Models section to use when installing /// a device from a device INF file. /// /// /// A pointer to an INF file context that specifies a manufacturer-identifier entry in an INF Manufacturer section of an INF file. /// The manufacturer-identifier entry specifies an INF Models section name and optionally specifies TargetOSVersion decorations for /// the Models section name. For information about INF files and an INF file context, see the Platform SDK topics on using INF files /// and the INFCONTEXT structure. /// /// /// A pointer to an SP_ALTPLATFORM_INFO structure that supplies information about a Windows version and processor architecture. The /// cbSize member of this structure must be set to sizeof( SP_ALTPLATFORM_INFO_V2 ). This parameter is optional /// and can be set to NULL. /// /// /// A pointer to a buffer that receives a string that contains the decorated INF Models section name and a NULL terminator. If /// AlternatePlatformInfo is not supplied, the decorated INF Models section name applies to the current platform; otherwise the name /// applies to the specified alternative platform. This parameter is optional and can be set to NULL. If this parameter is /// NULL, the function returns TRUE and sets RequiredSize to the size, in characters, that is required to return the /// decorated Models section name and a terminating NULL character. /// /// /// The size, in characters, of the DecoratedModelsSection buffer. If DecoratedModelsSection is NULL, this parameter must be /// set to zero. /// /// /// A pointer to a DWORD-type variable that receives the size, in characters, of the DecoratedModelsSection buffer that is required /// to retrieve the decorated Models section name and a terminating NULL character. This parameter is optional and can be set to NULL. /// /// Reserved for internal system use. This parameter must be set to NULL. /// /// SetupDiGetActualModelsSection returns TRUE if the operation succeeds. Otherwise, the function returns FALSE /// and the logged error can be retrieved with a call to GetLastError. /// /// /// /// SetupDiGetActualModelsSection determines which TargetOSVersion fields in the manufacturer-identifier entry (supplied by /// Context) apply to the current platform, if AlternatePlatformInfo is not supplied, or to an alternative platform, if alternative /// platform information is supplied. SetupDiGetActualModelsSection selects the most appropriate platform based on all the /// TargetOSVersion fields, appends the TargetOSVersion string to the INF Models section name, and returns the decorated INF Models /// section name to the caller. In a manufacturer-identifier entry, the operating system major version is specified by the /// OSMajorVersion field and the operating system minor version is specified by the OSMinorVersion field. /// /// For information about retrieving an INF DDInstall section for a device, see SetupDiGetActualSectionToInstall. /// // https://docs.microsoft.com/en-us/windows/win32/api/setupapi/nf-setupapi-setupdigetactualmodelssectiona WINSETUPAPI BOOL // SetupDiGetActualModelsSectionA( PINFCONTEXT Context, PSP_ALTPLATFORM_INFO AlternatePlatformInfo, PSTR InfSectionWithExt, DWORD // InfSectionWithExtSize, PDWORD RequiredSize, PVOID Reserved ); [DllImport(Lib_SetupAPI, SetLastError = true, CharSet = CharSet.Auto)] [PInvokeData("setupapi.h", MSDNShortId = "NF:setupapi.SetupDiGetActualModelsSectionA")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool SetupDiGetActualModelsSection(in INFCONTEXT Context, [In, Optional] IntPtr AlternatePlatformInfo, [Out, Optional, MarshalAs(UnmanagedType.LPTStr)] StringBuilder InfSectionWithExt, uint InfSectionWithExtSize, out uint RequiredSize, IntPtr Reserved = default); /// /// The SetupDiGetActualSectionToInstall function retrieves the appropriate INF DDInstall section to use when installing a /// device from a device INF file on a local computer. /// /// The handle to the INF file that contains the DDInstall section. /// /// A pointer to the DDInstall section name (as specified in an INF Models section). The maximum length of the section name, in /// characters, is 254. /// /// /// A pointer to a character buffer to receive the DDInstall section name, its platform extension, and a NULL terminator. This is /// the decorated section name that should be used for installation. If this parameter is NULL, InfSectionWithExtSize must be /// zero. If this parameter is NULL, the function returns TRUE and sets RequiredSize to the size, in characters, that /// is required to return the DDInstall section name, its platform extension, and a terminating NULL character. /// /// /// The size, in characters, of the InfSectionWithExt buffer. If InfSectionWithExt is NULL, this parameter must be zero. /// /// /// A pointer to the variable that receives the size, in characters, that is required to return the DDInstall section name, the /// platform extension, and a terminating NULL character. /// /// /// A pointer to a variable that receives a pointer to the '.' character that marks the start of the extension in the /// InfSectionWithExt buffer. If the InfSectionWithExt buffer is not supplied or is too small, this parameter is not set. Set this /// parameter to NULL if a pointer to the extension is not required. /// /// /// If the function is successful, it returns TRUE. If the function fails, it returns FALSE. To get extended error /// information, call GetLastError. /// /// /// /// This function supports the extensions to DDInstall section names that are used to specify OS-specific and architecture-specific /// installation behaviors for a device. For information about these extensions, see Creating INF Files for Multiple Platforms and /// Operating Systems. SetupDiGetActualSectionToInstall searches for a DDInstall section name that matches the local computer /// in the manner described below. /// /// /// The function first searches in the specified INF file for a decorated install section name that matches the specified name and /// has an extension that matches the operating system and processor architecture of the local computer. If, for example, you /// specify a section name of InstallSec, the function searches for one of the following decorated names, depending on the /// processor architecture of the local computer: /// /// /// /// For a computer that is based on the x86 processor architecture, the function searches for the decorated name InstallSec.ntx86. /// /// /// For a computer that is based on the x64 processor architecture, the function searches for the decorated name InstallSec.ntamd64. /// /// /// For a computer that is based on the Itanium processor architecture, the function searches for the decorated name InstallSec.ntia64. /// /// /// /// If the function finds a match for the name, operating system, and processor architecture, it terminates the search and returns /// the corresponding decorated name. If the function does not find such a match, the function searches for a section whose name is /// InstallSec.NT. If the function finds a match for InstallSec.NT, it terminates the search and returns this name. If /// the function does not find a match for either of the above searches, it returns InstallSec, but does not verify that the /// INF file contains an install section whose name is InstallSec. /// /// /// The DDInstall section name is used as the base for Hardware and Services section names. For example, if the /// DDInstall section name that is found is InstallSec.NTX86, the Services section name must be named InstallSec.NTX86.Services. /// /// /// The original DDInstall section name that is specified in the driver node is written to the driver's registry key's /// InfSection value entry. The extension that was found is stored in the key as the REG_SZ value InfSectionExt. For example: /// /// /// InfSection : REG_SZ : "InstallSec" InfSectionExt : REG_SZ : ".NTX86" /// /// /// If a driver is not selected for the specified device information element, a null driver is installed. Upon return, the flags in /// the device's SP_DEVINSTALL_PARAMS structure indicate whether the system should be restarted or rebooted to cause the device to start. /// /// // https://docs.microsoft.com/en-us/windows/win32/api/setupapi/nf-setupapi-setupdigetactualsectiontoinstalla WINSETUPAPI BOOL // SetupDiGetActualSectionToInstallA( HINF InfHandle, PCSTR InfSectionName, PSTR InfSectionWithExt, DWORD InfSectionWithExtSize, // PDWORD RequiredSize, PSTR *Extension ); [DllImport(Lib_SetupAPI, SetLastError = true, CharSet = CharSet.Auto)] [PInvokeData("setupapi.h", MSDNShortId = "NF:setupapi.SetupDiGetActualSectionToInstallA")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool SetupDiGetActualSectionToInstall(HINF InfHandle, [MarshalAs(UnmanagedType.LPTStr)] string InfSectionName, [Out, Optional, MarshalAs(UnmanagedType.LPTStr)] StringBuilder InfSectionWithExt, uint InfSectionWithExtSize, out uint RequiredSize, out StrPtrAuto Extension); /// /// The SetupDiGetActualSectionToInstallEx function retrieves the name of the INF DDInstall section that installs a device /// for a specified operating system and processor architecture. /// /// A handle to the INF file that contains the DDInstall section. /// /// A pointer to the DDInstall section name (as specified in an INF Models section). The maximum length of the section name, in /// characters, is 254. /// /// /// /// A pointer, if non- NULL, to an SP_ALTPLATFORM_INFO structure. This structure is used to specify an operating system and /// processor architecture that is different from that on the local computer. To return the DDInstall section name for the local /// computer, set this parameter to NULL. Otherwise, provide an SP_ALTPLATFORM structure and set its members as follows: /// /// cbSize /// Set to the size, in bytes, of an SP_ALTPLATFORM_INFO structure. /// Platform /// Set to VER_PLATFORM_WIN32_NT for Windows XP and later versions of Windows. /// MajorVersion /// Not used. /// MinorVersion /// Not Used. /// ProcessorArchitecture /// Set one of the following processor architecture constants. /// /// /// Processor Architecture Constant /// Meaning /// /// /// PROCESSOR_ARCHITECTURE_INTEL /// The alternative platform is an x86-based processor architecture. /// /// /// PROCESSOR_ARCHITECTURE_IA64 /// The alternative platform is an Itanium-based processor architecture. /// /// /// PROCESSOR_ARCHITECTURE_AMD64 /// The alternative platform is an x64-based processor architecture. /// /// /// Reserved /// Set to zero. /// /// /// A pointer to a character buffer to receive the DDInstall section name, its platform extension, and a NULL terminator. This is /// the decorated section name that should be used for installation. If this parameter is NULL, the function returns /// TRUE and sets RequiredSize to the size, in characters, that is required to return the DDInstall section name, its /// platform extension, and a terminating NULL character. /// /// /// The size, in characters, of the buffer that is pointed to by the InfSectionWithExt parameter. The maximum length of a /// NULL-terminated INF section name, in characters, is MAX_INF_SECTION_NAME_LENGTH. /// /// /// A pointer to the variable that receives the size, in characters, that is required to return the DDInstall section name, the /// platform extension, and a terminating NULL character. /// /// /// A pointer to a variable that receives a pointer to the '.' character that marks the start of the extension in the /// InfSectionWithExt buffer. If the InfSectionWithExt buffer is not supplied or is too small, this parameter is not set. Set this /// parameter to NULL if a pointer to the extension is not required. /// /// Reserved for internal use only. Must be set to NULL. /// /// If the function is successful, it returns TRUE. Otherwise, it returns FALSE. To get extended error information, /// call GetLastError. /// /// /// /// SetupDiGetActualSectionToInstallEx is an extended form of SetupDiGetActualSectionToInstall. These functions support the /// extensions to DDInstall section names that are used to specify OS-specific and architecture-specific installation actions for a /// device. For information about these extensions, see Creating INF Files for Multiple Platforms and Operating Systems. /// /// /// If you do not supply alternative platform information with a call to SetupDiGetActualSectionToInstallEx, the function /// performs the same operation as SetupDiGetActualSectionToInstall. The latter function searches for the specified install /// section name using the platform information for the local computer. /// /// /// If you supply alternative platform information with a call to SetupDiGetActualSectionToInstallEx, the function does the following: /// /// /// /// /// If you specify a platform of VER_PLATFORM_WIN32_NT, the function first searches in the specified INF file for a decorated /// install section name that matches the name, operating system, and processor architecture that you specify. If, for example, you /// specify an install section name of InstallSec, the function searches for one of the following decorated names, depending /// on the specified processor architecture: /// /// /// /// // https://docs.microsoft.com/en-us/windows/win32/api/setupapi/nf-setupapi-setupdigetactualsectiontoinstallexa WINSETUPAPI BOOL // SetupDiGetActualSectionToInstallExA( HINF InfHandle, PCSTR InfSectionName, PSP_ALTPLATFORM_INFO AlternatePlatformInfo, PSTR // InfSectionWithExt, DWORD InfSectionWithExtSize, PDWORD RequiredSize, PSTR *Extension, PVOID Reserved ); [DllImport(Lib_SetupAPI, SetLastError = true, CharSet = CharSet.Auto)] [PInvokeData("setupapi.h", MSDNShortId = "NF:setupapi.SetupDiGetActualSectionToInstallExA")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool SetupDiGetActualSectionToInstallEx(HINF InfHandle, [MarshalAs(UnmanagedType.LPTStr)] string InfSectionName, [In, Optional] IntPtr AlternatePlatformInfo, [Out, Optional, MarshalAs(UnmanagedType.LPTStr)] StringBuilder InfSectionWithExt, uint InfSectionWithExtSize, out uint RequiredSize, out StrPtrAuto Extension, IntPtr Reserved = default); /// The SetupDiGetClassBitmapIndex function retrieves the index of the mini-icon supplied for the specified class. /// /// A pointer to the GUID of the device setup class for which to retrieve the mini-icon. This pointer is optional and can be NULL. /// /// /// A pointer to a variable of type INT that receives the index of the mini-icon for the specified device setup class. If the /// ClassGuid parameter is NULL or if there is no mini-icon for the specified class, SetupDiGetClassBitmapIndex /// returns the index of the mini-icon for the Unknown device setup class. /// /// /// If there is a min-icon for the specified device setup class, SetupDiGetClassBitmapIndex returns TRUE. Otherwise, /// this function returns FALSE and the logged error can be retrieved with a call to GetLastError. If the ClassGuid parameter /// is NULL, or if there is no mini-icon for the specified class, the function returns FALSE and GetLastError returns ERROR_NO_DEVICE_ICON. /// /// For a list of the device setup class mini-icons and their corresponding indexes, see SetupDiDrawMiniIcon. // https://docs.microsoft.com/en-us/windows/win32/api/setupapi/nf-setupapi-setupdigetclassbitmapindex WINSETUPAPI BOOL // SetupDiGetClassBitmapIndex( const GUID *ClassGuid, PINT MiniIconIndex ); [DllImport(Lib_SetupAPI, SetLastError = true, ExactSpelling = true)] [PInvokeData("setupapi.h", MSDNShortId = "NF:setupapi.SetupDiGetClassBitmapIndex")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool SetupDiGetClassBitmapIndex(in Guid ClassGuid, out int MiniIconIndex); /// The SetupDiGetClassBitmapIndex function retrieves the index of the mini-icon supplied for the specified class. /// /// A pointer to the GUID of the device setup class for which to retrieve the mini-icon. This pointer is optional and can be NULL. /// /// /// A pointer to a variable of type INT that receives the index of the mini-icon for the specified device setup class. If the /// ClassGuid parameter is NULL or if there is no mini-icon for the specified class, SetupDiGetClassBitmapIndex /// returns the index of the mini-icon for the Unknown device setup class. /// /// /// If there is a min-icon for the specified device setup class, SetupDiGetClassBitmapIndex returns TRUE. Otherwise, /// this function returns FALSE and the logged error can be retrieved with a call to GetLastError. If the ClassGuid parameter /// is NULL, or if there is no mini-icon for the specified class, the function returns FALSE and GetLastError returns ERROR_NO_DEVICE_ICON. /// /// For a list of the device setup class mini-icons and their corresponding indexes, see SetupDiDrawMiniIcon. // https://docs.microsoft.com/en-us/windows/win32/api/setupapi/nf-setupapi-setupdigetclassbitmapindex WINSETUPAPI BOOL // SetupDiGetClassBitmapIndex( const GUID *ClassGuid, PINT MiniIconIndex ); [DllImport(Lib_SetupAPI, SetLastError = true, ExactSpelling = true)] [PInvokeData("setupapi.h", MSDNShortId = "NF:setupapi.SetupDiGetClassBitmapIndex")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool SetupDiGetClassBitmapIndex([In, Optional] IntPtr ClassGuid, out int MiniIconIndex); /// /// The SetupDiGetClassDescription function retrieves the class description associated with the specified setup class GUID. /// /// The GUID of the setup class whose description is to be retrieved. /// A pointer to a character buffer that receives the class description. /// The size, in characters, of the ClassDescription buffer. /// /// A pointer to variable of type DWORD that receives the size, in characters, that is required to store the class description /// (including a NULL terminator). RequiredSize is always less than LINE_LEN. This parameter is optional and can be NULL. /// /// /// The function returns TRUE if it is successful. Otherwise, it returns FALSE and the logged error can be retrieved /// with a call to GetLastError. /// /// Call SetupDiGetClassDescriptionEx to retrieve the description of a setup class installed on a remote computer. // https://docs.microsoft.com/en-us/windows/win32/api/setupapi/nf-setupapi-setupdigetclassdescriptiona WINSETUPAPI BOOL // SetupDiGetClassDescriptionA( const GUID *ClassGuid, PSTR ClassDescription, DWORD ClassDescriptionSize, PDWORD RequiredSize ); [DllImport(Lib_SetupAPI, SetLastError = true, CharSet = CharSet.Auto)] [PInvokeData("setupapi.h", MSDNShortId = "NF:setupapi.SetupDiGetClassDescriptionA")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool SetupDiGetClassDescription(in Guid ClassGuid, [Out, MarshalAs(UnmanagedType.LPTStr)] StringBuilder ClassDescription, uint ClassDescriptionSize, out uint RequiredSize); /// /// The SetupDiGetClassDescriptionEx function retrieves the description of a setup class installed on a local or remote computer. /// /// A pointer to the GUID for the setup class whose description is to be retrieved. /// A pointer to a character buffer that receives the class description. /// /// The size, in characters, of the buffer that is pointed to by the ClassDescription parameter. The maximum length, in characters, /// of a NULL-terminated class description is LINE_LEN. For more information, see the following Remarks section. /// /// /// A pointer to a DWORD-typed variable that receives the size, in characters, that is required to store the requested /// NULL-terminated class description. This pointer is optional and can be NULL. /// /// /// A pointer to a NULL-terminated string that supplies the name of a remote computer on which the setup class resides. This pointer /// is optional and can be NULL. If the class is installed on a local computer, set the pointer to NULL. /// /// Reserved for system use. A caller of this function must set this parameter to NULL. /// /// The function returns TRUE if it is successful. Otherwise, it returns FALSE and the logged error can be retrieved /// with a call to GetLastError. /// /// /// /// If there is a friendly name in the registry key for the class, this routine returns the friendly name. Otherwise, this routine /// returns the class name. /// /// /// SetupDiGetClassDescriptionEx does not enforce a restriction on the length of the class description that it can return. /// This function returns the required size for a NULL-terminated class description even if it is greater than LINE_LEN. However, /// LINE_LEN is the maximum length of a valid NULL-terminated class description. A caller should never need a buffer that is larger /// than LINE_LEN. /// /// // https://docs.microsoft.com/en-us/windows/win32/api/setupapi/nf-setupapi-setupdigetclassdescriptionexa WINSETUPAPI BOOL // SetupDiGetClassDescriptionExA( const GUID *ClassGuid, PSTR ClassDescription, DWORD ClassDescriptionSize, PDWORD RequiredSize, // PCSTR MachineName, PVOID Reserved ); [DllImport(Lib_SetupAPI, SetLastError = true, CharSet = CharSet.Auto)] [PInvokeData("setupapi.h", MSDNShortId = "NF:setupapi.SetupDiGetClassDescriptionExA")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool SetupDiGetClassDescriptionEx(in Guid ClassGuid, [Out, MarshalAs(UnmanagedType.LPTStr)] StringBuilder ClassDescription, uint ClassDescriptionSize, out uint RequiredSize, [In, Optional, MarshalAs(UnmanagedType.LPTStr)] string MachineName, IntPtr Reserved = default); /// /// The SetupDiGetClassDevPropertySheets function retrieves handles to the property sheets of a device information element or /// of the device setup class of a device information set. /// /// /// A handle to the device information set for which to return property sheet handles. If DeviceInfoData does not specify a device /// information element in the device information set, the device information set must have an associated device setup class. /// /// /// A pointer to an SP_DEVINFO_DATA structure that specifies a device information element in DeviceInfoSet. /// /// This parameter is optional and can be NULL. If this parameter is specified, SetupDiGetClassDevPropertySheets /// retrieves the property sheets handles that are associated with the specified device. If this parameter is NULL, /// SetupDiGetClassDevPropertySheets retrieves the property sheets handles that are associated with the device setup class /// specified in DeviceInfoSet. /// /// /// /// /// A pointer to a PROPERTYSHEETHEADER structure. See the Remarks section for information about the caller-supplied array of /// property sheet handles that is associated with this structure. /// /// For more documentation on this structure and property sheets in general, see the Microsoft Windows SDK. /// /// /// The maximum number of handles that the caller-supplied array of property sheet handles can hold. /// /// /// A pointer to a variable of type DWORD that receives the number of property sheets that are associated with the specified device /// information element or the device setup class of the specified device information set. The pointer is optional and can be NULL. /// /// /// A flag that indicates one of the following types of property sheets. /// /// /// Property sheet type /// Meaning /// /// /// DIGCDP_FLAG_ADVANCED /// Advanced property sheets. /// /// /// DIGCDP_FLAG_BASIC /// /// Basic property sheets. Supported only in Microsoft Windows 95 and Windows 98. Do not use in Windows 2000 and later versions of Windows. /// /// /// /// DIGCDP_FLAG_REMOTE_ADVANCED /// Advanced property sheets on a remote computer. /// /// /// /// /// The function returns TRUE if successful. Otherwise, the function returns FALSE. Call GetLastError to obtain the /// error code. /// /// /// /// A PROPERTYSHEETHEADER structure contains two members that are associated with a caller-supplied array that the function uses to /// return the handles of property sheets. The phpages member is a pointer to a caller-supplied array of property sheet /// handles, and the input value of the nPages member specifies the number of handles that are already contained in the /// handle array. The function adds property sheet handles to the handle array beginning with the array element whose array index is /// the input value of nPages. The function adds handles to the array in consecutive order until either the array is full or /// the handles of all the requested property sheet pages have been added to the array. The maximum number of property sheet handles /// that the function can return is equal to (PropertySheetHeaderPageListSize - (input value of nPages)). /// /// If the handle array is large enough to hold the handles of all the requested property sheet pages, the function: /// /// /// Adds the handles to the handle array. /// /// /// Sets nPages to the total number of handles in the array. /// /// /// Sets RequiredSize to the number of handles that it returns. /// /// /// Returns TRUE. /// /// /// If the handle array is not large enough to hold the handles of all the specified property sheet pages, the function: /// /// /// Adds as many handles as the array can hold. /// /// /// Sets nPages to PropertySheetHeaderPageListSize. /// /// /// /// Sets RequiredSize to the total number of requested property sheet pages. The number of handles that are not returned by the /// function is equal to (RequiredSize - PropertySheetHeaderPageListSize - (input value of nPages)). /// /// /// /// Sets the error code to ERROR_INSUFFICIENT_BUFFER. /// /// /// Returns FALSE. /// /// /// // https://docs.microsoft.com/en-us/windows/win32/api/setupapi/nf-setupapi-setupdigetclassdevpropertysheetsa WINSETUPAPI BOOL // SetupDiGetClassDevPropertySheetsA( HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, LPPROPSHEETHEADERA // PropertySheetHeader, DWORD PropertySheetHeaderPageListSize, PDWORD RequiredSize, DWORD PropertySheetType ); [DllImport(Lib_SetupAPI, SetLastError = true, CharSet = CharSet.Auto)] [PInvokeData("setupapi.h", MSDNShortId = "NF:setupapi.SetupDiGetClassDevPropertySheetsA")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool SetupDiGetClassDevPropertySheets(HDEVINFO DeviceInfoSet, in SP_DEVINFO_DATA DeviceInfoData, [In] IntPtr PropertySheetHeader, uint PropertySheetHeaderPageListSize, out uint RequiredSize, DIGCDP_FLAG PropertySheetType); /// /// The SetupDiGetClassDevs function returns a handle to a device information set that contains requested device information /// elements for a local computer. /// /// /// A pointer to the GUID for a device setup class or a device interface class. This pointer is optional and can be NULL. For /// more information about how to set ClassGuid, see the following Remarks section. /// /// /// A pointer to a NULL-terminated string that specifies: /// /// /// /// An identifier (ID) of a Plug and Play (PnP) enumerator. This ID can either be the value's globally unique identifier (GUID) or /// symbolic name. For example, "PCI" can be used to specify the PCI PnP value. Other examples of symbolic names for PnP values /// include "USB," "PCMCIA," and "SCSI". /// /// /// /// A PnP device instance ID. When specifying a PnP device instance ID, DIGCF_DEVICEINTERFACE must be set in the Flags parameter. /// /// /// This pointer is optional and can be /// NULL /// . If an /// enumeration /// value is not used to select devices, set /// Enumerator /// to /// NULL /// For more information about how to set the Enumerator value, see the following Remarks section. /// /// /// A handle to the top-level window to be used for a user interface that is associated with installing a device instance in the /// device information set. This handle is optional and can be NULL. /// /// /// /// A variable of type DWORD that specifies control options that filter the device information elements that are added to the device /// information set. This parameter can be a bitwise OR of zero or more of the following flags. For more information about combining /// these flags, see the following Remarks section. /// /// DIGCF_ALLCLASSES /// Return a list of installed devices for all device setup classes or all device interface classes. /// DIGCF_DEVICEINTERFACE /// /// Return devices that support device interfaces for the specified device interface classes. This flag must be set in the Flags /// parameter if the Enumerator parameter specifies a device instance ID. /// /// DIGCF_DEFAULT /// /// Return only the device that is associated with the system default device interface, if one is set, for the specified device /// interface classes. /// /// DIGCF_PRESENT /// Return only devices that are currently present in a system. /// DIGCF_PROFILE /// Return only devices that are a part of the current hardware profile. /// /// /// If the operation succeeds, SetupDiGetClassDevs returns a handle to a device information set that contains all installed /// devices that matched the supplied parameters. If the operation fails, the function returns INVALID_HANDLE_VALUE. To get extended /// error information, call GetLastError. /// /// /// /// The caller of SetupDiGetClassDevs must delete the returned device information set when it is no longer needed by calling SetupDiDestroyDeviceInfoList. /// /// Call SetupDiGetClassDevsEx to retrieve the devices for a class on a remote computer. /// Device Setup Class Control Options /// /// Use the following filtering options to control whether SetupDiGetClassDevs returns devices for all device setup classes /// or only for a specified device setup class: /// /// /// /// To return devices for all device setup classes, set the DIGCF_ALLCLASSES flag, and set the ClassGuid parameter to NULL. /// /// /// /// To return devices only for a specific device setup class, do not set DIGCF_ALLCLASSES, and use ClassGuid to supply the GUID of /// the device setup class. /// /// /// /// /// In addition, you can use the following filtering options in combination with one another to further restrict which devices are returned: /// /// /// /// To return only devices that are present in the system, set the DIGCF_PRESENT flag. /// /// /// To return only devices that are part of the current hardware profile, set the DIGCF_PROFILE flag. /// /// /// /// To return devices only for a specific PnP enumerator, use the Enumerator parameter to supply the GUID or symbolic name of the /// enumerator. If Enumerator is NULL, SetupDiGetClassDevs returns devices for all PnP enumerators. /// /// /// /// Device Interface Class Control Options /// /// Use the following filtering options to control whether SetupDiGetClassDevs returns devices that support any device /// interface class or only devices that support a specified device interface class: /// /// /// /// /// To return devices that support a device interface of any class, set the DIGCF_DEVICEINTERFACE flag, set the DIGCF_ALLCLASSES /// flag, and set ClassGuid to NULL. The function adds to the device information set a device information element that /// represents such a device and then adds to the device information element a device interface list that contains all the device /// interfaces that the device supports. /// /// /// /// /// To return only devices that support a device interface of a specified class, set the DIGCF_DEVICEINTERFACE flag and use the /// ClassGuid parameter to supply the class GUID of the device interface class. The function adds to the device information set a /// device information element that represents such a device and then adds a device interface of the specified class to the device /// interface list for that device information element. /// /// /// /// /// In addition, you can use the following filtering options to control whether SetupDiGetClassDevs returns only devices that /// support the system default interface for device interface classes: /// /// /// /// /// To return only the device that supports the system default interface, if one is set, for a specified device interface class, set /// the DIGCF_DEVICEINTERFACE flag, set the DIGCF_DEFAULT flag, and use ClassGuid to supply the class GUID of the device interface /// class. The function adds to the device information set a device information element that represents such a device and then adds /// the system default interface to the device interface list for that device information element. /// /// /// /// /// To return a device that supports a system default interface for an unspecified device interface class, set the /// DIGCF_DEVICEINTERFACE flag, set the DIGCF_ALLCLASSES flag, set the DIGCF_DEFAULT flag, and set ClassGuid to NULL. The /// function adds to the device information set a device information element that represents such a device and then adds the system /// default interface to the device interface list for that device information element. /// /// /// /// You can also use the following options in combination with the other options to further restrict which devices are returned: /// /// /// To return only devices that are present in the system, set the DIGCF_PRESENT flag. /// /// /// To return only devices that are part of the current hardware profile, set the DIGCF_PROFILE flag. /// /// /// /// To return only a specific device, set the DIGCF_DEVICEINTERFACE flag and use the Enumerator parameter to supply the device /// instance ID of the device. To include all possible devices, set Enumerator to NULL. /// /// /// /// Examples /// The following are some examples of how to use the SetupDiGetClassDevs function. /// Example 1: Build a list of all devices in the system, including devices that are not currently present. /// /// Handle = SetupDiGetClassDevs(NULL, NULL, NULL, DIGCF_ALLCLASSES); /// /// Example 2: Build a list of all devices that are present in the system. /// /// Handle = SetupDiGetClassDevs(NULL, NULL, NULL, DIGCF_ALLCLASSES | DIGCF_PRESENT); /// /// /// Example 3: Build a list of all devices that are present in the system that are from the network adapter device setup class. /// /// /// Handle = SetupDiGetClassDevs(&GUID_DEVCLASS_NET, NULL, NULL, DIGCF_PRESENT); /// /// /// Example 4: Build a list of all devices that are present in the system that have enabled an interface from the storage /// volume device interface class. /// /// /// Handle = SetupDiGetClassDevs(&GUID_DEVINTERFACE_VOLUME, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); /// /// /// Example 5: Build a list of all devices that are present in the system but do not belong to any known device setup class /// (Windows Vista and later versions of Windows). /// /// /// Note You cannot set the ClassGuid parameter to GUID_DEVCLASS_UNKNOWN to detect devices with an unknown setup class. /// Instead, you must follow this example. /// /// /// DeviceInfoSet = SetupDiGetClassDevs( NULL, NULL, NULL, DIGCF_ALLCLASSES | DIGCF_PRESENT); ZeroMemory(&DeviceInfoData, sizeof(SP_DEVINFO_DATA)); DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA); DeviceIndex = 0; while (SetupDiEnumDeviceInfo( DeviceInfoSet, DeviceIndex, &DeviceInfoData)) { DeviceIndex++; if (!SetupDiGetDeviceProperty( DeviceInfoSet, &DeviceInfoData, &DEVPKEY_Device_Class, &PropType, (PBYTE)&DevGuid, sizeof(GUID), &Size, 0) || PropType != DEVPROP_TYPE_GUID) { Error = GetLastError(); if (Error == ERROR_NOT_FOUND) { \\ \\ This device has an unknown device setup class. \\ } } } if (DeviceInfoSet) { SetupDiDestroyDeviceInfoList(DeviceInfoSet); } /// /// // https://docs.microsoft.com/en-us/windows/win32/api/setupapi/nf-setupapi-setupdigetclassdevsw WINSETUPAPI HDEVINFO // SetupDiGetClassDevsW( const GUID *ClassGuid, PCWSTR Enumerator, HWND hwndParent, DWORD Flags ); [DllImport(Lib_SetupAPI, SetLastError = true, CharSet = CharSet.Auto)] [PInvokeData("setupapi.h", MSDNShortId = "NF:setupapi.SetupDiGetClassDevsW")] public static extern SafeHDEVINFO SetupDiGetClassDevs(in Guid ClassGuid, [In, Optional] string Enumerator, [In, Optional] HWND hwndParent, DIGCF Flags); /// /// The SetupDiGetClassDevs function returns a handle to a device information set that contains requested device information /// elements for a local computer. /// /// /// A pointer to the GUID for a device setup class or a device interface class. This pointer is optional and can be NULL. For /// more information about how to set ClassGuid, see the following Remarks section. /// /// /// A pointer to a NULL-terminated string that specifies: /// /// /// /// An identifier (ID) of a Plug and Play (PnP) enumerator. This ID can either be the value's globally unique identifier (GUID) or /// symbolic name. For example, "PCI" can be used to specify the PCI PnP value. Other examples of symbolic names for PnP values /// include "USB," "PCMCIA," and "SCSI". /// /// /// /// A PnP device instance ID. When specifying a PnP device instance ID, DIGCF_DEVICEINTERFACE must be set in the Flags parameter. /// /// /// This pointer is optional and can be /// NULL /// . If an /// enumeration /// value is not used to select devices, set /// Enumerator /// to /// NULL /// For more information about how to set the Enumerator value, see the following Remarks section. /// /// /// A handle to the top-level window to be used for a user interface that is associated with installing a device instance in the /// device information set. This handle is optional and can be NULL. /// /// /// /// A variable of type DWORD that specifies control options that filter the device information elements that are added to the device /// information set. This parameter can be a bitwise OR of zero or more of the following flags. For more information about combining /// these flags, see the following Remarks section. /// /// DIGCF_ALLCLASSES /// Return a list of installed devices for all device setup classes or all device interface classes. /// DIGCF_DEVICEINTERFACE /// /// Return devices that support device interfaces for the specified device interface classes. This flag must be set in the Flags /// parameter if the Enumerator parameter specifies a device instance ID. /// /// DIGCF_DEFAULT /// /// Return only the device that is associated with the system default device interface, if one is set, for the specified device /// interface classes. /// /// DIGCF_PRESENT /// Return only devices that are currently present in a system. /// DIGCF_PROFILE /// Return only devices that are a part of the current hardware profile. /// /// /// If the operation succeeds, SetupDiGetClassDevs returns a handle to a device information set that contains all installed /// devices that matched the supplied parameters. If the operation fails, the function returns INVALID_HANDLE_VALUE. To get extended /// error information, call GetLastError. /// /// /// /// The caller of SetupDiGetClassDevs must delete the returned device information set when it is no longer needed by calling /// . /// /// Call SetupDiGetClassDevsEx to retrieve the devices for a class on a remote computer. /// Device Setup Class Control Options /// /// Use the following filtering options to control whether SetupDiGetClassDevs returns devices for all device setup classes /// or only for a specified device setup class: /// /// /// /// To return devices for all device setup classes, set the DIGCF_ALLCLASSES flag, and set the ClassGuid parameter to NULL. /// /// /// /// To return devices only for a specific device setup class, do not set DIGCF_ALLCLASSES, and use ClassGuid to supply the GUID of /// the device setup class. /// /// /// /// /// In addition, you can use the following filtering options in combination with one another to further restrict which devices are returned: /// /// /// /// To return only devices that are present in the system, set the DIGCF_PRESENT flag. /// /// /// To return only devices that are part of the current hardware profile, set the DIGCF_PROFILE flag. /// /// /// /// To return devices only for a specific PnP enumerator, use the Enumerator parameter to supply the GUID or symbolic name of the /// enumerator. If Enumerator is NULL, SetupDiGetClassDevs returns devices for all PnP enumerators. /// /// /// /// Device Interface Class Control Options /// /// Use the following filtering options to control whether SetupDiGetClassDevs returns devices that support any device /// interface class or only devices that support a specified device interface class: /// /// /// /// /// To return devices that support a device interface of any class, set the DIGCF_DEVICEINTERFACE flag, set the DIGCF_ALLCLASSES /// flag, and set ClassGuid to NULL. The function adds to the device information set a device information element that /// represents such a device and then adds to the device information element a device interface list that contains all the device /// interfaces that the device supports. /// /// /// /// /// To return only devices that support a device interface of a specified class, set the DIGCF_DEVICEINTERFACE flag and use the /// ClassGuid parameter to supply the class GUID of the device interface class. The function adds to the device information set a /// device information element that represents such a device and then adds a device interface of the specified class to the device /// interface list for that device information element. /// /// /// /// /// In addition, you can use the following filtering options to control whether SetupDiGetClassDevs returns only devices that /// support the system default interface for device interface classes: /// /// /// /// /// To return only the device that supports the system default interface, if one is set, for a specified device interface class, set /// the DIGCF_DEVICEINTERFACE flag, set the DIGCF_DEFAULT flag, and use ClassGuid to supply the class GUID of the device interface /// class. The function adds to the device information set a device information element that represents such a device and then adds /// the system default interface to the device interface list for that device information element. /// /// /// /// /// To return a device that supports a system default interface for an unspecified device interface class, set the /// DIGCF_DEVICEINTERFACE flag, set the DIGCF_ALLCLASSES flag, set the DIGCF_DEFAULT flag, and set ClassGuid to NULL. The /// function adds to the device information set a device information element that represents such a device and then adds the system /// default interface to the device interface list for that device information element. /// /// /// /// You can also use the following options in combination with the other options to further restrict which devices are returned: /// /// /// To return only devices that are present in the system, set the DIGCF_PRESENT flag. /// /// /// To return only devices that are part of the current hardware profile, set the DIGCF_PROFILE flag. /// /// /// /// To return only a specific device, set the DIGCF_DEVICEINTERFACE flag and use the Enumerator parameter to supply the device /// instance ID of the device. To include all possible devices, set Enumerator to NULL. /// /// /// /// Examples /// The following are some examples of how to use the SetupDiGetClassDevs function. /// Example 1: Build a list of all devices in the system, including devices that are not currently present. /// /// Handle = SetupDiGetClassDevs(NULL, NULL, NULL, DIGCF_ALLCLASSES); /// /// Example 2: Build a list of all devices that are present in the system. /// /// Handle = SetupDiGetClassDevs(NULL, NULL, NULL, DIGCF_ALLCLASSES | DIGCF_PRESENT); /// /// /// Example 3: Build a list of all devices that are present in the system that are from the network adapter device setup class. /// /// /// Handle = SetupDiGetClassDevs(&GUID_DEVCLASS_NET, NULL, NULL, DIGCF_PRESENT); /// /// /// Example 4: Build a list of all devices that are present in the system that have enabled an interface from the storage /// volume device interface class. /// /// /// Handle = SetupDiGetClassDevs(&GUID_DEVINTERFACE_VOLUME, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); /// /// /// Example 5: Build a list of all devices that are present in the system but do not belong to any known device setup class /// (Windows Vista and later versions of Windows). /// /// /// Note You cannot set the ClassGuid parameter to GUID_DEVCLASS_UNKNOWN to detect devices with an unknown setup class. /// Instead, you must follow this example. /// /// /// DeviceInfoSet = SetupDiGetClassDevs( NULL, NULL, NULL, DIGCF_ALLCLASSES | DIGCF_PRESENT); ZeroMemory(&DeviceInfoData, sizeof(SP_DEVINFO_DATA)); DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA); DeviceIndex = 0; while (SetupDiEnumDeviceInfo( DeviceInfoSet, DeviceIndex, &DeviceInfoData)) { DeviceIndex++; if (!SetupDiGetDeviceProperty( DeviceInfoSet, &DeviceInfoData, &DEVPKEY_Device_Class, &PropType, (PBYTE)&DevGuid, sizeof(GUID), &Size, 0) || PropType != DEVPROP_TYPE_GUID) { Error = GetLastError(); if (Error == ERROR_NOT_FOUND) { \\ \\ This device has an unknown device setup class. \\ } } } if (DeviceInfoSet) { SetupDiDestroyDeviceInfoList(DeviceInfoSet); } /// /// // https://docs.microsoft.com/en-us/windows/win32/api/setupapi/nf-setupapi-setupdigetclassdevsw WINSETUPAPI HDEVINFO // SetupDiGetClassDevsW( const GUID *ClassGuid, PCWSTR Enumerator, HWND hwndParent, DWORD Flags ); [DllImport(Lib_SetupAPI, SetLastError = true, CharSet = CharSet.Auto)] [PInvokeData("setupapi.h", MSDNShortId = "NF:setupapi.SetupDiGetClassDevsW")] public static extern SafeHDEVINFO SetupDiGetClassDevs([In, Optional] IntPtr ClassGuid, [In, Optional] string Enumerator, [In, Optional] HWND hwndParent, DIGCF Flags); /// /// The SetupDiGetClassDevsEx function returns a handle to a device information set that contains requested device /// information elements for a local or a remote computer. /// /// /// A pointer to the GUID for a device setup class or a device interface class. This pointer is optional and can be NULL. If /// a GUID value is not used to select devices, set ClassGuid to NULL. For more information about how to use ClassGuid, see /// the following Remarks section. /// /// /// A pointer to a NULL-terminated string that specifies: /// /// /// An identifier (ID) of a Plug and Play (PnP) enumerator. This ID can either be the enumerator's globally unique identifier (GUID) /// or symbolic name. For example, "PCI" can be used to specify the PCI PnP enumerator. Other examples of symbolic names for PnP /// enumerators include "USB", "PCMCIA", and "SCSI". /// /// A PnP device instance IDs. When specifying a PnP device instance ID, DIGCF_DEVICEINTERFACE must be set in the Flags parameter /// /// This pointer is optional and can be NULL. If an Enumerator value is not used to select devices, set Enumerator to NULL. /// For more information about how to set the Enumerator value, see the following Remarks section. /// /// /// A handle to the top-level window to be used for a user interface that is associated with installing a device instance in the /// device information set. This handle is optional and can be NULL. /// /// /// /// A variable of type DWORD that specifies control options that filter the device information elements that are added to the device /// information set. This parameter can be a bitwise OR of one or more of the following flags. For more information about combining /// these control options, see the following Remarks section. /// /// /// /// DIGCF_ALLCLASSES /// Return a list of installed devices for the specified device setup classes or device interface classes. /// /// /// DIGCF_DEVICEINTERFACE /// /// Return devices that support device interfaces for the specified device interface classes. This flag must be set in the Flags /// parameter if the Enumerator parameter specifies a device instance ID. /// /// /// /// DIGCF_DEFAULT /// /// Return only the device that is associated with the system default device interface, if one is set, for the specified device /// interface classes. /// /// /// /// DIGCF_PRESENT /// Return only devices that are currently present. /// /// /// DIGCF_PROFILE /// Return only devices that are a part of the current hardware profile. /// /// /// /// /// The handle to an existing device information set to which SetupDiGetClassDevsEx adds the requested device information /// elements. This parameter is optional and can be set to NULL. For more information about using this parameter, see the /// following Remarks section. /// /// /// A pointer to a constant string that contains the name of a remote computer on which the devices reside. A value of NULL /// for MachineName specifies that the device is installed on the local computer. /// /// Reserved for internal use. This parameter must be set to NULL. /// /// If the operation succeeds, SetupDiGetClassDevsEx returns a handle to a device information set that contains all installed /// devices that matched the supplied parameters. If the operation fails, the function returns INVALID_HANDLE_VALUE. To get extended /// error information, call GetLastError. /// /// /// /// The caller of SetupDiGetClassDevsEx must delete the returned device information set when it is no longer needed by /// calling SetupDiDestroyDeviceInfoList. /// /// /// If DeviceInfoSet is NULL, SetupDiGetClassDevsEx creates a new device information set that contains the retrieved /// device information elements and returns a handle to the new device information set. If the caller requests that the function /// retrieve devices for a device setup class that is supplied by the ClassGuid parameter, the function sets the device setup class /// of the new device information set to the supplied class GUID. /// /// /// If DeviceInfoSet is not set to NULL, the function adds the retrieved device information elements to the device /// information set that is associated with the supplied handle, and returns the supplied handle. If ClassGuid supplies a device /// setup class, the device setup class of the supplied device information set must be set to the supplied class GUID. /// /// Device Setup Class Control Options /// /// Use the following filtering options to control whether SetupDiGetClassDevsEx returns devices for all device setup classes /// or only for a specified device setup class: /// /// /// To return devices for all device setup classes, set the DIGCF_ALLCLASSES flag and set the ClassGuid parameter to NULL. /// /// To return devices only for a specific device setup class, do not set DIGCF_ALLCLASSES and use ClassGuid to supply the GUID of /// the device setup class. /// /// /// In addition, you can use the following filtering options to further restrict which devices are returned. /// /// To return only devices that are present in the system, set the DIGCF_PRESENT flag. /// To return only devices that are part of the current hardware profile, set the DIGCF_PROFILE flag. /// /// To return devices for a specific PnP enumerator only, use the Enumerator parameter to supply the GUID or symbolic name of the /// enumerator. If Enumerator is NULL, SetupDiGetClassDevsEx returns devices for all PnP enumerators. /// /// /// Device Interface Class Control Options /// /// Use the following filtering options to control whether SetupDiGetClassDevsEx returns devices that support any device /// interface class or only devices that support a specified device interface class: /// /// /// /// To return devices that support a device interface of any class, set the DIGCF_DEVICEINTERFACE flag, set the DIGCF_ALLCLASSES /// flag, and set ClassGuid to NULL. The function adds to the device information set a device information element that /// represents such a device, and then adds to the device information element a device interface list that contains all the device /// interfaces that the device supports. /// /// /// To return only devices that support a device interface of a specified class, set the DIGCF_DEVICEINTERFACE flag and use the /// ClassGuid parameter to supply the class GUID of the device interface class. The function adds to the device information set a /// device information element that represents such a device, and then adds a device interface of the specified class to the device /// interface list for that device information element. /// /// /// /// In addition, you can use the following filtering options to control whether SetupDiGetClassDevsEx returns only devices /// that support the system default interface for device interface classes: /// /// /// /// To return only the device that supports the system default interface, if one is set, for a specified device interface class, set /// the DIGCF_DEVICEINTERFACE flag, set the DIGCF_DEFAULT flag, and use ClassGuid to supply the class GUID of the device interface /// class. The function adds to the device information set a device information element that represents such a device, and then adds /// the system default interface to the device interface list for that device information element. /// /// /// To return a device that supports a system default interface for an unspecified device interface class, set the /// DIGCF_DEVICEINTERFACE flag, set the DIGCF_ALLCLASSES flag, set the DIGCF_DEFAULT flag, and set ClassGuid to NULL. The /// function adds to the device information set a device information element that represents such a device, and then adds the system /// default interface to the device interface list for that device information element. /// /// /// You can also use the following options in combination with the other options to further restrict which devices are returned. /// /// To return only devices that are present in the system, set the DIGCF_PRESENT flag. /// To return only devices that are part of the current hardware profile, set the DIGCF_PROFILE flag. /// /// To return only a specific device, set the DIGCF_DEVICEINTERFACE flag and use the Enumerator parameter to supply the device /// instance ID of the device. To include all possible devices, set Enumerator to NULL. /// /// /// Retrieving Devices in a Device Setup Class That Support a Device Interface Class /// /// An installer can use SetupDiGetClassDevsEx to retrieve a list of devices of a particular device setup class that support /// a device interface of a specified device interface class. For example, to retrieve a list of all devices on a local computer /// that support a device interface in the "mounted device" interface class and that are members of the "Volume" device setup class, /// an installer should perform the following operations: /// /// /// /// Call SetupDiCreateDeviceInfoList to create an empty device information set for the "Volume" device setup class. Set ClassGuid to /// a pointer to the class GUID for the "Volume" device setup class and set hwndParent as appropriate. In response to such a call, /// the function will return a handle to type HDEVINFO to the device information set. /// /// /// Call SetupDiGetClassDevsEx with the following settings: /// /// Set ClassGuid to a pointer to the class GUID of the "mounted device" device interface class. /// Set Flags to DIGCF_DEVICEINTERFACE. /// Set DeviceInfoSet to the HDEVINFO handle obtained in step (1). /// Set hwndParent as appropriate and the remaining parameters to NULL. /// /// /// /// /// In an operation of this type, SetupDiGetClassDevsEx returns a device if the device setup class of the device is the same /// as the supplied device information set and if the device supports a device interface whose class is the same as the specified /// device interface class. /// /// // https://docs.microsoft.com/en-us/windows/win32/api/setupapi/nf-setupapi-setupdigetclassdevsexa WINSETUPAPI HDEVINFO // SetupDiGetClassDevsExA( const GUID *ClassGuid, PCSTR Enumerator, HWND hwndParent, DWORD Flags, HDEVINFO DeviceInfoSet, PCSTR // MachineName, PVOID Reserved ); [DllImport(Lib_SetupAPI, SetLastError = true, CharSet = CharSet.Auto)] [PInvokeData("setupapi.h", MSDNShortId = "NF:setupapi.SetupDiGetClassDevsExA")] public static extern SafeHDEVINFO SetupDiGetClassDevsEx(in Guid ClassGuid, [In, Optional, MarshalAs(UnmanagedType.LPTStr)] string Enumerator, [In, Optional] HWND hwndParent, DIGCF Flags, [In, Optional] HDEVINFO DeviceInfoSet, [In, Optional, MarshalAs(UnmanagedType.LPTStr)] string MachineName, [In, Optional] IntPtr Reserved); /// /// The SetupDiGetClassDevsEx function returns a handle to a device information set that contains requested device /// information elements for a local or a remote computer. /// /// /// A pointer to the GUID for a device setup class or a device interface class. This pointer is optional and can be NULL. If /// a GUID value is not used to select devices, set ClassGuid to NULL. For more information about how to use ClassGuid, see /// the following Remarks section. /// /// /// A pointer to a NULL-terminated string that specifies: /// /// /// An identifier (ID) of a Plug and Play (PnP) enumerator. This ID can either be the enumerator's globally unique identifier (GUID) /// or symbolic name. For example, "PCI" can be used to specify the PCI PnP enumerator. Other examples of symbolic names for PnP /// enumerators include "USB", "PCMCIA", and "SCSI". /// /// A PnP device instance IDs. When specifying a PnP device instance ID, DIGCF_DEVICEINTERFACE must be set in the Flags parameter /// /// This pointer is optional and can be NULL. If an Enumerator value is not used to select devices, set Enumerator to NULL. /// For more information about how to set the Enumerator value, see the following Remarks section. /// /// /// A handle to the top-level window to be used for a user interface that is associated with installing a device instance in the /// device information set. This handle is optional and can be NULL. /// /// /// /// A variable of type DWORD that specifies control options that filter the device information elements that are added to the device /// information set. This parameter can be a bitwise OR of one or more of the following flags. For more information about combining /// these control options, see the following Remarks section. /// /// /// /// DIGCF_ALLCLASSES /// Return a list of installed devices for the specified device setup classes or device interface classes. /// /// /// DIGCF_DEVICEINTERFACE /// /// Return devices that support device interfaces for the specified device interface classes. This flag must be set in the Flags /// parameter if the Enumerator parameter specifies a device instance ID. /// /// /// /// DIGCF_DEFAULT /// /// Return only the device that is associated with the system default device interface, if one is set, for the specified device /// interface classes. /// /// /// /// DIGCF_PRESENT /// Return only devices that are currently present. /// /// /// DIGCF_PROFILE /// Return only devices that are a part of the current hardware profile. /// /// /// /// /// The handle to an existing device information set to which SetupDiGetClassDevsEx adds the requested device information /// elements. This parameter is optional and can be set to NULL. For more information about using this parameter, see the /// following Remarks section. /// /// /// A pointer to a constant string that contains the name of a remote computer on which the devices reside. A value of NULL /// for MachineName specifies that the device is installed on the local computer. /// /// Reserved for internal use. This parameter must be set to NULL. /// /// If the operation succeeds, SetupDiGetClassDevsEx returns a handle to a device information set that contains all installed /// devices that matched the supplied parameters. If the operation fails, the function returns INVALID_HANDLE_VALUE. To get extended /// error information, call GetLastError. /// /// /// /// The caller of SetupDiGetClassDevsEx must delete the returned device information set when it is no longer needed by /// calling SetupDiDestroyDeviceInfoList. /// /// /// If DeviceInfoSet is NULL, SetupDiGetClassDevsEx creates a new device information set that contains the retrieved /// device information elements and returns a handle to the new device information set. If the caller requests that the function /// retrieve devices for a device setup class that is supplied by the ClassGuid parameter, the function sets the device setup class /// of the new device information set to the supplied class GUID. /// /// /// If DeviceInfoSet is not set to NULL, the function adds the retrieved device information elements to the device /// information set that is associated with the supplied handle, and returns the supplied handle. If ClassGuid supplies a device /// setup class, the device setup class of the supplied device information set must be set to the supplied class GUID. /// /// Device Setup Class Control Options /// /// Use the following filtering options to control whether SetupDiGetClassDevsEx returns devices for all device setup classes /// or only for a specified device setup class: /// /// /// To return devices for all device setup classes, set the DIGCF_ALLCLASSES flag and set the ClassGuid parameter to NULL. /// /// To return devices only for a specific device setup class, do not set DIGCF_ALLCLASSES and use ClassGuid to supply the GUID of /// the device setup class. /// /// /// In addition, you can use the following filtering options to further restrict which devices are returned. /// /// To return only devices that are present in the system, set the DIGCF_PRESENT flag. /// To return only devices that are part of the current hardware profile, set the DIGCF_PROFILE flag. /// /// To return devices for a specific PnP enumerator only, use the Enumerator parameter to supply the GUID or symbolic name of the /// enumerator. If Enumerator is NULL, SetupDiGetClassDevsEx returns devices for all PnP enumerators. /// /// /// Device Interface Class Control Options /// /// Use the following filtering options to control whether SetupDiGetClassDevsEx returns devices that support any device /// interface class or only devices that support a specified device interface class: /// /// /// /// To return devices that support a device interface of any class, set the DIGCF_DEVICEINTERFACE flag, set the DIGCF_ALLCLASSES /// flag, and set ClassGuid to NULL. The function adds to the device information set a device information element that /// represents such a device, and then adds to the device information element a device interface list that contains all the device /// interfaces that the device supports. /// /// /// To return only devices that support a device interface of a specified class, set the DIGCF_DEVICEINTERFACE flag and use the /// ClassGuid parameter to supply the class GUID of the device interface class. The function adds to the device information set a /// device information element that represents such a device, and then adds a device interface of the specified class to the device /// interface list for that device information element. /// /// /// /// In addition, you can use the following filtering options to control whether SetupDiGetClassDevsEx returns only devices /// that support the system default interface for device interface classes: /// /// /// /// To return only the device that supports the system default interface, if one is set, for a specified device interface class, set /// the DIGCF_DEVICEINTERFACE flag, set the DIGCF_DEFAULT flag, and use ClassGuid to supply the class GUID of the device interface /// class. The function adds to the device information set a device information element that represents such a device, and then adds /// the system default interface to the device interface list for that device information element. /// /// /// To return a device that supports a system default interface for an unspecified device interface class, set the /// DIGCF_DEVICEINTERFACE flag, set the DIGCF_ALLCLASSES flag, set the DIGCF_DEFAULT flag, and set ClassGuid to NULL. The /// function adds to the device information set a device information element that represents such a device, and then adds the system /// default interface to the device interface list for that device information element. /// /// /// You can also use the following options in combination with the other options to further restrict which devices are returned. /// /// To return only devices that are present in the system, set the DIGCF_PRESENT flag. /// To return only devices that are part of the current hardware profile, set the DIGCF_PROFILE flag. /// /// To return only a specific device, set the DIGCF_DEVICEINTERFACE flag and use the Enumerator parameter to supply the device /// instance ID of the device. To include all possible devices, set Enumerator to NULL. /// /// /// Retrieving Devices in a Device Setup Class That Support a Device Interface Class /// /// An installer can use SetupDiGetClassDevsEx to retrieve a list of devices of a particular device setup class that support /// a device interface of a specified device interface class. For example, to retrieve a list of all devices on a local computer /// that support a device interface in the "mounted device" interface class and that are members of the "Volume" device setup class, /// an installer should perform the following operations: /// /// /// /// Call SetupDiCreateDeviceInfoList to create an empty device information set for the "Volume" device setup class. Set ClassGuid to /// a pointer to the class GUID for the "Volume" device setup class and set hwndParent as appropriate. In response to such a call, /// the function will return a handle to type HDEVINFO to the device information set. /// /// /// Call SetupDiGetClassDevsEx with the following settings: /// /// Set ClassGuid to a pointer to the class GUID of the "mounted device" device interface class. /// Set Flags to DIGCF_DEVICEINTERFACE. /// Set DeviceInfoSet to the HDEVINFO handle obtained in step (1). /// Set hwndParent as appropriate and the remaining parameters to NULL. /// /// /// /// /// In an operation of this type, SetupDiGetClassDevsEx returns a device if the device setup class of the device is the same /// as the supplied device information set and if the device supports a device interface whose class is the same as the specified /// device interface class. /// /// // https://docs.microsoft.com/en-us/windows/win32/api/setupapi/nf-setupapi-setupdigetclassdevsexa WINSETUPAPI HDEVINFO // SetupDiGetClassDevsExA( const GUID *ClassGuid, PCSTR Enumerator, HWND hwndParent, DWORD Flags, HDEVINFO DeviceInfoSet, PCSTR // MachineName, PVOID Reserved ); [DllImport(Lib_SetupAPI, SetLastError = true, CharSet = CharSet.Auto)] [PInvokeData("setupapi.h", MSDNShortId = "NF:setupapi.SetupDiGetClassDevsExA")] public static extern SafeHDEVINFO SetupDiGetClassDevsEx([In, Optional] IntPtr ClassGuid, [In, Optional, MarshalAs(UnmanagedType.LPTStr)] string Enumerator, [In, Optional] HWND hwndParent, DIGCF Flags, [In, Optional] HDEVINFO DeviceInfoSet, [In, Optional, MarshalAs(UnmanagedType.LPTStr)] string MachineName, [In, Optional] IntPtr Reserved); /// The SetupDiGetClassImageIndex function retrieves the index within the class image list of a specified class. /// /// A pointer to an SP_CLASSIMAGELIST_DATA structure that describes a class image list that includes the image for the device setup /// class that is specified by the ClassGuid parameter. /// /// /// A pointer to the GUID of the device setup class for which to retrieve the index of the class image in the specified class image list. /// /// /// A pointer to an INT-typed variable that receives the index of the specified class image in the class image list. /// /// /// The function returns TRUE if it is successful. Otherwise, it returns FALSE and the logged error can be retrieved /// by a call to GetLastError. /// /// /// If the specified device setup class is not included in the specified class image list, SetupDiGetClassImageIndex returns /// the image index for the Unknown device setup class in the ImageIndex parameter. /// // https://docs.microsoft.com/en-us/windows/win32/api/setupapi/nf-setupapi-setupdigetclassimageindex WINSETUPAPI BOOL // SetupDiGetClassImageIndex( PSP_CLASSIMAGELIST_DATA ClassImageListData, const GUID *ClassGuid, PINT ImageIndex ); [DllImport(Lib_SetupAPI, SetLastError = true, ExactSpelling = true)] [PInvokeData("setupapi.h", MSDNShortId = "NF:setupapi.SetupDiGetClassImageIndex")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool SetupDiGetClassImageIndex(in SP_CLASSIMAGELIST_DATA ClassImageListData, in Guid ClassGuid, out int ImageIndex); /// /// The SetupDiGetClassImageList function builds an image list that contains bitmaps for every installed class and returns /// the list in a data structure. /// /// /// A pointer to an SP_CLASSIMAGELIST_DATA structure to receive information regarding the class image list, including a handle to /// the image list. The cbSize field of this structure must be initialized with the size of the structure, in bytes, before /// calling this function or it will fail. /// /// /// The function returns TRUE if it is successful. Otherwise, it returns FALSE and the logged error can be retrieved /// by a call to GetLastError. /// /// /// The image list built by this function should be destroyed by calling SetupDiDestroyClassImageList. /// Call SetupDiGetClassImageListEx to retrieve the image list for classes installed on a remote computer. /// // https://docs.microsoft.com/en-us/windows/win32/api/setupapi/nf-setupapi-setupdigetclassimagelist WINSETUPAPI BOOL // SetupDiGetClassImageList( PSP_CLASSIMAGELIST_DATA ClassImageListData ); [DllImport(Lib_SetupAPI, SetLastError = true, ExactSpelling = true)] [PInvokeData("setupapi.h", MSDNShortId = "NF:setupapi.SetupDiGetClassImageList")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool SetupDiGetClassImageList(ref SP_CLASSIMAGELIST_DATA ClassImageListData); /// /// The SetupDiGetClassImageListEx function builds an image list of bitmaps for every class installed on a local or remote system. /// /// /// A pointer to an SP_CLASSIMAGELIST_DATA structure to receive information regarding the class image list, including a handle to /// the image list. The cbSize field of this structure must be initialized with the size of the structure, in bytes, before /// calling this function or it will fail. /// /// /// A pointer to NULL-terminated string that supplies the name of a remote system for whose classes SetupDiGetClassImageListEx /// must build the bitmap. This parameter is optional and can be NULL. If MachineName is NULL, /// SetupDiGetClassImageListEx builds the list for the local system. /// /// Must be NULL. /// /// The function returns TRUE if it is successful. Otherwise, it returns FALSE and the logged error can be retrieved /// by a call to GetLastError. /// /// /// The image list built by this function should be destroyed by calling SetupDiDestroyClassImageList. /// /// Note Class-specific icons on a remote computer can only be displayed if the class is also present on the local computer. /// Thus, if the remote computer has class X, but class X is not installed locally, then the generic (unknown) icon will be returned. /// /// // https://docs.microsoft.com/en-us/windows/win32/api/setupapi/nf-setupapi-setupdigetclassimagelistexa WINSETUPAPI BOOL // SetupDiGetClassImageListExA( PSP_CLASSIMAGELIST_DATA ClassImageListData, PCSTR MachineName, PVOID Reserved ); [DllImport(Lib_SetupAPI, SetLastError = true, CharSet = CharSet.Auto)] [PInvokeData("setupapi.h", MSDNShortId = "NF:setupapi.SetupDiGetClassImageListExA")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool SetupDiGetClassImageListEx(ref SP_CLASSIMAGELIST_DATA ClassImageListData, [In, Optional, MarshalAs(UnmanagedType.LPTStr)] string MachineName, [In, Optional] IntPtr Reserved); /// /// The SetupDiGetClassInstallParams function retrieves class installation parameters for a device information set or a /// particular device information element. /// /// A handle to a device information set that contains the class install parameters to retrieve. /// /// A pointer to an SP_DEVINFO_DATA structure that specified a device information element in DeviceInfoSet. This parameter is /// optional and can be NULL. If this parameter is specified, SetupDiGetClassInstallParams retrieves the class /// installation parameters for the specified device. If this parameter is NULL, SetupDiGetClassInstallParams /// retrieves the class install parameters for the global class driver list that is associated with DeviceInfoSet. /// /// /// A pointer to a buffer that contains an SP_CLASSINSTALL_HEADER structure. This structure must have its cbSize member set /// to sizeof( SP_CLASSINSTALL_HEADER ) on input or the buffer is considered to be invalid. On output, the /// InstallFunction member is filled with the device installation function code for the class installation parameters being /// retrieved. If the buffer is large enough, it also receives the class installation parameters structure specific to the function /// code. If ClassInstallParams is not specified, ClassInstallParamsSize must be 0. /// /// /// The size, in bytes, of the ClassInstallParams buffer. If the buffer is supplied, it must be at least as large as sizeof( /// SP_CLASSINSTALL_HEADER ). If the buffer is not supplied, ClassInstallParamsSize must be 0. /// /// /// A pointer to a variable of type DWORD that receives the number of bytes required to store the class install parameters. This /// parameter is optional and can be NULL. /// /// /// The function returns TRUE if it is successful. Otherwise, it returns FALSE and the logged error can be retrieved /// with a call to GetLastError. /// /// /// The class install parameters are specific to a particular device installation function code that is stored in the /// ClassInstallHeader field located at the beginning of the ClassInstallParams buffer. /// // https://docs.microsoft.com/en-us/windows/win32/api/setupapi/nf-setupapi-setupdigetclassinstallparamsa WINSETUPAPI BOOL // SetupDiGetClassInstallParamsA( HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, PSP_CLASSINSTALL_HEADER // ClassInstallParams, DWORD ClassInstallParamsSize, PDWORD RequiredSize ); [DllImport(Lib_SetupAPI, SetLastError = true, CharSet = CharSet.Auto)] [PInvokeData("setupapi.h", MSDNShortId = "NF:setupapi.SetupDiGetClassInstallParamsA")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool SetupDiGetClassInstallParams(HDEVINFO DeviceInfoSet, in SP_DEVINFO_DATA DeviceInfoData, [In, Optional] IntPtr ClassInstallParams, uint ClassInstallParamsSize, out uint RequiredSize); /// Provides a for that is disposed using . public class SafeHDEVINFO : SafeHANDLE { private readonly Lazy detail; /// Initializes a new instance of the class and assigns an existing handle. /// An object that represents the pre-existing handle to use. /// /// to reliably release the handle during the finalization phase; otherwise, (not recommended). /// public SafeHDEVINFO(IntPtr preexistingHandle, bool ownsHandle = true) : base(preexistingHandle, ownsHandle) => detail = new Lazy(GetDetail); /// Initializes a new instance of the class. private SafeHDEVINFO() : base() => detail = new Lazy(GetDetail); /// /// If the device information set is for a remote computer, this member is a configuration manager machine handle for the remote /// computer. If the device information set is for the local computer, this member is HANDLE.NULL. /// public HANDLE MachineHandle => detail.Value.RemoteMachineHandle; /// /// A string that contains the name of the remote computer. If the device information set is for the local computer, this member /// is . /// public string MachineName => detail.Value.RemoteMachineName == "" ? null : detail.Value.RemoteMachineName; /// /// The setup class GUID that is associated with the device information set or if there is no associated /// setup class. /// public Guid? ClassGuid => detail.Value.ClassGuid == Guid.Empty ? null : detail.Value.ClassGuid; /// /// Returns a handle to a device information set that contains requested device information elements for a local or a remote computer. /// /// /// The GUID for a device setup class or a device interface class. This value is optional and can be NULL. If a GUID /// value is not used to select devices, set ClassGuid to NULL. /// /// /// A pointer to a NULL-terminated string that specifies: /// /// /// An identifier (ID) of a Plug and Play (PnP) enumerator. This ID can either be the enumerator's globally unique identifier /// (GUID) or symbolic name. For example, "PCI" can be used to specify the PCI PnP enumerator. Other examples of symbolic names /// for PnP enumerators include "USB", "PCMCIA", and "SCSI". /// /// /// A PnP device instance IDs. When specifying a PnP device instance ID, DIGCF_DEVICEINTERFACE must be set in the Flags parameter /// /// /// /// This pointer is optional and can be NULL. If an Enumerator value is not used to select devices, set Enumerator to NULL. /// /// /// /// /// A value that specifies control options that filter the device information elements that are added to the device information set. /// /// /// /// A string that contains the name of a remote computer on which the devices reside. A value of NULL for MachineName /// specifies that the device is installed on the local computer. /// /// /// If the operation succeeds, SetupDiGetClassDevsEx returns a handle to a device information set that contains all /// installed devices that matched the supplied parameters. If the operation fails, the function returns INVALID_HANDLE_VALUE. /// To get extended error information, call GetLastError. /// /// See for more detail. public static SafeHDEVINFO Create(Guid? classGuid, DIGCF flags = DIGCF.DIGCF_PRESENT, string pnpFilter = null, string machineName = null) { if (classGuid.HasValue) return Win32Error.ThrowLastErrorIfInvalid(SetupDiGetClassDevsEx(classGuid.Value, pnpFilter, default, flags, default, machineName)); else return Win32Error.ThrowLastErrorIfInvalid(SetupDiGetClassDevsEx(IntPtr.Zero, pnpFilter, default, flags, default, machineName)); } /// /// Creates an empty device information set on a remote or a local computer and optionally associates the set with a device /// setup class. /// /// /// The GUID of the device setup class to associate with the newly created device information set. If this parameter is /// specified, only devices of this class can be included in this device information set. If this parameter is set to the device information set is not associated with a specific device setup class. /// /// /// A string that contains the name of a computer on a network. If a name is specified, only devices on that computer can be /// created and opened in this device information set. If this parameter is set to , the device /// information set is for devices on the local computer. /// /// A handle to an empty device information set. /// /// If the device information set is for devices on a remote computer (MachineName is not NULL), all subsequent /// operations on this set or any of its elements must use routines that support device information sets with remote elements. /// The SetupDi Xxx routines that do not provide this support, such as SetupDiCallClassInstaller, have a statement to /// that effect in their reference page. /// public static SafeHDEVINFO CreateEmpty(Guid? classGuid = null, string machineName = null) { if (classGuid.HasValue) return Win32Error.ThrowLastErrorIfInvalid(SetupDiCreateDeviceInfoListEx(classGuid.Value, default, machineName)); else return Win32Error.ThrowLastErrorIfInvalid(SetupDiCreateDeviceInfoListEx(IntPtr.Zero, default, machineName)); } /// Performs an implicit conversion from to . /// The safe handle instance. /// The result of the conversion. public static implicit operator HDEVINFO(SafeHDEVINFO h) => h.handle; /// Adjusts the current handle to include additional requested device information elements. /// /// The GUID for a device setup class or a device interface class. This value is optional and can be NULL. If a GUID /// value is not used to select devices, set ClassGuid to NULL. /// /// /// A pointer to a NULL-terminated string that specifies: /// /// /// An identifier (ID) of a Plug and Play (PnP) enumerator. This ID can either be the enumerator's globally unique identifier /// (GUID) or symbolic name. For example, "PCI" can be used to specify the PCI PnP enumerator. Other examples of symbolic names /// for PnP enumerators include "USB", "PCMCIA", and "SCSI". /// /// /// A PnP device instance IDs. When specifying a PnP device instance ID, DIGCF_DEVICEINTERFACE must be set in the Flags parameter /// /// /// /// This pointer is optional and can be NULL. If an Enumerator value is not used to select devices, set Enumerator to NULL. /// /// /// /// /// A value that specifies control options that filter the device information elements that are added to the device information set. /// /// /// /// If the operation succeeds, SetupDiGetClassDevsEx returns a handle to a device information set that contains all /// installed devices that matched the supplied parameters. If the operation fails, the function returns INVALID_HANDLE_VALUE. /// To get extended error information, call GetLastError. /// /// See for more detail. public void Adjust(Guid? classGuid, DIGCF flags = DIGCF.DIGCF_ALLCLASSES, string pnpFilter = null) { SafeHDEVINFO hNew; if (classGuid.HasValue) hNew = SetupDiGetClassDevsEx(classGuid.Value, pnpFilter, default, flags, handle, MachineName); else hNew = SetupDiGetClassDevsEx(IntPtr.Zero, pnpFilter, default, flags, handle, MachineName); Win32Error.ThrowLastErrorIfInvalid(hNew); SetHandle(hNew.handle); hNew.SetHandleAsInvalid(); } /// protected override bool InternalReleaseHandle() => SetupDiDestroyDeviceInfoList(handle); private SP_DEVINFO_LIST_DETAIL_DATA GetDetail() { SP_DEVINFO_LIST_DETAIL_DATA data = new() { cbSize = IntPtr.Size == 4 ? 550U : (uint)Marshal.SizeOf(typeof(SP_DEVINFO_LIST_DETAIL_DATA)) }; Win32Error.ThrowLastErrorIfFalse(SetupDiGetDeviceInfoListDetail(handle, ref data)); return data; } } } }