using Microsoft.Win32.SafeHandles; using static Vanara.PInvoke.AdvApi32; using static Vanara.PInvoke.SetupAPI; namespace Vanara.PInvoke; /// Items from the CfgMgr32.dll public static partial class CfgMgr32 { /// The callback routine invoked by the Configuration Manager when listening for events. /// The handle of the notification context which invoked the callback. /// A user-provided callback context. /// The device action which triggered the callback. /// The callback data. /// The size of the callback data struct. /// /// If responding to a notification, the callback should return either or , as appropriate. Otherwise, the callback should return . The callback should not return any other values. /// [UnmanagedFunctionPointer(CallingConvention.Winapi)] public delegate Win32Error CM_NOTIFY_CALLBACK(HCMNOTIFICATION notify, [Optional] IntPtr context, CM_NOTIFY_ACTION action, [In] IntPtr eventData, uint eventDataSize); /// /// A variable of ULONG type that supplies one of the following flag values that apply if the caller supplies a device instance identifier /// [PInvokeData("cfgmgr32.h", MSDNShortId = "NF:cfgmgr32.CM_Locate_DevNodeA")] [Flags] public enum CM_LOCATE_DEVINST : uint { /// CM_LOCATE_DEVINST_NORMAL = CM_LOCATE_DEVNODE.CM_LOCATE_DEVNODE_NORMAL, /// CM_LOCATE_DEVINST_PHANTOM = CM_LOCATE_DEVNODE.CM_LOCATE_DEVNODE_PHANTOM, /// CM_LOCATE_DEVINST_CANCELREMOVE = CM_LOCATE_DEVNODE.CM_LOCATE_DEVNODE_CANCELREMOVE, /// CM_LOCATE_DEVINST_NOVALIDATION = CM_LOCATE_DEVNODE.CM_LOCATE_DEVNODE_NOVALIDATION, } /// /// A variable of ULONG type that supplies one of the following flag values that apply if the caller supplies a device instance identifier /// [PInvokeData("cfgmgr32.h", MSDNShortId = "NF:cfgmgr32.CM_Locate_DevNodeA")] [Flags] public enum CM_LOCATE_DEVNODE : uint { /// /// The function retrieves the device instance handle for the specified device only if the device is currently configured in the /// device tree. /// CM_LOCATE_DEVNODE_NORMAL = 0x00000000, /// /// 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. /// CM_LOCATE_DEVNODE_PHANTOM = 0x00000001, /// /// 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. /// CM_LOCATE_DEVNODE_CANCELREMOVE = 0x00000002, /// Not used. CM_LOCATE_DEVNODE_NOVALIDATION = 0x00000004, } /// This enumeration identifies Plug and Play device event types. /// /// 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 CM_NOTIFY_ACTION enumeration. /// // 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 { /// /// 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. /// CM_NOTIFY_ACTION_DEVICEINTERFACEARRIVAL = 0, /// /// 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. /// CM_NOTIFY_ACTION_DEVICEINTERFACEREMOVAL, /// /// 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. /// CM_NOTIFY_ACTION_DEVICEQUERYREMOVE, /// /// 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. /// CM_NOTIFY_ACTION_DEVICEQUERYREMOVEFAILED, /// /// 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. /// CM_NOTIFY_ACTION_DEVICEREMOVEPENDING, /// /// 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. /// CM_NOTIFY_ACTION_DEVICEREMOVECOMPLETE, /// /// 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. /// CM_NOTIFY_ACTION_DEVICECUSTOMEVENT, /// /// 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. /// CM_NOTIFY_ACTION_DEVICEINSTANCEENUMERATED, /// /// 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. /// CM_NOTIFY_ACTION_DEVICEINSTANCESTARTED, /// /// 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. /// CM_NOTIFY_ACTION_DEVICEINSTANCEREMOVED, } /// Flags for [Flags] public enum CM_NOTIFY_FILTER_FLAG : uint { /// /// Register to receive notifications for PnP events for all device interface classes. The memory at /// pFilter->u.DeviceInterface.ClassGuid must be zeroes. Do not use this flag with /// CM_NOTIFY_FILTER_FLAG_ALL_DEVICE_INSTANCES. This flag is only valid if pFilter->FilterType is CM_NOTIFY_FILTER_TYPE_DEVICEINTERFACE. /// CM_NOTIFY_FILTER_FLAG_ALL_INTERFACE_CLASSES = 0x00000001, /// /// Register to receive notifications for PnP events for all devices. pFilter->u.DeviceInstance.InstanceId must be an /// empty string. Do not use this flag with CM_NOTIFY_FILTER_FLAG_ALL_INTERFACE_CLASSES. This flag is only valid if /// pFilter->FilterType is CM_NOTIFY_FILTER_TYPE_DEVICEINSTANCE. /// CM_NOTIFY_FILTER_FLAG_ALL_DEVICE_INSTANCES = 0x00000002, } /// Options for [PInvokeData("cfgmgr32.h", MSDNShortId = "NS:cfgmgr32._CM_NOTIFY_FILTER")] public enum CM_NOTIFY_FILTER_TYPE { /// /// Register for notifications for device interface events. pFilter->u.DeviceInterface.ClassGuid should be filled in /// with the GUID of the device interface class to receive notifications for. /// CM_NOTIFY_FILTER_TYPE_DEVICEINTERFACE = 0, /// /// Register for notifications for device handle events. pFilter->u.DeviceHandle.hTarget must be filled in with a /// handle to the device to receive notifications for. /// CM_NOTIFY_FILTER_TYPE_DEVICEHANDLE, /// /// Register for notifications for device instance events. pFilter->u.DeviceInstance.InstanceId should be filled in /// with the device instance ID of the device to receive notifications for. /// CM_NOTIFY_FILTER_TYPE_DEVICEINSTANCE, } /// Open class key flags [PInvokeData("cfgmgr32.h", MSDNShortId = "NF:cfgmgr32.CM_Open_Class_KeyW")] public enum CM_OPEN_CLASS_KEY { /// The key to be opened is for a device setup class. CM_OPEN_CLASS_KEY_INSTALLER = 0x00000000, /// The key to be opened is for a device interface class. CM_OPEN_CLASS_KEY_INTERFACE = 0x00000001, } /// Caller-supplied flags that specify how reenumeration should occur. [PInvokeData("cfgmgr32.h", MSDNShortId = "NF:cfgmgr32.CM_Reenumerate_DevNode")] [Flags] public enum CM_REENUMERATE : uint { /// /// Specifies default reenumeration behavior, in which reenumeration occurs synchronously. This flag is functionally equivalent /// to CM_REENUMERATE_SYNCHRONOUS. /// CM_REENUMERATE_NORMAL = 0x00000000, /// /// 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. /// CM_REENUMERATE_SYNCHRONOUS = 0x00000001, /// /// /// 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. /// /// /// 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. /// /// CM_REENUMERATE_RETRY_INSTALLATION = 0x00000002, /// /// 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. /// CM_REENUMERATE_ASYNCHRONOUS = 0x00000004, } /// A bitwise OR of the caller-supplied flag constants [Flags] public enum CM_REMOVE : uint { /// CM_REMOVE_UI_OK = 0x00000000, /// CM_REMOVE_UI_NOT_OK = 0x00000001, /// CM_REMOVE_NO_RESTART = 0x00000002, } /// Flags for . [PInvokeData("cfgmgr32.h", MSDNShortId = "NF:cfgmgr32.CM_Setup_DevNode")] public enum CM_SETUP_DEVNODE { /// Configure devinst without (re)starting CM_SETUP_DEVNODE_CONFIG = 0x00000005, /// Configure devinst class without (re)starting CM_SETUP_DEVNODE_CONFIG_CLASS = 0x00000006, /// Configure devinst extensions without (re)starting CM_SETUP_DEVNODE_CONFIG_EXTENSIONS = 0x00000007, /// Reset devinst configuration without (re)starting CM_SETUP_DEVNODE_CONFIG_RESET = 0x00000008, /// Restarts a device instance that is not running because of a problem with the device configuration. CM_SETUP_DEVNODE_READY = 0x00000000, /// /// 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 CM_Query_And_Remove_SubTree or CM_Query_And_Remove_SubTree_Ex and specifying the /// CM_REMOVE_NO_RESTART flag. /// CM_SETUP_DEVNODE_RESET = 0x00000004, } /// Flags for . [PInvokeData("cfgmgr32.h", MSDNShortId = "NS:cfgmgr32.DMA_Des_s")] [Flags] public enum DMA_DES_FLAGS : uint { /// Bitmask for the bits within DD_Flags that specify the channel width value. mDD_Width = 0x3, /// 8-bit DMA channel fDD_BYTE = 0x0, /// 16-bit DMA channel fDD_WORD = 0x1, /// 32-bit DMA channel fDD_DWORD = 0x2, /// 8-bit and 16-bit DMA channel fDD_BYTE_AND_WORD = 0x3, /// Bitmask for the bits within DD_Flags that specify the bus mastering value. mDD_BusMaster = 0x4, /// No bus mastering fDD_NoBusMaster = 0x0, /// Bus mastering fDD_BusMaster = 0x4, /// Bitmask for the bits within DD_Flags that specify the DMA type value. mDD_Type = 0x18, /// Standard DMA fDD_TypeStandard = 0x00, /// Type-A DMA fDD_TypeA = 0x08, /// Type-B DMA fDD_TypeB = 0x10, /// Type-F DMA fDD_TypeF = 0x18, } /// Flags for . [PInvokeData("cfgmgr32.h", MSDNShortId = "NS:cfgmgr32.IO_Des_s")] [Flags] public enum IO_DES_FLAGS : uint { /// Bitmask for the bits within IOD_DesFlags that specify the port type value. fIOD_PortType = 0x1, /// The device is accessed in memory address space. fIOD_Memory = 0x0, /// The device is accessed in I/O address space. fIOD_IO = 0x1, /// Bitmask for the bits within IOD_DesFlags that specify the decode value. fIOD_DECODE = 0x00fc, /// The device decodes 10 bits of the port address. fIOD_10_BIT_DECODE = 0x0004, /// The device decodes 12 bits of the port address. fIOD_12_BIT_DECODE = 0x0008, /// The device decodes 16 bits of the port address. fIOD_16_BIT_DECODE = 0x0010, /// The device uses "positive decode" instead of "subtractive decode." fIOD_POSITIVE_DECODE = 0x0020, /// fIOD_PASSIVE_DECODE = 0x0040, /// fIOD_WINDOW_DECODE = 0x0080, /// fIOD_PORT_BAR = 0x0100, } /// Flags for [Flags] public enum IRQD_FLAGS : ushort { /// Bitmask,whether the IRQ may be shared: mIRQD_Share = 0x1, /// The IRQ may not be shared fIRQD_Exclusive = 0x0, /// The IRQ may be shared fIRQD_Share = 0x1, /// Bitmask,whether edge or level triggered: mIRQD_Edge_Level = 0x2, /// The IRQ is level-sensitive fIRQD_Level = 0x0, /// The IRQ is edge-sensitive fIRQD_Edge = 0x2, } /// Flags for [PInvokeData("cfgmgr32.h", MSDNShortId = "NS:cfgmgr32.Mem_Des_s")] [Flags] public enum MEM_DES_FLAGS : uint { /// Bitmask, whether memory is writable mMD_MemoryType = 0x1, /// Memory range is read-only fMD_ROM = 0x0, /// Memory range may be written to fMD_RAM = 0x1, /// Bitmask, memory is 24 or 32-bit mMD_32_24 = 0x2, /// Memory range is 24-bit fMD_24 = 0x0, /// Memory range is 32-bit fMD_32 = 0x2, /// Bitmask,whether memory prefetchable mMD_Prefetchable = 0x4, /// Memory range is not prefetchable fMD_PrefetchDisallowed = 0x0, /// Memory range is prefetchable fMD_PrefetchAllowed = 0x4, /// Bitmask,whether memory is readable mMD_Readable = 0x8, /// Memory range is readable fMD_ReadAllowed = 0x0, /// Memory range is write-only fMD_ReadDisallowed = 0x8, /// Bitmask,supports write-behind mMD_CombinedWrite = 0x10, /// no combined-write caching fMD_CombinedWriteDisallowed = 0x0, /// supports combined-write caching fMD_CombinedWriteAllowed = 0x10, /// Bitmask,whether memory is cacheable mMD_Cacheable = 0x20, /// Memory range is non-cacheable fMD_NonCacheable = 0x0, /// Memory range is cacheable fMD_Cacheable = 0x20, /// Memory range is bridge window decode. fMD_WINDOW_DECODE = 0x40, /// Memory BAR resource. fMD_MEMORY_BAR = 0x80, } /// Flags for [Flags] public enum MFCARD_DES_FLAGS : uint { /// Bitmask, whether audio is enabled or not mPMF_AUDIO_ENABLE = 0x8, /// Audio is enabled fPMF_AUDIO_ENABLE = 0x8, } /// Flags for . [Flags] public enum PCD_FLAGS : uint { /// Bitmask, whether I/O is 8 or 16 bits mPCD_IO_8_16 = 0x1, /// I/O is 8-bit fPCD_IO_8 = 0x0, /// I/O is 16-bit fPCD_IO_16 = 0x1, /// Bitmask, whether MEM is 8 or 16 bits mPCD_MEM_8_16 = 0x2, /// MEM is 8-bit fPCD_MEM_8 = 0x0, /// MEM is 16-bit fPCD_MEM_16 = 0x2, /// Bitmask, whether MEMx is Attribute or Common mPCD_MEM_A_C = 0xC, /// MEM1 is Attribute fPCD_MEM1_A = 0x4, /// MEM2 is Attribute fPCD_MEM2_A = 0x8, /// zero wait on 8 bit I/O fPCD_IO_ZW_8 = 0x10, /// iosrc 16 fPCD_IO_SRC_16 = 0x20, /// wait states on 16 bit io fPCD_IO_WS_16 = 0x40, /// Bitmask, for additional wait states on memory windows mPCD_MEM_WS = 0x300, /// 1 wait state fPCD_MEM_WS_ONE = 0x100, /// 2 wait states fPCD_MEM_WS_TWO = 0x200, /// 3 wait states fPCD_MEM_WS_THREE = 0x300, /// MEM is Attribute fPCD_MEM_A = 0x4, /// fPCD_ATTRIBUTES_PER_WINDOW = 0x8000, /// I/O window 1 is 16-bit fPCD_IO1_16 = 0x00010000, /// I/O window 1 zero wait on 8 bit I/O fPCD_IO1_ZW_8 = 0x00020000, /// I/O window 1 iosrc 16 fPCD_IO1_SRC_16 = 0x00040000, /// I/O window 1 wait states on 16 bit io fPCD_IO1_WS_16 = 0x00080000, /// I/O window 2 is 16-bit fPCD_IO2_16 = 0x00100000, /// I/O window 2 zero wait on 8 bit I/O fPCD_IO2_ZW_8 = 0x00200000, /// I/O window 2 iosrc 16 fPCD_IO2_SRC_16 = 0x00400000, /// I/O window 2 wait states on 16 bit io fPCD_IO2_WS_16 = 0x00800000, /// MEM window 1 Bitmask, for additional wait states on memory windows mPCD_MEM1_WS = 0x03000000, /// MEM window 1, 1 wait state fPCD_MEM1_WS_ONE = 0x01000000, /// MEM window 1, 2 wait states fPCD_MEM1_WS_TWO = 0x02000000, /// MEM window 1, 3 wait states fPCD_MEM1_WS_THREE = 0x03000000, /// MEM window 1 is 16-bit fPCD_MEM1_16 = 0x04000000, /// MEM window 2 Bitmask, for additional wait states on memory windows mPCD_MEM2_WS = 0x30000000, /// MEM window 2, 1 wait state fPCD_MEM2_WS_ONE = 0x10000000, /// MEM window 2, 2 wait states fPCD_MEM2_WS_TWO = 0x20000000, /// MEM window 2, 3 wait states fPCD_MEM2_WS_THREE = 0x30000000, /// MEM window 2 is 16-bit fPCD_MEM2_16 = 0x40000000, } /// Specifies how the registry key is to be opened. [PInvokeData("cfgmgr32.h", MSDNShortId = "NF:cfgmgr32.CM_Open_Class_KeyW")] public enum REGDISPOSITION { /// Open the key if it exists. Otherwise, create the key. RegDisposition_OpenAlways = 0x00000000, /// Open the key only if it exists. RegDisposition_OpenExisting = 0x00000001, } /// /// The CM_Get_Sibling function obtains a device instance handle to the next sibling node of a specified device node /// (devnode) in the local machine's device tree. /// /// /// 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. /// /// Caller-supplied device instance handle that is bound to the local machine. /// Not used, must be zero. /// /// If the operation succeeds, the function returns CR_SUCCESS. Otherwise, it returns one of the CR_-prefixed error codes defined in Cfgmgr32.h. /// /// /// /// 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 CM_Get_Sibling to obtain handles for the rest of the children. /// /// For information about using device instance handles that are bound to the local machine, see CM_Get_Child. /// // 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); /// /// [Beginning with Windows 8 and Windows Server 2012, this function has been deprecated. Please use CM_Get_Sibling instead.] /// /// The CM_Get_Sibling_Ex 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. /// /// /// /// 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. /// /// Caller-supplied device instance handle that is bound to the machine handle specified by hMachine. /// Not used, must be zero. /// /// Caller-supplied machine handle to which the caller-supplied device instance handle is bound. /// /// Note Using this function to access remote machines is not supported beginning with Windows 8 and Windows Server 2012, as /// this functionality has been removed. /// /// /// /// If the operation succeeds, the function returns CR_SUCCESS. Otherwise, it returns one of the CR_-prefixed error codes defined in Cfgmgr32.h. /// /// /// /// 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 CM_Get_Sibling_Ex to obtain handles for the rest of the children. /// /// For information about using device instance handles that are bound to a local or a remote machine, see CM_Get_Child_Ex. /// /// 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. /// /// // 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); /// /// [Beginning with Windows 8 and Windows Server 2012, this function has been deprecated and should not be used.] /// /// The CM_Get_Version function returns version 4.0 of the Plug and Play (PnP) Configuration Manager DLL (Cfgmgr32.dll) for a /// local machine. /// /// /// /// 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. /// /// /// /// 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. /// /// /// 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. /// /// // 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(); /// /// [Beginning with Windows 8 and Windows Server 2012, this function has been deprecated and should not be used.] /// /// The CM_Get_Version_Ex function returns version 4.0 of the Plug and Play (PnP) Configuration Manager DLL (Cfgmgr32.dll) /// for a local or a remote machine. /// /// /// /// Supplies a machine handle that is returned by CM_Connect_Machine. /// /// Note Using this function to access remote machines is not supported beginning with Windows 8 and Windows Server 2012, as /// this functionality has been removed. /// /// /// /// 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. /// /// /// /// 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. /// /// /// 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. /// /// /// 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. /// /// // 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); /// The CM_Is_Dock_Station_Present function identifies whether a docking station is present in a local machine. /// /// Pointer to a Boolean value that indicates whether a docking station is present in a local machine. The function sets *pbPresent /// to TRUE if a docking station is present. Otherwise, the function sets *pbPresent to FALSE. /// /// /// 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. /// /// /// /// 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: /// /// /// /// /// CM_Is_Dock_Station_Present_Ex identifies whether a docking station is present in a local or a remote machine. /// /// /// /// /// CM_Request_Eject_PC requests that a portable PC, which is inserted in a local docking station, be ejected. /// /// /// /// /// CM_Request_Eject_PC_Ex requests that a portable PC, which is inserted in a local or a remote docking station, be ejected. /// /// /// /// // 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); /// /// /// [Beginning with Windows 8 and Windows Server 2012, this function has been deprecated. Please use CM_Is_Dock_Station_Present instead.] /// /// /// The CM_Is_Dock_Station_Present_Ex function identifies whether a docking station is present in a local or a remote machine. /// /// /// /// Pointer to a Boolean value that indicates whether a docking station is present in a local machine. The function sets *pbPresent /// to TRUE if a docking station is present. The function sets *pbPresent to FALSE if the function cannot connect to /// the specified machine or a docking station is not present. /// /// /// Supplies a machine handle that is returned by CM_Connect_Machine. /// /// Note Using this function to access remote machines is not supported beginning with Windows 8 and Windows Server 2012, as /// this functionality has been removed. /// /// /// /// 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. /// /// /// /// 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: /// /// /// /// /// CM_Is_Dock_Station_Present identifies whether a docking station is present in a local machine. /// /// /// /// /// CM_Request_Eject_PC requests that a portable PC, which is inserted in a local docking station, be ejected. /// /// /// /// /// CM_Request_Eject_PC_Ex requests that a portable PC, which is inserted in a local or a remote docking station, be ejected. /// /// /// /// /// 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. /// /// // 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); /// /// [Beginning with Windows 8 and Windows Server 2012, this function has been deprecated and should not be used.] /// /// The CM_Is_Version_Available function indicates whether a specified version of the Plug and Play (PnP) Configuration /// Manager DLL (Cfgmgr32.dll) is supported by a local machine. /// /// /// /// /// 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 2000 and later versions of /// Windows. 0x0501 specifies version 5.1, which is supported by Windows XP and later versions of Windows. /// /// /// /// The function returns TRUE if the local machine supports the specified version of the configuration manager. Otherwise, /// the function returns FALSE. /// /// /// 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. /// // 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); /// /// [Beginning with Windows 8 and Windows Server 2012, this function has been deprecated and should not be used.] /// /// The CM_Is_Version_Available_Ex 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. /// /// /// /// 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. /// /// /// Supplies a machine handle that is returned by CM_Connect_Machine. /// /// Note Using this function to access remote machines is not supported beginning with Windows 8 and Windows Server 2012, as /// this functionality has been removed. /// /// /// /// The function returns TRUE if the function can connect to the specified machine and if the machine supports the specified /// version. Otherwise, the function returns FALSE. /// /// /// /// 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. /// /// /// 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. /// /// // 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); /// /// The CM_Locate_DevNode function obtains a device instance handle to the device node that is associated with a specified /// device instance ID on the local machine. /// /// /// A pointer to a device instance handle that CM_Locate_DevNode retrieves. The retrieved handle is bound to the local machine. /// /// /// A pointer to a NULL-terminated string representing a device instance ID. If this value is NULL, 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. /// /// /// /// A variable of ULONG type that supplies one of the following flag values that apply if the caller supplies a device instance identifier: /// /// CM_LOCATE_DEVNODE_NORMAL /// /// The function retrieves the device instance handle for the specified device only if the device is currently configured in the /// device tree. /// /// CM_LOCATE_DEVNODE_PHANTOM /// /// 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. /// /// CM_LOCATE_DEVNODE_CANCELREMOVE /// /// 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. /// /// CM_LOCATE_DEVNODE_NOVALIDATION /// Not used. /// /// /// If the operation succeeds, CM_Locate_DevNode returns CR_SUCCESS. Otherwise, the function returns one of the CR_Xxx error /// codes that are defined in Cfgmgr32.h. /// /// /// For information about using device instance handles that are bound to the local machine, see CM_Get_Child. /// /// Note /// /// 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. /// /// /// // 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); /// /// [Beginning with Windows 8 and Windows Server 2012, this function has been deprecated. Please use CM_Locate_DevNode instead.] /// /// The CM_Locate_DevNode_Ex 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. /// /// /// /// A pointer to the device instance handle that this function retrieves. The retrieved handle is bound to the machine handle /// specified by hMachine. /// /// /// A pointer to a NULL-terminated string representing a device instance ID. If this value is NULL, 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. /// /// /// /// A variable of ULONG type that supplies one of the following flag values that apply if the caller supplies a device instance identifier: /// /// CM_LOCATE_DEVNODE_NORMAL /// /// The function retrieves the device instance handle for the specified device only if the device is currently configured in the /// device tree. /// /// CM_LOCATE_DEVNODE_PHANTOM /// /// 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. /// /// CM_LOCATE_DEVNODE_CANCELREMOVE /// /// 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. /// /// CM_LOCATE_DEVNODE_NOVALIDATION /// Not used. /// /// /// /// 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 RemoteMachineHandle 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. /// /// /// Note Using this function to access remote machines is not supported beginning with Windows 8 and Windows Server 2012, as /// this functionality has been removed. /// /// /// /// If the operation succeeds, CM_Locate_DevNode returns CR_SUCCESS. Otherwise, the function returns one of the CR_-prefixed /// error codes that are defined in Cfgmgr32.h. /// /// /// For information about using device instance handles that are bound to a local or a remote machine, see CM_Get_Child_Ex. /// /// 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. /// /// // 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); /// Converts a specified CONFIGRET code to its equivalent system error code. /// The CONFIGRET code to be converted. CONFIGRET error codes are defined in CfgMgr32.h. /// /// A default system error code to be returned when no system error code is mapped to the specified CONFIGRET code. /// /// /// The system error code that corresponds to the CONFIGRET code. System error codes are defined in Winerror.h. /// /// When there is no mapping from the specified CONFIGRET code to a system error code, CM_MapCrToWin32Err returns the /// value specified in the DefaultErr parameter. /// /// // 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); /// The CM_Modify_Res_Des function modifies a specified resource descriptor on the local machine. /// Pointer to a location to receive a handle to the modified resource descriptor. /// /// /// Caller-supplied handle to the resource descriptor to be modified. This handle must have been previously obtained by calling one /// of the following functions: /// /// CM_Add_Res_Des /// CM_Add_Res_Des_Ex /// CM_Get_Next_Res_Des /// CM_Get_Next_Res_Des_Ex /// CM_Modify_Res_Des /// CM_Modify_Res_Des_Ex /// /// /// Caller-supplied resource type identifier. This must be one of the ResType_-prefixed constants defined in Cfgmgr32.h. /// /// /// 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. /// /// Caller-supplied length of the structure pointed to by ResourceData. /// Not used, must be zero. /// /// /// If the operation succeeds, the function returns CR_SUCCESS. Otherwise, it returns one of the CR_-prefixed error codes defined in Cfgmgr32.h. /// /// /// Note Starting with Windows 8, CM_Modify_Res_Des 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. /// /// /// /// /// 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. /// /// /// If the value specified for ResourceID is ResType_ClassSpecific, then the specified resource descriptor must be the last /// one associated with the logical configuration. /// /// /// Callers of CM_Modify_Res_Des must call CM_Free_Res_Des_Handle to deallocate the resource descriptor handle, after it is /// no longer needed. /// /// /// Callers of this function must have SeLoadDriverPrivilege. (Privileges are described in the Microsoft Windows SDK documentation.) /// /// // 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); /// The CM_Modify_Res_Des function modifies a specified resource descriptor on the local machine. /// The type of the data. /// /// /// Caller-supplied handle to the resource descriptor to be modified. This handle must have been previously obtained by calling one /// of the following functions: /// /// CM_Add_Res_Des /// CM_Add_Res_Des_Ex /// CM_Get_Next_Res_Des /// CM_Get_Next_Res_Des_Ex /// CM_Modify_Res_Des /// CM_Modify_Res_Des_Ex /// /// /// 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. /// /// /// Caller-supplied resource type identifier. This must be one of the ResType_-prefixed constants defined in Cfgmgr32.h. /// /// /// A handle to the modified resource descriptor. /// /// Note Starting with Windows 8, CM_Modify_Res_Des 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. /// /// /// Unable to determine RESOURCEID from type. - T /// /// /// 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. /// /// /// If the value specified for ResourceID is ResType_ClassSpecific, then the specified resource descriptor must be the last /// one associated with the logical configuration. /// /// /// Callers of this function must have SeLoadDriverPrivilege. (Privileges are described in the Microsoft Windows SDK documentation.) /// /// public static SafeRES_DES CM_Modify_Res_Des(RES_DES rdResDes, T data, RESOURCEID ResourceID = 0) where T : struct { if (ResourceID == 0 && !CorrespondingTypeAttribute.CanSet(out ResourceID)) throw new ArgumentException("Unable to determine RESOURCEID from type.", nameof(T)); using var mem = new SafeAnysizeStruct(data); CM_Modify_Res_Des(out var hRD, rdResDes, ResourceID, mem, mem.Size).ThrowIfFailed(); return hRD; } /// /// [Beginning with Windows 8 and Windows Server 2012, this function has been deprecated. Please use CM_Modify_Res_Des instead.] /// The CM_Modify_Res_Des_Ex function modifies a specified resource descriptor on a local or a remote machine. /// /// Pointer to a location to receive a handle to the modified resource descriptor. /// /// /// Caller-supplied handle to the resource descriptor to be modified. This handle must have been previously obtained by calling one /// of the following functions: /// /// CM_Add_Res_Des /// CM_Add_Res_Des_Ex /// CM_Get_Next_Res_Des /// CM_Get_Next_Res_Des_Ex /// CM_Modify_Res_Des /// CM_Modify_Res_Des_Ex /// /// /// Caller-supplied resource type identifier. This must be one of the ResType_-prefixed constants defined in Cfgmgr32.h. /// /// /// 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. /// /// Caller-supplied length of the structure pointed to by ResourceData. /// Not used, must be zero. /// /// Caller-supplied machine handle, obtained from a previous call to CM_Connect_Machine. /// /// Note Using this function to access remote machines is not supported beginning with Windows 8 and Windows Server 2012, as /// this functionality has been removed. /// /// /// /// /// If the operation succeeds, the function returns CR_SUCCESS. Otherwise, it returns one of the CR_-prefixed error codes defined in Cfgmgr32.h. /// /// /// Note Starting with Windows 8, CM_Modify_Res_Des_Ex 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. /// /// /// /// /// 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. /// /// /// If the value specified for ResourceID is ResType_ClassSpecific, then the specified resource descriptor must be the last /// one associated with the logical configuration. /// /// /// Callers of CM_Modify_Res_Des_Ex must call CM_Free_Res_Des_Handle to deallocate the resource descriptor handle, after it /// is no longer needed. /// /// /// Callers of this function must have SeLoadDriverPrivilege. (Privileges are described in the Microsoft Windows SDK documentation.) /// /// /// 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. /// /// // 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); /// /// The CM_Open_Class_Key function opens the device setup class registry key, the device interface class registry key, or a /// specific subkey of a class. /// /// /// 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. /// /// Reserved. Must be set to NULL. /// The registry security access for the key to be opened. /// /// Specifies how the registry key is to be opened. May be one of the following values: /// RegDisposition_OpenAlways /// Open the key if it exists. Otherwise, create the key. /// RegDisposition_OpenExisting /// Open the key only if it exists. /// /// Pointer to an HKEY that will receive the opened key upon success. /// /// Open class key flags: /// CM_OPEN_CLASS_KEY_INSTALLER /// The key to be opened is for a device setup class. /// CM_OPEN_CLASS_KEY_INTERFACE /// The key to be opened is for a device interface class. /// /// /// If the operation succeeds, the function returns CR_SUCCESS. Otherwise, it returns one of the CR_-prefixed error codes defined in Cfgmgr32.h. /// /// Close the handle returned from this function by calling RegCloseKey. // 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); /// /// The CM_Open_Class_Key function opens the device setup class registry key, the device interface class registry key, or a /// specific subkey of a class. /// /// /// 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. /// /// Reserved. Must be set to NULL. /// The registry security access for the key to be opened. /// /// Specifies how the registry key is to be opened. May be one of the following values: /// RegDisposition_OpenAlways /// Open the key if it exists. Otherwise, create the key. /// RegDisposition_OpenExisting /// Open the key only if it exists. /// /// Pointer to an HKEY that will receive the opened key upon success. /// /// Open class key flags: /// CM_OPEN_CLASS_KEY_INSTALLER /// The key to be opened is for a device setup class. /// CM_OPEN_CLASS_KEY_INTERFACE /// The key to be opened is for a device interface class. /// /// /// If the operation succeeds, the function returns CR_SUCCESS. Otherwise, it returns one of the CR_-prefixed error codes defined in Cfgmgr32.h. /// /// Close the handle returned from this function by calling RegCloseKey. // 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] GuidPtr ClassGuid, [Optional, MarshalAs(UnmanagedType.LPTStr)] string? pszClassName, REGSAM samDesired, REGDISPOSITION Disposition, out SafeRegistryHandle phkClass, CM_OPEN_CLASS_KEY ulFlags); /// /// The CM_Open_Device_Interface_Key function opens the registry subkey that is used by applications and drivers to store /// information that is specific to a device interface. /// /// /// Pointer to a string that identifies the device interface instance to open the registry subkey for. /// /// The requested registry security access to the registry subkey. /// /// Specifies how the registry key is to be opened. May be one of the following values: /// RegDisposition_OpenAlways /// Open the key if it exists. Otherwise, create the key. /// RegDisposition_OpenExisting /// Open the key only if it exists. /// /// Pointer to an HKEY that will receive the opened key upon success. /// Reserved. Must be set to zero. /// /// If the operation succeeds, the function returns CR_SUCCESS. Otherwise, it returns one of the CR_-prefixed error codes defined in Cfgmgr32.h. /// /// /// Close the handle returned from this function by calling RegCloseKey. /// /// Note /// /// 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. /// /// /// // 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); /// /// /// [Beginning with Windows 8 and Windows Server 2012, this function has been deprecated. Please use CM_Open_Device_Interface_Key instead.] /// /// /// The CM_Open_Device_Interface_Key_ExA function opens the registry subkey that is used by applications and drivers to store /// information that is specific to a device interface. /// /// /// /// Pointer to a string that identifies the device interface instance to open the registry subkey for. /// /// The requested registry security access to the registry subkey. /// /// Specifies how the registry key is to be opened. May be one of the following values: /// RegDisposition_OpenAlways /// Open the key if it exists. Otherwise, create the key. /// RegDisposition_OpenExisting /// Open the key only if it exists. /// /// Pointer to an HKEY that will receive the opened key upon success. /// Reserved. Must be set to zero. /// /// Caller-supplied machine handle, obtained from a previous call to CM_Connect_Machine. /// /// Note Using this function to access remote machines is not supported beginning with Windows 8 and Windows Server 2012, as /// this functionality has been removed. /// /// /// /// If the operation succeeds, the function returns CR_SUCCESS. Otherwise, it returns one of the CR_-prefixed error codes defined in Cfgmgr32.h. /// /// /// Close the handle returned from this function by calling RegCloseKey. /// /// Note /// /// 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. /// /// /// // 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); /// The CM_Open_DevNode_Key function opens a registry key for device-specific configuration information. /// Caller-supplied device instance handle that is bound to the local machine /// The registry security access that is required for the requested key. /// /// 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. /// /// /// Specifies how the registry key is to be opened. May be one of the following values: /// RegDisposition_OpenAlways /// Open the key if it exists. Otherwise, create the key. /// RegDisposition_OpenExisting /// Open the key only if it exists. /// /// Pointer to an HKEY that will receive the opened key upon success. /// /// /// Open device node key flags. Indicates the scope and type of registry storage key to open. Can be a combination of the following flags: /// /// CM_REGISTRY_HARDWARE /// Open the device’s hardware key. Do not combine with CM_REGISTRY_SOFTWARE. /// CM_REGISTRY_SOFTWARE /// Open the device’s software key. Do not combine with CM_REGISTRY_HARDWARE. /// CM_REGISTRY_USER /// Open the per-user key for the current user. Do not combine with CM_REGISTRY_CONFIG. /// CM_REGISTRY_CONFIG /// Open the key that stores hardware profile-specific configuration information. Do not combine with CM_REGISTRY_USER. /// /// /// If the operation succeeds, the function returns CR_SUCCESS. Otherwise, it returns one of the CR_-prefixed error codes defined in Cfgmgr32.h. /// /// Close the handle returned from this function by calling RegCloseKey. // 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); /// /// The CM_Query_And_Remove_SubTree function checks whether a device instance and its children can be removed and, if so, it /// removes them. /// /// /// 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. /// /// /// (Optional) If the caller does not pass NULL 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. /// /// /// (Optional) If the caller does not pass NULL 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. /// /// /// Caller-supplied value representing the length (number of characters) of the string buffer supplied by pszVetoName. This should /// be set to MAX_PATH. /// /// A bitwise OR of the caller-supplied flag constants that are described in the Remarks section. /// /// If the operation succeeds, the function returns CR_SUCCESS. Otherwise, it returns one of the other CR_-prefixed error codes /// defined in Cfgmgr32.h. /// /// /// /// The purpose of the CM_Query_And_Remove_SubTree 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 SurpriseRemovalOK member of /// DEVICE_CAPABILITIES. If a driver has set SurpriseRemovalOK, the application should call CM_Request_Device_Eject instead /// of CM_Query_And_Remove_SubTree. /// /// /// CM_Query_And_Remove_SubTree 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: /// /// /// Beginning with Windows XP, CM_Query_And_Remove_SubTree also supports setting the following additional flag; this flag /// applies only if the function successfully removes the device instance: /// /// /// Windows applications that do not require the low-level operation CM_Query_And_Remove_SubTree should use the /// DIF_PROPERTYCHANGE request to disable a device instead of using CM_Query_And_Remove_SubTree to remove a device. The /// DIF_PROPERTYCHANGE request can be used to enable, disable, restart, stop, or change the properties of a device. /// /// /// Callers of this function must have SeLoadDriverPrivilege. (Privileges are described in the Microsoft Windows SDK documentation.) /// /// For information about using device instance handles that are bound to the local machine, see CM_Get_Child. /// // 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); /// /// The CM_Query_And_Remove_SubTree function checks whether a device instance and its children can be removed and, if so, it /// removes them. /// /// /// 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. /// /// /// (Optional) If the caller does not pass NULL 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. /// /// /// (Optional) If the caller does not pass NULL 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. /// /// /// Caller-supplied value representing the length (number of characters) of the string buffer supplied by pszVetoName. This should /// be set to MAX_PATH. /// /// A bitwise OR of the caller-supplied flag constants that are described in the Remarks section. /// /// If the operation succeeds, the function returns CR_SUCCESS. Otherwise, it returns one of the other CR_-prefixed error codes /// defined in Cfgmgr32.h. /// /// /// /// The purpose of the CM_Query_And_Remove_SubTree 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 SurpriseRemovalOK member of /// DEVICE_CAPABILITIES. If a driver has set SurpriseRemovalOK, the application should call CM_Request_Device_Eject instead /// of CM_Query_And_Remove_SubTree. /// /// /// CM_Query_And_Remove_SubTree 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: /// /// /// Beginning with Windows XP, CM_Query_And_Remove_SubTree also supports setting the following additional flag; this flag /// applies only if the function successfully removes the device instance: /// /// /// Windows applications that do not require the low-level operation CM_Query_And_Remove_SubTree should use the /// DIF_PROPERTYCHANGE request to disable a device instead of using CM_Query_And_Remove_SubTree to remove a device. The /// DIF_PROPERTYCHANGE request can be used to enable, disable, restart, stop, or change the properties of a device. /// /// /// Callers of this function must have SeLoadDriverPrivilege. (Privileges are described in the Microsoft Windows SDK documentation.) /// /// For information about using device instance handles that are bound to the local machine, see CM_Get_Child. /// // 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); /// /// /// [Beginning with Windows 8 and Windows Server 2012, this function has been deprecated. Please use CM_Query_And_Remove_SubTree instead.] /// /// /// The CM_Query_And_Remove_SubTree_Ex function checks whether a device instance and its children can be removed and, if so, /// it removes them. /// /// /// /// 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. /// /// /// (Optional) If the caller does not pass NULL 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. /// /// /// (Optional) If the caller does not pass NULL 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. /// /// /// (Optional.) Caller-supplied value representing the length (number of characters) of the string buffer supplied by pszVetoName. /// This should be set to MAX_PATH. /// /// A bitwise OR of the caller-supplied flag constants that are described in the Remarks section. /// /// Caller-supplied machine handle to which the caller-supplied device instance handle is bound. /// /// Note Using this function to access remote machines is not supported beginning with Windows 8 and Windows Server 2012, as /// this functionality has been removed. /// /// /// /// If the operation succeeds, the function returns CR_SUCCESS. Otherwise, it returns one of the CR_-prefixed error codes defined in Cfgmgr32.h. /// /// /// /// The purpose of the CM_Query_And_Remove_SubTree_Ex 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 SurpriseRemovalOK /// member of DEVICE_CAPABILITIES. If a driver has set SurpriseRemovalOK, the application should call /// CM_Request_Device_Eject_Ex instead of CM_Query_And_Remove_SubTree_Ex. /// /// /// CM_Query_And_Remove_SubTree_Ex 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: /// /// /// Beginning with Windows XP, CM_Query_And_Remove_SubTree_Ex also supports setting the following additional flag; this flag /// applies only if the function successfully removes the device instance: /// /// /// Device installation applications that do not require the low-level operation of CM_Query_And_Remove_SubTree_Ex should use /// the DIF_PROPERTYCHANGE request to disable a device instead of using CM_Query_And_Remove_SubTree_Ex to remove a device. /// The DIF_PROPERTYCHANGE request can be used to enable, disable, restart, stop, or change the properties of a device. /// /// /// Callers of this function must have SeLoadDriverPrivilege. (Privileges are described in the Microsoft Windows SDK documentation.) /// /// For information about using device instance handles that are bound to a local or a remote machine, see CM_Get_Child_Ex. /// /// 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. /// /// // 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); /// /// /// [Beginning with Windows 8 and Windows Server 2012, this function has been deprecated. Please use CM_Query_And_Remove_SubTree instead.] /// /// /// The CM_Query_And_Remove_SubTree_Ex function checks whether a device instance and its children can be removed and, if so, /// it removes them. /// /// /// /// 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. /// /// /// (Optional) If the caller does not pass NULL 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. /// /// /// (Optional) If the caller does not pass NULL 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. /// /// /// (Optional.) Caller-supplied value representing the length (number of characters) of the string buffer supplied by pszVetoName. /// This should be set to MAX_PATH. /// /// A bitwise OR of the caller-supplied flag constants that are described in the Remarks section. /// /// Caller-supplied machine handle to which the caller-supplied device instance handle is bound. /// /// Note Using this function to access remote machines is not supported beginning with Windows 8 and Windows Server 2012, as /// this functionality has been removed. /// /// /// /// If the operation succeeds, the function returns CR_SUCCESS. Otherwise, it returns one of the CR_-prefixed error codes defined in Cfgmgr32.h. /// /// /// /// The purpose of the CM_Query_And_Remove_SubTree_Ex 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 SurpriseRemovalOK /// member of DEVICE_CAPABILITIES. If a driver has set SurpriseRemovalOK, the application should call /// CM_Request_Device_Eject_Ex instead of CM_Query_And_Remove_SubTree_Ex. /// /// /// CM_Query_And_Remove_SubTree_Ex 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: /// /// /// Beginning with Windows XP, CM_Query_And_Remove_SubTree_Ex also supports setting the following additional flag; this flag /// applies only if the function successfully removes the device instance: /// /// /// Device installation applications that do not require the low-level operation of CM_Query_And_Remove_SubTree_Ex should use /// the DIF_PROPERTYCHANGE request to disable a device instead of using CM_Query_And_Remove_SubTree_Ex to remove a device. /// The DIF_PROPERTYCHANGE request can be used to enable, disable, restart, stop, or change the properties of a device. /// /// /// Callers of this function must have SeLoadDriverPrivilege. (Privileges are described in the Microsoft Windows SDK documentation.) /// /// For information about using device instance handles that are bound to a local or a remote machine, see CM_Get_Child_Ex. /// /// 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. /// /// // 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); /// /// The CM_Query_Resource_Conflict_List function identifies device instances having resource requirements that conflict with /// a specified device instance's resource description. /// /// Caller-supplied address of a location to receive a handle to a conflict list. /// Caller-supplied device instance handle that is bound to the machine handle supplied by hMachine. /// /// Caller-supplied resource type identifier. This must be one of the ResType_-prefixed constants defined in Cfgmgr32.h. /// /// /// 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. /// /// Caller-supplied length of the structure pointed to by ResourceData. /// Not used, must be zero. /// Caller-supplied machine handle to which the caller-supplied device instance handle is bound. /// /// /// If the operation succeeds, the function returns CR_SUCCESS. Otherwise, it returns one of the CR_-prefixed error codes defined in Cfgmgr32.h. /// /// /// Note Starting with Windows 8, CM_Query_Resource_Conflict_List 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. /// /// /// /// /// When calling CM_Query_Resource_Conflict_List, 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. /// /// /// After calling CM_Query_Resource_Conflict_List, 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. /// /// After an application has finished using the handle received for pclConflictList, it must call CM_Free_Resource_Conflict_Handle. /// For information about using device instance handles that are bound to a local or a remote machine, see CM_Get_Child_Ex. /// // 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); /// /// The CM_Query_Resource_Conflict_List function identifies device instances having resource requirements that conflict with /// a specified device instance's resource description. /// /// The type of the supplied data. /// Caller-supplied device instance handle that is bound to the machine handle supplied by hMachine. /// /// 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. /// /// /// Caller-supplied resource type identifier. If 0, then the is determined by . /// /// /// A handle to a conflict list. /// /// Note Starting with Windows 8, CM_Query_Resource_Conflict_List 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. /// /// /// /// /// When calling CM_Query_Resource_Conflict_List, 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. /// /// /// After calling CM_Query_Resource_Conflict_List, 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. /// /// For information about using device instance handles that are bound to a local or a remote machine, see CM_Get_Child_Ex. /// [PInvokeData("cfgmgr32.h", MSDNShortId = "NF:cfgmgr32.CM_Query_Resource_Conflict_List")] public static SafeCONFLICT_LIST CM_Query_Resource_Conflict_List(uint dnDevInst, T data, RESOURCEID ResourceID = 0) where T : struct { if (ResourceID == 0 && !CorrespondingTypeAttribute.CanSet(out ResourceID)) throw new ArgumentException("Unable to determine RESOURCEID from type.", nameof(T)); using var mem = new SafeAnysizeStruct(data); CM_Query_Resource_Conflict_List(out var hcl, dnDevInst, ResourceID, mem, mem.Size).ThrowIfFailed(); return hcl; } /// /// The CM_Reenumerate_DevNode function enumerates the devices identified by a specified device node and all of its children. /// /// Caller-supplied device instance handle that is bound to the local machine. /// /// /// Caller-supplied flags that specify how reenumeration should occur. This parameter can be set to a combination of the following /// flags, as noted: /// /// CM_REENUMERATE_ASYNCHRONOUS /// /// 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. /// /// CM_REENUMERATE_NORMAL /// /// Specifies default reenumeration behavior, in which reenumeration occurs synchronously. This flag is functionally equivalent to CM_REENUMERATE_SYNCHRONOUS. /// /// CM_REENUMERATE_RETRY_INSTALLATION /// /// 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. /// /// /// 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. /// /// CM_REENUMERATE_SYNCHRONOUS /// /// 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. /// /// /// /// If the operation succeeds, the function returns CR_SUCCESS. Otherwise, it returns one of the CR_-prefixed error codes defined in Cfgmgr32.h. /// /// /// /// 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). /// /// /// Callers of this function must have SeLoadDriverPrivilege. (Privileges are described in the Microsoft Windows SDK documentation.) /// /// For information about using device instance handles that are bound to the local machine, see CM_Get_Child. /// // 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); /// /// /// [Beginning with Windows 8 and Windows Server 2012, this function has been deprecated. Please use CM_Reenumerate_DevNode instead.] /// /// /// The CM_Reenumerate_DevNode_Ex function enumerates the devices identified by a specified device node and all of its children. /// /// /// Caller-supplied device instance handle that is bound to the machine handle supplied by hMachine. /// /// /// Caller-supplied flags that specify how reenumeration should occur. This parameter can be set to a combination of the following /// flags, as noted: /// /// CM_REENUMERATE_ASYNCHRONOUS /// /// 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. /// /// CM_REENUMERATE_NORMAL /// /// Specifies default reenumeration behavior, in which reenumeration occurs synchronously. This flag is currently equivalent to CM_REENUMERATE_SYNCHRONOUS. /// /// CM_REENUMERATE_RETRY_INSTALLATION /// /// 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. /// /// /// 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. /// /// CM_REENUMERATE_SYNCHRONOUS /// /// 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. /// /// /// /// Caller-supplied machine handle to which the caller-supplied device instance handle is bound. /// /// Note Using this function to access remote machines is not supported beginning with Windows 8 and Windows Server 2012, as /// this functionality has been removed. /// /// /// /// If the operation succeeds, the function returns CR_SUCCESS. Otherwise, it returns one of the CR_-prefixed error codes defined in Cfgmgr32.h. /// /// /// /// 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). /// /// /// Callers of this function must have SeLoadDriverPrivilege. (Privileges are described in the Microsoft Windows SDK documentation.) /// /// For information about using device instance handles that are bound to a local or a remote machine, see CM_Get_Child_Ex. /// /// 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. /// /// // 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); /// /// /// Use RegisterDeviceNotification instead of CM_Register_Notification if your code targets Windows 7 or earlier versions of /// Windows. Kernel mode callers should use IoRegisterPlugPlayNotification instead. /// /// /// The CM_Register_Notification function registers an application callback routine to be called when a PnP event of the /// specified type occurs. /// /// /// Pointer to a CM_NOTIFY_FILTER structure. /// /// Pointer to a caller-allocated buffer containing the context to be passed to the callback routine in pCallback. /// /// /// /// Pointer to the routine to be called when the specified PnP event occurs. See the Remarks section for the callback /// function's prototype. /// /// The callback routine’s Action parameter will be a value from the CM_NOTIFY_ACTION enumeration. /// /// Upon receiving a notification, how the callback examines the notification will depend on the FilterType member of the /// callback routine's EventData parameter: /// /// CM_NOTIFY_FILTER_TYPE_DEVICEINTERFACE /// The callback should examine EventData->u.DeviceInterface. /// CM_NOTIFY_FILTER_TYPE_DEVICEHANDLE /// The callback should examine EventData->u.DeviceHandle. /// CM_NOTIFY_FILTER_TYPE_DEVICEINSTANCE /// The callback should examine EventData->u.DeviceInstance. /// /// Pointer to receive the HCMNOTIFICATION handle that corresponds to the registration call. /// /// If the operation succeeds, the function returns CR_SUCCESS. Otherwise, it returns one of the CR_-prefixed error codes defined in Cfgmgr32.h. /// /// /// /// 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. /// /// /// The CM_Register_Notification function does not provide notification of existing device interfaces. To retrieve existing /// interfaces, first call CM_Register_Notification, and then call CM_Get_Device_Interface_List. If the interface is enabled /// after your driver calls CM_Register_Notification, but before your driver calls CM_Get_Device_Interface_List, the /// driver receives a notification for the interface arrival, and the interface also appears in the list of device interface /// instances returned by CM_Get_Device_Interface_List. /// /// /// HCMNOTIFICATION handles returned by CM_Register_Notification must be closed by calling the CM_Unregister_Notification /// function when they are no longer needed. /// /// A callback routine uses the following function prototype: /// /// 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 ); /// /// /// If responding to a CM_NOTIFY_ACTION_DEVICEQUERYREMOVE 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. /// /// Examples /// For an example, see Registering for Notification of Device Interface Arrival and Device Removal. /// // 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, CM_NOTIFY_CALLBACK pCallback, out SafeHCMNOTIFICATION pNotifyContext); /// /// The CM_Request_Device_Eject function prepares a local device instance for safe removal, if the device is removable. If /// the device can be physically ejected, it will be. /// /// Caller-supplied device instance handle that is bound to the local machine. /// /// (Optional.) If not NULL, this points to a location that, if the removal request fails, receives a PNP_VETO_TYPE-typed /// value indicating the reason for the failure. /// /// /// (Optional.) If not NULL, 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. /// /// /// (Optional.) Caller-supplied value representing the length of the string buffer supplied by pszVetoName. This should be set to MAX_PATH. /// /// Not used. /// /// If the operation succeeds, the function returns CR_SUCCESS. Otherwise, it returns one of the CR_-prefixed error codes defined in Cfgmgr32.h. /// /// /// /// If pszVetoName is NULL, 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 NULL, 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 /// NULL, if the device's CM_DEVCAP_DOCKDEVICE capability is set.) /// /// /// Callers of CM_Request_Device_Eject sometimes require SeUndockPrivilege or SeLoadDriverPrivilege, as follows: /// /// /// /// /// If the device's CM_DEVCAP_DOCKDEVICE capability is set (the device is a "dock" device), callers must have /// SeUndockPrivilege. ( SeLoadDriverPrivilege is not required.) /// /// /// /// /// 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 SeLoadDriverPrivilege. /// /// /// /// Privileges are described in the Microsoft Windows SDK documentation. /// For information about using device instance handles that are bound to the local machine, see CM_Get_Child. /// // 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); /// /// The CM_Request_Device_Eject function prepares a local device instance for safe removal, if the device is removable. If /// the device can be physically ejected, it will be. /// /// Caller-supplied device instance handle that is bound to the local machine. /// /// (Optional.) If not NULL, this points to a location that, if the removal request fails, receives a PNP_VETO_TYPE-typed /// value indicating the reason for the failure. /// /// /// (Optional.) If not NULL, 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. /// /// /// (Optional.) Caller-supplied value representing the length of the string buffer supplied by pszVetoName. This should be set to MAX_PATH. /// /// Not used. /// /// If the operation succeeds, the function returns CR_SUCCESS. Otherwise, it returns one of the CR_-prefixed error codes defined in Cfgmgr32.h. /// /// /// /// If pszVetoName is NULL, 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 NULL, 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 /// NULL, if the device's CM_DEVCAP_DOCKDEVICE capability is set.) /// /// /// Callers of CM_Request_Device_Eject sometimes require SeUndockPrivilege or SeLoadDriverPrivilege, as follows: /// /// /// /// /// If the device's CM_DEVCAP_DOCKDEVICE capability is set (the device is a "dock" device), callers must have /// SeUndockPrivilege. ( SeLoadDriverPrivilege is not required.) /// /// /// /// /// 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 SeLoadDriverPrivilege. /// /// /// /// Privileges are described in the Microsoft Windows SDK documentation. /// For information about using device instance handles that are bound to the local machine, see CM_Get_Child. /// // 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); /// /// /// [Beginning with Windows 8 and Windows Server 2012, this function has been deprecated. Please use CM_Request_Device_Eject instead.] /// /// /// The CM_Request_Device_Eject_Ex 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. /// /// /// Caller-supplied device instance handle that is bound to the machine handle supplied by hMachine. /// /// (Optional.) If not NULL, this points to a location that, if the removal request fails, receives a PNP_VETO_TYPE-typed /// value indicating the reason for the failure. /// /// /// (Optional.) If not NULL, 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. /// /// /// (Optional.) Caller-supplied value representing the length of the string buffer supplied by pszVetoName. This should be set to MAX_PATH. /// /// Not used. /// /// Caller-supplied machine handle to which the caller-supplied device instance handle is bound. /// /// Note Using this function to access remote machines is not supported beginning with Windows 8 and Windows Server 2012, as /// this functionality has been removed. /// /// /// /// If the operation succeeds, the function returns CR_SUCCESS. Otherwise, it returns one of the CR_-prefixed error codes defined in Cfgmgr32.h. /// /// /// /// If pszVetoName is NULL, 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 NULL, 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 /// NULL, if the device's CM_DEVCAP_DOCKDEVICE capability is set.) /// /// /// 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 SeUndockPrivilege. /// /// Callers of CM_Request_Eject_Ex sometimes require SeUndockPrivilege or SeLoadDriverPrivilege, as follows: /// /// /// /// If the device's CM_DEVCAP_DOCKDEVICE capability is set (the device is a "dock" device), callers must have /// SeUndockPrivilege. ( SeLoadDriverPrivilege is not required.) /// /// /// /// /// 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 SeLoadDriverPrivilege. /// /// /// /// (Privileges are described in the Microsoft Windows SDK documentation.) /// For information about using device instance handles that are bound to a local or a remote machine, see CM_Get_Child_Ex. /// /// 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. /// /// // 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); /// /// /// [Beginning with Windows 8 and Windows Server 2012, this function has been deprecated. Please use CM_Request_Device_Eject instead.] /// /// /// The CM_Request_Device_Eject_Ex 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. /// /// /// Caller-supplied device instance handle that is bound to the machine handle supplied by hMachine. /// /// (Optional.) If not NULL, this points to a location that, if the removal request fails, receives a PNP_VETO_TYPE-typed /// value indicating the reason for the failure. /// /// /// (Optional.) If not NULL, 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. /// /// /// (Optional.) Caller-supplied value representing the length of the string buffer supplied by pszVetoName. This should be set to MAX_PATH. /// /// Not used. /// /// Caller-supplied machine handle to which the caller-supplied device instance handle is bound. /// /// Note Using this function to access remote machines is not supported beginning with Windows 8 and Windows Server 2012, as /// this functionality has been removed. /// /// /// /// If the operation succeeds, the function returns CR_SUCCESS. Otherwise, it returns one of the CR_-prefixed error codes defined in Cfgmgr32.h. /// /// /// /// If pszVetoName is NULL, 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 NULL, 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 /// NULL, if the device's CM_DEVCAP_DOCKDEVICE capability is set.) /// /// /// 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 SeUndockPrivilege. /// /// Callers of CM_Request_Eject_Ex sometimes require SeUndockPrivilege or SeLoadDriverPrivilege, as follows: /// /// /// /// If the device's CM_DEVCAP_DOCKDEVICE capability is set (the device is a "dock" device), callers must have /// SeUndockPrivilege. ( SeLoadDriverPrivilege is not required.) /// /// /// /// /// 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 SeLoadDriverPrivilege. /// /// /// /// (Privileges are described in the Microsoft Windows SDK documentation.) /// For information about using device instance handles that are bound to a local or a remote machine, see CM_Get_Child_Ex. /// /// 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. /// /// // 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); /// /// The CM_Request_Eject_PC function requests that a portable PC, which is inserted in a local docking station, be ejected. /// /// /// 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. /// /// /// /// 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: /// /// /// /// /// CM_Is_Dock_Station_Present identifies whether a docking station is present in a local machine. /// /// /// /// /// CM_Is_Dock_Station_Present_Ex identifies whether a docking station is present in a local or a remote machine. /// /// /// /// /// CM_Request_Eject_PC_Ex requests that a portable PC, which is inserted in a local or a remote docking station, be ejected. /// /// /// /// // 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(); /// /// [Beginning with Windows 8 and Windows Server 2012, this function has been deprecated. Please use CM_Request_Eject_PC instead.] /// /// The CM_Request_Eject_PC_Ex function requests that a portable PC, which is inserted in a local or a remote docking /// station, be ejected. /// /// /// /// Supplies a machine handle that is returned by CM_Connect_Machine. /// /// Note Using this function to access remote machines is not supported beginning with Windows 8 and Windows Server 2012, as /// this functionality has been removed. /// /// /// /// 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. /// /// /// /// 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: /// /// /// /// /// CM_Is_Dock_Station_Present identifies whether a docking station is present in a local machine. /// /// /// /// /// CM_Is_Dock_Station_Present_Ex identifies whether a docking station is present in a local or a remote machine. /// /// /// /// /// CM_Request_Eject_PC requests that a portable PC, which is inserted in a local docking station, be ejected. /// /// /// /// /// 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. /// /// // 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); /// The CM_Set_Class_Property function sets a class property for a device setup class or a device interface class. /// /// 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. /// /// /// Pointer to a DEVPROPKEY structure that represents the property key of the device class property to set. /// /// /// 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. /// /// /// 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. /// /// /// The size, in bytes, of the PropertyBuffer buffer. If PropertyBuffer is set to NULL, PropertyBufferSize must be set to zero. /// /// /// Class property flags: /// CM_CLASS_PROPERTY_INSTALLER /// ClassGUID specifies a device setup class. Do not combine with CM_CLASS_PROPERTY_INTERFACE. /// CM_CLASS_PROPERTY_INTERFACE /// ClassGUID specifies a device interface class. Do not combine with CM_CLASS_PROPERTY_INSTALLER. /// /// /// If the operation succeeds, the function returns CR_SUCCESS. Otherwise, it returns one of the CR_-prefixed error codes defined in Cfgmgr32.h. /// /// CM_Set_Class_Property is part of the Unified Device Property Model. // 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); /// /// /// [Beginning with Windows 8 and Windows Server 2012, this function has been deprecated. Please use CM_Set_Class_Property instead.] /// /// The CM_Set_Class_Property_ExW function sets a class property for a device setup class or a device interface class. /// /// /// 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. /// /// /// Pointer to a DEVPROPKEY structure that represents the property key of the device class property to set. /// /// /// 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. /// /// /// 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. /// /// /// The size, in bytes, of the PropertyBuffer buffer. If PropertyBuffer is set to NULL, PropertyBufferSize must be set to zero. /// /// /// Class property flags: /// CM_CLASS_PROPERTY_INSTALLER /// ClassGUID specifies a device setup class. Do not combine with CM_CLASS_PROPERTY_INTERFACE. /// CM_CLASS_PROPERTY_INTERFACE /// ClassGUID specifies a device interface class. Do not combine with CM_CLASS_PROPERTY_INSTALLER. /// /// /// Caller-supplied machine handle, obtained from a previous call to CM_Connect_Machine. /// /// Note Using this function to access remote machines is not supported beginning with Windows 8 and Windows Server 2012, as /// this functionality has been removed. /// /// /// /// If the operation succeeds, the function returns CR_SUCCESS. Otherwise, it returns one of the CR_-prefixed error codes defined in Cfgmgr32.h. /// /// CM_Set_Class_Property_ExW is part of the Unified Device Property Model. // 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); /// The CM_Set_Class_Registry_Property function sets or deletes a property of a device setup class. /// A pointer to the GUID that represents the device setup class for which to set a property. /// /// 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. /// /// /// A pointer to a buffer that contains the property data. This parameter is optional and can be set to NULL. For more /// information about setting this parameter and the corresponding ulLength parameter, see the following Remarks section. /// /// A value of type ULONG that specifies the size, in bytes, of the property data. /// Reserved for internal use only. Must be set to zero. /// /// A handle to a remote machine on which to set the specified device setup class property. This parameter is optional. If set to /// NULL, the property is set on the local machine. /// /// /// If the operation succeeds, CM_Set_Class_Registry_Property returns CR_SUCCESS. Otherwise, the function returns one of the /// other CR_Xxx status codes that are defined in Cfgmgr32.h. /// /// /// If Buffer is NULL, ulLength must be set to zero. /// If ulLength is set to zero, the function deletes the property. /// /// If Buffer is not set to NULL 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. /// /// // 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); /// The CM_Set_Device_Interface_Property function sets a device property of a device interface. /// /// Pointer to a string that identifies the device interface instance for which to set a property for. /// /// /// Pointer to a DEVPROPKEY structure that represents the property key of the device interface property to set. /// /// /// 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. /// /// /// 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. /// /// /// The size, in bytes, of the PropertyBuffer buffer. If PropertyBuffer is set to NULL, PropertyBufferSize must be set to zero. /// /// Reserved. Must be set to zero. /// /// If the operation succeeds, the function returns CR_SUCCESS. Otherwise, it returns one of the CR_-prefixed error codes defined in Cfgmgr32.h. /// /// CM_Set_Device_Interface_Property is part of the Unified Device Property Model. // 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); /// /// /// [Beginning with Windows 8 and Windows Server 2012, this function has been deprecated. Please use /// CM_Set_Device_Interface_Property instead.] /// /// The CM_Set_Device_Interface_Property_ExW function sets a device property of a device interface. /// /// /// Pointer to a string that identifies the device interface instance for which to set a property for. /// /// /// Pointer to a DEVPROPKEY structure that represents the property key of the device interface property to set. /// /// /// 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. /// /// /// 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. /// /// /// The size, in bytes, of the PropertyBuffer buffer. If PropertyBuffer is set to NULL, PropertyBufferSize must be set to zero. /// /// Reserved. Must be set to zero. /// /// Caller-supplied machine handle, obtained from a previous call to CM_Connect_Machine. /// /// Note Using this function to access remote machines is not supported beginning with Windows 8 and Windows Server 2012, as /// this functionality has been removed. /// /// /// /// If the operation succeeds, the function returns CR_SUCCESS. Otherwise, it returns one of the CR_-prefixed error codes defined in Cfgmgr32.h. /// /// CM_Set_Device_Interface_Property_ExW is part of the Unified Device Property Model. // 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); /// The CM_Set_DevNode_Problem function sets a problem code for a device that is installed in a local machine. /// Caller-supplied device instance handle that is bound to the local machine. /// /// 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. /// /// Must be set to zero. /// /// 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. /// /// /// /// 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: /// /// /// /// /// CM_Get_DevNode_Status returns the problem code set for a device installed in a local machine. /// /// /// /// /// CM_Get_DevNode_Status_Ex returns the problem code set for a device installed in a local or a remote machine. /// /// /// /// /// CM_Set_DevNode_Problem_Ex sets a problem code for a device installed in a local or a remote machine. /// /// /// /// For information about using device instance handles that are bound to the local machine, see CM_Get_Child. /// // 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); /// /// /// [Beginning with Windows 8 and Windows Server 2012, this function has been deprecated. Please use CM_Set_DevNode_Problem instead.] /// /// /// The CM_Set_DevNode_Problem_Ex function sets a problem code for a device that is installed in a local or a remote machine. /// /// /// Caller-supplied device instance handle that is bound to the machine handle supplied by hMachine. /// /// 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. /// /// Must be set to zero. /// /// Caller-supplied machine handle to which the caller-supplied device instance handle is bound. /// /// Note Using this function to access remote machines is not supported beginning with Windows 8 and Windows Server 2012, as /// this functionality has been removed. /// /// /// /// 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. /// /// /// /// 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: /// /// /// /// /// CM_Get_DevNode_Status returns the problem code set for a device installed in a local machine. /// /// /// /// /// CM_Get_DevNode_Status_Ex returns the problem code set for a device installed in a local or a remote machine. /// /// /// /// /// CM_Set_DevNode_Problem sets a problem code for a device installed in a local machine. /// /// /// /// For information about using device instance handles that are bound to a local or a remote machine, see CM_Get_Child_Ex. /// /// 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. /// /// // 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); /// The CM_Set_DevNode_Property function sets a device instance property. /// Device instance handle that is bound to the local machine. /// /// Pointer to a DEVPROPKEY structure that represents the property key of the device instance property to set. /// /// /// 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. /// /// /// 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. /// /// /// The size, in bytes, of the PropertyBuffer buffer. If PropertyBuffer is set to NULL, PropertyBufferSize must be set to zero. /// /// Reserved. Must be set to zero. /// /// If the operation succeeds, the function returns CR_SUCCESS. Otherwise, it returns one of the CR_-prefixed error codes defined in Cfgmgr32.h. /// /// CM_Set_DevNode_Property is part of the Unified Device Property Model. // 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); /// /// /// [Beginning with Windows 8 and Windows Server 2012, this function has been deprecated. Please use CM_Set_DevNode_Property instead.] /// /// The CM_Set_DevNode_Property_ExW function sets a device instance property. /// /// Device instance handle that is bound to the local machine. /// /// Pointer to a DEVPROPKEY structure that represents the property key of the device instance property to set. /// /// /// 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. /// /// /// 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. /// /// /// The size, in bytes, of the PropertyBuffer buffer. If PropertyBuffer is set to NULL, PropertyBufferSize must be set to zero. /// /// Reserved. Must be set to zero. /// /// Caller-supplied machine handle, obtained from a previous call to CM_Connect_Machine. /// /// Note Using this function to access remote machines is not supported beginning with Windows 8 and Windows Server 2012, as /// this functionality has been removed. /// /// /// /// If the operation succeeds, the function returns CR_SUCCESS. Otherwise, it returns one of the CR_-prefixed error codes defined in Cfgmgr32.h. /// /// CM_Set_DevNode_Property_ExW is part of the Unified Device Property Model. // 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); /// The CM_Set_DevNode_Registry_Property function sets a specified device property in the registry. /// A caller-supplied device instance handle that is bound to the local machine. /// /// A CM_DRP_-prefixed constant value that identifies the device property to be set in the registry. These constants are defined in Cfgmgr32.h. /// /// /// A pointer to a caller-supplied buffer that supplies the requested device property, formatted appropriately for the property's /// data type. /// /// The length, in bytes, of the supplied device property. /// Not used, must be zero. /// /// 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. /// /// For information about how to use device instance handles that are bound to the local machine, see CM_Get_Child. // 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); /// /// The CM_Setup_DevNode function restarts a device instance that is not running because there is a problem with the device configuration. /// /// A device instance handle that is bound to the local system. /// /// One of the following flag values: /// CM_SETUP_DEVNODE_READY /// Restarts a device instance that is not running because of a problem with the device configuration. /// CM_SETUP_DEVNODE_RESET (Windows XP and later versions of Windows) /// /// 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 CM_Query_And_Remove_SubTree or CM_Query_And_Remove_SubTree_Ex and specifying the /// CM_REMOVE_NO_RESTART flag. /// /// /// /// 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. /// /// /// /// 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. /// /// /// If a device instance does not have a problem and is already started, CM_Setup_DevNode returns without changing the status /// of the device instance. /// /// Call CM_Get_DevNode_Status or CM_Get_DevNode_Status_Ex to determine the status and problem code for a device instance. /// // 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); /// The CM_Uninstall_DevNode function removes all persistent state associated with a device instance. /// Device instance handle that is bound to the local machine. /// Reserved. Must be set to zero. /// /// If the operation succeeds, the function returns CR_SUCCESS. Otherwise, it returns one of the CR_-prefixed error codes defined in Cfgmgr32.h. /// /// /// /// This function uninstalls the device without sending an IRP_MN_QUERY_REMOVE_DEVICE request or calling class installers or /// co-installers. If your application will run only on a Target Platform of Desktop, instead of calling /// CM_Uninstall_DevNode, the application should uninstall the device by calling SetupDiCallClassInstaller with the /// DIF_REMOVE code, or by calling DiUninstallDevice. /// /// Use the following sequence to call this function: /// /// /// Check if CM_Get_DevNode_Status returns success. This means that the device is present. /// /// /// If the device is present, call CM_Query_And_Remove_SubTree. /// /// /// Call CM_Uninstall_DevNode. /// /// /// // 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); /// /// /// Use UnregisterDeviceNotification instead of CM_Unregister_Notification if your code targets Windows 7 or earlier versions /// of Windows. /// /// The CM_Unregister_Notification function closes the specified HCMNOTIFICATION handle. /// /// The HCMNOTIFICATION handle returned by the CM_Register_Notification function. /// /// If the operation succeeds, the function returns CR_SUCCESS. Otherwise, it returns one of the CR_-prefixed error codes defined in Cfgmgr32.h. /// /// /// /// Do not call CM_Unregister_Notification from a notification callback. Doing so may cause a deadlock because /// CM_Unregister_Notification waits for pending callbacks to finish. /// /// /// Instead, if you want to unregister from the notification callback, you must do so asynchronously. The following sequence shows /// one way to do this: /// /// /// /// /// Allocate a context structure to use with your notifications. Include a pointer to a threadpool work structure ( PTP_WORK) /// and any other information you would like to pass to the notification callback. /// /// /// /// /// Call CreateThreadpoolWork. Provide a callback function that calls CM_Unregister_Notification. Add the returned work /// structure to the previously allocated context structure. /// /// /// /// Call CM_Register_Notification and provide the context structure as the pContext parameter. /// /// /// Do work, get notifications, etc. /// /// /// /// Call SubmitThreadpoolWork from within the notification callback, providing the pointer to a threadpool work structure ( /// PTP_WORK) stored in your context structure. /// /// /// /// When the threadpool thread runs, the work item calls CM_Unregister_Notification. /// /// /// Call CloseThreadpoolWork to release the work object. /// /// /// If you are finished with the context structure, don't forget to release resources and and free the structure. /// /// Caution Do not free the context structure until after the work item has called CM_Unregister_Notification. You can /// still receive notifications after submitting the threadpool work item and before the work item calls CM_Unregister_Notification. /// /// Examples /// The following example shows how to unregister from the notification callback, as described in the Remarks section. /// /// 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(&(pCallbackContext->lock)); // in case this callback fires before the registration call returns, make sure the notification handle is properly set Context->hNotify = hNotification; if (!pCallbackContext->bUnregister) { pCallbackContext->bUnregister = TRUE; SubmitThreadpoolWork(pCallbackContext->pWork); } LeaveCriticalSection(&(pCallbackContext->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->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(&(context->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->pWork = CreateThreadpoolWork(WorkCallback, context, NULL); if (context->pWork == NULL) { goto end; } cr = CM_Register_Notification(&NotifyFilter, context, EventCallback, &context->hNotify); if (cr != CR_SUCCESS) { goto end; } // ... do work here ... EnterCriticalSection(&(context->lock)); if (!context->bUnregister) { // unregister not from the callback bShouldUnregister = TRUE; context->bUnregister = TRUE; } LeaveCriticalSection(&(context->lock)); if (bShouldUnregister) { cr = CM_Unregister_Notification(context->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->pWork, FALSE); } end: if (context != NULL) { if (context->pWork != NULL) { CloseThreadpoolWork(context->pWork); } DeleteCriticalSection(&(context->lock)); HeapFree(GetProcessHeap(), 0, context); } return; } /// /// // 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); /// /// The CMP_WaitNoPendingInstallEvents (CM_WaitNoPendingInstallEvents) function waits until there are no pending device /// installation activities for the PnP manager to perform. /// /// /// Specifies a time-out interval, in milliseconds. /// /// /// If dwTimeout is set to zero, the function tests whether there are pending installation events and returns immediately. /// /// /// If dwTimeout is set to INFINITE (defined in Winbase.h), the function's time-out interval never elapses. /// /// /// /// For all other dwTimeout values, the function returns when the specified interval elapses, even if there are still pending /// installation events. /// /// /// /// /// /// The function returns one of the following values (defined in Winbase.h): /// /// /// Return code /// Description /// /// /// WAIT_OBJECT_0 /// There are no pending installation activities. /// /// /// WAIT_TIMEOUT /// The time-out interval elapsed, and installation activities are still pending. /// /// /// WAIT_FAILED /// The function failed. Call GetLastError for additional error information. /// /// /// /// /// /// The function waits for an internal event object, which the PnP manager sets when it determines that no installation activities /// are pending. /// /// /// If a non-zero time-out value is specified, then CMP_WaitNoPendingInstallEvents will return either when no installation /// events are pending or when the time-out period has expired, whichever comes first. /// /// /// 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. /// /// /// This function is typically used by device installation applications. For more information, see Writing a Device Installation Application. /// /// /// 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 ServiceMain callback function) or while /// processing any control in the service handler (for example, the Handler callback function), or from installation /// components such as class-installers or co-installers. /// /// /// 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. /// /// // 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); /// Gets the .NET exception for a value. /// The value to check. /// The message. /// An exception instance or if value indicated success. 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); } /// Throws an exception if value is not . /// The value to check. /// The message. public static void ThrowIfFailed(this CONFIGRET cr, string? message = null) { if (cr != CONFIGRET.CR_SUCCESS) throw cr.GetException(message)!; } /// Converts a specified CONFIGRET code to its equivalent system error code. /// The CONFIGRET code to be converted. /// /// A default system error code to be returned when no system error code is mapped to the specified CONFIGRET code. /// /// /// The system error code that corresponds to the CONFIGRET code. /// /// When there is no mapping from the specified CONFIGRET code to a system error code, CM_MapCrToWin32Err returns the /// value specified in . /// /// public static Win32Error ToError(this CONFIGRET cr, Win32Error defaultErr) => CM_MapCrToWin32Err(cr, (uint)defaultErr); }