首页 > 代码库 > 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传递零值
                     ))

 

总结下 驱动层提供 设备对象,应用层根据设备对象创建符号链接,根据符号链接生成设备句柄,传递给驱动层。两者就联系起来了。