metalwing
驱动中牛
驱动中牛
  • 注册日期2003-10-13
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分178分
  • 威望58点
  • 贡献值0点
  • 好评度17点
  • 原创分0分
  • 专家分0分
阅读:4155回复:18

请教与USB接口通信的问题,能进来帮我看一下吗

楼主#
更多 发布于:2004-07-19 18:42
使用windows server 2003 ddk 模仿别人的程序自己做了一个打开USB设备的程序。但有问题:

DEFINE_GUID(USB_DRIVER_GUID, 0x0748816c, 0x9b2d, 0x4796, 0x82, 0x4a, 0xc4, 0xa0, 0xdb, 0x48, 0x22, 0xfb);

HANDLE OpenOneDevice(HDEVINFO hDvcInfo, PSP_INTERFACE_DEVICE_DATA DvcInfoData, char *sDevNameBuf)
{
    HANDLE hOut = INVALID_HANDLE_VALUE;

    ULONG iReqLen = 0;

    //这条语句的执行结果为false
    //iReqLen=83
    //这个函数是干什么的?谁能帮我解释一下?或告诉我在哪能查到
    SetupDiGetInterfaceDeviceDetail(hDvcInfo, DvcInfoData, NULL, 0, &iReqLen, NULL);

    ULONG iDevDataLen = iReqLen; //sizeof(SP_FNCLASS_DEVICE_DATA) + 512;
    PSP_INTERFACE_DEVICE_DETAIL_DATA pDevData = (PSP_INTERFACE_DEVICE_DETAIL_DATA)malloc(iDevDataLen);
    if(pDevData == NULL)
        return INVALID_HANDLE_VALUE;

    //pDevData->cbSize=8
    pDevData->cbSize = sizeof(SP_INTERFACE_DEVICE_DETAIL_DATA);

    //这句返回为“假”,美景到判断里面
    if(SetupDiGetInterfaceDeviceDetail(hDvcInfo, DvcInfoData, pDevData, iDevDataLen, &iReqLen, NULL))
    {
        strcpy(sDevNameBuf, pDevData->DevicePath);
        hOut = CreateFile(pDevData->DevicePath, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
    }

    free(pDevData);
    return hOut;
}
//----------------------------------------------------------HANDLE OpenUsbDevice(const GUID *pGuid, char *sDevNameBuf)
{
    HANDLE hOut = INVALID_HANDLE_VALUE;

    //查了Setupapi.h,HDEVINFO是一个指针变量,SetupDiGetClassDevs()返回指向一个设备信息集的句柄
    //但这个信息集究竟是什么样的呀?能帮我解释一下吗?
    HDEVINFO hDevInfo = SetupDiGetClassDevs(pGuid, NULL, NULL,
        DIGCF_PRESENT|DIGCF_INTERFACEDEVICE);

    SP_INTERFACE_DEVICE_DATA deviceInfoData;

    deviceInfoData.cbSize = sizeof (SP_INTERFACE_DEVICE_DATA);

    ULONG nGuessCount = MAXLONG;
    for(ULONG iDevIndex = 0;iDevIndex < nGuessCount;iDevIndex ++)
    {

      //这句返回为“真”。iDevIndex=0;
      //deviceInfoData={cbsize=28, interfaceclassGUID={122192236UL (0x0748816C), 39725U (0x9B2D), 18326U (0x4796), "xFFFFFF82+0x4A+xFFFFFFC4+xFFFFFFA0+xFFFFFFDB+0x48+0x22+0xFFFFFFFB"}, flags=1, reserved=1595112UL}
      //我查不到deviceInfoData->flags及reserved的帮助,谁能帮我解释一下吗?  
      if(SetupDiEnumDeviceInterfaces(hDevInfo, 0, pGuid, iDevIndex, &deviceInfoData))
      {
          hOut = OpenOneDevice(hDevInfo, &deviceInfoData, sDevNameBuf);
          if(hOut != INVALID_HANDLE_VALUE)
              break;
      }
      else if(GetLastError() == ERROR_NO_MORE_ITEMS) //No more items
      {
          break;
      }
  }
  SetupDiDestroyDeviceInfoList(hDevInfo);
  return hOut;
}
//----------------------------------------------------------
HANDLE OpenMyDevice()
{
  char DeviceName[MAXPATH] = "";
  return OpenUsbDevice(&USB_DRIVER_GUID, DeviceName);
}
//----------------------------------------------------------

我用的GUID是DS开发的驱动中DeviceInterface.h中的GUID,在注册表中也找到了这个设备。使用DS自动生成的Test_Usb.exe程序可以打开设备,为什么我上面的程序却不行呢?

[编辑 -  7/19/04 by  metalwing]
新手上路,请多关照.
snowStart
驱动老牛
驱动老牛
  • 注册日期2004-04-06
  • 最后登录2011-06-02
  • 粉丝0
  • 关注0
  • 积分95分
  • 威望19点
  • 贡献值177点
  • 好评度1点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2004-07-19 21:24

//这句返回为“假”,美景到判断里面
if(SetupDiGetInterfaceDeviceDetail(hDvcInfo, DvcInfoData, pDevData, iDevDataLen, &iReqLen, NULL))
{
strcpy(sDevNameBuf, pDevData->DevicePath);
hOut = CreateFile(pDevData->DevicePath, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
}

这一段是
Retrieve the information from Plug and Play.
你可以用getlasterror()察看错误信息,需要硬件支持
学习,关注,交流中... [email=fengyu@163.com]Email:snowstarth@163.com[/email] [url]http://bbs.zndev.com/?a=snowStart[/url]
metalwing
驱动中牛
驱动中牛
  • 注册日期2003-10-13
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分178分
  • 威望58点
  • 贡献值0点
  • 好评度17点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2004-07-20 15:01
谢谢你的回答,分已给了。另外还想请教一下:
我将那句改为:

    SetupDiGetInterfaceDeviceDetail(hDvcInfo, DvcInfoData, pDevData, iDevDataLen, &iReqLen, NULL);
    int my_error = GetLastError();
    int len = FormatMessage(
        FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
        NULL,
        GetLastError(),
        //MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
        MAKELANGID(LANG_NEUTRAL, SUBLANG_SYS_DEFAULT),
        (LPTSTR) &lpMsgBuf,
        0,
        NULL
    );

执行结果为:
my_error = 1784
len = 34
一次:lpMsgBuf={0x0, 0x53, 0x18}
二次:lpMsgBuf={0x18, 0x52, 0x18}
三次:lpMsgBuf={0xB0, 0x53, 0x18}

1。不知什么意思。能给解释一下吗?
2。你说的需要硬件支持是指什么?我用USB Monitor看,并为看见相应坚范颂了什么请求呀。
新手上路,请多关照.
snowStart
驱动老牛
驱动老牛
  • 注册日期2004-04-06
  • 最后登录2011-06-02
  • 粉丝0
  • 关注0
  • 积分95分
  • 威望19点
  • 贡献值177点
  • 好评度1点
  • 原创分0分
  • 专家分0分
地板#
发布于:2004-07-20 17:43
errcode=1784
表示: 所提供的用户缓冲区对所申请的操作无效。
学习,关注,交流中... [email=fengyu@163.com]Email:snowstarth@163.com[/email] [url]http://bbs.zndev.com/?a=snowStart[/url]
metalwing
驱动中牛
驱动中牛
  • 注册日期2003-10-13
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分178分
  • 威望58点
  • 贡献值0点
  • 好评度17点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2004-07-20 19:57
谢谢你的回答。
那该怎么办呢?我用DS自动生成的测试程序为什么可以呀?
你说的“所提供的用户缓存区”是指pDevData的长度吗?
我试一下先
errcode=1784
表示: 所提供的用户缓冲区对所申请的操作无效。
新手上路,请多关照.
metalwing
驱动中牛
驱动中牛
  • 注册日期2003-10-13
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分178分
  • 威望58点
  • 贡献值0点
  • 好评度17点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2004-07-20 20:24
SetupDiGetInterfaceDeviceDetail()中的几个参数是什么意思呀?我把pDevData的长度设到520=512+8
PSP_INTERFACE_DEVICE_DETAIL_DATA pDevData = PSP_INTERFACE_DEVICE_DETAIL_DATA(new char[520]);

可还是不行。我对比了一下我这个程序和Driver Studio自动生成的测试程序(包括他的CDeviceInterfaceClass及CDeviceInterface),基本上差不多呀?只不过我这个程序是在BCB下编译的,DS的程序是在VC下编译的。明天准备把DS的程序展开试一下。
新手上路,请多关照.
metalwing
驱动中牛
驱动中牛
  • 注册日期2003-10-13
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分178分
  • 威望58点
  • 贡献值0点
  • 好评度17点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2004-07-21 11:09
刚试完了。在DS+VC环境中,展开CDeviceInterfaceClass和CDeviceInterface(在测试程序中的OpenByInterface函数中),编译通过执行正常。
将整个函数移植到BCB中,编译通过,但执行到
SetupDiGetInterfaceDeviceDetail(hDvcInfo, DvcInfoData, pDevData, iDevDataLen, &iReqLen, NULL);
DWORD Error = GetLastError();
还是Error=1784.不能打开设备。
谁能告诉我为什么呀?
新手上路,请多关照.
AllenZh
驱动老牛
驱动老牛
  • 注册日期2001-08-19
  • 最后登录2015-11-27
  • 粉丝19
  • 关注10
  • 积分1316分
  • 威望2387点
  • 贡献值7点
  • 好评度321点
  • 原创分0分
  • 专家分0分
7楼#
发布于:2004-07-21 21:56
刚试完了。在DS+VC环境中,展开CDeviceInterfaceClass和CDeviceInterface(在测试程序中的OpenByInterface函数中),编译通过执行正常。
将整个函数移植到BCB中,编译通过,但执行到
SetupDiGetInterfaceDeviceDetail(hDvcInfo, DvcInfoData, pDevData, iDevDataLen, &iReqLen, NULL);
DWORD Error = GetLastError();
还是Error=1784.不能打开设备。
谁能告诉我为什么呀?

提供的指针有问题,不一定非得是NULL
空间不够或大小部对也可能有问题
1,承接Windows下驱动/应用开发 2,本人原创虚拟鼠标/键盘,触摸屏,虚拟显卡,Mirror驱动,XP无盘的SCSI虚拟磁盘驱动等 3,windows下有尝技术服务(包括BUG调试,员工培训等) 欢迎深圳和海外企业联系.msn:mfczmh@sina.com
metalwing
驱动中牛
驱动中牛
  • 注册日期2003-10-13
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分178分
  • 威望58点
  • 贡献值0点
  • 好评度17点
  • 原创分0分
  • 专家分0分
8楼#
发布于:2004-07-22 08:11
谢谢。
但为什么在DS+VC编译成的程序就没问题呢?(是相同的语句呀)
另外,snowStart告诉我了
errcode=1784
表示: 所提供的用户缓冲区对所申请的操作无效。
那究竟是那个指针(缓冲区)有问题呢?我估计是pDevData,但pDevData的申请,我原来是:
PSP_INTERFACE_DEVICE_DETAIL_DATA pDevData = (PSP_INTERFACE_DEVICE_DETAIL_DATA)malloc(iDevDataLen);
pDevData->cbSize = sizeof(SP_INTERFACE_DEVICE_DETAIL_DATA);
也试过
PSP_INTERFACE_DEVICE_DETAIL_DATA pDevData = PSP_INTERFACE_DEVICE_DETAIL_DATA (new char[iDevDataLen]);
pDevData->cbSize = sizeof(SP_INTERFACE_DEVICE_DETAIL_DATA);
都有问题。不知为什么。(iDevDataLen跟踪发现值为83)
是BCB编译器的问题吗?

[quote]刚试完了。在DS+VC环境中,展开CDeviceInterfaceClass和CDeviceInterface(在测试程序中的OpenByInterface函数中),编译通过执行正常。
将整个函数移植到BCB中,编译通过,但执行到
SetupDiGetInterfaceDeviceDetail(hDvcInfo, DvcInfoData, pDevData, iDevDataLen, &iReqLen, NULL);
DWORD Error = GetLastError();
还是Error=1784.不能打开设备。
谁能告诉我为什么呀?

提供的指针有问题,不一定非得是NULL
空间不够或大小部对也可能有问题 [/quote]
新手上路,请多关照.
leadphone
驱动牛犊
驱动牛犊
  • 注册日期2002-11-28
  • 最后登录2008-09-04
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
9楼#
发布于:2004-07-24 17:34
粗略的看了一下,看不出什么问题。随便说两句,希望能给你帮助:

在函数OpenOneDevice中SetupDiGetInterfaceDeviceDetail是需要执行两遍的,你的程序里也是如此。第一次调用你用getlasterror会发现0x7a的错误,别担心,这是正常的,iReqLen参数会包含正确的deviceInterfaceDetailDataSize数值。第二次调用的时候传递此传回值,函数就会执行成功。你可以在第二次调用后用getlasterror看返回值是不是0。这个函数就是区的设备的路径!

然后就可以用creatfile创建句柄了。 ;)
metalwing
驱动中牛
驱动中牛
  • 注册日期2003-10-13
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分178分
  • 威望58点
  • 贡献值0点
  • 好评度17点
  • 原创分0分
  • 专家分0分
10楼#
发布于:2004-07-25 09:18
谢谢你的帮助。我也是这么考虑的。现在的问题是:前面都跟你说的一样(程序设计、执行效果(iReqLen=83)),但第二次调用SetupDiGetInterfaceDeviceDetail还是不成功(getLastError()=1784所提供的用户缓冲区对所申请的操作无效。并且,不成功仅是在BCB环境中发生,而在VC+DS中不会发生),我估计是pDevData的长度有问题。但究竟是怎么回事,我还不太清楚。分已经给别人了,若能解决,我再开贴给分。谢谢。
粗略的看了一下,看不出什么问题。随便说两句,希望能给你帮助:

在函数OpenOneDevice中SetupDiGetInterfaceDeviceDetail是需要执行两遍的,你的程序里也是如此。第一次调用你用getlasterror会发现0x7a的错误,别担心,这是正常的,iReqLen参数会包含正确的deviceInterfaceDetailDataSize数值。第二次调用的时候传递此传回值,函数就会执行成功。你可以在第二次调用后用getlasterror看返回值是不是0。这个函数就是区的设备的路径!

然后就可以用creatfile创建句柄了。 ;)


