天天看点

应用层与驱动层通信DeviceIoControl

驱动层与应用层通信是通过DeviceIoControl,

首先驱动层要实现:

pDriverObject->DriverUnload = MyDriverUnload;

pDriverObject->MajorFunction[IRP_MJ_CREATE] = MyCreate;

pDriverObject->MajorFunction[IRP_MJ_CLOSE] = MyClose;

pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = MyDispatchDeviceControl;

其中MyDispatchDeviceControl用来与应用层通过DeviceIoControl通信

NTSTATUS

MyDispatchDeviceControl(

 IN PDEVICE_OBJECT DeviceObject,

 IN PIRP Irp

 )

{

NTSTATUS             status = STATUS_SUCCESS;

PVOID                context;

KEVENT               waitEvent;

PIO_STACK_LOCATION   irpSp;

ULONG                ioControlCode = 0;

PAGED_CODE();

//DbgPrint(("MyDispatchDeviceControlbegin \n"));

//if (IS_MY_CONTROL_DEVICE_OBJECT(DeviceObject)) 

//{

//

//}

DbgPrint("%s begin... \r\n", __FUNCTION__);

irpSp = IoGetCurrentIrpStackLocation(Irp);

//控制码

ioControlCode = irpSp->Parameters.DeviceIoControl.IoControlCode;

DbgPrint("[%d, %d] \r\n", irpSp->MajorFunction, irpSp->MinorFunction);

switch(ioControlCode)

{

case 4096://4096只是临时定义一个值

{

DbgPrint("get iocontrol code %x \r\n", 

ioControlCode);

//输入缓冲区大小,缓冲区数据,如果应用层传入的不止单纯的字符串则最好打印16进制,而不是打印%s

DbgPrint("in: size %d [%s] \r\n", 

irpSp->Parameters.DeviceIoControl.InputBufferLength,

Irp->AssociatedIrp.SystemBuffer);

//给输入缓冲区赋值,并设置其大小,

RtlCopyMemory((char*)Irp->AssociatedIrp.SystemBuffer, "i get it", strlen("i get it"));

Irp->IoStatus.Information = strlen((char*)Irp->AssociatedIrp.SystemBuffer) + 1;

//打印输出数据,可以跟应用层获取到的数据进行比较

DbgPrint("out : size %d [%s] \r\n", 

Irp->IoStatus.Information, 

Irp->AssociatedIrp.SystemBuffer);

}

break;

default:

{

DbgPrint("unknow control code \r\n");

}

break;

}

Irp->IoStatus.Status = STATUS_SUCCESS;

IoCompleteRequest( Irp, IO_NO_INCREMENT );

return status;

}

然后应用层要打开驱动层的设备链接符号,来得到句柄,DeviceIoControl的通信依赖句柄

void TestDriver()

{

FILE               *pFile = NULL;

HANDLE             hDevice = INVALID_HANDLE_VALUE;

DWORD              retCount = 0;

char               szControl[100];

char               szRet[100];

hDevice = CreateFile(SYMBOLLINK_NAME,  

GENERIC_WRITE | GENERIC_READ,  

FILE_SHARE_WRITE|FILE_SHARE_READ,  

NULL,  

OPEN_EXISTING,  

FILE_ATTRIBUTE_NORMAL,  

NULL);  

if( hDevice != INVALID_HANDLE_VALUE )  

{

_tprintf(_T("Create Device %s ok ! \r\n"), SYMBOLLINK_NAME);  

}

else  

{

_tprintf(_T("Create Device %s faild %d ! \r\n"), SYMBOLLINK_NAME, GetLastError() );

return;

 }

do 

{

scanf("%s", szControl);

//strcpy(szControl, "hello world");

//retCount = 100;

//4096只是临时定义一个值

DeviceIoControl(hDevice, 4096, szControl, strlen(szControl), szRet, sizeof(szRet), &retCount, NULL);

//打印驱动层返回的数据,可以跟驱动层内部打印对比

_tprintf(_T("device io control done\r\n"));

printf("get %d %s \r\n", retCount, szRet);

if ('q' == szControl[0])

{

break;

}

} while (1);

CloseHandle( hDevice );

}

继续阅读