using DetectDrive;
using System.IO;
namespace SimpleDetector
{
public partial class Form1 : Form
{
private DriveDetector driveDetector = null;
public Form1()
{
InitializeComponent();
driveDetector = new DriveDetector(this);
driveDetector.DeviceArrived += new DriveDetectorEventHandler(OnDriveArrived);
driveDetector.DeviceRemoved += new DriveDetectorEventHandler(OnDriveRemoved);
driveDetector.QueryRemove += new DriveDetectorEventHandler(OnQueryRemove);
}
// Called by DriveDetector when removable device in inserted
private void OnDriveArrived(object sender, DriveDetectorEventArgs e)
{
// Report the event in the listbox.
// e.Drive is the drive letter for the device which just arrived, e.g. "E:\\"
listBox1.Items.Clear();
string s = "Drive arrived " + e.Drive;
listBox1.Items.Add(s);
MessageBox.Show(e.Drive.ToString());
// If you want to be notified when drive is being removed (and be able to cancel it),
// set HookQueryRemove to true
if ( checkBoxAskMe.Checked )
e.HookQueryRemove = true;
}
// Called by DriveDetector after removable device has been unpluged
private void OnDriveRemoved(object sender, DriveDetectorEventArgs e)
{
// TODO: do clean up here, etc. Letter of the removed drive is in e.Drive;
// Just add report to the listbox
listBox1.Items.Clear();
string s = "Drive removed " + e.Drive;
listBox1.Items.Add(s);
}
// Called by DriveDetector when removable drive is about to be removed
private void OnQueryRemove(object sender, DriveDetectorEventArgs e)
{
// Should we allow the drive to be unplugged?
if (checkBoxAskMe.Checked)
{
if (MessageBox.Show("Allow remove?", "Query remove",
MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
e.Cancel = false; // Allow removal
else
e.Cancel = true; // Cancel the removal of the device
}
}
protected override void WndProc(ref Message m)
{
base.WndProc(ref m); // call default p
if (driveDetector != null)
{
driveDetector.WndProc(ref m);
}
}
// User checked the "Ask me before drive can be disconnected box"
private void checkBoxAskMe_CheckedChanged(object sender, EventArgs e)
{
if (checkBoxAskMe.Checked)
{
// Is QueryRemove enabled?
// If not, we will enable it for the drive which is selected
// in the listbox.
// If the listbox is empty, no drive has been detected yet so do nothing now.
if (!driveDetector.IsQueryHooked && listBox1.Items.Count > 0)
{
if (listBox1.SelectedItem == null)
{
MessageBox.Show("Please choose the drive for which you wish to be asked in the list (select its message).");
checkBoxAskMe.Checked = false;
return;
}
bool ok = false;
string s = (string)listBox1.SelectedItem;
int n = s.IndexOf(':');
if (n > 0)
{
s = s.Substring(n - 1, 3); // Gets drive letter from the message, (e.g. "E:\\")
// Tell DriveDetector to monitor this drive
ok = driveDetector.EnableQueryRemove(s);
}
if (!ok)
MessageBox.Show("Sorry, for some reason notification for QueryRemove did not work out.");
}
}
else
{
if (driveDetector.IsQueryHooked)
driveDetector.DisableQueryRemove();
}
}
2/2
[CODE]
using System.Windows.Forms; // required for Message
using System.Runtime.InteropServices; // required for Marshal
using System.IO;
using Microsoft.Win32.SafeHandles;
namespace DetectDrive
{
// Delegate for event handler to handle the device events
public delegate void DriveDetectorEventHandler(Object sender, DriveDetectorEventArgs e);
public class DriveDetectorEventArgs : EventArgs
{
public DriveDetectorEventArgs()
{
Cancel = false;
Drive = "";
HookQueryRemove = false;
}
public bool Cancel;
public string Drive;
public bool HookQueryRemove;
}
class DriveDetector : IDisposable
{
public event DriveDetectorEventHandler DeviceArrived;
public event DriveDetectorEventHandler DeviceRemoved;
public event DriveDetectorEventHandler QueryRemove;
public string HookedDrive
{
get
{
return mCurrentDrive;
}
}
public FileStream OpenedFile
{
get
{
return mFileOnFlash;
}
}
public bool EnableQueryRemove(string fileOnDrive)
{
if (fileOnDrive == null || fileOnDrive.Length == 0)
throw new 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)
{
RegisterForDeviceChange(false, null);
}
if (!File.Exists(fileOnDrive))
mFileToOpen = null; // use any file
else
mFileToOpen = fileOnDrive;
RegisterQuery(Path.GetPathRoot(fileOnDrive));
if (mDeviceNotifyHandle == IntPtr.Zero)
return false; // failed to register
return true;
}
public void DisableQueryRemove()
{
if (mDeviceNotifyHandle != IntPtr.Zero)
{
RegisterForDeviceChange(false, null);
}
}
public void Dispose()
{
RegisterForDeviceChange(false, null);
}
#region WindowProc
public void WndProc(ref Message m)
{
int devType;
char c;
if (m.Msg == WM_DEVICECHANGE)
{
// WM_DEVICECHANGE can have several meanings depending on the WParam value...
switch (m.WParam.ToInt32())
{
//
// New device has just arrived
//
case DBT_DEVICEARRIVAL:
// Get the drive letter
c = DriveMaskToLetter(vol.dbcv_unitmask);
if ( tempDeviceArrived != null )
{
DriveDetectorEventArgs e = new DriveDetectorEventArgs();
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;
case DBT_DEVICEQUERYREMOVE:
devType = Marshal.ReadInt32(m.LParam, 4);
if (devType == DBT_DEVTYP_HANDLE)
{
DriveDetectorEventHandler tempQuery = QueryRemove;
if (tempQuery != null)
{
DriveDetectorEventArgs e = new DriveDetectorEventArgs();
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
{
// Close the handle so that the drive can be unmounted
if (mFileOnFlash != null)
{
mFileOnFlash.Close();
mFileOnFlash = null;
}
}
}
}
break;
//
// Device has been removed
//
case DBT_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);
DriveDetectorEventHandler tempDeviceRemoved = DeviceRemoved;
if (tempDeviceRemoved != null)
{
DriveDetectorEventArgs e = new DriveDetectorEventArgs();
e.Drive = c + ":\\";
tempDeviceRemoved(this, e);
}
// Win32 constants
private const int DBT_DEVTYP_DEVICEINTERFACE = 5;
private const int DBT_DEVTYP_HANDLE = 6;
private const int BROADCAST_QUERY_DENY = 0x424D5144;
private const int WM_DEVICECHANGE = 0x0219;
private const int DBT_DEVICEARRIVAL = 0x8000; // system detected a new device
private const int DBT_DEVICEQUERYREMOVE = 0x8001; // Preparing to remove (any program can disable the removal)
private const int DBT_DEVICEREMOVECOMPLETE = 0x8004; // removed
private const int DBT_DEVTYP_VOLUME = 0x00000002; // drive type is logical volume
if (mFileToOpen == null)
{
// If client gave us no file, let's pick one on the drive...
mFileToOpen = GetAnyFile(drive);
if (mFileToOpen.Length == 0)
return; // no file found on the flash drive
}
else
{
try
{
mFileOnFlash = new FileStream(mFileToOpen, FileMode.Open);
}
catch (Exception)
{
// just do not register if the file could not be opened
register = false;
}
if (register)
{
RegisterForDeviceChange(true, mFileOnFlash.SafeFileHandle);
mCurrentDrive = drive;
}
}
private static char DriveMaskToLetter(int mask)
{
char letter;
string drives = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
// 1 = A
// 2 = B
// 4 = C...
int cnt = 0;
int pom = 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 = '?';
return letter;
}
private string GetAnyFile(string drive)
{
string file = "";
// First try files in the root
string[] files = Directory.GetFiles(drive);
if (files.Length == 0)
{
// if no file in the root, search whole drive
files = Directory.GetFiles(drive, "*.*", SearchOption.AllDirectories);
}
if (files.Length > 0)
file = files[0]; // get the first file
// return empty string if no file found
return file;
}
#endregion
#region Native Win32 API
private class Native
{
// HDEVNOTIFY RegisterDeviceNotification(HANDLE hRecipient,LPVOID NotificationFilter,DWORD Flags);
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr RegisterDeviceNotification(IntPtr hRecipient, IntPtr NotificationFilter, uint Flags);
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern uint UnregisterDeviceNotification(IntPtr hHandle);
}
// Structure with information for RegisterDeviceNotification.
[StructLayout(LayoutKind.Sequential)]
public struct DEV_BROADCAST_HANDLE
{
public int dbch_size;
public int dbch_devicetype;
public int dbch_reserved;
public IntPtr dbch_handle;
public IntPtr dbch_hdevnotify;
public Guid dbch_eventguid;
public long dbch_nameoffset;
//public byte[] dbch_data[1]; // = new byte[1];
public byte dbch_data;
public byte dbch_data1;
}
// Struct for parameters of the WM_DEVICECHANGE message
[StructLayout(LayoutKind.Sequential)]
public struct DEV_BROADCAST_VOLUME
{
public int dbcv_size;
public int dbcv_devicetype;
public int dbcv_reserved;
public int dbcv_unitmask;
}
#endregion
}
}
[/CODE]
before my head breaks...
i think i found what im lookin for, my next step now is how could i search all files including subfolders (considering i don't know the folder names)in the USB storage since it is obvious that i already know the drive letter?
below is helpful but you must specify the folder names
foreach (string filepath in System.IO.Directory.GetFiles(@"C:\folder" , "*.txt", System.IO.SearchOption.AllDirectories))
sorry for many texts i just wanna share the code for future reference.
below is helpful but you must specify the folder names
foreach (string filepath in System.IO.Directory.GetFiles(@"C:\folder" , "*.txt", System.IO.SearchOption.AllDirectories))
for searching drive with directories i found this on microsoft's website
void DirSearch(string sDir)
{
try
{
foreach (string d in Directory.GetDirectories(sDir))
{
foreach (string f in Directory.GetFiles(d, txtFile.Text))
{
lstFilesFound.Items.Add(f);
}
DirSearch(d);
}
}
catch (System.Exception excpt)
{
Console.WriteLine(excpt.Message);
}
}
tnx to you people!
"don't do to other people if you don't want to experience what you did"
ok tnx, anyway that's why i'm doing this project is because
we issued several usb's our point is contents on the usb must be legal files
e.g. .xls, ppt, .doc, .odt and other than that it will not permitted.
i don't exactly how to detect in COM ports, as an example is when you insert a device in COM1 or COM2 nothing happens right? so where could i find the trigger?
but in your code you can specify whether it is COM1 or COM2, about in USB see the attachment i've searched this for you,
hope it would help.
how would i know if the USB Storage device is inserted
and determine the drive letter?
it can be D:, E:, F: and etc.
i just want to know if it is inserted and i want to know what drive letter it is?
i always used this function:
Code:
Declare Function GetDriveType& Lib "kernel32" Alias "GetDriveTypeA" (ByVal _
nDrive As String)
you pass it a drive letter and colon and it returns a number depending on what kind of drive it is.
If you run it with a loop through every drive letter, you will be able to pick out removable storage easy.
that's what the function is for.
[quote:=Desaware Visual Basic Programmer's Guide to the Win32 api]
The GetdriveType function has a return value that is a Long—Zero if the drive cannot be identified. One if the specified directory does not exist. One of the constants DRIVE_REMOVABLE, DRIVE_FIXED, DRIVE_REMOTE, DRIVE_CDROM or DRIVE_RAMDISK specifying the drive type on success
[/quote]
call it like this:
msgbox getdrivetype("c:")
If you pass it an invalid drive, the function returns a 1.
Here are the values of the constants:
Code:
Public Const DRIVE_CDROM = 5
Public Const DRIVE_FIXED = 3
Public Const DRIVE_RAMDISK = 6
Public Const DRIVE_REMOTE = 4
Public Const DRIVE_REMOVABLE = 2
A jump drive should be listed as 2. A floppy disk or tape drive is also a 2, but you can eliminate them easily by not checking A or B. I've never used a zip drive, so i don't know what they have for a drive letter, so it might not stop them. But filesystem checks can work too.
It's what i used in a project of mine. I created a program in VB6 to do all of this:
1. read a cd or dvd directory structure as deep as you want to and store it as a searchable file
2. allow you to add notes on each file and add a description for the disk.
3. allow you to navigate the stored directory tree like in explorer.
4. search for keywords both in the entire file list or just in the description of the disk
5. automatically assign id numbers for the read disks for you to mark on the disk.
Program works fine and i still have it, although i will be the first to admit it has a very unusual user interface. If you right-click on a button, a context menu (which is really a hidden frame) appears with options for that button.
The part i use it for is this: when you right click the import button, among other options is a image combo loaded with a list of all your cd drives to choose from.
Program works fine and i still have it, although i will be the first to admit it has a very unusual user interface. If you right-click on a button, a context menu (which is really a hidden frame) appears with options for that button.
The part i use it for is this: when you right click the import button, among other options is a image combo loaded with a list of all your cd drives to choose from.
This part make sense to me. Do you have any idea, how that hidden frame is work. I mean any special logic there.
“victory breeds hatred, the defeated live in pain; happily the peaceful live giving up victory and defeat” - Gautama Buddha
no special logic. It was murder to design in the IDE though. It just simply showed the frame on right click, and the frame had a close-x in the corner.