[编辑 -  7/25/04 by  metalwing]
新手上路,请多关照.
leadphone
驱动牛犊
驱动牛犊
  • 注册日期2002-11-28
  • 最后登录2008-09-04
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
11楼#
发布于:2004-07-26 00:23
会不会是系统不支持对设备的访问?
比如说win2k下就不能访问鼠标键盘类的hid设备,但是我换了joystick却可以访问,也是hid的。

分不分的无所谓的,关键是讨论问题嘛,呵呵
metalwing
驱动中牛
驱动中牛
  • 注册日期2003-10-13
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分178分
  • 威望58点
  • 贡献值0点
  • 好评度17点
  • 原创分0分
  • 专家分0分
12楼#
发布于:2004-07-26 09:37
谢谢帮助。
系统应该是支持的,我使用两种环境(VC+DDK+DS、BCB,程序一样)编译,两种环境都能编译通过,但只有第一种环境编译的程序执行正确,而使用BCB环境编译的程序执行到第二个SetupDiGetInterfaceDeviceDetail()不成功,用GetLastError(),发现返回错误代码1784。不知为何?
另外,我现在使用另一种方法打开USB设备,倒是能成功。但不知会否有什么问题,请指教。
利用注册表,在HKEY_LOCAL_MACHINE中的SYSTEMCONTROLSET001ControlDeviceClass中查找设备的GUID,打开后,获取键名:
    RegEnumKey(m_hKey, 0, cKeyName, 255);//cKeyName为char[255]
