驱动程序调用驱动程序1

除了在Win32下面可以调用ReadFile,
WriteFile之类的函数打开设备对象, 在内核中也是可以的, 而且方法比用户态这边更多.
首先这种方法就是Win32上面相同的方式了, 直接打开设备. 内核也有一套函数类似Win32下面的CreateFile,
WriteFile, ReadFile.

下面代码那个写入设备基本就没有什么好说的.
和Win32上面的套路差不多, Win32上面其实也有一个WriteFileEx. 就是可以设置回调函数那个.
内核里面的函数就合二为一了, 都是ZwWriteFile,看心情, 如果喜欢用回调函数那就用回调函数.
如果不喜欢用回调函数那么就NULL, 就OK了..

在打开设备的时候不但可以使用设备名称来打开,
也可以利用符号链接名称来打开, 总之Win32下面有的, 内核里面都有了,
而且更暴力!很好很强大!
 
 主要说说这个读取设备这块, 读取设备的时候, 也用了事件对象,
不过这里的事件对象用的是设备句柄的文件句柄, 我倒. 有点绕啊, 其实是这样的, 每打开一个文件句柄,
都会伴随着存在一个关联的文件对象(File_Object). 利用内核函数ObReferenceObjectByHandle可以获取设备相关的文件句柄的指针.当IRP_MJ_READ请求被结束的时候,
文件对象的Event会被设置,
因此可以利用这个Event对象来做同步.下面的代码正是这样做的. 当然, 这个要记得在后面调用ObDereferenceObject,
来解引用.

我在调用ObReferenceObjectByHandle的时候老是返回失败,
后来google一下, 发现第3个参数设置为NULL就没有问题了,
所以我也就这样做了. 不知为何. 这里先留下这个问题. 回头再倒腾!

现在这套打开设备, 读写的函数.
其实和Win32下面是差不多的, 所以不说了. 直接上代码:首先是测试驱动:

/*
Windows 内核下驱动程序调用驱动程序 测试驱动
编译方法参见makefile. TAB = 8
*/
#include <ntddk.h>

#define DEVICE_NAME L"\\Device\\DevTestDriver"
#define SYSLINK_NAME L"\\??\\SysLinkTestDriver"

typedef struct tagDeviceExt {
KDPC StDpc;
PIRP pIrp;
KTIMER StTimer;
PVOID pBuf;
PDEVICE_OBJECT pDeviceObj;
UNICODE_STRING USzDeviceName;
UNICODE_STRING USzSysLinkName;
} DEVICE_EXT, *PDEVICE_EXT;

