I'm trying to catch VIP and PID from USB device:
public const int WM_DEVICECHANGE = 0x219;
public const int DBT_DEVTYP_VOLUME = 0x00000002;
public const int DBT_DEVICEARRIVAL = 0x8000;
[StructLayout(LayoutKind.Sequential)]
internal class DEV_BROADCAST_HDR
{
public int dbch_size;
public int dbch_devicetype;
public int dbch_reserved;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct DEV_BROADCAST_DEVICEINTERFACE
{
public int dbcc_size;
public int dbcc_devicetype;
public int dbcc_reserved;
[MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.U1, SizeConst = 16)]
public byte[] dbcc_classguid;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 256)]
public char[] dbcc_name;
}
public void WndProc(ref Message m)
{
if (m.Msg == WM_DEVICECHANGE) //Device state has changed
{
switch (m.WParam.ToInt32())
{
case DBT_DEVICEARRIVAL: //New device arrives
DEV_BROADCAST_HDR hdr;
hdr = (DEV_BROADCAST_HDR)Marshal.PtrToStructure(m.LParam, typeof(DEV_BROADCAST_HDR));
if (hdr.dbch_devicetype == DBT_DEVTYP_VOLUME) //If it is a USB Mass Storage or Hard Drive
{
//Save Device name
DEV_BROADCAST_DEVICEINTERFACE deviceInterface;
string deviceName = "";
deviceInterface = (DEV_BROADCAST_DEVICEINTERFACE)Marshal.PtrToStructure(m.LParam, typeof(DEV_BROADCAST_DEVICEINTERFACE));
deviceName = new string(deviceInterface.dbcc_name).Trim();
}
}
}
}
But deviceName
always returns a string with non sense characters. I have change CharSet
in DEV_BROADCAST_DEVICEINTERFACE
structure and declare dbcc.name
as string but the result is the same.
I would like to avoid reading from registry, and among all I have read, I have seen that it is possible to cast a DEV_BROADCAST_HEADER
to a DEV_BROADCAST_DEVICEINTERFACE
only if dbch_devicetype==DBT_DEVTYP_DEVICEINTERFACE
. In my case, dbch_devicetype is 2, not 5, and I am using some common USB Mass Storage devices. What am I doing wrong? Thanks in advance!