jiing's c# collection

Friday, August 12, 2005

.Net code to Detect When an External Drive is Mounted?

REF: http://0rz.net/530xD

Here you go. I know that this code works for CD removal/insertion. I
haven't tested it for other devices, but it really ought to work.

using System;
using System.IO;
using System.Runtime.InteropServices;

namespace Whatever {

public class HookEventArgs : EventArgs {
public int HookCode;
public IntPtr wParam;
public IntPtr lParam;

}

// Hook Types
public enum HookType : int {
WH_JOURNALRECORD = 0,
WH_JOURNALPLAYBACK = 1,
WH_KEYBOARD = 2,
WH_GETMESSAGE = 3,
WH_CALLWNDPROC = 4,
WH_CBT = 5,
WH_SYSMSGFILTER = 6,
WH_MOUSE = 7,
WH_HARDWARE = 8,
WH_DEBUG = 9,
WH_SHELL = 10,
WH_FOREGROUNDIDLE = 11,
WH_CALLWNDPROCRET = 12,
WH_KEYBOARD_LL = 13,
WH_MOUSE_LL = 14

}

///


/// Summary description for Win32Hooks.
///

public class Win32Hook {

public delegate int HookProc(int code, IntPtr wParam, IntPtr
lParam);

protected IntPtr m_hhook = IntPtr.Zero;
protected HookProc m_filterFunc = null;
protected HookType m_hookType;

public delegate void HookEventHandler(object sender, HookEventArgs
e);

public event HookEventHandler HookInvoked;
protected void OnHookInvoked(HookEventArgs e) {
if (HookInvoked != null) {
HookInvoked(this, e);

}
}

public Win32Hook(HookType hook) {
m_hookType = hook;
m_filterFunc = new HookProc(this.CoreHookProc);
}

public Win32Hook(HookType hook, HookProc func) {
m_hookType = hook;
m_filterFunc = func;

}

public int CoreHookProc(int code, IntPtr wParam, IntPtr lParam) {

if (code < 0) {
return CallNextHookEx(m_hhook, code, wParam, lParam);

}

HookEventArgs e = new HookEventArgs();
e.HookCode = code;
e.wParam = wParam;
e.lParam = lParam;
OnHookInvoked(e);

return CallNextHookEx(m_hhook, code, wParam, lParam);

} // CoreHookProc

public void Install() {

m_hhook = SetWindowsHookEx(m_hookType, m_filterFunc, IntPtr.Zero,
(int) AppDomain.GetCurrentThreadId());

}

public void Uninstall() {
UnhookWindowsHookEx(m_hhook);

}

#region Win32 Imports
[DllImport("user32.dll")]
protected static extern IntPtr SetWindowsHookEx(HookType code,
HookProc func, IntPtr hInstance, int threadID);

[DllImport("user32.dll")]
protected static extern int UnhookWindowsHookEx(IntPtr hhook);

[DllImport("user32.dll")]
protected static extern int CallNextHookEx(IntPtr hhook, int code,
IntPtr wParam, IntPtr lParam);
#endregion

}

public class DeviceChangeEventArgs {
public string drive;
public DirectoryInfo driveInfo;
public IntPtr eventHwnd;

}

public class DeviceChangeHook : Win32Hook {
const int WM_DEVICECHANGE = 0x0219;
private static IntPtr _forHWnd;
public static IntPtr ForHWnd {
get {
return DeviceChangeHook._forHWnd;

}

set {
DeviceChangeHook._forHWnd = value;

}
}

protected enum DbtHookActions {
DeviceArrival = 0x8000,
DeviceRemoveComplete = 0x8004

}

[StructLayout(LayoutKind.Sequential)]
protected class DevBroadcastVolume {
public int dbcv_size;
public int dbcv_devicetype;
public int dbcv_reserved;
public int dbcv_unitmask;
public short dbcv_flags;

}

// class cwp maps the unmanaged Win32 struct CWPSTRUCT that is
declared in
// winuser.h
// See
http://msdn.microsoft.com/libr ary/default.asp?url=/library/e n-us/winu...
[StructLayout(LayoutKind.Sequential)]
protected class cwp {
public IntPtr lParam;
public int wParam;
public ushort message;
public IntPtr hwnd;

}

public delegate void DeviceChangeEventHandler(object sender,
DeviceChangeEventArgs dce);
public event DeviceChangeEventHandler DeviceArrived;
public event DeviceChangeEventHandler DeviceRemoved;

static DeviceChangeHook() {
DeviceChangeHook._forHWnd = IntPtr.Zero;

}

public DeviceChangeHook() : base(HookType.WH_CALLWNDPROC) {
this.HookInvoked += new HookEventHandler(GetMessageHookInvoked);

}

public DeviceChangeHook(HookProc func) :
base(HookType.WH_CALLWNDPROC, func) {
this.HookInvoked += new HookEventHandler(GetMessageHookInvoked);

}

private void GetMessageHookInvoked(object sender, HookEventArgs he)
{

cwp eventMessage = new cwp();
eventMessage = (cwp) Marshal.PtrToStructure(he.lParam,
eventMessage.GetType());
if ((eventMessage.message == 0x0219) && (eventMessage.hwnd ==
DeviceChangeHook._forHWnd)) {
DbtHookActions action = (DbtHookActions) eventMessage.wParam;
DevBroadcastVolume eventInfo = new DevBroadcastVolume();
eventInfo = (DevBroadcastVolume)
Marshal.PtrToStructure(eventMessage.lParam, eventInfo.GetType());

DeviceChangeEventArgs changeArgs = new DeviceChangeEventArgs();

switch (action) {
case DbtHookActions.DeviceArrival:
changeArgs.drive =
decodeDriveLetter(eventInfo.dbcv_unitmask);
changeArgs.driveInfo = new DirectoryInfo(changeArgs.drive +
":\\");
changeArgs.eventHwnd = eventMessage.hwnd;
DeviceArrived(this, changeArgs);
break;
case DbtHookActions.DeviceRemoveComplete:
changeArgs.drive =
decodeDriveLetter(eventInfo.dbcv_unitmask);
changeArgs.driveInfo = null;
changeArgs.eventHwnd = eventMessage.hwnd;
DeviceRemoved(this, changeArgs);
break;
default:
break;

} // switch
}
} // GetMessageHookInvoked

protected string decodeDriveLetter(int unitMask) {

char driveLetter;
for (driveLetter = 'A'; driveLetter <= 'Z'; ++driveLetter) {
if ((unitMask & 0x1) == 0x1)
break;
unitMask = unitMask >> 1;

}

if (driveLetter > 'Z') // Catch any unitMask failure
driveLetter = '0';

return driveLetter.ToString();

0 Comments:

Post a Comment

<< Home