首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > VC/MFC >

USB不能打开请诸位看看错在哪里

2012-12-30 
USB不能打开请各位看看错在哪里我写的用来打开US旧的device是可以打开可以使用的,但是新的却不可以,我知道

USB不能打开请各位看看错在哪里
我写的用来打开US旧的device是可以打开可以使用的,但是新的却不可以,我知道新的机器的vid,pid都改变了,但是我已经将所有的代码里的vid ,pid改成新的了。打开程序每次运行到SetupDiEnumDeviceInterfaces里面返回的strtInterfaceData.Flags=SPINT_ACTIVE,说明device已经在启用了。但是旧机器却没有这种情况这是怎么回事呢?跟硬件有关?
下面是代码:
BOOL CUSBCalcDlg::UsbOpenDriver(HANDLE *hDevice) 
{
// TODO: Add your control notification handler code here
#ifdef Debug_mode
MessageBox(_T("start the  usbopendriver "),NULL, NULL);
#endif

HDEVINFO hDevInfo = SetupDiGetClassDevs(&guidHID,NULL,0,   //取得HID资讯的结构阵列//失败了.
                DIGCF_PRESENT|DIGCF_INTERFACEDEVICE );
if(hDevInfo == INVALID_HANDLE_VALUE) //没有设备连接
{
#ifdef Debug_mode
MessageBox(_T("can not find the device"),NULL, NULL);
#endif
return FALSE;
}
SP_DEVICE_INTERFACE_DATA strtInterfaceData;
strtInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
DWORD index = 0;
CString temp;
BOOL findFlag = FALSE;
int i = 0;
while(1)     // 查找人体学输入设备类USB,直到查完或已经查到为止
{
//枚举每一个设备
    if(!SetupDiEnumDeviceInterfaces(hDevInfo, 
                            NULL, 
&guidHID, 
i,
                                &strtInterfaceData))   
{
#ifdef Debug_mode
MessageBox((LPCTSTR)strtInterfaceData.Flags,NULL, NULL);
#endif

break;
}
//strtInterfaceData.Flags = SPINT_DEFAULT;
i++;
if(strtInterfaceData.Flags == SPINT_ACTIVE )
{
//调用两次SetupDiGetDeviceInterfaceDetail()
//第一次调用,虽然返回值出错,但获得DeviceInterfaceDetailDataSize数值的大小,存在strSize中
//第二次调用,函数执行正常,可以获得PSP_DEVICE_INTERFACE_DETAIL_DATA结构
//通过两次调用,获得设备的路径名称。
#ifdef Debug_mode
MessageBox(_T("stuck here in the second call"),NULL, NULL);
#endif
DWORD strSize = 0, requiesize = 0;
        SetupDiGetDeviceInterfaceDetail(hDevInfo, &strtInterfaceData, NULL, 0, &strSize, NULL);
        requiesize = strSize;  
PSP_DEVICE_INTERFACE_DETAIL_DATA strtDetailData;
strtDetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)malloc(requiesize);
        strtDetailData -> cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
        SP_DEVINFO_DATA infodata;
        infodata.cbSize = sizeof(SP_DEVINFO_DATA);
if(!SetupDiGetDeviceInterfaceDetail(hDevInfo, 
                                &strtInterfaceData,
                                        strtDetailData, 
strSize, 


&requiesize, 
NULL))
{
#ifdef Debug_mode
MessageBox(_T("stuck here in the scecond SetupDiGetDeviceInterfacDetail call"),NULL, NULL);
#endif
        free(strtDetailData);
        break;
}
CString str;
str = strtDetailData -> DevicePath;
str.MakeLower();
if(str.Find(_T("vid_c251&pid_1301")) == -1) //是否是我们所需的设备
{
#ifdef Debug_mode
MessageBox(_T("can not find the device"),NULL, NULL);
#endif

continue;
}
    *hDevice = CreateFile(strtDetailData->DevicePath,
                                  GENERIC_READ | GENERIC_WRITE,
                                  FILE_SHARE_READ | FILE_SHARE_WRITE,
                                  NULL, 
                                  OPEN_EXISTING, 
  0, 
                                  NULL);   //取得设备的句柄
if(*hDevice == INVALID_HANDLE_VALUE)
{
#ifdef Debug_mode
MessageBox(NULL, _T("could  not get the device handle "), NULL);
#endif

        free(strtDetailData);  //释放资源
        continue;
}
free(strtDetailData);  //释放资源
            /////////////////////////////////////////////////////////////////////////
/////读取硬件信息,判断是否是我们的设备
DWORD BytesReturned;
BYTE deviceDescriptor[50];
if(!DeviceIoControl(*hDevice, 
 IOCTL_USBKBD_GET_DEVICE_DESCRIPTOR,
 NULL, 
 0,        // Input
 deviceDescriptor, 
 sizeof(deviceDescriptor),  // Output
 &BytesReturned, NULL))
{
#ifdef Debug_mode
MessageBox(NULL, _T("could not get the device descriptor"), NULL);
#endif
// Could not get deveice descriptor
CloseHandle(*hDevice);
continue;
}

if((deviceDescriptor[0x0C] != 0x02) || (deviceDescriptor[0x0D] != 0x01))
{
CloseHandle(*hDevice);
continue;
}
////////读取硬件信息完
////////////////////////////////////////////////////////////////////////////
findFlag = TRUE;
break;
}
}

    SetupDiDestroyDeviceInfoList(hDevInfo);   //释放由SetupDiGetClassDevs()产生的资源
    if(findFlag == FALSE) 


    {
        return FALSE;
    }
    else 
    {
if(calc_OpenDevice(*hDevice))
            return TRUE;
else 
return FALSE;
    }    //打开设备就返回true,反之,返回false
