I'm trying to get the Name of the USB device pluged in from the
RegisterDeviceN otification that I've used P/Invoke to marshal. I have
seen a similar posting on the VisualBasic newgroups but I do not know
how to translate the ReDim that occurs there into C#. Or wither this
will actually give me what I'm looking for.
The code I'm posting seems to work although I don't know how to
set the length of the name correctly in the Marshal.PtrToSt ructure()
call.
Thanks all for any help.
Hopefully this VB->VC translation can help someone out there as well
Jeff
Visual Basic Code:
=============== ===
Imports System.Runtime. InteropServices
Imports System.Windows. Forms
Imports System.Text
Public Class Form1
Inherits System.Windows. Forms.Form
Public Class Win32
Public Const WM_DEVICECHANGE = &H219
Public Const DBT_DEVICEARRIV AL = &H8000
Public Const DBT_DEVICEREMOV ECOMPLETE = &H8004
Public Const DEVICE_NOTIFY_W INDOW_HANDLE = 0
Public Const DEVICE_NOTIFY_S ERVICE_HANDLE = 1
Public Const DBT_DEVTYP_DEVI CEINTERFACE = 5
Public Shared GUID_IO_MEDIA_A RRIVAL As Guid = New
Guid("A5DCBF10-6530-11D2-901F-00C04FB951ED")
<StructLayout(L ayoutKind.Seque ntial)> _
Public Class DEV_BROADCAST_D EVICEINTERFACE
Public dbcc_size As Integer
Public dbcc_devicetype As Integer
Public dbcc_reserved As Integer
Public dbcc_classguid As Guid
Public dbcc_name As Short
End Class
<StructLayout(L ayoutKind.Seque ntial,
CharSet:=CharSe t.Unicode)> _
Public Class DEV_BROADCAST_D EVICEINTERFACE1
Public dbcc_size As Integer
Public dbcc_devicetype As Integer
Public dbcc_reserved As Integer
<MarshalAs(Unma nagedType.ByVal Array,
ArraySubType:=U nmanagedType.U1 , SizeConst:=16)> _
Public dbcc_classguid( ) As Byte
<MarshalAs(Unma nagedType.ByVal Array, SizeConst:=128) > _
Public dbcc_name() As Char
End Class
<StructLayout(L ayoutKind.Seque ntial)> _
Public Class DEV_BROADCAST_H DR
Public dbcc_size As Integer
Public dbcc_devicetype As Integer
Public dbcc_reserved As Integer
End Class
<DllImport("use r32.DLL", SetLastError:=T rue)> _
Public Shared Function _
RegisterDeviceN otification(ByV al IntPtr As IntPtr, ByVal
NotificationFil ter As IntPtr, ByVal Flags As Int32) As IntPtr
End Function
<DllImport("ker nel32.DLL")> _
Public Shared Function _
GetLastError() As Integer
End Function
End Class
Public Sub New()
MyBase.New()
InitializeCompo nent()
RegisterHidNoti fication()
End Sub
Public Sub RegisterHidNoti fication()
Dim dbi As Win32.DEV_BROAD CAST_DEVICEINTE RFACE = New
Win32.DEV_BROAD CAST_DEVICEINTE RFACE
Dim size As Integer
size = Marshal.SizeOf( dbi)
Dim gd As Guid
' MsgBox(Marshal. SizeOf(gd))
' MsgBox(Marshal. SizeOf(New
Win32.DEV_BROAD CAST_DEVICEINTE RFACE1))
dbi.dbcc_size = size
dbi.dbcc_device type = Win32.DBT_DEVTY P_DEVICEINTERFA CE
dbi.dbcc_reserv ed = 0
dbi.dbcc_classg uid = Win32.GUID_IO_M EDIA_ARRIVAL
Dim Buffer As IntPtr
Buffer = Marshal.AllocHG lobal(size)
Marshal.Structu reToPtr(dbi, Buffer, True)
Dim r As IntPtr
r = Win32.RegisterD eviceNotificati on(Handle, Buffer,
Win32.DEVICE_NO TIFY_WINDOW_HAN DLE)
Marshal.PtrToSt ructure(Buffer, dbi)
If r.ToInt32 = IntPtr.Zero.ToI nt32 Then
MessageBox.Show (Win32.GetLastE rror().ToString ())
End If
End Sub
Protected Overrides Sub WndProc(ByRef m As Message)
If m.Msg = Win32.WM_DEVICE CHANGE Then
OnDeviceChange( m)
End If
MyBase.WndProc( m)
End Sub
Private Sub OnDeviceChange( ByVal msg As Message)
Dim wParam As Integer
wParam = msg.WParam.ToIn t32()
If wParam = Win32.DBT_DEVIC EARRIVAL Then
Dim o As New Win32.DEV_BROAD CAST_HDR
Dim b As New Win32.DEV_BROAD CAST_DEVICEINTE RFACE1
Dim gd As Guid
Marshal.PtrToSt ructure(msg.LPa ram, o)
If (o.dbcc_devicet ype = Win32.DBT_DEVTY P_DEVICEINTERFA CE)
Then
Dim strsize As Integer = (o.dbcc_size - 28) / 2
ReDim b.dbcc_name(str size)
Marshal.PtrToSt ructure(msg.LPa ram, b)
MsgBox(New Guid(b.dbcc_cla ssguid).ToStrin g)
Dim str As New String(b.dbcc_n ame, 0, strsize)
MsgBox(str)
End If
MessageBox.Show ("Arrival")
ElseIf wParam = Win32.DBT_DEVIC EREMOVECOMPLETE Then
MessageBox.Show ("Remove")
End If
End Sub
'Form overrides dispose to clean up the component list.
Protected Overloads Overrides Sub Dispose(ByVal disposing As
Boolean)
If disposing Then
If Not (components Is Nothing) Then
components.Disp ose()
End If
End If
MyBase.Dispose( disposing)
End Sub
'Required by the Windows Form Designer
Private components As System.Componen tModel.IContain er
'NOTE: The following procedure is required by the Windows Form
Designer
'It can be modified using the Windows Form Designer.
'Do not modify it using the code editor.
<System.Diagnos tics.DebuggerSt epThrough()> Private Sub
InitializeCompo nent()
components = New System.Componen tModel.Containe r
Me.Text = "Form1"
Dim t As New Guid("d07433c0-a98e-11d2-917a-00a0c9068ff3")
End Sub
End Class
Visual CSharp Equivilent
=============== =========
using System;
using System.Drawing;
using System.Collecti ons;
using System.Componen tModel;
using System.Windows. Forms;
using System.Data;
using System.Runtime. InteropServices ;
namespace WindowsApplicat ion1
{
/// <summary>
/// Summary description for Form1.
/// </summary>
public class Form1 : System.Windows. Forms.Form
{
private System.Componen tModel.Containe r components = null;
public Form1()
{
InitializeCompo nent();
RegisterDeviceN otification();
}
private void InitializeCompo nent()
{
this.components = new System.Componen tModel.Containe r();
this.Size = new System.Drawing. Size(300,300);
this.Text = "Form1";
}
[STAThread] static void Main()
{
Application.Run (new Form1());
}
void RegisterDeviceN otification()
{
Win32.DEV_BROAD CAST_DEVICEINTE RFACE dbi = new
Win32.DEV_BROAD CAST_DEVICEINTE RFACE();
int size = Marshal.SizeOf( dbi);
dbi.dbcc_size = size;
dbi.dbcc_device type = Win32.DBT_DEVTY P_DEVICEINTERFA CE;
dbi.dbcc_reserv ed = 0;
dbi.dbcc_classg uid = Win32.GUID_DEVI NTERFACE_USB_DE VICE;
dbi.dbcc_name = 0;
IntPtr buffer = Marshal.AllocHG lobal(size);
Marshal.Structu reToPtr(dbi, buffer, true);
IntPtr r = Win32.RegisterD eviceNotificati on(Handle, buffer,
Win32.DEVICE_NO TIFY_WINDOW_HAN DLE);
if(r == IntPtr.Zero)
MessageBox.Show (Win32.GetLastE rror().ToString ());
}
protected override void WndProc(ref Message m)
{
switch(m.Msg)
{
case Win32.WM_DEVICE CHANGE: OnDeviceChange( ref m); break;
}
base.WndProc (ref m);
}
void OnDeviceChange( ref Message msg)
{
int wParam = (int)msg.WParam ;
if((wParam == Win32.DBT_DEVIC EARRIVAL) || (wParam ==
Win32.DBT_DEVIC EREMOVECOMPLETE ))
{
// Read the dhdr.dbcc_devic etype - The Following code could also
be used
////////////////////////////////////////////////////////////////////////
//Win32.DEV_BROAD CAST_HDR dhdr;
//dhdr = (Win32.DEV_BROA DCAST_HDR)
Marshal.PtrToSt ructure(msg.LPa ram,typeof(Win3 2.DEV_BROADCAST _HDR));
//if (dhdr.dbcc_devi cetype == Win32.DBT_DEVTY P_DEVICEINTERFA CE)
int dbccSize = Marshal.ReadInt 32(msg.LParam,0 );
int devType = Marshal.ReadInt 32(msg.LParam,4 );
if(devType == Win32.DBT_DEVTY P_DEVICEINTERFA CE)
{
Win32.DEV_BROAD CAST_DEVICEINTE RFACE1 dip;
dip = (Win32.DEV_BROA DCAST_DEVICEINT ERFACE1)
Marshal.PtrToSt ructure(msg.LPa ram,typeof(Win3 2.DEV_BROADCAST _DEVICEINTERFAC E1));
string csTemp = new string(dip.dbcc _name);
MessageBox.Show (csTemp + " arrived/removed");
}
}
}
}
public class Win32
{
public const int WM_DEVICECHANGE = 0x0219;
public const int DBT_DEVICEARRIV AL = 0x8000, // system
detected a new device
DBT_DEVICEREMOV ECOMPLETE = 0x8004; // device is gone
public const int DEVICE_NOTIFY_W INDOW_HANDLE = 0,
DEVICE_NOTIFY_S ERVICE_HANDLE = 1;
public const int DBT_DEVTYP_DEVI CEINTERFACE = 0x00000005; // device
interface class
public static Guid GUID_DEVINTERFA CE_USB_DEVICE = new
Guid("A5DCBF10-6530-11D2-901F-00C04FB951ED");
[StructLayout(La youtKind.Sequen tial)] public class DEV_BROADCAST_H DR
{
public int dbcc_size;
public int dbcc_devicetype ;
public int dbcc_reserved;
}
[StructLayout(La youtKind.Sequen tial)] public class
DEV_BROADCAST_D EVICEINTERFACE
{
public int dbcc_size;
public int dbcc_devicetype ;
public int dbcc_reserved;
public Guid dbcc_classguid;
public short dbcc_name;
}
[StructLayout(La youtKind.Sequen tial, CharSet=CharSet .Unicode)]
public class DEV_BROADCAST_D EVICEINTERFACE1
{
public int dbcc_size;
public int dbcc_devicetype ;
public int dbcc_reserved;
[MarshalAs(Unman agedType.ByValA rray, ArraySubType=Un managedType.U1,
SizeConst=16)] public byte [] dbcc_classguid;
[MarshalAs(Unman agedType.ByValA rray, SizeConst=128)] public char []
dbcc_name;
}
[DllImport("user 32.dll", SetLastError=tr ue)] public static extern
IntPtr RegisterDeviceN otification( IntPtr hRecipient, IntPtr
NotificationFil ter, Int32 Flags);
[DllImport("kern el32.dll")] public static extern int GetLastError();
}
}