分层驱动完成历程
2015-08-08 19:03
197 查看
EXE部分
SYS部分
驱动A部分
驱动B部分
#include <stdio.h> #include <Windows.h> #include <WinIoCtl.h> #include "Ioctl.h" int main (void) { char linkname[]="\\\\.\\HelloDDKB"; HANDLE hDevice = CreateFileA(linkname, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hDevice == INVALID_HANDLE_VALUE) { printf("Win32 error code: %d\n",GetLastError()); return 1; } DWORD dwRead; //如果读IRP没有被完成,ReadFile一直都不会退出 ReadFile(hDevice,NULL,NULL,&dwRead,NULL); printf("Readfile返回%d\n",GetLastError()); CloseHandle(hDevice); getchar(); getchar(); return 0; }
SYS部分
驱动A部分
#pragma once #include <ntddk.h> #define CountArray(Array) ( sizeof(Array) / sizeof(Array[0]) ) typedef struct _DEVICE_EXTENSION { PDEVICE_OBJECT pDevice; //设备对象 UNICODE_STRING ustrDeviceName; //设备名称 UNICODE_STRING ustrSymLinkName; //符号名称 KDPC pollingDPC; //存储DPC对象 KTIMER pollingTimer; //存储计时器对象 PIRP currentPendingIRP; //记录当前挂起的IRP }DEVICE_EXTENSION,*PDEVICE_EXTENSION; #ifdef __cplusplus extern "C" NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath); #endif void HelloUnload(IN PDRIVER_OBJECT DriverObject); //卸载函数 NTSTATUS CreateDevice(PDRIVER_OBJECT PDevObj); //创建设备 NTSTATUS HelloDDKDispatchRoutine(IN PDEVICE_OBJECT pDevObj,IN PIRP pIrp); //派遣函数 NTSTATUS HelloDDKControl(IN PDEVICE_OBJECT pDevObj,IN PIRP pIrp); //IRP_MJ_DIRECTORY_CONTROL NTSTATUS HelloDDKRead(IN PDEVICE_OBJECT pDevObj,IN PIRP pIrp); NTSTATUS HelloDDKCreate(IN PDEVICE_OBJECT pDevObj,IN PIRP pIrp); NTSTATUS HelloDDKClose(IN PDEVICE_OBJECT pDevObj,IN PIRP pIrp);
#include "hello.h" #include "Ioctl.h" NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath) { DbgPrint("Hello from!\n"); DriverObject->DriverUnload = HelloUnload; for (int i=0;i<IRP_MJ_MAXIMUM_FUNCTION;i++) { DriverObject->MajorFunction[i]=HelloDDKDispatchRoutine; } DriverObject->MajorFunction[IRP_MJ_READ]=HelloDDKRead; DriverObject->MajorFunction[IRP_MJ_CREATE]=HelloDDKCreate; DriverObject->MajorFunction[IRP_MJ_CLOSE]=HelloDDKClose; #if DBG _asm int 3 #endif //创建设备 CreateDevice(DriverObject); return STATUS_SUCCESS; } //卸载函数 void HelloUnload(IN PDRIVER_OBJECT DriverObject) { #if DBG _asm int 3 #endif DbgPrint("Goodbye from!\n"); PDEVICE_OBJECT pNextObj=NULL; pNextObj=DriverObject->DeviceObject; while (pNextObj) { PDEVICE_EXTENSION pDevExt=(PDEVICE_EXTENSION)pNextObj->DeviceExtension; //删除符号连接 IoDeleteSymbolicLink(&pDevExt->ustrSymLinkName); //删除设备 IoDeleteDevice(pDevExt->pDevice); pNextObj=pNextObj->NextDevice; } KdPrint(("DriverA:Leave A DriverUnload\n")); } NTSTATUS HelloDDKControl(IN PDEVICE_OBJECT pDevObj,IN PIRP pIrp) { #if DBG _asm int 3 #endif NTSTATUS status=STATUS_SUCCESS; //获取当前堆栈 PIO_STACK_LOCATION stack=IoGetCurrentIrpStackLocation(pIrp); //获取输入参数大小 ULONG cbin=stack->Parameters.DeviceIoControl.InputBufferLength; //获取输出参数大小 ULONG cbout=stack->Parameters.DeviceIoControl.OutputBufferLength; //得到IOCTL控制码 ULONG code=stack->Parameters.DeviceIoControl.IoControlCode; //获取设备扩展 PDEVICE_EXTENSION pDevExt=(PDEVICE_EXTENSION)pDevObj->DeviceExtension; //从用户模式传进来的微秒数 ULONG ulMircoSeconds=*(PULONG)pIrp->AssociatedIrp.SystemBuffer; switch (code) { case IOCTL_WAIT_METHOD1: { } break; default: status=STATUS_INVALID_VARIANT; } //设置IRP的完成状态 pIrp->IoStatus.Status=status; pIrp->IoStatus.Information=0; IoCompleteRequest(pIrp,IO_NO_INCREMENT); return status; } VOID OnTimerDpc(IN PKDPC pDpc,IN PVOID pContext,IN PVOID SysArg1,IN PVOID SysArg2) { #if DBG _asm int 3 #endif PDEVICE_OBJECT pDevObj=(PDEVICE_OBJECT)pContext; PDEVICE_EXTENSION pdx=(PDEVICE_EXTENSION)pDevObj->DeviceExtension; PIRP currentPendingIRP=pdx->currentPendingIRP; DbgPrint("DriverA:complete the Driver A IRP_MJ_READ irp\n"); //设置完成状态为STATUS_SUCCESS currentPendingIRP->IoStatus.Status=STATUS_SUCCESS; //完成 currentPendingIRP->IoStatus.Information=0; IoCompleteRequest(currentPendingIRP,IO_NO_INCREMENT); return; } NTSTATUS HelloDDKRead(IN PDEVICE_OBJECT pDevObj,IN PIRP pIrp) { #if DBG _asm int 3 #endif PDEVICE_EXTENSION pDevExt=(PDEVICE_EXTENSION)pDevObj->DeviceExtension; //将IRP设置为挂起 IoMarkIrpPending(pIrp); //将挂起的IRP记录下来 pDevExt->currentPendingIRP=pIrp; //定义5秒的超时 ULONG ulMicroSecond=5000000; //将32位整数转化成64位整数 LARGE_INTEGER timeout=RtlConvertLongToLargeInteger(-10*ulMicroSecond); KeSetTimer(&pDevExt->pollingTimer,timeout,&pDevExt->pollingDPC); DbgPrint("DriverA:Leave A HelloDDKRead\n"); return STATUS_PENDING; //挂起 } NTSTATUS HelloDDKCreate(IN PDEVICE_OBJECT pDevObj,IN PIRP pIrp) { #if DBG _asm int 3 #endif DbgPrint("DriverA:Enter A HelloDDKCreate\n"); //完成IRP pIrp->IoStatus.Status=STATUS_SUCCESS; pIrp->IoStatus.Information=0; IoCompleteRequest(pIrp,IO_NO_INCREMENT); return STATUS_SUCCESS; } NTSTATUS HelloDDKClose(IN PDEVICE_OBJECT pDevObj,IN PIRP pIrp) { #if DBG _asm int 3 #endif DbgPrint("DriverA:Enter A HelloDDKClose\n"); //完成IRP pIrp->IoStatus.Status=STATUS_SUCCESS; pIrp->IoStatus.Information=0; IoCompleteRequest(pIrp,IO_NO_INCREMENT); return STATUS_SUCCESS; } //创建设备 NTSTATUS CreateDevice(PDRIVER_OBJECT pDriver_Object) { //定义变量 NTSTATUS status=STATUS_SUCCESS; PDEVICE_OBJECT pDevObj=NULL; PDEVICE_EXTENSION pDevExt=NULL; //初始化字符串 UNICODE_STRING devname; UNICODE_STRING symLinkName; RtlInitUnicodeString(&devname,L"\\device\\MyDDKDeviceA"); RtlInitUnicodeString(&symLinkName,L"\\??\\HelloDDKA"); //创建设备 status =IoCreateDevice(pDriver_Object,sizeof(DEVICE_EXTENSION),&devname,FILE_DEVICE_UNKNOWN,NULL,TRUE,&pDevObj); if (!NT_SUCCESS(status)) { DbgPrint("创建设备失败\n"); return status; } pDevObj->Flags |= DO_BUFFERED_IO;; pDevExt=(PDEVICE_EXTENSION)pDevObj->DeviceExtension; pDevExt->pDevice=pDevObj; pDevExt->ustrDeviceName=devname; pDevExt->ustrSymLinkName=symLinkName; KeInitializeTimer(&pDevExt->pollingTimer); KeInitializeDpc(&pDevExt->pollingDPC,OnTimerDpc,(PVOID)pDevObj); //创建符号连接 status =IoCreateSymbolicLink(&symLinkName,&devname) ; if (!NT_SUCCESS(status)) { DbgPrint("创建符号连接失败\n"); IoDeleteDevice(pDevObj); return status; } return STATUS_SUCCESS; } //派遣函数 NTSTATUS HelloDDKDispatchRoutine(IN PDEVICE_OBJECT pDevObj,IN PIRP pIrP) { //#if DBG // _asm int 3 //#endif PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(pIrP); //建立一个字符串数组与IRP类型对应起来 static char* irpname[] = { "IRP_MJ_CREATE", "IRP_MJ_CREATE_NAMED_PIPE", "IRP_MJ_CLOSE", "IRP_MJ_READ", "IRP_MJ_WRITE", "IRP_MJ_QUERY_INFORMATION", "IRP_MJ_SET_INFORMATION", "IRP_MJ_QUERY_EA", "IRP_MJ_SET_EA", "IRP_MJ_FLUSH_BUFFERS", "IRP_MJ_QUERY_VOLUME_INFORMATION", "IRP_MJ_SET_VOLUME_INFORMATION", "IRP_MJ_DIRECTORY_CONTROL", "IRP_MJ_FILE_SYSTEM_CONTROL", "IRP_MJ_DEVICE_CONTROL", "IRP_MJ_INTERNAL_DEVICE_CONTROL", "IRP_MJ_SHUTDOWN", "IRP_MJ_LOCK_CONTROL", "IRP_MJ_CLEANUP", "IRP_MJ_CREATE_MAILSLOT", "IRP_MJ_QUERY_SECURITY", "IRP_MJ_SET_SECURITY", "IRP_MJ_POWER", "IRP_MJ_SYSTEM_CONTROL", "IRP_MJ_DEVICE_CHANGE", "IRP_MJ_QUERY_QUOTA", "IRP_MJ_SET_QUOTA", "IRP_MJ_PNP", }; UCHAR type = stack->MajorFunction; if (type >= CountArray(irpname)) KdPrint(("无效的IRP类型 %X\n", type)); else KdPrint(("%s\n", irpname[type])); pIrP->IoStatus.Status=STATUS_SUCCESS; //设置完成状态 pIrP->IoStatus.Information=0; //设置操作字节为0 IoCompleteRequest(pIrP,IO_NO_INCREMENT); //结束IRP派遣函数,第二个参数表示不增加优先级 return STATUS_SUCCESS; }
驱动B部分
#pragma once #include <ntddk.h> #define CountArray(Array) ( sizeof(Array) / sizeof(Array[0]) ) typedef struct _DEVICE_EXTENSION { PDEVICE_OBJECT pDevice; //设备对象 UNICODE_STRING ustrDeviceName; //设备名称 UNICODE_STRING ustrSymLinkName; //符号名称 PDEVICE_OBJECT TargetDevice; }DEVICE_EXTENSION,*PDEVICE_EXTENSION; #ifdef __cplusplus extern "C" NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath); #endif void HelloUnload(IN PDRIVER_OBJECT DriverObject); //卸载函数 NTSTATUS CreateDevice(PDRIVER_OBJECT PDevObj); //创建设备 NTSTATUS HelloDDKDispatchRoutine(IN PDEVICE_OBJECT pDevObj,IN PIRP pIrp); //派遣函数 NTSTATUS HelloDDKControl(IN PDEVICE_OBJECT pDevObj,IN PIRP pIrp); //IRP_MJ_DIRECTORY_CONTROL NTSTATUS HelloDDKRead(IN PDEVICE_OBJECT pDevObj,IN PIRP pIrp); NTSTATUS HelloDDKCreate(IN PDEVICE_OBJECT pDevObj,IN PIRP pIrp); NTSTATUS HelloDDKClose(IN PDEVICE_OBJECT pDevObj,IN PIRP pIrp);
#include "hello.h" #include "Ioctl.h" NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath) { DbgPrint("Hello from!\n"); DriverObject->DriverUnload = HelloUnload; for (int i=0;i<IRP_MJ_MAXIMUM_FUNCTION;i++) { DriverObject->MajorFunction[i]=HelloDDKDispatchRoutine; } DriverObject->MajorFunction[IRP_MJ_READ]=HelloDDKRead; DriverObject->MajorFunction[IRP_MJ_CREATE]=HelloDDKCreate; DriverObject->MajorFunction[IRP_MJ_CLOSE]=HelloDDKClose; #if DBG _asm int 3 #endif NTSTATUS status=STATUS_SUCCESS; UNICODE_STRING DeviceName; RtlInitUnicodeString(&DeviceName,L"\\Device\\MyDDKDeviceA"); //寻找DriverA创建的设备对象 PDEVICE_OBJECT DevObj=NULL; PFILE_OBJECT FileObject=NULL; status=IoGetDeviceObjectPointer(&DeviceName,FILE_ALL_ACCESS,&FileObject,&DevObj); if (!NT_SUCCESS(status)) { return status; } #if DBG _asm int 3 #endif //创建设备 status=CreateDevice(DriverObject); if (!NT_SUCCESS(status)) { ObDereferenceObject(FileObject); return status; } PDEVICE_EXTENSION pdx=(PDEVICE_EXTENSION)DriverObject->DeviceObject->DeviceExtension; PDEVICE_OBJECT FilterDeviceObject=pdx->pDevice; //将自己的设备对象挂载在DriverA的设备对象上 PDEVICE_OBJECT TargetDevice=IoAttachDeviceToDeviceStack(FilterDeviceObject,DevObj); #if DBG _asm int 3 #endif //将底层设备对象记录下 pdx->TargetDevice=TargetDevice; if (!TargetDevice) { ObDereferenceObject(FileObject); IoDeleteDevice(FilterDeviceObject); return STATUS_INSUFFICIENT_RESOURCES; } FilterDeviceObject->DeviceType=TargetDevice->DeviceType; FilterDeviceObject->Characteristics=TargetDevice->Characteristics; FilterDeviceObject->Flags&=~DO_DEVICE_INITIALIZING; FilterDeviceObject->Flags|=(TargetDevice->Flags & (DO_DIRECT_IO | DO_BUFFERED_IO)); ObDereferenceObject(FileObject); return STATUS_SUCCESS; } //卸载函数 void HelloUnload(IN PDRIVER_OBJECT DriverObject) { #if DBG _asm int 3 #endif DbgPrint("Goodbye from!\n"); PDEVICE_OBJECT pNextObj=NULL; pNextObj=DriverObject->DeviceObject; while (pNextObj) { PDEVICE_EXTENSION pDevExt=(PDEVICE_EXTENSION)pNextObj->DeviceExtension; //删除符号连接 IoDeleteSymbolicLink(&pDevExt->ustrSymLinkName); //从设备栈中弹出设备 IoDetachDevice(pDevExt->TargetDevice); //删除设备 IoDeleteDevice(pDevExt->pDevice); pNextObj=pNextObj->NextDevice; } KdPrint(("DriverB:Leave B DriverUnload\n")); } NTSTATUS HelloDDKControl(IN PDEVICE_OBJECT pDevObj,IN PIRP pIrp) { #if DBG _asm int 3 #endif NTSTATUS status=STATUS_SUCCESS; //获取当前堆栈 PIO_STACK_LOCATION stack=IoGetCurrentIrpStackLocation(pIrp); //获取输入参数大小 ULONG cbin=stack->Parameters.DeviceIoControl.InputBufferLength; //获取输出参数大小 ULONG cbout=stack->Parameters.DeviceIoControl.OutputBufferLength; //得到IOCTL控制码 ULONG code=stack->Parameters.DeviceIoControl.IoControlCode; //获取设备扩展 PDEVICE_EXTENSION pDevExt=(PDEVICE_EXTENSION)pDevObj->DeviceExtension; //从用户模式传进来的微秒数 ULONG ulMircoSeconds=*(PULONG)pIrp->AssociatedIrp.SystemBuffer; switch (code) { case IOCTL_WAIT_METHOD1: { } break; default: status=STATUS_INVALID_VARIANT; } //设置IRP的完成状态 pIrp->IoStatus.Status=status; pIrp->IoStatus.Information=0; IoCompleteRequest(pIrp,IO_NO_INCREMENT); return status; } NTSTATUS MyIoCompletion(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp,IN PVOID Context) { #if DBG _asm int 3 #endif if (Irp->PendingReturned==TRUE) { //设置事件 KeSetEvent((PKEVENT)Context,IO_NO_INCREMENT,FALSE); } return STATUS_MORE_PROCESSING_REQUIRED; } NTSTATUS HelloDDKRead(IN PDEVICE_OBJECT pDevObj,IN PIRP pIrp) { #if DBG _asm int 3 #endif //将自己完成IRP,改成由底层驱动负责 DbgPrint("DriverB:Enter B HelloDDKRead\n"); PDEVICE_EXTENSION pdx=(PDEVICE_EXTENSION)pDevObj->DeviceExtension; //将本层的IRP栈拷贝到底层堆栈 IoCopyCurrentIrpStackLocationToNext(pIrp); //初始化事件 KEVENT event; KeInitializeEvent(&event,NotificationEvent,FALSE); //设置完成历程 IoSetCompletionRoutine(pIrp,MyIoCompletion,&event,TRUE,TRUE,TRUE); //调用底层驱动 NTSTATUS status=IoCallDriver(pdx->TargetDevice,pIrp); if (status==STATUS_PENDING) { KeWaitForSingleObject(&event,Executive,KernelMode,FALSE,NULL); status=pIrp->IoStatus.Status; } #if DBG _asm int 3 #endif //虽然在底层驱动已经将IRP完成了,但是由于完成历程返回的是 //STATUS_MORE_PROCESSING_REQUIRED,因此需要再次调用IoCompleteRequest IoCompleteRequest(pIrp,IO_NO_INCREMENT); return status; } NTSTATUS HelloDDKCreate(IN PDEVICE_OBJECT pDevObj,IN PIRP pIrp) { #if DBG _asm int 3 #endif DbgPrint("DriverB:Enter B HelloDDKCreate\n"); PDEVICE_EXTENSION pdx=(PDEVICE_EXTENSION)pDevObj->DeviceExtension; IoSkipCurrentIrpStackLocation(pIrp); NTSTATUS status= IoCallDriver(pdx->TargetDevice,pIrp); return status; } NTSTATUS HelloDDKClose(IN PDEVICE_OBJECT pDevObj,IN PIRP pIrp) { #if DBG _asm int 3 #endif DbgPrint("DriverB:Enter B HelloDDKClose\n"); PDEVICE_EXTENSION pdx=(PDEVICE_EXTENSION)pDevObj->DeviceExtension; IoSkipCurrentIrpStackLocation(pIrp); NTSTATUS status=IoCallDriver(pdx->TargetDevice,pIrp); return status; } //创建设备 NTSTATUS CreateDevice(PDRIVER_OBJECT pDriver_Object) { //定义变量 NTSTATUS status=STATUS_SUCCESS; PDEVICE_OBJECT pDevObj=NULL; PDEVICE_EXTENSION pDevExt=NULL; //初始化字符串 UNICODE_STRING devname; UNICODE_STRING symLinkName; RtlInitUnicodeString(&devname,L"\\device\\MyDDKDeviceB"); RtlInitUnicodeString(&symLinkName,L"\\??\\HelloDDKB"); //创建设备 status =IoCreateDevice(pDriver_Object,sizeof(DEVICE_EXTENSION),&devname,FILE_DEVICE_UNKNOWN,NULL,TRUE,&pDevObj); if (!NT_SUCCESS(status)) { DbgPrint("创建设备失败\n"); return status; } pDevObj->Flags |= DO_BUFFERED_IO;; pDevExt=(PDEVICE_EXTENSION)pDevObj->DeviceExtension; pDevExt->pDevice=pDevObj; pDevExt->ustrDeviceName=devname; pDevExt->ustrSymLinkName=symLinkName; //创建符号连接 status =IoCreateSymbolicLink(&symLinkName,&devname) ; if (!NT_SUCCESS(status)) { DbgPrint("创建符号连接失败\n"); IoDeleteDevice(pDevObj); return status; } return STATUS_SUCCESS; } //派遣函数 NTSTATUS HelloDDKDispatchRoutine(IN PDEVICE_OBJECT pDevObj,IN PIRP pIrP) { //#if DBG // _asm int 3 //#endif PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(pIrP); //建立一个字符串数组与IRP类型对应起来 static char* irpname[] = { "IRP_MJ_CREATE", "IRP_MJ_CREATE_NAMED_PIPE", "IRP_MJ_CLOSE", "IRP_MJ_READ", "IRP_MJ_WRITE", "IRP_MJ_QUERY_INFORMATION", "IRP_MJ_SET_INFORMATION", "IRP_MJ_QUERY_EA", "IRP_MJ_SET_EA", "IRP_MJ_FLUSH_BUFFERS", "IRP_MJ_QUERY_VOLUME_INFORMATION", "IRP_MJ_SET_VOLUME_INFORMATION", "IRP_MJ_DIRECTORY_CONTROL", "IRP_MJ_FILE_SYSTEM_CONTROL", "IRP_MJ_DEVICE_CONTROL", "IRP_MJ_INTERNAL_DEVICE_CONTROL", "IRP_MJ_SHUTDOWN", "IRP_MJ_LOCK_CONTROL", "IRP_MJ_CLEANUP", "IRP_MJ_CREATE_MAILSLOT", "IRP_MJ_QUERY_SECURITY", "IRP_MJ_SET_SECURITY", "IRP_MJ_POWER", "IRP_MJ_SYSTEM_CONTROL", "IRP_MJ_DEVICE_CHANGE", "IRP_MJ_QUERY_QUOTA", "IRP_MJ_SET_QUOTA", "IRP_MJ_PNP", }; UCHAR type = stack->MajorFunction; if (type >= CountArray(irpname)) KdPrint(("无效的IRP类型 %X\n", type)); else KdPrint(("%s\n", irpname[type])); pIrP->IoStatus.Status=STATUS_SUCCESS; //设置完成状态 pIrP->IoStatus.Information=0; //设置操作字节为0 IoCompleteRequest(pIrP,IO_NO_INCREMENT); //结束IRP派遣函数,第二个参数表示不增加优先级 return STATUS_SUCCESS; }
相关文章推荐
- 【笔试】1、斐波拉契数列
- 【Android开发经验】使用反射,得到的类的字段、方法、并实现了简单的调用
- administrator
- 数据挖掘主要解决的四类问题
- 自定义视图
- Improving the GPA 贪心 HDU4968
- 第一次编写opengl程序,遇到“无法打开包括文件:“gl\glaux.h”: No such file or directory”怎么办?
- poj 1276 Cash Machine 多重背包
- poj 1276 Cash Machine 多重背包
- minecraft花生壳怎样开服
- “TCP:三次握手”分析——以一个简单的“服务器”和“客户端”为例
- Reverse Integer
- @Controller's and AOP Proxying
- 小鱼收纳app V1.0.6 安卓版
- 音频播放
- Bootstrap 准备工作
- 首次使用pod遇到问题后在stackoverflow寻找的解决方案
- HDU 4095 Y (树上计数问题)
- HDU 3172 Virtual Friends
- boostrape 栅栏总结