windows驱动之间异步调用(一)

本文介绍了一种Windows驱动间同步调用的方法,重点讲解了如何通过异步读取操作实现两个驱动之间的通信,并利用事件来通知读取操作的完成。

需要配合Windows驱动同步调用文档代码,唯一修改的部分是DriverB_SyncCallStandartDriver的Read的派遣函数:

实现是通过将一个事件的指针传递给zwReadFile的函数的完成例程,在完成例程中触发改事件,当此事件触发时表示IRP_MJ_READ请求已经结束。


CPP代码:


///////////////////////////////////////////////////////////////////////////////
///
/// Copyright (c) 2014 - <company name here>
///
/// Original filename: DriverB_SyncCallStandartDriver.cpp
/// Project          : DriverB_SyncCallStandartDriver
/// Date of creation : 2014-06-24
/// Author(s)        : <author name(s)>
///
/// Purpose          : <description>
///
/// Revisions:
///  0000 [2014-06-24] Initial revision.
///
///////////////////////////////////////////////////////////////////////////////

// $Id$

#ifdef __cplusplus
extern "C" {
#endif
#include <ntddk.h>
#include <string.h>
#ifdef __cplusplus
}; // extern "C"
#endif

#include "DriverB_SyncCallStandartDriver.h"

#ifdef __cplusplus
namespace { // anonymous namespace to limit the scope of this global variable!
#endif
PDRIVER_OBJECT pdoGlobalDrvObj = 0;
#ifdef __cplusplus
}; // anonymous namespace
#endif

NTSTATUS DRIVERBSYNCCALLSTANDARTDRIVER_DispatchCreateClose(
    IN PDEVICE_OBJECT		DeviceObject,
    IN PIRP					Irp
    )
{
    NTSTATUS status = STATUS_SUCCESS;
    Irp->IoStatus.Status = status;
    Irp->IoStatus.Information = 0;
    IoCompleteRequest(Irp, IO_NO_INCREMENT);
    return status;
}

NTSTATUS DRIVERBSYNCCALLSTANDARTDRIVER_DispatchDeviceControl(
    IN PDEVICE_OBJECT		DeviceObject,
    IN PIRP					Irp
    )
{
    NTSTATUS status = STATUS_SUCCESS;
    PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation(Irp);

    switch(irpSp->Parameters.DeviceIoControl.IoControlCode)
    {
    case IOCTL_DRIVERBSYNCCALLSTANDARTDRIVER_OPERATION:
        // status = SomeHandlerFunction(irpSp);
        break;
    default:
        Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
        Irp->IoStatus.Information = 0;
        break;
    }

    status = Irp->IoStatus.Status;
    IoCompleteRequest(Irp, IO_NO_INCREMENT);
    return status;
}

VOID DRIVERBSYNCCALLSTANDARTDRIVER_DriverUnload(
    IN PDRIVER_OBJECT		DriverObject
    )
{
    PDEVICE_OBJECT pdoNextDeviceObj = pdoGlobalDrvObj->DeviceObject;
    IoDeleteSymbolicLink(&usSymlinkName);

    // Delete all the device objects
    while(pdoNextDeviceObj)
    {
        PDEVICE_OBJECT pdoThisDeviceObj = pdoNextDeviceObj;
        pdoNextDeviceObj = pdoThisDeviceObj->NextDevice;
        IoDeleteDevice(pdoThisDeviceObj);
    }

	KdPrint(("DriverB_SyncCallStandartDriver.-DriverUnload.."));

}


typedef struct _DEVICE_EXTENSION 
{
	PDEVICE_OBJECT pDebObj;
	UNICODE_STRING usDevName;
	UNICODE_STRING usLinkName;
	PIRP pIrp;


}DEIVCE_EXTENSION,*PDEVICE_EXTENSION;


void completeCallStandardDriver(PVOID context,PIO_STATUS_BLOCK pStatusBlock,ULONG uVal)
{
	KdPrint(("completeCallStandardDriver...."));

	KeSetEvent((PRKEVENT)context,IO_NO_INCREMENT,FALSE);
}

