USB驱动开发—bulkusb 那个例子中的一些疑问,求大家帮忙答疑解惑!

南国时代 2016-09-16 10:28:13
一、前提
前段时间开始学习Windows驱动 开发(主要是我需要自己实现USB驱动开发部分) 。
参考书籍: 《Windows驱动开发技术详解》;
开发环境: VS2013+WDK8.1
开发板 : ZC702

二、问题详述:
1)以那本参考书附赠光盘里的bulkusb 例子做为USB驱动开发部分的第一个实验(主要是感觉整个框架好大,只能在别人的例子上进行修改。。。。),。在完成板上固件部分的开发后,修改INF文件,安装驱动;
2)之后,设备枚举成功、上位机可以正常的检测到设备,然后createfile函数打开设备最开始以为也是成功的(因为返回了有效的句柄)。。。但之后写数据时却返回错误——代码06,句柄无效(但是在调试时,可以看到写句柄其实是有效的,但不知怎的返回的就是这个句柄无效的错误。。。好心塞。。。)。因为之前做过mass storage 和HID设备的实验,在应用程序对设备的读写方式上我自以为是没有错误的,所以开始了下一步;
3)考虑驱动开发部分的错误。。经过一番查找——最初发现的错误在IRP_MJ_CREATE的派遣例程中:
NTSTATUS BulkUsb_DispatchCreate(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp )
{
ULONG i;
NTSTATUS ntStatus;
PFILE_OBJECT fileObject;
PDEVICE_EXTENSION deviceExtension;
PIO_STACK_LOCATION irpStack;
PBULKUSB_PIPE_CONTEXT pipeContext;
PUSBD_INTERFACE_INFORMATION interface;

PAGED_CODE();
KdPrint(("进入BulkUsb_DispatchCreate 例程 \n"));
//
// initialize variables
//
irpStack = IoGetCurrentIrpStackLocation(Irp);
KdPrint((" 当前文件对象中的文件名 :%ws\n", irpStack->FileObject->FileName.Buffer));
fileObject = irpStack->FileObject;
deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;

if(deviceExtension->DeviceState != Working) {
KdPrint(("当前设备处于未工作状态 !\n"));
ntStatus = STATUS_INVALID_DEVICE_STATE;
goto BulkUsb_DispatchCreate_Exit;
}

if(deviceExtension->UsbInterface) {

interface = deviceExtension->UsbInterface;
}
else {
KdPrint(("UsbInterface not found\n"));
ntStatus = STATUS_INVALID_DEVICE_STATE;
goto BulkUsb_DispatchCreate_Exit;
}

//
// FsContext is Null for the device
//
if(fileObject) {

fileObject->FsContext = NULL;
KdPrint(("FsContext = NULL \n"));
}
else {

ntStatus = STATUS_INVALID_PARAMETER;
KdPrint(("ntStatus = Invalid parameter \n"));
goto BulkUsb_DispatchCreate_Exit;
}
KdPrint(("FileName :%wZ \n", &fileObject->FileName));
if(0 == fileObject->FileName.Length)
{
KdPrint(("FileName length =0 \n"));
ntStatus = STATUS_SUCCESS;

InterlockedIncrement(&deviceExtension->OpenHandleCount);

//
// the device is idle if it has no open handles or pending PnP Irps
// since we just received an open handle request, cancel idle req.
//
if(deviceExtension->SSEnable) {
CancelSelectSuspend(deviceExtension);
}

goto BulkUsb_DispatchCreate_Exit;
}

KdPrint(("文件对象名: %wZ \n", &fileObject->FileName));
pipeContext = BulkUsb_PipeWithName(DeviceObject, &fileObject->FileName);
KdPrint(("Device power :%d System Power : %d \n", deviceExtension->DevPower, deviceExtension->SysPower));

if(pipeContext == NULL) {
KdPrint(("BulkUsb_PipeWithName之后,pipeContext仍为NULL \n"));
ntStatus = STATUS_INVALID_PARAMETER;
goto BulkUsb_DispatchCreate_Exit;
}


ntStatus = STATUS_INVALID_PARAMETER;

for(i=0; i<interface->NumberOfPipes; i++) {

if(pipeContext == &deviceExtension->PipeContext[i]) {
KdPrint(("open pipe %d\n", i));
fileObject->FsContext = &interface->Pipes[i];

ASSERT(fileObject->FsContext);
if (fileObject->FsContext != NULL)
{
KdPrint(("FsContext != NULL \n"));

}

pipeContext->PipeOpen = TRUE;

ntStatus = STATUS_SUCCESS;

//
// increment OpenHandleCounts
//
InterlockedIncrement(&deviceExtension->OpenHandleCount);

//
// the device is idle if it has no open handles or pending PnP Irps
// since we just received an open handle request, cancel idle req.
//
if(deviceExtension->SSEnable) {

CancelSelectSuspend(deviceExtension);
}
}
}

BulkUsb_DispatchCreate_Exit:

Irp->IoStatus.Status = ntStatus;
Irp->IoStatus.Information = 0;

IoCompleteRequest(Irp, IO_NO_INCREMENT);

BulkUsb_DbgPrint(3, ("BulkUsb_DispatchCreate - ends\n"));
KdPrint(("离开BulkUsb_DispatchCreate 例程 \n"));
return ntStatus;
}

