驱动程序之间调用实例,以读操作模拟调用。
调用过程:exe------->DRIVERBSYNCCALLSTANDARTDRIVER_DeviceName----->STANDARDDRIVER_DeviceName
说明:exe程序调用驱动DRIVERBSYNCCALLSTANDARTDRIVER_DeviceName,此驱动再读派遣函数内调用驱动STANDARDDRIVER_DeviceName,STANDARDDRIVER_DeviceName添加了一个延时DPC调用,当STANDARDDRIVER_DeviceName驱动将IRP完成时,DRIVERBSYNCCALLSTANDARTDRIVER_DeviceName读操作才能完成返回,然后exe程序的readFile函数才可返回。
exe代码:
// TestCallDriver.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include "TestCallDriver.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// 唯一的应用程序对象
CWinApp theApp;
using namespace std;
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
int nRetCode = 0;
// 初始化 MFC 并在失败时显示错误
if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
{
// TODO: 更改错误代码以符合您的需要
_tprintf(_T("错误: MFC 初始化失败\n"));
nRetCode = 1;
}
else
{
// TODO: 在此处为应用程序的行为编写代码。
}
HANDLE hdl = CreateFile(L"\\\\.\\DRIVERBSYNCCALLSTANDARTDRIVER_DeviceName",
GENERIC_WRITE | GENERIC_READ,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
if (hdl == INVALID_HANDLE_VALUE)
{
CString csLog;
csLog.Format(L"CreateFile Error:%d",GetLastError());
AfxMessageBox(csLog);
return -1;
}
DWORD dwRetLen = 0;
BOOL bRetRead = ReadFile(hdl,NULL,0,&dwRetLen,NULL);
if (bRetRead)
{
cout<<"ReadFile OK!"<<endl;
}
CloseHandle(hdl);
system("PAUSE");
return nRetCode;
}
DRIVERBSYNCCALLSTANDARTDRIVER_DeviceName代码:
///
///
/// 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;
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.."));
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
STANDARDDRIVER_DeviceName代码:
///
///
/// Copyright (c) 2014 - <company name here>
///
/// Original filename: StandardDriver.cpp
/// Project : StandardDriver
/// 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 "StandardDriver.h"
#ifdef __cplusplus
namespace { // anonymous namespace to limit the scope of this global variable!
#endif
PDRIVER_OBJECT pdoGlobalDrvObj = 0;
#ifdef __cplusplus
}; // anonymous namespace
#endif
typedef struct _DEVICE_EXTENSION
{
UNICODE_STRING usDevName;
UNICODE_STRING usLinkName;
PDEVICE_OBJECT pDevObj;
KDPC pollingDPC;//存储DPC对象
KTIMER pollingTimer;//存储计时器对象
PIRP pendingIrp;//记录当前挂起的IRP
}DEVICE_EXTENSION,*PDEVICE_EXTENSION;
VOID TimerDpc(
__in struct _KDPC *Dpc,
__in_opt PVOID DeferredContext,
__in_opt PVOID SystemArgument1,
__in_opt PVOID SystemArgument2
)
{
PDEVICE_OBJECT pDevObj = (PDEVICE_OBJECT)DeferredContext;
PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)pDevObj->DeviceExtension;
PIRP currentPendingIrp = pDevExt->pendingIrp;
NTSTATUS status = STATUS_SUCCESS;
currentPendingIrp->IoStatus.Status = status;
currentPendingIrp->IoStatus.Information = 0;
IoCompleteRequest(currentPendingIrp,IO_NO_INCREMENT);
KdPrint(("StandardDriver-TimerDpc.."));
}
NTSTATUS STANDARDDRIVER_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 STANDARDDRIVER_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_STANDARDDRIVER_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 STANDARDDRIVER_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(("StandardDriver-DriverUnload.."));
}
NTSTATUS StandardDriver_ReadDispath(PDEVICE_OBJECT pDevObj,PIRP pIrp)
{
NTSTATUS status = STATUS_SUCCESS;
PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)pDevObj->DeviceExtension;
IoMarkIrpPending(pIrp);
pDevExt->pendingIrp = pIrp;
ULONG uMicroSec = 3000000;
LARGE_INTEGER lTime = RtlConvertLongToLargeInteger(-10*uMicroSec);
KeSetTimer(&(pDevExt->pollingTimer),lTime,&(pDevExt->pollingDPC));
status = STATUS_PENDING;
KdPrint(("StandardDriver-ReadDispath.."));
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(("StandardDriver-DriverEntry.."));
// Create the device object.
if(!NT_SUCCESS(status = IoCreateDevice(
DriverObject,
sizeof(DEVICE_EXTENSION),//0,
&usDeviceName,
FILE_DEVICE_UNKNOWN,
FILE_DEVICE_SECURE_OPEN,
FALSE,
&pdoDeviceObj
)))
{
// Bail out (implicitly forces the driver to unload).
return status;
};
PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)pdoDeviceObj->DeviceExtension;
pDevExt->usDevName = usDeviceName;
pDevExt->usLinkName = usSymlinkName;
pDevExt->pDevObj = pdoDeviceObj;
KeInitializeDpc(&(pDevExt->pollingDPC),TimerDpc,(PVOID)pdoDeviceObj);
KeInitializeTimer(&(pDevExt->pollingTimer));
pdoDeviceObj->Flags |= DO_BUFFERED_IO;
// 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] = STANDARDDRIVER_DispatchCreateClose;
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = STANDARDDRIVER_DispatchDeviceControl;
DriverObject->MajorFunction[IRP_MJ_READ] = StandardDriver_ReadDispath;
DriverObject->DriverUnload = STANDARDDRIVER_DriverUnload;
return STATUS_SUCCESS;
}
#ifdef __cplusplus
}; // extern "C"
#endif