Ejemplo n.º 1
0
SCM usb_device(SCM name)
{
	io_iterator_t iterator = 0;
	
	CFDictionaryRef matchDict = IOServiceMatching(kIOUSBDeviceClassName);
	IOServiceGetMatchingServices(kIOMasterPortDefault, matchDict, &iterator);

	io_service_t device;
	int cnt = 0;
	
	int found_device = false;

	while(device = IOIteratorNext(iterator))
	{
		io_name_t dev_name;

		if(IORegistryEntryGetName(device, dev_name) == KERN_SUCCESS)
			if(!strncmp(dev_name,scm_to_locale_string(name),strlen(scm_to_locale_string(name))))
				found_device = true;
		
		IOObjectRelease(device);

		++cnt;
	}
	
	IOObjectRelease(iterator);
	
	return scm_from_int(found_device);
}
Ejemplo n.º 2
0
void dumpIter( io_iterator_t iter, mach_port_t recvPort )
{
    kern_return_t	kr;
    io_object_t		obj;
    io_name_t		name;
    io_string_t		path;
    mach_port_t		iter3;
    
    while( (obj = IOIteratorNext( iter))) {
        assert( KERN_SUCCESS == (
        kr = IORegistryEntryGetName( obj, name )
        ));
	printf("name:%s(%d)\n", name, obj);
        kr = IORegistryEntryGetPath( obj, kIOServicePlane, path );
        if( KERN_SUCCESS == kr) {
            
	    // if the object is detached, getPath will fail
            printf("path:%s\n", path);

            // as will IOServiceAddInterestNotification
            if( KERN_SUCCESS != (
                    kr = IOServiceAddInterestNotificationMsg( obj, kIOGeneralInterest,
                            recvPort, (unsigned int) obj, &iter3)
            )) printf("IOServiceAddInterestNotification(%lx)\n", kr);
            // can compare two kernel objects with IOObjectIsEqualTo() if we keep the object,
            // otherwise, release
            IOObjectRelease( obj );
        }
    }
}
Ejemplo n.º 3
0
void IOKitEventPublisher::newEvent(const io_service_t& device,
                                   IOKitEventContext::Action action) {
  auto ec = createEventContext();
  ec->action = action;

  {
    // The IORegistry name is not needed.
    io_name_t class_name = {0};
    if (IOObjectGetClass(device, class_name) != kIOReturnSuccess) {
      return;
    }
    ec->type = std::string(class_name);
  }

  // Get the device details
  CFMutableDictionaryRef details;
  IORegistryEntryCreateCFProperties(
      device, &details, kCFAllocatorDefault, kNilOptions);
  if (ec->type == kIOUSBDeviceClassName_) {
    ec->path = getIOKitProperty(details, "USB Address") + ":";
    ec->path += getIOKitProperty(details, "PortNum");
    ec->model = getIOKitProperty(details, "USB Product Name");
    ec->model_id = getIOKitProperty(details, "idProduct");
    ec->vendor = getIOKitProperty(details, "USB Vendor Name");
    ec->vendor_id = getIOKitProperty(details, "idVendor");
    idToHex(ec->vendor_id);
    idToHex(ec->model_id);
    ec->serial = getIOKitProperty(details, "USB Serial Number");
    if (ec->serial.size() == 0) {
      ec->serial = getIOKitProperty(details, "iSerialNumber");
    }
    ec->version = "";
    ec->driver = getIOKitProperty(details, "IOUserClientClass");
  } else if (ec->type == kIOPCIDeviceClassName_) {
    auto compatible = getIOKitProperty(details, "compatible");
    auto properties = IOKitPCIProperties(compatible);
    ec->model_id = properties.model_id;
    ec->vendor_id = properties.vendor_id;
    ec->driver = properties.driver;
    if (ec->driver.empty()) {
      ec->driver = getIOKitProperty(details, "IOName");
    }

    ec->path = getIOKitProperty(details, "pcidebug");
    ec->version = getIOKitProperty(details, "revision-id");
    ec->model = getIOKitProperty(details, "model");
  } else {
    // Get the name as the model.
    io_name_t name = {0};
    IORegistryEntryGetName(device, name);
    if (name[0] != 0) {
      ec->model = std::string(name);
    }
  }

  CFRelease(details);
  fire(ec);
}
Ejemplo n.º 4
0
bool find_service(const char *target_name, io_connect_t *ptarget_port) {
  io_iterator_t iter;
  kern_return_t r =
    IOServiceGetMatchingServices(kIOMasterPortDefault,
				 IOServiceMatching("IOService"), &iter);

  if (r != KERN_SUCCESS) {
    fprintf(stderr, " [!] IOServiceGetMatchingServices() failed\n");
    return -1;
  }

  io_object_t service;
  while ((service = IOIteratorNext(iter)) != IO_OBJECT_NULL) {
    /* Get service name */
    io_name_t name;
    r = IORegistryEntryGetName(service, name);
    if (r != KERN_SUCCESS) {
      fprintf(stderr, " [!] IORegistryEntryGetName() failed\n");
      IOObjectRelease(service);
      continue;
    }

    io_string_t path;
    r = IORegistryEntryGetPath(service, "IOService", path);

    /* Try to open service */
    io_connect_t port = (io_connect_t) 0;
    r = IOServiceOpen(service, mach_task_self(), 0, &port);
    IOObjectRelease(service);
    if (r != kIOReturnSuccess) {
      continue;
    }

    if (strstr(name, target_name)) {
      printf(" [+] Found service %s\n", name);
      *ptarget_port = port;
      return true;
    }

    IOServiceClose(port);
  }

  return false;
}
Ejemplo n.º 5
0
void search_wifi_mac_callback(void** context, io_iterator_t iterator) {
    unsigned char macaddrBytes[6];
    io_iterator_t iterator2=0;
    io_object_t obj2=0;
    io_name_t name;
    CFDataRef t1=0;
    io_object_t next;
    
    while ((next = IOIteratorNext(iterator)) != 0)
    {
        if (!IORegistryEntryCreateIterator(next, "IOService", 3, &iterator2))
        {
            while((obj2 = IOIteratorNext(iterator2)) != 0)
            {
                if (!IORegistryEntryGetName(obj2,name))
                {
                    if (!strcmp(name, "sdio") || !strcmp(name, "wlan"))
                    {
                        if((t1 = IORegistryEntryCreateCFProperty(obj2, CFSTR("local-mac-address"), kCFAllocatorDefault, 0)) != 0)
                        {
                            CFDataGetBytes(t1, CFRangeMake(0,6), macaddrBytes);
                            *context = (void*) CFStringCreateWithFormat(kCFAllocatorDefault,
                                        NULL,
                                        CFSTR("%02x:%02x:%02x:%02x:%02x:%02x"),
                                        macaddrBytes[0],
                                        macaddrBytes[1],
                                        macaddrBytes[2],
                                        macaddrBytes[3],
                                        macaddrBytes[4],
                                        macaddrBytes[5]);
                            CFRelease(t1);
                        }  
                    }
                }

            }
            IOObjectRelease(iterator2);
        }
        IOObjectRelease(next);
        if (*context != NULL)
            break;
    }
}
static void DeviceAdded(void *refCon, io_iterator_t iter1)
{
    int oldMouseCount = g_MouseCount;
    io_service_t service;
    while ((service = IOIteratorNext(iter1)))
    {
        io_iterator_t iter2;
        kern_return_t kr = IORegistryEntryCreateIterator(service, kIOServicePlane, kIORegistryIterateRecursively, &iter2);
        if (KERN_SUCCESS != kr)
        {
            DEBUG_LOG("IORegistryEntryCreateIterator returned 0x%08x\n", kr);
            continue;
        }
        
        io_service_t temp;
        while ((temp = IOIteratorNext(iter2)))
        {
            io_name_t name;
            kr = IORegistryEntryGetName(temp, name);
            if (KERN_SUCCESS != kr)
                continue;
            if (0 == strcmp("IOHIDPointing", name) || 0 == strcmp("IOHIDPointingDevice", name))
            {
                NotificationData* pData = (NotificationData*)malloc(sizeof(*pData));
                if (pData == NULL)
                    continue;
                kr = IOServiceAddInterestNotification(g_NotifyPort, temp, kIOGeneralInterest, DeviceNotification, pData, &pData->notification);
                if (KERN_SUCCESS != kr)
                {
                    DEBUG_LOG("IOServiceAddInterestNotification returned 0x%08x\n", kr);
                    continue;
                }
                ++g_MouseCount;
                DEBUG_LOG("mouse count is now: %d\n", g_MouseCount);
            }
            IOObjectRelease(temp);
        }
        IOObjectRelease(iter2);
        IOObjectRelease(service);
    }
    if (oldMouseCount != g_MouseCount)
        SendMouseCount(g_MouseCount);
}
Ejemplo n.º 7
0
TorcUSBDevice TorcUSBPrivOSX::GetDevice(io_service_t Device)
{
    TorcUSBDevice usbdevice;

    if (Device)
    {
        io_name_t buffer;
        IOReturn ok = IORegistryEntryGetName(Device, buffer);

        QString name = kIOReturnSuccess == ok ?  QString(buffer) : "Unknown";

        IOCFPlugInInterface **plugin;
        qint32 score;

        ok = IOCreatePlugInInterfaceForService(Device, kIOUSBDeviceUserClientTypeID, kIOCFPlugInInterfaceID, &plugin, &score);
        if (kIOReturnSuccess == ok)
        {
            IOUSBDeviceInterface **interface;

            ok = (*plugin)->QueryInterface(plugin, CFUUIDGetUUIDBytes(kIOUSBDeviceInterfaceID), (void**)&interface);
            if (kIOReturnSuccess == ok)
            {
                quint16  vendor;
                quint16  product;
                quint32  location;
                quint8   classtype;

                IOReturn vendorok    = (*interface)->GetDeviceVendor(interface, &vendor);
                IOReturn productok   = (*interface)->GetDeviceProduct(interface, &product);
                IOReturn locationok  = (*interface)->GetLocationID(interface, &location);
                IOReturn classtypeok = (*interface)->GetDeviceClass(interface, &classtype);

                if ((classtypeok == kIOReturnSuccess) && !TorcUSBDevice::IgnoreClass(ToTorcClass(classtype)))
                {
                    TorcUSBDevice::Classes torcclass = ToTorcClass(classtype);

                    io_service_t usbinterface;
                    io_iterator_t iterator;
                    IOUSBFindInterfaceRequest request;
                    request.bInterfaceClass    = kIOUSBFindInterfaceDontCare;
                    request.bInterfaceSubClass = kIOUSBFindInterfaceDontCare;
                    request.bInterfaceProtocol = kIOUSBFindInterfaceDontCare;
                    request.bAlternateSetting  = kIOUSBFindInterfaceDontCare;

                    ok = (*interface)->CreateInterfaceIterator(interface, &request, &iterator);

                    while ((ok == kIOReturnSuccess) && (usbinterface = IOIteratorNext(iterator)))
                    {
                        IOCFPlugInInterface **interfaceplugin;
                        if (kIOReturnSuccess == IOCreatePlugInInterfaceForService(usbinterface, kIOUSBInterfaceUserClientTypeID,
                                                                                  kIOCFPlugInInterfaceID, &interfaceplugin, &score))
                        {
                            IOUSBInterfaceInterface** interfaceinterface;
                            if (kIOReturnSuccess == (*interfaceplugin)->QueryInterface(interfaceplugin, CFUUIDGetUUIDBytes(kIOUSBInterfaceInterfaceID),
                                                                        (void**)&interfaceinterface))
                            {
                                QString path = locationok == kIOReturnSuccess ? QString::number(location) : "Error";

                                quint8 interfaceclass;
                                IOReturn result = (*interfaceinterface)->GetInterfaceClass(interfaceinterface, &interfaceclass);

                                if (result == kIOReturnSuccess)
                                {
                                    io_registry_entry_t parent;
                                    kern_return_t kernresult;
                                    kernresult = IORegistryEntryGetParentEntry(usbinterface, kIOServicePlane, &parent);
                                    if (kernresult == KERN_SUCCESS)
                                    {
                                        CFStringRef pathstring = (CFStringRef)IORegistryEntrySearchCFProperty(parent,
                                                kIOServicePlane, CFSTR(kIOCalloutDeviceKey), kCFAllocatorDefault, kIORegistryIterateRecursively);
                                        if (pathstring)
                                            path = CFStringReftoQString(pathstring);
                                        IOObjectRelease(parent);
                                    }
                                }

                                usbdevice = TorcUSBDevice(path, vendorok == kIOReturnSuccess ? vendor : 0,
                                                          productok == kIOReturnSuccess ? product : 0, torcclass);
                                usbdevice.m_product = name;
                            }

                            IODestroyPlugInInterface(interfaceplugin);
                        }

                        IOObjectRelease(usbinterface);
                    }
                }
            }

            IODestroyPlugInInterface(plugin);
        }
    }

    return usbdevice;
}
void traverse(unsigned int options,
	      io_name_t plane, io_iterator_t services,
	      io_registry_entry_t serviceUpNext,
	      int depth, UInt64 stackOfBits)
{
    io_registry_entry_t service;                                ///ok
    Boolean		doProps;

    // We loop for every service in the list of services provided.

    while ( (service = serviceUpNext) )
    {
        io_iterator_t		children;
        Boolean			hasChildren;
        io_name_t    		name;
        kern_return_t		status;
	io_registry_entry_t	child;
	int			busy;

        // Obtain the next service entry, if any.

        serviceUpNext = IOIteratorNext(services);

        // Obtain the current service entry's children, if any.

        status = IORegistryEntryGetChildIterator(service,
                                                 plane,
                                                 &children);
        assert(status == KERN_SUCCESS);

        child = IOIteratorNext(children); ///ok
        hasChildren = child ? true : false;

        // Save has-more-siblings state into stackOfBits for this depth.

        if (serviceUpNext)
            stackOfBits |=  (1 << depth);
        else
            stackOfBits &= ~(1 << depth);

        // Save has-children state into stackOfBits for this depth.

        if (hasChildren)
            stackOfBits |=  (2 << depth);
        else
            stackOfBits &= ~(2 << depth);

        indent(true, depth, stackOfBits);

        // Print out the name of the service.

        status = IORegistryEntryGetName(service, name);
        assert(status == KERN_SUCCESS);

        printf("%s", name);

	if (strcmp("Root", name))
            doProps = (options & kDoPropsOption) != 0;
	else
            doProps = (options & kDoRootOption) != 0;

        // Print out the class of the service.

        status = IOObjectGetClass(service, name);
        assert(status == KERN_SUCCESS);
        printf("  <class %s", name);

	status = IOServiceGetBusyState(service, &busy);
	if(status == KERN_SUCCESS)
            printf(", busy %d", busy);

        // Print out the retain count of the service.

        printf(", retain count %d>\n", IOObjectGetRetainCount(service));

        // Print out the properties of the service.

	if (doProps)
            properties(service, depth, stackOfBits);

        // Recurse down.

	traverse(options, plane, children, child, depth + 1, stackOfBits);

        // Release resources.

        IOObjectRelease(children); children = 0;
        IOObjectRelease(service);  service  = 0;
    }
}
Ejemplo n.º 9
0
void notifyTest( char * arg )
{
    kern_return_t	kr;
    io_iterator_t	iter1, iter2, iter3;
    mach_port_t		port;
    io_service_t	obj;
    io_name_t		name;
    const char *	type;
    IOServiceInterestContent * content;
    vm_size_t		size;
    unsigned long int  	notifyType;
    unsigned long int  	ref;
    struct {
        mach_msg_header_t	msgHdr;
        OSNotificationHeader	notifyHeader;
        IOServiceInterestContent	content;
        mach_msg_trailer_t	trailer;
    } msg;

    assert( KERN_SUCCESS == (
    kr = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &port)
    ));

    type = kIOMatchedNotification;// or kIOPublishNotification;
    assert( KERN_SUCCESS == (
    kr = IOServiceAddNotification( masterPort, type,
                                    IOServiceMatching( arg ),
//                                    IOBSDNameMatching( masterPort, 0, arg ),
                                    port, (unsigned int) type, &iter2 )
    ));
    printf("IOServiceAddNotification: %s: ", type );
    // dumping the iterator gives us the current list
    // and arms the notification for changes
    dumpIter( iter2, port );
    printf("\n");

    type = kIOTerminatedNotification;
    assert( KERN_SUCCESS == (
    kr = IOServiceAddNotification( masterPort, type,
                                    IOServiceMatching( arg ),
                                    port, (unsigned int) type, &iter1 )
    ));
    printf("IOServiceAddNotification: %s: ", type );
    dumpIter( iter1, port );
    printf("\n");

    type = kIOBusyInterest;
    obj = IORegistryEntryFromPath( masterPort, kIOServicePlane ":/");
    assert( obj );
    assert( KERN_SUCCESS == (
    kr = IOServiceAddInterestNotificationMsg( obj, type,
                                           port, (unsigned int) obj, &iter3)
    ));

    printf("ports: iter1=%d, iter2=%d, rcv=%d\n", iter1, iter2, port);

    do {
	printf("waiting...\n");
        assert( KERN_SUCCESS == (
        kr = mach_msg(&msg.msgHdr, MACH_RCV_MSG,
                    0, sizeof(msg), port, 0, MACH_PORT_NULL)
        ));

        assert( KERN_SUCCESS == (
	kr = OSGetNotificationFromMessage( &msg.msgHdr, 0, &notifyType, &ref,
			(void **) &content, &size )
        ));

	// we passed a string for the refcon
        printf("got notification, type=%d, local=%d, remote=%d\n", notifyType,
		msg.msgHdr.msgh_local_port, msg.msgHdr.msgh_remote_port );
        if( notifyType == kIOServiceMessageNotificationType) {
            obj = ref;
            if( KERN_SUCCESS == (
            kr = IORegistryEntryGetName( obj, name )
                                 )) printf(name); else printf("???");
            printf(": messageType %08lx, arg %08lx\n",
                   content->messageType, content->messageArgument[0]);
        } else {
            printf("%s: ", ref );
            // remote port is the notification (an iterator_t) that fired
            dumpIter( msg.msgHdr.msgh_remote_port, port );
        }

    } while( TRUE );

    IOObjectRelease( iter1 );
    IOObjectRelease( iter2 );
    IOObjectRelease( iter3 );
}
Ejemplo n.º 10
0
static void
dumpDevice(io_connect_t connect, uint32_t segment,
                                uint32_t bus, uint32_t device, uint32_t fn,
                                uint32_t * maxBus, uint32_t * maxFn)
{
    io_registry_entry_t service;
    kern_return_t       status;
    io_name_t           name;
    uint64_t     		entryID;
    uint32_t off;
    uint32_t vendProd;
    uint32_t vend;
    uint32_t prod;
    uint32_t headerType;
    uint32_t priBusNum;
    uint32_t secBusNum;
    uint32_t subBusNum;
    uint32_t data[256/sizeof(uint32_t)];
    uint8_t *bytes = (uint8_t *)&data[0];

    for(off = 0; off < 256; off += 4)
        data[off >> 2] = configRead32(connect, segment, bus, device, fn, off);

    vendProd = data[0];
    vend = vendProd & 0xffff;
    prod = vendProd >> 16;
    printf("[%d, %d, %d] 0x%04x, 0x%04x - ", bus, device, fn, vend, prod);

    service = lookService(segment, bus, device, fn);
    if (service)
    {
        status = IORegistryEntryGetName(service, name);
        assert(kIOReturnSuccess == status);
        status = IORegistryEntryGetRegistryEntryID(service, &entryID);
        assert(kIOReturnSuccess == status);
        printf("\"%s\", 0x%qx - ", name, entryID);
        IOObjectRelease(service);
    }

    headerType = bytes[kIOPCIConfigHeaderType];
    if (maxFn && (0x80 & headerType))
        *maxFn = 7;
    headerType &= 0x7f;
    if (!headerType)
    {
        // device dump
        printf("class: 0x%x, 0x%x, 0x%x\n", 
                bytes[kIOPCIConfigRevisionID + 3],
                bytes[kIOPCIConfigRevisionID + 2],
                bytes[kIOPCIConfigRevisionID + 1]);
    }
    else
    {
        priBusNum = bytes[kPCI2PCIPrimaryBus];
        secBusNum = bytes[kPCI2PCISecondaryBus];
        subBusNum = bytes[kPCI2PCISubordinateBus];
        printf("bridge: [%d, %d, %d]\n", priBusNum, secBusNum, subBusNum);
        if (maxBus && (subBusNum > *maxBus))
            *maxBus = subBusNum;
    }

    dump(bytes, sizeof(data));
    printf("\n");
}
Ejemplo n.º 11
0
/*
 * Finds PC Card devices currently registered in the system that match any of
 * the drivers detected in the driver bundle vector.
 */
