新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > windowsNT4.0下設備驅動程序的開發與應用

        windowsNT4.0下設備驅動程序的開發與應用

        作者: 時間:2016-09-12 來源:網絡 收藏

        RtlInitUnicodeString(Win32DeviceName, SelfWin32Name);

        //聯接內部設備名與Win32子系統下的設備名

        Status = IoCreateSymbolicLink( Win32DeviceName, NtDeviceName);

        //利用RtlQueryRegistryValues函數讀出注冊表中Parameters下的參數值,初始化自己的硬件

        ...

        4 驅動程序服務例程

        驅動程序初始化之后,始終等待發自用戶的命令或由其它事件源引起的事件。一旦命令或事件發生,I/O管理器就調用相應的服務例程提供服務。而幾乎所有的I/O都是通過I/O請求包IRP驅動的。所謂IRP驅動,就是I/O管理器負責在非分頁的系統內存中分配一定空間,當接受用戶發出的命令或由事件引發后,將工作指令按一定的數據結構置于其中,傳遞到驅動程序服務例程。換言之,IRP包含了驅動程序服務例程所需要的信息指令。表2、表3為IRP的一些數據結構。

        同時,I/O管理器和驅動程序都需要在所有時候知道一個I/O設備所進行的情況。系統提供Device對象以滿足此要求。該對象在DriverEntry例程中生成設備時由系統創建后,分配給驅動程序,并在整個驅動程序生存期內有效。當I/O管理器調用驅動程序服務例程時,傳遞該對象。表4為Device對象的外部可見域。

        表2 IRP標頭中外部可見的域

        2.jpg

        表3 IRP堆棧單元的一些內容

        3.jpg

        表4 Device 對象的外部可見域

        4.jpg

        其中,DeviceExtension域是一個重要的數據結構。它是由I/O管理器創建并自動掛接到Device對象的非分頁池,是保存驅動程序任意全局變量的最好辦法。因為DeviceExtension是驅動程序特定的,要自定義它的數據結構。

        下面是一個驅動程序服務例程利用Device對象和IRP的片段:

        NTSTATUS XxSelfDispatch(IN PDEVICE_OBJECT pDO IN PIRP pIrp);

        {

        PLOCAL_DEVICE_INFO pLDI;

        PIO_STACK_LOCATION pIrpStack;

        PULONG pIOBuffer;

        //得到全局信息

        pLDI = (PSELF_DEVICE_INFO)pDO->DeviceExtension;

        pIrpStack = IoGetCurrentIrpStackLocation(pIrp);

        //得到由用戶應用程序發來的用戶數據,并在需要時,將結果通過此變量返回給用戶

        pIOBuffer=PULONGpIrp->AssociatedIrp.System

        Buffer;

        // 由IRP攜帶的信息決定驅動程序的執行

        switch (pIrpStack->MajorFunction)

        {

        case IRP_MJ_CREATE:

        case IRP_MJ_CLOSE:

        Status = STATUS_SUCCESS;

        break;

        case IRP_MJ_DEVICE_CONTROL:

        //由Parameters進一步解釋控制代碼含義

        switch (pIrpStack->Parameters.DeviceIoControl.IoControlCode)

        {

        case IOCTL_Function1:

        //執行功能代碼

        Field1 = pLDI->SelfField1;

        ...

        break;

        case IOCTL_Function2:

        //執行功能代碼

        ...

        break;

        break

        // 返回I/O操作的狀態

        pIrp->IoStatus.Status = Status;

        IoCompleteRequest(pIrp IO_NO_INCREMENT);

        return Status;

        5 驅動程序終止例程

        Unload例程負責取消由DriverEntry例程所做的任何事情,包括解除屬于該驅動程序的任何硬件資源的分配,以及刪除屬于驅動程序的任何內核對象。通常這僅在系統關閉時需要。

        VOID XxUnload(PDRIVER_OBJECT DriverObject)

        {

        PLOCAL_DEVICE_INFO pLDI;

        UNICODE_STRING Win32DeviceName;

        // 得到全局數據,根據全局數據進行清理工作

        pLDI=PLOCAL_DEVICE_INFODriverObject->Device

        Object->DeviceExtension

        if (pLDI->Field2 == TRUE)

        {

        ...

        // 刪除分配的設備名及設備

        RtlInitUnicodeString(Win32DeviceName, SelfWin32 Name);

        IoDeleteSymbolicLink(Win32DeviceName);

        IoDeleteDevice(pLDI->DeviceObject);

        6 用戶層應用程序與驅動程序間的接口

        驅動程序完成后,將在系統重新引導時裝入并初始化(由DriverEntry例程完成)。此時,驅動程序處于可用狀態,等待用戶層應用程序使用。用戶層應用程序可以:

        ·打開該設備文件(由IRP_MJ_CREATE功能代碼完成)

        ·讀出數據(由IRP_MJ_READ功能代碼完成)

        ·寫入數據(由IRP_MJ_WRITE功能代碼完成)

        ·執行用戶自定義的功能代碼(由IRP_MJ_DEVICE_CONTROL功能代碼完成)

        ·關閉該設備文件(由IRP_MJ_CLOSE功能代碼完成)

        以下是部分實現代碼:

        void main()

        {

        HANDLE hndFile; // 由CreateFile得到

        union {

        ULONG LongData;

        USHORT ShortData;

        UCHAR CharData;

        }DataBuffer; //從設備驅動程序中得到的數據

        LONG IoctlCode; //功能代碼

        ULONG DataLength;

        LONG Parameter1;

        //調用IRP中的IRP _MJ_CREATE功能

        hndFile = CreateFile(

        ″\\.\SelfWin32Name″, // 打開設備文件″ SelfWin32Name″



        關鍵詞:

        評論


        相關推薦

        技術專區

        關閉
        主站蜘蛛池模板: 贺州市| 阜康市| 内黄县| 营口市| 保定市| 化州市| 罗城| 西青区| 巫山县| 贞丰县| 湟源县| 高碑店市| 文安县| 万全县| 商洛市| 奎屯市| 吉隆县| 镇康县| 武陟县| 霍邱县| 清苑县| 临湘市| 沧州市| 开远市| 安吉县| 永靖县| 临沂市| 图木舒克市| 阿瓦提县| 钦州市| 连山| 确山县| 祁连县| 卢龙县| 长丰县| 重庆市| 宜兰市| 乳源| 庄浪县| 闻喜县| 曲阳县|