//===========================================================================
//驱动卸载例程
//===========================================================================
#pragma code_seg( "PAGE" )
VOID DriverUnLoad( PDRIVER_OBJECT pDriverObj ) {
PDEVICE_EXT pDeviceExt = NULL;
PDEVICE_OBJECT pNextDeviceObj = NULL;

pNextDeviceObj = pDriverObj->DeviceObject;

while ( pNextDeviceObj != NULL ) {
pDeviceExt = pNextDeviceObj->DeviceExtension;

IoDeleteDevice( pDeviceExt->pDeviceObj );
IoDeleteSymbolicLink( &pDeviceExt->USzSysLinkName );

if ( pDeviceExt->pBuf != NULL ) {
ExFreePool( pDeviceExt->pBuf );
}

KdPrint( ( "删除设备%wZ成功!\n", &pDeviceExt->USzDeviceName ) );
pNextDeviceObj = pNextDeviceObj->NextDevice;
}
}
//===========================================================================
//所有不关系的Irp处理
//===========================================================================
NTSTATUS DispathRoutine( PDEVICE_OBJECT pDeviceObj, PIRP pIrp ) {

pIrp->IoStatus.Information = 0;
pIrp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest( pIrp, IO_NO_INCREMENT );

return STATUS_SUCCESS;
}
//===========================================================================
//超时Dpc例程
//===========================================================================
#pragma code_seg()
VOID OnTimerDpc( PKDPC pDpc, PVOID pContext, PVOID SysArg1, PVOID SysArg2 ) {
PIRP pIrp = NULL;
PCHAR pBuf = NULL;
ULONG ulBufLen, i;
NTSTATUS Status;
PDEVICE_EXT pDeviceExt = NULL;
PDEVICE_OBJECT pDeviceObj = NULL;
PIO_STACK_LOCATION Stack = NULL;

PAGED_CODE_LOCKED();
//---------------------------------------------------------------------------
pDeviceObj = ( PDEVICE_OBJECT )pContext;
pDeviceExt = pDeviceObj->DeviceExtension;

pIrp = pDeviceExt->pIrp;
ASSERT ( pIrp != NULL );

Stack = IoGetCurrentIrpStackLocation( pIrp );
Status = STATUS_SUCCESS;

do {
pBuf = pIrp->AssociatedIrp.SystemBuffer;
if ( pBuf == NULL ) {
ulBufLen = 0;
Status = STATUS_UNSUCCESSFUL;
break;
}
//---------------------------------------------------------------------------
if ( Stack->MajorFunction == IRP_MJ_WRITE ) {

ulBufLen = Stack->Parameters.Write.Length;

for( i = 0; i < ulBufLen; i++ ) {
KdPrint( ( "%c\t", *( pBuf + i ) ) );
}
KdPrint( ( "\n" ) );

pDeviceExt->pBuf = ExAllocatePool( NonPagedPool, ulBufLen );
ASSERT( pDeviceExt->pBuf );

RtlCopyMemory( pDeviceExt->pBuf, pBuf, ulBufLen );

KdPrint( ( "TestDriver: 超时Dpc例程IRP_MJ_WRITE离开!\n" ) );
//---------------------------------------------------------------------------
} else if( Stack->MajorFunction == IRP_MJ_READ ) {

ulBufLen = Stack->Parameters.Read.Length;

ASSERT( pDeviceExt->pBuf != NULL );

RtlCopyMemory( pBuf, pDeviceExt->pBuf, ulBufLen );

KdPrint( ( "TestDriver: 超时Dpc例程IRP_MJ_READ离开!\n" ) );
}

} while ( FALSE );

pIrp->IoStatus.Information = ulBufLen;
pIrp->IoStatus.Status = Status;
IoCompleteRequest( pIrp, IO_NO_INCREMENT );
}
//===========================================================================
//写入请求
//===========================================================================
#pragma code_seg( "PAGE" )
NTSTATUS DispatchWrite ( PDEVICE_OBJECT pDeviceObj, PIRP pIrp ) {
LARGE_INTEGER liTimeOut;
PDEVICE_EXT pDeviceExt = NULL;

pDeviceExt = pDeviceObj->DeviceExtension;
pDeviceExt->pIrp = pIrp;

//挂起Irp
IoMarkIrpPending( pIrp );

//设置超时时间为3S
liTimeOut = RtlConvertLongToLargeInteger( -10 * 3000 * 1000 );

//开启定时器
KeSetTimer( &pDeviceExt->StTimer, liTimeOut, &pDeviceExt->StDpc );

KdPrint( ( "TestDriver: DispatchWrite挂起!\n" ) );
return STATUS_PENDING;
}
//===========================================================================
//读取请求
//===========================================================================
NTSTATUS DispatchRead( PDEVICE_OBJECT pDeviceObj, PIRP pIrp ) {
LARGE_INTEGER liTimeOut;
PDEVICE_EXT pDeviceExt = NULL;

pDeviceExt = pDeviceObj->DeviceExtension;
pDeviceExt->pIrp = pIrp;

//挂起Irp
IoMarkIrpPending( pIrp );

//设置超时时间为3S
liTimeOut = RtlConvertLongToLargeInteger( -10 * 3000 * 1000 );

//开启定时器
KeSetTimer( &pDeviceExt->StTimer, liTimeOut, &pDeviceExt->StDpc );

KdPrint( ( "TestDriver: DispatchRead 挂起!\n" ) );
return STATUS_PENDING;
}

