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)。。。。


...全文
892 2 打赏 收藏 转发到动态 举报
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
南国时代 2016-09-18
  • 打赏
  • 举报
回复
再顶
南国时代 2016-09-17
  • 打赏
  • 举报
回复
自顶

21,597

社区成员

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

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