白話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傳遞零值
                     ))

 

總結下 驅動層提供 設備對象,應用層根據設備對象創建符號鏈接,根據符號鏈接生成設備句柄,傳遞給驅動層。兩者就聯繫起來了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章