应用层与驱动层通信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 );
}





猜你喜欢

转载自blog.csdn.net/youyudexiaowangzi/article/details/54380433