应用程序中调用createfile函数 ,产生了这个IRP。但我在使用DbgView查看打印的log信息时,结果发现
fileObject = irpStack->FileObject文件对象FileObject->FileName为NULL。这就直接导致后面
pipeContext = BulkUsb_PipeWithName(DeviceObject, &fileObject->FileName);返回NULL。Create派遣例程就这么退出了。。。pipeContext为NULL,fileObject->FsContext也就为NULL。
而在后面IRP_MJ_WRITE的派遣例程中:
if(fileObject && fileObject->FsContext) {

pipeInformation = fileObject->FsContext;

if(UsbdPipeTypeBulk != pipeInformation->PipeType) {

BulkUsb_DbgPrint(1, ("Usbd pipe type is not bulk\n"));

ntStatus = STATUS_INVALID_HANDLE;
goto BulkUsb_DispatchReadWrite_Exit;
}
}
else {

BulkUsb_DbgPrint(1, ("Invalid handle\n"));

ntStatus = STATUS_INVALID_HANDLE;
goto BulkUsb_DispatchReadWrite_Exit;
}
直接回返回 invalid handle。。。。。
三、具体问题
每打开一个设备,都会伴随存在一个关联的文件对象,FILE_OBJECT。其中的FileName具体是什么呢?和CreateFile函数的第一个参数DevPath有关吗?或者说由于是自定义驱动,DevPath使用的符号链接(或者说是设备链接)需要在原来的基础上进行修改吗??(因为FileName在上述函数中被解释成pipe name string ,貌似FileName中的最后一个数字用于确定pipeContext)。。。。


...全文
893 2 打赏 收藏 转发到动态 举报
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
南国时代 2016-09-18
  • 打赏
  • 举报
回复
再顶
南国时代 2016-09-17
  • 打赏
  • 举报
回复
自顶
非常欢迎各位零基础的同学参与我个人亲自录制讲解的Spring Boot开发入门课程!我将会带领大家从零开始,一步步地学习如何利用Spring Boot进行开发,并教授基于前后端分离编程思想的实践方法,本课程提供答疑,解决大家的课后学习问题在这个课程,我们将使用Spring Boot作为后端框架,与前端通过JSON数据交互。前后端分离的编程思想是当前的大势所趋,在实际开发具有很高的灵活性和可扩展性。我将详细解释这种编程思想的原理和优势,并带领大家亲自动手实现一个基于前后端分离的Spring Boot项目。即使你没有任何编程基础,也不用担心!我的课程将从头开始,由浅入深地教授Spring Boot开发的每个步骤。基础语法还是常用的,我都会在项目实现的过程进行引导和讲解。通过实际项目的学习,你将能够熟悉开发项目常用的工具和技术。学完我的课程后,你将能够自信地实现一个Spring Boot的后台管理项目。我们将涵盖如用户管理、登录控制、数据增删改查等常见管理功能,并通过前后端分离的方式进行数据交互。我将为你提供学习答疑的支持,确保你能够顺利掌握这些技术和概念。这个课程只是你学习java编程的起点,后续的学习和进步需要你自己不断的努力和实践。我期待与你们的相遇,并希望能一起为编程这个充满挑战和乐趣的领域努力奋斗!让我们一起探索编程的世界,共同成长!

21,600

社区成员

发帖
与我相关
我的任务
社区描述
硬件/嵌入开发 驱动开发/核心开发
社区管理员
  • 驱动开发/核心开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