//===========================================================================
//驱动入口
//===========================================================================
#pragma code_seg( "INIT" )
NTSTATUS DriverEntry( PDRIVER_OBJECT pDriverObj, PUNICODE_STRING pUSzRegPath ) {
NTSTATUS Status;
ULONG i;
PDEVICE_OBJECT pDeviceObj = NULL;
PDEVICE_EXT pDeviceExt = NULL;
UNICODE_STRING USzDeviceName = RTL_CONSTANT_STRING( DEVICE_NAME );
UNICODE_STRING USzSysLinkName = RTL_CONSTANT_STRING( SYSLINK_NAME );

Status = IoCreateDevice( pDriverObj, sizeof( DEVICE_EXT ), &USzDeviceName,
FILE_DEVICE_UNKNOWN, 0, TRUE, &pDeviceObj );

if ( !NT_SUCCESS( Status ) ) {
KdPrint( ( "创建设备失败!\n" ) );
return Status;
}

// Status = IoCreateSymbolicLink( &USzSysLinkName, &USzDeviceName );
// if ( !NT_SUCCESS( Status ) ) {
// KdPrint( ( "创建符号链接失败!\n" ) );
// IoDeleteDevice( pDeviceObj );
// }

pDeviceObj->Flags |= DO_BUFFERED_IO;
pDeviceExt = pDeviceObj->DeviceExtension;
pDeviceExt->pDeviceObj = pDeviceObj;
pDeviceExt->USzDeviceName = USzDeviceName;
pDeviceExt->USzSysLinkName = USzSysLinkName;
pDeviceExt->pBuf = NULL;

//初始化Timer对象和定时器对象
KeInitializeTimer( &pDeviceExt->StTimer );
KeInitializeDpc( &pDeviceExt->StDpc, &OnTimerDpc, ( PVOID ) pDeviceObj );

for( i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++ ) {
pDriverObj->MajorFunction[i] = &DispathRoutine;
}
pDriverObj->MajorFunction[IRP_MJ_WRITE] = &DispatchWrite;
pDriverObj->MajorFunction[IRP_MJ_READ] = &DispatchRead;
pDriverObj->DriverUnload = &DriverUnLoad;

return Status;
}


驱动程序调用驱动程序1

时间: 2024-10-12 22:33:01

驱动程序调用驱动程序1的相关文章

驱动程序调用驱动程序2

上一篇说到内核里面用户态这边差不多的函数, 比如ZwCreateFile, ZwReadFile什么之类的, 内核里面其实还有些更加暴力的东西存在的, 比如说用户态这边打开设备只有一个句柄, 但是内核里面是可以直接触摸到指针的, 用户态那边只可以调用几个固定的函数来发送Irp. 那么内核里面可以自定义Irp的发送, 非常的暴力, 好用! 首先我们也不用去调用什么ZwCreateFile了, 直接用这个IoGetDeviceObjectPointer函数, 这个函数可以通过设备名获得文件对象指针,

PCI/PCIe接口卡Windows驱动程序(4)- 驱动程序代码(源文件)

本篇文章将对PCIe驱动程序的源文件代码作详细解释与说明.整个WDF驱动程序工程共包含4个头文件(已经在上篇文章中讲解)和3个.c文件(Driver.c  Device.c   Queue.c) Driver.c 在看复杂的代码前,先给出程序流程图 1 #include "driver.h" 2 #include "driver.tmh" 3 4 #ifdef ALLOC_PRAGMA 5 #pragma alloc_text (INIT, DriverEntry)

《Linux Device Drivers》第六章 高级字符驱动程序操作——note

