Example #1
0
// ======================================================================
void ListHookedDevice::Item::setDeviceIdentifier(void) {
  if (!device_) return;

  IORegistryEntry* dev = device_;

  while (dev) {
    const OSNumber* vid = nullptr;
    vid = OSDynamicCast(OSNumber, dev->getProperty(kIOHIDVendorIDKey));

    const OSNumber* pid = nullptr;
    pid = OSDynamicCast(OSNumber, dev->getProperty(kIOHIDProductIDKey));

    if (vid && pid) {
      deviceIdentifier_.setVendor(DeviceVendor(vid->unsigned32BitValue()));
      deviceIdentifier_.setProduct(DeviceProduct(pid->unsigned32BitValue()));

      goto finish;

    } else {
      // ApplePS2Keyboard does not have ProductID,
      // so we check for Manufacturer and Product strings
      const char* name = dev->getName();

      if (name && strcmp(name, "ApplePS2Keyboard") == 0) {
        // kIOHIDManufacturerKey == "Manufacturer"
        // kIOHIDProductKey == "Product"
        const OSString* manufacturer = OSDynamicCast(OSString, dev->getProperty(kIOHIDManufacturerKey));
        const OSString* product = OSDynamicCast(OSString, dev->getProperty(kIOHIDProductKey));

        if (manufacturer && product) {
          if (manufacturer->isEqualTo("Apple") &&
              product->isEqualTo("Keyboard")) {
            deviceIdentifier_.setVendor(DeviceVendor::APPLE_COMPUTER);
            deviceIdentifier_.setProduct(DeviceProduct::APPLE_INTERNAL_KEYBOARD_TRACKPAD_0x0218);
            goto finish;
          }
        }
      }
    }

    // check parent property.
    dev = dev->getParentEntry(IORegistryEntry::getPlane(kIOServicePlane));
  }

finish:
  // Set LocationID
  if (dev) {
    const OSNumber* locationid = nullptr;
    locationid = OSDynamicCast(OSNumber, dev->getProperty(kIOHIDLocationIDKey));
    if (locationid) {
      deviceIdentifier_.setLocation(DeviceLocation(locationid->unsigned32BitValue()));
    }
  }

  IOLOG_DEBUG("HookedDevice::setVendorProductLocation device_:%p, vendor:0x%04x, product:0x%04x location:0x%04x\n",
              device_,
              deviceIdentifier_.getVendor().get(),
              deviceIdentifier_.getProduct().get(),
              deviceIdentifier_.getLocation().get());
}
bool ListHookedKeyboard::isExternalDevicesConnected(void) const {
  for (Item* p = static_cast<Item*>(list_.safe_front()); p; p = static_cast<Item*>(p->getnext())) {
    if (Config::get_essential_config(BRIDGE_ESSENTIAL_CONFIG_INDEX_general_treat_unifying_as_pointing_device)) {
      if (p->getDeviceIdentifier().isEqualVendorProduct(DeviceVendor(0x046d), DeviceProduct(0xc52b))) {
        continue;
      }
    }
    if (Config::get_essential_config(BRIDGE_ESSENTIAL_CONFIG_INDEX_general_treat_bluetooth_usb_host_controller_broadcom_as_pointing_device)) {
      if (p->getDeviceIdentifier().isEqualVendorProduct(DeviceVendor(0x05ac), DeviceProduct(0x8290))) {
        continue;
      }
    }
    if (Config::get_essential_config(BRIDGE_ESSENTIAL_CONFIG_INDEX_general_ignore_invalid_devices_from_external_keyboard)) {
      if (p->getDeviceIdentifier().isEqualVendorProduct(DeviceVendor(0x0000), DeviceProduct(0x0000))) {
        continue;
      }
    }

    // Ignore Mice which has keyboard interface:
    // * Razer DeathAdder Chroma
    // * Mionix Naos 7000
    // * Logitech Bluetooth Mouse M555b
    if (p->getDeviceIdentifier().isEqualVendorProduct(DeviceVendor::Razer, DeviceProduct::Razer_DeathAdder_Chroma) ||
        p->getDeviceIdentifier().isEqualVendorProduct(DeviceVendor::Mionix, DeviceProduct::Mionix_Naos_7000) ||
        p->getDeviceIdentifier().isEqualVendorProduct(DeviceVendor::LOGITECH, DeviceProduct::Logitech_Bluetooth_Mouse_M555b) ||
#if 0
        /* Debug code: HHKB Professional JP */
        p->getDeviceIdentifier().isEqualVendorProduct(DeviceVendor(0x04fe), DeviceProduct(0x000d)) ||
#endif
        false) {
      continue;
    }

    if (p->getDeviceType() != DeviceType::APPLE_MIKEY_HID_DRIVER &&
        p->getDeviceType() != DeviceType::APPLE_INTERNAL) {
      return true;
    }
  }

  return false;
}
Example #3
0
  DeviceFilter(unsigned int type, const unsigned int* vec, size_t length) : RemapFilterBase(type) {
    targets_.reserve(length / 3);

    for (int i = 0; i < static_cast<int>(length) - 2; i += 3) {
      targets_.push_back(DeviceIdentifier(DeviceVendor(vec[i]),
                                          DeviceProduct(vec[i + 1]),
                                          DeviceLocation(vec[i + 2])));
    }

    if (length % 3 > 0) {
      IOLOG_WARN("Invalid length(%d) in BRIDGE_FILTERTYPE_DEVICE_*\n", static_cast<int>(length));
    }
  }