然后修正cKeyName:
    cKeyName[0]='';
    cKeyName[1]='';
    cKeyName[3]='';
这时,cKeyName就相当于使用传统方法获得的Detail->Devicepath了。应用程序可以使用它来打开Usb设备。
这是我调试程序的时候无意间发现的。也估计到会有问题,因传统方法打不开设备,就先用这个方法。谁能帮我说明一下,这个方法的原因。也说一下这个方法的漏洞。谢谢。

[编辑 -  7/26/04 by  metalwing]

[编辑 -  7/26/04 by  metalwing]
新手上路,请多关照.
lhm_as
驱动牛犊
驱动牛犊
  • 注册日期2004-03-08
  • 最后登录2006-04-19
  • 粉丝0
  • 关注0
  • 积分4分
  • 威望1点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
13楼#
发布于:2004-07-28 20:25
SetupDi... 是winapi函数你可以在msdn中找到他们,错误代码你可以通过vc tools中的error lookup查到。你可以试一下将pGuid改为
(LPGUID)&pGuid。
metalwing
驱动中牛
驱动中牛
  • 注册日期2003-10-13
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分178分
  • 威望58点
  • 贡献值0点
  • 好评度17点
  • 原创分0分
  • 专家分0分
14楼#
发布于:2004-08-01 19:25
非常感谢你的回答,你告诉我的error lookup工具非常有用。
我把pGuid改成(LPGUID)&pGuid了,还是不成。我个人觉得这跟GUID好像没有太大关系。SetupDiGetClassDevs、SetupDiEnumDeviceInterfaces都返回了值(不知道返回值对不对怎么确认呢?)。就是在SetupDiGetInterfaceDeviceDetail那里死活过不去。郁闷中。
我现在已经用另一种办法,通过注册表来获得DevicePath了。
SetupDi... 是winapi函数你可以在msdn中找到他们,错误代码你可以通过vc tools中的error lookup查到。你可以试一下将pGuid改为
(LPGUID)&pGuid。
 
