关于使用IoBuildAsynchronousFsdRequest创建读写IRP出现蓝屏(蓝屏错误码:0x000000BE)的问题
2018-03-27 18:47
633 查看
最近学习使用IoBuildAsynchronousFsdRequest创建读写IRP进行驱动间通讯的方式,在使用IoBuildAsynchronousFsdRequest成功创建读IRP后进行安装,安装时出现蓝屏,蓝屏提示错误0x000000BE:Write Read-Only Memory。 进过研究分析,发现IoBuildAsynchronousFsdRequest创建读IRP时我传入的输入缓冲区为局部变量缓冲区地址,而在IRP的完成例程中使用了此地址,局部变量的有效性只限于当前函数,所以非法使用导致出现蓝屏。所以在使用IoBuildAsynchronousFsdRequest创建读写IRP时,如果在其它函数中需要使用到输入输出缓冲区时,应该传入全局的缓冲区地址。
下面是一个例子:
char g_szbuffer[4096] = "";
//用来处理等待请求
void CompleteWait(WDFQUEUE Queue)
{
NTSTATUS status = STATUS_SUCCESS;
IO_STATUS_BLOCK IoStatus;
WDFREQUEST WaitRequest = NULL;
int nRes = 1;
HANDLE hReadEvent;
PKEVENT pEvent;
PDEVICE_CONTEXT pDeviceContext;
PIRP irp; //char szBuf[4096] = "";
LARGE_INTEGER StartingOffset = { 0 };
PDEVICE_OBJECT pUsbDeviceObject = NULL;
PDRIVER_OBJECT pParentDriverObject = NULL;
PIRP pNewIrp;
KEVENT event;
PIO_STACK_LOCATION stack;
IO_STATUS_BLOCK status_block;
// 将32位整数转为64位的整数
LARGE_INTEGER offsert = RtlConvertLongToLargeInteger(0);
UNICODE_STRING DeviceName;
PDEVICE_OBJECT DeviceObject = NULL;
PFILE_OBJECT FileObject = NULL;
PAGED_CODE();
RtlInitUnicodeString( &DeviceName, L"\\DosDevices\\ScannerUSBDriver03" );
DbgPrint("begin CompleteWait\n");
// 初始化一个同步对象
KeInitializeEvent(&event,NotificationEvent,FALSE);
pDeviceContext = GetDeviceContext(WdfIoQueueGetDevice(Queue));
if(pDeviceContext->bOpen)
DbgPrint("pDeviceContext->bOpen is true\n");
else
DbgPrint("pDeviceContext->bOpen is false\n");
pUsbDeviceObject = pDeviceContext->pPdoDeviceObject->NextDevice;
if (pUsbDeviceObject && pDeviceContext->bOpen)
{
KdPrint(("pUsbDeviceObject:%x\n",pUsbDeviceObject));
//创建ReadIRP
irp = IoBuildAsynchronousFsdRequest(IRP_MJ_READ, pUsbDeviceObject, g_szbuffer,sizeof(g_szbuffer), &StartingOffset, NULL); //此处只能用全局的缓冲区(g_szbuffer),不能使用此函数里的局部缓冲区(szBuf),否则蓝屏
if (irp != NULL)
{
DbgPrint("IoBuildAsynchronousFsdRequest success\n");
status = IoAcquireRemoveLock(&pDeviceContext->RemoveLock, irp);
if (NT_SUCCESS(status))
{
IoSetCompletionRoutineEx(pUsbDeviceObject, irp,
AsynReadCompletion,
pDeviceContext,
TRUE,
TRUE,
TRUE);
status = IoCallDriver(pUsbDeviceObject, irp);
if (!NT_SUCCESS(status))
{
DbgPrint("Failed to send async Read irp (status=%x)\n", status);
}
}
else
{
IoFreeIrp(irp);
DbgPrint("IoAcquireRemoveLock failed\n");
}
}
else
{
DbgPrint("IoBuildAsynchronousFsdRequest failed\n");
}
}
}
NTSTATUS
AsynReadCompletion(
__in PDEVICE_OBJECT DeviceObject,
__in PIRP Irp,
__in PVOID Context
)
{
NTSTATUS status = Irp->IoStatus.Status;
WDFREQUEST WaitRequest = NULL;
int nRes = 1;
PDEVICE_CONTEXT pDevExt = (PDEVICE_CONTEXT)Context;
UNREFERENCED_PARAMETER(DeviceObject);
DbgPrint((PCHAR)(Irp->AssociatedIrp.SystemBuffer));
DbgPrint(g_szbuffer);
if (status == STATUS_CANCELLED)
{
DbgPrint("AsynRead IRP was cancelled\n");
}
else if (!NT_SUCCESS(status))
{
DbgPrint("AsynRead IRP failed (status=%x)\n", status);
}
else //Read成功
{
DbgPrint("begin Write ringbuffer\n");
//结束等待请求
if ((pDevExt->wdfQueue) && (nRes >= 0))
{
//取出自定义队列中的WAIT请求
status = WdfIoQueueRetrieveNextRequest(pDevExt->wdfQueue, &WaitRequest);
if (NT_SUCCESS(status))
{
if (WaitRequest)
{
//结束等待
WdfRequestComplete(WaitRequest, STATUS_SUCCESS);
DbgPrint("Complete Wait Mask succeed\n");
WaitRequest = NULL;
}
}
else
DbgPrint("WaitRequest is null\n");
}
}
if (NULL != pDevExt)
IoReleaseRemoveLock(&pDevExt->RemoveLock, Irp);
//IoFreeIrp(Irp);
return status;
}
下面是一个例子:
char g_szbuffer[4096] = "";
//用来处理等待请求
void CompleteWait(WDFQUEUE Queue)
{
NTSTATUS status = STATUS_SUCCESS;
IO_STATUS_BLOCK IoStatus;
WDFREQUEST WaitRequest = NULL;
int nRes = 1;
HANDLE hReadEvent;
PKEVENT pEvent;
PDEVICE_CONTEXT pDeviceContext;
PIRP irp; //char szBuf[4096] = "";
LARGE_INTEGER StartingOffset = { 0 };
PDEVICE_OBJECT pUsbDeviceObject = NULL;
PDRIVER_OBJECT pParentDriverObject = NULL;
PIRP pNewIrp;
KEVENT event;
PIO_STACK_LOCATION stack;
IO_STATUS_BLOCK status_block;
// 将32位整数转为64位的整数
LARGE_INTEGER offsert = RtlConvertLongToLargeInteger(0);
UNICODE_STRING DeviceName;
PDEVICE_OBJECT DeviceObject = NULL;
PFILE_OBJECT FileObject = NULL;
PAGED_CODE();
RtlInitUnicodeString( &DeviceName, L"\\DosDevices\\ScannerUSBDriver03" );
DbgPrint("begin CompleteWait\n");
// 初始化一个同步对象
KeInitializeEvent(&event,NotificationEvent,FALSE);
pDeviceContext = GetDeviceContext(WdfIoQueueGetDevice(Queue));
if(pDeviceContext->bOpen)
DbgPrint("pDeviceContext->bOpen is true\n");
else
DbgPrint("pDeviceContext->bOpen is false\n");
pUsbDeviceObject = pDeviceContext->pPdoDeviceObject->NextDevice;
if (pUsbDeviceObject && pDeviceContext->bOpen)
{
KdPrint(("pUsbDeviceObject:%x\n",pUsbDeviceObject));
//创建ReadIRP
irp = IoBuildAsynchronousFsdRequest(IRP_MJ_READ, pUsbDeviceObject, g_szbuffer,sizeof(g_szbuffer), &StartingOffset, NULL); //此处只能用全局的缓冲区(g_szbuffer),不能使用此函数里的局部缓冲区(szBuf),否则蓝屏
if (irp != NULL)
{
DbgPrint("IoBuildAsynchronousFsdRequest success\n");
status = IoAcquireRemoveLock(&pDeviceContext->RemoveLock, irp);
if (NT_SUCCESS(status))
{
IoSetCompletionRoutineEx(pUsbDeviceObject, irp,
AsynReadCompletion,
pDeviceContext,
TRUE,
TRUE,
TRUE);
status = IoCallDriver(pUsbDeviceObject, irp);
if (!NT_SUCCESS(status))
{
DbgPrint("Failed to send async Read irp (status=%x)\n", status);
}
}
else
{
IoFreeIrp(irp);
DbgPrint("IoAcquireRemoveLock failed\n");
}
}
else
{
DbgPrint("IoBuildAsynchronousFsdRequest failed\n");
}
}
}
NTSTATUS
AsynReadCompletion(
__in PDEVICE_OBJECT DeviceObject,
__in PIRP Irp,
__in PVOID Context
)
{
NTSTATUS status = Irp->IoStatus.Status;
WDFREQUEST WaitRequest = NULL;
int nRes = 1;
PDEVICE_CONTEXT pDevExt = (PDEVICE_CONTEXT)Context;
UNREFERENCED_PARAMETER(DeviceObject);
DbgPrint((PCHAR)(Irp->AssociatedIrp.SystemBuffer));
DbgPrint(g_szbuffer);
if (status == STATUS_CANCELLED)
{
DbgPrint("AsynRead IRP was cancelled\n");
}
else if (!NT_SUCCESS(status))
{
DbgPrint("AsynRead IRP failed (status=%x)\n", status);
}
else //Read成功
{
DbgPrint("begin Write ringbuffer\n");
//结束等待请求
if ((pDevExt->wdfQueue) && (nRes >= 0))
{
//取出自定义队列中的WAIT请求
status = WdfIoQueueRetrieveNextRequest(pDevExt->wdfQueue, &WaitRequest);
if (NT_SUCCESS(status))
{
if (WaitRequest)
{
//结束等待
WdfRequestComplete(WaitRequest, STATUS_SUCCESS);
DbgPrint("Complete Wait Mask succeed\n");
WaitRequest = NULL;
}
}
else
DbgPrint("WaitRequest is null\n");
}
}
if (NULL != pDevExt)
IoReleaseRemoveLock(&pDevExt->RemoveLock, Irp);
//IoFreeIrp(Irp);
return status;
}
相关文章推荐
- IoBuildAsynchronousFsdRequest创建IRP数据包_异步
- IoBuildSynchronousFsdRequest创建IRP数据包_同步
- 关于allegro16.6 orCAD capture CIS 创建网表出现错误的问题解决方法
- 关于Python 3.x中,使用print函数时出现的语法错误(SyntaxError: invalid syntax)的问题的原因
- 关于spring-mvc中使用ajax调用后台接口出现400 bad request的问题解决方案
- 关于使用ui-select出现Error: [ui.select:choices] htt错误的问题
- 关于ViewPager使用出现的图片覆盖错误问题
- 关于使用CreateUserWinzard控件创建用户时出现连接数据库问题的解决方法
- VMware 下的linux,使用dbca创建数据库时出现关于jvm的问题
- 关于使用myeclipse创建web项目中可能出现的问题
- 关于Python 3.x中,使用print函数时出现的语法错误(SyntaxError: invalid syntax)的问题的原因
- 关于asp使用CreateObject("Excel.Application")出现无法创建ActiveX对象的错误
- 【Python】 关于Python 3.x中,使用print函数时出现的语法错误(SyntaxError: invalid syntax)的问题的原因
- 关于allegro16.6 orCAD capture CIS 创建网表出现错误的问题解决方法
- 关于使用Tomcat服务器出现413错误的解决办法(Request Entity Too Large)
- 关于在Log4j中使用JDBCAppender时出现死循环的问题
- 教程┊解决使用USB键盘进行游戏后按任意键出现蓝屏的错误
- 关于使用 jquery Validate 使用出现的问题
- 关于使用ISA代理导致一些网上银行出现不能正常打开的问题
- 关于用c生成的dll在使用其他供应商的工具创建可执行模块时遇到的一些问题