Link to home
Start Free TrialLog in
Avatar of ben84
ben84

asked on

Cannot marshal string from DEV_BROADCAST_DEVICEINTERFACE in WM_DEVICECHANGE message

Hi,

I am using a C# windows app to detect insertion or removal of a USB mass storage device, and to get the USB device name when this happens.

I got as far as detecting insert/remove events, but i'm having trouble getting the device name.

I have successfully used RegisterDeviceNotification() to tell windows to send my WM_DEVICECHANGE messages for USB class devices.

When I receive a WM_DEVICECHANGE of (WParam) type DBT_DEVICEARRIVAL the MSDN docs say that LParam should point to a DEV_BROADCAST_HDR structure with some optional extra data on the end.

As I am interested in the DBT_DEVTYP_DEVICEINTERFACE structure, I check that the DEV_BROADCAST_HDR.dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE, if so then I use Marshal.PtrToStructure(...) to transfer the data in LParam to a managed struct declared as follows:

        //typedef struct _DEV_BROADCAST_DEVICEINTERFACE {
        //  DWORD dbcc_size;
        //  DWORD dbcc_devicetype;
        //  DWORD dbcc_reserved;
        //  GUID  dbcc_classguid;
        //  TCHAR dbcc_name[1];
        //} DEV_BROADCAST_DEVICEINTERFACE, *PDEV_BROADCAST_DEVICEINTERFACE;
        [StructLayout(LayoutKind.Sequential,CharSet = CharSet.Auto)]
        internal struct DEV_BROADCAST_DEVICEINTERFACE
        {
            internal int dbcc_size;
            internal int dbcc_devicetype;
            internal int dbcc_reserved;
            internal Guid dbcc_classguid;
            internal string dbcc_name;
        }

Soooo, here is the problem:

 all the fields in my DEV_BROADCAST_DEVICEINTERFACE are populated correctly except for the one i'm after: dbcc_name.

In a sample run of my program, I plug in a USB pendrive and get the following DEV_BROADCAST_DEVICEINTERFACE data:

dbcc_size      172      int
dbcc_devicetype      5      int
dbcc_reserved      0      int
dbcc_classguid      {a5dcbf10-6530-11d2-901f-00c04fb951ed}      System.Guid
dbcc_name      ""      string

The value of 172 for dbcc_size suggests that windows IS sending the correct data, but that i'm not correctly marshalling it.

Thanks,

Ben.
Avatar of pgnatyuk
pgnatyuk
Flag of Israel image

This example will help you a lot:
Detecting Media Insertion or Removal
http://msdn.microsoft.com/en-us/library/aa363215(v=VS.85).aspx
(FirstDriveFromMask - pay attention on this function, this is the one character you are trying to convert to a string, but it is a mask)
DEV_BROADCAST_HDR Structure:
 http://msdn.microsoft.com/en-us/library/aa363246(v=VS.85).aspx
 I think you make a mistake with this structure.
Check here:
MSDN. DBT_DEVICEARRIVAL Event
http://msdn.microsoft.com/en-us/library/aa363205(v=VS.85).aspx
"If media is being inserted, the type of device arriving is a volume (the dbch_devicetype member is DBT_DEVTYP_VOLUME) and the change effects the media (the dbcv_flags member is DBTF_MEDIA)."
If I remember correctly, your app receives few such messages. Comment the code that parse this message in your app and add a Trace - you will see what's going on, no breakpoints.
 
Avatar of ben84
ben84

ASKER

Thanks for your reply pgnatyuk, but i'm afraid what you've posted doesn't really help.   I have already read all three of the above, and DBT_DEVTYP_VOLUME does not give me the info I need: the DevceID.  My problem is specifically with marshalling, and I think my question should have stressed that.

ASKER CERTIFIED SOLUTION
Avatar of ben84
ben84

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
what is the use of the application that you are trying to build