I created a service and run the code for the USb is connected and the eventType is "DBT_DEVICEARRIVAL
" is hitted and when we "Eject the Usb" and the eventType is "DBT_DEVICEQUERYREMOVE
" is hitted but the safely remove is not working.
It showing the message as
"this device is currently in use. close any programs or windows that might be using the device, and then try again"
My Code is:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using System.Runtime.InteropServices;
using System.IO;
using System.Threading;
namespace UsbService
{
public partial class EntredaUsbService : ServiceBase
{
public static string log_path = AppDomain.CurrentDomain.BaseDirectory.ToString() + "\\Usbservice.log";
static string deviceid = "";
static string path = "";
static long oldstamp;
static long oldstamp1;
static string create;
public static long usbval = 0;
public static string drivecaption = "";
public static long setdrive = 0;
private IntPtr deviceNotifyHandle;
private IntPtr deviceEventHandle;
private IntPtr directoryHandle;
public static int prev_control = 0;
public static int prev_eventtype = 0;
private Win32.ServiceControlHandlerEx myCallback;
private int ServiceControlHandler(int control, int eventType, IntPtr eventData, IntPtr context)
{
File.AppendAllText(log_path, "Entered into ServiceControlHandler" + Environment.NewLine);
File.AppendAllText(log_path, "Control is : " + control + "event type is :" + eventType + "event data is :" + eventData + "context is : " + context + Environment.NewLine);
while (eventType != prev_eventtype)
{
prev_eventtype = eventType;
prev_control = control;
if (control == Win32.SERVICE_CONTROL_STOP || control == Win32.SERVICE_CONTROL_SHUTDOWN)
{
UnregisterHandles();
Win32.UnregisterDeviceNotification(deviceEventHandle);
File.AppendAllText(log_path, "Stopping or shutdown the service" + Environment.NewLine);
base.Stop();
}
else if (control == Win32.SERVICE_CONTROL_DEVICEEVENT)
{
FileSystemWatcher fileSystemWatcher = new FileSystemWatcher();
File.AppendAllText(log_path, "Control is : " + control + "event type is before switch :" + eventType);
switch (eventType)
{
case Win32.DBT_DEVICEQUERYREMOVE:
File.AppendAllText(log_path, "Eventtype is DBT_DEVICEQUERYREMOVE" + Environment.NewLine);
fileSystemWatcher.EnableRaisingEvents = false;
// fileSystemWatcher.Dispose();
UnregisterHandles();
File.AppendAllText(log_path, "fswatcher raising events are :" + fileSystemWatcher.EnableRaisingEvents + Environment.NewLine);
break;
case Win32.DBT_DEVICEREMOVECOMPLETE:
File.AppendAllText(log_path, "Eventtype is DBT_DEVICEREMOVECOMPLETE" + Environment.NewLine);
break;
case Win32.DBT_DEVICEARRIVAL:
string driveLetter = "";
File.AppendAllText(log_path, "Entered into DBT_DEVICEARRIVAL" + Environment.NewLine);
Win32.DEV_BROADCAST_HDR hdr;
hdr = (Win32.DEV_BROADCAST_HDR)
Marshal.PtrToStructure(eventData, typeof(Win32.DEV_BROADCAST_HDR));
if (hdr.dbcc_devicetype == Win32.DBT_DEVTYP_DEVICEINTERFACE)
{
File.AppendAllText(log_path, "Hdr.dbcc_devicetype is :" + hdr.dbcc_devicetype + Environment.NewLine);
Win32.DEV_BROADCAST_DEVICEINTERFACE deviceInterface;
deviceInterface = (Win32.DEV_BROADCAST_DEVICEINTERFACE)
Marshal.PtrToStructure(eventData, typeof(Win32.DEV_BROADCAST_DEVICEINTERFACE));
var usbdrives = DriveInfo.GetDrives();
foreach (var usbdrive in usbdrives)
{
if (usbdrive.DriveType == DriveType.Removable)
{
// string drivepah = usbdrive.Name;
driveLetter = usbdrive.Name;
File.AppendAllText(log_path, "Drive letter is : " + driveLetter + Environment.NewLine);
}
}
/*
if (!Win32.GetVolumePathNamesForVolumeNameW(stringBuilder.ToString(), driveLetter, stringReturnLength, ref stringReturnLength))
{
File.AppendAllText(log_path, "getvolume is null" + Environment.NewLine);
}
*/
RegisterForHandle(driveLetter[0]);
// usbdrives = DriveInfo.GetDrives();
// foreach (var usbdrive in usbdrives)
{
// if (usbdrive.DriveType == DriveType.Removable)
{
// File.AppendAllText(log_path, "USBDrive:" + usbdrive.Name);
// string drivepath = usbdrive.Name;
fileSystemWatcher.Path = driveLetter;
File.AppendAllText(log_path, "Drive path is :" + driveLetter + Environment.NewLine);
fileSystemWatcher.NotifyFilter = NotifyFilters.Size | NotifyFilters.FileName | NotifyFilters.DirectoryName;
fileSystemWatcher.IncludeSubdirectories = true;
fileSystemWatcher.Filter = "*.*";
fileSystemWatcher.InternalBufferSize = 1321440;
fileSystemWatcher.Created += new System.IO.FileSystemEventHandler(fileSystemWatcher_Created);
fileSystemWatcher.Deleted += new System.IO.FileSystemEventHandler(fileSystemWatcher_Deleted);
fileSystemWatcher.Changed += new System.IO.FileSystemEventHandler(fileSystemWatcher_Changed);
fileSystemWatcher.Renamed += new System.IO.RenamedEventHandler(fileSystemWatcher_Renamed);
fileSystemWatcher.EnableRaisingEvents = true;
File.AppendAllText(log_path, "fswatcher raising events are: " + fileSystemWatcher.EnableRaisingEvents + Environment.NewLine);
}
}
}
break;
}
}
}
return 0;
}
private void UnregisterHandles()
{
File.AppendAllText(log_path, "Entered into UnregisterHandles" + Environment.NewLine);
File.AppendAllText(log_path, "directory handle : " + directoryHandle + " devicenotifyhandle : " + deviceNotifyHandle + Environment.NewLine);
if (directoryHandle != IntPtr.Zero)
{
bool k = Win32.CloseHandle(directoryHandle);
File.AppendAllText(log_path, "Close handle return : " + k + Environment.NewLine);
directoryHandle = IntPtr.Zero;
}
if (deviceNotifyHandle != IntPtr.Zero)
{
uint k = Win32.UnregisterDeviceNotification(deviceNotifyHandle);
File.AppendAllText(log_path, "UnregisterDeviceNotification return : " + k + Environment.NewLine);
deviceNotifyHandle = IntPtr.Zero;
}
}
private void RegisterForHandle(char c)
{
File.AppendAllText(log_path, "Register to handle and char c is :" + c + Environment.NewLine);
Win32.DEV_BROADCAST_HANDLE deviceHandle = new Win32.DEV_BROADCAST_HANDLE();
File.AppendAllText(log_path, "Device handle is : " + deviceHandle + Environment.NewLine);
int size = Marshal.SizeOf(deviceHandle);
deviceHandle.dbch_size = size;
deviceHandle.dbch_devicetype = Win32.DBT_DEVTYP_HANDLE;
directoryHandle = CreateFileHandle(c + ":\\");
File.AppendAllText(log_path, "Directory handle : " + directoryHandle + Environment.NewLine);
deviceHandle.dbch_handle = directoryHandle;
IntPtr buffer = Marshal.AllocHGlobal(size);
Marshal.StructureToPtr(deviceHandle, buffer, true);
deviceNotifyHandle = Win32.RegisterDeviceNotification(this.ServiceHandle, buffer, Win32.DEVICE_NOTIFY_SERVICE_HANDLE);
if (deviceNotifyHandle == IntPtr.Zero)
{
File.AppendAllText(log_path, "DeviceNotifyhandle is null" + Environment.NewLine);
}
else
{
File.AppendAllText(log_path, "DeviceNotifyHandle is : " + deviceNotifyHandle + Environment.NewLine);
}
}
private void RegisterDeviceNotification(string logpath)
{
File.AppendAllText(logpath, "Entered into RegisterDeviceNotification" + Environment.NewLine);
// while (true)
{
myCallback = new Win32.ServiceControlHandlerEx(ServiceControlHandler);
IntPtr m = Win32.RegisterServiceCtrlHandlerEx(this.ServiceName, myCallback, IntPtr.Zero);
File.AppendAllText(logpath, "Register m value : " + m + Environment.NewLine);
}
if (this.ServiceHandle == IntPtr.Zero)
{
File.AppendAllText(logpath, "Service Handle is null" + Environment.NewLine);
}
else
{
File.AppendAllText(logpath, "Service handle is :" + this.ServiceHandle + Environment.NewLine);
}
Win32.DEV_BROADCAST_DEVICEINTERFACE deviceInterface = new Win32.DEV_BROADCAST_DEVICEINTERFACE();
File.AppendAllText(logpath, "Device Interface is :" + deviceInterface + Environment.NewLine);
int size = Marshal.SizeOf(deviceInterface);
deviceInterface.dbcc_size = size;
deviceInterface.dbcc_devicetype = Win32.DBT_DEVTYP_DEVICEINTERFACE;
IntPtr buffer = default(IntPtr);
buffer = Marshal.AllocHGlobal(size);
Marshal.StructureToPtr(deviceInterface, buffer, true);
deviceEventHandle = Win32.RegisterDeviceNotification(this.ServiceHandle, buffer, Win32.DEVICE_NOTIFY_SERVICE_HANDLE | Win32.DEVICE_NOTIFY_ALL_INTERFACE_CLASSES);
if (deviceEventHandle == IntPtr.Zero)
{
File.AppendAllText(logpath, "DeviceEventHandle is null" + Environment.NewLine);
}
else
{
File.AppendAllText(logpath, "DeviceEventHandle is : " + deviceEventHandle + Environment.NewLine);
}
}
public EntredaUsbService()
{
InitializeComponent();
}
void fileSystemWatcher_Created(object sender, System.IO.FileSystemEventArgs e)
{
File.AppendAllText(log_path, "Entered into fswatcher_created" + Environment.NewLine);
}
void fileSystemWatcher_Renamed(object sender, System.IO.RenamedEventArgs e)
{
File.AppendAllText(log_path, "Entered into fswatcher_renamed" + Environment.NewLine);
}
void fileSystemWatcher_Changed(object sender, System.IO.FileSystemEventArgs e)
{
File.AppendAllText(log_path, "Entered into fswatcher_changed" + Environment.NewLine);
}
void fileSystemWatcher_Deleted(object sender, System.IO.FileSystemEventArgs e)
{
File.AppendAllText(log_path, "Entered into fswatcher_deleted" + Environment.NewLine);
}
public static IntPtr CreateFileHandle(string driveLetter)
{
// open the existing file for reading
IntPtr handle = Win32.CreateFile(
driveLetter,
Win32.GENERIC_READ,
Win32.FILE_SHARE_READ | Win32.FILE_SHARE_WRITE,
0,
Win32.OPEN_EXISTING,
Win32.FILE_FLAG_BACKUP_SEMANTICS | Win32.FILE_ATTRIBUTE_NORMAL,
0);
if (handle == Win32.INVALID_HANDLE_VALUE)
{
File.AppendAllText(log_path, "Return handle is null" + Environment.NewLine);
return IntPtr.Zero;
}
else
{
File.AppendAllText(log_path, "Return handle is :" + handle + Environment.NewLine);
return handle;
}
}
protected override void OnStart(string[] args)
{
base.OnStart(args);
//while (true)
{
File.WriteAllText(log_path, "Just entered to onstart for usbservice" + Environment.NewLine);
RegisterDeviceNotification(log_path);
File.AppendAllText(log_path, "Register Device Notification is ended" + Environment.NewLine);
Win32.ServiceControlHandlerEx mycall = new Win32.ServiceControlHandlerEx(ServiceControlHandler);
Win32.RegisterServiceCtrlHandlerEx(this.ServiceName, mycall, IntPtr.Zero);
File.AppendAllText(log_path, "End" + Environment.NewLine);
}
}
public class Win32
{
public const int DEVICE_NOTIFY_SERVICE_HANDLE = 1;
public const int DEVICE_NOTIFY_ALL_INTERFACE_CLASSES = 4;
public const int SERVICE_CONTROL_STOP = 1;
public const int SERVICE_CONTROL_DEVICEEVENT = 11;
public const int SERVICE_CONTROL_SHUTDOWN = 5;
public const uint GENERIC_READ = 0x80000000;
public const uint OPEN_EXISTING = 3;
public const uint FILE_SHARE_READ = 1;
public const uint FILE_SHARE_WRITE = 2;
public const uint FILE_SHARE_DELETE = 4;
public const uint FILE_ATTRIBUTE_NORMAL = 128;
public const uint FILE_FLAG_BACKUP_SEMANTICS = 0x02000000;
public static readonly IntPtr INVALID_HANDLE_VALUE = new IntPtr(-1);
public const int DBT_DEVTYP_DEVICEINTERFACE = 5;
public const int DBT_DEVTYP_HANDLE = 6;
public const int DBT_DEVICEARRIVAL = 0x8000;
public const int DBT_DEVICEQUERYREMOVE = 0x8001;
public const int DBT_DEVICEREMOVECOMPLETE = 0x8004;
public const int WM_DEVICECHANGE = 0x219;
public delegate int ServiceControlHandlerEx(int control, int eventType, IntPtr eventData, IntPtr context);
[DllImport("advapi32.dll", SetLastError = true)]
public static extern IntPtr RegisterServiceCtrlHandlerEx(string lpServiceName, ServiceControlHandlerEx cbex, IntPtr context);
[DllImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool GetVolumePathNamesForVolumeNameW(
[MarshalAs(UnmanagedType.LPWStr)]
string lpszVolumeName,
[MarshalAs(UnmanagedType.LPWStr)]
string lpszVolumePathNames,
uint cchBuferLength,
ref UInt32 lpcchReturnLength);
[DllImport("kernel32.dll")]
public static extern bool GetVolumeNameForVolumeMountPoint(string
lpszVolumeMountPoint, [Out] StringBuilder lpszVolumeName,
uint cchBufferLength);
[DllImport("user32.dll", SetLastError = true)]
public static extern IntPtr RegisterDeviceNotification(IntPtr IntPtr, IntPtr NotificationFilter, Int32 Flags);
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern uint UnregisterDeviceNotification(IntPtr hHandle);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern IntPtr CreateFile(
string FileName, // file name
uint DesiredAccess, // access mode
uint ShareMode, // share mode
uint SecurityAttributes, // Security Attributes
uint CreationDisposition, // how to create
uint FlagsAndAttributes, // file attributes
int hTemplateFile // handle to template file
);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool CloseHandle(IntPtr hObject);
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct DEV_BROADCAST_DEVICEINTERFACE
{
public int dbcc_size;
public int dbcc_devicetype;
public int dbcc_reserved;
[MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.U1, SizeConst = 16)]
public byte[] dbcc_classguid;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)]
public char[] dbcc_name;
}
[StructLayout(LayoutKind.Sequential)]
public struct DEV_BROADCAST_HDR
{
public int dbcc_size;
public int dbcc_devicetype;
public int dbcc_reserved;
}
[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;
public byte dbch_data1;
}
}
Call HDEVNOTIFY RegisterDeviceNotification(HANDLE hRecipient,
LPVOID NotificationFilter,DWORD Flags);
https://www.codeproject.com/Articles/18062/Detecting-USB-Drive-Removal-in-a-C-Program
User contributions licensed under CC BY-SA 3.0