17.driverbase—IOCtl的三种数据交互方式(buffer、direct、other)

#define IOCTL_DIRECT_IN_IO	CTL_CODE(FILE_DEVICE_COMM_DRIVER, 0x700, METHOD_IN_DIRECT,  FILE_READ_ACCESS¦FILE_WRITE_ACCESS)//直接输入缓冲输出I/O
#define IOCTL_DIRECT_OUT_IO   CTL_CODE(FILE_DEVICE_COMM_DRIVER, 0x701, METHOD_OUT_DIRECT, FILE_READ_ACCESS¦FILE_WRITE_ACCESS)//缓冲输入直接输出I/O
#define IOCTL_BUFFERED_IO	 CTL_CODE(FILE_DEVICE_COMM_DRIVER, 0x702, METHOD_BUFFERED,   FILE_READ_ACCESS¦FILE_WRITE_ACCESS)//输入输出缓冲I/O
#define IOCTL_NEITHER_IO	  CTL_CODE(FILE_DEVICE_COMM_DRIVER, 0x703, METHOD_NEITHER,	FILE_READ_ACCESS¦FILE_WRITE_ACCESS)//Other I/0

IOCTL请求有以上四种

它们的输入输出缓冲区方式如下:

IOCTL请求类型输入缓冲存地址输出缓冲区地址
METHOD_IN_DIRECT/ METHOD_OUT_DIRECTIrp->AssociatedIrp.SystemBufferMmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority)
METHOD_BUFFEREDIrp->AssociatedIrp.SystemBufferIrp->AssociatedIrp.SystemBuffer
METHOD_NEITHERpIoStackIrp->Parameters.DeviceIoControl.Type3InputBufferpIoStackIrp->Parameters.DeviceIoCont
METHOD_IN_DIRECT/ METHOD_OUT_DIRECT  示例代码:

NTSTATUS DirectIo(PIRP Irp, PIO_STACK_LOCATION pIoStackIrp)
{
	//以下四个变量都由DeviceIoControl参数传入
	ULONG ulInputLength = pIoStackIrp->Parameters.DeviceIoControl.InputBufferLength;//输入长度
	PVOID pInputBuf = Irp->AssociatedIrp.SystemBuffer;//输入buf
 
	ULONG ulOutputLength = pIoStackIrp->Parameters.DeviceIoControl.OutputBufferLength;//输出长度
	PVOID pOutputBuf = NULL;
	if (Irp->MdlAddress)
	{
		pOutputBuf = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);
	}
 
	//TODO.对pOutputBuf 赋值
}
METHOD_BUFFERED  示例代码:

NTSTATUS BufferIo(PIRP Irp, PIO_STACK_LOCATION pIoStackIrp)
{
	//以下四个变量都由DeviceIoControl参数传入
	ULONG ulInputLength = pIoStackIrp->Parameters.DeviceIoControl.InputBufferLength;//输入长度
	PVOID pInputBuf = Irp->AssociatedIrp.SystemBuffer;//输入buf
 
	ULONG ulOutputLength = pIoStackIrp->Parameters.DeviceIoControl.OutputBufferLength;//输出长度
	PVOID pOutputBuf = Irp->AssociatedIrp.SystemBuffer;
 
	//TODO.对pOutputBuf 赋值
}

我们注意到BufferIo中输入和输出指向同一个缓冲区,如果输入数据有用的话,我们应当从系统缓冲区( Irp->AssociatedIrp.SystemBuffer)先获取输入,再将输出写入到系统缓冲区(同一个地方: Irp->AssociatedIrp.SystemBuffer)。当完成请求时,I/O 系统将输出数据从系统缓冲区复制到用户缓冲区

METHOD_NEITHER示例:

NTSTATUS NeitherIo(PIRP Irp, PIO_STACK_LOCATION pIoStackIrp)
{
	//以下四个变量都由DeviceIoControl参数传入
	ULONG ulInputLength = pIoStackIrp->Parameters.DeviceIoControl.InputBufferLength;//输入长度
	PVOID pInputBuf = pIoStackIrp->Parameters.DeviceIoControl.Type3InputBuffer;//输入buf
 
	ULONG ulOutputLength = pIoStackIrp->Parameters.DeviceIoControl.OutputBufferLength;//输出长度
	PVOID pOutputBuf = Irp->UserBuffer;
 
	//TODO.对pOutputBuf 赋值
}





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值