windows驱动编程(一) 先写个NTDDK例子

来源:互联网 发布:广州数控g76锥螺纹编程 编辑:程序博客网 时间:2024/06/06 09:26
参考张帆的windows驱动开发技术详解,自学中。。。
#pragma once#ifndef __HELLODDK__HH#define __HELLODDK__HH//包含ntddk.h文件,使用c标准的方式编译#ifdef __cplusplusextern "C"{#endif#include <ntddk.h>#ifdef __cplusplus};#endif//定义分页标记,非分页标记和初始化内存块,//在windows驱动程序的开发中,所有程序的函数和变量都有指明被加载到分页内存还是非分页内存//DriverEntry函数需要放在INIT标志的内存中//关于区别后续解释#define  PAGEDCODE code_seg("PAGE")#define  LOCKEDCODE code_seg()#define  INITCODE code_seg("INIT")#define PAGEDDATAdata_seg("PAGE")#define LOCKEDDATAdata_seg()#define INITDATAdata_seg("INIT")#define arraySize(p)(sizeof(p)/sizeof((p)[0])) //得到数组的元素个数//设备扩展结构体,根据个人需要可以添加所需信息typedef struct _DEVICE_EXTENSION {PDEVICE_OBJECT pDevice; //设备结构体指针UNICODE_STRING usDeviceName;//设备名称UNICODE_STRING usSymLinkName;//符号连接名}DEVICE_EXTENSION,*pDEVICE_EXTENSION;NTSTATUS CreateDevice(IN PDRIVER_OBJECT pDriverObject); //创建设备VOID HelloDDKUnload(IN PDRIVER_OBJECT pDriverObject);//卸载设备NTSTATUS HelloDDKDispatchRoutine(IN PDRIVER_OBJECT pDriverObject,IN PIRP pIrp);//通用的设备例程函数#endif



#include "MyDDKHello.h"/*DriverEntry:驱动程序的入口函数功能:初始化驱动程序,申请硬件资源,创建内核对象参数:IN pDriverObject 从I/O管理器中传进来的驱动对象IN pRegisterPath 驱动程序在注册表中的路径返回:返回初始化驱动的状态*///#include <wdm.h>#pragma  INITCODEextern "C" NTSTATUS DriverEntry(IN PDRIVER_OBJECT pDriverObject,IN PUNICODE_STRING pRegisterPath){NTSTATUS status;DbgPrint("Into DriverEntry..."); //相当于TRACRE()//向I/O管理器注册驱动回调函数pDriverObject->MajorFunction[IRP_MJ_CREATE] = pDriverObject->MajorFunction[IRP_MJ_CLOSE] = pDriverObject->MajorFunction[IRP_MJ_WRITE] = pDriverObject->MajorFunction[IRP_MJ_READ] = (PDRIVER_DISPATCH)HelloDDKDispatchRoutine;pDriverObject->DriverUnload = HelloDDKUnload;status = CreateDevice(pDriverObject);DbgPrint("DriverEntry End...");return status;}/*CreateDevice:初始化设备对象参数:pDriverObject 从I/O管理器传进来的驱动对象返回:返回创建设备的初始化状态*/#pragma INITCODENTSTATUS CreateDevice(PDRIVER_OBJECT pDriverObject){NTSTATUS status = STATUS_UNSUCCESSFUL;PDEVICE_OBJECT pDeviceObject;//设备的扩展结构体,其他的驱动程序的函数中,可以很方便的得到此结构体,进而得到设备的自定义信息pDEVICE_EXTENSION pDevExt; //创建设备名UNICODE_STRING usDevName;RtlInitUnicodeString(&usDevName,L"\\Device\\MyDDKDevice"); //初始化UNICODE_STRING类型的变量,使用后不需要释放//创建设备status = IoCreateDevice(pDriverObject,sizeof(DEVICE_EXTENSION),&usDevName,FILE_DEVICE_UNKNOWN,//此种设备为独占设备,设备只能被一个应用程序所使用 0, //TRUE,//&pDeviceObject);if (!NT_SUCCESS(status)){return status;}pDeviceObject->Flags |= DO_BUFFERED_IO; //设备对内存的操作分类:DO_BUFFERED_IO DO_DIRECT_IO ,详解后说明pDevExt = (pDEVICE_EXTENSION)pDeviceObject->DeviceExtension;pDevExt->pDevice = pDeviceObject;pDevExt->usDeviceName = usDevName;//创建符号连接UNICODE_STRING usSymLinkName;RtlInitUnicodeString(&usSymLinkName,L"\\??\\MySymbLinkNameHelloDDK");pDevExt->usSymLinkName = usSymLinkName;//对于应用程序,设备名称是不可见的,只能使用符号连接名称,该连接指向真正的设备名称status = IoCreateSymbolicLink(&usSymLinkName,&usDevName);if (!NT_SUCCESS(status)){IoDeleteDevice(pDeviceObject); //删除设备对象return status;}return STATUS_SUCCESS;}/*HelloDDKUnload:负责驱动程序的卸载操作参数: pDriverObject :驱动程序对象*//*此历程遍历系统中所有的此类设备对象。第一个设备对象的地址存在于驱动对象的DeviceObject域中,每个设备对象的NextDevice域记录着下一个设备对象的地址,这样就形成了一个链表。卸载驱动函数的主要目的就是遍历此链表,获得设备名称和符号链接名称,并执行删除操作。*/#pragma  PAGEDCODEVOID HelloDDKUnload(IN PDRIVER_OBJECT pDriverObject){NTSTATUS status = STATUS_UNSUCCESSFUL;PDEVICE_OBJECT pDevNext;DbgPrint("into HelloDDKUnload");pDevNext = pDriverObject->DeviceObject;while (pDevNext != NULL){pDEVICE_EXTENSION pDevExt = (pDEVICE_EXTENSION)pDevNext->DeviceExtension;//删除符号链接UNICODE_STRING usLinkName = pDevExt->usSymLinkName;IoDeleteSymbolicLink(&usLinkName);pDevNext = pDevNext->NextDevice;IoDeleteDevice(pDevNext); //删除设备}}/*HelloDDKDispatchRoutine:默认派遣函数参数:pDriverObject:功能设备对象pIrp:从I/O请求包返回值:返回处理的状态*/#pragma PAGEDCODENTSTATUS HelloDDKDispatchRoutine(IN PDRIVER_OBJECT pDriverObject,IN PIRP pIrp){DbgPrint("in to HelloDDKDispatchRoutine");NTSTATUS status = STATUS_SUCCESS;//完成IRPpIrp->IoStatus .Status= status;pIrp->IoStatus.Information = 0;IoCompleteRequest(pIrp,IO_NO_INCREMENT//后续详解);DbgPrint("end HelloDDKDispatchRoutine");return  status;}


原创粉丝点击