From 8b02aed5c5643df5e02f99b7f461d13408d1d650 Mon Sep 17 00:00:00 2001 From: David Hall Date: Sun, 24 Feb 2019 18:39:30 -0700 Subject: [PATCH] Added device broadcast message supporting functions and structures --- PInvoke/User32.Gdi/WinUser.Dbt.cs | 742 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 742 insertions(+) create mode 100644 PInvoke/User32.Gdi/WinUser.Dbt.cs diff --git a/PInvoke/User32.Gdi/WinUser.Dbt.cs b/PInvoke/User32.Gdi/WinUser.Dbt.cs new file mode 100644 index 00000000..dcda7dd4 --- /dev/null +++ b/PInvoke/User32.Gdi/WinUser.Dbt.cs @@ -0,0 +1,742 @@ +using System; +using System.Runtime.InteropServices; +using Vanara.InteropServices; + +namespace Vanara.PInvoke +{ + public static partial class User32_Gdi + { + public const uint WM_DEVICECHANGE = 0x0219; + + /// The device type, which determines the event-specific information that follows the first three members. + [PInvokeData("dbt.h", MSDNShortId = "4fc81fcb-b9fe-4016-b639-a43845af2c5f")] + public enum DBT_DEVTYPE : uint + { + /// OEM- or IHV-defined device type. This structure is a DEV_BROADCAST_OEM structure. + [CorrespondingType(typeof(DEV_BROADCAST_OEM))] + DBT_DEVTYP_OEM = 0, + + /// devnode number + [CorrespondingType(typeof(DEV_BROADCAST_DEVNODE))] + DBT_DEVTYP_DEVNODE = 1, + + /// Logical volume. This structure is a DEV_BROADCAST_VOLUME structure. + [CorrespondingType(typeof(DEV_BROADCAST_VOLUME))] + DBT_DEVTYP_VOLUME = 2, + + /// Port device (serial or parallel). This structure is a DEV_BROADCAST_PORT structure. + [CorrespondingType(typeof(DEV_BROADCAST_PORT))] + DBT_DEVTYP_PORT = 3, + + /// network resource + [CorrespondingType(typeof(DEV_BROADCAST_NET))] + DBT_DEVTYP_NET = 4, + + /// Class of devices. This structure is a DEV_BROADCAST_DEVICEINTERFACE structure. + [CorrespondingType(typeof(DEV_BROADCAST_DEVICEINTERFACE))] + DBT_DEVTYP_DEVICEINTERFACE = 5, + + /// File system handle. This structure is a DEV_BROADCAST_HANDLE structure. + [CorrespondingType(typeof(DEV_BROADCAST_HANDLE))] + DBT_DEVTYP_HANDLE = 6, + } + + /// Flags for DEV_BROADCAST_VOLUME. + [PInvokeData("dbt.h", MSDNShortId = "8ce644d9-1e95-458e-924f-67bd37831048")] + public enum DBTF : uint + { + /// Change affects media in drive. If not set, change affects physical device or drive. + DBTF_MEDIA = 0x0001, + + /// Indicated logical volume is a network volume. + DBTF_NET = 0x0002, + } + + /// Flags for . + [PInvokeData("winuser.h", MSDNShortId = "82094d95-9af3-4222-9c5e-ce2df9bab5e3")] + public enum DEVICE_NOTIFY + { + /// The hRecipient parameter is a window handle. + DEVICE_NOTIFY_WINDOW_HANDLE = 0x00000000, + + /// The hRecipient parameter is a service status handle. + DEVICE_NOTIFY_SERVICE_HANDLE = 0x00000001, + + /// + /// Notifies the recipient of device interface events for all device interface classes. (The dbcc_classguid member is ignored.) + /// This value can be used only if the dbch_devicetype member is DBT_DEVTYP_DEVICEINTERFACE. + /// + DEVICE_NOTIFY_ALL_INTERFACE_CLASSES = 0x00000004, + } + + /// Possible WPARAM values for WM_DEVICECHANGE messages. + [PInvokeData("dbt.h")] + public enum DeviceBroadcastEvent + { + /// 'Appy-time is now available. + DBT_APPYBEGIN = 0x0000, + + /// 'Appy-time is no longer available. + DBT_APPYEND = 0x0001, + + /// + /// The system broadcasts the DBT_DEVNODES_CHANGED device event when a device has been added to or removed from the system. + /// Applications that maintain lists of devices in the system should refresh their lists. + /// + DBT_DEVNODES_CHANGED = 0x0007, + + /// + /// The system broadcasts the DBT_QUERYCHANGECONFIG device event to request permission to change the current configuration (dock + /// or undock). Any application can deny this request and cancel the change. + /// + DBT_QUERYCHANGECONFIG = 0x0017, + + /// + /// The system broadcasts the DBT_CONFIGCHANGED device event to indicate that the current configuration has changed, due to a + /// dock or undock. An application or driver that stores data in the registry under the HKEY_CURRENT_CONFIG key should update the data. + /// + DBT_CONFIGCHANGED = 0x0018, + + /// + /// The system broadcasts the DBT_CONFIGCHANGECANCELED device event when a request to change the current configuration (dock or + /// undock) has been canceled. + /// + DBT_CONFIGCHANGECANCELED = 0x0019, + + /// + /// This message is sent when the display monitor has changed and the system should change the display mode to match it. + /// + DBT_MONITORCHANGE = 0x001B, + + /// The shell has finished login on: VxD can now do Shell_EXEC. + DBT_SHELLLOGGEDON = 0x0020, + + /// CONFIGMG ring 3 call. + DBT_CONFIGMGAPI32 = 0x0022, + + /// CONFIGMG ring 3 call. + DBT_VXDINITCOMPLETE = 0x0023, + + /// + /// Messages issued by IFSMGR for volume locking purposes on WM_DEVICECHANGE. All these messages pass a pointer to a struct which + /// has no pointers. + /// + DBT_VOLLOCKQUERYLOCK = 0x8041, + + /// + /// Messages issued by IFSMGR for volume locking purposes on WM_DEVICECHANGE. All these messages pass a pointer to a struct which + /// has no pointers. + /// + DBT_VOLLOCKLOCKTAKEN = 0x8042, + + /// + /// Messages issued by IFSMGR for volume locking purposes on WM_DEVICECHANGE. All these messages pass a pointer to a struct which + /// has no pointers. + /// + DBT_VOLLOCKLOCKFAILED = 0x8043, + + /// + /// Messages issued by IFSMGR for volume locking purposes on WM_DEVICECHANGE. All these messages pass a pointer to a struct which + /// has no pointers. + /// + DBT_VOLLOCKQUERYUNLOCK = 0x8044, + + /// + /// Messages issued by IFSMGR for volume locking purposes on WM_DEVICECHANGE. All these messages pass a pointer to a struct which + /// has no pointers. + /// + DBT_VOLLOCKLOCKRELEASED = 0x8045, + + /// + /// Messages issued by IFSMGR for volume locking purposes on WM_DEVICECHANGE. All these messages pass a pointer to a struct which + /// has no pointers. + /// + DBT_VOLLOCKUNLOCKFAILED = 0x8046, + + /// Message issued by IFS manager when it detects that a drive is run out of free space. + DBT_NO_DISK_SPACE = 0x0047, + + /// + /// Message issued by VFAT when it detects that a drive it has mounted has the remaining free space below a threshold specified + /// by the registry or by a disk space management application. The broadcast is issued by VFAT ONLY when space is either + /// allocated or freed by VFAT. + /// + DBT_LOW_DISK_SPACE = 0x0048, + + /// Undocumented. + DBT_CONFIGMGPRIVATE = 0x7FFF, + + /// + /// The system broadcasts the DBT_DEVICEARRIVAL device event when a device or piece of media has been inserted and becomes available. + /// + DBT_DEVICEARRIVAL = 0x8000, + + /// + /// The system broadcasts the DBT_DEVICEQUERYREMOVE device event to request permission to remove a device or piece of media. This + /// message is the last chance for applications and drivers to prepare for this removal. However, any application can deny this + /// request and cancel the operation. + /// + DBT_DEVICEQUERYREMOVE = 0x8001, + + /// + /// The system broadcasts the DBT_DEVICEQUERYREMOVEFAILED device event when a request to remove a device or piece of media has + /// been canceled. + /// + DBT_DEVICEQUERYREMOVEFAILED = 0x8002, + + /// + /// The system broadcasts the DBT_DEVICEREMOVEPENDING device event when a device or piece of media is being removed and is no + /// longer available for use. + /// + DBT_DEVICEREMOVEPENDING = 0x8003, + + /// + /// The system broadcasts the DBT_DEVICEREMOVECOMPLETE device event when a device or piece of media has been physically removed. + /// + DBT_DEVICEREMOVECOMPLETE = 0x8004, + + /// The system broadcasts the DBT_DEVICETYPESPECIFIC device event when a device-specific event occurs. + DBT_DEVICETYPESPECIFIC = 0x8005, + + /// The system sends the DBT_CUSTOMEVENT device event when a driver-defined custom event has occurred. + DBT_CUSTOMEVENT = 0x8006, + + /// VPOWERD API for Win95 + DBT_VPOWERDAPI = 0x8100, + + /// The DBT_USERDEFINED device event identifies a user-defined event. + DBT_USERDEFINED = 0xFFFF, + } + + /// Undocumented. + [PInvokeData("dbt.h")] + public enum LOCKF : byte + { + /// Undocumented. + LOCKF_LOGICAL_LOCK = 0x00, + + /// Undocumented. + LOCKF_PHYSICAL_LOCK = 0x01, + } + + /// Undocumented. + [PInvokeData("dbt.h")] + public enum LOCKP : byte + { + /// Undocumented. + LOCKP_ALLOW_WRITES = 0x01, + + /// Undocumented. + LOCKP_FAIL_WRITES = 0x00, + + /// Undocumented. + LOCKP_FAIL_MEM_MAPPING = 0x02, + + /// Undocumented. + LOCKP_ALLOW_MEM_MAPPING = 0x00, + + /// Undocumented. + LOCKP_USER_MASK = 0x03, + + /// Undocumented. + LOCKP_LOCK_FOR_FORMAT = 0x04, + } + + /// Registers the device or type of device for which a window will receive notifications. + /// + /// + /// A handle to the window or service that will receive device events for the devices specified in the NotificationFilter parameter. + /// The same window handle can be used in multiple calls to RegisterDeviceNotification. + /// + /// Services can specify either a window handle or service status handle. + /// + /// + /// A pointer to a block of data that specifies the type of device for which notifications should be sent. This block always begins + /// with the DEV_BROADCAST_HDR structure. The data following this header is dependent on the value of the dbch_devicetype + /// member, which can be DBT_DEVTYP_DEVICEINTERFACE or DBT_DEVTYP_HANDLE. For more information, see Remarks. + /// + /// + /// This parameter can be one of the following values. + /// + /// + /// Value + /// Meaning + /// + /// + /// DEVICE_NOTIFY_WINDOW_HANDLE 0x00000000 + /// The hRecipient parameter is a window handle. + /// + /// + /// DEVICE_NOTIFY_SERVICE_HANDLE 0x00000001 + /// The hRecipient parameter is a service status handle. + /// + /// + /// In addition, you can specify the following value. + /// + /// + /// Value + /// Meaning + /// + /// + /// DEVICE_NOTIFY_ALL_INTERFACE_CLASSES 0x00000004 + /// + /// Notifies the recipient of device interface events for all device interface classes. (The dbcc_classguid member is ignored.) This + /// value can be used only if the dbch_devicetype member is DBT_DEVTYP_DEVICEINTERFACE. + /// + /// + /// + /// + /// + /// If the function succeeds, the return value is a device notification handle. + /// If the function fails, the return value is NULL. To get extended error information, call GetLastError. + /// + /// + /// + /// Applications send event notifications using the BroadcastSystemMessage function. Any application with a top-level window can + /// receive basic notifications by processing the WM_DEVICECHANGE message. Applications can use the RegisterDeviceNotification + /// function to register to receive device notifications. + /// + /// + /// Services can use the RegisterDeviceNotification function to register to receive device notifications. If a service + /// specifies a window handle in the hRecipient parameter, the notifications are sent to the window procedure. If hRecipient is a + /// service status handle, SERVICE_CONTROL_DEVICEEVENT notifications are sent to the service control handler. For more + /// information about the service control handler, see HandlerEx. + /// + /// + /// Be sure to handle Plug and Play device events as quickly as possible. Otherwise, the system may become unresponsive. If your + /// event handler is to perform an operation that may block execution (such as I/O), it is best to start another thread to perform + /// the operation asynchronously. + /// + /// + /// Device notification handles returned by RegisterDeviceNotification must be closed by calling the + /// UnregisterDeviceNotification function when they are no longer needed. + /// + /// + /// The DBT_DEVICEARRIVAL and DBT_DEVICEREMOVECOMPLETE events are automatically broadcast to all top-level windows for port devices. + /// Therefore, it is not necessary to call RegisterDeviceNotification for ports, and the function fails if the + /// dbch_devicetype member is DBT_DEVTYP_PORT. Volume notifications are also broadcast to top-level windows, so the + /// function fails if dbch_devicetype is DBT_DEVTYP_VOLUME. OEM-defined devices are not used directly by the system, so + /// the function fails if dbch_devicetype is DBT_DEVTYP_OEM. + /// + /// Examples + /// For an example, see Registering for Device Notification. + /// + // https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-registerdevicenotificationa HDEVNOTIFY + // RegisterDeviceNotificationA( HANDLE hRecipient, LPVOID NotificationFilter, DWORD Flags ); + [DllImport(Lib.User32, SetLastError = true, CharSet = CharSet.Auto)] + [PInvokeData("winuser.h", MSDNShortId = "82094d95-9af3-4222-9c5e-ce2df9bab5e3")] + public static extern SafeHDEVNOTIFY RegisterDeviceNotification(HANDLE hRecipient, IntPtr NotificationFilter, DEVICE_NOTIFY Flags); + + /// Closes the specified device notification handle. + /// Device notification handle returned by the RegisterDeviceNotification function. + /// + /// If the function succeeds, the return value is nonzero. + /// If the function fails, the return value is zero. To get extended error information, call GetLastError. + /// + // https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-unregisterdevicenotification BOOL + // UnregisterDeviceNotification( HDEVNOTIFY Handle ); + [DllImport(Lib.User32, SetLastError = true, ExactSpelling = true)] + [PInvokeData("winuser.h", MSDNShortId = "bcc0cf87-f996-47b5-937c-14a6332d00d9")] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool UnregisterDeviceNotification(HDEVNOTIFY Handle); + + /// Contains information about a class of devices. + // https://docs.microsoft.com/en-us/windows/desktop/api/dbt/ns-dbt-_dev_broadcast_deviceinterface_a typedef struct + // _DEV_BROADCAST_DEVICEINTERFACE_A { DWORD dbcc_size; DWORD dbcc_devicetype; DWORD dbcc_reserved; GUID dbcc_classguid; char + // dbcc_name[1]; } DEV_BROADCAST_DEVICEINTERFACE_A, *PDEV_BROADCAST_DEVICEINTERFACE_A; + [PInvokeData("dbt.h", MSDNShortId = "23e6b2b9-2053-4dfa-9c0a-283279f086b8")] + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] + public struct DEV_BROADCAST_DEVICEINTERFACE + { + /// + /// The size of this structure, in bytes. This is the size of the members plus the actual length of the dbcc_name string + /// (the null character is accounted for by the declaration of dbcc_name as a one-character array.) + /// + public uint dbcc_size; + + /// Set to DBT_DEVTYP_DEVICEINTERFACE. + public uint dbcc_devicetype; + + /// Reserved; do not use. + public uint dbcc_reserved; + + /// The GUID for the interface device class. + public Guid dbcc_classguid; + + /// + /// A null-terminated string that specifies the name of the device. + /// + /// When this structure is returned to a window through the WM_DEVICECHANGE message, the dbcc_name string is converted to + /// ANSI as appropriate. Services always receive a Unicode string, whether they call RegisterDeviceNotificationW or RegisterDeviceNotificationA. + /// + /// + public StrPtrAuto dbcc_name; + } + + /// Undocumented. + [PInvokeData("dbt.h")] + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] + public struct DEV_BROADCAST_DEVNODE + { + /// The size of this structure, in bytes. + public uint dbcd_size; + + /// Set to DBT_DEVTYP_DEVNODE. + public uint dbcd_devicetype; + + /// Reserved; do not use. + public uint dbcd_reserved; + + /// Undocumented. + public uint dbcd_devnode; + } + + /// + /// Contains information about a file system handle. + /// + // https://docs.microsoft.com/en-us/windows/desktop/api/dbt/ns-dbt-_dev_broadcast_handle typedef struct _DEV_BROADCAST_HANDLE { DWORD + // dbch_size; DWORD dbch_devicetype; DWORD dbch_reserved; HANDLE dbch_handle; HDEVNOTIFY dbch_hdevnotify; GUID dbch_eventguid; LONG + // dbch_nameoffset; BYTE dbch_data[1]; } DEV_BROADCAST_HANDLE, *PDEV_BROADCAST_HANDLE; + [PInvokeData("dbt.h", MSDNShortId = "5e542abc-8db3-4251-8b68-11456aa2da5e")] + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] + public struct DEV_BROADCAST_HANDLE + { + /// + /// The size of this structure, in bytes. + /// + public uint dbch_size; + + /// + /// Set to DBT_DEVTYP_HANDLE. + /// + public uint dbch_devicetype; + + /// + /// Reserved; do not use. + /// + public uint dbch_reserved; + + /// + /// A handle to the device to be checked. + /// + public HANDLE dbch_handle; + + /// + /// A handle to the device notification. This handle is returned by RegisterDeviceNotification. + /// + public HDEVNOTIFY dbch_hdevnotify; + + /// + /// The GUID for the custom event. For more information, see Device Events. Valid only for DBT_CUSTOMEVENT. + /// + public Guid dbch_eventguid; + + /// + /// The offset of an optional string buffer. Valid only for DBT_CUSTOMEVENT. + /// + public int dbch_nameoffset; + + /// + /// Optional binary data. This member is valid only for DBT_CUSTOMEVENT. + /// + public IntPtr dbch_data; + } + + /// + /// Serves as a standard header for information related to a device event reported through the WM_DEVICECHANGE message. + /// + /// The members of the DEV_BROADCAST_HDR structure are contained in each device management structure. To determine which + /// structure you have received through WM_DEVICECHANGE, treat the structure as a DEV_BROADCAST_HDR structure and check its + /// dbch_devicetype member. + /// + /// + // https://docs.microsoft.com/en-us/windows/desktop/api/Dbt/ns-dbt-_dev_broadcast_hdr typedef struct _DEV_BROADCAST_HDR { DWORD + // dbch_size; DWORD dbch_devicetype; DWORD dbch_reserved; } DEV_BROADCAST_HDR; + [PInvokeData("dbt.h", MSDNShortId = "4fc81fcb-b9fe-4016-b639-a43845af2c5f")] + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] + public struct DEV_BROADCAST_HDR + { + /// + /// The size of this structure, in bytes. + /// + /// If this is a user-defined event, this member must be the size of this header, plus the size of the variable-length data in + /// the _DEV_BROADCAST_USERDEFINED structure. + /// + /// + public uint dbch_size; + + /// + /// + /// The device type, which determines the event-specific information that follows the first three members. This member can be one + /// of the following values. + /// + /// + /// + /// Value + /// Meaning + /// + /// + /// DBT_DEVTYP_DEVICEINTERFACE 0x00000005 + /// Class of devices. This structure is a DEV_BROADCAST_DEVICEINTERFACE structure. + /// + /// + /// DBT_DEVTYP_HANDLE 0x00000006 + /// File system handle. This structure is a DEV_BROADCAST_HANDLE structure. + /// + /// + /// DBT_DEVTYP_OEM 0x00000000 + /// OEM- or IHV-defined device type. This structure is a DEV_BROADCAST_OEM structure. + /// + /// + /// DBT_DEVTYP_PORT 0x00000003 + /// Port device (serial or parallel). This structure is a DEV_BROADCAST_PORT structure. + /// + /// + /// DBT_DEVTYP_VOLUME 0x00000002 + /// Logical volume. This structure is a DEV_BROADCAST_VOLUME structure. + /// + /// + /// + public DBT_DEVTYPE dbch_devicetype; + + /// Reserved; do not use. + public uint dbch_reserved; + } + + /// Undocumented. + [PInvokeData("dbt.h")] + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] + public struct DEV_BROADCAST_NET + { + /// The size of this structure, in bytes. + public uint dbcn_size; + + /// Set to DBT_DEVTYP_NET. + public uint dbcn_devicetype; + + /// Reserved; do not use. + public uint dbcn_reserved; + + /// Undocumented. + public uint dbcn_resource; + + /// Undocumented. + public uint dbcn_flags; + } + + /// Contains information about a OEM-defined device type. + // https://docs.microsoft.com/en-us/windows/desktop/api/dbt/ns-dbt-_dev_broadcast_oem typedef struct _DEV_BROADCAST_OEM { DWORD + // dbco_size; DWORD dbco_devicetype; DWORD dbco_reserved; DWORD dbco_identifier; DWORD dbco_suppfunc; } DEV_BROADCAST_OEM; + [PInvokeData("dbt.h", MSDNShortId = "32d72002-1e67-4f72-8821-6712eb898e7d")] + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] + public struct DEV_BROADCAST_OEM + { + /// The size of this structure, in bytes. + public uint dbco_size; + + /// Set to DBT_DEVTYP_OEM. + public uint dbco_devicetype; + + /// Reserved; do not use. + public uint dbco_reserved; + + /// The OEM-specific identifier for the device. + public uint dbco_identifier; + + /// The OEM-specific function value. Possible values depend on the device. + public uint dbco_suppfunc; + } + + /// Contains information about a modem, serial, or parallel port. + // https://docs.microsoft.com/en-us/windows/desktop/api/dbt/ns-dbt-_dev_broadcast_port_a typedef struct _DEV_BROADCAST_PORT_A { DWORD + // dbcp_size; DWORD dbcp_devicetype; DWORD dbcp_reserved; char dbcp_name[1]; } DEV_BROADCAST_PORT_A, *PDEV_BROADCAST_PORT_A; + [PInvokeData("dbt.h", MSDNShortId = "b8789f1c-7d82-4637-bdb0-016a22b3bc8a")] + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] + public struct DEV_BROADCAST_PORT + { + /// + /// The size of this structure, in bytes. This is the size of the members plus the actual length of the dbcp_name string + /// (the null character is accounted for by the declaration of dbcp_name as a one-character array.) + /// + public uint dbcp_size; + + /// Set to DBT_DEVTYP_PORT. + public uint dbcp_devicetype; + + /// Reserved; do not use. + public uint dbcp_reserved; + + /// + /// A null-terminated string specifying the friendly name of the port or the device connected to the port. Friendly names are + /// intended to help the user quickly and accurately identify the device—for example, "COM1" and "Standard 28800 bps Modem" are + /// considered friendly names. + /// + public StrPtrAuto dbcp_name; + } + + /// Undocumented. + [PInvokeData("dbt.h")] + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] + public struct DEV_BROADCAST_USERDEFINED + { + /// Header. + public DEV_BROADCAST_HDR dbud_dbh; + + /// Undocumented. + public StrPtrAnsi dbud_szName; + } + + /// Contains information about a logical volume. + /// + /// + /// Although the dbcv_unitmask member may specify more than one volume in any message, this does not guarantee that only one + /// message is generated for a specified event. Multiple system features may independently generate messages for logical volumes at + /// the same time. + /// + /// + /// Messages for media arrival and removal are sent only for media in devices that support a soft-eject mechanism. For example, + /// applications will not see media-related volume messages for floppy disks. + /// + /// + /// Messages for network drive arrival and removal are not sent whenever network commands are issued, but rather when network + /// connections will disappear as the result of a hardware event. + /// + /// + // https://docs.microsoft.com/en-us/windows/desktop/api/dbt/ns-dbt-_dev_broadcast_volume typedef struct _DEV_BROADCAST_VOLUME { DWORD + // dbcv_size; DWORD dbcv_devicetype; DWORD dbcv_reserved; DWORD dbcv_unitmask; WORD dbcv_flags; } DEV_BROADCAST_VOLUME; + [PInvokeData("dbt.h", MSDNShortId = "8ce644d9-1e95-458e-924f-67bd37831048")] + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] + public struct DEV_BROADCAST_VOLUME + { + /// The size of this structure, in bytes. + public uint dbcv_size; + + /// Set to DBT_DEVTYP_VOLUME (2). + public uint dbcv_devicetype; + + /// Reserved; do not use. + public uint dbcv_reserved; + + /// + /// The logical unit mask identifying one or more logical units. Each bit in the mask corresponds to one logical drive. Bit 0 + /// represents drive A, bit 1 represents drive B, and so on. + /// + public uint dbcv_unitmask; + + /// + /// This parameter can be one of the following values. + /// + /// + /// Value + /// Meaning + /// + /// + /// DBTF_MEDIA 0x0001 + /// Change affects media in drive. If not set, change affects physical device or drive. + /// + /// + /// DBTF_NET 0x0002 + /// Indicated logical volume is a network volume. + /// + /// + /// + public DBTF dbcv_flags; + } + + /// Provides a handle to a device notification. + [PInvokeData("dbt.h")] + [StructLayout(LayoutKind.Sequential)] + public struct HDEVNOTIFY : IHandle + { + private IntPtr handle; + + /// Initializes a new instance of the struct. + /// An object that represents the pre-existing handle to use. + public HDEVNOTIFY(IntPtr preexistingHandle) => handle = preexistingHandle; + + /// Returns an invalid handle by instantiating a object with . + public static HDEVNOTIFY NULL => new HDEVNOTIFY(IntPtr.Zero); + + /// Gets a value indicating whether this instance is a null handle. + public bool IsNull => handle == IntPtr.Zero; + + /// Performs an explicit conversion from to . + /// The handle. + /// The result of the conversion. + public static explicit operator IntPtr(HDEVNOTIFY h) => h.handle; + + /// Performs an implicit conversion from to . + /// The pointer to a handle. + /// The result of the conversion. + public static implicit operator HDEVNOTIFY(IntPtr h) => new HDEVNOTIFY(h); + + /// Implements the operator !=. + /// The first handle. + /// The second handle. + /// The result of the operator. + public static bool operator !=(HDEVNOTIFY h1, HDEVNOTIFY h2) => !(h1 == h2); + + /// Implements the operator ==. + /// The first handle. + /// The second handle. + /// The result of the operator. + public static bool operator ==(HDEVNOTIFY h1, HDEVNOTIFY h2) => h1.Equals(h2); + + /// + public override bool Equals(object obj) => obj is HDEVNOTIFY h ? handle == h.handle : false; + + /// + public override int GetHashCode() => handle.GetHashCode(); + + /// + public IntPtr DangerousGetHandle() => handle; + } + + /// Undocumented. + [PInvokeData("dbt.h")] + [StructLayout(LayoutKind.Sequential)] + public struct VolLockBroadcast + { + /// Undocumented. + public DEV_BROADCAST_HDR vlb_dbh; + + /// thread on which lock request is being issued. + public uint vlb_owner; + + /// lock permission flags. + public LOCKP vlb_perms; + + /// type of lock + public byte vlb_lockType; + + /// drive on which lock is issued + public byte vlb_drive; + + /// miscellaneous flags + public LOCKF vlb_flags; + } + + /// Provides a for that is disposed using . + [PInvokeData("dbt.h")] + public class SafeHDEVNOTIFY : SafeHANDLE + { + /// Initializes a new instance of the class and assigns an existing handle. + /// An object that represents the pre-existing handle to use. + /// + /// to reliably release the handle during the finalization phase; otherwise, (not recommended). + /// + public SafeHDEVNOTIFY(IntPtr preexistingHandle, bool ownsHandle = true) : base(preexistingHandle, ownsHandle) { } + + /// Initializes a new instance of the class. + private SafeHDEVNOTIFY() : base() { } + + /// Performs an implicit conversion from to . + /// The SafeHDEVNOTIFY. + /// The result of the conversion. + public static implicit operator HDEVNOTIFY(SafeHDEVNOTIFY h) => h.handle; + + /// + protected override bool InternalReleaseHandle() => UnregisterDeviceNotification(handle); + } + } +} \ No newline at end of file