码迷,mamicode.com
首页 > 其他好文 > 详细

驱动程序调用驱动程序1

时间:2014-05-08 12:04:23      阅读:315      评论:0      收藏:0      [点我收藏+]

标签:style   code   ext   int   get   c   

除了在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,布布扣,bubuko.com

驱动程序调用驱动程序1

标签:style   code   ext   int   get   c   

原文地址:http://www.cnblogs.com/adylee/p/3714287.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!