ioctl 支持的操作,例如 简单数据传输 控制动作,例如用户空间发起弹出介质动作 反馈硬件的状态,例如报告错误信息 参数配置,例如改变波特率 执行自破坏 用户空间的ioctl方法原型:int ioctl(int fd, unsigned long cmd, -);每个ioctl命令就是一个独立的系统调用,而且是非公开的 驱动程序的ioctl方法原型:int (*ioctl) (struct inode *inode, struct file *filp, unsigned int cmd, u

linux驱动程序之电源管理之linux的电源管理架构(3)

设备电源管理 Copyright (c) 2010 Rafael J. Wysocki<[email protected]>, Novell Inc. Copyright (c) 2010 Alan Stern[email protected] ************************************************************* 本文由DroidPhone翻译于2011.8.5 ***************************************

【Linux 驱动】设备驱动程序再理解

学习设备驱动编程也有一段时间了,也写过了几个驱动程序,因此有对设备驱动程序有了一些新的理解和认识,总结一下.学习设备驱动编程也有一段时间了,也写过了几个驱动程序,因此有对设备驱动程序有了一些新的理解和认识,总结一下. ★什么是驱动程序 刚开始学习设备驱动程序的时候,产生了许多的问题.什么是驱动程序?驱动程序是干嘛的?它是如何工作的?它又是如何跟操作系统联系起来的?一系列的问题,现在有些地方还是不一定清楚,但是相比起刚开始的那个阶段,感觉自己还是清楚了很多. 设备驱动程序说白了(实质)就是为应用程

Windows打印体系结构之Windows内置打印驱动程序

时间是一种很残酷的东西,它只会冲淡能够冲淡的,但也会洗尽铅华帮你留下该留下的. 1.3.4.Windows内置打印驱动程序 现在的Windows下的打印机驱动程序通常分为V4打印机驱动程序(V4 Printer Driver).XPS打印机驱动程序(XPSDrv).微软通用打印机驱动程序(Microsoft UniversalPrinter Driver).微软PostScript打印机驱动程序(Microsoft PostScriptPrinter Driver)和微软绘图仪驱动程序(Micr

为不同版本的 Windows 编写驱动程序

MSDN原文:https://msdn.microsoft.com/zh-cn/library/windows/hardware/ff554887(v=vs.85).aspx 创建驱动程序项目时,指定基本的目标操作系统,该系统是运行驱动程序的基本版本的 Windows.例如,你可以指定 Windows 7 为基本的目标操作系统.在这种情况下,驱动程序会在 Windows 7 和更高版本的 Windows 上运行. 注意  如果为特定的基本版本的 Windows 开发驱动程序且希望驱动程序运行在更

基于WDF的PCI/PCIe接口卡Windows驱动程序(5)-如何为硬件移植驱动程序

原文地址:http://www.cnblogs.com/jacklu/p/6139347.html 正如前几篇博客所说,使用WDF开发PCIe驱动程序是我本科毕业设计的主要工作.在读研的两年,我也分别为所在课题组移植了自己编写的驱动程序,在Windows 32位和64位平台下的PXI.PXIe.PCI.PCIe板卡分别得到了验证. 这篇文章根据自己最新编写的驱动代码(源代码请找博主索取),主要讲述如何为自己的硬件板卡移植驱动程序,并简单讲述如何使用Altera系列FPGA配置PCI IP核,然后

驱动程序简单开发

我们学习程序设计,都是从“Hello World”开始的,驱动程序也不例外,今天我就写一个驱动版的“Hello World”来热热身,目的希望大家能对驱动程序的基本框架有所了解. 驱动程序分为2类,一个是Kernel模式驱动,另一个是Windows模式驱动,2种模式本质是相同,但细节不同,本文介绍的是内核模式驱动和驱动程序的安装.使用. 驱动程序同普通的EXE,DLL一样,都属于PE文件,而且都有一个入口函数.但EXE中,入口函数是main()/WinMain()和Unicode的wmain()