In this post i am going to explain some more interesting thing, USB Detector so this article deals with create a application for detect the USB when inserted and removed from computer and make a notification to user on removal
USB Detector :
Click Here To DownloadLaunch the application after the download, Then plug in the USB device in the computer now you will see a device add in the application and select a Notify checkbox to notify the user when it is try to remove
Now we see how to do this application.
USBDetector:public class USBDetector: IDisposable
{
public event USBDetectorEventHandlerDeviceArrived;
public event USBDetectorEventHandlerDeviceRemoved;
public event USBDetectorEventHandlerQueryRemove;
publicUSBDetector()
{
DriveFormfrm = new DriveForm(this);
frm.Show();
Init(frm, null);
}
publicUSBDetector(Control control)
{
Init(control, null);
}
publicUSBDetector(Control control, string FileToOpen)
{
Init(control, FileToOpen);
}
privatevoid Init(Controlcontrol, string fileToOpen)
{
mFileToOpen = fileToOpen;
mFileOnFlash = null;
mDeviceNotifyHandle = IntPtr.Zero;
mRecipientHandle = control.Handle;
mDirHandle = IntPtr.Zero;
mCurrentDrive = "";
}
public bool IsQueryHooked
{
get
{
if(mDeviceNotifyHandle == IntPtr.Zero)
returnfalse;
else
returntrue;
}
}
public string HookedDrive
{
get
{
returnmCurrentDrive;
}
}
public FileStream OpenedFile
{
get
{
returnmFileOnFlash;
}
}
public bool EnableQueryRemove(stringfileOnDrive)
{
if(fileOnDrive == null || fileOnDrive.Length == 0)
thrownew ArgumentException("Drive path must be supplied to register for Query remove.");
if(fileOnDrive.Length == 2 && fileOnDrive[1] == ':')
fileOnDrive += '\\'; // append "\\" if only drive letter with ":" was passed in.
if(mDeviceNotifyHandle != IntPtr.Zero)
{
// Unregister first...
RegisterForDeviceChange(false, null);
}
if(Path.GetFileName(fileOnDrive).Length == 0 || !File.Exists(fileOnDrive))
mFileToOpen = null; // use root directory...
else
mFileToOpen = fileOnDrive;
RegisterQuery(Path.GetPathRoot(fileOnDrive));
if(mDeviceNotifyHandle == IntPtr.Zero)
returnfalse; // failed to register
returntrue;
}
publicvoid DisableQueryRemove()
{
if(mDeviceNotifyHandle != IntPtr.Zero)
{
RegisterForDeviceChange(false, null);
}
}
public void Dispose()
{
RegisterForDeviceChange(false, null);
}
#region WindowProc
public void WndProc(ref Message m)
{
intdevType;
charc;
if(m.Msg == WM_DEVICECHANGE)
{
switch(m.WParam.ToInt32())
{
caseDBT_DEVICEARRIVAL:
devType = Marshal.ReadInt32(m.LParam, 4);
if (devType == DBT_DEVTYP_VOLUME)
{
DEV_BROADCAST_VOLUME vol;
vol = (DEV_BROADCAST_VOLUME)
Marshal.PtrToStructure(m.LParam, typeof(DEV_BROADCAST_VOLUME));
c = DriveMaskToLetter(vol.dbcv_unitmask);
USBDetectorEventHandler tempDeviceArrived = DeviceArrived;
if (tempDeviceArrived != null)
{
USBDetectorEventArgs e = newUSBDetectorEventArgs();
e.Drive = c + ":\\";
tempDeviceArrived(this, e);
// Register for query remove if requested
if (e.HookQueryRemove)
{
// If something is already hooked, unhook it now
if (mDeviceNotifyHandle != IntPtr.Zero)
{
RegisterForDeviceChange(false, null);
}
RegisterQuery(c + ":\\");
}
} // if has event handler
}
break;
caseDBT_DEVICEQUERYREMOVE:
devType = Marshal.ReadInt32(m.LParam, 4);
if (devType == DBT_DEVTYP_HANDLE)
{
USBDetectorEventHandler tempQuery = QueryRemove;
if (tempQuery != null)
{
USBDetectorEventArgs e = newUSBDetectorEventArgs();
e.Drive = mCurrentDrive; // drive which is hooked
tempQuery(this, e);
// If the client wants to cancel, let Windows know
if (e.Cancel)
{
m.Result = (IntPtr)BROADCAST_QUERY_DENY;
}
else
{
RegisterForDeviceChange(false, null); // will also close the mFileOnFlash
}
}
}
break;
//
// Device has been removed
//
caseDBT_DEVICEREMOVECOMPLETE:
devType = Marshal.ReadInt32(m.LParam, 4);
if (devType == DBT_DEVTYP_VOLUME)
{
devType = Marshal.ReadInt32(m.LParam, 4);
if (devType == DBT_DEVTYP_VOLUME)
{
DEV_BROADCAST_VOLUME vol;
vol = (DEV_BROADCAST_VOLUME)
Marshal.PtrToStructure(m.LParam, typeof(DEV_BROADCAST_VOLUME));
c = DriveMaskToLetter(vol.dbcv_unitmask);
//
// Call the client event handler
//
USBDetectorEventHandler tempDeviceRemoved = DeviceRemoved;
if (tempDeviceRemoved != null)
{
USBDetectorEventArgs e = newUSBDetectorEventArgs();
e.Drive = c + ":\\";
tempDeviceRemoved(this, e);
}
}
}
break;
}
}
}
#endregion
#region Private Area
privateIntPtr mDirHandle = IntPtr.Zero;
privateFileStream mFileOnFlash = null;
privatestring mFileToOpen;
privateIntPtr mDeviceNotifyHandle;
privateIntPtr mRecipientHandle;
privatestring mCurrentDrive;
privateconst intDBT_DEVTYP_DEVICEINTERFACE = 5;
privateconst intDBT_DEVTYP_HANDLE = 6;
privateconst intBROADCAST_QUERY_DENY = 0x424D5144;
privateconst intWM_DEVICECHANGE = 0x0219;
privateconst intDBT_DEVICEARRIVAL = 0x8000; // system detected a new device
privateconst intDBT_DEVICEQUERYREMOVE = 0x8001; // Preparing to remove (any program can disable the removal)
privateconst intDBT_DEVICEREMOVECOMPLETE = 0x8004; // removed
privateconst intDBT_DEVTYP_VOLUME = 0x00000002; // drive type is logical volume
privatevoid RegisterQuery(stringdrive)
{
boolregister = true;
if(mFileToOpen == null)
{
}
else
{
if(mFileToOpen.Contains(":"))
{
stringtmp = mFileToOpen.Substring(3);
stringroot = Path.GetPathRoot(drive);
mFileToOpen = Path.Combine(root, tmp);
}
else
mFileToOpen = Path.Combine(drive, mFileToOpen);
}
try
{
if(mFileToOpen == null) // open root directory
mFileOnFlash = null;
else
mFileOnFlash = new FileStream(mFileToOpen, FileMode.Open);
}
catch(Exception)
{
// just do not register if the file could not be opened
register = false;
}
if(register)
{
if(mFileOnFlash == null)
RegisterForDeviceChange(drive);
else
// old version
RegisterForDeviceChange(true, mFileOnFlash.SafeFileHandle);
mCurrentDrive = drive;
}
}
privatevoid RegisterForDeviceChange(string dirPath)
{
IntPtrhandle = Native.OpenDirectory(dirPath);
if(handle == IntPtr.Zero)
{
mDeviceNotifyHandle = IntPtr.Zero;
return;
}
else
mDirHandle = handle; // save handle for closing it when unregistering
// Register for handle
DEV_BROADCAST_HANDLEdata = new DEV_BROADCAST_HANDLE();
data.dbch_devicetype = DBT_DEVTYP_HANDLE;
data.dbch_reserved = 0;
data.dbch_nameoffset = 0;
//data.dbch_data = null;
//data.dbch_eventguid = 0;
data.dbch_handle = handle;
data.dbch_hdevnotify = (IntPtr)0;
intsize = Marshal.SizeOf(data);
data.dbch_size = size;
IntPtrbuffer = Marshal.AllocHGlobal(size);
Marshal.StructureToPtr(data, buffer, true);
mDeviceNotifyHandle = Native.RegisterDeviceNotification(mRecipientHandle, buffer, 0);
}
privatevoid RegisterForDeviceChange(bool register, SafeFileHandlefileHandle)
{
if(register)
{
// Register for handle
DEV_BROADCAST_HANDLEdata = new DEV_BROADCAST_HANDLE();
data.dbch_devicetype = DBT_DEVTYP_HANDLE;
data.dbch_reserved = 0;
data.dbch_nameoffset = 0;
//data.dbch_data = null;
//data.dbch_eventguid = 0;
data.dbch_handle = fileHandle.DangerousGetHandle(); //Marshal. fileHandle;
data.dbch_hdevnotify = (IntPtr)0;
intsize = Marshal.SizeOf(data);
data.dbch_size = size;
IntPtrbuffer = Marshal.AllocHGlobal(size);
Marshal.StructureToPtr(data, buffer, true);
mDeviceNotifyHandle = Native.RegisterDeviceNotification(mRecipientHandle, buffer, 0);
}
else
{
// close the directory handle
if(mDirHandle != IntPtr.Zero)
{
Native.CloseDirectoryHandle(mDirHandle);
// string er = Marshal.GetLastWin32Error().ToString();
}
// unregister
if(mDeviceNotifyHandle != IntPtr.Zero)
{
Native.UnregisterDeviceNotification(mDeviceNotifyHandle);
}
mDeviceNotifyHandle = IntPtr.Zero;
mDirHandle = IntPtr.Zero;
mCurrentDrive = "";
if(mFileOnFlash != null)
{
mFileOnFlash.Close();
mFileOnFlash = null;
}
}
}
privatestatic charDriveMaskToLetter(int mask)
{
charletter;
stringdrives = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
// 1 = A
// 2 = B
// 4 = C...
intcnt = 0;
intpom = mask / 2;
while(pom != 0)
{
// while there is any bit set in the mask
// shift it to the righ...
pom = pom / 2;
cnt++;
}
if(cnt < drives.Length)
letter = drives[cnt];
else
letter = '?';
returnletter;
}
#endregion
#region Native Win32 API
/// <summary>
/// WinAPI functions
/// </summary>
privateclass Native
{
// HDEVNOTIFY RegisterDeviceNotification(HANDLE hRecipient,LPVOID NotificationFilter,DWORD Flags);
[DllImport("user32.dll", CharSet = CharSet.Auto)]
publicstatic extern IntPtr RegisterDeviceNotification(IntPtr hRecipient, IntPtrNotificationFilter, uint Flags);
[DllImport("user32.dll", CharSet = CharSet.Auto)]
publicstatic extern uint UnregisterDeviceNotification(IntPtr hHandle);
//
// CreateFile - MSDN
constuint GENERIC_READ = 0x80000000;
constuint OPEN_EXISTING = 3;
constuint FILE_SHARE_READ = 0x00000001;
constuint FILE_SHARE_WRITE = 0x00000002;
constuint FILE_ATTRIBUTE_NORMAL = 128;
constuint FILE_FLAG_BACKUP_SEMANTICS = 0x02000000;
staticreadonly IntPtrINVALID_HANDLE_VALUE = new IntPtr(-1);
// should be "static extern unsafe"
[DllImport("kernel32", SetLastError = true)]
staticextern IntPtrCreateFile(
stringFileName, // file name
uintDesiredAccess, // access mode
uintShareMode, // share mode
uintSecurityAttributes, // Security Attributes
uintCreationDisposition, // how to create
uintFlagsAndAttributes, // file attributes
inthTemplateFile // handle to template file
);
[DllImport("kernel32", SetLastError = true)]
staticextern boolCloseHandle(
IntPtrhObject // handle to object
);
/// <summary>
/// Opens a directory, returns it's handle or zero.
/// </summary>
/// <param name="dirPath">path to the directory, e.g. "C:\\dir"</param>
/// <returns>handle to the directory. Close it with CloseHandle().</returns>
staticpublic IntPtrOpenDirectory(string dirPath)
{
// open the existing file for reading
IntPtrhandle = CreateFile(
dirPath,
GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE,
0,
OPEN_EXISTING,
FILE_FLAG_BACKUP_SEMANTICS | FILE_ATTRIBUTE_NORMAL,
0);
if(handle == INVALID_HANDLE_VALUE)
returnIntPtr.Zero;
else
returnhandle;
}
publicstatic boolCloseDirectoryHandle(IntPtr handle)
{
returnCloseHandle(handle);
}
}
// Structure with information for RegisterDeviceNotification.
[StructLayout(LayoutKind.Sequential)]
public struct DEV_BROADCAST_HANDLE
{
publicint dbch_size;
publicint dbch_devicetype;
publicint dbch_reserved;
publicIntPtr dbch_handle;
publicIntPtr dbch_hdevnotify;
publicGuid dbch_eventguid;
publiclong dbch_nameoffset;
//public byte[] dbch_data[1]; // = new byte[1];
publicbyte dbch_data;
publicbyte dbch_data1;
}
// Struct for parameters of the WM_DEVICECHANGE message
[StructLayout(LayoutKind.Sequential)]
public struct DEV_BROADCAST_VOLUME
{
publicint dbcv_size;
publicint dbcv_devicetype;
publicint dbcv_reserved;
publicint dbcv_unitmask;
}
#endregion
}
UsbDetectorEventArgsusing System;
usingSystem.Collections.Generic;
using System.Linq;
using System.Text;
namespace USB_Detector
{
// Delegate for event handler to handle the device events
public delegatevoid USBDetectorEventHandler(Object sender, USBDetectorEventArgse);
/// <summary>
/// Our class for passing in custom arguments to our event handlers
///
/// </summary>
public classUSBDetectorEventArgs : EventArgs
{
publicUSBDetectorEventArgs()
{
Cancel = false;
Drive = "";
HookQueryRemove = false;
}
/// <summary>
/// Get/Set the value indicating that the event should be cancelled
/// Only in QueryRemove handler.
/// </summary>
public bool Cancel;
/// <summary>
/// Drive letter for the device which caused this event
/// </summary>
public string Drive;
/// <summary>
/// Set to true in your DeviceArrived event handler if you wish to receive the
/// QueryRemove event for this drive.
/// </summary>
public bool HookQueryRemove;
}
}
Now create a Form which is invisble at runtime because we need a WndProc to get the Notification from the Native OS.
public partial class DriveForm : Form
{
publicDriveForm()
{
}
private Labellabel1;
private USBDetectormDetector = null;
/// <summary>
/// Set up the hidden form.
/// </summary>
/// <param name="detector">DriveDetector object which will receive notification about USB drives, see WndProc</param>
public DriveForm(USBDetectordetector)
{
mDetector = detector;
this.MinimizeBox = false;
this.MaximizeBox = false;
this.ShowInTaskbar = false;
this.ShowIcon = false;
this.FormBorderStyle = FormBorderStyle.None;
this.Load += newSystem.EventHandler(this.Load_Form);
this.Activated += newEventHandler(this.Form_Activated);
}
/// <summary>
/// This function receives all the windows messages for this window (form).
/// We call the DriveDetector from here so that is can pick up the messages about
/// drives arrived and removed.
/// </summary>
protected override void WndProc(ref Message m)
{
base.WndProc(ref m);
if (mDetector != null)
{
mDetector.WndProc(ref m);
}
}
private voidLoad_Form(object sender, EventArgs e)
{
InitializeComponent();
this.Size = newSystem.Drawing.Size(5, 5);
}
private voidForm_Activated(object sender, EventArgs e)
{
this.Visible = false;
}
}
From this article you will get some interesting tool to get notify for portable devices plug in computer.