需要配合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