HelloWDM.h
#pragma once#ifdef __cplusplusextern "C"{#endif#include#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_EXTERNSION{ PDEVICE_OBJECT fdo; PDEVICE_OBJECT NextStackDevice; UNICODE_STRING ustrDeviceName; //设备名称 UNICODE_STRING ustrSymLinkName; //符号链接名}DEVICE_EXTENSION, *PDEVICE_EXTENSION;//函数声明NTSTATUS HelloWDMAddDevice( IN PDRIVER_OBJECT pDriverObject, IN PDEVICE_OBJECT PhySicalDeviceObject);NTSTATUS HelloWDMPnp( IN PDEVICE_OBJECT fdo, IN PIRP pIrp);VOID HelloWDMUnload(IN PDRIVER_OBJECT pDriverObject);NTSTATUS HelloWDMDispatchRoutine( IN PDEVICE_OBJECT fdo, IN PIRP pIrp);extern "C" NTSTATUS DriverEntry( IN PDRIVER_OBJECT pDriverObject, IN PUNICODE_STRING pRegistryPath);
HelloWDM.cpp
#include "HelloWDM.h"/************************************************************************* 函数名称:DriverEntry* 功能描述:初始化驱动程序,定位和申请硬件资源,创建内核对象* 参数列表: pDriverObject:从I/O管理器中传进来的驱动对象 pRegistryPath:驱动程序在注册表的中的路径* 返回 值:返回初始化驱动状态*************************************************************************/#pragma INITCODEextern "C" NTSTATUS DriverEntry( IN PDRIVER_OBJECT pDriverObject, IN PUNICODE_STRING pRegistryPath){ KdPrint(("Enter DriverEntry\n")); pDriverObject->DriverExtension->AddDevice = HelloWDMAddDevice; pDriverObject->MajorFunction[IRP_MJ_PNP] = HelloWDMPnp; pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = pDriverObject->MajorFunction[IRP_MJ_CREATE] = pDriverObject->MajorFunction[IRP_MJ_READ] = pDriverObject->MajorFunction[IRP_MJ_WRITE] = HelloWDMDispatchRoutine; pDriverObject->DriverUnload = HelloWDMUnload; KdPrint(("Leave DriverEntry\n")); return STATUS_SUCCESS;}/************************************************************************* 函数名称:HelloWDMAddDevice* 功能描述:添加新设备* 参数列表: DriverObject:从I/O管理器中传进来的驱动对象 PhysicalDeviceObject:从I/O管理器中传进来的物理设备对象* 返回 值:返回添加新设备状态*************************************************************************/#pragma PAGEDCODENTSTATUS HelloWDMAddDevice( IN PDRIVER_OBJECT pDriverObject, IN PDEVICE_OBJECT PhySicalDeviceObject){ PAGED_CODE();//只在Check版本中有效 KdPrint(("Enter HelloWDMAddDevice\n")); NTSTATUS status; PDEVICE_OBJECT fdo; UNICODE_STRING devName; RtlInitUnicodeString(&devName, L"\\Device\\MyWDMDevice"); status = IoCreateDevice( pDriverObject, sizeof(DEVICE_EXTENSION), &(UNICODE_STRING)devName, FILE_DEVICE_UNKNOWN, 0, FALSE, &fdo); if(!NT_SUCCESS(status)) return status; PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION)fdo->DeviceExtension; pdx->fdo = fdo; //将此fdo(功能设备对象)挂载在设备堆栈上,并将返回值(下层堆栈的位置),记录在设备扩展结构中 pdx->NextStackDevice = IoAttachDeviceToDeviceStack(fdo, PhySicalDeviceObject); UNICODE_STRING symLinkName; RtlInitUnicodeString(&symLinkName, L"\\??\\HelloWDM"); pdx->ustrDeviceName = devName; pdx->ustrSymLinkName = symLinkName; status = IoCreateSymbolicLink(&(UNICODE_STRING)symLinkName, &(UNICODE_STRING)devName); if(!NT_SUCCESS(status)) { IoDeleteSymbolicLink(&pdx->ustrSymLinkName); status = IoCreateSymbolicLink(&symLinkName, &devName); if(!NT_SUCCESS(status)) return status; } fdo->Flags |= DO_BUFFERED_IO | DO_POWER_PAGABLE; fdo->Flags &= ~DO_DEVICE_INITIALIZING; KdPrint(("Leave HelloWDMAddDevice\n")); return STATUS_SUCCESS;}/************************************************************************* 函数名称:DefaultPnpHandler* 功能描述:对PNP IRP进行缺省处理* 参数列表: pdx:设备对象的扩展 Irp:从IO请求包* 返回 值:返回状态*************************************************************************/ #pragma PAGEDCODENTSTATUS DefaultPnpHandler(PDEVICE_EXTENSION pdx, PIRP Irp){ PAGED_CODE(); KdPrint(("Enter DefaultPnpHandler\n")); //略过当前堆栈 IoSkipCurrentIrpStackLocation(Irp); KdPrint(("Leave DefaultPnpHandler\n")); //用下层堆栈的驱动设备对象处理此IRP return IoCallDriver(pdx->NextStackDevice, Irp);}/************************************************************************* 函数名称:HandleRemoveDevice* 功能描述:对IRP_MN_REMOVE_DEVICE IRP进行处理* 参数列表: pdx:设备对象的扩展 Irp:从IO请求包* 返回 值:返回状态*************************************************************************/#pragma PAGEDCODENTSTATUS HandleRemoveDevice(PDEVICE_EXTENSION pdx, PIRP Irp){ PAGED_CODE(); KdPrint(("Enter HandleRemoveDevice\n")); Irp->IoStatus.Status = STATUS_SUCCESS; NTSTATUS status = DefaultPnpHandler(pdx, Irp); //删除符号链接 IoDeleteSymbolicLink(&(UNICODE_STRING)pdx->ustrSymLinkName); //从车陂堆栈中卸载此设备对象 if (pdx->NextStackDevice) IoDetachDevice(pdx->NextStackDevice); //删除设备对象fdo: IoDeleteDevice(pdx->fdo); KdPrint(("Leave HandleRemoveDevice\n")); return status;}/************************************************************************* 函数名称:HelloWDMPnp* 功能描述:对即插即用IRP进行处理* 参数列表: fdo:功能设备对象 Irp:从IO请求包* 返回 值:返回状态*************************************************************************/#pragma PAGEDCODENTSTATUS HelloWDMPnp( IN PDEVICE_OBJECT fdo, IN PIRP pIrp){ PAGED_CODE();//确保该例程运行在低于APC_LEVEL的中断优先级的级别上 KdPrint(("Enter HelloWDMPnp\n")); NTSTATUS status = STATUS_SUCCESS; PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION)fdo->DeviceExtension; //得到当前IRP的堆栈 PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(pIrp); static NTSTATUS (*fcntab[])(PDEVICE_EXTENSION pdx, PIRP Irp) = { DefaultPnpHandler, // IRP_MN_START_DEVICE DefaultPnpHandler, // IRP_MN_QUERY_REMOVE_DEVICE HandleRemoveDevice, // IRP_MN_REMOVE_DEVICE DefaultPnpHandler, // IRP_MN_CANCEL_REMOVE_DEVICE DefaultPnpHandler, // IRP_MN_STOP_DEVICE DefaultPnpHandler, // IRP_MN_QUERY_STOP_DEVICE DefaultPnpHandler, // IRP_MN_CANCEL_STOP_DEVICE DefaultPnpHandler, // IRP_MN_QUERY_DEVICE_RELATIONS DefaultPnpHandler, // IRP_MN_QUERY_INTERFACE DefaultPnpHandler, // IRP_MN_QUERY_CAPABILITIES DefaultPnpHandler, // IRP_MN_QUERY_RESOURCES DefaultPnpHandler, // IRP_MN_QUERY_RESOURCE_REQUIREMENTS DefaultPnpHandler, // IRP_MN_QUERY_DEVICE_TEXT DefaultPnpHandler, // IRP_MN_FILTER_RESOURCE_REQUIREMENTS DefaultPnpHandler, // DefaultPnpHandler, // IRP_MN_READ_CONFIG DefaultPnpHandler, // IRP_MN_WRITE_CONFIG DefaultPnpHandler, // IRP_MN_EJECT DefaultPnpHandler, // IRP_MN_SET_LOCK DefaultPnpHandler, // IRP_MN_QUERY_ID DefaultPnpHandler, // IRP_MN_QUERY_PNP_DEVICE_STATE DefaultPnpHandler, // IRP_MN_QUERY_BUS_INFORMATION DefaultPnpHandler, // IRP_MN_DEVICE_USAGE_NOTIFICATION DefaultPnpHandler, // IRP_MN_SURPRISE_REMOVAL }; ULONG fcn = stack->MinorFunction; if (fcn >= arraysize(fcntab)) { // unknown function status = DefaultPnpHandler(pdx, pIrp); // some function we don't know about return status; } // unknown function#if DBG static char* fcnname[] = { "IRP_MN_START_DEVICE", "IRP_MN_QUERY_REMOVE_DEVICE", "IRP_MN_REMOVE_DEVICE", "IRP_MN_CANCEL_REMOVE_DEVICE", "IRP_MN_STOP_DEVICE", "IRP_MN_QUERY_STOP_DEVICE", "IRP_MN_CANCEL_STOP_DEVICE", "IRP_MN_QUERY_DEVICE_RELATIONS", "IRP_MN_QUERY_INTERFACE", "IRP_MN_QUERY_CAPABILITIES", "IRP_MN_QUERY_RESOURCES", "IRP_MN_QUERY_RESOURCE_REQUIREMENTS", "IRP_MN_QUERY_DEVICE_TEXT", "IRP_MN_FILTER_RESOURCE_REQUIREMENTS", "", "IRP_MN_READ_CONFIG", "IRP_MN_WRITE_CONFIG", "IRP_MN_EJECT", "IRP_MN_SET_LOCK", "IRP_MN_QUERY_ID", "IRP_MN_QUERY_PNP_DEVICE_STATE", "IRP_MN_QUERY_BUS_INFORMATION", "IRP_MN_DEVICE_USAGE_NOTIFICATION", "IRP_MN_SURPRISE_REMOVAL", }; KdPrint(("PNP Request (%s)\n", fcnname[fcn]));#endif // DBG status = (*fcntab[fcn])(pdx, pIrp); KdPrint(("Leave HelloWDMPnp\n")); return status;}/************************************************************************* 函数名称:HelloWDMDispatchRoutine* 功能描述:对缺省IRP进行处理* 参数列表: fdo:功能设备对象 Irp:从IO请求包* 返回 值:返回状态*************************************************************************/#pragma PAGEDCODENTSTATUS HelloWDMDispatchRoutine(IN PDEVICE_OBJECT fdo, IN PIRP Irp){ PAGED_CODE(); KdPrint(("Enter HelloWDMDispatchRoutine\n")); Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Information = 0; // no bytes xfered IoCompleteRequest( Irp, IO_NO_INCREMENT ); KdPrint(("Leave HelloWDMDispatchRoutine\n")); return STATUS_SUCCESS;}/************************************************************************* 函数名称:HelloWDMUnload* 功能描述:负责驱动程序的卸载操作* 参数列表: DriverObject:驱动对象* 返回 值:返回状态*************************************************************************/#pragma PAGEDCODEvoid HelloWDMUnload(IN PDRIVER_OBJECT DriverObject){ PAGED_CODE(); KdPrint(("Enter HelloWDMUnload\n")); KdPrint(("Leave HelloWDMUnload\n"));}