#ifdef Debug_mode
MessageBox(_T("function finished "),NULL, NULL);
#endif
 return TRUE;
}
还是是不是有可能guid不对?但是也不可能那~
我用的guid:
GUID guidHID1= {0x4D1E55B2, 0xF16F, 0x11CF, {0x88, 0xCB, 0x00, 0x11, 0x11, 0x00, 0x00, 0x30}};
[解决办法]
没时间看~太长了~给你我的代码吧~


BOOL OpenDevice(CString byDevPathName)
{
hWriteHandle=INVALID_HANDLE_VALUE;
m_DevPathName = byDevPathName;
MyDevFound=TRUE; 
//那么就是我们要找的设备,分别使用读写方式打开之,并保存其句柄
//并且选择为异步访问方式。
//读方式打开设备
hReadHandle=CreateFile(byDevPathName, 
               GENERIC_READ,
                           FILE_SHARE_READ
[解决办法]
FILE_SHARE_WRITE, 
                           NULL,
   OPEN_EXISTING,
   FILE_ATTRIBUTE_NORMAL
[解决办法]
FILE_FLAG_OVERLAPPED,
   NULL);

if(hReadHandle==INVALID_HANDLE_VALUE)
return FALSE;
hWriteHandle=CreateFile(m_DevPathName, 
GENERIC_WRITE,
FILE_SHARE_READ
[解决办法]
FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL
[解决办法]
FILE_FLAG_OVERLAPPED,
NULL); 

if(hWriteHandle==INVALID_HANDLE_VALUE)
return FALSE;

DataInSending=FALSE; //可以发送数据

      //手动触发事件,让读报告线程恢复运行。因为在这之前并没有调用
      //读数据的函数,也就不会引起事件的产生,所以需要先手动触发一
      //次事件,让读报告线程恢复运行。
SetEvent(ReadOverlapped.hEvent);
      
//显示设备的状态。

return TRUE;
}



