Search code examples
c#winapiguiddevice-instance-id

How to get friendly device name from DEV_BROADCAST_DEVICEINTERFACE and Device Instance ID


I've registered a window with RegisterDeviceNotification and can successfully recieve DEV_BROADCAST_DEVICEINTERFACE messages. However, the dbcc_name field in the returned struct is always empty. The struct I have is defined as such:

[StructLayout(LayoutKind.Sequential)]
public struct DEV_BROADCAST_DEVICEINTERFACE
{
    public int dbcc_size;
    public int dbcc_devicetype;
    public int dbcc_reserved;
    public Guid dbcc_classguid;
    [MarshalAs(UnmanagedType.LPStr)]
    public string dbcc_name;
}

And I'm using Marshal.PtrToStructure on the LParam of the WM_DEVICECHANGE message.

Should this be working?

Or even better... Is there an alternative way to get the name of a device upon connection?

EDIT (02/05/2010 20:56GMT):

I found out how to get the dbcc_name field to populate by doing this:

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct DEV_BROADCAST_DEVICEINTERFACE
{
    public int dbcc_size;
    public int dbcc_devicetype;
    public int dbcc_reserved;
    public Guid dbcc_classguid;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst=255)]
    public string dbcc_name;
}

but I still need a way to get a "Friendly" name from what is int dbcc_name. It looks like the following:

\?\USB#VID_05AC&PID_1294&MI_00#0#{6bdd1fc6-810f-11d0-bec7-08002be2092f}

And I really just want it to say "Apple iPhone" (which is what the device is in this case).


Solution

  • Well, as noted above I found out how to get dbcc_name to populate correctly. I found that this was the easiest way to get the device name:

    private static string GetDeviceName(DEV_BROADCAST_DEVICEINTERFACE dvi)
    {
        string[] Parts = dvi.dbcc_name.Split('#');
        if (Parts.Length >= 3)
        {
            string DevType = Parts[0].Substring(Parts[0].IndexOf(@"?\") + 2);
            string DeviceInstanceId = Parts[1];
            string DeviceUniqueID = Parts[2];
            string RegPath = @"SYSTEM\CurrentControlSet\Enum\" + DevType + "\\" + DeviceInstanceId + "\\" + DeviceUniqueID;
            RegistryKey key = Registry.LocalMachine.OpenSubKey(RegPath);
            if (key != null)
            {
                object result = key.GetValue("FriendlyName");
                if (result != null)
                    return result.ToString();
                result = key.GetValue("DeviceDesc");
                if (result != null)
                    return result.ToString();
            }
        }
        return String.Empty;
    }