首页 > 代码库 > DeviceIoControl 应用层如何和驱动层通信?
DeviceIoControl 应用层如何和驱动层通信?
调用的方法之一的DeviceIoControl
驱动层提供设备名 例如filedisk 在驱动层
首先先是注册列表
用winObj查看 filedisk的驱动对象
但是 这八个对象时怎么生成的呢?
我们在加载filedisk.sys驱动时进行中断 查看过程 具体的双击调试 看我的另一篇文章 http://www.cnblogs.com/UnMovedMover/p/3690369.html
在下载的源码filedisk中sys下面的filedisk-17\filedisk-17\sys\src filedisk.c的入口函数DriverEntry中加入中断 _asm int 3;
query_table[0].EntryContext = &n_devices;
通过调用RtlQueryRegistryValues函数
status = RtlQueryRegistryValues(
RTL_REGISTRY_ABSOLUTE,
parameter_path.Buffer,
&query_table[0],
NULL,
NULL
);
n_devices = 4.
然后循环生成8个设备
for (n = 0, n_created_devices = 0; n < n_devices; n++)
{
status = FileDiskCreateDevice(DriverObject, n, FILE_DEVICE_DISK);
if (NT_SUCCESS(status))
{
n_created_devices++;
}
}
for (n = 0; n < n_devices; n++)
{
status = FileDiskCreateDevice(DriverObject, n, FILE_DEVICE_CD_ROM);
if (NT_SUCCESS(status))
{
n_created_devices++;
}
}
驱动层创建了设备对象之后,应用层将设备对象进行符号链接
DefineDosDevice( DDD_RAW_TARGET_PATH, &VolumeName[4], DeviceName )
DeViceName来自于
if (CdImage)
{
sprintf(DeviceName, DEVICE_NAME_PREFIX "Cd" "%u", DeviceNumber);
}
else
{
sprintf(DeviceName, DEVICE_NAME_PREFIX "%u", DeviceNumber);
}
DEVICE_NAME_PREFIX 在宏定义中如下
#define DEVICE_BASE_NAME _T("\\FileDisk")
#define DEVICE_DIR_NAME _T("\\Device") DEVICE_BASE_NAME
#define DEVICE_NAME_PREFIX DEVICE_DIR_NAME DEVICE_BASE_NAME
就是
设备句柄 通过CreateFile绑定符号链接名进行创建
Device = CreateFile(
VolumeName,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_FLAG_NO_BUFFERING,
NULL
);
最后通过DeviceIoControl 将设备句柄传递给驱动层
DeviceIoControl(
Device, //hDevice Long,设备句柄
IOCTL_FILE_DISK_OPEN_FILE, //dwIoControlCode Long,应用程序调用驱动程序的控制命令,就是IOCTL_XXX IOCTLs。
OpenFileInformation, //lpInBuffer Any,应用程序传递给驱动程序的数据缓冲区地址。
sizeof(OPEN_FILE_INFORMATION) + OpenFileInformation->FileNameLength - 1, //nInBufferSize Long,应用程序传递给驱动程序的数据缓冲区大小,字节数。
NULL, //lpOutBuffer Any,驱动程序返回给应用程序的数据缓冲区地址。
0, //nOutBufferSize Long,驱动程序返回给应用程序的数据缓冲区大小,字节数。
&BytesReturned, //lpBytesReturned Long,驱动程序实际返回给应用程序的数据字节数地址。
NULL //lpOverlapped OVERLAPPED,这个结构用于重叠操作。针对同步操作,请用ByVal As Long传递零值
))
总结下 驱动层提供 设备对象,应用层根据设备对象创建符号链接,根据符号链接生成设备句柄,传递给驱动层。两者就联系起来了。