新手上路,请多关照.
billy2004
驱动牛犊
驱动牛犊
  • 注册日期2004-07-03
  • 最后登录2005-01-13
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
15楼#
发布于:2004-08-03 08:18
是GUIDD的事,查查我以前的帖子。
metalwing
驱动中牛
驱动中牛
  • 注册日期2003-10-13
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分178分
  • 威望58点
  • 贡献值0点
  • 好评度17点
  • 原创分0分
  • 专家分0分
16楼#
发布于:2004-08-03 10:04
谢谢你的帮助,但我认为应该不是GUID的问题,原因有两点:
1。 我使用该函数在VC+DDK+DS没有问题,可创建设备句柄。只是在BCB+DDK HEADER 的情况下SetDiGetDeviceInterfaceDetail(最后的那个)不正确(第一个也不正确不过是返回了0x7a)。
2。我对可正确执行的函数在争取执行的情况下跟踪,发现DevicePath为\\?\\Usb\....{ GUID },中的GUID就是我使用的GUID(函数中的使用、deviceinterface.h中的定义、注册表中的都是)。
是GUIDD的事,查查我以前的帖子。
 
新手上路,请多关照.
qifeng8
驱动小牛
驱动小牛
  • 注册日期2003-08-26
  • 最后登录2013-01-31
  • 粉丝0
  • 关注0
  • 积分9分
  • 威望80点
  • 贡献值0点
  • 好评度21点
  • 原创分0分
  • 专家分0分
17楼#
发布于:2004-09-23 09:21
不知道解决没有,小弟也碰到了同样的问题
sendwb
驱动牛犊
驱动牛犊
  • 注册日期2004-05-21
  • 最后登录2006-09-01
  • 粉丝0
  • 关注0
  • 积分2分
  • 威望1点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
18楼#
发布于:2005-06-22 10:52
我也遇到同样的问题了,我也是直接在注册表里找到符号连接,然后直接打开通讯端口的,不知道楼主有没有解决,能QQ上交流一下:13488339
游客

返回顶部