驱动中以文件句柄形式调用其他驱动程序(异步调用二)
2015-08-07 11:38
281 查看
EXE部分
SYS部分(驱动B调用驱动A异步方式)
#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部分(驱动B调用驱动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; //符号名称 }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(("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 HelloDDKRead(IN PDEVICE_OBJECT pDevObj,IN PIRP pIrp) { #if DBG _asm int 3 #endif DbgPrint("DriverB:Enter B HelloDDKRead\n"); NTSTATUS status=STATUS_SUCCESS; UNICODE_STRING DeviceName; RtlInitUnicodeString(&DeviceName,L"\\device\\MyDDKDeviceA"); //初始化objectAttributes; OBJECT_ATTRIBUTES objectAttributes; InitializeObjectAttributes(&objectAttributes,&DeviceName,OBJ_CASE_INSENSITIVE,NULL,NULL); //异步打开设备 HANDLE hDevice=NULL; IO_STATUS_BLOCK status_block; //没有设定FILE_SYNCHRONOUS_IO_NONALERT或者FILE_SYNCHRONOUS_IO_ALERT为异步打开设备 status=ZwCreateFile(&hDevice, FILE_READ_ATTRIBUTES,//没有设置SYNCHRONIZE, &objectAttributes, &status_block, NULL, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ, FILE_OPEN_IF, NULL, NULL, NULL); LARGE_INTEGER offset=RtlConvertLongToLargeInteger(0); //判断文件打开成功 if (NT_SUCCESS(status)) { status= ZwReadFile(hDevice,NULL,NULL,NULL,&status_block,NULL,NULL,&offset,NULL); } #if DBG _asm int 3 #endif if (status==STATUS_PENDING) { DbgPrint("DriverB:ZwReadFile return STATUS_PENDING\n"); DbgPrint("DriverB:Waiting...\n"); //获得和设备相关的文件对象指针 PFILE_OBJECT FileObject; status=ObReferenceObjectByHandle(hDevice,EVENT_MODIFY_STATE,*IoFileObjectType,KernelMode,(PVOID*)&FileObject,NULL); if (NT_SUCCESS(status)) { //当IRP_MJ_READ请求被结束后,文件对象的子域Event会被设置,因此用文件对象的Event子域当作同步点使用 KeWaitForSingleObject(&FileObject->Event,Executive,KernelMode,FALSE,NULL); ObDereferenceObject(FileObject); } else if (status==STATUS_OBJECT_TYPE_MISMATCH) { DbgPrint("ERROR\n"); } else if (status==STATUS_ACCESS_DENIED) { DbgPrint("ERROR\n"); } else if (status==STATUS_INVALID_HANDLE) { DbgPrint("ERROR\n"); } else { DbgPrint("ERROR\n"); } } #if DBG _asm int 3 #endif ZwClose(hDevice); //完成IRP pIrp->IoStatus.Status=STATUS_SUCCESS; pIrp->IoStatus.Information=0; IoCompleteRequest(pIrp,IO_NO_INCREMENT); return STATUS_SUCCESS; } NTSTATUS HelloDDKCreate(IN PDEVICE_OBJECT pDevObj,IN PIRP pIrp) { #if DBG _asm int 3 #endif DbgPrint("DriverB:Enter B 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("DriverB:Enter B 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\\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; }
相关文章推荐
- 【Lua、LuaJIT、tolua++、lua for windows】这几个到底有什么关系?!
- WPF 3D 知识点大全以及实例
- SAP HR 工资状态和控制记录(转)
- 新浪微博共享登录后无法退出切换账号问题解决
- ThinkPHP学习笔记( 一)安装配置
- 解决MAVEN内存溢出
- Java ConcurrentModificationException 异常分析与解决方案
- Windows/MFC_ 如何判断CString类型是否为空
- editui界面常用代码
- jQuery使用animate创建动画用法实例
- 电脑在IDE模式下能正常启动,改成AHCI后蓝屏——解决方法
- KMP Oulipo
- 44. Element insertBefore() 方法
- 禁用触发器的N种方法
- HDU5363:Key Set
- .net导出EXCEL
- 启动mongodb报1067错误
- php静态文件配置
- debug_toolbar的安装配置
- CAS单点登录(SSO)完整教程