Esempio n. 1
0
void CPeripheralBus::UnregisterRemovedDevices(const PeripheralScanResults &results)
{
  CSingleLock lock(m_critSection);
  std::vector<CPeripheral *> removedPeripherals;
  for (int iDevicePtr = (int) m_peripherals.size() - 1; iDevicePtr >= 0; iDevicePtr--)
  {
    CPeripheral *peripheral = m_peripherals.at(iDevicePtr);
    PeripheralScanResult updatedDevice(m_type);
    if (!results.GetDeviceOnLocation(peripheral->Location(), &updatedDevice) ||
        *peripheral != updatedDevice)
    {
      /* device removed */
      removedPeripherals.push_back(peripheral);
      m_peripherals.erase(m_peripherals.begin() + iDevicePtr);
    }
  }
  lock.Leave();

  for (unsigned int iDevicePtr = 0; iDevicePtr < removedPeripherals.size(); iDevicePtr++)
  {
    CPeripheral *peripheral = removedPeripherals.at(iDevicePtr);
    std::vector<PeripheralFeature> features;
    peripheral->GetFeatures(features);
    bool peripheralHasFeatures = features.size() > 1 || (features.size() == 1 && features.at(0) != FEATURE_UNKNOWN);
    if (peripheral->Type() != PERIPHERAL_UNKNOWN || peripheralHasFeatures)
    {
      CLog::Log(LOGNOTICE, "%s - device removed from %s/%s: %s (%s:%s)", __FUNCTION__, PeripheralTypeTranslator::TypeToString(peripheral->Type()), peripheral->Location().c_str(), peripheral->DeviceName().c_str(), peripheral->VendorIdAsString(), peripheral->ProductIdAsString());
      peripheral->OnDeviceRemoved();
    }

    m_manager->OnDeviceDeleted(*this, *peripheral);
    delete peripheral;
  }
}
Esempio n. 2
0
void CPeripheralAddon::UnregisterRemovedDevices(const PeripheralScanResults &results, PeripheralVector& removedPeripherals)
{
  CSingleLock lock(m_critSection);
  std::vector<unsigned int> removedIndexes;
  for (auto& it : m_peripherals)
  {
    const PeripheralPtr& peripheral = it.second;
    PeripheralScanResult updatedDevice(PERIPHERAL_BUS_ADDON);
    if (!results.GetDeviceOnLocation(peripheral->Location(), &updatedDevice) ||
      *peripheral != updatedDevice)
    {
      // Device removed
      removedIndexes.push_back(it.first);
    }
  }
  lock.Leave();

  for (auto index : removedIndexes)
  {
    auto it = m_peripherals.find(index);
    const PeripheralPtr& peripheral = it->second;
    CLog::Log(LOGNOTICE, "%s - device removed from %s/%s: %s (%s:%s)", __FUNCTION__, PeripheralTypeTranslator::TypeToString(peripheral->Type()), peripheral->Location().c_str(), peripheral->DeviceName().c_str(), peripheral->VendorIdAsString(), peripheral->ProductIdAsString());
    UnregisterButtonMap(peripheral.get());
    peripheral->OnDeviceRemoved();
    removedPeripherals.push_back(peripheral);
    m_peripherals.erase(it);
  }
}
Esempio n. 3
0
void CPeripheralBus::UnregisterRemovedDevices(const PeripheralScanResults &results)
{
  CSingleLock lock(m_critSection);
  for (int iDevicePtr = (int) m_peripherals.size() - 1; iDevicePtr >= 0; iDevicePtr--)
  {
    CPeripheral *peripheral = m_peripherals.at(iDevicePtr);
    PeripheralScanResult updatedDevice;
    if (!results.GetDeviceOnLocation(peripheral->Location(), &updatedDevice) ||
        updatedDevice != *peripheral)
    {
      /* device removed */
      if (peripheral->Type() != PERIPHERAL_UNKNOWN)
        CLog::Log(LOGNOTICE, "%s - device removed from %s/%s: %s (%s:%s)", __FUNCTION__, PeripheralTypeTranslator::TypeToString(peripheral->Type()), peripheral->Location().c_str(), peripheral->DeviceName().c_str(), peripheral->VendorIdAsString(), peripheral->ProductIdAsString());
      m_peripherals.erase(m_peripherals.begin() + iDevicePtr);
      lock.Leave();

      m_manager->OnDeviceDeleted(*this, peripheral->FileLocation());
      delete peripheral;
    }
  }
}
Esempio n. 4
0
bool CPeripheralBusUSB::PerformDeviceScan(const GUID *guid, const PeripheralType type, PeripheralScanResults &results)
{
  bool     bReturn(false);
  HDEVINFO hDevHandle;
  DWORD    required = 0, iMemberIndex = 0;
  int      nBufferSize = 0;

  SP_DEVICE_INTERFACE_DATA deviceInterfaceData;
  deviceInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);

  SP_DEVINFO_DATA devInfoData;
  devInfoData.cbSize = sizeof(SP_DEVINFO_DATA);

  if ((hDevHandle = SetupDiGetClassDevs(guid, 0, 0, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE)) == INVALID_HANDLE_VALUE)
  {
    CLog::Log(LOGWARNING, "%s - cannot query USB devices: invalid handle", __FUNCTION__);
    return bReturn;
  }

  bReturn = true;
  BOOL bResult = true;
  PSP_DEVICE_INTERFACE_DETAIL_DATA devicedetailData = NULL;
  while(bResult)
  {
    bResult = SetupDiEnumDeviceInfo(hDevHandle, iMemberIndex, &devInfoData);

    if (bResult)
      bResult = SetupDiEnumDeviceInterfaces(hDevHandle, 0, guid, iMemberIndex, &deviceInterfaceData);

    if (bResult)
    {
      iMemberIndex++;
      BOOL bDetailResult = false;
      {
        // As per MSDN, Get the required buffer size. Call SetupDiGetDeviceInterfaceDetail with a 
        // NULL DeviceInterfaceDetailData pointer, a DeviceInterfaceDetailDataSize of zero, 
        // and a valid RequiredSize variable. In response to such a call, this function returns 
        // the required buffer size at RequiredSize and fails with GetLastError returning 
        // ERROR_INSUFFICIENT_BUFFER. 
        // Allocate an appropriately sized buffer and call the function again to get the interface details. 

        SetupDiGetDeviceInterfaceDetail(hDevHandle, &deviceInterfaceData, NULL, 0, &required, NULL);

        devicedetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)malloc(required * sizeof(TCHAR));
        devicedetailData->cbSize = sizeof(SP_INTERFACE_DEVICE_DETAIL_DATA);
        nBufferSize = required;
      }

      bDetailResult = SetupDiGetDeviceInterfaceDetail(hDevHandle, &deviceInterfaceData, devicedetailData, nBufferSize , &required, NULL);
      if (bDetailResult)
      {
        CStdString strVendorId(StringUtils::EmptyString);
        CStdString strProductId(StringUtils::EmptyString);
        CStdString strTmp(devicedetailData->DevicePath);
        strVendorId = strTmp.substr(strTmp.Find("vid_") + 4, 4);
        strProductId = strTmp.substr(strTmp.Find("pid_") + 4, 4);

        if ((strTmp.Find("&mi_") < 0) || (strTmp.Find("&mi_00") >= 0))
        {
          PeripheralScanResult prevDevice;
          if (!results.GetDeviceOnLocation(devicedetailData->DevicePath, &prevDevice))
          {
            PeripheralScanResult result;
            result.m_strLocation  = devicedetailData->DevicePath;
            result.m_type         = type;
            result.m_iVendorId    = PeripheralTypeTranslator::HexStringToInt(strVendorId.c_str());
            result.m_iProductId   = PeripheralTypeTranslator::HexStringToInt(strProductId.c_str());

            if (!results.ContainsResult(result))
              results.m_results.push_back(result);
          }
        }
      }

      if (devicedetailData)
      {
        free(devicedetailData);
        devicedetailData = NULL;
      } 
    }
    else
    {
      SetupDiDestroyDeviceInfoList(hDevHandle);
      return bReturn;
    }
  }

  return bReturn;
}
Esempio n. 5
0
bool CPeripheralBusUSB::PerformDeviceScan(const GUID *guid, const PeripheralType defaultType, PeripheralScanResults &results)
{
  using KODI::PLATFORM::WINDOWS::FromW;

  bool     bReturn(false);
  DWORD    required = 0, iMemberIndex = 0;
  int      nBufferSize = 200;  // Just initial guess, will be increased if required

  SP_DEVICE_INTERFACE_DATA deviceInterfaceData;
  deviceInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);

  SP_DEVINFO_DATA devInfoData;
  devInfoData.cbSize = sizeof(SP_DEVINFO_DATA);

  HDEVINFO const hDevHandle = SetupDiGetClassDevs(guid, 0, 0, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
  if (hDevHandle == INVALID_HANDLE_VALUE)
  {
    CLog::Log(LOGWARNING, "%s - cannot query USB devices: invalid handle", __FUNCTION__);
    return bReturn;
  }

  PSP_DEVICE_INTERFACE_DETAIL_DATA devicedetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)malloc(nBufferSize);
  int nPropertyBufferSize = 100; // Just initial guess, will be increased if required
  char* deviceProperty = (char*)malloc(nPropertyBufferSize);
  if (!devicedetailData || !deviceProperty)
  {
    free(devicedetailData);
    free(deviceProperty);
    CLog::Log(LOGSEVERE, "%s: memory allocation failed", __FUNCTION__);
    return false;
  }

  SP_DEVINFO_DATA deviceInfo;
  bReturn = true;
  for (iMemberIndex = 0; bReturn && iMemberIndex < MAX_BUS_DEVICES; iMemberIndex++)
  {
    bReturn = SetupDiEnumDeviceInfo(hDevHandle, iMemberIndex, &devInfoData) == TRUE;

    if (bReturn)
      bReturn = SetupDiEnumDeviceInterfaces(hDevHandle, 0, guid, iMemberIndex, &deviceInterfaceData) == TRUE;
    else
    {
      bReturn = true;
      if (GetLastError() == ERROR_NO_MORE_ITEMS)
        break; // no more USB devices, nothing more to scan
      else
        continue; // try to get other USB devices
    }

    if (bReturn)
    {
      devicedetailData->cbSize = sizeof(SP_INTERFACE_DEVICE_DETAIL_DATA);
      deviceInfo.cbSize = sizeof(SP_DEVINFO_DATA);

      BOOL bDetailResult = SetupDiGetDeviceInterfaceDetail(hDevHandle, &deviceInterfaceData, devicedetailData, nBufferSize , &required, &deviceInfo);
      if (!bDetailResult && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
      {
        free(devicedetailData);
        devicedetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)malloc(required * sizeof(TCHAR));
        if (!devicedetailData)
        {
          free(deviceProperty);
          CLog::Log(LOGSEVERE, "%s: memory allocation failed", __FUNCTION__);
          return false;
        }
        devicedetailData->cbSize = sizeof(SP_INTERFACE_DEVICE_DETAIL_DATA);
        nBufferSize = required;
        bDetailResult = SetupDiGetDeviceInterfaceDetail(hDevHandle, &deviceInterfaceData, devicedetailData, nBufferSize , &required, &deviceInfo);
      }

      if (bDetailResult)
      {
        bDetailResult = SetupDiGetDeviceRegistryProperty(hDevHandle, &deviceInfo, SPDRP_HARDWAREID, NULL, (PBYTE)deviceProperty, nPropertyBufferSize, &required);
        if (!bDetailResult && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
        {
          free(deviceProperty);
          deviceProperty = (char*)malloc(required);
          if (!deviceProperty)
          {
            free(devicedetailData);
            CLog::Log(LOGSEVERE, "%s: memory allocation failed", __FUNCTION__);
            return false;
          }
          nPropertyBufferSize = required;
          bDetailResult = SetupDiGetDeviceRegistryProperty(hDevHandle, &deviceInfo, SPDRP_HARDWAREID, NULL, (PBYTE)deviceProperty, nPropertyBufferSize, &required);
        }
      }

      if (bDetailResult)
      {
        std::string strTmp(deviceProperty);

        StringUtils::ToLower(strTmp);
        size_t posVid, posPid;
        if (((posVid=strTmp.find("\\vid_")) != std::string::npos || (posVid=strTmp.find("&vid_")) != std::string::npos) &&
              ((posPid=strTmp.find("\\pid_")) != std::string::npos || (posPid=strTmp.find("&pid_")) != std::string::npos))
        {
          std::string strVendorId(strTmp, posVid + 5, 4);
          std::string strProductId(strTmp, posPid + 5, 4);
          PeripheralScanResult prevDevice(m_type);
          if (!results.GetDeviceOnLocation(FromW(devicedetailData->DevicePath), &prevDevice))
          {
            PeripheralScanResult result(m_type);
            result.m_strLocation  = FromW(devicedetailData->DevicePath);
            result.m_iVendorId    = PeripheralTypeTranslator::HexStringToInt(strVendorId.c_str());
            result.m_iProductId   = PeripheralTypeTranslator::HexStringToInt(strProductId.c_str());
            result.m_iSequence    = GetNumberOfPeripheralsWithId(result.m_iVendorId, result.m_iProductId);

            // Assume that buffer is more then enough (we need only 8 chars, initial allocation is 100 chars). If not - just skip type detection.
            if (SetupDiGetDeviceRegistryProperty(hDevHandle, &devInfoData, SPDRP_CLASS, NULL, (PBYTE)deviceProperty, nPropertyBufferSize, &required) &&
                strcmp("HIDClass", deviceProperty) == 0)
              result.m_type = PERIPHERAL_HID;
            else
              result.m_type = defaultType;

            if (!results.ContainsResult(result))
              results.m_results.push_back(result);
          }
        }
      }
    }
  }

  SetupDiDestroyDeviceInfoList(hDevHandle);
  if (devicedetailData)
    free(devicedetailData);
  if (deviceProperty)
    free(deviceProperty);

  return bReturn;
}