Thanks Jan. I don't have the console part working yet, but I did stumble across a way to make DEV_BROADCAST_DEVICE_INTERFACE_1 unnecessary (i think):
/// <summary>
/// Contains information about a class of devices.
///
/// <para>Use this one in the call to RegisterDeviceNotification() and
/// in checking dbch_devicetype in a DEV_BROADCAST_HDR structure:</para>
/// </summary>
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Auto)]
public class DEV_BROADCAST_DEVICEINTERFACE
{
/// <summary>
/// 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.)
/// </summary>
public int dbcc_size;
/// <summary>
/// Set to DBT_DEVTYP_DEVICEINTERFACE
/// </summary>
public DBT_DEVTYP dbcc_devicetype;
/// <summary>
/// Reserved; do not use.
/// </summary>
public int dbcc_reserved;
/// <summary>
/// The GUID for the interface device class.
/// </summary>
public Guid dbcc_classguid;
/// <summary>
/// A null-terminated string that specifies the name of the device.
///
/// <para>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.</para>
/// </summary>
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 255)]
public string dbcc_name;
}
It is working in the "it hasn't crashed my machine yet" sense of the word, but I thought it might interest you. I am using this single structure declaration for registering and receiving.