SearchDevice(CString &byDevPathName)
{

GUID HidGuid;
HDEVINFO hDevInfoSet;
DWORD MemberIndex;
SP_DEVICE_INTERFACE_DATA DevInterfaceData;
BOOL Result;
DWORD RequiredSize;
PSP_DEVICE_INTERFACE_DETAIL_DATApDevDetailData;
 HANDLE hDevHandle;
HIDD_ATTRIBUTES DevAttributes;
HIDP_CAPS Caps;

//初始化读、写句柄为无效句柄。
DevInterfaceData.cbSize=sizeof(DevInterfaceData);
DevAttributes.Size=sizeof(DevAttributes);

HidD_GetHidGuid(&HidGuid);
hDevInfoSet=SetupDiGetClassDevs(&HidGuid,
                             NULL,
 NULL,


 DIGCF_DEVICEINTERFACE
[解决办法]
DIGCF_PRESENT);
MemberIndex=0;
while(1)
{

Result=SetupDiEnumDeviceInterfaces(hDevInfoSet,
NULL,
     &HidGuid,
     MemberIndex,
      &DevInterfaceData);
if(Result==FALSE)  
break;
MemberIndex++;
Result=SetupDiGetDeviceInterfaceDetail(hDevInfoSet,
                                  &DevInterfaceData,
    NULL,
NULL,
&RequiredSize,
NULL);
pDevDetailData=(PSP_DEVICE_INTERFACE_DETAIL_DATA)malloc(RequiredSize);
if(pDevDetailData==NULL) //如果内存不足,则直接返回。
{
SetupDiDestroyDeviceInfoList(hDevInfoSet);
return FALSE;
}

//并设置pDevDetailData的cbSize为结构体的大小(注意只是结构体大小,
//不包括后面缓冲区)。
pDevDetailData->cbSize=sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);

//然后再次调用SetupDiGetDeviceInterfaceDetail函数来获取设备的
//详细信息。这次调用设置使用的缓冲区以及缓冲区大小。
Result=SetupDiGetDeviceInterfaceDetail(hDevInfoSet,
                                   &DevInterfaceData,
pDevDetailData,
RequiredSize,
NULL,
NULL);
//将设备路径复制出来,然后销毁刚刚申请的内存。
byDevPathName=pDevDetailData->DevicePath;
free(pDevDetailData);

//如果调用失败,则查找下一个设备。
if(Result==FALSE) 
continue;

//如果调用成功,则使用不带读写访问的CreateFile函数
//来获取设备的属性,包括VID、PID、版本号等。
//对于一些独占设备(例如USB键盘),使用读访问方式是无法打开的,
//而使用不带读写访问的格式才可以打开这些设备,从而获取设备的属性。
hDevHandle=CreateFile(byDevPathName, 
            NULL,
                        FILE_SHARE_READ
[解决办法]
FILE_SHARE_WRITE, 
                        NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);

//如果打开成功,则获取设备属性。
if(hDevHandle!=INVALID_HANDLE_VALUE)
{
//获取设备的属性并保存在DevAttributes结构体中
Result=HidD_GetAttributes(hDevHandle,&DevAttributes);
PHIDP_PREPARSED_DATA PreparsedData;
HidD_GetPreparsedData(hDevHandle,&PreparsedData);
HidP_GetCaps (PreparsedData,&Caps);


//关闭刚刚打开的设备
CloseHandle(hDevHandle);

   //获取失败,查找下一个
   if(Result==FALSE) 
   continue;
   if(DevAttributes.VersionNumber == 0x0200
   && Caps.UsagePage == 0xFFB1
   && Caps.Usage == 1
   && Caps.InputReportByteLength == 8
   && Caps.OutputReportByteLength == 8)
{
Result=TRUE; //设置设备已经找到
break;
}
}
else 
continue;
}
SetupDiDestroyDeviceInfoList(hDevInfoSet);
return Result;


}


[解决办法]
guid没问题。

[解决办法]
引用:
guid没问题。
大哥
你怎么刚过来
这都是月初的帖子了
[解决办法]
引用:
引用:

guid没问题。
大哥
你怎么刚过来
这都是月初的帖子了

俗事缠身啊。

热点排行