Example #4
0
void ForceNumLockOn::add(AddDataType datatype, AddValue newval) {
  switch (datatype) {
  case BRIDGE_DATATYPE_DEVICEVENDOR:
    switch (index_) {
    case 0:
      deviceIdentifier_.setVendor(DeviceVendor(newval));
      ++index_;
      break;
    default:
      IOLOG_ERROR("Invalid ForceNumLockOn::add\n");
      break;
    }
    break;

  case BRIDGE_DATATYPE_DEVICEPRODUCT:
    switch (index_) {
    case 1:
      deviceIdentifier_.setProduct(DeviceProduct(newval));
      ++index_;
      break;
    default:
      IOLOG_ERROR("Invalid ForceNumLockOn::add\n");
      break;
    }
    break;

  case BRIDGE_DATATYPE_DEVICELOCATION:
    switch (index_) {
    case 2:
      deviceIdentifier_.setLocation(DeviceLocation(newval));
      ++index_;
      break;
    default:
      IOLOG_ERROR("Invalid ForceNumLockOn::add\n");
      break;
    }
    break;

  case BRIDGE_DATATYPE_OPTION: {
    Option option(newval);
    if (Option::FORCENUMLOCKON_FORCE_OFF == option) {
      forceOffMode_ = true;
    }
    break;
  }

  default:
    IOLOG_ERROR("ForceNumLockOn::add invalid datatype:%u\n", static_cast<unsigned int>(datatype));
    break;
  }
}
Example #5
0
    void
    FilterUnion::initialize(const unsigned int* vec, size_t length)
    {
      type_ = BRIDGE_FILTERTYPE_NONE;

      // ------------------------------------------------------------
      // check parameters.
      //
      if (! vec || length == 0) {
        IOLOG_ERROR("FilterUnion::initialize invalid parameter.\n");
        goto error;
      }

      // ------------------------------------------------------------
      // initialize values.
      //
      type_ = vec[0];

      switch (type_) {
        case BRIDGE_FILTERTYPE_APPLICATION_NOT:
        case BRIDGE_FILTERTYPE_APPLICATION_ONLY:
          p_.applicationFilter = new ApplicationFilter(type_);
          if (p_.applicationFilter) {
            for (size_t i = 1; i < length; ++i) {
              (p_.applicationFilter)->add(AddValue(vec[i]));
            }
          }
          break;

        case BRIDGE_FILTERTYPE_CONFIG_NOT:
        case BRIDGE_FILTERTYPE_CONFIG_ONLY:
          p_.configFilter = new ConfigFilter(type_);
          if (p_.configFilter) {
            for (size_t i = 1; i < length; ++i) {
              (p_.configFilter)->add(AddValue(vec[i]));
            }
          }
          break;

        case BRIDGE_FILTERTYPE_DEVICE_NOT:
        case BRIDGE_FILTERTYPE_DEVICE_ONLY:
          p_.deviceFilter = new DeviceFilter(type_);
          if (p_.deviceFilter) {
            for (size_t i = 1; i < length - 2; i += 3) {
              (p_.deviceFilter)->add(DeviceVendor(vec[i]),
                                     DeviceProduct(vec[i + 1]),
                                     DeviceLocation(vec[i + 2]));
            }
            if ((length - 1) % 3 > 0) {
              IOLOG_WARN("Invalid length(%d) in BRIDGE_FILTERTYPE_DEVICE_*\n", static_cast<int>(length));
            }
          }
          break;

        case BRIDGE_FILTERTYPE_ELAPSEDTIMESINCELASTPRESSED_GREATERTHAN:
        case BRIDGE_FILTERTYPE_ELAPSEDTIMESINCELASTPRESSED_LESSTHAN:
          p_.elapsedTimeSinceLastPressedFilter = new ElapsedTimeSinceLastPressedFilter(type_);
          if (p_.elapsedTimeSinceLastPressedFilter) {
            for (size_t i = 1; i < length - 1; i += 2) {
              (p_.elapsedTimeSinceLastPressedFilter)->add(AddDataType(vec[i]), AddValue(vec[i + 1]));
            }
          }
          break;

        case BRIDGE_FILTERTYPE_INPUTSOURCE_NOT:
        case BRIDGE_FILTERTYPE_INPUTSOURCE_ONLY:
        case BRIDGE_FILTERTYPE_INPUTSOURCEDETAIL_NOT:
        case BRIDGE_FILTERTYPE_INPUTSOURCEDETAIL_ONLY:
          p_.inputSourceFilter = new InputSourceFilter(type_);
          if (p_.inputSourceFilter) {
            for (size_t i = 1; i < length; ++i) {
              (p_.inputSourceFilter)->add(AddValue(vec[i]));
            }
          }
          break;

        case BRIDGE_FILTERTYPE_LASTPRESSEDPHYSICALKEY_NOT:
        case BRIDGE_FILTERTYPE_LASTPRESSEDPHYSICALKEY_ONLY:
          p_.lastPressedPhysicalKeyFilter = new LastPressedPhysicalKeyFilter(type_);
          if (p_.lastPressedPhysicalKeyFilter) {
            for (size_t i = 1; i < length - 1; i += 2) {
              (p_.lastPressedPhysicalKeyFilter)->add(AddDataType(vec[i]), AddValue(vec[i + 1]));
            }
          }
          break;

        case BRIDGE_FILTERTYPE_MODIFIER_NOT:
        case BRIDGE_FILTERTYPE_MODIFIER_ONLY:
          p_.modifierFilter = new ModifierFilter(type_);
          if (p_.modifierFilter) {
            for (size_t i = 1; i < length - 1; i += 2) {
              (p_.modifierFilter)->add(AddDataType(vec[i]), AddValue(vec[i + 1]));
            }
          }
          break;

        case BRIDGE_FILTERTYPE_WINDOWNAME_NOT:
        case BRIDGE_FILTERTYPE_WINDOWNAME_ONLY:
          p_.windowNameFilter = new WindowNameFilter(type_);
          if (p_.windowNameFilter) {
            for (size_t i = 1; i < length; ++i) {
              (p_.windowNameFilter)->add(AddValue(vec[i]));
            }
          }
          break;

        case BRIDGE_FILTERTYPE_UIELEMENTROLE_NOT:
        case BRIDGE_FILTERTYPE_UIELEMENTROLE_ONLY:
          p_.uiElementRoleFilter = new UIElementRoleFilter(type_);
          if (p_.uiElementRoleFilter) {
            for (size_t i = 1; i < length; ++i) {
              (p_.uiElementRoleFilter)->add(AddValue(vec[i]));
            }
          }
          break;

        default:
          IOLOG_ERROR("FilterUnion::initialize unknown type_:%d.\n", type_);
          goto error;
      }

      return;

    error:
      terminate();
    }