应用程序和硬件设备的通信过程是:应用程序使用CreateFile函数打开设备,然后用DeviceIoControl()与硬件设备通信.
CreateFile函数:
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)] private static extern IntPtr CreateFile( string lpFileName, uint dwDesiredAccess, uint dwShareMode, IntPtr SecurityAttributes, uint dwCreationDisposition, uint dwFlagsAndAttributes, IntPtr hTemplateFile);
DeviceIoControl函数:
[DllImport("kernel32.dll", ExactSpelling = true, SetLastError = true, CharSet = CharSet.Auto)] private static extern bool DeviceIoControl( IntPtr hDevice, uint dwIoControlCode, IntPtr lpInBuffer, uint nInBufferSize, IntPtr lpOutBuffer, uint nOutBufferSize, out uint lpBytesReturned, IntPtr lpOverlapped );
const uint GENERIC_READ = 0x80000000;
const int GENERIC_WRITE = 0x40000000;
const int FILE_SHARE_READ = 0x1;
const int FILE_SHARE_WRITE = 0x2;
const int IOCTL_STORAGE_EJECT_MEDIA = 0x2D4808;
具体过程如下:
1. 打开设备,得到设备的句柄handle.
IntPtr handle = CreateFile(filename, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, IntPtr.Zero, 0x3, 0, IntPtr.Zero);
第一个参数filename与普通文件名有所不同,设备驱动的“文件名”(常称为“设备路径”)形式固定为“\\.\DeviceName”, 如 string filename = @"\\.\I:";
2. 向目标设备发送设备控制码,也就是发送命令。IOCTL_STORAGE_EJECT_MEDIA 弹出U盘。
uint byteReturned; DeviceIoControl(handle, IOCTL_STORAGE_EJECT_MEDIA, IntPtr.Zero, 0, IntPtr.Zero, 0, out byteReturned, IntPtr.Zero);