分享

Windows驱动开发技术详解

 safulo 2014-10-23

    首先需要安装DDK,这里我选择Microsoft Windows Server 2003 SP1 DDK

    Windows驱动分成两类,一类是不支持即插即用的NT式驱动,一类是支持即插即用的WDM驱动。

    首先来看一个最简单的NT式驱动。

    #pragma once

    #ifdef __cplusplus

    extern "C"

    {

    #endif

    #include <NTDDK.h>

    #ifdef __cplusplus

    }

    #endif

    #define PAGEDCODE code_seg("PAGE")

    #define LOCKEDCODE code_seg()

    #define INITCODE code_seg("INIT")

    #define PAGEDDATA data_seg("PAGE")

    #define LOCKEDDATA data_seg()

    #define INITDATA data_seg("INIT")

    #define arraysize(p) (sizeof(p)/sizeof((p)[0]))

    typedef struct _DEVICE_EXTENSION {

    PDEVICE_OBJECT pDevice;

    UNICODE_STRING ustrDeviceName;    //设备名称

    UNICODE_STRING ustrSymLinkName;    //符号链接名

    } DEVICE_EXTENSION, *PDEVICE_EXTENSION;

    // 驱动函数声明

    NTSTATUS CreateDevice (IN PDRIVER_OBJECT pDriverObject);

    VOID HelloDDKUnload (IN PDRIVER_OBJECT pDriverObject);

    NTSTATUS HelloDDKDispatchRoutine(IN PDEVICE_OBJECT pDevObj,

    IN PIRP pIrp);

    Driver.h头文件中包含了开发NT式驱动所需要的NTDDK.h,此外还定义了几个标志来指明函数和变量分配在分页内存还是非分页内存中。Windows驱动程序的入口函数是DriverEntry函数,

    #include "Driver.h"

    /************************************************************************

    * 函数名称:DriverEntry

    * 功能描述:初始化驱动程序,定位和申请硬件资源,创建内核对象

    * 参数列表:

    pDriverObject:从I/O管理器中传进来的驱动对象

    pRegistryPath:驱动程序在注册表的中的路径

    * 返回 值:返回初始化驱动状态

    *************************************************************************/

    #pragma INITCODE

    extern "C" NTSTATUS DriverEntry (

    IN PDRIVER_OBJECT pDriverObject,

    IN PUNICODE_STRING pRegistryPath    )

    {

    NTSTATUS status;

    KdPrint(("Enter DriverEntry\n"));

    //注册其他驱动调用函数入口

    pDriverObject->DriverUnload = HelloDDKUnload;

    pDriverObject->MajorFunction[IRP_MJ_CREATE] = HelloDDKDispatchRoutine;

    pDriverObject->MajorFunction[IRP_MJ_CLOSE] = HelloDDKDispatchRoutine;

    pDriverObject->MajorFunction[IRP_MJ_WRITE] = HelloDDKDispatchRoutine;

    pDriverObject->MajorFunction[IRP_MJ_READ] = HelloDDKDispatchRoutine;

    //创建驱动设备对象

    status = CreateDevice(pDriverObject);

    KdPrint(("DriverEntry end\n"));

    return status;

    }

    /************************************************************************

    * 函数名称:CreateDevice

    * 功能描述:初始化设备对象

    * 参数列表:

    pDriverObject:从I/O管理器中传进来的驱动对象

    * 返回 值:返回初始化状态

    *************************************************************************/

    #pragma INITCODE   //指明此函数加载到INIT内存区域(即只在加载的时候需要载入内存,加载成功后可以从内存中卸载掉)

    NTSTATUS CreateDevice (

    IN PDRIVER_OBJECT    pDriverObject)

    {

    NTSTATUS status;

    PDEVICE_OBJECT pDevObj;

    PDEVICE_EXTENSION pDevExt;

    //创建设备名称

    UNICODE_STRING devName;

    RtlInitUnicodeString(&devName,L"\\Device\\MyDDKDevice");

    //创建设备

    status = IoCreateDevice( pDriverObject,

    sizeof(DEVICE_EXTENSION),

    &(UNICODE_STRING)devName,

    FILE_DEVICE_UNKNOWN,//此种设备为独占设备

    0, TRUE,

    &pDevObj );

    if (!NT_SUCCESS(status))

    return status;

    pDevObj->Flags |= DO_BUFFERED_IO;

    pDevExt = (PDEVICE_EXTENSION)pDevObj->DeviceExtension;

    pDevExt->pDevice = pDevObj;

    pDevExt->ustrDeviceName = devName;

    //创建符号链接

    UNICODE_STRING symLinkName;

    RtlInitUnicodeString(&symLinkName,L"\\??\\HelloDDK");

    pDevExt->ustrSymLinkName = symLinkName;

    status = IoCreateSymbolicLink( &symLinkName,&devName );

    if (!NT_SUCCESS(status))

    {

    IoDeleteDevice( pDevObj );

    return status;

    }

    return STATUS_SUCCESS;

    }

    /************************************************************************

    * 函数名称:HelloDDKUnload

    * 功能描述:负责驱动程序的卸载操作

【责编:cc】

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多