static int
HPDriversMatchPCCardDevices(HPDriver * driverBundle,
	HPDeviceList * readerList)
{
	CFDictionaryRef pccMatch = IOServiceMatching("IOPCCard16Device");

	if (pccMatch == NULL)
	{
		Log1(PCSC_LOG_ERROR,
			"error getting PCCard match from IOServiceMatching()");
		return 1;
	}

	io_iterator_t pccIter;
	kern_return_t kret =
		IOServiceGetMatchingServices(kIOMasterPortDefault, pccMatch,
		&pccIter);
	if (kret != 0)
	{
		Log1(PCSC_LOG_ERROR,
			"error getting iterator from IOServiceGetMatchingServices()");
		return 1;
	}

	IOIteratorReset(pccIter);
	io_object_t pccDevice = 0;

	while ((pccDevice = IOIteratorNext(pccIter)))
	{
		char namebuf[1024];

		kret = IORegistryEntryGetName(pccDevice, namebuf);
		if (kret != 0)
		{
			Log1(PCSC_LOG_ERROR, "error getting plugin interface from IOCreatePlugInInterfaceForService()");
			return 1;
		}
		UInt32 vendorId = 0;
		UInt32 productId = 0;
		UInt32 pccAddress = 0;
		CFTypeRef valueRef =
			IORegistryEntryCreateCFProperty(pccDevice, CFSTR("VendorID"),
			kCFAllocatorDefault, 0);

		if (!valueRef)
		{
			Log1(PCSC_LOG_ERROR, "error getting vendor");
		}
		else
		{
			CFNumberGetValue((CFNumberRef) valueRef, kCFNumberSInt32Type,
				&vendorId);
		}
		valueRef =
			IORegistryEntryCreateCFProperty(pccDevice, CFSTR("DeviceID"),
			kCFAllocatorDefault, 0);
		if (!valueRef)
		{
			Log1(PCSC_LOG_ERROR, "error getting device");
		}
		else
		{
			CFNumberGetValue((CFNumberRef) valueRef, kCFNumberSInt32Type,
				&productId);
		}
		valueRef =
			IORegistryEntryCreateCFProperty(pccDevice, CFSTR("SocketNumber"),
			kCFAllocatorDefault, 0);
		if (!valueRef)
		{
			Log1(PCSC_LOG_ERROR, "error getting PC Card socket");
		}
		else
		{
			CFNumberGetValue((CFNumberRef) valueRef, kCFNumberSInt32Type,
				&pccAddress);
		}
		HPDriver *driver = driverBundle;

		for (; driver->m_vendorId; ++driver)
		{
			if ((driver->m_vendorId == vendorId)
				&& (driver->m_productId == productId))
			{
				*readerList =
					HPDeviceListInsert(*readerList, driver, pccAddress);
			}
		}
	}
	IOObjectRelease(pccIter);
	return 0;
}
Ejemplo n.º 12
0
/*
 * Finds USB devices currently registered in the system that match any of
 * the drivers detected in the driver bundle vector.
 */
