1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
| using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace USBDetector
{
/// <summary>
/// Code coped from
/// http://www.lesite.com/codes/USB-DETECTOR_36407.aspx
/// </summary>
public partial class frmMain : Form
{
private const int WM_DEVICECHANGE = 0x0219;
private const int DBT_DEVICEARRIVAL = 0x8000;
private const int DBT_DEVICEREMOVECOMPLETE = 0x8004;
private const int DBT_DEVTYP_VOLUME = 0x2;
public frmMain()
{
InitializeComponent();
}
/// <summary>
/// Surcharge de la fonction de Message Loop, WndProc
/// </summary>
/// <param name="m">Message reçu dans la boucle de messages</param>
protected override void WndProc(ref Message m)
{
// le message est de type DEVICECHANGE, ce qui nous interesse
if (m.Msg == WM_DEVICECHANGE)
{
// le "sous-message" dit que le device vient d'etre pluggé
if (m.WParam.ToInt32() == DBT_DEVICEARRIVAL)
{
// device plugged
// on créé une structure depuis un pointeur a l'aide du Marshalling
// cette structure est generique mais on peut "l'interroger" comme une structure DEV_BROADCAST_HDR
DEV_BROADCAST_HDR hdr = (DEV_BROADCAST_HDR)Marshal.PtrToStructure(m.LParam, typeof(DEV_BROADCAST_HDR));
// ok, le device pluggé est un volume (aussi appelé 'périphérique de stockage de masse')...
if (hdr.dbch_devicetype == DBT_DEVTYP_VOLUME)
{
// ... et donc on recréé une structure, a partir du même pointeur de structure "générique",
// une structure un poil plus spécifique
DEV_BROADCAST_VOLUME vol = (DEV_BROADCAST_VOLUME)Marshal.PtrToStructure(m.LParam, typeof(DEV_BROADCAST_VOLUME));
// le champs dbcv_unitmask contient la ou les lettres de lecteur du ou des devices qui viennent d'etre pluggé
// MSDN nous dit que si le bit 0 est à 1 alors le lecteur est a:, si le bit 1 est à 1 alors le lecteur est b:
// et ainsi de suite
uint mask = vol.dbcv_unitmask;
// recupèration des lettres de lecteurs
char[] letters = MaskDepioteur(mask);
// mise à jour de l'IHM pour notifier nos petits yeux tout content :)
this.Text = string.Format("USB key plugged on drive {0}:", letters[0].ToString().ToUpper());
}
}
// le device vient d'etre retirer bourrinement ou proprement
// (ce message intervient même quand on défait la clef softwarement mais qu'elle reste physiquement branché)
else if (m.WParam.ToInt32() == DBT_DEVICEREMOVECOMPLETE)
{
// device removed
// mise à jour de l'IHM
this.Text = "USB key unplugged";
}
}
// laissons notre fenêtre faire tout de même son boulot
base.WndProc(ref m);
}
// fonction d'extraction des lettres de lecteur
public static char[] MaskDepioteur(uint mask)
{
int cnt = 0;
uint temp_mask = mask;
// on compte le nombre de bits à 1
for (int i = 0; i < 32; i++)
{
if ((temp_mask & 1) == 1)
cnt++;
temp_mask >>= 1;
if (temp_mask == 0)
break;
}
// on instancie le bon nombre d'elements
char[] result = new char[cnt];
cnt = 0;
// on refait mais ce coup ci on attribut
for (int i = 0; i < 32; i++)
{
if ((mask & 1) == 1)
result[cnt++] = (char)('a' + i);
mask >>= 1;
if (mask == 0)
break;
}
return (result);
}
}
// structure générique
public struct DEV_BROADCAST_HDR
{
public uint dbch_size;
public uint dbch_devicetype;
public uint dbch_reserved;
}
// structure spécifique
// notez qu'elle a strictement le même tronche que la générique mais
// avec des trucs en plus
public struct DEV_BROADCAST_VOLUME
{
public uint dbcv_size;
public uint dbcv_devicetype;
public uint dbcv_reserved;
public uint dbcv_unitmask;
public ushort dbcv_flags;
}
} |
Partager