Vanara/PInvoke/CfgMgr32/CfgMgr32_3.cs

2964 lines
168 KiB
C#
Raw Blame History

using Microsoft.Win32.SafeHandles;
using System;
using System.Runtime.InteropServices;
using System.Text;
using Vanara.InteropServices;
using static Vanara.PInvoke.AdvApi32;
using static Vanara.PInvoke.SetupAPI;
namespace Vanara.PInvoke
{
/// <summary>Items from the CfgMgr32.dll</summary>
public static partial class CfgMgr32
{
/// <summary>The callback routine invoked by the Configuration Manager when listening for events.</summary>
/// <param name="notify">The handle of the notification context which invoked the callback.</param>
/// <param name="context">A user-provided callback context.</param>
/// <param name="action">The device action which triggered the callback.</param>
/// <param name="eventData">The callback data.</param>
/// <param name="eventDataSize">The size of the callback data struct.</param>
/// <returns>
/// If responding to a <see cref="CM_NOTIFY_ACTION.CM_NOTIFY_ACTION_DEVICEQUERYREMOVE"/> notification, the <see
/// cref="CM_NOTIFY_CALLBACK"/> callback should return either <see cref="Win32Error.ERROR_SUCCESS"/> or <see
/// cref="Win32Error.ERROR_CANCELLED"/>, as appropriate. Otherwise, the callback should return <see
/// cref="Win32Error.ERROR_SUCCESS"/>. The callback should not return any other values.
/// </returns>
[UnmanagedFunctionPointer(CallingConvention.Winapi)]
public delegate Win32Error CM_NOTIFY_CALLBACK(HCMNOTIFICATION notify, [Optional] IntPtr context, CM_NOTIFY_ACTION action, [In] IntPtr eventData, uint eventDataSize);
/// <summary>
/// A variable of ULONG type that supplies one of the following flag values that apply if the caller supplies a device instance identifier
/// </summary>
[PInvokeData("cfgmgr32.h", MSDNShortId = "NF:cfgmgr32.CM_Locate_DevNodeA")]
[Flags]
public enum CM_LOCATE_DEVINST : uint
{
/// <summary></summary>
CM_LOCATE_DEVINST_NORMAL = CM_LOCATE_DEVNODE.CM_LOCATE_DEVNODE_NORMAL,
/// <summary></summary>
CM_LOCATE_DEVINST_PHANTOM = CM_LOCATE_DEVNODE.CM_LOCATE_DEVNODE_PHANTOM,
/// <summary></summary>
CM_LOCATE_DEVINST_CANCELREMOVE = CM_LOCATE_DEVNODE.CM_LOCATE_DEVNODE_CANCELREMOVE,
/// <summary></summary>
CM_LOCATE_DEVINST_NOVALIDATION = CM_LOCATE_DEVNODE.CM_LOCATE_DEVNODE_NOVALIDATION,
}
/// <summary>
/// A variable of ULONG type that supplies one of the following flag values that apply if the caller supplies a device instance identifier
/// </summary>
[PInvokeData("cfgmgr32.h", MSDNShortId = "NF:cfgmgr32.CM_Locate_DevNodeA")]
[Flags]
public enum CM_LOCATE_DEVNODE : uint
{
/// <summary>
/// The function retrieves the device instance handle for the specified device only if the device is currently configured in the
/// device tree.
/// </summary>
CM_LOCATE_DEVNODE_NORMAL = 0x00000000,
/// <summary>
/// The function retrieves a device instance handle for the specified device if the device is currently configured in the device
/// tree or the device is a nonpresent device that is not currently configured in the device tree.
/// </summary>
CM_LOCATE_DEVNODE_PHANTOM = 0x00000001,
/// <summary>
/// The function retrieves a device instance handle for the specified device if the device is currently configured in the device
/// tree or in the process of being removed from the device tree. If the device is in the process of being removed, the function
/// cancels the removal of the device.
/// </summary>
CM_LOCATE_DEVNODE_CANCELREMOVE = 0x00000002,
/// <summary>Not used.</summary>
CM_LOCATE_DEVNODE_NOVALIDATION = 0x00000004,
}
/// <summary>This enumeration identifies Plug and Play device event types.</summary>
/// <remarks>
/// When a driver calls the CM_Register_Notification function, the pCallback parameter contains a pointer to a routine to be called
/// when a specified PnP event occurs. The callback routine's Action parameter is a value from the <c>CM_NOTIFY_ACTION</c> enumeration.
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/cfgmgr32/ne-cfgmgr32-cm_notify_action typedef enum _CM_NOTIFY_ACTION {
// CM_NOTIFY_ACTION_DEVICEINTERFACEARRIVAL, CM_NOTIFY_ACTION_DEVICEINTERFACEREMOVAL, CM_NOTIFY_ACTION_DEVICEQUERYREMOVE,
// CM_NOTIFY_ACTION_DEVICEQUERYREMOVEFAILED, CM_NOTIFY_ACTION_DEVICEREMOVEPENDING, CM_NOTIFY_ACTION_DEVICEREMOVECOMPLETE,
// CM_NOTIFY_ACTION_DEVICECUSTOMEVENT, CM_NOTIFY_ACTION_DEVICEINSTANCEENUMERATED, CM_NOTIFY_ACTION_DEVICEINSTANCESTARTED,
// CM_NOTIFY_ACTION_DEVICEINSTANCEREMOVED, CM_NOTIFY_ACTION_MAX } CM_NOTIFY_ACTION, *PCM_NOTIFY_ACTION;
[PInvokeData("cfgmgr32.h", MSDNShortId = "NE:cfgmgr32._CM_NOTIFY_ACTION")]
public enum CM_NOTIFY_ACTION
{
/// <summary>
/// For this value, set the FilterType member of the CM_NOTIFY_FILTER structure to CM_NOTIFY_FILTER_TYPE_DEVICEINTERFACE. This
/// action indicates that a device interface that meets your filter criteria has been enabled.
/// </summary>
CM_NOTIFY_ACTION_DEVICEINTERFACEARRIVAL = 0,
/// <summary>
/// For this value, set the FilterType member of the CM_NOTIFY_FILTER structure to CM_NOTIFY_FILTER_TYPE_DEVICEINTERFACE. This
/// action indicates that a device interface that meets your filter criteria has been disabled.
/// </summary>
CM_NOTIFY_ACTION_DEVICEINTERFACEREMOVAL,
/// <summary>
/// For this value, set the FilterType member of the CM_NOTIFY_FILTER structure to CM_NOTIFY_FILTER_TYPE_DEVICEHANDLE. This
/// action indicates that the device is being query removed. In order to allow the query remove to succeed, call CloseHandle to
/// close any handles you have open to the device. If you do not do this, your open handle prevents the query remove of this
/// device from succeeding. See Registering for Notification of Device Interface Arrival and Device Removal for more
/// information.To veto the query remove, return ERROR_CANCELLED. However, it is recommended that you do not veto the query
/// remove and allow it to happen by closing any handles you have open to the device.
/// </summary>
CM_NOTIFY_ACTION_DEVICEQUERYREMOVE,
/// <summary>
/// For this value, set the FilterType member of the CM_NOTIFY_FILTER structure to CM_NOTIFY_FILTER_TYPE_DEVICEHANDLE. This
/// action indicates that the query remove of a device was failed. If you closed the handle to this device during a previous
/// notification of CM_NOTIFY_ACTION_DEVICEQUERYREMOVE, open a new handle to the device to continue sending I/O requests to it.
/// See Registering for Notification of Device Interface Arrival and Device Removal for more information.
/// </summary>
CM_NOTIFY_ACTION_DEVICEQUERYREMOVEFAILED,
/// <summary>
/// For this value, set the FilterType member of the CM_NOTIFY_FILTER structure to CM_NOTIFY_FILTER_TYPE_DEVICEHANDLE.The device
/// will be removed. If you still have an open handle to the device, call CloseHandle to close the device handle. See
/// Registering for Notification of Device Interface Arrival and Device Removal for more information. The system may send a
/// CM_NOTIFY_ACTION_DEVICEREMOVEPENDING notification without sending a corresponding CM_NOTIFY_ACTION_DEVICEQUERYREMOVE
/// message. In such cases, the applications and drivers must recover from the loss of the device as best they can.
/// </summary>
CM_NOTIFY_ACTION_DEVICEREMOVEPENDING,
/// <summary>
/// For this value, set the FilterType member of the CM_NOTIFY_FILTER structure to CM_NOTIFY_FILTER_TYPE_DEVICEHANDLE.The device
/// has been removed. If you still have an open handle to the device, call CloseHandle to close the device handle. See
/// Registering for Notification of Device Interface Arrival and Device Removal for more information. The system may send a
/// CM_NOTIFY_ACTION_DEVICEREMOVECOMPLETE notification without sending corresponding CM_NOTIFY_ACTION_DEVICEQUERYREMOVE or
/// CM_NOTIFY_ACTION_DEVICEREMOVEPENDING messages. In such cases, the applications and drivers must recover from the loss of the
/// device as best they can.
/// </summary>
CM_NOTIFY_ACTION_DEVICEREMOVECOMPLETE,
/// <summary>
/// For this value, set the FilterType member of the CM_NOTIFY_FILTER structure to CM_NOTIFY_FILTER_TYPE_DEVICEHANDLE. This
/// action is sent when a driver-defined custom event has occurred.
/// </summary>
CM_NOTIFY_ACTION_DEVICECUSTOMEVENT,
/// <summary>
/// For this value, set the FilterType member of the CM_NOTIFY_FILTER structure to CM_NOTIFY_FILTER_TYPE_DEVICEINSTANCE. This
/// action is sent when a new device instance that meets your filter criteria has been enumerated.
/// </summary>
CM_NOTIFY_ACTION_DEVICEINSTANCEENUMERATED,
/// <summary>
/// For this value, set the FilterType member of the CM_NOTIFY_FILTER structure to CM_NOTIFY_FILTER_TYPE_DEVICEINSTANCE. This
/// action is sent when a device instance that meets your filter criteria becomes started.
/// </summary>
CM_NOTIFY_ACTION_DEVICEINSTANCESTARTED,
/// <summary>
/// For this value, set the FilterType member of the CM_NOTIFY_FILTER structure to CM_NOTIFY_FILTER_TYPE_DEVICEINSTANCE. This
/// action is sent when a device instance that meets your filter criteria is no longer present.
/// </summary>
CM_NOTIFY_ACTION_DEVICEINSTANCEREMOVED,
}
/// <summary>Flags for <see cref="CM_NOTIFY_FILTER"/></summary>
[Flags]
public enum CM_NOTIFY_FILTER_FLAG : uint
{
/// <summary>
/// Register to receive notifications for PnP events for all device interface classes. The memory at
/// <c>pFilter-&gt;u.DeviceInterface.ClassGuid</c> must be zeroes. Do not use this flag with
/// CM_NOTIFY_FILTER_FLAG_ALL_DEVICE_INSTANCES. This flag is only valid if <c>pFilter-&gt;FilterType</c> is CM_NOTIFY_FILTER_TYPE_DEVICEINTERFACE.
/// </summary>
CM_NOTIFY_FILTER_FLAG_ALL_INTERFACE_CLASSES = 0x00000001,
/// <summary>
/// Register to receive notifications for PnP events for all devices. <c>pFilter-&gt;u.DeviceInstance.InstanceId</c> must be an
/// empty string. Do not use this flag with CM_NOTIFY_FILTER_FLAG_ALL_INTERFACE_CLASSES. This flag is only valid if
/// <c>pFilter-&gt;FilterType</c> is CM_NOTIFY_FILTER_TYPE_DEVICEINSTANCE.
/// </summary>
CM_NOTIFY_FILTER_FLAG_ALL_DEVICE_INSTANCES = 0x00000002,
}
/// <summary>Options for <see cref="CM_NOTIFY_FILTER"/></summary>
[PInvokeData("cfgmgr32.h", MSDNShortId = "NS:cfgmgr32._CM_NOTIFY_FILTER")]
public enum CM_NOTIFY_FILTER_TYPE
{
/// <summary>
/// Register for notifications for device interface events. <c>pFilter-&gt;u.DeviceInterface.ClassGuid</c> should be filled in
/// with the GUID of the device interface class to receive notifications for.
/// </summary>
CM_NOTIFY_FILTER_TYPE_DEVICEINTERFACE = 0,
/// <summary>
/// Register for notifications for device handle events. <c>pFilter-&gt;u.DeviceHandle.hTarget</c> must be filled in with a
/// handle to the device to receive notifications for.
/// </summary>
CM_NOTIFY_FILTER_TYPE_DEVICEHANDLE,
/// <summary>
/// Register for notifications for device instance events. <c>pFilter-&gt;u.DeviceInstance.InstanceId</c> should be filled in
/// with the device instance ID of the device to receive notifications for.
/// </summary>
CM_NOTIFY_FILTER_TYPE_DEVICEINSTANCE,
}
/// <summary>Open class key flags</summary>
[PInvokeData("cfgmgr32.h", MSDNShortId = "NF:cfgmgr32.CM_Open_Class_KeyW")]
public enum CM_OPEN_CLASS_KEY
{
/// <summary>The key to be opened is for a device setup class.</summary>
CM_OPEN_CLASS_KEY_INSTALLER = 0x00000000,
/// <summary>The key to be opened is for a device interface class.</summary>
CM_OPEN_CLASS_KEY_INTERFACE = 0x00000001,
}
/// <summary>Caller-supplied flags that specify how reenumeration should occur.</summary>
[PInvokeData("cfgmgr32.h", MSDNShortId = "NF:cfgmgr32.CM_Reenumerate_DevNode")]
[Flags]
public enum CM_REENUMERATE : uint
{
/// <summary>
/// Specifies default reenumeration behavior, in which reenumeration occurs synchronously. This flag is functionally equivalent
/// to CM_REENUMERATE_SYNCHRONOUS.
/// </summary>
CM_REENUMERATE_NORMAL = 0x00000000,
/// <summary>
/// Reenumeration should occur synchronously. The call to this function returns when all devices in the specified subtree have
/// been reenumerated. If this flag is set, the CM_REENUMERATE_ASYNCHRONOUS flag should not also be set. This flag is
/// functionally equivalent to CM_REENUMERATE_NORMAL.
/// </summary>
CM_REENUMERATE_SYNCHRONOUS = 0x00000001,
/// <summary>
/// <para>
/// Specifies that Plug and Play should make another attempt to install any devices in the specified subtree that have been
/// detected but are not yet configured, or are marked as needing reinstallation, or for which installation must be completed.
/// This flag can be set along with either the CM_REENUMERATE_SYNCHRONOUS flag or the CM_REENUMERATE_ASYNCHRONOUS flag.
/// </para>
/// <para>
/// This flag must be used with extreme caution, because it can cause the PnP manager to prompt the user to perform installation
/// of any such devices. Currently, only components such as Device Manager and Hardware Wizard use this flag, to allow the user
/// to retry installation of devices that might already have been detected but are not currently installed.
/// </para>
/// </summary>
CM_REENUMERATE_RETRY_INSTALLATION = 0x00000002,
/// <summary>
/// Reenumeration should occur asynchronously. The call to this function returns immediately after the PnP manager receives the
/// reenumeration request. If this flag is set, the CM_REENUMERATE_SYNCHRONOUS flag should not also be set.
/// </summary>
CM_REENUMERATE_ASYNCHRONOUS = 0x00000004,
}
/// <summary>A bitwise OR of the caller-supplied flag constants</summary>
[Flags]
public enum CM_REMOVE : uint
{
/// <summary></summary>
CM_REMOVE_UI_OK = 0x00000000,
/// <summary></summary>
CM_REMOVE_UI_NOT_OK = 0x00000001,
/// <summary></summary>
CM_REMOVE_NO_RESTART = 0x00000002,
}
/// <summary>Flags for <see cref="CM_Setup_DevNode"/>.</summary>
[PInvokeData("cfgmgr32.h", MSDNShortId = "NF:cfgmgr32.CM_Setup_DevNode")]
public enum CM_SETUP_DEVNODE
{
/// <summary>Configure devinst without (re)starting</summary>
CM_SETUP_DEVNODE_CONFIG = 0x00000005,
/// <summary>Configure devinst class without (re)starting</summary>
CM_SETUP_DEVNODE_CONFIG_CLASS = 0x00000006,
/// <summary>Configure devinst extensions without (re)starting</summary>
CM_SETUP_DEVNODE_CONFIG_EXTENSIONS = 0x00000007,
/// <summary>Reset devinst configuration without (re)starting</summary>
CM_SETUP_DEVNODE_CONFIG_RESET = 0x00000008,
/// <summary>Restarts a device instance that is not running because of a problem with the device configuration.</summary>
CM_SETUP_DEVNODE_READY = 0x00000000,
/// <summary>
/// Resets a device instance that has the no restart device status flag set. The no restart device status flag is set if a
/// device is removed by calling <c>CM_Query_And_Remove_SubTree</c> or <c>CM_Query_And_Remove_SubTree_Ex</c> and specifying the
/// CM_REMOVE_NO_RESTART flag.
/// </summary>
CM_SETUP_DEVNODE_RESET = 0x00000004,
}
/// <summary>Flags for <see cref="DMA_DES"/>.</summary>
[PInvokeData("cfgmgr32.h", MSDNShortId = "NS:cfgmgr32.DMA_Des_s")]
[Flags]
public enum DMA_DES_FLAGS : uint
{
/// <summary>Bitmask for the bits within DD_Flags that specify the channel width value.</summary>
mDD_Width = 0x3,
/// <summary>8-bit DMA channel</summary>
fDD_BYTE = 0x0,
/// <summary>16-bit DMA channel</summary>
fDD_WORD = 0x1,
/// <summary>32-bit DMA channel</summary>
fDD_DWORD = 0x2,
/// <summary>8-bit and 16-bit DMA channel</summary>
fDD_BYTE_AND_WORD = 0x3,
/// <summary>Bitmask for the bits within DD_Flags that specify the bus mastering value.</summary>
mDD_BusMaster = 0x4,
/// <summary>No bus mastering</summary>
fDD_NoBusMaster = 0x0,
/// <summary>Bus mastering</summary>
fDD_BusMaster = 0x4,
/// <summary>Bitmask for the bits within DD_Flags that specify the DMA type value.</summary>
mDD_Type = 0x18,
/// <summary>Standard DMA</summary>
fDD_TypeStandard = 0x00,
/// <summary>Type-A DMA</summary>
fDD_TypeA = 0x08,
/// <summary>Type-B DMA</summary>
fDD_TypeB = 0x10,
/// <summary>Type-F DMA</summary>
fDD_TypeF = 0x18,
}
/// <summary>Flags for <see cref="IO_DES"/>.</summary>
[PInvokeData("cfgmgr32.h", MSDNShortId = "NS:cfgmgr32.IO_Des_s")]
[Flags]
public enum IO_DES_FLAGS : uint
{
/// <summary>Bitmask for the bits within IOD_DesFlags that specify the port type value.</summary>
fIOD_PortType = 0x1,
/// <summary>The device is accessed in memory address space.</summary>
fIOD_Memory = 0x0,
/// <summary>The device is accessed in I/O address space.</summary>
fIOD_IO = 0x1,
/// <summary>Bitmask for the bits within IOD_DesFlags that specify the decode value.</summary>
fIOD_DECODE = 0x00fc,
/// <summary>The device decodes 10 bits of the port address.</summary>
fIOD_10_BIT_DECODE = 0x0004,
/// <summary>The device decodes 12 bits of the port address.</summary>
fIOD_12_BIT_DECODE = 0x0008,
/// <summary>The device decodes 16 bits of the port address.</summary>
fIOD_16_BIT_DECODE = 0x0010,
/// <summary>The device uses "positive decode" instead of "subtractive decode."</summary>
fIOD_POSITIVE_DECODE = 0x0020,
/// <summary></summary>
fIOD_PASSIVE_DECODE = 0x0040,
/// <summary></summary>
fIOD_WINDOW_DECODE = 0x0080,
/// <summary></summary>
fIOD_PORT_BAR = 0x0100,
}
/// <summary>Flags for <see cref="IRQ_DES_32"/></summary>
[Flags]
public enum IRQD_FLAGS : ushort
{
/// <summary>Bitmask,whether the IRQ may be shared:</summary>
mIRQD_Share = 0x1,
/// <summary>The IRQ may not be shared</summary>
fIRQD_Exclusive = 0x0,
/// <summary>The IRQ may be shared</summary>
fIRQD_Share = 0x1,
/// <summary>Bitmask,whether edge or level triggered:</summary>
mIRQD_Edge_Level = 0x2,
/// <summary>The IRQ is level-sensitive</summary>
fIRQD_Level = 0x0,
/// <summary>The IRQ is edge-sensitive</summary>
fIRQD_Edge = 0x2,
}
/// <summary>Flags for <see cref="MEM_DES"/></summary>
[PInvokeData("cfgmgr32.h", MSDNShortId = "NS:cfgmgr32.Mem_Des_s")]
[Flags]
public enum MEM_DES_FLAGS : uint
{
/// <summary>Bitmask, whether memory is writable</summary>
mMD_MemoryType = 0x1,
/// <summary>Memory range is read-only</summary>
fMD_ROM = 0x0,
/// <summary>Memory range may be written to</summary>
fMD_RAM = 0x1,
/// <summary>Bitmask, memory is 24 or 32-bit</summary>
mMD_32_24 = 0x2,
/// <summary>Memory range is 24-bit</summary>
fMD_24 = 0x0,
/// <summary>Memory range is 32-bit</summary>
fMD_32 = 0x2,
/// <summary>Bitmask,whether memory prefetchable</summary>
mMD_Prefetchable = 0x4,
/// <summary>Memory range is not prefetchable</summary>
fMD_PrefetchDisallowed = 0x0,
/// <summary>Memory range is prefetchable</summary>
fMD_PrefetchAllowed = 0x4,
/// <summary>Bitmask,whether memory is readable</summary>
mMD_Readable = 0x8,
/// <summary>Memory range is readable</summary>
fMD_ReadAllowed = 0x0,
/// <summary>Memory range is write-only</summary>
fMD_ReadDisallowed = 0x8,
/// <summary>Bitmask,supports write-behind</summary>
mMD_CombinedWrite = 0x10,
/// <summary>no combined-write caching</summary>
fMD_CombinedWriteDisallowed = 0x0,
/// <summary>supports combined-write caching</summary>
fMD_CombinedWriteAllowed = 0x10,
/// <summary>Bitmask,whether memory is cacheable</summary>
mMD_Cacheable = 0x20,
/// <summary>Memory range is non-cacheable</summary>
fMD_NonCacheable = 0x0,
/// <summary>Memory range is cacheable</summary>
fMD_Cacheable = 0x20,
/// <summary>Memory range is bridge window decode.</summary>
fMD_WINDOW_DECODE = 0x40,
/// <summary>Memory BAR resource.</summary>
fMD_MEMORY_BAR = 0x80,
}
/// <summary>Flags for <see cref="MFCARD_DES"/></summary>
[Flags]
public enum MFCARD_DES_FLAGS : uint
{
/// <summary>Bitmask, whether audio is enabled or not</summary>
mPMF_AUDIO_ENABLE = 0x8,
/// <summary>Audio is enabled</summary>
fPMF_AUDIO_ENABLE = 0x8,
}
/// <summary>Flags for <see cref="PCCARD_DES"/>.</summary>
[Flags]
public enum PCD_FLAGS : uint
{
/// <summary>Bitmask, whether I/O is 8 or 16 bits</summary>
mPCD_IO_8_16 = 0x1,
/// <summary>I/O is 8-bit</summary>
fPCD_IO_8 = 0x0,
/// <summary>I/O is 16-bit</summary>
fPCD_IO_16 = 0x1,
/// <summary>Bitmask, whether MEM is 8 or 16 bits</summary>
mPCD_MEM_8_16 = 0x2,
/// <summary>MEM is 8-bit</summary>
fPCD_MEM_8 = 0x0,
/// <summary>MEM is 16-bit</summary>
fPCD_MEM_16 = 0x2,
/// <summary>Bitmask, whether MEMx is Attribute or Common</summary>
mPCD_MEM_A_C = 0xC,
/// <summary>MEM1 is Attribute</summary>
fPCD_MEM1_A = 0x4,
/// <summary>MEM2 is Attribute</summary>
fPCD_MEM2_A = 0x8,
/// <summary>zero wait on 8 bit I/O</summary>
fPCD_IO_ZW_8 = 0x10,
/// <summary>iosrc 16</summary>
fPCD_IO_SRC_16 = 0x20,
/// <summary>wait states on 16 bit io</summary>
fPCD_IO_WS_16 = 0x40,
/// <summary>Bitmask, for additional wait states on memory windows</summary>
mPCD_MEM_WS = 0x300,
/// <summary>1 wait state</summary>
fPCD_MEM_WS_ONE = 0x100,
/// <summary>2 wait states</summary>
fPCD_MEM_WS_TWO = 0x200,
/// <summary>3 wait states</summary>
fPCD_MEM_WS_THREE = 0x300,
/// <summary>MEM is Attribute</summary>
fPCD_MEM_A = 0x4,
/// <summary></summary>
fPCD_ATTRIBUTES_PER_WINDOW = 0x8000,
/// <summary>I/O window 1 is 16-bit</summary>
fPCD_IO1_16 = 0x00010000,
/// <summary>I/O window 1 zero wait on 8 bit I/O</summary>
fPCD_IO1_ZW_8 = 0x00020000,
/// <summary>I/O window 1 iosrc 16</summary>
fPCD_IO1_SRC_16 = 0x00040000,
/// <summary>I/O window 1 wait states on 16 bit io</summary>
fPCD_IO1_WS_16 = 0x00080000,
/// <summary>I/O window 2 is 16-bit</summary>
fPCD_IO2_16 = 0x00100000,
/// <summary>I/O window 2 zero wait on 8 bit I/O</summary>
fPCD_IO2_ZW_8 = 0x00200000,
/// <summary>I/O window 2 iosrc 16</summary>
fPCD_IO2_SRC_16 = 0x00400000,
/// <summary>I/O window 2 wait states on 16 bit io</summary>
fPCD_IO2_WS_16 = 0x00800000,
/// <summary>MEM window 1 Bitmask, for additional wait states on memory windows</summary>
mPCD_MEM1_WS = 0x03000000,
/// <summary>MEM window 1, 1 wait state</summary>
fPCD_MEM1_WS_ONE = 0x01000000,
/// <summary>MEM window 1, 2 wait states</summary>
fPCD_MEM1_WS_TWO = 0x02000000,
/// <summary>MEM window 1, 3 wait states</summary>
fPCD_MEM1_WS_THREE = 0x03000000,
/// <summary>MEM window 1 is 16-bit</summary>
fPCD_MEM1_16 = 0x04000000,
/// <summary>MEM window 2 Bitmask, for additional wait states on memory windows</summary>
mPCD_MEM2_WS = 0x30000000,
/// <summary>MEM window 2, 1 wait state</summary>
fPCD_MEM2_WS_ONE = 0x10000000,
/// <summary>MEM window 2, 2 wait states</summary>
fPCD_MEM2_WS_TWO = 0x20000000,
/// <summary>MEM window 2, 3 wait states</summary>
fPCD_MEM2_WS_THREE = 0x30000000,
/// <summary>MEM window 2 is 16-bit</summary>
fPCD_MEM2_16 = 0x40000000,
}
/// <summary>Specifies how the registry key is to be opened.</summary>
[PInvokeData("cfgmgr32.h", MSDNShortId = "NF:cfgmgr32.CM_Open_Class_KeyW")]
public enum REGDISPOSITION
{
/// <summary>Open the key if it exists. Otherwise, create the key.</summary>
RegDisposition_OpenAlways = 0x00000000,
/// <summary>Open the key only if it exists.</summary>
RegDisposition_OpenExisting = 0x00000001,
}
/// <summary>
/// The <c>CM_Get_Sibling</c> function obtains a device instance handle to the next sibling node of a specified device node
/// (devnode) in the local machine's device tree.
/// </summary>
/// <param name="pdnDevInst">
/// Caller-supplied pointer to the device instance handle to the sibling node that this function retrieves. The retrieved handle is
/// bound to the local machine.
/// </param>
/// <param name="dnDevInst">Caller-supplied device instance handle that is bound to the local machine.</param>
/// <param name="ulFlags">Not used, must be zero.</param>
/// <returns>
/// If the operation succeeds, the function returns CR_SUCCESS. Otherwise, it returns one of the CR_-prefixed error codes defined in Cfgmgr32.h.
/// </returns>
/// <remarks>
/// <para>
/// To enumerate all children of a devnode in the local machine's device tree, first call CM_Get_Child to obtain a handle to the
/// first child node, then call <c>CM_Get_Sibling</c> to obtain handles for the rest of the children.
/// </para>
/// <para>For information about using device instance handles that are bound to the local machine, see CM_Get_Child.</para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/cfgmgr32/nf-cfgmgr32-cm_get_sibling CMAPI CONFIGRET CM_Get_Sibling( PDEVINST
// pdnDevInst, DEVINST dnDevInst, ULONG ulFlags );
[DllImport(Lib_Cfgmgr32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("cfgmgr32.h", MSDNShortId = "NF:cfgmgr32.CM_Get_Sibling")]
public static extern CONFIGRET CM_Get_Sibling(out uint pdnDevInst, uint dnDevInst, uint ulFlags = 0);
/// <summary>
/// <para>[Beginning with Windows 8 and Windows Server 2012, this function has been deprecated. Please use CM_Get_Sibling instead.]</para>
/// <para>
/// The <c>CM_Get_Sibling_Ex</c> function obtains a device instance handle to the next sibling node of a specified device node, in a
/// local or a remote machine's device tree.
/// </para>
/// </summary>
/// <param name="pdnDevInst">
/// Caller-supplied pointer to the device instance handle to the sibling node that this function retrieves. The retrieved handle is
/// bound to the machine handle specified by hMachine.
/// </param>
/// <param name="dnDevInst">Caller-supplied device instance handle that is bound to the machine handle specified by hMachine.</param>
/// <param name="ulFlags">Not used, must be zero.</param>
/// <param name="hMachine">
/// <para>Caller-supplied machine handle to which the caller-supplied device instance handle is bound.</para>
/// <para>
/// <c>Note</c> Using this function to access remote machines is not supported beginning with Windows 8 and Windows Server 2012, as
/// this functionality has been removed.
/// </para>
/// </param>
/// <returns>
/// If the operation succeeds, the function returns CR_SUCCESS. Otherwise, it returns one of the CR_-prefixed error codes defined in Cfgmgr32.h.
/// </returns>
/// <remarks>
/// <para>
/// To enumerate all children of a device node in the local machine's device tree, first call CM_Get_Child_Ex to obtain a handle to
/// the first child node, then call <c>CM_Get_Sibling_Ex</c> to obtain handles for the rest of the children.
/// </para>
/// <para>For information about using device instance handles that are bound to a local or a remote machine, see CM_Get_Child_Ex.</para>
/// <para>
/// Functionality to access remote machines has been removed in Windows 8 and Windows Server 2012 and later operating systems thus
/// you cannot access remote machines when running on these versions of Windows.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/cfgmgr32/nf-cfgmgr32-cm_get_sibling_ex CMAPI CONFIGRET CM_Get_Sibling_Ex(
// PDEVINST pdnDevInst, DEVINST dnDevInst, ULONG ulFlags, HMACHINE hMachine );
[DllImport(Lib_Cfgmgr32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("cfgmgr32.h", MSDNShortId = "NF:cfgmgr32.CM_Get_Sibling_Ex")]
public static extern CONFIGRET CM_Get_Sibling_Ex(out uint pdnDevInst, uint dnDevInst, [In, Optional] uint ulFlags, [In, Optional] HMACHINE hMachine);
/// <summary>
/// <para>[Beginning with Windows 8 and Windows Server 2012, this function has been deprecated and should not be used.]</para>
/// <para>
/// The <c>CM_Get_Version</c> function returns version 4.0 of the Plug and Play (PnP) Configuration Manager DLL (Cfgmgr32.dll) for a
/// local machine.
/// </para>
/// </summary>
/// <returns>
/// If the function succeeds, it returns the major revision number in the high-order byte, and the minor revision number in the
/// low-order byte. Version 4.0 is returned as 0x0400. By default, version 4.0 is supported by Microsoft Windows 2000 and later
/// versions of Windows. If an internal error occurs, the function returns 0x0000. Call GetLastError to obtain the error code for
/// the failure.
/// </returns>
/// <remarks>
/// <para>
/// This function returns version 4.0 of the configuration manager to ensure compatibility with version 4.0 and all later versions
/// of the configuration manager, and to ensure compatibility with all applications that require version 4.0 of the configuration manager.
/// </para>
/// <para>
/// To determine if a specific version of the configuration manager is available on a machine, use CM_Is_Version_Available or CM_Is_Version_Available_Ex.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/cfgmgr32/nf-cfgmgr32-cm_get_version CMAPI WORD CM_Get_Version();
[DllImport(Lib_Cfgmgr32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("cfgmgr32.h", MSDNShortId = "NF:cfgmgr32.CM_Get_Version")]
public static extern ushort CM_Get_Version();
/// <summary>
/// <para>[Beginning with Windows 8 and Windows Server 2012, this function has been deprecated and should not be used.]</para>
/// <para>
/// The <c>CM_Get_Version_Ex</c> function returns version 4.0 of the Plug and Play (PnP) Configuration Manager DLL (Cfgmgr32.dll)
/// for a local or a remote machine.
/// </para>
/// </summary>
/// <param name="hMachine">
/// <para>Supplies a machine handle that is returned by CM_Connect_Machine.</para>
/// <para>
/// <c>Note</c> Using this function to access remote machines is not supported beginning with Windows 8 and Windows Server 2012, as
/// this functionality has been removed.
/// </para>
/// </param>
/// <returns>
/// If the function succeeds, it returns the major revision number in the high-order byte and the minor revision number in the
/// low-order byte. Version 4.0 is returned as 0x0400. By default, version 4.0 is supported by Microsoft Windows 2000 and later
/// versions of Windows. If an internal error occurs, the function returns 0x0000. Call GetLastError to obtain the error code for
/// the failure.
/// </returns>
/// <remarks>
/// <para>
/// This function returns version 4.0 of the configuration manager to ensure compatibility with version 4.0 and all later versions
/// of the configuration manager, and to ensure compatibility with all applications that require version 4.0 of the configuration manager.
/// </para>
/// <para>
/// To determine if a specific version of the configuration manager is available on a machine, use CM_Is_Version_Available or CM_Is_Version_Available_Ex.
/// </para>
/// <para>
/// Functionality to access remote machines has been removed in Windows 8 and Windows Server 2012 and later operating systems thus
/// you cannot access remote machines when running on these versions of Windows.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/cfgmgr32/nf-cfgmgr32-cm_get_version_ex CMAPI WORD CM_Get_Version_Ex( HMACHINE
// hMachine );
[DllImport(Lib_Cfgmgr32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("cfgmgr32.h", MSDNShortId = "NF:cfgmgr32.CM_Get_Version_Ex")]
public static extern ushort CM_Get_Version_Ex([In, Optional] HMACHINE hMachine);
/// <summary>The <c>CM_Is_Dock_Station_Present</c> function identifies whether a docking station is present in a local machine.</summary>
/// <param name="pbPresent">
/// Pointer to a Boolean value that indicates whether a docking station is present in a local machine. The function sets *pbPresent
/// to <c>TRUE</c> if a docking station is present. Otherwise, the function sets *pbPresent to <c>FALSE</c>.
/// </param>
/// <returns>
/// If the operation succeeds, the function returns CR_SUCCESS. Otherwise, the function returns one of the CR_-prefixed error codes
/// that are defined in Cfgmgr32.h.
/// </returns>
/// <remarks>
/// <para>
/// Use this function to determine whether a docking station is present in a local machine. You can also use the following related
/// functions with docking stations:
/// </para>
/// <list type="bullet">
/// <item>
/// <term>
/// <para>CM_Is_Dock_Station_Present_Ex identifies whether a docking station is present in a local or a remote machine.</para>
/// </term>
/// </item>
/// <item>
/// <term>
/// <para>CM_Request_Eject_PC requests that a portable PC, which is inserted in a local docking station, be ejected.</para>
/// </term>
/// </item>
/// <item>
/// <term>
/// <para>CM_Request_Eject_PC_Ex requests that a portable PC, which is inserted in a local or a remote docking station, be ejected.</para>
/// </term>
/// </item>
/// </list>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/cfgmgr32/nf-cfgmgr32-cm_is_dock_station_present CMAPI CONFIGRET
// CM_Is_Dock_Station_Present( PBOOL pbPresent );
[DllImport(Lib_Cfgmgr32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("cfgmgr32.h", MSDNShortId = "NF:cfgmgr32.CM_Is_Dock_Station_Present")]
public static extern CONFIGRET CM_Is_Dock_Station_Present([MarshalAs(UnmanagedType.Bool)] out bool pbPresent);
/// <summary>
/// <para>
/// [Beginning with Windows 8 and Windows Server 2012, this function has been deprecated. Please use CM_Is_Dock_Station_Present instead.]
/// </para>
/// <para>
/// The <c>CM_Is_Dock_Station_Present_Ex</c> function identifies whether a docking station is present in a local or a remote machine.
/// </para>
/// </summary>
/// <param name="pbPresent">
/// Pointer to a Boolean value that indicates whether a docking station is present in a local machine. The function sets *pbPresent
/// to <c>TRUE</c> if a docking station is present. The function sets *pbPresent to <c>FALSE</c> if the function cannot connect to
/// the specified machine or a docking station is not present.
/// </param>
/// <param name="hMachine">
/// <para>Supplies a machine handle that is returned by CM_Connect_Machine.</para>
/// <para>
/// <c>Note</c> Using this function to access remote machines is not supported beginning with Windows 8 and Windows Server 2012, as
/// this functionality has been removed.
/// </para>
/// </param>
/// <returns>
/// If the operation succeeds, the function returns CR_SUCCESS. Otherwise, the function returns one of the CR_-prefixed error codes
/// that are defined in Cfgmgr32.h.
/// </returns>
/// <remarks>
/// <para>
/// Use this function to determine whether a docking station is present in a local or a remote machine. You can also use the
/// following related functions with docking stations:
/// </para>
/// <list type="bullet">
/// <item>
/// <term>
/// <para>CM_Is_Dock_Station_Present identifies whether a docking station is present in a local machine.</para>
/// </term>
/// </item>
/// <item>
/// <term>
/// <para>CM_Request_Eject_PC requests that a portable PC, which is inserted in a local docking station, be ejected.</para>
/// </term>
/// </item>
/// <item>
/// <term>
/// <para>CM_Request_Eject_PC_Ex requests that a portable PC, which is inserted in a local or a remote docking station, be ejected.</para>
/// </term>
/// </item>
/// </list>
/// <para>
/// Functionality to access remote machines has been removed in Windows 8 and Windows Server 2012 and later operating systems thus
/// you cannot access remote machines when running on these versions of Windows.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/cfgmgr32/nf-cfgmgr32-cm_is_dock_station_present_ex CMAPI CONFIGRET
// CM_Is_Dock_Station_Present_Ex( PBOOL pbPresent, HMACHINE hMachine );
[DllImport(Lib_Cfgmgr32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("cfgmgr32.h", MSDNShortId = "NF:cfgmgr32.CM_Is_Dock_Station_Present_Ex")]
public static extern CONFIGRET CM_Is_Dock_Station_Present_Ex([MarshalAs(UnmanagedType.Bool)] out bool pbPresent, [In, Optional] HMACHINE hMachine);
/// <summary>
/// <para>[Beginning with Windows 8 and Windows Server 2012, this function has been deprecated and should not be used.]</para>
/// <para>
/// The <c>CM_Is_Version_Available</c> function indicates whether a specified version of the Plug and Play (PnP) Configuration
/// Manager DLL (Cfgmgr32.dll) is supported by a local machine.
/// </para>
/// </summary>
/// <param name="wVersion">
/// <para>
/// Identifies a version of the configuration manager. The supported version of the configuration manager corresponds directly to
/// the operating system version. The major version is specified by the high-order byte and the minor version is specified by the
/// low-order byte.
/// </para>
/// <para>
/// For example, 0x0400 specifies version 4.0, which is supported by default by Microsoft Windows 2000 and later versions of
/// Windows. 0x0501 specifies version 5.1, which is supported by Windows XP and later versions of Windows.
/// </para>
/// </param>
/// <returns>
/// The function returns <c>TRUE</c> if the local machine supports the specified version of the configuration manager. Otherwise,
/// the function returns <c>FALSE</c>.
/// </returns>
/// <remarks>
/// Use this function to determine whether a specified version of the configuration manager is supported by a local machine. If the
/// specified version is supported, all versions earlier and including this version are supported by the machine. You can also use
/// CM_Is_Version_Available_Ex to determine if a local or a remote machine supports a specific version of the configuration manager.
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/cfgmgr32/nf-cfgmgr32-cm_is_version_available CMAPI BOOL
// CM_Is_Version_Available( WORD wVersion );
[DllImport(Lib_Cfgmgr32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("cfgmgr32.h", MSDNShortId = "NF:cfgmgr32.CM_Is_Version_Available")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CM_Is_Version_Available(ushort wVersion);
/// <summary>
/// <para>[Beginning with Windows 8 and Windows Server 2012, this function has been deprecated and should not be used.]</para>
/// <para>
/// The <c>CM_Is_Version_Available_Ex</c> function indicates whether a specified version of the Plug and Play (PNP) Configuration
/// Manager DLL (Cfgmgr32.dll) is supported by a local or a remote machine.
/// </para>
/// </summary>
/// <param name="wVersion">
/// Identifies a version of the configuration manager. The supported version of the configuration manager corresponds directly to
/// the operating system version. The major version is specified by the high-order byte and the minor version is specified by the
/// low-order byte. For example, 0x0400 specifies version 4.0, which is supported by default by Microsoft Windows NT 4.0 and later
/// versions of Windows. Version 0x0501 specifies version 5.1, which is supported by Windows XP and later versions of Windows.
/// </param>
/// <param name="hMachine">
/// <para>Supplies a machine handle that is returned by CM_Connect_Machine.</para>
/// <para>
/// <c>Note</c> Using this function to access remote machines is not supported beginning with Windows 8 and Windows Server 2012, as
/// this functionality has been removed.
/// </para>
/// </param>
/// <returns>
/// The function returns <c>TRUE</c> if the function can connect to the specified machine and if the machine supports the specified
/// version. Otherwise, the function returns <c>FALSE</c>.
/// </returns>
/// <remarks>
/// <para>
/// Use this function to determine whether a specified version of the configuration manager is supported by a local or a remote
/// machine. If the specified version is supported, all versions earlier and including this version are supported by the machine.
/// You can also use CM_Is_Version_Available to determine if the local machine supports a specific version of the configuration manager.
/// </para>
/// <para>
/// Functionality to access remote machines has been removed in Windows 8 and Windows Server 2012 and later operating systems thus
/// you cannot access remote machines when running on these versions of Windows.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/cfgmgr32/nf-cfgmgr32-cm_is_version_available_ex CMAPI BOOL
// CM_Is_Version_Available_Ex( WORD wVersion, HMACHINE hMachine );
[DllImport(Lib_Cfgmgr32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("cfgmgr32.h", MSDNShortId = "NF:cfgmgr32.CM_Is_Version_Available_Ex")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CM_Is_Version_Available_Ex(ushort wVersion, [In, Optional] HMACHINE hMachine);
/// <summary>
/// The <c>CM_Locate_DevNode</c> function obtains a device instance handle to the device node that is associated with a specified
/// device instance ID on the local machine.
/// </summary>
/// <param name="pdnDevInst">
/// A pointer to a device instance handle that <c>CM_Locate_DevNode</c> retrieves. The retrieved handle is bound to the local machine.
/// </param>
/// <param name="pDeviceID">
/// A pointer to a NULL-terminated string representing a device instance ID. If this value is <c>NULL</c>, or if it points to a
/// zero-length string, the function retrieves a device instance handle to the device at the root of the device tree.
/// </param>
/// <param name="ulFlags">
/// <para>
/// A variable of ULONG type that supplies one of the following flag values that apply if the caller supplies a device instance identifier:
/// </para>
/// <para>CM_LOCATE_DEVNODE_NORMAL</para>
/// <para>
/// The function retrieves the device instance handle for the specified device only if the device is currently configured in the
/// device tree.
/// </para>
/// <para>CM_LOCATE_DEVNODE_PHANTOM</para>
/// <para>
/// The function retrieves a device instance handle for the specified device if the device is currently configured in the device
/// tree or the device is a nonpresent device that is not currently configured in the device tree.
/// </para>
/// <para>CM_LOCATE_DEVNODE_CANCELREMOVE</para>
/// <para>
/// The function retrieves a device instance handle for the specified device if the device is currently configured in the device
/// tree or in the process of being removed from the device tree. If the device is in the process of being removed, the function
/// cancels the removal of the device.
/// </para>
/// <para>CM_LOCATE_DEVNODE_NOVALIDATION</para>
/// <para>Not used.</para>
/// </param>
/// <returns>
/// If the operation succeeds, <c>CM_Locate_DevNode</c> returns CR_SUCCESS. Otherwise, the function returns one of the CR_Xxx error
/// codes that are defined in Cfgmgr32.h.
/// </returns>
/// <remarks>
/// <para>For information about using device instance handles that are bound to the local machine, see CM_Get_Child.</para>
/// <para>
/// <para>Note</para>
/// <para>
/// The cfgmgr32.h header defines CM_Locate_DevNode as an alias which automatically selects the ANSI or Unicode version of this
/// function based on the definition of the UNICODE preprocessor constant. Mixing usage of the encoding-neutral alias with code that
/// not encoding-neutral can lead to mismatches that result in compilation or runtime errors. For more information, see Conventions
/// for Function Prototypes.
/// </para>
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/cfgmgr32/nf-cfgmgr32-cm_locate_devnodea CMAPI CONFIGRET CM_Locate_DevNodeA(
// PDEVINST pdnDevInst, DEVINSTID_A pDeviceID, ULONG ulFlags );
[DllImport(Lib_Cfgmgr32, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("cfgmgr32.h", MSDNShortId = "NF:cfgmgr32.CM_Locate_DevNodeA")]
public static extern CONFIGRET CM_Locate_DevNode(out uint pdnDevInst, [In, Optional, MarshalAs(UnmanagedType.LPTStr)] string pDeviceID, CM_LOCATE_DEVNODE ulFlags = CM_LOCATE_DEVNODE.CM_LOCATE_DEVNODE_NORMAL);
/// <summary>
/// <para>[Beginning with Windows 8 and Windows Server 2012, this function has been deprecated. Please use CM_Locate_DevNode instead.]</para>
/// <para>
/// The <c>CM_Locate_DevNode_Ex</c> function obtains a device instance handle to the device node that is associated with a specified
/// device instance ID, on a local machine or a remote machine.
/// </para>
/// </summary>
/// <param name="pdnDevInst">
/// A pointer to the device instance handle that this function retrieves. The retrieved handle is bound to the machine handle
/// specified by hMachine.
/// </param>
/// <param name="pDeviceID">
/// A pointer to a NULL-terminated string representing a device instance ID. If this value is <c>NULL</c>, or if it points to a
/// zero-length string, the function supplies a device instance handle to the device at the root of the device tree.
/// </param>
/// <param name="ulFlags">
/// <para>
/// A variable of ULONG type that supplies one of the following flag values that apply if the caller supplies a device instance identifier:
/// </para>
/// <para>CM_LOCATE_DEVNODE_NORMAL</para>
/// <para>
/// The function retrieves the device instance handle for the specified device only if the device is currently configured in the
/// device tree.
/// </para>
/// <para>CM_LOCATE_DEVNODE_PHANTOM</para>
/// <para>
/// The function retrieves a device instance handle for the specified device if the device is currently configured in the device
/// tree or the device is a nonpresent device that is not currently configured in the device tree.
/// </para>
/// <para>CM_LOCATE_DEVNODE_CANCELREMOVE</para>
/// <para>
/// The function retrieves a device instance handle for the specified device if the device is currently configured in the device
/// tree or in the process of being removed for the device tree. If the device is in the process of being removed, the function
/// cancels the removal of the device.
/// </para>
/// <para>CM_LOCATE_DEVNODE_NOVALIDATION</para>
/// <para>Not used.</para>
/// </param>
/// <param name="hMachine">
/// <para>
/// A machine handle obtained from a call to CM_Connect_Machine, or a machine handle to which a device information set is bound. The
/// machine handle for a device information set is obtained from the <c>RemoteMachineHandle</c> member of the
/// SP_DEVINFO_LIST_DETAIL_DATA structure for the device information set. Call SetupDiGetDeviceInfoListDetail to obtain an
/// SP_DEVINFO_LIST_DETAIL_DATA structure.
/// </para>
/// <para>
/// <c>Note</c> Using this function to access remote machines is not supported beginning with Windows 8 and Windows Server 2012, as
/// this functionality has been removed.
/// </para>
/// </param>
/// <returns>
/// If the operation succeeds, <c>CM_Locate_DevNode</c> returns CR_SUCCESS. Otherwise, the function returns one of the CR_-prefixed
/// error codes that are defined in Cfgmgr32.h.
/// </returns>
/// <remarks>
/// <para>For information about using device instance handles that are bound to a local or a remote machine, see CM_Get_Child_Ex.</para>
/// <para>
/// Functionality to access remote machines has been removed in Windows 8 and Windows Server 2012 and later operating systems thus
/// you cannot access remote machines when running on these versions of Windows.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/cfgmgr32/nf-cfgmgr32-cm_locate_devnode_exw CMAPI CONFIGRET
// CM_Locate_DevNode_ExW( PDEVINST pdnDevInst, DEVINSTID_W pDeviceID, ULONG ulFlags, HMACHINE hMachine );
[DllImport(Lib_Cfgmgr32, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("cfgmgr32.h", MSDNShortId = "NF:cfgmgr32.CM_Locate_DevNode_ExW")]
public static extern CONFIGRET CM_Locate_DevNode_Ex(out uint pdnDevInst, [In, Optional, MarshalAs(UnmanagedType.LPTStr)] string pDeviceID, CM_LOCATE_DEVNODE ulFlags, [In, Optional] HMACHINE hMachine);
/// <summary>Converts a specified <c>CONFIGRET</c> code to its equivalent system error code.</summary>
/// <param name="CmReturnCode">The <c>CONFIGRET</c> code to be converted. <c>CONFIGRET</c> error codes are defined in CfgMgr32.h.</param>
/// <param name="DefaultErr">
/// A default system error code to be returned when no system error code is mapped to the specified <c>CONFIGRET</c> code.
/// </param>
/// <returns>
/// <para>The system error code that corresponds to the <c>CONFIGRET</c> code. System error codes are defined in Winerror.h.</para>
/// <para>
/// When there is no mapping from the specified <c>CONFIGRET</c> code to a system error code, <c>CM_MapCrToWin32Err</c> returns the
/// value specified in the DefaultErr parameter.
/// </para>
/// </returns>
// https://docs.microsoft.com/en-us/windows/win32/api/cfgmgr32/nf-cfgmgr32-cm_mapcrtowin32err CMAPI DWORD CM_MapCrToWin32Err(
// CONFIGRET CmReturnCode, DWORD DefaultErr );
[DllImport(Lib_Cfgmgr32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("cfgmgr32.h", MSDNShortId = "NF:cfgmgr32.CM_MapCrToWin32Err")]
public static extern Win32Error CM_MapCrToWin32Err(CONFIGRET CmReturnCode, uint DefaultErr);
/// <summary>The <c>CM_Modify_Res_Des</c> function modifies a specified resource descriptor on the local machine.</summary>
/// <param name="prdResDes">Pointer to a location to receive a handle to the modified resource descriptor.</param>
/// <param name="rdResDes">
/// <para>
/// Caller-supplied handle to the resource descriptor to be modified. This handle must have been previously obtained by calling one
/// of the following functions:
/// </para>
/// <para>CM_Add_Res_Des</para>
/// <para>CM_Add_Res_Des_Ex</para>
/// <para>CM_Get_Next_Res_Des</para>
/// <para>CM_Get_Next_Res_Des_Ex</para>
/// <para><c>CM_Modify_Res_Des</c></para>
/// <para>CM_Modify_Res_Des_Ex</para>
/// </param>
/// <param name="ResourceID">
/// Caller-supplied resource type identifier. This must be one of the <c>ResType_</c>-prefixed constants defined in Cfgmgr32.h.
/// </param>
/// <param name="ResourceData">
/// Caller-supplied pointer to a resource descriptor, which can be one of the structures listed under the CM_Add_Res_Des function's
/// description of ResourceData.
/// </param>
/// <param name="ResourceLen">Caller-supplied length of the structure pointed to by ResourceData.</param>
/// <param name="ulFlags">Not used, must be zero.</param>
/// <returns>
/// <para>
/// If the operation succeeds, the function returns CR_SUCCESS. Otherwise, it returns one of the CR_-prefixed error codes defined in Cfgmgr32.h.
/// </para>
/// <para>
/// <c>Note</c> Starting with Windows 8, <c>CM_Modify_Res_Des</c> returns CR_CALL_NOT_IMPLEMENTED when used in a Wow64 scenario. To
/// request information about the hardware resources on a local machine it is necessary implement an architecture-native version of
/// the application using the hardware resource APIs. For example: An AMD64 application for AMD64 systems.
/// </para>
/// </returns>
/// <remarks>
/// <para>
/// The caller-supplied resource descriptor data replaces the existing data. The values specified for ResourceID and ResourceLen do
/// not have to match the existing resource descriptor.
/// </para>
/// <para>
/// If the value specified for ResourceID is <c>ResType_ClassSpecific</c>, then the specified resource descriptor must be the last
/// one associated with the logical configuration.
/// </para>
/// <para>
/// Callers of <c>CM_Modify_Res_Des</c> must call CM_Free_Res_Des_Handle to deallocate the resource descriptor handle, after it is
/// no longer needed.
/// </para>
/// <para>
/// Callers of this function must have <c>SeLoadDriverPrivilege</c>. (Privileges are described in the Microsoft Windows SDK documentation.)
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/cfgmgr32/nf-cfgmgr32-cm_modify_res_des CMAPI CONFIGRET CM_Modify_Res_Des(
// PRES_DES prdResDes, RES_DES rdResDes, RESOURCEID ResourceID, PCVOID ResourceData, ULONG ResourceLen, ULONG ulFlags );
[DllImport(Lib_Cfgmgr32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("cfgmgr32.h", MSDNShortId = "NF:cfgmgr32.CM_Modify_Res_Des")]
public static extern CONFIGRET CM_Modify_Res_Des(out SafeRES_DES prdResDes, RES_DES rdResDes, RESOURCEID ResourceID, [In] IntPtr ResourceData, uint ResourceLen, uint ulFlags = 0);
/// <summary>The <c>CM_Modify_Res_Des</c> function modifies a specified resource descriptor on the local machine.</summary>
/// <typeparam name="T">The type of the data.</typeparam>
/// <param name="rdResDes">
/// <para>
/// Caller-supplied handle to the resource descriptor to be modified. This handle must have been previously obtained by calling one
/// of the following functions:
/// </para>
/// <para>CM_Add_Res_Des</para>
/// <para>CM_Add_Res_Des_Ex</para>
/// <para>CM_Get_Next_Res_Des</para>
/// <para>CM_Get_Next_Res_Des_Ex</para>
/// <para><c>CM_Modify_Res_Des</c></para>
/// <para>CM_Modify_Res_Des_Ex</para>
/// </param>
/// <param name="data">
/// Caller-supplied pointer to a resource descriptor, which can be one of the structures listed under the CM_Add_Res_Des function's
/// description of ResourceData.
/// </param>
/// <param name="ResourceID">
/// Caller-supplied resource type identifier. This must be one of the <c>ResType_</c>-prefixed constants defined in Cfgmgr32.h.
/// </param>
/// <returns>
/// <para>A handle to the modified resource descriptor.</para>
/// <para>
/// <c>Note</c> Starting with Windows 8, <c>CM_Modify_Res_Des</c> throws CR_CALL_NOT_IMPLEMENTED when used in a Wow64 scenario. To
/// request information about the hardware resources on a local machine it is necessary implement an architecture-native version of
/// the application using the hardware resource APIs. For example: An AMD64 application for AMD64 systems.
/// </para>
/// </returns>
/// <exception cref="ArgumentException">Unable to determine RESOURCEID from type. - T</exception>
/// <remarks>
/// <para>
/// The caller-supplied resource descriptor data replaces the existing data. The values specified for ResourceID and ResourceLen do
/// not have to match the existing resource descriptor.
/// </para>
/// <para>
/// If the value specified for ResourceID is <c>ResType_ClassSpecific</c>, then the specified resource descriptor must be the last
/// one associated with the logical configuration.
/// </para>
/// <para>
/// Callers of this function must have <c>SeLoadDriverPrivilege</c>. (Privileges are described in the Microsoft Windows SDK documentation.)
/// </para>
/// </remarks>
public static SafeRES_DES CM_Modify_Res_Des<T>(RES_DES rdResDes, T data, RESOURCEID ResourceID = 0) where T : struct
{
if (ResourceID == 0 && !CorrespondingTypeAttribute.CanSet<T, RESOURCEID>(out ResourceID))
throw new ArgumentException("Unable to determine RESOURCEID from type.", nameof(T));
using var mem = new SafeAnysizeStruct<T>(data);
CM_Modify_Res_Des(out var hRD, rdResDes, ResourceID, mem, mem.Size).ThrowIfFailed();
return hRD;
}
/// <summary>
/// <para>[Beginning with Windows 8 and Windows Server 2012, this function has been deprecated. Please use CM_Modify_Res_Des instead.]</para>
/// <para>The <c>CM_Modify_Res_Des_Ex</c> function modifies a specified resource descriptor on a local or a remote machine.</para>
/// </summary>
/// <param name="prdResDes">Pointer to a location to receive a handle to the modified resource descriptor.</param>
/// <param name="rdResDes">
/// <para>
/// Caller-supplied handle to the resource descriptor to be modified. This handle must have been previously obtained by calling one
/// of the following functions:
/// </para>
/// <para>CM_Add_Res_Des</para>
/// <para>CM_Add_Res_Des_Ex</para>
/// <para>CM_Get_Next_Res_Des</para>
/// <para>CM_Get_Next_Res_Des_Ex</para>
/// <para>CM_Modify_Res_Des</para>
/// <para><c>CM_Modify_Res_Des_Ex</c></para>
/// </param>
/// <param name="ResourceID">
/// Caller-supplied resource type identifier. This must be one of the <c>ResType_</c>-prefixed constants defined in Cfgmgr32.h.
/// </param>
/// <param name="ResourceData">
/// Caller-supplied pointer to a resource descriptor, which can be one of the structures listed under the CM_Add_Res_Des_Ex
/// function's description of ResourceData.
/// </param>
/// <param name="ResourceLen">Caller-supplied length of the structure pointed to by ResourceData.</param>
/// <param name="ulFlags">Not used, must be zero.</param>
/// <param name="hMachine">
/// <para>Caller-supplied machine handle, obtained from a previous call to CM_Connect_Machine.</para>
/// <para>
/// <c>Note</c> Using this function to access remote machines is not supported beginning with Windows 8 and Windows Server 2012, as
/// this functionality has been removed.
/// </para>
/// </param>
/// <returns>
/// <para>
/// If the operation succeeds, the function returns CR_SUCCESS. Otherwise, it returns one of the CR_-prefixed error codes defined in Cfgmgr32.h.
/// </para>
/// <para>
/// <c>Note</c> Starting with Windows 8, <c>CM_Modify_Res_Des_Ex</c> returns CR_CALL_NOT_IMPLEMENTED when used in a Wow64 scenario.
/// To request information about the hardware resources on a local machine it is necessary implement an architecture-native version
/// of the application using the hardware resource APIs. For example: An AMD64 application for AMD64 systems.
/// </para>
/// </returns>
/// <remarks>
/// <para>
/// The caller-supplied resource descriptor data replaces the existing data. The values specified for ResourceID and ResourceLen do
/// not have to match the existing resource descriptor.
/// </para>
/// <para>
/// If the value specified for ResourceID is <c>ResType_ClassSpecific</c>, then the specified resource descriptor must be the last
/// one associated with the logical configuration.
/// </para>
/// <para>
/// Callers of <c>CM_Modify_Res_Des_Ex</c> must call CM_Free_Res_Des_Handle to deallocate the resource descriptor handle, after it
/// is no longer needed.
/// </para>
/// <para>
/// Callers of this function must have <c>SeLoadDriverPrivilege</c>. (Privileges are described in the Microsoft Windows SDK documentation.)
/// </para>
/// <para>
/// Functionality to access remote machines has been removed in Windows 8 and Windows Server 2012 and later operating systems thus
/// you cannot access remote machines when running on these versions of Windows.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/cfgmgr32/nf-cfgmgr32-cm_modify_res_des_ex CMAPI CONFIGRET
// CM_Modify_Res_Des_Ex( PRES_DES prdResDes, RES_DES rdResDes, RESOURCEID ResourceID, PCVOID ResourceData, ULONG ResourceLen, ULONG
// ulFlags, HMACHINE hMachine );
[DllImport(Lib_Cfgmgr32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("cfgmgr32.h", MSDNShortId = "NF:cfgmgr32.CM_Modify_Res_Des_Ex")]
public static extern CONFIGRET CM_Modify_Res_Des_Ex(out SafeRES_DES prdResDes, RES_DES rdResDes, RESOURCEID ResourceID, [In] IntPtr ResourceData, uint ResourceLen, [In, Optional] uint ulFlags,
[In, Optional] HMACHINE hMachine);
/// <summary>
/// The <c>CM_Open_Class_Key</c> function opens the device setup class registry key, the device interface class registry key, or a
/// specific subkey of a class.
/// </summary>
/// <param name="ClassGuid">
/// Pointer to the GUID of the class whose registry key is to be opened. This parameter is optional and can be NULL. If this
/// parameter is NULL, the root of the class tree is opened.
/// </param>
/// <param name="pszClassName">Reserved. Must be set to NULL.</param>
/// <param name="samDesired">The registry security access for the key to be opened.</param>
/// <param name="Disposition">
/// <para>Specifies how the registry key is to be opened. May be one of the following values:</para>
/// <para>RegDisposition_OpenAlways</para>
/// <para>Open the key if it exists. Otherwise, create the key.</para>
/// <para>RegDisposition_OpenExisting</para>
/// <para>Open the key only if it exists.</para>
/// </param>
/// <param name="phkClass">Pointer to an HKEY that will receive the opened key upon success.</param>
/// <param name="ulFlags">
/// <para>Open class key flags:</para>
/// <para>CM_OPEN_CLASS_KEY_INSTALLER</para>
/// <para>The key to be opened is for a device setup class.</para>
/// <para>CM_OPEN_CLASS_KEY_INTERFACE</para>
/// <para>The key to be opened is for a device interface class.</para>
/// </param>
/// <returns>
/// If the operation succeeds, the function returns CR_SUCCESS. Otherwise, it returns one of the CR_-prefixed error codes defined in Cfgmgr32.h.
/// </returns>
/// <remarks>Close the handle returned from this function by calling <c>RegCloseKey</c>.</remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/cfgmgr32/nf-cfgmgr32-cm_open_class_keyw CMAPI CONFIGRET CM_Open_Class_KeyW(
// LPGUID ClassGuid, LPCWSTR pszClassName, REGSAM samDesired, REGDISPOSITION Disposition, PHKEY phkClass, ULONG ulFlags );
[DllImport(Lib_Cfgmgr32, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("cfgmgr32.h", MSDNShortId = "NF:cfgmgr32.CM_Open_Class_KeyW")]
public static extern CONFIGRET CM_Open_Class_Key(in Guid ClassGuid, [Optional, MarshalAs(UnmanagedType.LPTStr)] string pszClassName, REGSAM samDesired, REGDISPOSITION Disposition,
out SafeRegistryHandle phkClass, CM_OPEN_CLASS_KEY ulFlags);
/// <summary>
/// The <c>CM_Open_Class_Key</c> function opens the device setup class registry key, the device interface class registry key, or a
/// specific subkey of a class.
/// </summary>
/// <param name="ClassGuid">
/// Pointer to the GUID of the class whose registry key is to be opened. This parameter is optional and can be NULL. If this
/// parameter is NULL, the root of the class tree is opened.
/// </param>
/// <param name="pszClassName">Reserved. Must be set to NULL.</param>
/// <param name="samDesired">The registry security access for the key to be opened.</param>
/// <param name="Disposition">
/// <para>Specifies how the registry key is to be opened. May be one of the following values:</para>
/// <para>RegDisposition_OpenAlways</para>
/// <para>Open the key if it exists. Otherwise, create the key.</para>
/// <para>RegDisposition_OpenExisting</para>
/// <para>Open the key only if it exists.</para>
/// </param>
/// <param name="phkClass">Pointer to an HKEY that will receive the opened key upon success.</param>
/// <param name="ulFlags">
/// <para>Open class key flags:</para>
/// <para>CM_OPEN_CLASS_KEY_INSTALLER</para>
/// <para>The key to be opened is for a device setup class.</para>
/// <para>CM_OPEN_CLASS_KEY_INTERFACE</para>
/// <para>The key to be opened is for a device interface class.</para>
/// </param>
/// <returns>
/// If the operation succeeds, the function returns CR_SUCCESS. Otherwise, it returns one of the CR_-prefixed error codes defined in Cfgmgr32.h.
/// </returns>
/// <remarks>Close the handle returned from this function by calling <c>RegCloseKey</c>.</remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/cfgmgr32/nf-cfgmgr32-cm_open_class_keyw CMAPI CONFIGRET CM_Open_Class_KeyW(
// LPGUID ClassGuid, LPCWSTR pszClassName, REGSAM samDesired, REGDISPOSITION Disposition, PHKEY phkClass, ULONG ulFlags );
[DllImport(Lib_Cfgmgr32, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("cfgmgr32.h", MSDNShortId = "NF:cfgmgr32.CM_Open_Class_KeyW")]
public static extern CONFIGRET CM_Open_Class_Key([In, Optional] InteropServices.GuidPtr ClassGuid,
[Optional, MarshalAs(UnmanagedType.LPTStr)] string pszClassName, REGSAM samDesired, REGDISPOSITION Disposition,
out SafeRegistryHandle phkClass, CM_OPEN_CLASS_KEY ulFlags);
/// <summary>
/// The <c>CM_Open_Device_Interface_Key</c> function opens the registry subkey that is used by applications and drivers to store
/// information that is specific to a device interface.
/// </summary>
/// <param name="pszDeviceInterface">
/// Pointer to a string that identifies the device interface instance to open the registry subkey for.
/// </param>
/// <param name="samDesired">The requested registry security access to the registry subkey.</param>
/// <param name="Disposition">
/// <para>Specifies how the registry key is to be opened. May be one of the following values:</para>
/// <para>RegDisposition_OpenAlways</para>
/// <para>Open the key if it exists. Otherwise, create the key.</para>
/// <para>RegDisposition_OpenExisting</para>
/// <para>Open the key only if it exists.</para>
/// </param>
/// <param name="phkDeviceInterface">Pointer to an HKEY that will receive the opened key upon success.</param>
/// <param name="ulFlags">Reserved. Must be set to zero.</param>
/// <returns>
/// If the operation succeeds, the function returns CR_SUCCESS. Otherwise, it returns one of the CR_-prefixed error codes defined in Cfgmgr32.h.
/// </returns>
/// <remarks>
/// <para>Close the handle returned from this function by calling <c>RegCloseKey</c>.</para>
/// <para>
/// <para>Note</para>
/// <para>
/// The cfgmgr32.h header defines CM_Open_Device_Interface_Key as an alias which automatically selects the ANSI or Unicode version
/// of this function based on the definition of the UNICODE preprocessor constant. Mixing usage of the encoding-neutral alias with
/// code that not encoding-neutral can lead to mismatches that result in compilation or runtime errors. For more information, see
/// Conventions for Function Prototypes.
/// </para>
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/cfgmgr32/nf-cfgmgr32-cm_open_device_interface_keya CMAPI CONFIGRET
// CM_Open_Device_Interface_KeyA( LPCSTR pszDeviceInterface, REGSAM samDesired, REGDISPOSITION Disposition, PHKEY
// phkDeviceInterface, ULONG ulFlags );
[DllImport(Lib_Cfgmgr32, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("cfgmgr32.h", MSDNShortId = "NF:cfgmgr32.CM_Open_Device_Interface_KeyA")]
public static extern CONFIGRET CM_Open_Device_Interface_Key([MarshalAs(UnmanagedType.LPTStr)] string pszDeviceInterface, REGSAM samDesired, REGDISPOSITION Disposition,
out SafeRegistryHandle phkDeviceInterface, uint ulFlags = 0);
/// <summary>
/// <para>
/// [Beginning with Windows 8 and Windows Server 2012, this function has been deprecated. Please use CM_Open_Device_Interface_Key instead.]
/// </para>
/// <para>
/// The <c>CM_Open_Device_Interface_Key_ExA</c> function opens the registry subkey that is used by applications and drivers to store
/// information that is specific to a device interface.
/// </para>
/// </summary>
/// <param name="pszDeviceInterface">
/// Pointer to a string that identifies the device interface instance to open the registry subkey for.
/// </param>
/// <param name="samDesired">The requested registry security access to the registry subkey.</param>
/// <param name="Disposition">
/// <para>Specifies how the registry key is to be opened. May be one of the following values:</para>
/// <para>RegDisposition_OpenAlways</para>
/// <para>Open the key if it exists. Otherwise, create the key.</para>
/// <para>RegDisposition_OpenExisting</para>
/// <para>Open the key only if it exists.</para>
/// </param>
/// <param name="phkDeviceInterface">Pointer to an HKEY that will receive the opened key upon success.</param>
/// <param name="ulFlags">Reserved. Must be set to zero.</param>
/// <param name="hMachine">
/// <para>Caller-supplied machine handle, obtained from a previous call to CM_Connect_Machine.</para>
/// <para>
/// <c>Note</c> Using this function to access remote machines is not supported beginning with Windows 8 and Windows Server 2012, as
/// this functionality has been removed.
/// </para>
/// </param>
/// <returns>
/// If the operation succeeds, the function returns CR_SUCCESS. Otherwise, it returns one of the CR_-prefixed error codes defined in Cfgmgr32.h.
/// </returns>
/// <remarks>
/// <para>Close the handle returned from this function by calling <c>RegCloseKey</c>.</para>
/// <para>
/// <para>Note</para>
/// <para>
/// The cfgmgr32.h header defines CM_Open_Device_Interface_Key_Ex as an alias which automatically selects the ANSI or Unicode
/// version of this function based on the definition of the UNICODE preprocessor constant. Mixing usage of the encoding-neutral
/// alias with code that not encoding-neutral can lead to mismatches that result in compilation or runtime errors. For more
/// information, see Conventions for Function Prototypes.
/// </para>
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/cfgmgr32/nf-cfgmgr32-cm_open_device_interface_key_exa CMAPI CONFIGRET
// CM_Open_Device_Interface_Key_ExA( LPCSTR pszDeviceInterface, REGSAM samDesired, REGDISPOSITION Disposition, PHKEY
// phkDeviceInterface, ULONG ulFlags, HMACHINE hMachine );
[DllImport(Lib_Cfgmgr32, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("cfgmgr32.h", MSDNShortId = "NF:cfgmgr32.CM_Open_Device_Interface_Key_ExA")]
public static extern CONFIGRET CM_Open_Device_Interface_Key_Ex([MarshalAs(UnmanagedType.LPTStr)] string pszDeviceInterface, REGSAM samDesired, REGDISPOSITION Disposition,
out SafeRegistryHandle phkDeviceInterface, [In, Optional] uint ulFlags, [In, Optional] HMACHINE hMachine);
/// <summary>The <c>CM_Open_DevNode_Key</c> function opens a registry key for device-specific configuration information.</summary>
/// <param name="dnDevNode">Caller-supplied device instance handle that is bound to the local machine</param>
/// <param name="samDesired">The registry security access that is required for the requested key.</param>
/// <param name="ulHardwareProfile">
/// The hardware profile to open if ulFlags includes CM_REGISTRY_CONFIG. If this value is zero, the key for the current hardware
/// profile is opened.
/// </param>
/// <param name="Disposition">
/// <para>Specifies how the registry key is to be opened. May be one of the following values:</para>
/// <para>RegDisposition_OpenAlways</para>
/// <para>Open the key if it exists. Otherwise, create the key.</para>
/// <para>RegDisposition_OpenExisting</para>
/// <para>Open the key only if it exists.</para>
/// </param>
/// <param name="phkDevice">Pointer to an HKEY that will receive the opened key upon success.</param>
/// <param name="ulFlags">
/// <para>
/// Open device node key flags. Indicates the scope and type of registry storage key to open. Can be a combination of the following flags:
/// </para>
/// <para>CM_REGISTRY_HARDWARE</para>
/// <para>Open the device<63>s hardware key. Do not combine with CM_REGISTRY_SOFTWARE.</para>
/// <para>CM_REGISTRY_SOFTWARE</para>
/// <para>Open the device<63>s software key. Do not combine with CM_REGISTRY_HARDWARE.</para>
/// <para>CM_REGISTRY_USER</para>
/// <para>Open the per-user key for the current user. Do not combine with CM_REGISTRY_CONFIG.</para>
/// <para>CM_REGISTRY_CONFIG</para>
/// <para>Open the key that stores hardware profile-specific configuration information. Do not combine with CM_REGISTRY_USER.</para>
/// </param>
/// <returns>
/// If the operation succeeds, the function returns CR_SUCCESS. Otherwise, it returns one of the CR_-prefixed error codes defined in Cfgmgr32.h.
/// </returns>
/// <remarks>Close the handle returned from this function by calling <c>RegCloseKey</c>.</remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/cfgmgr32/nf-cfgmgr32-cm_open_devnode_key CMAPI CONFIGRET CM_Open_DevNode_Key(
// DEVINST dnDevNode, REGSAM samDesired, ULONG ulHardwareProfile, REGDISPOSITION Disposition, PHKEY phkDevice, ULONG ulFlags );
[DllImport(Lib_Cfgmgr32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("cfgmgr32.h", MSDNShortId = "NF:cfgmgr32.CM_Open_DevNode_Key")]
public static extern CONFIGRET CM_Open_DevNode_Key(uint dnDevNode, REGSAM samDesired, uint ulHardwareProfile, REGDISPOSITION Disposition, out SafeRegistryHandle phkDevice, CM_REGISTRY ulFlags);
/// <summary>
/// The <c>CM_Query_And_Remove_SubTree</c> function checks whether a device instance and its children can be removed and, if so, it
/// removes them.
/// </summary>
/// <param name="dnAncestor">
/// Caller-supplied device instance handle to the device at the root of the subtree to be removed. This device instance handle is
/// bound to the local machine.
/// </param>
/// <param name="pVetoType">
/// (Optional) If the caller does not pass <c>NULL</c> and the removal request is vetoed (that is, the function returns
/// CR_REMOVE_VETOED), on return this points to a PNP_VETO_TYPE-typed value that indicates the reason for the veto.
/// </param>
/// <param name="pszVetoName">
/// (Optional) If the caller does not pass <c>NULL</c> and the removal request is vetoed (that is, the function returns
/// CR_REMOVE_VETOED), on return this points to a text string that is associated with the veto type. The type of information this
/// string provides is dependent on the value received by pVetoType. For information about these strings, see PNP_VETO_TYPE.
/// </param>
/// <param name="ulNameLength">
/// Caller-supplied value representing the length (number of characters) of the string buffer supplied by pszVetoName. This should
/// be set to MAX_PATH.
/// </param>
/// <param name="ulFlags">A bitwise OR of the caller-supplied flag constants that are described in the <c>Remarks</c> section.</param>
/// <returns>
/// If the operation succeeds, the function returns CR_SUCCESS. Otherwise, it returns one of the other CR_-prefixed error codes
/// defined in Cfgmgr32.h.
/// </returns>
/// <remarks>
/// <para>
/// The purpose of the <c>CM_Query_And_Remove_SubTree</c> function is to allow an application to prepare a device for safe removal
/// from the local machine. Use this function to remove devices only if a driver has not set the <c>SurpriseRemovalOK</c> member of
/// DEVICE_CAPABILITIES. If a driver has set <c>SurpriseRemovalOK</c>, the application should call CM_Request_Device_Eject instead
/// of <c>CM_Query_And_Remove_SubTree</c>.
/// </para>
/// <para>
/// <c>CM_Query_And_Remove_SubTree</c> supports setting the flags parameter ulFlags with one of the following two flags; these flags
/// apply only if Windows or an installer vetoes the removal of a device:
/// </para>
/// <para>
/// Beginning with Windows XP, <c>CM_Query_And_Remove_SubTree</c> also supports setting the following additional flag; this flag
/// applies only if the function successfully removes the device instance:
/// </para>
/// <para>
/// Windows applications that do not require the low-level operation <c>CM_Query_And_Remove_SubTree</c> should use the
/// DIF_PROPERTYCHANGE request to disable a device instead of using <c>CM_Query_And_Remove_SubTree</c> to remove a device. The
/// DIF_PROPERTYCHANGE request can be used to enable, disable, restart, stop, or change the properties of a device.
/// </para>
/// <para>
/// Callers of this function must have <c>SeLoadDriverPrivilege</c>. (Privileges are described in the Microsoft Windows SDK documentation.)
/// </para>
/// <para>For information about using device instance handles that are bound to the local machine, see CM_Get_Child.</para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/cfgmgr32/nf-cfgmgr32-cm_query_and_remove_subtreew CMAPI CONFIGRET
// CM_Query_And_Remove_SubTreeW( DEVINST dnAncestor, PPNP_VETO_TYPE pVetoType, LPWSTR pszVetoName, ULONG ulNameLength, ULONG ulFlags );
[DllImport(Lib_Cfgmgr32, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("cfgmgr32.h", MSDNShortId = "NF:cfgmgr32.CM_Query_And_Remove_SubTreeW")]
public static extern CONFIGRET CM_Query_And_Remove_SubTree(uint dnAncestor, out PNP_VETO_TYPE pVetoType, [Optional] StringBuilder pszVetoName, uint ulNameLength, CM_REMOVE ulFlags);
/// <summary>
/// The <c>CM_Query_And_Remove_SubTree</c> function checks whether a device instance and its children can be removed and, if so, it
/// removes them.
/// </summary>
/// <param name="dnAncestor">
/// Caller-supplied device instance handle to the device at the root of the subtree to be removed. This device instance handle is
/// bound to the local machine.
/// </param>
/// <param name="pVetoType">
/// (Optional) If the caller does not pass <c>NULL</c> and the removal request is vetoed (that is, the function returns
/// CR_REMOVE_VETOED), on return this points to a PNP_VETO_TYPE-typed value that indicates the reason for the veto.
/// </param>
/// <param name="pszVetoName">
/// (Optional) If the caller does not pass <c>NULL</c> and the removal request is vetoed (that is, the function returns
/// CR_REMOVE_VETOED), on return this points to a text string that is associated with the veto type. The type of information this
/// string provides is dependent on the value received by pVetoType. For information about these strings, see PNP_VETO_TYPE.
/// </param>
/// <param name="ulNameLength">
/// Caller-supplied value representing the length (number of characters) of the string buffer supplied by pszVetoName. This should
/// be set to MAX_PATH.
/// </param>
/// <param name="ulFlags">A bitwise OR of the caller-supplied flag constants that are described in the <c>Remarks</c> section.</param>
/// <returns>
/// If the operation succeeds, the function returns CR_SUCCESS. Otherwise, it returns one of the other CR_-prefixed error codes
/// defined in Cfgmgr32.h.
/// </returns>
/// <remarks>
/// <para>
/// The purpose of the <c>CM_Query_And_Remove_SubTree</c> function is to allow an application to prepare a device for safe removal
/// from the local machine. Use this function to remove devices only if a driver has not set the <c>SurpriseRemovalOK</c> member of
/// DEVICE_CAPABILITIES. If a driver has set <c>SurpriseRemovalOK</c>, the application should call CM_Request_Device_Eject instead
/// of <c>CM_Query_And_Remove_SubTree</c>.
/// </para>
/// <para>
/// <c>CM_Query_And_Remove_SubTree</c> supports setting the flags parameter ulFlags with one of the following two flags; these flags
/// apply only if Windows or an installer vetoes the removal of a device:
/// </para>
/// <para>
/// Beginning with Windows XP, <c>CM_Query_And_Remove_SubTree</c> also supports setting the following additional flag; this flag
/// applies only if the function successfully removes the device instance:
/// </para>
/// <para>
/// Windows applications that do not require the low-level operation <c>CM_Query_And_Remove_SubTree</c> should use the
/// DIF_PROPERTYCHANGE request to disable a device instead of using <c>CM_Query_And_Remove_SubTree</c> to remove a device. The
/// DIF_PROPERTYCHANGE request can be used to enable, disable, restart, stop, or change the properties of a device.
/// </para>
/// <para>
/// Callers of this function must have <c>SeLoadDriverPrivilege</c>. (Privileges are described in the Microsoft Windows SDK documentation.)
/// </para>
/// <para>For information about using device instance handles that are bound to the local machine, see CM_Get_Child.</para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/cfgmgr32/nf-cfgmgr32-cm_query_and_remove_subtreew CMAPI CONFIGRET
// CM_Query_And_Remove_SubTreeW( DEVINST dnAncestor, PPNP_VETO_TYPE pVetoType, LPWSTR pszVetoName, ULONG ulNameLength, ULONG ulFlags );
[DllImport(Lib_Cfgmgr32, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("cfgmgr32.h", MSDNShortId = "NF:cfgmgr32.CM_Query_And_Remove_SubTreeW")]
public static extern CONFIGRET CM_Query_And_Remove_SubTree(uint dnAncestor, [In, Optional] IntPtr pVetoType, [Optional] StringBuilder pszVetoName, uint ulNameLength, CM_REMOVE ulFlags);
/// <summary>
/// <para>
/// [Beginning with Windows 8 and Windows Server 2012, this function has been deprecated. Please use CM_Query_And_Remove_SubTree instead.]
/// </para>
/// <para>
/// The <c>CM_Query_And_Remove_SubTree_Ex</c> function checks whether a device instance and its children can be removed and, if so,
/// it removes them.
/// </para>
/// </summary>
/// <param name="dnAncestor">
/// Caller-supplied device instance handle to the device at the root of the subtree to be removed. This device instance handle is
/// bound to the machine handle supplied by hMachine.
/// </param>
/// <param name="pVetoType">
/// (Optional) If the caller does not pass <c>NULL</c> and the removal request is vetoed (that is, the function returns
/// CR_REMOVE_VETOED), on return this points to a PNP_VETO_TYPE-typed value that indicates the reason for the veto.
/// </param>
/// <param name="pszVetoName">
/// (Optional) If the caller does not pass <c>NULL</c> and the removal request is vetoed (that is, the function returns
/// CR_REMOVE_VETOED), on return this points to a text string that is associated with the veto type. The type of information this
/// string provides is dependent on the value received by pVetoType. For information about these strings, see PNP_VETO_TYPE.
/// </param>
/// <param name="ulNameLength">
/// (Optional.) Caller-supplied value representing the length (number of characters) of the string buffer supplied by pszVetoName.
/// This should be set to MAX_PATH.
/// </param>
/// <param name="ulFlags">A bitwise OR of the caller-supplied flag constants that are described in the <c>Remarks</c> section.</param>
/// <param name="hMachine">
/// <para>Caller-supplied machine handle to which the caller-supplied device instance handle is bound.</para>
/// <para>
/// <c>Note</c> Using this function to access remote machines is not supported beginning with Windows 8 and Windows Server 2012, as
/// this functionality has been removed.
/// </para>
/// </param>
/// <returns>
/// If the operation succeeds, the function returns CR_SUCCESS. Otherwise, it returns one of the CR_-prefixed error codes defined in Cfgmgr32.h.
/// </returns>
/// <remarks>
/// <para>
/// The purpose of the <c>CM_Query_And_Remove_SubTree_Ex</c> function is to allow an application to prepare a device for safe
/// removal from a remote machine. Use this function to remove devices only if a driver has not set the <c>SurpriseRemovalOK</c>
/// member of DEVICE_CAPABILITIES. If a driver has set <c>SurpriseRemovalOK</c>, the application should call
/// CM_Request_Device_Eject_Ex instead of <c>CM_Query_And_Remove_SubTree_Ex</c>.
/// </para>
/// <para>
/// <c>CM_Query_And_Remove_SubTree_Ex</c> supports setting the flags parameter ulFlags with one of the following two flags; these
/// flags apply only if Windows or an installer vetoes the removal of a device:
/// </para>
/// <para>
/// Beginning with Windows XP, <c>CM_Query_And_Remove_SubTree_Ex</c> also supports setting the following additional flag; this flag
/// applies only if the function successfully removes the device instance:
/// </para>
/// <para>
/// Device installation applications that do not require the low-level operation of <c>CM_Query_And_Remove_SubTree_Ex</c> should use
/// the DIF_PROPERTYCHANGE request to disable a device instead of using <c>CM_Query_And_Remove_SubTree_Ex</c> to remove a device.
/// The DIF_PROPERTYCHANGE request can be used to enable, disable, restart, stop, or change the properties of a device.
/// </para>
/// <para>
/// Callers of this function must have <c>SeLoadDriverPrivilege</c>. (Privileges are described in the Microsoft Windows SDK documentation.)
/// </para>
/// <para>For information about using device instance handles that are bound to a local or a remote machine, see CM_Get_Child_Ex.</para>
/// <para>
/// Functionality to access remote machines has been removed in Windows 8 and Windows Server 2012 and later operating systems thus
/// you cannot access remote machines when running on these versions of Windows.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/cfgmgr32/nf-cfgmgr32-cm_query_and_remove_subtree_exw CMAPI CONFIGRET
// CM_Query_And_Remove_SubTree_ExW( DEVINST dnAncestor, PPNP_VETO_TYPE pVetoType, LPWSTR pszVetoName, ULONG ulNameLength, ULONG
// ulFlags, HMACHINE hMachine );
[DllImport(Lib_Cfgmgr32, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("cfgmgr32.h", MSDNShortId = "NF:cfgmgr32.CM_Query_And_Remove_SubTree_ExW")]
public static extern CONFIGRET CM_Query_And_Remove_SubTree_Ex(uint dnAncestor, out PNP_VETO_TYPE pVetoType, [Optional] StringBuilder pszVetoName, uint ulNameLength, CM_REMOVE ulFlags, [In, Optional] HMACHINE hMachine);
/// <summary>
/// <para>
/// [Beginning with Windows 8 and Windows Server 2012, this function has been deprecated. Please use CM_Query_And_Remove_SubTree instead.]
/// </para>
/// <para>
/// The <c>CM_Query_And_Remove_SubTree_Ex</c> function checks whether a device instance and its children can be removed and, if so,
/// it removes them.
/// </para>
/// </summary>
/// <param name="dnAncestor">
/// Caller-supplied device instance handle to the device at the root of the subtree to be removed. This device instance handle is
/// bound to the machine handle supplied by hMachine.
/// </param>
/// <param name="pVetoType">
/// (Optional) If the caller does not pass <c>NULL</c> and the removal request is vetoed (that is, the function returns
/// CR_REMOVE_VETOED), on return this points to a PNP_VETO_TYPE-typed value that indicates the reason for the veto.
/// </param>
/// <param name="pszVetoName">
/// (Optional) If the caller does not pass <c>NULL</c> and the removal request is vetoed (that is, the function returns
/// CR_REMOVE_VETOED), on return this points to a text string that is associated with the veto type. The type of information this
/// string provides is dependent on the value received by pVetoType. For information about these strings, see PNP_VETO_TYPE.
/// </param>
/// <param name="ulNameLength">
/// (Optional.) Caller-supplied value representing the length (number of characters) of the string buffer supplied by pszVetoName.
/// This should be set to MAX_PATH.
/// </param>
/// <param name="ulFlags">A bitwise OR of the caller-supplied flag constants that are described in the <c>Remarks</c> section.</param>
/// <param name="hMachine">
/// <para>Caller-supplied machine handle to which the caller-supplied device instance handle is bound.</para>
/// <para>
/// <c>Note</c> Using this function to access remote machines is not supported beginning with Windows 8 and Windows Server 2012, as
/// this functionality has been removed.
/// </para>
/// </param>
/// <returns>
/// If the operation succeeds, the function returns CR_SUCCESS. Otherwise, it returns one of the CR_-prefixed error codes defined in Cfgmgr32.h.
/// </returns>
/// <remarks>
/// <para>
/// The purpose of the <c>CM_Query_And_Remove_SubTree_Ex</c> function is to allow an application to prepare a device for safe
/// removal from a remote machine. Use this function to remove devices only if a driver has not set the <c>SurpriseRemovalOK</c>
/// member of DEVICE_CAPABILITIES. If a driver has set <c>SurpriseRemovalOK</c>, the application should call
/// CM_Request_Device_Eject_Ex instead of <c>CM_Query_And_Remove_SubTree_Ex</c>.
/// </para>
/// <para>
/// <c>CM_Query_And_Remove_SubTree_Ex</c> supports setting the flags parameter ulFlags with one of the following two flags; these
/// flags apply only if Windows or an installer vetoes the removal of a device:
/// </para>
/// <para>
/// Beginning with Windows XP, <c>CM_Query_And_Remove_SubTree_Ex</c> also supports setting the following additional flag; this flag
/// applies only if the function successfully removes the device instance:
/// </para>
/// <para>
/// Device installation applications that do not require the low-level operation of <c>CM_Query_And_Remove_SubTree_Ex</c> should use
/// the DIF_PROPERTYCHANGE request to disable a device instead of using <c>CM_Query_And_Remove_SubTree_Ex</c> to remove a device.
/// The DIF_PROPERTYCHANGE request can be used to enable, disable, restart, stop, or change the properties of a device.
/// </para>
/// <para>
/// Callers of this function must have <c>SeLoadDriverPrivilege</c>. (Privileges are described in the Microsoft Windows SDK documentation.)
/// </para>
/// <para>For information about using device instance handles that are bound to a local or a remote machine, see CM_Get_Child_Ex.</para>
/// <para>
/// Functionality to access remote machines has been removed in Windows 8 and Windows Server 2012 and later operating systems thus
/// you cannot access remote machines when running on these versions of Windows.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/cfgmgr32/nf-cfgmgr32-cm_query_and_remove_subtree_exw CMAPI CONFIGRET
// CM_Query_And_Remove_SubTree_ExW( DEVINST dnAncestor, PPNP_VETO_TYPE pVetoType, LPWSTR pszVetoName, ULONG ulNameLength, ULONG
// ulFlags, HMACHINE hMachine );
[DllImport(Lib_Cfgmgr32, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("cfgmgr32.h", MSDNShortId = "NF:cfgmgr32.CM_Query_And_Remove_SubTree_ExW")]
public static extern CONFIGRET CM_Query_And_Remove_SubTree_Ex(uint dnAncestor, [In, Optional] IntPtr pVetoType, [Optional] StringBuilder pszVetoName, uint ulNameLength, CM_REMOVE ulFlags, [In, Optional] HMACHINE hMachine);
/// <summary>
/// The <c>CM_Query_Resource_Conflict_List</c> function identifies device instances having resource requirements that conflict with
/// a specified device instance's resource description.
/// </summary>
/// <param name="pclConflictList">Caller-supplied address of a location to receive a handle to a conflict list.</param>
/// <param name="dnDevInst">Caller-supplied device instance handle that is bound to the machine handle supplied by hMachine.</param>
/// <param name="ResourceID">
/// Caller-supplied resource type identifier. This must be one of the <c>ResType_</c>-prefixed constants defined in Cfgmgr32.h.
/// </param>
/// <param name="ResourceData">
/// Caller-supplied pointer to a resource descriptor, which can be one of the structures listed under the CM_Add_Res_Des function's
/// description of ResourceData.
/// </param>
/// <param name="ResourceLen">Caller-supplied length of the structure pointed to by ResourceData.</param>
/// <param name="ulFlags">Not used, must be zero.</param>
/// <param name="hMachine">Caller-supplied machine handle to which the caller-supplied device instance handle is bound.</param>
/// <returns>
/// <para>
/// If the operation succeeds, the function returns CR_SUCCESS. Otherwise, it returns one of the CR_-prefixed error codes defined in Cfgmgr32.h.
/// </para>
/// <para>
/// <c>Note</c> Starting with Windows 8, <c>CM_Query_Resource_Conflict_List</c> returns CR_CALL_NOT_IMPLEMENTED when used in a Wow64
/// scenario. To request information about the hardware resources on a local machine it is necessary implement an
/// architecture-native version of the application using the hardware resource APIs. For example: An AMD64 application for AMD64 systems.
/// </para>
/// </returns>
/// <remarks>
/// <para>
/// When calling <c>CM_Query_Resource_Conflict_List</c>, specify a device instance handle and resource descriptor. (Resource
/// descriptors for existing device nodes can be obtained by calling CM_Get_Res_Des_Data.) These parameters indicate the specific
/// resources you'd like a specific device to use. The resulting conflict list identifies devices that use the same resources, along
/// with resources reserved by the machine.
/// </para>
/// <para>
/// After calling <c>CM_Query_Resource_Conflict_List</c>, an application can call CM_Get_Resource_Conflict_Count to determine the
/// number of conflicts contained in the resource conflict list. (The number of conflicts can be zero.) Then the application can
/// call CM_Get_Resource_Conflict_Details for each entry in the conflict list.
/// </para>
/// <para>After an application has finished using the handle received for pclConflictList, it must call CM_Free_Resource_Conflict_Handle.</para>
/// <para>For information about using device instance handles that are bound to a local or a remote machine, see CM_Get_Child_Ex.</para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/cfgmgr32/nf-cfgmgr32-cm_query_resource_conflict_list CMAPI CONFIGRET
// CM_Query_Resource_Conflict_List( PCONFLICT_LIST pclConflictList, DEVINST dnDevInst, RESOURCEID ResourceID, PCVOID ResourceData,
// ULONG ResourceLen, ULONG ulFlags, HMACHINE hMachine );
[DllImport(Lib_Cfgmgr32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("cfgmgr32.h", MSDNShortId = "NF:cfgmgr32.CM_Query_Resource_Conflict_List")]
public static extern CONFIGRET CM_Query_Resource_Conflict_List(out SafeCONFLICT_LIST pclConflictList, uint dnDevInst, RESOURCEID ResourceID, [In] IntPtr ResourceData,
uint ResourceLen, [In, Optional] uint ulFlags, [In, Optional] HMACHINE hMachine);
/// <summary>
/// The <c>CM_Query_Resource_Conflict_List</c> function identifies device instances having resource requirements that conflict with
/// a specified device instance's resource description.
/// </summary>
/// <typeparam name="T">The type of the supplied data.</typeparam>
/// <param name="dnDevInst">Caller-supplied device instance handle that is bound to the machine handle supplied by hMachine.</param>
/// <param name="data">
/// Caller-supplied pointer to a resource descriptor, which can be one of the structures listed under the CM_Add_Res_Des function's
/// description of ResourceData.
/// </param>
/// <param name="ResourceID">
/// Caller-supplied resource type identifier. If <c>0</c>, then the <see cref="RESOURCEID"/> is determined by <typeparamref name="T"/>.
/// </param>
/// <returns>
/// <para>A handle to a conflict list.</para>
/// <para>
/// <c>Note</c> Starting with Windows 8, <c>CM_Query_Resource_Conflict_List</c> throws CR_CALL_NOT_IMPLEMENTED when used in a Wow64
/// scenario. To request information about the hardware resources on a local machine it is necessary implement an
/// architecture-native version of the application using the hardware resource APIs. For example: An AMD64 application for AMD64 systems.
/// </para>
/// </returns>
/// <remarks>
/// <para>
/// When calling <c>CM_Query_Resource_Conflict_List</c>, specify a device instance handle and resource descriptor. (Resource
/// descriptors for existing device nodes can be obtained by calling CM_Get_Res_Des_Data.) These parameters indicate the specific
/// resources you'd like a specific device to use. The resulting conflict list identifies devices that use the same resources, along
/// with resources reserved by the machine.
/// </para>
/// <para>
/// After calling <c>CM_Query_Resource_Conflict_List</c>, an application can call CM_Get_Resource_Conflict_Count to determine the
/// number of conflicts contained in the resource conflict list. (The number of conflicts can be zero.) Then the application can
/// call CM_Get_Resource_Conflict_Details for each entry in the conflict list.
/// </para>
/// <para>For information about using device instance handles that are bound to a local or a remote machine, see CM_Get_Child_Ex.</para>
/// </remarks>
[PInvokeData("cfgmgr32.h", MSDNShortId = "NF:cfgmgr32.CM_Query_Resource_Conflict_List")]
public static SafeCONFLICT_LIST CM_Query_Resource_Conflict_List<T>(uint dnDevInst, T data, RESOURCEID ResourceID = 0) where T : struct
{
if (ResourceID == 0 && !CorrespondingTypeAttribute.CanSet<T, RESOURCEID>(out ResourceID))
throw new ArgumentException("Unable to determine RESOURCEID from type.", nameof(T));
using var mem = new SafeAnysizeStruct<T>(data);
CM_Query_Resource_Conflict_List(out var hcl, dnDevInst, ResourceID, mem, mem.Size).ThrowIfFailed();
return hcl;
}
/// <summary>
/// The <c>CM_Reenumerate_DevNode</c> function enumerates the devices identified by a specified device node and all of its children.
/// </summary>
/// <param name="dnDevInst">Caller-supplied device instance handle that is bound to the local machine.</param>
/// <param name="ulFlags">
/// <para>
/// Caller-supplied flags that specify how reenumeration should occur. This parameter can be set to a combination of the following
/// flags, as noted:
/// </para>
/// <para>CM_REENUMERATE_ASYNCHRONOUS</para>
/// <para>
/// Reenumeration should occur asynchronously. The call to this function returns immediately after the PnP manager receives the
/// reenumeration request. If this flag is set, the CM_REENUMERATE_SYNCHRONOUS flag should not also be set.
/// </para>
/// <para>CM_REENUMERATE_NORMAL</para>
/// <para>
/// Specifies default reenumeration behavior, in which reenumeration occurs synchronously. This flag is functionally equivalent to CM_REENUMERATE_SYNCHRONOUS.
/// </para>
/// <para>CM_REENUMERATE_RETRY_INSTALLATION</para>
/// <para>
/// Specifies that Plug and Play should make another attempt to install any devices in the specified subtree that have been detected
/// but are not yet configured, or are marked as needing reinstallation, or for which installation must be completed. This flag can
/// be set along with either the CM_REENUMERATE_SYNCHRONOUS flag or the CM_REENUMERATE_ASYNCHRONOUS flag.
/// </para>
/// <para>
/// This flag must be used with extreme caution, because it can cause the PnP manager to prompt the user to perform installation of
/// any such devices. Currently, only components such as Device Manager and Hardware Wizard use this flag, to allow the user to
/// retry installation of devices that might already have been detected but are not currently installed.
/// </para>
/// <para>CM_REENUMERATE_SYNCHRONOUS</para>
/// <para>
/// Reenumeration should occur synchronously. The call to this function returns when all devices in the specified subtree have been
/// reenumerated. If this flag is set, the CM_REENUMERATE_ASYNCHRONOUS flag should not also be set. This flag is functionally
/// equivalent to CM_REENUMERATE_NORMAL.
/// </para>
/// </param>
/// <returns>
/// If the operation succeeds, the function returns CR_SUCCESS. Otherwise, it returns one of the CR_-prefixed error codes defined in Cfgmgr32.h.
/// </returns>
/// <remarks>
/// <para>
/// If the specified device node represents a hardware or software bus device, the PnP manager queries the device's drivers for a
/// list of children, then attempts to configure and start any child devices that were not previously configured. The PnP manager
/// also initiates surprise-removal of devices that are no longer present (see IRP_MN_SURPRISE_REMOVAL).
/// </para>
/// <para>
/// Callers of this function must have <c>SeLoadDriverPrivilege</c>. (Privileges are described in the Microsoft Windows SDK documentation.)
/// </para>
/// <para>For information about using device instance handles that are bound to the local machine, see CM_Get_Child.</para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/cfgmgr32/nf-cfgmgr32-cm_reenumerate_devnode CMAPI CONFIGRET
// CM_Reenumerate_DevNode( DEVINST dnDevInst, ULONG ulFlags );
[DllImport(Lib_Cfgmgr32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("cfgmgr32.h", MSDNShortId = "NF:cfgmgr32.CM_Reenumerate_DevNode")]
public static extern CONFIGRET CM_Reenumerate_DevNode(uint dnDevInst, CM_REENUMERATE ulFlags);
/// <summary>
/// <para>
/// [Beginning with Windows 8 and Windows Server 2012, this function has been deprecated. Please use CM_Reenumerate_DevNode instead.]
/// </para>
/// <para>
/// The <c>CM_Reenumerate_DevNode_Ex</c> function enumerates the devices identified by a specified device node and all of its children.
/// </para>
/// </summary>
/// <param name="dnDevInst">Caller-supplied device instance handle that is bound to the machine handle supplied by hMachine.</param>
/// <param name="ulFlags">
/// <para>
/// Caller-supplied flags that specify how reenumeration should occur. This parameter can be set to a combination of the following
/// flags, as noted:
/// </para>
/// <para>CM_REENUMERATE_ASYNCHRONOUS</para>
/// <para>
/// Reenumeration should occur asynchronously. The call to this function returns immediately after the PnP manager receives the
/// reenumeration request. If this flag is set, the CM_REENUMERATE_SYNCHRONOUS flag should not also be set.
/// </para>
/// <para>CM_REENUMERATE_NORMAL</para>
/// <para>
/// Specifies default reenumeration behavior, in which reenumeration occurs synchronously. This flag is currently equivalent to CM_REENUMERATE_SYNCHRONOUS.
/// </para>
/// <para>CM_REENUMERATE_RETRY_INSTALLATION</para>
/// <para>
/// Specifies that Plug and Play should make another attempt to install any devices in the specified subtree that have been detected
/// but are not yet configured, or are marked as needing reinstallation, or for which installation must be completed. This flag can
/// be set along with either the CM_REENUMERATE_SYNCHRONOUS flag or the CM_REENUMERATE_ASYNCHRONOUS flag.
/// </para>
/// <para>
/// This flag must be used with extreme caution, because it can cause the PnP manager to prompt the user to perform installation of
/// any such devices. Currently, only components such as Device Manager and Hardware Wizard use this flag, to allow the user to
/// retry installation of devices that might already have been detected but are not currently installed.
/// </para>
/// <para>CM_REENUMERATE_SYNCHRONOUS</para>
/// <para>
/// Reenumeration should occur synchronously. The call to this function returns when all devices in the specified subtree have been
/// reenumerated. If this flag is set, the CM_REENUMERATE_ASYNCHRONOUS flag should not also be set. This flag is currently
/// equivalent to CM_REENUMERATE_NORMAL.
/// </para>
/// </param>
/// <param name="hMachine">
/// <para>Caller-supplied machine handle to which the caller-supplied device instance handle is bound.</para>
/// <para>
/// <c>Note</c> Using this function to access remote machines is not supported beginning with Windows 8 and Windows Server 2012, as
/// this functionality has been removed.
/// </para>
/// </param>
/// <returns>
/// If the operation succeeds, the function returns CR_SUCCESS. Otherwise, it returns one of the CR_-prefixed error codes defined in Cfgmgr32.h.
/// </returns>
/// <remarks>
/// <para>
/// If the specified device node represents a hardware or software bus device, the PnP manager queries the device's drivers for a
/// list of children, then attempts to configure and start any child devices that were not previously configured. The PnP manager
/// also initiates surprise-removal of devices that are no longer present (see IRP_MN_SURPRISE_REMOVAL).
/// </para>
/// <para>
/// Callers of this function must have <c>SeLoadDriverPrivilege</c>. (Privileges are described in the Microsoft Windows SDK documentation.)
/// </para>
/// <para>For information about using device instance handles that are bound to a local or a remote machine, see CM_Get_Child_Ex.</para>
/// <para>
/// Functionality to access remote machines has been removed in Windows 8 and Windows Server 2012 and later operating systems thus
/// you cannot access remote machines when running on these versions of Windows.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/cfgmgr32/nf-cfgmgr32-cm_reenumerate_devnode_ex CMAPI CONFIGRET
// CM_Reenumerate_DevNode_Ex( DEVINST dnDevInst, ULONG ulFlags, HMACHINE hMachine );
[DllImport(Lib_Cfgmgr32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("cfgmgr32.h", MSDNShortId = "NF:cfgmgr32.CM_Reenumerate_DevNode_Ex")]
public static extern CONFIGRET CM_Reenumerate_DevNode_Ex(uint dnDevInst, CM_REENUMERATE ulFlags, [In, Optional] HMACHINE hMachine);
/// <summary>
/// <para>
/// Use RegisterDeviceNotification instead of <c>CM_Register_Notification</c> if your code targets Windows 7 or earlier versions of
/// Windows. Kernel mode callers should use IoRegisterPlugPlayNotification instead.
/// </para>
/// <para>
/// The <c>CM_Register_Notification</c> function registers an application callback routine to be called when a PnP event of the
/// specified type occurs.
/// </para>
/// </summary>
/// <param name="pFilter">Pointer to a CM_NOTIFY_FILTER structure.</param>
/// <param name="pContext">
/// Pointer to a caller-allocated buffer containing the context to be passed to the callback routine in pCallback.
/// </param>
/// <param name="pCallback">
/// <para>
/// Pointer to the routine to be called when the specified PnP event occurs. See the <c>Remarks</c> section for the callback
/// function's prototype.
/// </para>
/// <para>The callback routine<6E>s Action parameter will be a value from the CM_NOTIFY_ACTION enumeration.</para>
/// <para>
/// Upon receiving a notification, how the callback examines the notification will depend on the <c>FilterType</c> member of the
/// callback routine's EventData parameter:
/// </para>
/// <para>CM_NOTIFY_FILTER_TYPE_DEVICEINTERFACE</para>
/// <para>The callback should examine <c>EventData-&gt;u.DeviceInterface</c>.</para>
/// <para>CM_NOTIFY_FILTER_TYPE_DEVICEHANDLE</para>
/// <para>The callback should examine <c>EventData-&gt;u.DeviceHandle</c>.</para>
/// <para>CM_NOTIFY_FILTER_TYPE_DEVICEINSTANCE</para>
/// <para>The callback should examine <c>EventData-&gt;u.DeviceInstance</c>.</para>
/// </param>
/// <param name="pNotifyContext">Pointer to receive the HCMNOTIFICATION handle that corresponds to the registration call.</param>
/// <returns>
/// If the operation succeeds, the function returns CR_SUCCESS. Otherwise, it returns one of the CR_-prefixed error codes defined in Cfgmgr32.h.
/// </returns>
/// <remarks>
/// <para>
/// Be sure to handle Plug and Play device events as quickly as possible. If your event handler performs any operation that may
/// block execution (such as I/O), it is best to start another thread to perform the operation asynchronously.
/// </para>
/// <para>
/// The <c>CM_Register_Notification</c> function does not provide notification of existing device interfaces. To retrieve existing
/// interfaces, first call <c>CM_Register_Notification</c>, and then call CM_Get_Device_Interface_List. If the interface is enabled
/// after your driver calls <c>CM_Register_Notification</c>, but before your driver calls <c>CM_Get_Device_Interface_List</c>, the
/// driver receives a notification for the interface arrival, and the interface also appears in the list of device interface
/// instances returned by <c>CM_Get_Device_Interface_List</c>.
/// </para>
/// <para>
/// HCMNOTIFICATION handles returned by <c>CM_Register_Notification</c> must be closed by calling the CM_Unregister_Notification
/// function when they are no longer needed.
/// </para>
/// <para>A callback routine uses the following function prototype:</para>
/// <para>
/// <code>typedef __callback DWORD (CALLBACK *PCM_NOTIFY_CALLBACK)( _In_ HCMNOTIFICATION hNotify, _In_opt_ PVOID Context, _In_ CM_NOTIFY_ACTION Action, _In_reads_bytes_(EventDataSize) PCM_NOTIFY_EVENT_DATA EventData, _In_ DWORD EventDataSize );</code>
/// </para>
/// <para>
/// If responding to a <c>CM_NOTIFY_ACTION_DEVICEQUERYREMOVE</c> notification, the PCM_NOTIFY_CALLBACK callback should return either
/// ERROR_SUCCESS or ERROR_CANCELLED, as appropriate. Otherwise, the callback should return ERROR_SUCCESS. The callback should not
/// return any other values. For a description of other actions, please refer to the CM_NOTIFY_ACTION documentation. Also see
/// CM_NOTIFY_EVENT_DATA for information about the structure that this callback receives in the EventData parameter.
/// </para>
/// <para>Examples</para>
/// <para>For an example, see Registering for Notification of Device Interface Arrival and Device Removal.</para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/cfgmgr32/nf-cfgmgr32-cm_register_notification CMAPI CONFIGRET
// CM_Register_Notification( PCM_NOTIFY_FILTER pFilter, PVOID pContext, PCM_NOTIFY_CALLBACK pCallback, PHCMNOTIFICATION
// pNotifyContext );
[DllImport(Lib_Cfgmgr32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("cfgmgr32.h", MSDNShortId = "NF:cfgmgr32.CM_Register_Notification")]
public static extern CONFIGRET CM_Register_Notification(in CM_NOTIFY_FILTER pFilter, [In, Optional] IntPtr pContext, [MarshalAs(UnmanagedType.FunctionPtr)] CM_NOTIFY_CALLBACK pCallback, out SafeHCMNOTIFICATION pNotifyContext);
/// <summary>
/// The <c>CM_Request_Device_Eject</c> function prepares a local device instance for safe removal, if the device is removable. If
/// the device can be physically ejected, it will be.
/// </summary>
/// <param name="dnDevInst">Caller-supplied device instance handle that is bound to the local machine.</param>
/// <param name="pVetoType">
/// (Optional.) If not <c>NULL</c>, this points to a location that, if the removal request fails, receives a PNP_VETO_TYPE-typed
/// value indicating the reason for the failure.
/// </param>
/// <param name="pszVetoName">
/// (Optional.) If not <c>NULL</c>, this is a caller-supplied pointer to a string buffer that receives a text string. The type of
/// information this string provides is dependent on the value received by pVetoType. For information about these strings, see PNP_VETO_TYPE.
/// </param>
/// <param name="ulNameLength">
/// (Optional.) Caller-supplied value representing the length of the string buffer supplied by pszVetoName. This should be set to MAX_PATH.
/// </param>
/// <param name="ulFlags">Not used.</param>
/// <returns>
/// If the operation succeeds, the function returns CR_SUCCESS. Otherwise, it returns one of the CR_-prefixed error codes defined in Cfgmgr32.h.
/// </returns>
/// <remarks>
/// <para>
/// If pszVetoName is <c>NULL</c>, the PnP manager displays a message to the user indicating the device was removed or, if the
/// request failed, identifying the reason for the failure. If pszVetoName is not <c>NULL</c>, the PnP manager does not display a
/// message. (Note, however, that for Microsoft Windows 2000 only, the PnP manager displays a message even if pszVetoName is not
/// <c>NULL</c>, if the device's CM_DEVCAP_DOCKDEVICE capability is set.)
/// </para>
/// <para>
/// Callers of <c>CM_Request_Device_Eject</c> sometimes require <c>SeUndockPrivilege</c> or <c>SeLoadDriverPrivilege</c>, as follows:
/// </para>
/// <list type="bullet">
/// <item>
/// <term>
/// If the device's CM_DEVCAP_DOCKDEVICE capability is set (the device is a "dock" device), callers must have
/// <c>SeUndockPrivilege</c>. ( <c>SeLoadDriverPrivilege</c> is not required.)
/// </term>
/// </item>
/// <item>
/// <term>
/// If the device's CM_DEVCAP_DOCKDEVICE capability is not set (the device is not a "dock" device), and if the calling process is
/// either not interactive or is running in a multi-user environment in a session not attached to the physical console (such as a
/// remote Terminal Services session), callers of this function must have <c>SeLoadDriverPrivilege</c>.
/// </term>
/// </item>
/// </list>
/// <para>Privileges are described in the Microsoft Windows SDK documentation.</para>
/// <para>For information about using device instance handles that are bound to the local machine, see CM_Get_Child.</para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/cfgmgr32/nf-cfgmgr32-cm_request_device_ejectw CMAPI CONFIGRET
// CM_Request_Device_EjectW( DEVINST dnDevInst, PPNP_VETO_TYPE pVetoType, LPWSTR pszVetoName, ULONG ulNameLength, ULONG ulFlags );
[DllImport(Lib_Cfgmgr32, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("cfgmgr32.h", MSDNShortId = "NF:cfgmgr32.CM_Request_Device_EjectW")]
public static extern CONFIGRET CM_Request_Device_Eject(uint dnDevInst, out PNP_VETO_TYPE pVetoType, [Out] StringBuilder pszVetoName, uint ulNameLength, uint ulFlags = 0);
/// <summary>
/// The <c>CM_Request_Device_Eject</c> function prepares a local device instance for safe removal, if the device is removable. If
/// the device can be physically ejected, it will be.
/// </summary>
/// <param name="dnDevInst">Caller-supplied device instance handle that is bound to the local machine.</param>
/// <param name="pVetoType">
/// (Optional.) If not <c>NULL</c>, this points to a location that, if the removal request fails, receives a PNP_VETO_TYPE-typed
/// value indicating the reason for the failure.
/// </param>
/// <param name="pszVetoName">
/// (Optional.) If not <c>NULL</c>, this is a caller-supplied pointer to a string buffer that receives a text string. The type of
/// information this string provides is dependent on the value received by pVetoType. For information about these strings, see PNP_VETO_TYPE.
/// </param>
/// <param name="ulNameLength">
/// (Optional.) Caller-supplied value representing the length of the string buffer supplied by pszVetoName. This should be set to MAX_PATH.
/// </param>
/// <param name="ulFlags">Not used.</param>
/// <returns>
/// If the operation succeeds, the function returns CR_SUCCESS. Otherwise, it returns one of the CR_-prefixed error codes defined in Cfgmgr32.h.
/// </returns>
/// <remarks>
/// <para>
/// If pszVetoName is <c>NULL</c>, the PnP manager displays a message to the user indicating the device was removed or, if the
/// request failed, identifying the reason for the failure. If pszVetoName is not <c>NULL</c>, the PnP manager does not display a
/// message. (Note, however, that for Microsoft Windows 2000 only, the PnP manager displays a message even if pszVetoName is not
/// <c>NULL</c>, if the device's CM_DEVCAP_DOCKDEVICE capability is set.)
/// </para>
/// <para>
/// Callers of <c>CM_Request_Device_Eject</c> sometimes require <c>SeUndockPrivilege</c> or <c>SeLoadDriverPrivilege</c>, as follows:
/// </para>
/// <list type="bullet">
/// <item>
/// <term>
/// If the device's CM_DEVCAP_DOCKDEVICE capability is set (the device is a "dock" device), callers must have
/// <c>SeUndockPrivilege</c>. ( <c>SeLoadDriverPrivilege</c> is not required.)
/// </term>
/// </item>
/// <item>
/// <term>
/// If the device's CM_DEVCAP_DOCKDEVICE capability is not set (the device is not a "dock" device), and if the calling process is
/// either not interactive or is running in a multi-user environment in a session not attached to the physical console (such as a
/// remote Terminal Services session), callers of this function must have <c>SeLoadDriverPrivilege</c>.
/// </term>
/// </item>
/// </list>
/// <para>Privileges are described in the Microsoft Windows SDK documentation.</para>
/// <para>For information about using device instance handles that are bound to the local machine, see CM_Get_Child.</para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/cfgmgr32/nf-cfgmgr32-cm_request_device_ejectw CMAPI CONFIGRET
// CM_Request_Device_EjectW( DEVINST dnDevInst, PPNP_VETO_TYPE pVetoType, LPWSTR pszVetoName, ULONG ulNameLength, ULONG ulFlags );
[DllImport(Lib_Cfgmgr32, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("cfgmgr32.h", MSDNShortId = "NF:cfgmgr32.CM_Request_Device_EjectW")]
public static extern CONFIGRET CM_Request_Device_Eject(uint dnDevInst, [In, Optional] IntPtr pVetoType, [Out] StringBuilder pszVetoName, uint ulNameLength, uint ulFlags = 0);
/// <summary>
/// <para>
/// [Beginning with Windows 8 and Windows Server 2012, this function has been deprecated. Please use CM_Request_Device_Eject instead.]
/// </para>
/// <para>
/// The <c>CM_Request_Device_Eject_Ex</c> function prepares a local or a remote device instance for safe removal, if the device is
/// removable. If the device can be physically ejected, it will be.
/// </para>
/// </summary>
/// <param name="dnDevInst">Caller-supplied device instance handle that is bound to the machine handle supplied by hMachine.</param>
/// <param name="pVetoType">
/// (Optional.) If not <c>NULL</c>, this points to a location that, if the removal request fails, receives a PNP_VETO_TYPE-typed
/// value indicating the reason for the failure.
/// </param>
/// <param name="pszVetoName">
/// (Optional.) If not <c>NULL</c>, this is a caller-supplied pointer to a string buffer that receives a text string. The type of
/// information this string provides is dependent on the value received by pVetoType. For information about these strings, see PNP_VETO_TYPE.
/// </param>
/// <param name="ulNameLength">
/// (Optional.) Caller-supplied value representing the length of the string buffer supplied by pszVetoName. This should be set to MAX_PATH.
/// </param>
/// <param name="ulFlags">Not used.</param>
/// <param name="hMachine">
/// <para>Caller-supplied machine handle to which the caller-supplied device instance handle is bound.</para>
/// <para>
/// <c>Note</c> Using this function to access remote machines is not supported beginning with Windows 8 and Windows Server 2012, as
/// this functionality has been removed.
/// </para>
/// </param>
/// <returns>
/// If the operation succeeds, the function returns CR_SUCCESS. Otherwise, it returns one of the CR_-prefixed error codes defined in Cfgmgr32.h.
/// </returns>
/// <remarks>
/// <para>
/// If pszVetoName is <c>NULL</c>, the PnP manager displays a message to the user indicating the device was removed or, if the
/// request failed, identifying the reason for the failure. If pszVetoName is not <c>NULL</c>, the PnP manager does not display a
/// message. (Note, however, that for Microsoft Windows 2000 only, the PnP manager displays a message even if pszVetoName is not
/// <c>NULL</c>, if the device's CM_DEVCAP_DOCKDEVICE capability is set.)
/// </para>
/// <para>
/// For remote machines, this function only works for "dock" device instances. That is, the function can only be used remotely to
/// undock a machine. In that case, the caller must have <c>SeUndockPrivilege</c>.
/// </para>
/// <para>Callers of <c>CM_Request_Eject_Ex</c> sometimes require <c>SeUndockPrivilege</c> or <c>SeLoadDriverPrivilege</c>, as follows:</para>
/// <list type="bullet">
/// <item>
/// <term>
/// If the device's CM_DEVCAP_DOCKDEVICE capability is set (the device is a "dock" device), callers must have
/// <c>SeUndockPrivilege</c>. ( <c>SeLoadDriverPrivilege</c> is not required.)
/// </term>
/// </item>
/// <item>
/// <term>
/// If the device's CM_DEVCAP_DOCKDEVICE capability is not set (the device is not a "dock" device), and if the calling process is
/// either not interactive or is running in a multi-user environment in a session not attached to the physical console (such as a
/// remote Terminal Services session) callers of this function must have <c>SeLoadDriverPrivilege</c>.
/// </term>
/// </item>
/// </list>
/// <para>(Privileges are described in the Microsoft Windows SDK documentation.)</para>
/// <para>For information about using device instance handles that are bound to a local or a remote machine, see CM_Get_Child_Ex.</para>
/// <para>
/// Functionality to access remote machines has been removed in Windows 8 and Windows Server 2012 and later operating systems thus
/// you cannot access remote machines when running on these versions of Windows.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/cfgmgr32/nf-cfgmgr32-cm_request_device_eject_exw CMAPI CONFIGRET
// CM_Request_Device_Eject_ExW( DEVINST dnDevInst, PPNP_VETO_TYPE pVetoType, LPWSTR pszVetoName, ULONG ulNameLength, ULONG ulFlags,
// HMACHINE hMachine );
[DllImport(Lib_Cfgmgr32, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("cfgmgr32.h", MSDNShortId = "NF:cfgmgr32.CM_Request_Device_Eject_ExW")]
public static extern CONFIGRET CM_Request_Device_Eject_Ex(uint dnDevInst, out PNP_VETO_TYPE pVetoType, [Out] StringBuilder pszVetoName, uint ulNameLength, [In, Optional] uint ulFlags, [In, Optional] HMACHINE hMachine);
/// <summary>
/// <para>
/// [Beginning with Windows 8 and Windows Server 2012, this function has been deprecated. Please use CM_Request_Device_Eject instead.]
/// </para>
/// <para>
/// The <c>CM_Request_Device_Eject_Ex</c> function prepares a local or a remote device instance for safe removal, if the device is
/// removable. If the device can be physically ejected, it will be.
/// </para>
/// </summary>
/// <param name="dnDevInst">Caller-supplied device instance handle that is bound to the machine handle supplied by hMachine.</param>
/// <param name="pVetoType">
/// (Optional.) If not <c>NULL</c>, this points to a location that, if the removal request fails, receives a PNP_VETO_TYPE-typed
/// value indicating the reason for the failure.
/// </param>
/// <param name="pszVetoName">
/// (Optional.) If not <c>NULL</c>, this is a caller-supplied pointer to a string buffer that receives a text string. The type of
/// information this string provides is dependent on the value received by pVetoType. For information about these strings, see PNP_VETO_TYPE.
/// </param>
/// <param name="ulNameLength">
/// (Optional.) Caller-supplied value representing the length of the string buffer supplied by pszVetoName. This should be set to MAX_PATH.
/// </param>
/// <param name="ulFlags">Not used.</param>
/// <param name="hMachine">
/// <para>Caller-supplied machine handle to which the caller-supplied device instance handle is bound.</para>
/// <para>
/// <c>Note</c> Using this function to access remote machines is not supported beginning with Windows 8 and Windows Server 2012, as
/// this functionality has been removed.
/// </para>
/// </param>
/// <returns>
/// If the operation succeeds, the function returns CR_SUCCESS. Otherwise, it returns one of the CR_-prefixed error codes defined in Cfgmgr32.h.
/// </returns>
/// <remarks>
/// <para>
/// If pszVetoName is <c>NULL</c>, the PnP manager displays a message to the user indicating the device was removed or, if the
/// request failed, identifying the reason for the failure. If pszVetoName is not <c>NULL</c>, the PnP manager does not display a
/// message. (Note, however, that for Microsoft Windows 2000 only, the PnP manager displays a message even if pszVetoName is not
/// <c>NULL</c>, if the device's CM_DEVCAP_DOCKDEVICE capability is set.)
/// </para>
/// <para>
/// For remote machines, this function only works for "dock" device instances. That is, the function can only be used remotely to
/// undock a machine. In that case, the caller must have <c>SeUndockPrivilege</c>.
/// </para>
/// <para>Callers of <c>CM_Request_Eject_Ex</c> sometimes require <c>SeUndockPrivilege</c> or <c>SeLoadDriverPrivilege</c>, as follows:</para>
/// <list type="bullet">
/// <item>
/// <term>
/// If the device's CM_DEVCAP_DOCKDEVICE capability is set (the device is a "dock" device), callers must have
/// <c>SeUndockPrivilege</c>. ( <c>SeLoadDriverPrivilege</c> is not required.)
/// </term>
/// </item>
/// <item>
/// <term>
/// If the device's CM_DEVCAP_DOCKDEVICE capability is not set (the device is not a "dock" device), and if the calling process is
/// either not interactive or is running in a multi-user environment in a session not attached to the physical console (such as a
/// remote Terminal Services session) callers of this function must have <c>SeLoadDriverPrivilege</c>.
/// </term>
/// </item>
/// </list>
/// <para>(Privileges are described in the Microsoft Windows SDK documentation.)</para>
/// <para>For information about using device instance handles that are bound to a local or a remote machine, see CM_Get_Child_Ex.</para>
/// <para>
/// Functionality to access remote machines has been removed in Windows 8 and Windows Server 2012 and later operating systems thus
/// you cannot access remote machines when running on these versions of Windows.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/cfgmgr32/nf-cfgmgr32-cm_request_device_eject_exw CMAPI CONFIGRET
// CM_Request_Device_Eject_ExW( DEVINST dnDevInst, PPNP_VETO_TYPE pVetoType, LPWSTR pszVetoName, ULONG ulNameLength, ULONG ulFlags,
// HMACHINE hMachine );
[DllImport(Lib_Cfgmgr32, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("cfgmgr32.h", MSDNShortId = "NF:cfgmgr32.CM_Request_Device_Eject_ExW")]
public static extern CONFIGRET CM_Request_Device_Eject_Ex(uint dnDevInst, [In, Optional] IntPtr pVetoType, [Out] StringBuilder pszVetoName, uint ulNameLength, [In, Optional] uint ulFlags, [In, Optional] HMACHINE hMachine);
/// <summary>
/// The <c>CM_Request_Eject_PC</c> function requests that a portable PC, which is inserted in a local docking station, be ejected.
/// </summary>
/// <returns>
/// If the operation succeeds, the function returns CR_SUCCESS. Otherwise, the function returns one of the CR_-prefixed error codes
/// that are defined in Cfgmgr32.h.
/// </returns>
/// <remarks>
/// <para>
/// Use this function to request that a portable PC, which is inserted in a local docking station, be ejected. You can also use the
/// following related functions with docking stations:
/// </para>
/// <list type="bullet">
/// <item>
/// <term>
/// <para>CM_Is_Dock_Station_Present identifies whether a docking station is present in a local machine.</para>
/// </term>
/// </item>
/// <item>
/// <term>
/// <para>CM_Is_Dock_Station_Present_Ex identifies whether a docking station is present in a local or a remote machine.</para>
/// </term>
/// </item>
/// <item>
/// <term>
/// <para>CM_Request_Eject_PC_Ex requests that a portable PC, which is inserted in a local or a remote docking station, be ejected.</para>
/// </term>
/// </item>
/// </list>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/cfgmgr32/nf-cfgmgr32-cm_request_eject_pc CMAPI CONFIGRET CM_Request_Eject_PC();
[DllImport(Lib_Cfgmgr32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("cfgmgr32.h", MSDNShortId = "NF:cfgmgr32.CM_Request_Eject_PC")]
public static extern CONFIGRET CM_Request_Eject_PC();
/// <summary>
/// <para>[Beginning with Windows 8 and Windows Server 2012, this function has been deprecated. Please use CM_Request_Eject_PC instead.]</para>
/// <para>
/// The <c>CM_Request_Eject_PC_Ex</c> function requests that a portable PC, which is inserted in a local or a remote docking
/// station, be ejected.
/// </para>
/// </summary>
/// <param name="hMachine">
/// <para>Supplies a machine handle that is returned by CM_Connect_Machine.</para>
/// <para>
/// <c>Note</c> Using this function to access remote machines is not supported beginning with Windows 8 and Windows Server 2012, as
/// this functionality has been removed.
/// </para>
/// </param>
/// <returns>
/// If the operation succeeds, the function returns CR_SUCCESS. Otherwise, the function returns one of the CR_-prefixed error codes
/// that are defined in Cfgmgr32.h.
/// </returns>
/// <remarks>
/// <para>
/// Use this function to request that a portable PC, which is inserted in a local or a remote docking station, be ejected. You can
/// also use the following related functions with docking stations:
/// </para>
/// <list type="bullet">
/// <item>
/// <term>
/// <para>CM_Is_Dock_Station_Present identifies whether a docking station is present in a local machine.</para>
/// </term>
/// </item>
/// <item>
/// <term>
/// <para>CM_Is_Dock_Station_Present_Ex identifies whether a docking station is present in a local or a remote machine.</para>
/// </term>
/// </item>
/// <item>
/// <term>
/// <para>CM_Request_Eject_PC requests that a portable PC, which is inserted in a local docking station, be ejected.</para>
/// </term>
/// </item>
/// </list>
/// <para>
/// Functionality to access remote machines has been removed in Windows 8 and Windows Server 2012 and later operating systems thus
/// you cannot access remote machines when running on these versions of Windows.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/cfgmgr32/nf-cfgmgr32-cm_request_eject_pc_ex CMAPI CONFIGRET
// CM_Request_Eject_PC_Ex( HMACHINE hMachine );
[DllImport(Lib_Cfgmgr32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("cfgmgr32.h", MSDNShortId = "NF:cfgmgr32.CM_Request_Eject_PC_Ex")]
public static extern CONFIGRET CM_Request_Eject_PC_Ex([In, Optional] HMACHINE hMachine);
/// <summary>The <c>CM_Set_Class_Property</c> function sets a class property for a device setup class or a device interface class.</summary>
/// <param name="ClassGUID">
/// Pointer to the GUID that identifies the device interface class or device setup class for which to set a device property. For
/// information about specifying the class type, see the ulFlags parameter.
/// </param>
/// <param name="PropertyKey">
/// Pointer to a DEVPROPKEY structure that represents the property key of the device class property to set.
/// </param>
/// <param name="PropertyType">
/// A DEVPROPTYPE-typed value that represents the property-data-type identifier for the device class property. To delete a property,
/// set this to DEVPROP_TYPE_EMPTY.
/// </param>
/// <param name="PropertyBuffer">
/// Pointer to a buffer that contains the property value of the device class property. If either the property or the data is to be
/// deleted, this pointer must be set to NULL, and PropertyBufferSize must be set to zero.
/// </param>
/// <param name="PropertyBufferSize">
/// The size, in bytes, of the PropertyBuffer buffer. If PropertyBuffer is set to NULL, PropertyBufferSize must be set to zero.
/// </param>
/// <param name="ulFlags">
/// <para>Class property flags:</para>
/// <para>CM_CLASS_PROPERTY_INSTALLER</para>
/// <para>ClassGUID specifies a device setup class. Do not combine with CM_CLASS_PROPERTY_INTERFACE.</para>
/// <para>CM_CLASS_PROPERTY_INTERFACE</para>
/// <para>ClassGUID specifies a device interface class. Do not combine with CM_CLASS_PROPERTY_INSTALLER.</para>
/// </param>
/// <returns>
/// If the operation succeeds, the function returns CR_SUCCESS. Otherwise, it returns one of the CR_-prefixed error codes defined in Cfgmgr32.h.
/// </returns>
/// <remarks><c>CM_Set_Class_Property</c> is part of the Unified Device Property Model.</remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/cfgmgr32/nf-cfgmgr32-cm_set_class_propertyw CMAPI CONFIGRET
// CM_Set_Class_PropertyW( LPCGUID ClassGUID, const DEVPROPKEY *PropertyKey, DEVPROPTYPE PropertyType, const PBYTE PropertyBuffer,
// ULONG PropertyBufferSize, ULONG ulFlags );
[DllImport(Lib_Cfgmgr32, SetLastError = false, CharSet = CharSet.Unicode)]
[PInvokeData("cfgmgr32.h", MSDNShortId = "NF:cfgmgr32.CM_Set_Class_PropertyW")]
public static extern CONFIGRET CM_Set_Class_Property(in Guid ClassGUID, in DEVPROPKEY PropertyKey, DEVPROPTYPE PropertyType, [In, Optional] IntPtr PropertyBuffer, uint PropertyBufferSize, uint ulFlags = 0);
/// <summary>
/// <para>
/// [Beginning with Windows 8 and Windows Server 2012, this function has been deprecated. Please use CM_Set_Class_Property instead.]
/// </para>
/// <para>The <c>CM_Set_Class_Property_ExW</c> function sets a class property for a device setup class or a device interface class.</para>
/// </summary>
/// <param name="ClassGUID">
/// Pointer to the GUID that identifies the device interface class or device setup class for which to set a device property. For
/// information about specifying the class type, see the ulFlags parameter.
/// </param>
/// <param name="PropertyKey">
/// Pointer to a DEVPROPKEY structure that represents the property key of the device class property to set.
/// </param>
/// <param name="PropertyType">
/// A DEVPROPTYPE-typed value that represents the property-data-type identifier for the device class property. To delete a property,
/// set this to <c>DEVPROP_TYPE_EMPTY</c>.
/// </param>
/// <param name="PropertyBuffer">
/// Pointer to a buffer that contains the property value of the device class property. If either the property or the data is to be
/// deleted, this pointer must be set to NULL, and PropertyBufferSize must be set to zero.
/// </param>
/// <param name="PropertyBufferSize">
/// The size, in bytes, of the PropertyBuffer buffer. If PropertyBuffer is set to NULL, PropertyBufferSize must be set to zero.
/// </param>
/// <param name="ulFlags">
/// <para>Class property flags:</para>
/// <para>CM_CLASS_PROPERTY_INSTALLER</para>
/// <para>ClassGUID specifies a device setup class. Do not combine with CM_CLASS_PROPERTY_INTERFACE.</para>
/// <para>CM_CLASS_PROPERTY_INTERFACE</para>
/// <para>ClassGUID specifies a device interface class. Do not combine with CM_CLASS_PROPERTY_INSTALLER.</para>
/// </param>
/// <param name="hMachine">
/// <para>Caller-supplied machine handle, obtained from a previous call to CM_Connect_Machine.</para>
/// <para>
/// <c>Note</c> Using this function to access remote machines is not supported beginning with Windows 8 and Windows Server 2012, as
/// this functionality has been removed.
/// </para>
/// </param>
/// <returns>
/// If the operation succeeds, the function returns CR_SUCCESS. Otherwise, it returns one of the CR_-prefixed error codes defined in Cfgmgr32.h.
/// </returns>
/// <remarks><c>CM_Set_Class_Property_ExW</c> is part of the Unified Device Property Model.</remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/cfgmgr32/nf-cfgmgr32-cm_set_class_property_exw CMAPI CONFIGRET
// CM_Set_Class_Property_ExW( LPCGUID ClassGUID, const DEVPROPKEY *PropertyKey, DEVPROPTYPE PropertyType, const PBYTE
// PropertyBuffer, ULONG PropertyBufferSize, ULONG ulFlags, HMACHINE hMachine );
[DllImport(Lib_Cfgmgr32, SetLastError = false, CharSet = CharSet.Unicode)]
[PInvokeData("cfgmgr32.h", MSDNShortId = "NF:cfgmgr32.CM_Set_Class_Property_ExW")]
public static extern CONFIGRET CM_Set_Class_Property_Ex(in Guid ClassGUID, in DEVPROPKEY PropertyKey, DEVPROPTYPE PropertyType, [In, Optional] IntPtr PropertyBuffer, uint PropertyBufferSize,
CM_CLASS_PROPERTY ulFlags, [In, Optional] HMACHINE hMachine);
/// <summary>The <c>CM_Set_Class_Registry_Property</c> function sets or deletes a property of a device setup class.</summary>
/// <param name="ClassGuid">A pointer to the GUID that represents the device setup class for which to set a property.</param>
/// <param name="ulProperty">
/// A value of type ULONG that identifies the property to set. This value must be one of the CM_CRP_Xxx values that are described
/// for the ulProperty parameter of the CM_Get_Class_Registry_Property function.
/// </param>
/// <param name="Buffer">
/// A pointer to a buffer that contains the property data. This parameter is optional and can be set to <c>NULL</c>. For more
/// information about setting this parameter and the corresponding ulLength parameter, see the following <c>Remarks</c> section.
/// </param>
/// <param name="ulLength">A value of type ULONG that specifies the size, in bytes, of the property data.</param>
/// <param name="ulFlags">Reserved for internal use only. Must be set to zero.</param>
/// <param name="hMachine">
/// A handle to a remote machine on which to set the specified device setup class property. This parameter is optional. If set to
/// <c>NULL</c>, the property is set on the local machine.
/// </param>
/// <returns>
/// If the operation succeeds, <c>CM_Set_Class_Registry_Property</c> returns CR_SUCCESS. Otherwise, the function returns one of the
/// other CR_Xxx status codes that are defined in Cfgmgr32.h.
/// </returns>
/// <remarks>
/// <para>If Buffer is <c>NULL</c>, ulLength must be set to zero.</para>
/// <para>If ulLength is set to zero, the function deletes the property.</para>
/// <para>
/// If Buffer is not set to <c>NULL</c> and ulLength is not set to zero, the supplied value must be the correct size for the REG_Xxx
/// data type for the property that is specified in ulProperty.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/cfgmgr32/nf-cfgmgr32-cm_set_class_registry_propertyw CMAPI CONFIGRET
// CM_Set_Class_Registry_PropertyW( LPGUID ClassGuid, ULONG ulProperty, PCVOID Buffer, ULONG ulLength, ULONG ulFlags, HMACHINE
// hMachine );
[DllImport(Lib_Cfgmgr32, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("cfgmgr32.h", MSDNShortId = "NF:cfgmgr32.CM_Set_Class_Registry_PropertyW")]
public static extern CONFIGRET CM_Set_Class_Registry_Property(in Guid ClassGuid, CM_CRP ulProperty, [In, Optional] IntPtr Buffer, uint ulLength, [In, Optional] uint ulFlags, [In, Optional] HMACHINE hMachine);
/// <summary>The <c>CM_Set_Device_Interface_Property</c> function sets a device property of a device interface.</summary>
/// <param name="pszDeviceInterface">
/// Pointer to a string that identifies the device interface instance for which to set a property for.
/// </param>
/// <param name="PropertyKey">
/// Pointer to a DEVPROPKEY structure that represents the property key of the device interface property to set.
/// </param>
/// <param name="PropertyType">
/// A DEVPROPTYPE-typed value that represents the property-data-type identifier for the device interface property. To delete a
/// property, this must be set to DEVPROP_TYPE_EMPTY.
/// </param>
/// <param name="PropertyBuffer">
/// Pointer to a buffer that contains the property value of the device interface property. If either the property or the data is
/// being deleted, this pointer must be set to NULL, and PropertyBufferSize must be set to zero.
/// </param>
/// <param name="PropertyBufferSize">
/// The size, in bytes, of the PropertyBuffer buffer. If PropertyBuffer is set to NULL, PropertyBufferSize must be set to zero.
/// </param>
/// <param name="ulFlags">Reserved. Must be set to zero.</param>
/// <returns>
/// If the operation succeeds, the function returns CR_SUCCESS. Otherwise, it returns one of the CR_-prefixed error codes defined in Cfgmgr32.h.
/// </returns>
/// <remarks><c>CM_Set_Device_Interface_Property</c> is part of the Unified Device Property Model.</remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/cfgmgr32/nf-cfgmgr32-cm_set_device_interface_propertyw CMAPI CONFIGRET
// CM_Set_Device_Interface_PropertyW( LPCWSTR pszDeviceInterface, const DEVPROPKEY *PropertyKey, DEVPROPTYPE PropertyType, const
// PBYTE PropertyBuffer, ULONG PropertyBufferSize, ULONG ulFlags );
[DllImport(Lib_Cfgmgr32, SetLastError = false, CharSet = CharSet.Unicode)]
[PInvokeData("cfgmgr32.h", MSDNShortId = "NF:cfgmgr32.CM_Set_Device_Interface_PropertyW")]
public static extern CONFIGRET CM_Set_Device_Interface_Property(string pszDeviceInterface, in DEVPROPKEY PropertyKey, DEVPROPTYPE PropertyType, [In, Optional] IntPtr PropertyBuffer,
uint PropertyBufferSize, uint ulFlags = 0);
/// <summary>
/// <para>
/// [Beginning with Windows 8 and Windows Server 2012, this function has been deprecated. Please use
/// CM_Set_Device_Interface_Property instead.]
/// </para>
/// <para>The <c>CM_Set_Device_Interface_Property_ExW</c> function sets a device property of a device interface.</para>
/// </summary>
/// <param name="pszDeviceInterface">
/// Pointer to a string that identifies the device interface instance for which to set a property for.
/// </param>
/// <param name="PropertyKey">
/// Pointer to a DEVPROPKEY structure that represents the property key of the device interface property to set.
/// </param>
/// <param name="PropertyType">
/// A DEVPROPTYPE-typed value that represents the property-data-type identifier for the device interface property. To delete a
/// property, this must be set to DEVPROP_TYPE_EMPTY.
/// </param>
/// <param name="PropertyBuffer">
/// Pointer to a buffer that contains the property value of the device interface property. If either the property or the data is
/// being deleted, this pointer must be set to NULL, and PropertyBufferSize must be set to zero.
/// </param>
/// <param name="PropertyBufferSize">
/// The size, in bytes, of the PropertyBuffer buffer. If PropertyBuffer is set to NULL, PropertyBufferSize must be set to zero.
/// </param>
/// <param name="ulFlags">Reserved. Must be set to zero.</param>
/// <param name="hMachine">
/// <para>Caller-supplied machine handle, obtained from a previous call to CM_Connect_Machine.</para>
/// <para>
/// <c>Note</c> Using this function to access remote machines is not supported beginning with Windows 8 and Windows Server 2012, as
/// this functionality has been removed.
/// </para>
/// </param>
/// <returns>
/// If the operation succeeds, the function returns CR_SUCCESS. Otherwise, it returns one of the CR_-prefixed error codes defined in Cfgmgr32.h.
/// </returns>
/// <remarks><c>CM_Set_Device_Interface_Property_ExW</c> is part of the Unified Device Property Model.</remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/cfgmgr32/nf-cfgmgr32-cm_set_device_interface_property_exw CMAPI CONFIGRET
// CM_Set_Device_Interface_Property_ExW( LPCWSTR pszDeviceInterface, const DEVPROPKEY *PropertyKey, DEVPROPTYPE PropertyType, const
// PBYTE PropertyBuffer, ULONG PropertyBufferSize, ULONG ulFlags, HMACHINE hMachine );
[DllImport(Lib_Cfgmgr32, SetLastError = false, CharSet = CharSet.Unicode)]
[PInvokeData("cfgmgr32.h", MSDNShortId = "NF:cfgmgr32.CM_Set_Device_Interface_Property_ExW")]
public static extern CONFIGRET CM_Set_Device_Interface_Property_Ex(string pszDeviceInterface, in DEVPROPKEY PropertyKey, DEVPROPTYPE PropertyType, [In, Optional] IntPtr PropertyBuffer,
uint PropertyBufferSize, [In, Optional] uint ulFlags, [In, Optional] HMACHINE hMachine);
/// <summary>The <c>CM_Set_DevNode_Problem</c> function sets a problem code for a device that is installed in a local machine.</summary>
/// <param name="dnDevInst">Caller-supplied device instance handle that is bound to the local machine.</param>
/// <param name="ulProblem">
/// Supplies a problem code, which is zero or one of the CM_PROB_Xxx flags that are described in Device Manager Error Messages. A
/// value of zero indicates that a problem is not set for the device.
/// </param>
/// <param name="ulFlags">Must be set to zero.</param>
/// <returns>
/// If the operation succeeds, the function returns CR_SUCCESS. Otherwise, the function returns one of the CR_-prefixed error codes
/// that are defined in Cfgmgr32.h.
/// </returns>
/// <remarks>
/// <para>
/// Use this function to set a problem code for a device that is installed in a local machine. You can also use the following
/// functions to set a device's problem code and to obtain the problem code set for the device:
/// </para>
/// <list type="bullet">
/// <item>
/// <term>
/// <para>CM_Get_DevNode_Status returns the problem code set for a device installed in a local machine.</para>
/// </term>
/// </item>
/// <item>
/// <term>
/// <para>CM_Get_DevNode_Status_Ex returns the problem code set for a device installed in a local or a remote machine.</para>
/// </term>
/// </item>
/// <item>
/// <term>
/// <para>CM_Set_DevNode_Problem_Ex sets a problem code for a device installed in a local or a remote machine.</para>
/// </term>
/// </item>
/// </list>
/// <para>For information about using device instance handles that are bound to the local machine, see CM_Get_Child.</para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/cfgmgr32/nf-cfgmgr32-cm_set_devnode_problem CMAPI CONFIGRET
// CM_Set_DevNode_Problem( DEVINST dnDevInst, ULONG ulProblem, ULONG ulFlags );
[DllImport(Lib_Cfgmgr32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("cfgmgr32.h", MSDNShortId = "NF:cfgmgr32.CM_Set_DevNode_Problem")]
public static extern CONFIGRET CM_Set_DevNode_Problem(uint dnDevInst, CM_PROB ulProblem, uint ulFlags = 0);
/// <summary>
/// <para>
/// [Beginning with Windows 8 and Windows Server 2012, this function has been deprecated. Please use CM_Set_DevNode_Problem instead.]
/// </para>
/// <para>
/// The <c>CM_Set_DevNode_Problem_Ex</c> function sets a problem code for a device that is installed in a local or a remote machine.
/// </para>
/// </summary>
/// <param name="dnDevInst">Caller-supplied device instance handle that is bound to the machine handle supplied by hMachine.</param>
/// <param name="ulProblem">
/// Supplies a problem code, which is zero or one of the CM_PROB_Xxx flags that are described in Device Manager Error Messages. A
/// value of zero indicates that a problem code is not set for the device.
/// </param>
/// <param name="ulFlags">Must be set to zero.</param>
/// <param name="hMachine">
/// <para>Caller-supplied machine handle to which the caller-supplied device instance handle is bound.</para>
/// <para>
/// <c>Note</c> Using this function to access remote machines is not supported beginning with Windows 8 and Windows Server 2012, as
/// this functionality has been removed.
/// </para>
/// </param>
/// <returns>
/// If the operation succeeds, the function returns CR_SUCCESS. Otherwise, the function returns one of the CR_-prefixed error codes
/// that are defined in Cfgmgr32.h.
/// </returns>
/// <remarks>
/// <para>
/// Use this function to set a problem code for a device that is installed in a local or a remote machine. You can also use the
/// following functions to set a device's problem code and to obtain the problem code set for the device:
/// </para>
/// <list type="bullet">
/// <item>
/// <term>
/// <para>CM_Get_DevNode_Status returns the problem code set for a device installed in a local machine.</para>
/// </term>
/// </item>
/// <item>
/// <term>
/// <para>CM_Get_DevNode_Status_Ex returns the problem code set for a device installed in a local or a remote machine.</para>
/// </term>
/// </item>
/// <item>
/// <term>
/// <para>CM_Set_DevNode_Problem sets a problem code for a device installed in a local machine.</para>
/// </term>
/// </item>
/// </list>
/// <para>For information about using device instance handles that are bound to a local or a remote machine, see CM_Get_Child_Ex.</para>
/// <para>
/// Functionality to access remote machines has been removed in Windows 8 and Windows Server 2012 and later operating systems thus
/// you cannot access remote machines when running on these versions of Windows.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/cfgmgr32/nf-cfgmgr32-cm_set_devnode_problem_ex CMAPI CONFIGRET
// CM_Set_DevNode_Problem_Ex( DEVINST dnDevInst, ULONG ulProblem, ULONG ulFlags, HMACHINE hMachine );
[DllImport(Lib_Cfgmgr32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("cfgmgr32.h", MSDNShortId = "NF:cfgmgr32.CM_Set_DevNode_Problem_Ex")]
public static extern CONFIGRET CM_Set_DevNode_Problem_Ex(uint dnDevInst, CM_PROB ulProblem, [In, Optional] uint ulFlags, [In, Optional] HMACHINE hMachine);
/// <summary>The <c>CM_Set_DevNode_Property</c> function sets a device instance property.</summary>
/// <param name="dnDevInst">Device instance handle that is bound to the local machine.</param>
/// <param name="PropertyKey">
/// Pointer to a DEVPROPKEY structure that represents the property key of the device instance property to set.
/// </param>
/// <param name="PropertyType">
/// A DEVPROPTYPE-typed value that represents the property-data-type identifier for the device instance property. To delete a
/// property, this must be set to DEVPROP_TYPE_EMPTY.
/// </param>
/// <param name="PropertyBuffer">
/// Pointer to a buffer that contains the property value of the device instance property. If either the property or the data is
/// being deleted, this pointer must be set to NULL, and PropertyBufferSize must be set to zero.
/// </param>
/// <param name="PropertyBufferSize">
/// The size, in bytes, of the PropertyBuffer buffer. If PropertyBuffer is set to NULL, PropertyBufferSize must be set to zero.
/// </param>
/// <param name="ulFlags">Reserved. Must be set to zero.</param>
/// <returns>
/// If the operation succeeds, the function returns CR_SUCCESS. Otherwise, it returns one of the CR_-prefixed error codes defined in Cfgmgr32.h.
/// </returns>
/// <remarks><c>CM_Set_DevNode_Property</c> is part of the Unified Device Property Model.</remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/cfgmgr32/nf-cfgmgr32-cm_set_devnode_propertyw CMAPI CONFIGRET
// CM_Set_DevNode_PropertyW( DEVINST dnDevInst, const DEVPROPKEY *PropertyKey, DEVPROPTYPE PropertyType, const PBYTE PropertyBuffer,
// ULONG PropertyBufferSize, ULONG ulFlags );
[DllImport(Lib_Cfgmgr32, SetLastError = false, CharSet = CharSet.Unicode)]
[PInvokeData("cfgmgr32.h", MSDNShortId = "NF:cfgmgr32.CM_Set_DevNode_PropertyW")]
public static extern CONFIGRET CM_Set_DevNode_Property(uint dnDevInst, in DEVPROPKEY PropertyKey, DEVPROPTYPE PropertyType, [In, Optional] IntPtr PropertyBuffer, uint PropertyBufferSize, uint ulFlags = 0);
/// <summary>
/// <para>
/// [Beginning with Windows 8 and Windows Server 2012, this function has been deprecated. Please use CM_Set_DevNode_Property instead.]
/// </para>
/// <para>The <c>CM_Set_DevNode_Property_ExW</c> function sets a device instance property.</para>
/// </summary>
/// <param name="dnDevInst">Device instance handle that is bound to the local machine.</param>
/// <param name="PropertyKey">
/// Pointer to a DEVPROPKEY structure that represents the property key of the device instance property to set.
/// </param>
/// <param name="PropertyType">
/// A DEVPROPTYPE-typed value that represents the property-data-type identifier for the device instance property. To delete a
/// property, this must be set to DEVPROP_TYPE_EMPTY.
/// </param>
/// <param name="PropertyBuffer">
/// Pointer to a buffer that contains the property value of the device instance property. If either the property or the data is
/// being deleted, this pointer must be set to NULL, and PropertyBufferSize must be set to zero.
/// </param>
/// <param name="PropertyBufferSize">
/// The size, in bytes, of the PropertyBuffer buffer. If PropertyBuffer is set to NULL, PropertyBufferSize must be set to zero.
/// </param>
/// <param name="ulFlags">Reserved. Must be set to zero.</param>
/// <param name="hMachine">
/// <para>Caller-supplied machine handle, obtained from a previous call to CM_Connect_Machine.</para>
/// <para>
/// <c>Note</c> Using this function to access remote machines is not supported beginning with Windows 8 and Windows Server 2012, as
/// this functionality has been removed.
/// </para>
/// </param>
/// <returns>
/// If the operation succeeds, the function returns CR_SUCCESS. Otherwise, it returns one of the CR_-prefixed error codes defined in Cfgmgr32.h.
/// </returns>
/// <remarks><c>CM_Set_DevNode_Property_ExW</c> is part of the Unified Device Property Model.</remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/cfgmgr32/nf-cfgmgr32-cm_set_devnode_property_exw CMAPI CONFIGRET
// CM_Set_DevNode_Property_ExW( DEVINST dnDevInst, const DEVPROPKEY *PropertyKey, DEVPROPTYPE PropertyType, const PBYTE
// PropertyBuffer, ULONG PropertyBufferSize, ULONG ulFlags, HMACHINE hMachine );
[DllImport(Lib_Cfgmgr32, SetLastError = false, CharSet = CharSet.Unicode)]
[PInvokeData("cfgmgr32.h", MSDNShortId = "NF:cfgmgr32.CM_Set_DevNode_Property_ExW")]
public static extern CONFIGRET CM_Set_DevNode_Property_Ex(uint dnDevInst, in DEVPROPKEY PropertyKey, DEVPROPTYPE PropertyType, [In, Optional] IntPtr PropertyBuffer, uint PropertyBufferSize,
[In, Optional] uint ulFlags, [In, Optional] HMACHINE hMachine);
/// <summary>The <c>CM_Set_DevNode_Registry_Property</c> function sets a specified device property in the registry.</summary>
/// <param name="dnDevInst">A caller-supplied device instance handle that is bound to the local machine.</param>
/// <param name="ulProperty">
/// A CM_DRP_-prefixed constant value that identifies the device property to be set in the registry. These constants are defined in Cfgmgr32.h.
/// </param>
/// <param name="Buffer">
/// A pointer to a caller-supplied buffer that supplies the requested device property, formatted appropriately for the property's
/// data type.
/// </param>
/// <param name="ulLength">The length, in bytes, of the supplied device property.</param>
/// <param name="ulFlags">Not used, must be zero.</param>
/// <returns>
/// If the operation succeeds, the function returns CR_SUCCESS. Otherwise, it returns one of the CR_-prefixed error codes that are
/// defined in Cfgmgr32.h.
/// </returns>
/// <remarks>For information about how to use device instance handles that are bound to the local machine, see CM_Get_Child.</remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/cfgmgr32/nf-cfgmgr32-cm_set_devnode_registry_propertyw CMAPI CONFIGRET
// CM_Set_DevNode_Registry_PropertyW( DEVINST dnDevInst, ULONG ulProperty, PCVOID Buffer, ULONG ulLength, ULONG ulFlags );
[DllImport(Lib_Cfgmgr32, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("cfgmgr32.h", MSDNShortId = "NF:cfgmgr32.CM_Set_DevNode_Registry_PropertyW")]
public static extern CONFIGRET CM_Set_DevNode_Registry_Property(uint dnDevInst, CM_DRP ulProperty, [In, Optional] IntPtr Buffer, uint ulLength, uint ulFlags = 0);
/// <summary>
/// The <c>CM_Setup_DevNode</c> function restarts a device instance that is not running because there is a problem with the device configuration.
/// </summary>
/// <param name="dnDevInst">A device instance handle that is bound to the local system.</param>
/// <param name="ulFlags">
/// <para>One of the following flag values:</para>
/// <para>CM_SETUP_DEVNODE_READY</para>
/// <para>Restarts a device instance that is not running because of a problem with the device configuration.</para>
/// <para>CM_SETUP_DEVNODE_RESET (Windows XP and later versions of Windows)</para>
/// <para>
/// Resets a device instance that has the no restart device status flag set. The no restart device status flag is set if a device is
/// removed by calling <c>CM_Query_And_Remove_SubTree</c> or <c>CM_Query_And_Remove_SubTree_Ex</c> and specifying the
/// CM_REMOVE_NO_RESTART flag.
/// </para>
/// </param>
/// <returns>
/// If the operation succeeds, the function returns CR_SUCCESS. Otherwise it returns one of the error codes with "CR_" prefix that
/// are defined in Cfgmgr32.h.
/// </returns>
/// <remarks>
/// <para>
/// Device installation applications should use the DIF_PROPERTYCHANGE request to restart a device instead of using this function.
/// The DIF_PROPERTYCHANGE request can be used to enable, disable, restart, stop, or change the properties of a device.
/// </para>
/// <para>
/// If a device instance does not have a problem and is already started, <c>CM_Setup_DevNode</c> returns without changing the status
/// of the device instance.
/// </para>
/// <para>Call CM_Get_DevNode_Status or CM_Get_DevNode_Status_Ex to determine the status and problem code for a device instance.</para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/cfgmgr32/nf-cfgmgr32-cm_setup_devnode CMAPI CONFIGRET CM_Setup_DevNode(
// DEVINST dnDevInst, ULONG ulFlags );
[DllImport(Lib_Cfgmgr32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("cfgmgr32.h", MSDNShortId = "NF:cfgmgr32.CM_Setup_DevNode")]
public static extern CONFIGRET CM_Setup_DevNode(uint dnDevInst, CM_SETUP_DEVNODE ulFlags);
/// <summary>The <c>CM_Uninstall_DevNode</c> function removes all persistent state associated with a device instance.</summary>
/// <param name="dnDevInst">Device instance handle that is bound to the local machine.</param>
/// <param name="ulFlags">Reserved. Must be set to zero.</param>
/// <returns>
/// If the operation succeeds, the function returns CR_SUCCESS. Otherwise, it returns one of the CR_-prefixed error codes defined in Cfgmgr32.h.
/// </returns>
/// <remarks>
/// <para>
/// This function uninstalls the device without sending an <c>IRP_MN_QUERY_REMOVE_DEVICE</c> request or calling class installers or
/// co-installers. If your application will run only on a Target Platform of Desktop, instead of calling
/// <c>CM_Uninstall_DevNode</c>, the application should uninstall the device by calling SetupDiCallClassInstaller with the
/// DIF_REMOVE code, or by calling DiUninstallDevice.
/// </para>
/// <para>Use the following sequence to call this function:</para>
/// <list type="number">
/// <item>
/// <term>Check if CM_Get_DevNode_Status returns success. This means that the device is present.</term>
/// </item>
/// <item>
/// <term>If the device is present, call CM_Query_And_Remove_SubTree.</term>
/// </item>
/// <item>
/// <term>Call <c>CM_Uninstall_DevNode</c>.</term>
/// </item>
/// </list>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/cfgmgr32/nf-cfgmgr32-cm_uninstall_devnode CMAPI CONFIGRET
// CM_Uninstall_DevNode( DEVNODE dnDevInst, ULONG ulFlags );
[DllImport(Lib_Cfgmgr32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("cfgmgr32.h", MSDNShortId = "NF:cfgmgr32.CM_Uninstall_DevNode")]
public static extern CONFIGRET CM_Uninstall_DevNode(uint dnDevInst, uint ulFlags = 0);
/// <summary>
/// <para>
/// Use UnregisterDeviceNotification instead of <c>CM_Unregister_Notification</c> if your code targets Windows 7 or earlier versions
/// of Windows.
/// </para>
/// <para>The <c>CM_Unregister_Notification</c> function closes the specified HCMNOTIFICATION handle.</para>
/// </summary>
/// <param name="NotifyContext">The HCMNOTIFICATION handle returned by the CM_Register_Notification function.</param>
/// <returns>
/// If the operation succeeds, the function returns CR_SUCCESS. Otherwise, it returns one of the CR_-prefixed error codes defined in Cfgmgr32.h.
/// </returns>
/// <remarks>
/// <para>
/// Do not call <c>CM_Unregister_Notification</c> from a notification callback. Doing so may cause a deadlock because
/// <c>CM_Unregister_Notification</c> waits for pending callbacks to finish.
/// </para>
/// <para>
/// Instead, if you want to unregister from the notification callback, you must do so asynchronously. The following sequence shows
/// one way to do this:
/// </para>
/// <list type="number">
/// <item>
/// <term>
/// Allocate a context structure to use with your notifications. Include a pointer to a threadpool work structure ( <c>PTP_WORK</c>)
/// and any other information you would like to pass to the notification callback.
/// </term>
/// </item>
/// <item>
/// <term>
/// Call CreateThreadpoolWork. Provide a callback function that calls <c>CM_Unregister_Notification</c>. Add the returned work
/// structure to the previously allocated context structure.
/// </term>
/// </item>
/// <item>
/// <term>Call CM_Register_Notification and provide the context structure as the pContext parameter.</term>
/// </item>
/// <item>
/// <term>Do work, get notifications, etc.</term>
/// </item>
/// <item>
/// <term>
/// Call SubmitThreadpoolWork from within the notification callback, providing the pointer to a threadpool work structure (
/// <c>PTP_WORK</c>) stored in your context structure.
/// </term>
/// </item>
/// <item>
/// <term>When the threadpool thread runs, the work item calls <c>CM_Unregister_Notification</c>.</term>
/// </item>
/// <item>
/// <term>Call CloseThreadpoolWork to release the work object.</term>
/// </item>
/// </list>
/// <para>If you are finished with the context structure, don't forget to release resources and and free the structure.</para>
/// <para>
/// <c>Caution</c> Do not free the context structure until after the work item has called <c>CM_Unregister_Notification</c>. You can
/// still receive notifications after submitting the threadpool work item and before the work item calls <c>CM_Unregister_Notification</c>.
/// </para>
/// <para>Examples</para>
/// <para>The following example shows how to unregister from the notification callback, as described in the Remarks section.</para>
/// <para>
/// <code>typedef struct _CALLBACK_CONTEXT { BOOL bUnregister; PTP_WORK pWork; HCMNOTIFICATION hNotify; CRITICAL_SECTION lock; } CALLBACK_CONTEXT, *PCALLBACK_CONTEXT; DWORD WINAPI EventCallback( __in HCMNOTIFICATION hNotification, __in PVOID Context, __in CM_NOTIFY_ACTION Action, __in PCM_NOTIFY_EVENT_DATA EventData, __in DWORD EventDataSize ) { PCALLBACK_CONTEXT pCallbackContext = (PCALLBACK_CONTEXT)Context; // unregister from the callback EnterCriticalSection(&amp;(pCallbackContext-&gt;lock)); // in case this callback fires before the registration call returns, make sure the notification handle is properly set Context-&gt;hNotify = hNotification; if (!pCallbackContext-&gt;bUnregister) { pCallbackContext-&gt;bUnregister = TRUE; SubmitThreadpoolWork(pCallbackContext-&gt;pWork); } LeaveCriticalSection(&amp;(pCallbackContext-&gt;lock)); return ERROR_SUCCESS; }; VOID CALLBACK WorkCallback( _Inout_ PTP_CALLBACK_INSTANCE Instance, _Inout_opt_ PVOID Context, _Inout_ PTP_WORK pWork ) { PCALLBACK_CONTEXT pCallbackContext = (PCALLBACK_CONTEXT)Context; CM_Unregister_Notification(pCallbackContext-&gt;hNotify); } VOID NotificationFunction() { CONFIGRET cr = CR_SUCCESS; HRESULT hr = S_OK; CM_NOTIFY_FILTER NotifyFilter = { 0 }; BOOL bShouldUnregister = FALSE; PCALLBACK_CONTEXT context; context = (PCALLBACK_CONTEXT)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CALLBACK_CONTEXT)); if (context == NULL) { goto end; } InitializeCriticalSection(&amp;(context-&gt;lock)); NotifyFilter.cbSize = sizeof(NotifyFilter); NotifyFilter.Flags = 0; NotifyFilter.FilterType = CM_NOTIFY_FILTER_TYPE_DEVICEINSTANCE; NotifyFilter.Reserved = 0; hr = StringCchCopy(NotifyFilter.u.DeviceInstance.InstanceId, MAX_DEVICE_ID_LEN, TEST_DEVICE_INSTANCE_ID); if (FAILED(hr)) { goto end; } context-&gt;pWork = CreateThreadpoolWork(WorkCallback, context, NULL); if (context-&gt;pWork == NULL) { goto end; } cr = CM_Register_Notification(&amp;NotifyFilter, context, EventCallback, &amp;context-&gt;hNotify); if (cr != CR_SUCCESS) { goto end; } // ... do work here ... EnterCriticalSection(&amp;(context-&gt;lock)); if (!context-&gt;bUnregister) { // unregister not from the callback bShouldUnregister = TRUE; context-&gt;bUnregister = TRUE; } LeaveCriticalSection(&amp;(context-&gt;lock)); if (bShouldUnregister) { cr = CM_Unregister_Notification(context-&gt;hNotify); if (cr != CR_SUCCESS) { goto end; } } else { // if the callback is the one performing the unregister, wait for the threadpool work item to complete the unregister WaitForThreadpoolWorkCallbacks(context-&gt;pWork, FALSE); } end: if (context != NULL) { if (context-&gt;pWork != NULL) { CloseThreadpoolWork(context-&gt;pWork); } DeleteCriticalSection(&amp;(context-&gt;lock)); HeapFree(GetProcessHeap(), 0, context); } return; }</code>
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/cfgmgr32/nf-cfgmgr32-cm_unregister_notification CMAPI CONFIGRET
// CM_Unregister_Notification( HCMNOTIFICATION NotifyContext );
[DllImport(Lib_Cfgmgr32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("cfgmgr32.h", MSDNShortId = "NF:cfgmgr32.CM_Unregister_Notification")]
public static extern CONFIGRET CM_Unregister_Notification([In] HCMNOTIFICATION NotifyContext);
/// <summary>
/// The <c>CMP_WaitNoPendingInstallEvents</c> (CM_WaitNoPendingInstallEvents) function waits until there are no pending device
/// installation activities for the PnP manager to perform.
/// </summary>
/// <param name="dwTimeout">
/// <para>Specifies a time-out interval, in milliseconds.</para>
/// <list type="bullet">
/// <item>
/// <term>If dwTimeout is set to zero, the function tests whether there are pending installation events and returns immediately.</term>
/// </item>
/// <item>
/// <term>If dwTimeout is set to INFINITE (defined in Winbase.h), the function's time-out interval never elapses.</term>
/// </item>
/// <item>
/// <term>
/// For all other dwTimeout values, the function returns when the specified interval elapses, even if there are still pending
/// installation events.
/// </term>
/// </item>
/// </list>
/// </param>
/// <returns>
/// <para>The function returns one of the following values (defined in Winbase.h):</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>WAIT_OBJECT_0</term>
/// <term>There are no pending installation activities.</term>
/// </item>
/// <item>
/// <term>WAIT_TIMEOUT</term>
/// <term>The time-out interval elapsed, and installation activities are still pending.</term>
/// </item>
/// <item>
/// <term>WAIT_FAILED</term>
/// <term>The function failed. Call GetLastError for additional error information.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// The function waits for an internal event object, which the PnP manager sets when it determines that no installation activities
/// are pending.
/// </para>
/// <para>
/// If a non-zero time-out value is specified, then <c>CMP_WaitNoPendingInstallEvents</c> will return either when no installation
/// events are pending or when the time-out period has expired, whichever comes first.
/// </para>
/// <para>
/// New installation events can occur at any time. This function just indicates that there are no pending installation activities at
/// the moment it is called.
/// </para>
/// <para>
/// This function is typically used by device installation applications. For more information, see Writing a Device Installation Application.
/// </para>
/// <para>
/// Do not call this function while processing any events inside of a system-initiated callback function that is expected to return
/// within a short amount of time. This includes service startup (for example in the <c>ServiceMain</c> callback function) or while
/// processing any control in the service handler (for example, the <c>Handler</c> callback function), or from installation
/// components such as class-installers or co-installers.
/// </para>
/// <para>
/// For Windows XP (with no service pack installed), this function must be called from session zero, with administrator privileges.
/// For Windows XP with Service Pack 1 (SP1) and later versions of Windows, the function can be called from any session, and
/// administrator privileges are not required.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/cfgmgr32/nf-cfgmgr32-cm_waitnopendinginstallevents DWORD
// CM_WaitNoPendingInstallEvents( DWORD dwTimeout );
[DllImport(Lib_Cfgmgr32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("cfgmgr32.h", MSDNShortId = "NF:cfgmgr32.CM_WaitNoPendingInstallEvents")]
public static extern Kernel32.WAIT_STATUS CM_WaitNoPendingInstallEvents(uint dwTimeout);
/// <summary>Gets the .NET exception for a <see cref="CONFIGRET"/> value.</summary>
/// <param name="cr">The <see cref="CONFIGRET"/> value to check.</param>
/// <param name="message">The message.</param>
/// <returns>An exception instance or <see langword="null"/> if value indicated success.</returns>
public static Exception GetException(this CONFIGRET cr, string message = null)
{
if (cr == CONFIGRET.CR_SUCCESS) return null;
var err = cr.ToError(Win32Error.RPC_S_UNKNOWN_IF);
if (err == Win32Error.RPC_S_UNKNOWN_IF)
{
var ex = new Exception(message);
ex.Data.Add("CONFIGRET", cr);
return ex;
}
return err.GetException(message);
}
/// <summary>Throws an exception if <see cref="CONFIGRET"/> value is not <see cref="CONFIGRET.CR_SUCCESS"/>.</summary>
/// <param name="cr">The <see cref="CONFIGRET"/> value to check.</param>
/// <param name="message">The message.</param>
public static void ThrowIfFailed(this CONFIGRET cr, string message = null) { if (cr != CONFIGRET.CR_SUCCESS) throw cr.GetException(message); }
/// <summary>Converts a specified <c>CONFIGRET</c> code to its equivalent system error code.</summary>
/// <param name="cr">The <c>CONFIGRET</c> code to be converted.</param>
/// <param name="defaultErr">
/// A default system error code to be returned when no system error code is mapped to the specified <c>CONFIGRET</c> code.
/// </param>
/// <returns>
/// <para>The system error code that corresponds to the <c>CONFIGRET</c> code.</para>
/// <para>
/// When there is no mapping from the specified <c>CONFIGRET</c> code to a system error code, <c>CM_MapCrToWin32Err</c> returns the
/// value specified in <paramref name="defaultErr"/>.
/// </para>
/// </returns>
public static Win32Error ToError(this CONFIGRET cr, Win32Error defaultErr) => CM_MapCrToWin32Err(cr, (uint)defaultErr);
}
}