NTSTATUS ReadDispatch(PDEVICE_OBJECT pDevObj,PIRP pIrp)
{
	/* //同步调用标准驱动
NTSTATUS status = STATUS_SUCCESS;

	UNICODE_STRING usStarDeviceName;
	RtlInitUnicodeString(&usStarDeviceName,L"\\Device\\STANDARDDRIVER_DeviceName");//标准取得的设备名

	OBJECT_ATTRIBUTES objAttr;
	InitializeObjectAttributes(
		&objAttr,
		&usStarDeviceName,
		OBJ_CASE_INSENSITIVE,
		NULL,
		NULL);

	HANDLE hdlDevive = NULL;

	IO_STATUS_BLOCK ioSb;

	status =  ZwCreateFile(
		&hdlDevive,
		FILE_READ_ATTRIBUTES | SYNCHRONIZE,
		&objAttr,
		&ioSb,
		NULL,
		FILE_ATTRIBUTE_NORMAL,
		FILE_SHARE_READ,
		FILE_OPEN_IF,
		FILE_SYNCHRONOUS_IO_NONALERT,
		NULL,
		0);

	if (NT_SUCCESS(status))
	{


		status = ZwReadFile(
			hdlDevive,
			NULL,
			NULL,
			NULL,
			&ioSb,
			NULL,
			0,
			NULL,
			NULL
			);

	}

	ZwClose(hdlDevive);
	

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

	KdPrint(("DriverB_SyncCallStandartDriver.-readDispatch.."));
*/


	NTSTATUS status = STATUS_SUCCESS;

	UNICODE_STRING usStarDeviceName;
	RtlInitUnicodeString(&usStarDeviceName,L"\\Device\\STANDARDDRIVER_DeviceName");//标准取得的设备名

	OBJECT_ATTRIBUTES objAttr;
	InitializeObjectAttributes(
		&objAttr,
		&usStarDeviceName,
		OBJ_CASE_INSENSITIVE,
		NULL,
		NULL);

	HANDLE hdlDevive = NULL;

	IO_STATUS_BLOCK ioSb;

	//异步调用
	status =  ZwCreateFile(
		&hdlDevive,
		FILE_READ_ATTRIBUTES ,//| SYNCHRONIZE,
		&objAttr,
		&ioSb,
		NULL,
		FILE_ATTRIBUTE_NORMAL,
		FILE_SHARE_READ,
		FILE_OPEN_IF,
		FILE_SHARE_READ,//FILE_SYNCHRONOUS_IO_NONALERT,
		NULL,
		0);


	KEVENT asyncEvent;
	KeInitializeEvent(&asyncEvent,SynchronizationEvent,FALSE);
	LARGE_INTEGER lOffSet = RtlConvertLongToLargeInteger((ULONG)0);


	if (NT_SUCCESS(status))
	{

		//异步调用,添加完成例程
		status = ZwReadFile(
			hdlDevive,
			NULL,completeCallStandardDriver,
			&asyncEvent,
			&ioSb,
			NULL,
			0,
			&lOffSet,
			NULL
			);

		if (status == STATUS_PENDING)
		{
			KeWaitForSingleObject(&asyncEvent,Executive,KernelMode,FALSE,NULL);
		}

	}

	ZwClose(hdlDevive);


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

	KdPrint(("DriverB_SyncCallStandartDriver.-readDispatch.."));

	return status;
}


#ifdef __cplusplus
extern "C" {
#endif
NTSTATUS DriverEntry(
    IN OUT PDRIVER_OBJECT   DriverObject,
    IN PUNICODE_STRING      RegistryPath
    )
{
    PDEVICE_OBJECT pdoDeviceObj = 0;
    NTSTATUS status = STATUS_UNSUCCESSFUL;
    pdoGlobalDrvObj = DriverObject;


	KdPrint(("DriverB_SyncCallStandartDriver.-DriverEntry.."));



    // Create the device object.
    if(!NT_SUCCESS(status = IoCreateDevice(
        DriverObject,
        0,
        &usDeviceName,
        FILE_DEVICE_UNKNOWN,
        FILE_DEVICE_SECURE_OPEN,
        FALSE,
        &pdoDeviceObj
        )))
    {
        // Bail out (implicitly forces the driver to unload).
        return status;
    };

    // Now create the respective symbolic link object
    if(!NT_SUCCESS(status = IoCreateSymbolicLink(
        &usSymlinkName,
        &usDeviceName
        )))
    {
        IoDeleteDevice(pdoDeviceObj);
        return status;
    }

    // NOTE: You need not provide your own implementation for any major function that
    //       you do not want to handle. I have seen code using DDKWizard that left the
    //       *empty* dispatch routines intact. This is not necessary at all!
    DriverObject->MajorFunction[IRP_MJ_CREATE] =
    DriverObject->MajorFunction[IRP_MJ_CLOSE] = DRIVERBSYNCCALLSTANDARTDRIVER_DispatchCreateClose;
    DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DRIVERBSYNCCALLSTANDARTDRIVER_DispatchDeviceControl;
	DriverObject->MajorFunction[IRP_MJ_READ] = ReadDispatch;
    DriverObject->DriverUnload = DRIVERBSYNCCALLSTANDARTDRIVER_DriverUnload;

    return STATUS_SUCCESS;
}
#ifdef __cplusplus
}; // extern "C"
#endif


其他部分代码和  windows驱动之间同步调用实例 相同。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值