应用层与驱动层通信DeviceIoControl
2017-01-12 18:15
162 查看
驱动层与应用层通信是通过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 );
}
首先驱动层要实现:
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 );
}
相关文章推荐
- 蓝牙设备的连接
- 算法杂货铺——分类算法之朴素贝叶斯分类(Naive Bayesian classification)
- 回顾2016--Apache Flink流处理在生产中的实践
- how to use novaclient python api
- 【SSH网上商城项目实战17】购物车基本功能的实现
- 面试相关
- OpenGL着色器语言注意点(部分)
- JNDI配置数据源dbcp方式,配置文件加密
- 以太网和令牌环网的区别
- unity—对话的设计
- spring拦截异常注解式和"非注解式+schema"和非注解式配置bean式
- Android常用的设计模式:Builder模式
- 一个线上缓存异常
- Java并发编程:Lock
- 【bzoj1455】罗马游戏
- 基于Bootstrap的后台管理界面
- 腾讯云证书 - 接入流程
- Apache限制IP访问
- 完全替代 RelativeLayout,ConstraintLayout 入门以及实践
- luogu2604网络扩容