static int
HPDriversMatchUSBDevices(HPDriverVector driverBundle,
	HPDeviceList * readerList)
{
	CFDictionaryRef usbMatch = IOServiceMatching("IOUSBDevice");

	if (0 == usbMatch)
	{
		Log1(PCSC_LOG_ERROR,
			"error getting USB match from IOServiceMatching()");
		return 1;
	}

	io_iterator_t usbIter;
	kern_return_t kret = IOServiceGetMatchingServices(kIOMasterPortDefault,
		usbMatch, &usbIter);

	if (kret != 0)
	{
		Log1(PCSC_LOG_ERROR,
			"error getting iterator from IOServiceGetMatchingServices()");
		return 1;
	}

	IOIteratorReset(usbIter);
	io_object_t usbDevice = 0;

	while ((usbDevice = IOIteratorNext(usbIter)))
	{
		char namebuf[1024];

		kret = IORegistryEntryGetName(usbDevice, namebuf);
		if (kret != 0)
		{
			Log1(PCSC_LOG_ERROR,
				"error getting device name from IORegistryEntryGetName()");
			return 1;
		}

		IOCFPlugInInterface **iodev;
		SInt32 score;

		kret = IOCreatePlugInInterfaceForService(usbDevice,
			kIOUSBDeviceUserClientTypeID,
			kIOCFPlugInInterfaceID, &iodev, &score);
		if (kret != 0)
		{
			Log1(PCSC_LOG_ERROR, "error getting plugin interface from IOCreatePlugInInterfaceForService()");
			return 1;
		}
		IOObjectRelease(usbDevice);

		IOUSBDeviceInterface **usbdev;
		HRESULT hres = (*iodev)->QueryInterface(iodev,
			CFUUIDGetUUIDBytes(kIOUSBDeviceInterfaceID),
			(LPVOID *) & usbdev);

		(*iodev)->Release(iodev);
		if (hres)
		{
			Log1(PCSC_LOG_ERROR,
				"error querying interface in QueryInterface()");
			return 1;
		}

		UInt16 vendorId = 0;
		UInt16 productId = 0;
		UInt32 usbAddress = 0;

		kret = (*usbdev)->GetDeviceVendor(usbdev, &vendorId);
		kret = (*usbdev)->GetDeviceProduct(usbdev, &productId);
		kret = (*usbdev)->GetLocationID(usbdev, &usbAddress);
		(*usbdev)->Release(usbdev);

#ifdef DEBUG_HOTPLUG
		Log4(PCSC_LOG_DEBUG, "Found USB device 0x%04X:0x%04X at 0x%X",
			vendorId, productId, usbAddress);
#endif
		HPDriver *driver;
		for (driver = driverBundle; driver->m_vendorId; ++driver)
		{
			if ((driver->m_vendorId == vendorId)
				&& (driver->m_productId == productId))
			{
#ifdef DEBUG_HOTPLUG
				Log4(PCSC_LOG_DEBUG, "Adding USB device %04X:%04X at 0x%X",
					vendorId, productId, usbAddress);
#endif
				*readerList =
					HPDeviceListInsert(*readerList, driver, usbAddress);
			}
		}
	}

	IOObjectRelease(usbIter);
	return 0;
}
Ejemplo n.º 13
0
//================================================================================================
//
//  DeviceAdded
//
//  This routine is the callback for our IOServiceAddMatchingNotification.  When we get called
//  we will look at all the devices that were added and we will:
//
//  1.  Create some private data to relate to each device (in this case we use the service's name
//      and the location ID of the device
//  2.  Submit an IOServiceAddInterestNotification of type kIOGeneralInterest for this device,
//      using the refCon field to store a pointer to our private data.  When we get called with
//      this interest notification, we can grab the refCon and access our private data.
//
//================================================================================================
void DeviceAdded(void *refCon, io_iterator_t iterator)
{
    kern_return_t       kr;
    io_service_t        usbDevice;
    IOCFPlugInInterface **plugInInterface = NULL;
    SInt32              score;
    HRESULT             res;
    
    while ((usbDevice = IOIteratorNext(iterator))) {
        io_name_t       deviceName;
        CFStringRef     deviceNameAsCFString;   
        MyPrivateData   *privateDataRef = NULL;
        UInt32          locationID;
        
        printf("Device added.\n");
        
        //
        // Launch our application
        system("open /Users/seanwhitsell/development/Pressure/Pressure/build/Debug/Pressure.app");
        
        // Add some app-specific information about this device.
        // Create a buffer to hold the data.
        privateDataRef = malloc(sizeof(MyPrivateData));
        bzero(privateDataRef, sizeof(MyPrivateData));
        
        // Get the USB device's name.
        kr = IORegistryEntryGetName(usbDevice, deviceName);
        if (KERN_SUCCESS != kr) {
            deviceName[0] = '\0';
        }
        
        deviceNameAsCFString = CFStringCreateWithCString(kCFAllocatorDefault, deviceName, 
                                                         kCFStringEncodingASCII);
        
        // Dump our data to stderr just to see what it looks like.
        fprintf(stderr, "deviceName: ");
        CFShow(deviceNameAsCFString);
        
        // Save the device's name to our private data.        
        privateDataRef->deviceName = deviceNameAsCFString;
        
        // Now, get the locationID of this device. In order to do this, we need to create an IOUSBDeviceInterface 
        // for our device. This will create the necessary connections between our userland application and the 
        // kernel object for the USB Device.
        kr = IOCreatePlugInInterfaceForService(usbDevice, kIOUSBDeviceUserClientTypeID, kIOCFPlugInInterfaceID,
                                               &plugInInterface, &score);
        
        if ((kIOReturnSuccess != kr) || !plugInInterface) {
            fprintf(stderr, "IOCreatePlugInInterfaceForService returned 0x%08x.\n", kr);
            continue;
        }
        
        // Use the plugin interface to retrieve the device interface.
        res = (*plugInInterface)->QueryInterface(plugInInterface, CFUUIDGetUUIDBytes(kIOUSBDeviceInterfaceID),
                                                 (LPVOID*) &privateDataRef->deviceInterface);
        
        // Now done with the plugin interface.
        (*plugInInterface)->Release(plugInInterface);
        
        if (res || privateDataRef->deviceInterface == NULL) {
            fprintf(stderr, "QueryInterface returned %d.\n", (int) res);
            continue;
        }
        
        // Now that we have the IOUSBDeviceInterface, we can call the routines in IOUSBLib.h.
        // In this case, fetch the locationID. The locationID uniquely identifies the device
        // and will remain the same, even across reboots, so long as the bus topology doesn't change.
        
        kr = (*privateDataRef->deviceInterface)->GetLocationID(privateDataRef->deviceInterface, &locationID);
        if (KERN_SUCCESS != kr) {
            fprintf(stderr, "GetLocationID returned 0x%08x.\n", kr);
            continue;
        }
        else {
            fprintf(stderr, "Location ID: 0x%x\n\n", locationID);
        }
        
        privateDataRef->locationID = locationID;
        
        // Register for an interest notification of this device being removed. Use a reference to our
        // private data as the refCon which will be passed to the notification callback.
        kr = IOServiceAddInterestNotification(gNotifyPort,                      // notifyPort
                                              usbDevice,                        // service
                                              kIOGeneralInterest,               // interestType
                                              DeviceNotification,               // callback
                                              privateDataRef,                   // refCon
                                              &(privateDataRef->notification)   // notification
                                              );
        
        if (KERN_SUCCESS != kr) {
            printf("IOServiceAddInterestNotification returned 0x%08x.\n", kr);
        }
        
        // Done with this USB device; release the reference added by IOIteratorNext
        kr = IOObjectRelease(usbDevice);
    }
}
Ejemplo n.º 14
0
//================================================================================================
//
//  DeviceAdded
//
//  This routine is the callback for our IOServiceAddMatchingNotification.  When we get called
//  we will look at all the devices that were added and we will:
//
//  1.  Create some private data to relate to each device (in this case we use the service's name
//      and the location ID of the device
//  2.  Submit an IOServiceAddInterestNotification of type kIOGeneralInterest for this device,
//      using the refCon field to store a pointer to our private data.  When we get called with
//      this interest notification, we can grab the refCon and access our private data.
//
//================================================================================================
static void DeviceAdded(void *refCon, io_iterator_t iterator) {
	kern_return_t kr;
	io_service_t usbDevice;
	IOCFPlugInInterface **plugInInterface = NULL;
	SInt32 score;
	HRESULT res;

	while((usbDevice = IOIteratorNext(iterator))) {
		io_name_t deviceName;
		CFStringRef deviceNameAsCFString;
		UInt32 locationID;
		UInt16 vendorId;
		UInt16 productId;
		UInt16 addr;

		DeviceItem_t* deviceItem = new DeviceItem_t();

		// Get the USB device's name.
		kr = IORegistryEntryGetName(usbDevice, deviceName);
		if(KERN_SUCCESS != kr) {
			deviceName[0] = '\0';
		}

		deviceNameAsCFString = CFStringCreateWithCString(kCFAllocatorDefault, deviceName, kCFStringEncodingASCII);


		if(deviceNameAsCFString) {
			Boolean result;
			char    deviceName[MAXPATHLEN];

			// Convert from a CFString to a C (NUL-terminated)
			result = CFStringGetCString(deviceNameAsCFString,
										deviceName,
										sizeof(deviceName),
										kCFStringEncodingUTF8);

			if(result) {
				deviceItem->deviceParams.deviceName = deviceName;
			}

			CFRelease(deviceNameAsCFString);
		}

		CFStringRef manufacturerAsCFString = (CFStringRef)IORegistryEntrySearchCFProperty(
				usbDevice,
				kIOServicePlane,
				CFSTR(kUSBVendorString),
				kCFAllocatorDefault,
				kIORegistryIterateRecursively
			);

		if(manufacturerAsCFString) {
			Boolean result;
			char    manufacturer[MAXPATHLEN];

			// Convert from a CFString to a C (NUL-terminated)
			result = CFStringGetCString(
					manufacturerAsCFString,
					manufacturer,
					sizeof(manufacturer),
					kCFStringEncodingUTF8
				);

			if(result) {
				deviceItem->deviceParams.manufacturer = manufacturer;
			}

			CFRelease(manufacturerAsCFString);
		}

		CFStringRef serialNumberAsCFString = (CFStringRef) IORegistryEntrySearchCFProperty(
				usbDevice,
				kIOServicePlane,
				CFSTR(kUSBSerialNumberString),
				kCFAllocatorDefault,
				kIORegistryIterateRecursively
			);

		if(serialNumberAsCFString) {
			Boolean result;
			char    serialNumber[MAXPATHLEN];

			// Convert from a CFString to a C (NUL-terminated)
			result = CFStringGetCString(
					serialNumberAsCFString,
					serialNumber,
					sizeof(serialNumber),
					kCFStringEncodingUTF8
				);

			if(result) {
				deviceItem->deviceParams.serialNumber = serialNumber;
			}

			CFRelease(serialNumberAsCFString);
		}


		// Now, get the locationID of this device. In order to do this, we need to create an IOUSBDeviceInterface
		// for our device. This will create the necessary connections between our userland application and the
		// kernel object for the USB Device.
		kr = IOCreatePlugInInterfaceForService(usbDevice, kIOUSBDeviceUserClientTypeID, kIOCFPlugInInterfaceID, &plugInInterface, &score);

		if((kIOReturnSuccess != kr) || !plugInInterface) {
			fprintf(stderr, "IOCreatePlugInInterfaceForService returned 0x%08x.\n", kr);
			continue;
		}

		stDeviceListItem *deviceListItem = new stDeviceListItem();

		// Use the plugin interface to retrieve the device interface.
		res = (*plugInInterface)->QueryInterface(plugInInterface, CFUUIDGetUUIDBytes(kIOUSBDeviceInterfaceID), (LPVOID*) &deviceListItem->deviceInterface);

		// Now done with the plugin interface.
		(*plugInInterface)->Release(plugInInterface);

		if(res || deviceListItem->deviceInterface == NULL) {
			fprintf(stderr, "QueryInterface returned %d.\n", (int) res);
			continue;
		}

		// Now that we have the IOUSBDeviceInterface, we can call the routines in IOUSBLib.h.
		// In this case, fetch the locationID. The locationID uniquely identifies the device
		// and will remain the same, even across reboots, so long as the bus topology doesn't change.

		kr = (*deviceListItem->deviceInterface)->GetLocationID(deviceListItem->deviceInterface, &locationID);
		if(KERN_SUCCESS != kr) {
			fprintf(stderr, "GetLocationID returned 0x%08x.\n", kr);
			continue;
		}
		std::stringstream sstream;
		sstream << std::hex << locationID;
		deviceItem->deviceParams.locationId = sstream.str();

		kr = (*deviceListItem->deviceInterface)->GetDeviceAddress(deviceListItem->deviceInterface, &addr);
		if(KERN_SUCCESS != kr) {
			fprintf(stderr, "GetDeviceAddress returned 0x%08x.\n", kr);
			continue;
		}
		deviceItem->deviceParams.deviceAddress = addr;


		kr = (*deviceListItem->deviceInterface)->GetDeviceVendor(deviceListItem->deviceInterface, &vendorId);
		if(KERN_SUCCESS != kr) {
			fprintf(stderr, "GetDeviceVendor returned 0x%08x.\n", kr);
			continue;
		}
		deviceItem->deviceParams.vendorId = vendorId;

		kr = (*deviceListItem->deviceInterface)->GetDeviceProduct(deviceListItem->deviceInterface, &productId);
		if(KERN_SUCCESS != kr) {
			fprintf(stderr, "GetDeviceProduct returned 0x%08x.\n", kr);
			continue;
		}
		deviceItem->deviceParams.productId = productId;


		// Extract path name as unique key
		io_string_t pathName;
		IORegistryEntryGetPath(usbDevice, kIOServicePlane, pathName);
		deviceNameAsCFString = CFStringCreateWithCString(kCFAllocatorDefault, pathName, kCFStringEncodingASCII);
		char cPathName[MAXPATHLEN];

		if(deviceNameAsCFString) {
			Boolean result;

			// Convert from a CFString to a C (NUL-terminated)
			result = CFStringGetCString(
					deviceNameAsCFString,
					cPathName,
					sizeof(cPathName),
					kCFStringEncodingUTF8
				);


			CFRelease(deviceNameAsCFString);
		}

		AddItemToList(cPathName, deviceItem);
		deviceListItem->deviceItem = deviceItem;

		if(initialDeviceImport == false) {
			WaitForDeviceHandled();
			currentItem = &deviceItem->deviceParams;
			isAdded = true;
			uv_async_send(&async_handler);
		}

		// Register for an interest notification of this device being removed. Use a reference to our
		// private data as the refCon which will be passed to the notification callback.
		kr = IOServiceAddInterestNotification(
				gNotifyPort, // notifyPort
				usbDevice, // service
				kIOGeneralInterest, // interestType
				DeviceRemoved, // callback
				deviceListItem, // refCon
				&(deviceListItem->notification) // notification
			);

		if(KERN_SUCCESS != kr) {
			printf("IOServiceAddInterestNotification returned 0x%08x.\n", kr);
		}

		// Done with this USB device; release the reference added by IOIteratorNext
		kr = IOObjectRelease(usbDevice);
	}
}
Ejemplo n.º 15
0
void genIOKitDevice(const io_service_t& device,
                    const io_service_t& parent,
                    const io_name_t plane,
                    int depth,
                    QueryData& results) {
  Row r;
  io_name_t name, device_class;
  auto kr = IORegistryEntryGetName(device, name);
  if (kr == KERN_SUCCESS) {
    r["name"] = std::string(name);
  }

  // Get the device class.
  kr = IOObjectGetClass(device, device_class);
  if (kr == KERN_SUCCESS) {
    r["class"] = std::string(device_class);
  }

  // The entry into the registry is the ID, and is used for children as parent.
  uint64_t device_id, parent_id;
  kr = IORegistryEntryGetRegistryEntryID(device, &device_id);
  if (kr == KERN_SUCCESS) {
    r["id"] = BIGINT(device_id);
  } else {
    r["id"] = "-1";
  }

  kr = IORegistryEntryGetRegistryEntryID(parent, &parent_id);
  if (kr == KERN_SUCCESS) {
    r["parent"] = BIGINT(parent_id);
  } else {
    r["parent"] = "-1";
  }

  r["depth"] = INTEGER(depth);

  if (IORegistryEntryInPlane(device, kIODeviceTreePlane)) {
    io_string_t device_path;
    kr = IORegistryEntryGetPath(device, kIODeviceTreePlane, device_path);
    if (kr == KERN_SUCCESS) {
      // Remove the "IODeviceTree:" from the device tree path.
      r["device_path"] = std::string(device_path).substr(13);
    }
  }

  // Fill in service bits and busy/latency time.
  if (IOObjectConformsTo(device, "IOService")) {
    r["service"] = "1";
  } else {
    r["service"] = "0";
  }

  uint32_t busy_state;
  kr = IOServiceGetBusyState(device, &busy_state);
  if (kr == KERN_SUCCESS) {
    r["busy_state"] = INTEGER(busy_state);
  } else {
    r["busy_state"] = "0";
  }

  auto retain_count = IOObjectGetKernelRetainCount(device);
  r["retain_count"] = INTEGER(retain_count);

  results.push_back(r);
}
Ejemplo n.º 16
0
void DeviceAdded(void *refCon, io_iterator_t iterator)
{
    kern_return_t		kr;
    io_service_t		usbDevice;
    IOCFPlugInInterface 	**plugInInterface=NULL;
    SInt32 			score;
    HRESULT 			res;

    while ( (usbDevice = IOIteratorNext(iterator)) )
    {
        io_name_t		deviceName;
        CFStringRef		deviceNameAsCFString;
        MyPrivateData		*privateDataRef = NULL;
        UInt32			locationID;

        printf("Device 0x%08x added.\n", usbDevice);

        // Make activity and turn screen on
        printf("Wake up on Yubikey insertion.\n");
        IOPMAssertionID assertionID;
        IOPMAssertionDeclareUserActivity(CFSTR(""), kIOPMUserActiveLocal, &assertionID);

        // Add some app-specific information about this device.
        // Create a buffer to hold the data.

        privateDataRef = malloc(sizeof(MyPrivateData));
        bzero( privateDataRef, sizeof(MyPrivateData));

        // In this sample we'll just use the service's name.
        //
        kr = IORegistryEntryGetName(usbDevice, deviceName);
        if (KERN_SUCCESS != kr)
        {
            deviceName[0] = '\0';
        }

        deviceNameAsCFString = CFStringCreateWithCString(kCFAllocatorDefault, deviceName, kCFStringEncodingASCII);

        // Dump our data to stdout just to see what it looks like.
        //
        CFShow(deviceNameAsCFString);

        privateDataRef->deviceName = deviceNameAsCFString;

        // Now, get the locationID of this device.  In order to do this, we need to create an IOUSBDeviceInterface for
        // our device.  This will create the necessary connections between our user land application and the kernel object
        // for the USB Device.
        //
        kr = IOCreatePlugInInterfaceForService(usbDevice, kIOUSBDeviceUserClientTypeID, kIOCFPlugInInterfaceID, &plugInInterface, &score);

        if ((kIOReturnSuccess != kr) || !plugInInterface)
        {
            printf("unable to create a plugin (%08x)\n", kr);
            continue;
        }

        // I have the device plugin, I need the device interface
        //
        res = (*plugInInterface)->QueryInterface(plugInInterface, CFUUIDGetUUIDBytes(kIOUSBDeviceInterfaceID), (LPVOID)&privateDataRef->deviceInterface);
        (*plugInInterface)->Release(plugInInterface);			// done with this
        if (res || !privateDataRef->deviceInterface)
        {
            printf("couldn't create a device interface (%08x)\n", (int) res);
            continue;
        }

        // Now that we have the IOUSBDeviceInterface, we can call the routines in IOUSBLib.h
        // In this case, we just want the locationID.
        //
        kr = (*privateDataRef->deviceInterface)->GetLocationID(privateDataRef->deviceInterface, &locationID);
        if (KERN_SUCCESS != kr)
        {
            printf("GetLocationID returned %08x\n", kr);
            continue;
        }
        else
        {
            printf("Location ID: 0x%lx\n", (unsigned long)locationID);

        }

        privateDataRef->locationID = locationID;

        // Register for an interest notification for this device. Pass the reference to our
        // private data as the refCon for the notification.
        //
        kr = IOServiceAddInterestNotification(	gNotifyPort,			// notifyPort
                                                usbDevice,			// service
                                                kIOGeneralInterest,		// interestType
                                                DeviceNotification,		// callback
                                                privateDataRef,			// refCon
                                                &(privateDataRef->notification)	// notification
                                             );

        if (KERN_SUCCESS != kr)
        {
            printf("IOServiceAddInterestNotification returned 0x%08x\n", kr);
        }

        // Done with this io_service_t
        //
        kr = IOObjectRelease(usbDevice);

        free(privateDataRef);
    }
}
Ejemplo n.º 17
-1
void genIOMediaDevice(const io_service_t& device,
                      std::vector<std::string>& whole_devices,
                      QueryData& results) {
  Row r;

  // Get the device properties
  CFMutableDictionaryRef properties;
  IORegistryEntryCreateCFProperties(
      device, &properties, kCFAllocatorDefault, kNilOptions);

  r["uuid"] = getIOKitProperty(properties, "UUID");
  r["name"] = "/dev/" + getIOKitProperty(properties, "BSD Name");
  r["size"] = getIOKitProperty(properties, "Size");

  auto type = getIOKitProperty(properties, "Whole");
  if (type == "1") {
    // The "Whole" property applies to the entire disk entry, not partitions.
    whole_devices.push_back(r["name"]);
  } else {
    // Otherwise search the list of whole disks to find the node parent.
    for (const auto& parent : whole_devices) {
      if (r.at("name").find(parent) == 0) {
        r["parent"] = parent;
      }
    }
  }

  // This is the IOKit name, which is the device's label.
  io_name_t name;
  auto kr = IORegistryEntryGetName(device, name);
  if (kr == KERN_SUCCESS && (char*)name != nullptr) {
    r["label"] = std::string(name);
  }

  // Remaining details come from the Disk Arbitration service.
  DASessionRef session = DASessionCreate(kCFAllocatorDefault);
  CFDictionaryRef details;
  if (session != nullptr) {
    auto disk = DADiskCreateFromIOMedia(kCFAllocatorDefault, session, device);
    if (disk != nullptr) {
      details = DADiskCopyDescription(disk);
      if (details != nullptr) {
        r["vendor"] =
            getIOKitProperty((CFMutableDictionaryRef)details, "DADeviceVendor");
        r["model"] =
            getIOKitProperty((CFMutableDictionaryRef)details, "DADeviceModel");
        r["type"] = getIOKitProperty((CFMutableDictionaryRef)details,
                                     "DADeviceProtocol");
        CFRelease(details);
      }
      CFRelease(disk);
    }
    CFRelease(session);
  }

  results.push_back(r);
  CFRelease(properties);
}