歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

根據USB設備硬件信息獲取Android設備型號

前些日子,自己接手專門為Android設備開發的數據恢復軟件,第一次作為項目經理帶隊進行項目開發。

其中為了解決設備和型號的對應關系,用於區分當前接入系統的設備是USB設備,並且是Android設備而不是通常的USB設備或者其他的手機設備。

故需要獲得設備的硬件設備序號,根據硬件信息特征碼來和Android特征碼數據庫進行匹配,來取得設備的型號。

首先根據硬件的GUID獲取USB類設備集句柄

//USB設備的GUID
static const GUID GUID_DEVINTERFACE_USB_DEVICE =
{ 0xA5DCBF10L, 0x6530, 0x11D2, { 0x90, 0x1F, 0x00, 0xC0, 0x4F, 0xB9, 0x51, 0xED } };
//磁盤的GUID
const GUID* szDiskClassGuid = &GUID_DEVINTERFACE_DISK;  //磁盤類
const GUID* volumeGuid_ = &GUID_DEVINTERFACE_VOLUME;   //卷類


//獲取USB類設備集句柄
int CusbDeviceInfo::EnumUsbDeviceSet()
{
 // Get device interface info set handle for all devices attached to system
    hDevInfo = NULL;
    hDevInfo = SetupDiGetClassDevs(
  szDiskClassGuid, /* CONST GUID * ClassGuid - USB class GUID */
  NULL, /* PCTSTR Enumerator */
  NULL, /* HWND hwndParent */
  DIGCF_PRESENT | DIGCF_DEVICEINTERFACE/* DWORD Flags */);

    if(hDevInfo == INVALID_HANDLE_VALUE)
    {    
     DWORD err = GetLastError();
     qDebug()<<"EnumUsbDeviceSet= "<<QString::number(err);
     return -1;
    }

    //獲取可移動分區
    bool Rv = GetAllRemovablePartitions();
    //if (Rv)
    //{
     int ret = EnumUsbDeviceInfo();
     return ret;
    //}
    //else
    //{
    //   return -1;
    //}
}


//獲取枚舉的設備信息
  SP_DEVINFO_DATA devInfoData = {sizeof(SP_DEVINFO_DATA)}; 
  bRet = SetupDiEnumDeviceInfo(hDevInfo,dwIndex,&devInfoData);
  if(!bRet)
  {
   DWORD err = GetLastError();
           SetupDiDestroyDeviceInfoList(hDevInfo);
      break;
  }

  DWORD nSize=0 ;       
  TCHAR DevInstanceId[MAX_PATH];
       if(SetupDiGetDeviceInstanceId(hDevInfo, &devInfoData, DevInstanceId, sizeof(DevInstanceId), &nSize))
    {   
     QString DeviceId = QString::fromWCharArray(DevInstanceId);
     //m_DeviceIdVector.append(DeviceId);
     if (DeviceId.left(3).toUpper() == "USB")
     {
              qDebug()<<"DeviceId = "<<DeviceId;
     }
   
    }
    else
    {
     DWORD err = GetLastError();
     continue;
    }

//
    //獲取設備接口數據集
    SP_DEVICE_INTERFACE_DATA devInterfaceData;
    BYTE buffer[BUFFER_SIZE];
    DWORD RequiredSize;
    TCHAR buf[BUFFER_SIZE];
    DEVINST devInstParent;

    ZeroMemory(&devInterfaceData, sizeof(devInterfaceData));
    devInterfaceData.cbSize = sizeof(devInterfaceData);
    if(!SetupDiEnumDeviceInterfaces(hDevInfo,NULL,szDiskClassGuid,dwIndex,&devInterfaceData))
    {
     qDebug()<<"SetupDiEnumDeviceInterfaces error ";
     DWORD err = GetLastError();
     continue;
    }

 //獲取設備接口細節信息
    ZeroMemory(&devInfoData, sizeof(devInfoData));
    devInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
    PSP_DEVICE_INTERFACE_DETAIL_DATA pDevDetail;
    pDevDetail = (PSP_DEVICE_INTERFACE_DETAIL_DATA)buffer;
    pDevDetail->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);

    bool ret = SetupDiGetDeviceInterfaceDetail(hDevInfo, &devInterfaceData,
     pDevDetail, BUFFER_SIZE, &RequiredSize, &devInfoData);
    if(!ret)
    {
     qDebug()<<"SetupDiGetDeviceInterfaceDetail error ";
     DWORD err = GetLastError();
     continue;
    }


 //獲取設備狀態
     CM_Get_Device_ID(devInfoData.DevInst, buf, sizeof(buf),0); 
  QString str = QString::fromStdWString(buf);
 
  if (str.left(3).toUpper() == "USB")
  {
   qDebug()<<"CM_GET_DEVICE_ID_1 = "<<str;
           m_DeviceVectorID_1.append(QString::fromStdWString(buf));
  }

     CM_Get_Parent(&devInstParent,devInfoData.DevInst, 0); 
  CM_Get_Device_ID(devInstParent, buf, sizeof(buf),0); 
  str = QString::fromStdWString(buf);

 //根據以下方法取得設備SDN id
 HANDLE hDrive = CreateFile(pDevDetail->DevicePath, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);

同時可根據系統中移動分區各個盤符取得對應的磁盤以及磁盤SDN id.

根據設備獲取的和通過系統中獲取的移動設備進行SDN匹配就能獲取設備和系統中盤符的對應關系。

同時可以根據上面獲取到的設備狀態和設備接口細節信息去Android SQL數據中通過正則表達式進行序列號匹配獲取是否是Android設備。

以及android設備的型號。 由於安卓設備型號復雜,種類繁多,所以目前只能通過數據庫匹配的方式來進行是否是Android設備的判斷。

如果新出的設備,需要隨時更新數據庫。 不知哪位大牛有更好的方法。

Copyright © Linux教程網 All Rights Reserved