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_dev icetype == 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_DEVICEINTER FACE {
// DWORD dbcc_size;
// DWORD dbcc_devicetype;
// DWORD dbcc_reserved;
// GUID dbcc_classguid;
// TCHAR dbcc_name[1];
//} DEV_BROADCAST_DEVICEINTERF ACE, *PDEV_BROADCAST_DEVICEINTE RFACE;
[StructLayout(LayoutKind.S equential, CharSet = CharSet.Auto)]
internal struct DEV_BROADCAST_DEVICEINTERF ACE
{
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_DEVICEINTERF ACE 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_DEVICEINTERF ACE data:
dbcc_size 172 int
dbcc_devicetype 5 int
dbcc_reserved 0 int
dbcc_classguid {a5dcbf10-6530-11d2-901f-0 0c04fb951e d} 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.
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
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
//typedef struct _DEV_BROADCAST_DEVICEINTER
// DWORD dbcc_size;
// DWORD dbcc_devicetype;
// DWORD dbcc_reserved;
// GUID dbcc_classguid;
// TCHAR dbcc_name[1];
//} DEV_BROADCAST_DEVICEINTERF
[StructLayout(LayoutKind.S
internal struct DEV_BROADCAST_DEVICEINTERF
{
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_DEVICEINTERF
In a sample run of my program, I plug in a USB pendrive and get the following DEV_BROADCAST_DEVICEINTERF
dbcc_size 172 int
dbcc_devicetype 5 int
dbcc_reserved 0 int
dbcc_classguid {a5dcbf10-6530-11d2-901f-0
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.
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
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
what is the use of the application that you are trying to build
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.