static int probe_sms(int kernFunc, char *servMatch, int dataType, void *data) { kern_return_t result; mach_port_t masterPort; io_iterator_t iterator; io_object_t aDevice; io_connect_t dataPort; IOItemCount structureInputSize; IOByteCount structureOutputSize; union motion_data inputStructure; union motion_data *outputStructure; outputStructure = (union motion_data *)data; result = IOMasterPort(MACH_PORT_NULL, &masterPort); CFMutableDictionaryRef matchingDictionary = IOServiceMatching(servMatch); result = IOServiceGetMatchingServices(masterPort, matchingDictionary, &iterator); if (result != KERN_SUCCESS) { //fputs("IOServiceGetMatchingServices returned error.\n", stderr); return 0; } aDevice = IOIteratorNext(iterator); IOObjectRelease(iterator); if (aDevice == 0) { //fputs("No motion sensor available\n", stderr); return 0; } result = IOServiceOpen(aDevice, mach_task_self(), 0, &dataPort); IOObjectRelease(aDevice); if (result != KERN_SUCCESS) { //fputs("Could not open motion sensor device\n", stderr); return 0; } switch ( dataType ) { case PB_IB: structureInputSize = sizeof(struct pb_ib_data); structureOutputSize = sizeof(struct pb_ib_data); break; case MBP: structureInputSize = sizeof(struct mbp_data); structureOutputSize = sizeof(struct mbp_data); break; default: return 0; } memset(&inputStructure, 0, sizeof(union motion_data)); memset(outputStructure, 0, sizeof(union motion_data)); #if !defined(__LP64__) // Check if Mac OS X 10.5 API is available... if (IOConnectCallMethod != NULL) { // ...and use it if it is. #endif result = IOConnectCallStructMethod(dataPort, kernFunc, &inputStructure, structureInputSize, outputStructure, (size_t *) &structureOutputSize); #if !defined(__LP64__) } else { // Otherwise fall back to older API. result = IOConnectMethodStructureIStructureO(dataPort, kernFunc, structureInputSize, &structureOutputSize, &inputStructure, outputStructure); } #endif IOServiceClose(dataPort); if (result != KERN_SUCCESS) { //puts("no coords"); return 0; } return 1; }
int DoIt( int doWhat ) { mach_port_t masterPort; io_object_t netif; // network interface io_connect_t conObj; // connection object kern_return_t kr; UInt32 outSize = sizeof( gBuffer ); /* Get master device port */ kr = IOMasterPort( bootstrap_port, &masterPort ); if ( kr != KERN_SUCCESS ) { printf( "IOMasterPort() failed: %08lx\n", (unsigned long)kr ); exit( 0 ); } netif = getInterfaceWithName( masterPort, "UniNEnet" ); if ( !netif ) { printf( "getInterfaceWithName failed.\n" ); exit( 0 ); } kr = IOServiceOpen( netif, mach_task_self(), 'GMAC', &conObj ); if ( kr != kIOReturnSuccess ) { printf( "open device failed 0x%x\n", kr ); IOObjectRelease( netif ); exit( 0 ); } // printf( "open device succeeded.\n" ); gInUCRequest.reqID = doWhat; kr = io_connect_method_structureI_structureO( conObj, /* connection object */ 0, /* method index for doRequest */ (void*)&gInUCRequest, /* input struct */ sizeof( gInUCRequest ), /* input size */ (void*)&gBuffer, /* output buffer */ (mach_msg_type_number_t*)&outSize ); /* output size */ if ( kr != kIOReturnSuccess ) { printf( "Request failed 0x%x\n", kr ); } else { switch ( doWhat ) { case kGMACUserCmd_GetRegs: OutputBuffer(); break; case kGMACUserCmd_GetOneReg: printf( "Register %04lx: %08lx\n", (UInt32)gInUCRequest.pBuffer, *(UInt32*)gBuffer ); break; case kGMACUserCmd_WriteOneReg: printf( "Writing Register %08lx with %08lx.\n", (UInt32)gInUCRequest.pBuffer, gInUCRequest.bufferSz ); break; } } IOServiceClose( conObj ); // printf( "Closed device.\n" ); IOObjectRelease( netif ); exit( 0 ); }/* end DoIt */
static VALUE method_xyz(){ struct data { signed short x; signed short y; signed short z; char pad[34]; }; kern_return_t result; mach_port_t masterPort; IOMasterPort(MACH_PORT_NULL, &masterPort); CFMutableDictionaryRef matchingDictionary = IOServiceMatching("SMCMotionSensor"); io_iterator_t iterator; result = IOServiceGetMatchingServices(masterPort, matchingDictionary, &iterator); if(result != KERN_SUCCESS) { return rb_str_new2("Error"); } io_object_t device = IOIteratorNext(iterator); IOObjectRelease(iterator); if(device == 0){ return rb_str_new2("Error"); } io_connect_t dataPort; result = IOServiceOpen(device, mach_task_self(), 0, &dataPort); IOObjectRelease(device); if(result != KERN_SUCCESS) { return rb_str_new2("Error"); } IOItemCount structureInputSize; size_t structureOutputSize; struct data inputStructure; struct data outputStructure; structureInputSize = sizeof(struct data); structureOutputSize = sizeof(struct data); memset(&inputStructure, 1, sizeof(inputStructure)); memset(&outputStructure, 0, sizeof(outputStructure)); result = IOConnectCallStructMethod( (mach_port_t)dataPort, (uint32_t)5, (const void*)&inputStructure, structureInputSize, (void*)&outputStructure, &structureOutputSize ); if(result != KERN_SUCCESS) { return rb_str_new2("Error"); } IOServiceClose(dataPort); VALUE coords = rb_ary_new2(3); rb_ary_store(coords, 0, INT2FIX(outputStructure.x)); rb_ary_store(coords, 1, INT2FIX(outputStructure.y)); rb_ary_store(coords, 2, INT2FIX(outputStructure.z)); return coords; }
static int do_dev( io_service_t usbDeviceRef ) { IOReturn err; IOCFPlugInInterface **iodev; // requires <IOKit/IOCFPlugIn.h> SInt32 score; UInt8 numConf; IOUSBConfigurationDescriptorPtr confDesc; IOUSBFindInterfaceRequest interfaceRequest; io_iterator_t iterator; io_service_t usbInterfaceRef; err = IOCreatePlugInInterfaceForService(usbDeviceRef, kIOUSBDeviceUserClientTypeID, kIOCFPlugInInterfaceID, &iodev, &score); if (err || !iodev) { fprintf( stderr, "unable to create plugin. ret = %08x, iodev = %p\n", err, iodev); return -1; } err = (*iodev)->QueryInterface(iodev, CFUUIDGetUUIDBytes(kIOUSBDeviceInterfaceID), (LPVOID)&usbDev); IODestroyPlugInInterface(iodev); // done with this if (err || !usbDev) { fprintf( stderr, "unable to create a device interface. ret = %08x, dev = %p\n", err, usbDev); return -1; } err = (*usbDev)->USBDeviceOpen(usbDev); if (err) { fprintf( stderr, "unable to open device. ret = %08x\n", err); return -1; } err = (*usbDev)->GetNumberOfConfigurations(usbDev, &numConf); if (err || !numConf) { fprintf( stderr, "unable to obtain the number of configurations. ret = %08x\n", err); return -1; } err = (*usbDev)->GetConfigurationDescriptorPtr(usbDev, 0, &confDesc); // get the first config desc (index 0) if (err) { fprintf( stderr, "unable to get config descriptor for index 0\n"); return -1; } err = (*usbDev)->SetConfiguration(usbDev, confDesc->bConfigurationValue); if (err) { fprintf( stderr, "unable to set the configuration\n"); return -1; } // requested class interfaceRequest.bInterfaceClass = kIOUSBFindInterfaceDontCare; // requested subclass interfaceRequest.bInterfaceSubClass = kIOUSBFindInterfaceDontCare; // requested protocol interfaceRequest.bInterfaceProtocol = kIOUSBFindInterfaceDontCare; // requested alt setting interfaceRequest.bAlternateSetting = kIOUSBFindInterfaceDontCare; err = (*usbDev)->CreateInterfaceIterator(usbDev, &interfaceRequest, &iterator); if (err) { fprintf( stderr, "unable to create interface iterator\n"); return -1; } while( (usbInterfaceRef = IOIteratorNext(iterator)) ) { if( do_intf( usbInterfaceRef ) == 0 ) { IOObjectRelease(iterator); iterator = 0; return 0; } } IOObjectRelease(iterator); iterator = 0; return -1; }
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); } }
void DarwinAddSerialPrefs(void) { mach_port_t masterPort; // The way to talk to the kernel io_iterator_t allModems; // List of modems on the system CFMutableDictionaryRef classesToMatch; io_object_t nextModem; if ( IOMasterPort(MACH_PORT_NULL, &masterPort) != KERN_SUCCESS ) bug("IOMasterPort failed. Won't be able to do anything with modems\n"); // Serial devices are instances of class IOSerialBSDClient classesToMatch = IOServiceMatching(kIOSerialBSDServiceValue); if ( classesToMatch ) { // Narrow the search a little further. Each serial device object has // a property with key kIOSerialBSDTypeKey and a value that is one of // kIOSerialBSDAllTypes, kIOSerialBSDModemType, or kIOSerialBSDRS232Type. CFDictionarySetValue(classesToMatch, CFSTR(kIOSerialBSDTypeKey), CFSTR(kIOSerialBSDModemType)); // This will find built-in and USB modems, but not serial modems. } if ( IOServiceGetMatchingServices(masterPort, classesToMatch, &allModems) != KERN_SUCCESS ) { D(bug("IOServiceGetMatchingServices failed. No modems found?\n")); return; } // Iterate through each modem while ( nextModem = IOIteratorNext(allModems)) { char bsdPath[MAXPATHLEN]; CFTypeRef bsdPathAsCFString = IORegistryEntryCreateCFProperty(nextModem, CFSTR(kIOCalloutDeviceKey), // kIODialinDeviceKey? kCFAllocatorDefault, 0); *bsdPath = '\0'; if ( bsdPathAsCFString ) { if ( CFStringGetCString((const __CFString *)bsdPathAsCFString, bsdPath, MAXPATHLEN, kCFStringEncodingASCII) ) { D(bug("Modem BSD path: %s\n", bsdPath)); // Note that if there are multiple modems, we only get the last PrefsAddString("seriala", bsdPath); } else D(bug("Could not get BSD device path for modem\n")); CFRelease(bsdPathAsCFString); } else D(puts("Cannot determine bsdPath for modem\n")); } IOObjectRelease(nextModem); IOObjectRelease(allModems); // Getting a printer device is a bit harder. Creating a fake device // that emulates a simple printer (e.g. a HP DeskJet) is one possibility, // but for now I will just create a fake, safe, device entry: PrefsAddString("serialb", "/dev/null"); }
// Return a list of all serial ports void ArduinoSerial::getAllPortsList() { list.clear(); #if defined(__linux__) // This is ugly guessing, but Linux doesn't seem to provide anything else. // If there really is an API to discover serial devices on Linux, please // email [email protected] with the info. Please? // The really BAD aspect is all ports get DTR raised briefly, because linux // has no way to open the port without raising DTR, and there isn't any way // to tell if the device file really represents hardware without opening it. // maybe sysfs or udev provides a useful API?? DIR *dir; struct dirent *f; struct stat st; unsigned int i, len[NUM_DEVNAMES]; char s[512]; int fd, bits; termios mytios; dir = opendir("/dev/"); if (dir == NULL) return ; for (i=0; i<NUM_DEVNAMES; i++) len[i] = strlen(devnames[i]); // Read all the filenames from the /dev directory... while ((f = readdir(dir)) != NULL) { // ignore everything that doesn't begin with "tty" if (strncmp(f->d_name, "tty", 3)) continue; // ignore anything that's not a known serial device name for (i=0; i<NUM_DEVNAMES; i++) { if (!strncmp(f->d_name + 3, devnames[i], len[i])) break; } if (i >= NUM_DEVNAMES) continue; snprintf(s, sizeof(s), "/dev/%s", f->d_name); // check if it's a character type device (almost certainly is) if (stat(s, &st) != 0 || !(st.st_mode & S_IFCHR)) continue; // now see if we can open the file - if the device file is // populating /dev but doesn't actually represent a loaded // driver, this is where we will detect it. fd = open(s, O_RDONLY | O_NOCTTY | O_NONBLOCK); if (fd < 0) { // if permission denied, give benefit of the doubt // (otherwise the port will be invisible to the user // and we won't have a to alert them to the permssion // problem) if (errno == EACCES) list.push_back(s); // any other error, assume it's not a real device continue; } // does it respond to termios requests? (probably will since // the name began with tty). Some devices where a single // driver exports multiple names will open but this is where // we can really tell if they work with real hardare. if (tcgetattr(fd, &mytios) != 0) { close(fd); continue; } // does it respond to reading the control signals? If it's // some sort of non-serial terminal (eg, pseudo terminals) // this is where we will detect it's not really a serial port if (ioctl(fd, TIOCMGET, &bits) < 0) { close(fd); continue; } // it passed all the tests, it's a serial port, or some sort // of "terminal" that looks exactly like a real serial port! close(fd); // unfortunately, Linux always raises DTR when open is called. // not nice! Every serial port is going to get DTR raised // and then lowered. I wish there were a way to prevent this, // but it seems impossible. list.push_back(s); } closedir(dir); #elif defined(__APPLE__) // adapted from SerialPortSample.c, by Apple // http://developer.apple.com/samplecode/SerialPortSample/listing2.html // and also testserial.c, by Keyspan // http://www.keyspan.com/downloads-files/developer/macosx/KesypanTestSerial.c // www.rxtx.org, src/SerialImp.c seems to be based on Keyspan's testserial.c // neither keyspan nor rxtx properly release memory allocated. // more documentation at: // http://developer.apple.com/documentation/DeviceDrivers/Conceptual/WorkingWSerial/WWSerial_SerialDevs/chapter_2_section_6.html mach_port_t masterPort; CFMutableDictionaryRef classesToMatch; io_iterator_t serialPortIterator; if (IOMasterPort(NULL, &masterPort) != KERN_SUCCESS) return; // a usb-serial adaptor is usually considered a "modem", // especially when it implements the CDC class spec classesToMatch = IOServiceMatching(kIOSerialBSDServiceValue); if (!classesToMatch) return; CFDictionarySetValue(classesToMatch, CFSTR(kIOSerialBSDTypeKey), CFSTR(kIOSerialBSDModemType)); if (IOServiceGetMatchingServices(masterPort, classesToMatch, &serialPortIterator) != KERN_SUCCESS) return; macos_ports(&serialPortIterator); IOObjectRelease(serialPortIterator); // but it might be considered a "rs232 port", so repeat this // search for rs232 ports classesToMatch = IOServiceMatching(kIOSerialBSDServiceValue); if (!classesToMatch) return; CFDictionarySetValue(classesToMatch, CFSTR(kIOSerialBSDTypeKey), CFSTR(kIOSerialBSDRS232Type)); if (IOServiceGetMatchingServices(masterPort, classesToMatch, &serialPortIterator) != KERN_SUCCESS) return; macos_ports(&serialPortIterator); IOObjectRelease(serialPortIterator); #elif defined(_WIN32) // http://msdn.microsoft.com/en-us/library/aa365461(VS.85).aspx // page with 7 ways - not all of them work! // http://www.naughter.com/enumser.html // may be possible to just query the windows registary // http://it.gps678.com/2/ca9c8631868fdd65.html // search in HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\SERIALCOMM // Vista has some special new way, vista-only // http://msdn2.microsoft.com/en-us/library/aa814070(VS.85).aspx char *buffer, *p; //DWORD size = QUERYDOSDEVICE_BUFFER_SIZE; DWORD ret; buffer = (char *)malloc(QUERYDOSDEVICE_BUFFER_SIZE); if (buffer == NULL) return; memset(buffer, 0, QUERYDOSDEVICE_BUFFER_SIZE); ret = QueryDosDeviceA(NULL, buffer, QUERYDOSDEVICE_BUFFER_SIZE); if (ret) { printf("Detect Serial using QueryDosDeviceA: "); for (p = buffer; *p; p += strlen(p) + 1) { printf(": %s", p); if (strncmp(p, "COM", 3)) continue; std::stringstream sstm; sstm << p << ":"; list.push_back(sstm.str().c_str()); } } else { char buf[1024]; win32_err(buf); printf("QueryDosDeviceA failed, error \"%s\"\n", buf); printf("Detect Serial using brute force GetDefaultCommConfig probing: "); for (int i=1; i<=32; i++) { printf("try %s", buf); COMMCONFIG cfg; DWORD len; snprintf(buf, sizeof(buf), "COM%d", i); if (GetDefaultCommConfig(buf, &cfg, &len)) { //wxString name; //name.Printf("COM%d:", i); std::stringstream sstm; sstm << "COM" << i; list.push_back(sstm.str().c_str()); //list.Add(name); printf(": %s", buf); } } } free(buffer); #endif // defined list.sort(); return; }
int main(int argc, char* argv[]) { int i; int nandReadOnly=0; struct stat st; printf("Starting ramdisk tool\n"); printf("Compiled " __DATE__ " " __TIME__ "\n"); printf("Revision " HGVERSION "\n"); CFMutableDictionaryRef matching; io_service_t service = 0; matching = IOServiceMatching("IOWatchDogTimer"); if (matching == NULL) { printf("unable to create matching dictionary for class IOWatchDogTimer\n"); } service = IOServiceGetMatchingService(kIOMasterPortDefault, matching); if (service == 0) { printf("unable to create matching dictionary for class IOWatchDogTimer\n"); } uint32_t zero = 0; CFNumberRef n = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &zero); IORegistryEntrySetCFProperties(service, n); IOObjectRelease(service); CFMutableDictionaryRef deviceInfos = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); get_device_infos(deviceInfos); init_tcp(); sysctlbyname("kern.bootargs", bootargs, &bootargs_len, NULL, 0); if (strstr(bootargs, "nand-readonly") || strstr(bootargs, "nand-disable")) { printf("NAND read only mode, data partition wont be mounted\n"); nandReadOnly = 1; } else { printf("Waiting for data partition\n"); for(i=0; i < 10; i++) { if(!stat("/dev/disk0s2s1", &st)) { system("/sbin/fsck_hfs /dev/disk0s2s1"); break; } if(!stat("/dev/disk0s1s2", &st)) { system("/sbin/fsck_hfs /dev/disk0s1s2"); break; } if(!stat("/dev/disk0s2", &st)) { system("/sbin/fsck_hfs /dev/disk0s2"); break; } sleep(5); } } init_usb(CFDictionaryGetValue(deviceInfos, CFSTR("udid"))); printf("USB init done\n"); system("mount /"); //make ramdisk writable chmod("/var/root/.ssh/authorized_keys", 0600); chown("/var/root/.ssh/authorized_keys", 0, 0); chown("/var/root/.ssh", 0, 0); chown("/var/root/", 0, 0); printf(" ####### ## ##\n"); printf("## ## ## ## \n"); printf("## ## ## ## \n"); printf("## ## ##### \n"); printf("## ## ## ## \n"); printf("## ## ## ## \n"); printf(" ####### ## ##\n"); printf("iphone-dataprotection ramdisk\n"); printf("revision: " HGVERSION " " __DATE__ " " __TIME__ "\n"); if(!stat(execve_params[0], &st)) { printf("Running %s\n", execve_params[0]); if((i = posix_spawn(NULL, execve_params[0], NULL, NULL, execve_params, execve_env))) printf("posix_spawn(%s) returned %d\n", execve_params[0], i); } else { printf("%s is missing\n", execve_params[0]); } /*if (nandReadOnly) {*/ if(!stat(ioflash[0], &st)) { printf("Running %s\n", ioflash[0]); if((i = posix_spawn(NULL, ioflash[0], NULL, NULL, ioflash, execve_env))) printf("posix_spawn(%s) returned %d\n", execve_params[0], i); } /*}*/ CFMutableDictionaryRef handlers = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, NULL); CFDictionaryAddValue(handlers, CFSTR("DeviceInfo"), device_info); CFDictionaryAddValue(handlers, CFSTR("GetSystemKeyBag"), load_system_keybag); CFDictionaryAddValue(handlers, CFSTR("BruteforceSystemKeyBag"), bruteforce_system_keybag); CFDictionaryAddValue(handlers, CFSTR("KeyBagGetPasscodeKey"), keybag_get_passcode_key); CFDictionaryAddValue(handlers, CFSTR("GetEscrowRecord"), get_escrow_record); CFDictionaryAddValue(handlers, CFSTR("DownloadFile"), download_file); CFDictionaryAddValue(handlers, CFSTR("AES"), remote_aes); CFDictionaryAddValue(handlers, CFSTR("Reboot"), reboot__); serve_plist_rpc(1999, handlers); return 0; }
static int disk_read (void) { #if HAVE_IOKIT_IOKITLIB_H io_registry_entry_t disk; io_registry_entry_t disk_child; io_iterator_t disk_list; CFDictionaryRef props_dict; CFDictionaryRef stats_dict; CFDictionaryRef child_dict; CFStringRef tmp_cf_string_ref; kern_return_t status; signed long long read_ops; signed long long read_byt; signed long long read_tme; signed long long write_ops; signed long long write_byt; signed long long write_tme; int disk_major; int disk_minor; char disk_name[DATA_MAX_NAME_LEN]; char disk_name_bsd[DATA_MAX_NAME_LEN]; /* Get the list of all disk objects. */ if (IOServiceGetMatchingServices (io_master_port, IOServiceMatching (kIOBlockStorageDriverClass), &disk_list) != kIOReturnSuccess) { ERROR ("disk plugin: IOServiceGetMatchingServices failed."); return (-1); } while ((disk = IOIteratorNext (disk_list)) != 0) { props_dict = NULL; stats_dict = NULL; child_dict = NULL; /* `disk_child' must be released */ if ((status = IORegistryEntryGetChildEntry (disk, kIOServicePlane, &disk_child)) != kIOReturnSuccess) { /* This fails for example for DVD/CD drives.. */ DEBUG ("IORegistryEntryGetChildEntry (disk) failed: 0x%08x", status); IOObjectRelease (disk); continue; } /* We create `props_dict' => we need to release it later */ if (IORegistryEntryCreateCFProperties (disk, (CFMutableDictionaryRef *) &props_dict, kCFAllocatorDefault, kNilOptions) != kIOReturnSuccess) { ERROR ("disk-plugin: IORegistryEntryCreateCFProperties failed."); IOObjectRelease (disk_child); IOObjectRelease (disk); continue; } if (props_dict == NULL) { DEBUG ("IORegistryEntryCreateCFProperties (disk) failed."); IOObjectRelease (disk_child); IOObjectRelease (disk); continue; } /* tmp_cf_string_ref doesn't need to be released. */ tmp_cf_string_ref = (CFStringRef) CFDictionaryGetValue (props_dict, CFSTR(kIOBSDNameKey)); if (!tmp_cf_string_ref) { DEBUG ("disk plugin: CFDictionaryGetValue(" "kIOBSDNameKey) failed."); CFRelease (props_dict); IOObjectRelease (disk_child); IOObjectRelease (disk); continue; } assert (CFGetTypeID (tmp_cf_string_ref) == CFStringGetTypeID ()); memset (disk_name_bsd, 0, sizeof (disk_name_bsd)); CFStringGetCString (tmp_cf_string_ref, disk_name_bsd, sizeof (disk_name_bsd), kCFStringEncodingUTF8); if (disk_name_bsd[0] == 0) { ERROR ("disk plugin: CFStringGetCString() failed."); CFRelease (props_dict); IOObjectRelease (disk_child); IOObjectRelease (disk); continue; } DEBUG ("disk plugin: disk_name_bsd = \"%s\"", disk_name_bsd); stats_dict = (CFDictionaryRef) CFDictionaryGetValue (props_dict, CFSTR (kIOBlockStorageDriverStatisticsKey)); if (stats_dict == NULL) { DEBUG ("disk plugin: CFDictionaryGetValue (" "%s) failed.", kIOBlockStorageDriverStatisticsKey); CFRelease (props_dict); IOObjectRelease (disk_child); IOObjectRelease (disk); continue; } if (IORegistryEntryCreateCFProperties (disk_child, (CFMutableDictionaryRef *) &child_dict, kCFAllocatorDefault, kNilOptions) != kIOReturnSuccess) { DEBUG ("disk plugin: IORegistryEntryCreateCFProperties (" "disk_child) failed."); IOObjectRelease (disk_child); CFRelease (props_dict); IOObjectRelease (disk); continue; } /* kIOBSDNameKey */ disk_major = (int) dict_get_value (child_dict, kIOBSDMajorKey); disk_minor = (int) dict_get_value (child_dict, kIOBSDMinorKey); read_ops = dict_get_value (stats_dict, kIOBlockStorageDriverStatisticsReadsKey); read_byt = dict_get_value (stats_dict, kIOBlockStorageDriverStatisticsBytesReadKey); read_tme = dict_get_value (stats_dict, kIOBlockStorageDriverStatisticsTotalReadTimeKey); write_ops = dict_get_value (stats_dict, kIOBlockStorageDriverStatisticsWritesKey); write_byt = dict_get_value (stats_dict, kIOBlockStorageDriverStatisticsBytesWrittenKey); /* This property describes the number of nanoseconds spent * performing writes since the block storage driver was * instantiated. It is one of the statistic entries listed * under the top-level kIOBlockStorageDriverStatisticsKey * property table. It has an OSNumber value. */ write_tme = dict_get_value (stats_dict, kIOBlockStorageDriverStatisticsTotalWriteTimeKey); if (use_bsd_name) sstrncpy (disk_name, disk_name_bsd, sizeof (disk_name)); else ssnprintf (disk_name, sizeof (disk_name), "%i-%i", disk_major, disk_minor); DEBUG ("disk plugin: disk_name = \"%s\"", disk_name); if ((read_byt != -1LL) || (write_byt != -1LL)) disk_submit (disk_name, "disk_octets", read_byt, write_byt); if ((read_ops != -1LL) || (write_ops != -1LL)) disk_submit (disk_name, "disk_ops", read_ops, write_ops); if ((read_tme != -1LL) || (write_tme != -1LL)) disk_submit (disk_name, "disk_time", read_tme / 1000, write_tme / 1000); CFRelease (child_dict); IOObjectRelease (disk_child); CFRelease (props_dict); IOObjectRelease (disk); } IOObjectRelease (disk_list); /* #endif HAVE_IOKIT_IOKITLIB_H */ #elif KERNEL_LINUX FILE *fh; char buffer[1024]; char *fields[32]; int numfields; int fieldshift = 0; int minor = 0; derive_t read_sectors = 0; derive_t write_sectors = 0; derive_t read_ops = 0; derive_t read_merged = 0; derive_t read_time = 0; derive_t write_ops = 0; derive_t write_merged = 0; derive_t write_time = 0; int is_disk = 0; diskstats_t *ds, *pre_ds; if ((fh = fopen ("/proc/diskstats", "r")) == NULL) { fh = fopen ("/proc/partitions", "r"); if (fh == NULL) { ERROR ("disk plugin: fopen (/proc/{diskstats,partitions}) failed."); return (-1); } /* Kernel is 2.4.* */ fieldshift = 1; } #if HAVE_LIBUDEV handle_udev = udev_new(); #endif while (fgets (buffer, sizeof (buffer), fh) != NULL) { char *disk_name; char *output_name; char *alt_name; numfields = strsplit (buffer, fields, 32); if ((numfields != (14 + fieldshift)) && (numfields != 7)) continue; minor = atoll (fields[1]); disk_name = fields[2 + fieldshift]; for (ds = disklist, pre_ds = disklist; ds != NULL; pre_ds = ds, ds = ds->next) if (strcmp (disk_name, ds->name) == 0) break; if (ds == NULL) { if ((ds = (diskstats_t *) calloc (1, sizeof (diskstats_t))) == NULL) continue; if ((ds->name = strdup (disk_name)) == NULL) { free (ds); continue; } if (pre_ds == NULL) disklist = ds; else pre_ds->next = ds; } is_disk = 0; if (numfields == 7) { /* Kernel 2.6, Partition */ read_ops = atoll (fields[3]); read_sectors = atoll (fields[4]); write_ops = atoll (fields[5]); write_sectors = atoll (fields[6]); } else if (numfields == (14 + fieldshift)) { read_ops = atoll (fields[3 + fieldshift]); write_ops = atoll (fields[7 + fieldshift]); read_sectors = atoll (fields[5 + fieldshift]); write_sectors = atoll (fields[9 + fieldshift]); if ((fieldshift == 0) || (minor == 0)) { is_disk = 1; read_merged = atoll (fields[4 + fieldshift]); read_time = atoll (fields[6 + fieldshift]); write_merged = atoll (fields[8 + fieldshift]); write_time = atoll (fields[10+ fieldshift]); } } else { DEBUG ("numfields = %i; => unknown file format.", numfields); continue; } { derive_t diff_read_sectors; derive_t diff_write_sectors; /* If the counter wraps around, it's only 32 bits.. */ if (read_sectors < ds->read_sectors) diff_read_sectors = 1 + read_sectors + (UINT_MAX - ds->read_sectors); else diff_read_sectors = read_sectors - ds->read_sectors; if (write_sectors < ds->write_sectors) diff_write_sectors = 1 + write_sectors + (UINT_MAX - ds->write_sectors); else diff_write_sectors = write_sectors - ds->write_sectors; ds->read_bytes += 512 * diff_read_sectors; ds->write_bytes += 512 * diff_write_sectors; ds->read_sectors = read_sectors; ds->write_sectors = write_sectors; } /* Calculate the average time an io-op needs to complete */ if (is_disk) { derive_t diff_read_ops; derive_t diff_write_ops; derive_t diff_read_time; derive_t diff_write_time; if (read_ops < ds->read_ops) diff_read_ops = 1 + read_ops + (UINT_MAX - ds->read_ops); else diff_read_ops = read_ops - ds->read_ops; DEBUG ("disk plugin: disk_name = %s; read_ops = %"PRIi64"; " "ds->read_ops = %"PRIi64"; diff_read_ops = %"PRIi64";", disk_name, read_ops, ds->read_ops, diff_read_ops); if (write_ops < ds->write_ops) diff_write_ops = 1 + write_ops + (UINT_MAX - ds->write_ops); else diff_write_ops = write_ops - ds->write_ops; if (read_time < ds->read_time) diff_read_time = 1 + read_time + (UINT_MAX - ds->read_time); else diff_read_time = read_time - ds->read_time; if (write_time < ds->write_time) diff_write_time = 1 + write_time + (UINT_MAX - ds->write_time); else diff_write_time = write_time - ds->write_time; if (diff_read_ops != 0) ds->avg_read_time += disk_calc_time_incr ( diff_read_time, diff_read_ops); if (diff_write_ops != 0) ds->avg_write_time += disk_calc_time_incr ( diff_write_time, diff_write_ops); ds->read_ops = read_ops; ds->read_time = read_time; ds->write_ops = write_ops; ds->write_time = write_time; } /* if (is_disk) */ /* Don't write to the RRDs if we've just started.. */ ds->poll_count++; if (ds->poll_count <= 2) { DEBUG ("disk plugin: (ds->poll_count = %i) <= " "(min_poll_count = 2); => Not writing.", ds->poll_count); continue; } if ((read_ops == 0) && (write_ops == 0)) { DEBUG ("disk plugin: ((read_ops == 0) && " "(write_ops == 0)); => Not writing."); continue; } output_name = disk_name; #if HAVE_LIBUDEV alt_name = disk_udev_attr_name (handle_udev, disk_name, conf_udev_name_attr); #else alt_name = NULL; #endif if (alt_name != NULL) output_name = alt_name; if ((ds->read_bytes != 0) || (ds->write_bytes != 0)) disk_submit (output_name, "disk_octets", ds->read_bytes, ds->write_bytes); if ((ds->read_ops != 0) || (ds->write_ops != 0)) disk_submit (output_name, "disk_ops", read_ops, write_ops); if ((ds->avg_read_time != 0) || (ds->avg_write_time != 0)) disk_submit (output_name, "disk_time", ds->avg_read_time, ds->avg_write_time); if (is_disk) { disk_submit (output_name, "disk_merged", read_merged, write_merged); } /* if (is_disk) */ /* release udev-based alternate name, if allocated */ free(alt_name); } /* while (fgets (buffer, sizeof (buffer), fh) != NULL) */ #if HAVE_LIBUDEV udev_unref(handle_udev); #endif fclose (fh); /* #endif defined(KERNEL_LINUX) */ #elif HAVE_LIBKSTAT # if HAVE_KSTAT_IO_T_WRITES && HAVE_KSTAT_IO_T_NWRITES && HAVE_KSTAT_IO_T_WTIME # define KIO_ROCTETS reads # define KIO_WOCTETS writes # define KIO_ROPS nreads # define KIO_WOPS nwrites # define KIO_RTIME rtime # define KIO_WTIME wtime # elif HAVE_KSTAT_IO_T_NWRITTEN && HAVE_KSTAT_IO_T_WRITES && HAVE_KSTAT_IO_T_WTIME # define KIO_ROCTETS nread # define KIO_WOCTETS nwritten # define KIO_ROPS reads # define KIO_WOPS writes # define KIO_RTIME rtime # define KIO_WTIME wtime # else # error "kstat_io_t does not have the required members" # endif static kstat_io_t kio; int i; if (kc == NULL) return (-1); for (i = 0; i < numdisk; i++) { if (kstat_read (kc, ksp[i], &kio) == -1) continue; if (strncmp (ksp[i]->ks_class, "disk", 4) == 0) { disk_submit (ksp[i]->ks_name, "disk_octets", kio.KIO_ROCTETS, kio.KIO_WOCTETS); disk_submit (ksp[i]->ks_name, "disk_ops", kio.KIO_ROPS, kio.KIO_WOPS); /* FIXME: Convert this to microseconds if necessary */ disk_submit (ksp[i]->ks_name, "disk_time", kio.KIO_RTIME, kio.KIO_WTIME); } else if (strncmp (ksp[i]->ks_class, "partition", 9) == 0) { disk_submit (ksp[i]->ks_name, "disk_octets", kio.KIO_ROCTETS, kio.KIO_WOCTETS); disk_submit (ksp[i]->ks_name, "disk_ops", kio.KIO_ROPS, kio.KIO_WOPS); } } /* #endif defined(HAVE_LIBKSTAT) */ #elif defined(HAVE_LIBSTATGRAB) sg_disk_io_stats *ds; int disks, counter; char name[DATA_MAX_NAME_LEN]; if ((ds = sg_get_disk_io_stats(&disks)) == NULL) return (0); for (counter=0; counter < disks; counter++) { strncpy(name, ds->disk_name, sizeof(name)); name[sizeof(name)-1] = '\0'; /* strncpy doesn't terminate longer strings */ disk_submit (name, "disk_octets", ds->read_bytes, ds->write_bytes); ds++; } /* #endif defined(HAVE_LIBSTATGRAB) */ #elif defined(HAVE_PERFSTAT) derive_t read_sectors; derive_t write_sectors; derive_t read_time; derive_t write_time; derive_t read_ops; derive_t write_ops; perfstat_id_t firstpath; int rnumdisk; int i; if ((numdisk = perfstat_disk(NULL, NULL, sizeof(perfstat_disk_t), 0)) < 0) { char errbuf[1024]; WARNING ("disk plugin: perfstat_disk: %s", sstrerror (errno, errbuf, sizeof (errbuf))); return (-1); } if (numdisk != pnumdisk || stat_disk==NULL) { if (stat_disk!=NULL) free(stat_disk); stat_disk = (perfstat_disk_t *)calloc(numdisk, sizeof(perfstat_disk_t)); } pnumdisk = numdisk; firstpath.name[0]='\0'; if ((rnumdisk = perfstat_disk(&firstpath, stat_disk, sizeof(perfstat_disk_t), numdisk)) < 0) { char errbuf[1024]; WARNING ("disk plugin: perfstat_disk : %s", sstrerror (errno, errbuf, sizeof (errbuf))); return (-1); } for (i = 0; i < rnumdisk; i++) { read_sectors = stat_disk[i].rblks*stat_disk[i].bsize; write_sectors = stat_disk[i].wblks*stat_disk[i].bsize; disk_submit (stat_disk[i].name, "disk_octets", read_sectors, write_sectors); read_ops = stat_disk[i].xrate; write_ops = stat_disk[i].xfers - stat_disk[i].xrate; disk_submit (stat_disk[i].name, "disk_ops", read_ops, write_ops); read_time = stat_disk[i].rserv; read_time *= ((double)(_system_configuration.Xint)/(double)(_system_configuration.Xfrac)) / 1000000.0; write_time = stat_disk[i].wserv; write_time *= ((double)(_system_configuration.Xint)/(double)(_system_configuration.Xfrac)) / 1000000.0; disk_submit (stat_disk[i].name, "disk_time", read_time, write_time); } #endif /* defined(HAVE_PERFSTAT) */ return (0); } /* int disk_read */
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"); }
int main(int argc, char **argv) { io_registry_entry_t service; io_connect_t connect; kern_return_t status; service = IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceMatching("AppleACPIPlatformExpert")); assert(service); if (service) { status = IOServiceOpen(service, mach_task_self(), 0, &connect); IOObjectRelease(service); assert(kIOReturnSuccess == status); } uint32_t count = 0; uint32_t segment = 0; uint32_t maxBus = 0; uint32_t bus, device, fn, maxFn; uint32_t vendProd; if (argc > 3) { bus = strtoul(argv[1], NULL, 0); device = strtoul(argv[2], NULL, 0); fn = strtoul(argv[3], NULL, 0); if (argc == 4) { dumpDevice(connect, segment, bus, device, fn, NULL, NULL); count++; } if (argc > 5) { uint32_t offs; uint32_t data; offs = strtoul(argv[4], NULL, 0); data = strtoul(argv[5], NULL, 0); configWrite32(connect, segment, bus, device, fn, offs, data); printf("wrote 0x%08x to [%d, %d, %d]:0x%X\n", data, bus, device, fn, offs); } else if (argc > 4) { uint32_t offs; uint32_t data; offs = strtoul(argv[4], NULL, 0); data = configRead32(connect, segment, bus, device, fn, offs); printf("read 0x%08x from [%d, %d, %d]:0x%X\n", data, bus, device, fn, offs); } } else if (argc > 2) { uint64_t offs; uint32_t data; offs = strtoull(argv[1], NULL, 0); data = strtoul(argv[2], NULL, 0); physWrite32(connect, offs, data); printf("wrote 0x%08x to 0x%llX\n", data, offs); } else if (argc > 1) { uint64_t offs; uint32_t data; offs = strtoull(argv[1], NULL, 0); if (true || (offs > 0x10000ULL)) { data = physRead32(connect, offs); printf("read 0x%08x from mem 0x%llX\n", data, offs); } else { data = ioRead32(connect, offs); printf("read 0x%08x from i/o 0x%llX\n", data, offs); } } else for (bus = 0; bus <= maxBus; bus++) { for (device = 0; device < 32; device++) { maxFn = 0; for (fn = 0; fn <= maxFn; fn++) { vendProd = configRead32(connect, segment, bus, device, fn, kIOPCIConfigVendorID); if ((0xFFFFFFFF == vendProd) || !vendProd) continue; count++; dumpDevice(connect, segment, bus, device, fn, &maxBus, &maxFn); } } } printf("total: %d\n", count); exit(0); }
static int disk_read (void) { #if HAVE_IOKIT_IOKITLIB_H io_registry_entry_t disk; io_registry_entry_t disk_child; io_iterator_t disk_list; CFMutableDictionaryRef props_dict, child_dict; CFDictionaryRef stats_dict; CFStringRef tmp_cf_string_ref; kern_return_t status; signed long long read_ops, read_byt, read_tme; signed long long write_ops, write_byt, write_tme; int disk_major, disk_minor; char disk_name[DATA_MAX_NAME_LEN]; char child_disk_name_bsd[DATA_MAX_NAME_LEN], props_disk_name_bsd[DATA_MAX_NAME_LEN]; /* Get the list of all disk objects. */ if (IOServiceGetMatchingServices (io_master_port, IOServiceMatching (kIOBlockStorageDriverClass), &disk_list) != kIOReturnSuccess) { ERROR ("disk plugin: IOServiceGetMatchingServices failed."); return (-1); } while ((disk = IOIteratorNext (disk_list)) != 0) { props_dict = NULL; stats_dict = NULL; child_dict = NULL; /* get child of disk entry and corresponding property dictionary */ if ((status = IORegistryEntryGetChildEntry (disk, kIOServicePlane, &disk_child)) != kIOReturnSuccess) { /* This fails for example for DVD/CD drives, which we want to ignore anyway */ DEBUG ("IORegistryEntryGetChildEntry (disk) failed: 0x%08x", status); IOObjectRelease (disk); continue; } if (IORegistryEntryCreateCFProperties (disk_child, (CFMutableDictionaryRef *) &child_dict, kCFAllocatorDefault, kNilOptions) != kIOReturnSuccess || child_dict == NULL) { ERROR ("disk plugin: IORegistryEntryCreateCFProperties (disk_child) failed."); IOObjectRelease (disk_child); IOObjectRelease (disk); continue; } /* extract name and major/minor numbers */ memset (child_disk_name_bsd, 0, sizeof (child_disk_name_bsd)); tmp_cf_string_ref = (CFStringRef) CFDictionaryGetValue (child_dict, CFSTR(kIOBSDNameKey)); if (tmp_cf_string_ref) { assert (CFGetTypeID (tmp_cf_string_ref) == CFStringGetTypeID ()); CFStringGetCString (tmp_cf_string_ref, child_disk_name_bsd, sizeof (child_disk_name_bsd), kCFStringEncodingUTF8); } disk_major = (int) dict_get_value (child_dict, kIOBSDMajorKey); disk_minor = (int) dict_get_value (child_dict, kIOBSDMinorKey); DEBUG ("disk plugin: child_disk_name_bsd=\"%s\" major=%d minor=%d", child_disk_name_bsd, disk_major, disk_minor); CFRelease (child_dict); IOObjectRelease (disk_child); /* get property dictionary of the disk entry itself */ if (IORegistryEntryCreateCFProperties (disk, (CFMutableDictionaryRef *) &props_dict, kCFAllocatorDefault, kNilOptions) != kIOReturnSuccess || props_dict == NULL) { ERROR ("disk-plugin: IORegistryEntryCreateCFProperties failed."); IOObjectRelease (disk); continue; } /* extract name and stats dictionary */ memset (props_disk_name_bsd, 0, sizeof (props_disk_name_bsd)); tmp_cf_string_ref = (CFStringRef) CFDictionaryGetValue (props_dict, CFSTR(kIOBSDNameKey)); if (tmp_cf_string_ref) { assert (CFGetTypeID (tmp_cf_string_ref) == CFStringGetTypeID ()); CFStringGetCString (tmp_cf_string_ref, props_disk_name_bsd, sizeof (props_disk_name_bsd), kCFStringEncodingUTF8); } stats_dict = (CFDictionaryRef) CFDictionaryGetValue (props_dict, CFSTR (kIOBlockStorageDriverStatisticsKey)); if (stats_dict == NULL) { ERROR ("disk plugin: CFDictionaryGetValue (%s) failed.", kIOBlockStorageDriverStatisticsKey); CFRelease (props_dict); IOObjectRelease (disk); continue; } DEBUG ("disk plugin: props_disk_name_bsd=\"%s\"", props_disk_name_bsd); /* choose name */ if (use_bsd_name) { if (child_disk_name_bsd[0] != 0) sstrncpy (disk_name, child_disk_name_bsd, sizeof (disk_name)); else if (props_disk_name_bsd[0] != 0) sstrncpy (disk_name, props_disk_name_bsd, sizeof (disk_name)); else { ERROR ("disk plugin: can't find bsd disk name."); ssnprintf (disk_name, sizeof (disk_name), "%i-%i", disk_major, disk_minor); } } else ssnprintf (disk_name, sizeof (disk_name), "%i-%i", disk_major, disk_minor); /* extract the stats */ read_ops = dict_get_value (stats_dict, kIOBlockStorageDriverStatisticsReadsKey); read_byt = dict_get_value (stats_dict, kIOBlockStorageDriverStatisticsBytesReadKey); read_tme = dict_get_value (stats_dict, kIOBlockStorageDriverStatisticsTotalReadTimeKey); write_ops = dict_get_value (stats_dict, kIOBlockStorageDriverStatisticsWritesKey); write_byt = dict_get_value (stats_dict, kIOBlockStorageDriverStatisticsBytesWrittenKey); write_tme = dict_get_value (stats_dict, kIOBlockStorageDriverStatisticsTotalWriteTimeKey); CFRelease (props_dict); IOObjectRelease (disk); /* and submit */ DEBUG ("disk plugin: disk_name = \"%s\"", disk_name); if ((read_byt != -1LL) || (write_byt != -1LL)) disk_submit (disk_name, "disk_octets", read_byt, write_byt); if ((read_ops != -1LL) || (write_ops != -1LL)) disk_submit (disk_name, "disk_ops", read_ops, write_ops); if ((read_tme != -1LL) || (write_tme != -1LL)) disk_submit (disk_name, "disk_time", read_tme / 1000, write_tme / 1000); } IOObjectRelease (disk_list); /* #endif HAVE_IOKIT_IOKITLIB_H */ #elif KERNEL_FREEBSD int retry, dirty; void *snap = NULL; struct devstat *snap_iter; struct gident *geom_id; const char *disk_name; long double read_time, write_time; for (retry = 0, dirty = 1; retry < 5 && dirty == 1; retry++) { if (snap != NULL) geom_stats_snapshot_free(snap); /* Get a fresh copy of stats snapshot */ snap = geom_stats_snapshot_get(); if (snap == NULL) { ERROR("disk plugin: geom_stats_snapshot_get() failed."); return (-1); } /* Check if we have dirty read from this snapshot */ dirty = 0; geom_stats_snapshot_reset(snap); while ((snap_iter = geom_stats_snapshot_next(snap)) != NULL) { if (snap_iter->id == NULL) continue; geom_id = geom_lookupid(&geom_tree, snap_iter->id); /* New device? refresh GEOM tree */ if (geom_id == NULL) { geom_deletetree(&geom_tree); if (geom_gettree(&geom_tree) != 0) { ERROR("disk plugin: geom_gettree() failed"); geom_stats_snapshot_free(snap); return (-1); } geom_id = geom_lookupid(&geom_tree, snap_iter->id); } /* * This should be rare: the device come right before we take the * snapshot and went away right after it. We will handle this * case later, so don't mark dirty but silently ignore it. */ if (geom_id == NULL) continue; /* Only collect PROVIDER data */ if (geom_id->lg_what != ISPROVIDER) continue; /* Only collect data when rank is 1 (physical devices) */ if (((struct gprovider *)(geom_id->lg_ptr))->lg_geom->lg_rank != 1) continue; /* Check if this is a dirty read quit for another try */ if (snap_iter->sequence0 != snap_iter->sequence1) { dirty = 1; break; } } } /* Reset iterator */ geom_stats_snapshot_reset(snap); for (;;) { snap_iter = geom_stats_snapshot_next(snap); if (snap_iter == NULL) break; if (snap_iter->id == NULL) continue; geom_id = geom_lookupid(&geom_tree, snap_iter->id); if (geom_id == NULL) continue; if (geom_id->lg_what != ISPROVIDER) continue; if (((struct gprovider *)(geom_id->lg_ptr))->lg_geom->lg_rank != 1) continue; /* Skip dirty reads, if present */ if (dirty && (snap_iter->sequence0 != snap_iter->sequence1)) continue; disk_name = ((struct gprovider *)geom_id->lg_ptr)->lg_name; if ((snap_iter->bytes[DEVSTAT_READ] != 0) || (snap_iter->bytes[DEVSTAT_WRITE] != 0)) { disk_submit(disk_name, "disk_octets", (derive_t)snap_iter->bytes[DEVSTAT_READ], (derive_t)snap_iter->bytes[DEVSTAT_WRITE]); } if ((snap_iter->operations[DEVSTAT_READ] != 0) || (snap_iter->operations[DEVSTAT_WRITE] != 0)) { disk_submit(disk_name, "disk_ops", (derive_t)snap_iter->operations[DEVSTAT_READ], (derive_t)snap_iter->operations[DEVSTAT_WRITE]); } read_time = devstat_compute_etime(&snap_iter->duration[DEVSTAT_READ], NULL); write_time = devstat_compute_etime(&snap_iter->duration[DEVSTAT_WRITE], NULL); if ((read_time != 0) || (write_time != 0)) { disk_submit (disk_name, "disk_time", (derive_t)(read_time*1000), (derive_t)(write_time*1000)); } } geom_stats_snapshot_free(snap); #elif KERNEL_LINUX FILE *fh; char buffer[1024]; char *fields[32]; int numfields; int fieldshift = 0; int minor = 0; derive_t read_sectors = 0; derive_t write_sectors = 0; derive_t read_ops = 0; derive_t read_merged = 0; derive_t read_time = 0; derive_t write_ops = 0; derive_t write_merged = 0; derive_t write_time = 0; gauge_t in_progress = NAN; derive_t io_time = 0; derive_t weighted_time = 0; int is_disk = 0; diskstats_t *ds, *pre_ds; if ((fh = fopen ("/proc/diskstats", "r")) == NULL) { fh = fopen ("/proc/partitions", "r"); if (fh == NULL) { ERROR ("disk plugin: fopen (/proc/{diskstats,partitions}) failed."); return (-1); } /* Kernel is 2.4.* */ fieldshift = 1; } #if HAVE_LIBUDEV handle_udev = udev_new(); #endif while (fgets (buffer, sizeof (buffer), fh) != NULL) { char *disk_name; char *output_name; numfields = strsplit (buffer, fields, 32); if ((numfields != (14 + fieldshift)) && (numfields != 7)) continue; minor = atoll (fields[1]); disk_name = fields[2 + fieldshift]; for (ds = disklist, pre_ds = disklist; ds != NULL; pre_ds = ds, ds = ds->next) if (strcmp (disk_name, ds->name) == 0) break; if (ds == NULL) { if ((ds = (diskstats_t *) calloc (1, sizeof (diskstats_t))) == NULL) continue; if ((ds->name = strdup (disk_name)) == NULL) { free (ds); continue; } if (pre_ds == NULL) disklist = ds; else pre_ds->next = ds; } is_disk = 0; if (numfields == 7) { /* Kernel 2.6, Partition */ read_ops = atoll (fields[3]); read_sectors = atoll (fields[4]); write_ops = atoll (fields[5]); write_sectors = atoll (fields[6]); } else if (numfields == (14 + fieldshift)) { read_ops = atoll (fields[3 + fieldshift]); write_ops = atoll (fields[7 + fieldshift]); read_sectors = atoll (fields[5 + fieldshift]); write_sectors = atoll (fields[9 + fieldshift]); if ((fieldshift == 0) || (minor == 0)) { is_disk = 1; read_merged = atoll (fields[4 + fieldshift]); read_time = atoll (fields[6 + fieldshift]); write_merged = atoll (fields[8 + fieldshift]); write_time = atoll (fields[10+ fieldshift]); in_progress = atof (fields[11 + fieldshift]); io_time = atof (fields[12 + fieldshift]); weighted_time = atof (fields[13 + fieldshift]); } } else { DEBUG ("numfields = %i; => unknown file format.", numfields); continue; } { derive_t diff_read_sectors; derive_t diff_write_sectors; /* If the counter wraps around, it's only 32 bits.. */ if (read_sectors < ds->read_sectors) diff_read_sectors = 1 + read_sectors + (UINT_MAX - ds->read_sectors); else diff_read_sectors = read_sectors - ds->read_sectors; if (write_sectors < ds->write_sectors) diff_write_sectors = 1 + write_sectors + (UINT_MAX - ds->write_sectors); else diff_write_sectors = write_sectors - ds->write_sectors; ds->read_bytes += 512 * diff_read_sectors; ds->write_bytes += 512 * diff_write_sectors; ds->read_sectors = read_sectors; ds->write_sectors = write_sectors; } /* Calculate the average time an io-op needs to complete */ if (is_disk) { derive_t diff_read_ops; derive_t diff_write_ops; derive_t diff_read_time; derive_t diff_write_time; if (read_ops < ds->read_ops) diff_read_ops = 1 + read_ops + (UINT_MAX - ds->read_ops); else diff_read_ops = read_ops - ds->read_ops; DEBUG ("disk plugin: disk_name = %s; read_ops = %"PRIi64"; " "ds->read_ops = %"PRIi64"; diff_read_ops = %"PRIi64";", disk_name, read_ops, ds->read_ops, diff_read_ops); if (write_ops < ds->write_ops) diff_write_ops = 1 + write_ops + (UINT_MAX - ds->write_ops); else diff_write_ops = write_ops - ds->write_ops; if (read_time < ds->read_time) diff_read_time = 1 + read_time + (UINT_MAX - ds->read_time); else diff_read_time = read_time - ds->read_time; if (write_time < ds->write_time) diff_write_time = 1 + write_time + (UINT_MAX - ds->write_time); else diff_write_time = write_time - ds->write_time; if (diff_read_ops != 0) ds->avg_read_time += disk_calc_time_incr ( diff_read_time, diff_read_ops); if (diff_write_ops != 0) ds->avg_write_time += disk_calc_time_incr ( diff_write_time, diff_write_ops); ds->read_ops = read_ops; ds->read_time = read_time; ds->write_ops = write_ops; ds->write_time = write_time; } /* if (is_disk) */ /* Don't write to the RRDs if we've just started.. */ ds->poll_count++; if (ds->poll_count <= 2) { DEBUG ("disk plugin: (ds->poll_count = %i) <= " "(min_poll_count = 2); => Not writing.", ds->poll_count); continue; } if ((read_ops == 0) && (write_ops == 0)) { DEBUG ("disk plugin: ((read_ops == 0) && " "(write_ops == 0)); => Not writing."); continue; } output_name = disk_name; #if HAVE_LIBUDEV char *alt_name = disk_udev_attr_name (handle_udev, disk_name, conf_udev_name_attr); if (alt_name != NULL) output_name = alt_name; #endif if ((ds->read_bytes != 0) || (ds->write_bytes != 0)) disk_submit (output_name, "disk_octets", ds->read_bytes, ds->write_bytes); if ((ds->read_ops != 0) || (ds->write_ops != 0)) disk_submit (output_name, "disk_ops", read_ops, write_ops); if ((ds->avg_read_time != 0) || (ds->avg_write_time != 0)) disk_submit (output_name, "disk_time", ds->avg_read_time, ds->avg_write_time); if (is_disk) { disk_submit (output_name, "disk_merged", read_merged, write_merged); submit_in_progress (output_name, in_progress); submit_io_time (output_name, io_time, weighted_time); } /* if (is_disk) */ #if HAVE_LIBUDEV /* release udev-based alternate name, if allocated */ sfree (alt_name); #endif } /* while (fgets (buffer, sizeof (buffer), fh) != NULL) */ #if HAVE_LIBUDEV udev_unref(handle_udev); #endif fclose (fh); /* #endif defined(KERNEL_LINUX) */ #elif HAVE_LIBKSTAT # if HAVE_KSTAT_IO_T_WRITES && HAVE_KSTAT_IO_T_NWRITES && HAVE_KSTAT_IO_T_WTIME # define KIO_ROCTETS reads # define KIO_WOCTETS writes # define KIO_ROPS nreads # define KIO_WOPS nwrites # define KIO_RTIME rtime # define KIO_WTIME wtime # elif HAVE_KSTAT_IO_T_NWRITTEN && HAVE_KSTAT_IO_T_WRITES && HAVE_KSTAT_IO_T_WTIME # define KIO_ROCTETS nread # define KIO_WOCTETS nwritten # define KIO_ROPS reads # define KIO_WOPS writes # define KIO_RTIME rtime # define KIO_WTIME wtime # else # error "kstat_io_t does not have the required members" # endif static kstat_io_t kio; int i; if (kc == NULL) return (-1); for (i = 0; i < numdisk; i++) { if (kstat_read (kc, ksp[i], &kio) == -1) continue; if (strncmp (ksp[i]->ks_class, "disk", 4) == 0) { disk_submit (ksp[i]->ks_name, "disk_octets", kio.KIO_ROCTETS, kio.KIO_WOCTETS); disk_submit (ksp[i]->ks_name, "disk_ops", kio.KIO_ROPS, kio.KIO_WOPS); /* FIXME: Convert this to microseconds if necessary */ disk_submit (ksp[i]->ks_name, "disk_time", kio.KIO_RTIME, kio.KIO_WTIME); } else if (strncmp (ksp[i]->ks_class, "partition", 9) == 0) { disk_submit (ksp[i]->ks_name, "disk_octets", kio.KIO_ROCTETS, kio.KIO_WOCTETS); disk_submit (ksp[i]->ks_name, "disk_ops", kio.KIO_ROPS, kio.KIO_WOPS); } } /* #endif defined(HAVE_LIBKSTAT) */ #elif defined(HAVE_LIBSTATGRAB) sg_disk_io_stats *ds; # if HAVE_LIBSTATGRAB_0_90 size_t disks; # else int disks; #endif int counter; char name[DATA_MAX_NAME_LEN]; if ((ds = sg_get_disk_io_stats(&disks)) == NULL) return (0); for (counter=0; counter < disks; counter++) { strncpy(name, ds->disk_name, sizeof(name)); name[sizeof(name)-1] = '\0'; /* strncpy doesn't terminate longer strings */ disk_submit (name, "disk_octets", ds->read_bytes, ds->write_bytes); ds++; } /* #endif defined(HAVE_LIBSTATGRAB) */ #elif defined(HAVE_PERFSTAT) derive_t read_sectors; derive_t write_sectors; derive_t read_time; derive_t write_time; derive_t read_ops; derive_t write_ops; perfstat_id_t firstpath; int rnumdisk; int i; if ((numdisk = perfstat_disk(NULL, NULL, sizeof(perfstat_disk_t), 0)) < 0) { char errbuf[1024]; WARNING ("disk plugin: perfstat_disk: %s", sstrerror (errno, errbuf, sizeof (errbuf))); return (-1); } if (numdisk != pnumdisk || stat_disk==NULL) { if (stat_disk!=NULL) free(stat_disk); stat_disk = (perfstat_disk_t *)calloc(numdisk, sizeof(perfstat_disk_t)); } pnumdisk = numdisk; firstpath.name[0]='\0'; if ((rnumdisk = perfstat_disk(&firstpath, stat_disk, sizeof(perfstat_disk_t), numdisk)) < 0) { char errbuf[1024]; WARNING ("disk plugin: perfstat_disk : %s", sstrerror (errno, errbuf, sizeof (errbuf))); return (-1); } for (i = 0; i < rnumdisk; i++) { read_sectors = stat_disk[i].rblks*stat_disk[i].bsize; write_sectors = stat_disk[i].wblks*stat_disk[i].bsize; disk_submit (stat_disk[i].name, "disk_octets", read_sectors, write_sectors); read_ops = stat_disk[i].xrate; write_ops = stat_disk[i].xfers - stat_disk[i].xrate; disk_submit (stat_disk[i].name, "disk_ops", read_ops, write_ops); read_time = stat_disk[i].rserv; read_time *= ((double)(_system_configuration.Xint)/(double)(_system_configuration.Xfrac)) / 1000000.0; write_time = stat_disk[i].wserv; write_time *= ((double)(_system_configuration.Xint)/(double)(_system_configuration.Xfrac)) / 1000000.0; disk_submit (stat_disk[i].name, "disk_time", read_time, write_time); } /* #endif defined(HAVE_PERFSTAT) */ #elif HAVE_SYSCTL && KERNEL_NETBSD int mib[3]; size_t size, i, nndrive; diskstats_t *ds, *pre_ds; char *output_name; u_int64_t ops; u_int64_t delta_t; /* figure out number of drives */ mib[0] = CTL_HW; mib[1] = HW_IOSTATS; mib[2] = sizeof(struct io_sysctl); if (sysctl(mib, 3, NULL, &size, NULL, 0) == -1) { ERROR ("disk plugin: sysctl for ndrives failed"); return -1; } nndrive = size / sizeof(struct io_sysctl); if (size == 0 ) { ERROR ("disk plugin: no drives found"); return -1; } /* number of drives changed, reallocate buffer */ if (nndrive != ndrive) { drives = (struct io_sysctl *)realloc(drives, size); if (drives == NULL) { ERROR ("disk plugin: memory allocation failure"); return -1; } ndrive = nndrive; } /* get stats for all drives */ mib[0] = CTL_HW; mib[1] = HW_IOSTATS; mib[2] = sizeof(struct io_sysctl); if (sysctl(mib, 3, drives, &size, NULL, 0) == -1) { ERROR ("disk plugin: sysctl for drive stats failed"); return -1; } for (i = 0; i < ndrive; i++) { if (drives[i].type != IOSTAT_DISK) continue; /* find drive stats, if present */ for (ds = disklist, pre_ds = disklist; ds != NULL; pre_ds = ds, ds = ds->next) { if (strcmp (drives[i].name, ds->name) == 0) break; } if (ds == NULL) { /* not found; allocate & link in */ if ((ds = calloc(1, sizeof(diskstats_t))) == NULL) continue; if ((ds->name = strdup(drives[i].name)) == NULL) { free(ds); continue; } if (pre_ds == NULL) disklist = ds; else pre_ds->next = ds; } ds->poll_count++; if (ds->poll_count <= 2) { DEBUG ("disk plugin: (ds->poll_count = %i) <= " "(min_poll_count = 2); => Not writing.", ds->poll_count); ds->stats = drives[i]; /* but save base values */ continue; } ds->read_ops = drives[i].rxfer - ds->stats.rxfer; ds->write_ops = drives[i].wxfer - ds->stats.wxfer; ds->read_bytes = drives[i].rbytes - ds->stats.rbytes; ds->write_bytes = drives[i].wbytes - ds->stats.wbytes; /* Need this dance because of unsigned values... */ if (drives[i].time_usec < ds->stats.time_usec) { delta_t = ((drives[i].time_sec - 1 - ds->stats.time_sec) * 1000) + ((drives[i].time_usec + 1000000 - ds->stats.time_usec) / 1000); } else { delta_t = ((drives[i].time_sec - ds->stats.time_sec) * 1000) + ((drives[i].time_usec - ds->stats.time_usec) / 1000); } ops = ds->read_ops + ds->write_ops; if (ops == 0) { DEBUG ("disk plugin: read + write ops == 0, " "not writing"); continue; } ds->avg_io_time = delta_t / ops; output_name = drives[i].name; if ((ds->read_bytes != 0) || (ds->write_bytes != 0)) disk_submit (output_name, "disk_octets", ds->read_bytes, ds->write_bytes); if ((ds->read_ops != 0) || (ds->write_ops != 0)) disk_submit (output_name, "disk_ops", ds->read_ops, ds->write_ops); if (ds->avg_io_time != 0) disk_submit (output_name, "disk_time", ds->avg_io_time, ds->avg_io_time); ds->stats = drives[i]; } #endif /* HAVE_SYSCTL && KERNEL_NETBSD */ return (0); } /* int disk_read */
/** @brief detect devices based on usb pid / vid. * @return list with usb VID / PID values. */ QMap<uint32_t, QString> System::listUsbDevices(void) { QMap<uint32_t, QString> usbids; // usb pid detection LOG_INFO() << "Searching for USB devices"; #if defined(Q_OS_LINUX) #if defined(LIBUSB1) libusb_device **devs; if(libusb_init(NULL) != 0) { LOG_ERROR() << "Initializing libusb-1 failed."; return usbids; } if(libusb_get_device_list(NULL, &devs) < 1) { LOG_ERROR() << "Error getting device list."; return usbids; } libusb_device *dev; int i = 0; while((dev = devs[i++]) != NULL) { QString name; unsigned char buf[256]; uint32_t id; struct libusb_device_descriptor descriptor; if(libusb_get_device_descriptor(dev, &descriptor) == 0) { id = descriptor.idVendor << 16 | descriptor.idProduct; libusb_device_handle *dh; if(libusb_open(dev, &dh) == 0) { libusb_get_string_descriptor_ascii(dh, descriptor.iManufacturer, buf, 256); name += QString::fromLatin1((char*)buf) + " "; libusb_get_string_descriptor_ascii(dh, descriptor.iProduct, buf, 256); name += QString::fromLatin1((char*)buf); libusb_close(dh); } if(name.isEmpty()) name = tr("(no description available)"); if(id) { usbids.insertMulti(id, name); LOG_INFO("USB: 0x%08x, %s", id, name.toLocal8Bit().data()); } } } libusb_free_device_list(devs, 1); libusb_exit(NULL); #else usb_init(); usb_find_busses(); usb_find_devices(); struct usb_bus *b; b = usb_busses; while(b) { if(b->devices) { struct usb_device *u; u = b->devices; while(u) { uint32_t id; id = u->descriptor.idVendor << 16 | u->descriptor.idProduct; // get identification strings usb_dev_handle *dev; QString name; char string[256]; int res; dev = usb_open(u); if(dev) { if(u->descriptor.iManufacturer) { res = usb_get_string_simple(dev, u->descriptor.iManufacturer, string, sizeof(string)); if(res > 0) name += QString::fromLatin1(string) + " "; } if(u->descriptor.iProduct) { res = usb_get_string_simple(dev, u->descriptor.iProduct, string, sizeof(string)); if(res > 0) name += QString::fromLatin1(string); } usb_close(dev); } if(name.isEmpty()) name = tr("(no description available)"); if(id) { usbids.insertMulti(id, name); LOG_INFO() << "USB:" << QString("0x%1").arg(id, 8, 16) << name; } u = u->next; } } b = b->next; } #endif #endif #if defined(Q_OS_MACX) kern_return_t result = KERN_FAILURE; CFMutableDictionaryRef usb_matching_dictionary; io_iterator_t usb_iterator = IO_OBJECT_NULL; usb_matching_dictionary = IOServiceMatching(kIOUSBDeviceClassName); result = IOServiceGetMatchingServices(kIOMasterPortDefault, usb_matching_dictionary, &usb_iterator); if(result) { LOG_ERROR() << "USB: IOKit: Could not get matching services."; return usbids; } io_object_t usbCurrentObj; while((usbCurrentObj = IOIteratorNext(usb_iterator))) { uint32_t id; QString name; /* get vendor ID */ CFTypeRef vidref = NULL; int vid = 0; vidref = IORegistryEntryCreateCFProperty(usbCurrentObj, CFSTR("idVendor"), kCFAllocatorDefault, 0); CFNumberGetValue((CFNumberRef)vidref, kCFNumberIntType, &vid); CFRelease(vidref); /* get product ID */ CFTypeRef pidref = NULL; int pid = 0; pidref = IORegistryEntryCreateCFProperty(usbCurrentObj, CFSTR("idProduct"), kCFAllocatorDefault, 0); CFNumberGetValue((CFNumberRef)pidref, kCFNumberIntType, &pid); CFRelease(pidref); id = vid << 16 | pid; /* get product vendor */ char vendor_buf[256]; CFIndex vendor_buflen = 256; CFTypeRef vendor_name_ref = NULL; vendor_name_ref = IORegistryEntrySearchCFProperty(usbCurrentObj, kIOServicePlane, CFSTR("USB Vendor Name"), kCFAllocatorDefault, 0); if(vendor_name_ref != NULL) { CFStringGetCString((CFStringRef)vendor_name_ref, vendor_buf, vendor_buflen, kCFStringEncodingUTF8); name += QString::fromUtf8(vendor_buf) + " "; CFRelease(vendor_name_ref); } else { name += QObject::tr("(unknown vendor name) "); } /* get product name */ char product_buf[256]; CFIndex product_buflen = 256; CFTypeRef product_name_ref = NULL; product_name_ref = IORegistryEntrySearchCFProperty(usbCurrentObj, kIOServicePlane, CFSTR("USB Product Name"), kCFAllocatorDefault, 0); if(product_name_ref != NULL) { CFStringGetCString((CFStringRef)product_name_ref, product_buf, product_buflen, kCFStringEncodingUTF8); name += QString::fromUtf8(product_buf); CFRelease(product_name_ref); } else { name += QObject::tr("(unknown product name)"); } if(id) { usbids.insertMulti(id, name); LOG_INFO() << "USB:" << QString("0x%1").arg(id, 8, 16) << name; } } IOObjectRelease(usb_iterator); #endif #if defined(Q_OS_WIN32) HDEVINFO deviceInfo; SP_DEVINFO_DATA infoData; DWORD i; // Iterate over all devices // by doing it this way it's unneccessary to use GUIDs which might be not // present in current MinGW. It also seemed to be more reliably than using // a GUID. // See KB259695 for an example. deviceInfo = SetupDiGetClassDevs(NULL, NULL, NULL, DIGCF_ALLCLASSES | DIGCF_PRESENT); infoData.cbSize = sizeof(SP_DEVINFO_DATA); for(i = 0; SetupDiEnumDeviceInfo(deviceInfo, i, &infoData); i++) { DWORD data; LPTSTR buffer = NULL; DWORD buffersize = 0; QString description; // get device desriptor first // for some reason not doing so results in bad things (tm) while(!SetupDiGetDeviceRegistryProperty(deviceInfo, &infoData, SPDRP_DEVICEDESC, &data, (PBYTE)buffer, buffersize, &buffersize)) { if(GetLastError() == ERROR_INSUFFICIENT_BUFFER) { if(buffer) free(buffer); // double buffer size to avoid problems as per KB888609 buffer = (LPTSTR)malloc(buffersize * 2); } else { break; } } description = QString::fromWCharArray(buffer); // now get the hardware id, which contains PID and VID. while(!SetupDiGetDeviceRegistryProperty(deviceInfo, &infoData, SPDRP_HARDWAREID, &data, (PBYTE)buffer, buffersize, &buffersize)) { if(GetLastError() == ERROR_INSUFFICIENT_BUFFER) { if(buffer) free(buffer); // double buffer size to avoid problems as per KB888609 buffer = (LPTSTR)malloc(buffersize * 2); } else { break; } } unsigned int vid, pid; // convert buffer text to upper case to avoid depending on the case of // the keys (W7 uses different casing than XP at least). int len = _tcslen(buffer); while(len--) buffer[len] = _totupper(buffer[len]); if(_stscanf(buffer, _TEXT("USB\\VID_%x&PID_%x"), &vid, &pid) == 2) { uint32_t id; id = vid << 16 | pid; usbids.insert(id, description); LOG_INFO("USB VID: %04x, PID: %04x", vid, pid); } if(buffer) free(buffer); } SetupDiDestroyDeviceInfoList(deviceInfo); #endif return usbids; }
/////////////////////////////////////////////////////////////////////// // Destructor /////////////////////////////////////////////////////////////////////// IOKitDevice::~IOKitDevice() { //Need to release objects if (hSavedService) IOObjectRelease(hSavedService); }
int main(int argc, char *argv[]) { io_connect_t manager_connect = IO_OBJECT_NULL; io_connect_t manager[kMaxSimultaneousConnections]; uint32_t openfailure = 0; uint32_t closefailure = 0; uint32_t ucOpenedCount = 0; uint32_t ucExclusiveOpenedCount = 0; IOReturn connectreturn = 0; kern_return_t kernreturn = 0; CFAbsoluteTime start_time = 0.0; CFAbsoluteTime end_time = 0.0; CFTimeInterval elapsed_time = 0.0; io_registry_entry_t IOREG_SmartBattery = IO_OBJECT_NULL; int simultaneousCount = 0; PMTestInitialize("SmartBatteryUserClient repetition test", "com.apple.iokit.smartbattery.repeater"); /* * Make sure we can open a few simultaneous user clients */ for(simultaneousCount=0; simultaneousCount < kMaxSimultaneousConnections; simultaneousCount++) { manager[simultaneousCount] = connectSmartBatteryManager(0, &connectreturn); if (kIOReturnSuccess != connectreturn) { manager[simultaneousCount] = 0; PMTestFail("Failed to open non-exclusive user client #%d of %d. Status = 0x%08x", simultaneousCount, kMaxSimultaneousConnections, connectreturn); } else { PMTestPass("Opened non-exclusive user client depth %d", simultaneousCount); } } IOREG_SmartBattery = IOServiceGetMatchingService( MACH_PORT_NULL, IOServiceNameMatching(kBatteryManagerName) ); if (IO_OBJECT_NULL == IOREG_SmartBattery) { PMTestLog("This machine does not support batteries. Skipping battery tests."); exit(0); } IOObjectRelease(IOREG_SmartBattery); for (simultaneousCount = kMaxSimultaneousConnections-1; simultaneousCount >= 0; simultaneousCount--) { if (!manager[simultaneousCount]) { PMTestLog("ODDITY: Trying to close connection %d - but NULL connection ID", simultaneousCount); continue; } connectreturn = IOServiceClose(manager[simultaneousCount]); if (kIOReturnSuccess != connectreturn) { PMTestFail("Failed to CLOSE non-exclusive user client #%d of %d. Status = 0x%08x", simultaneousCount, kMaxSimultaneousConnections, connectreturn); } else { PMTestPass("Closed user client at depth %d", simultaneousCount); } } while ( (ucOpenedCount < kUCIterationsCount) && (ucExclusiveOpenedCount < kUCExclusiveIterationsCount)) { /* * Regular user client */ if (ucOpenedCount < kUCIterationsCount) { /* OPEN REGULAR */ start_time = CFAbsoluteTimeGetCurrent(); manager_connect = connectSmartBatteryManager(0, &connectreturn); if (MACH_PORT_NULL == manager_connect) { PMTestFail("IOServiceOpen error 0x%08x opening %s", connectreturn, kBatteryManagerName); openfailure++; } else { end_time = CFAbsoluteTimeGetCurrent(); elapsed_time = end_time - start_time; PMTestPass("User client opened successfully in %d.%02d seconds", (int)elapsed_time, (int)(100.0 * elapsed_time)%100); if (elapsed_time > kMaxSecondsUCOperation) { PMTestFail("Error - opening user client took %d.%02d, exceeding %d.%02d", (int)elapsed_time, (int)(100.0 * elapsed_time)%100, (int)kMaxSecondsUCOperation, (int)(100.0*kMaxSecondsUCOperation)%100); } /* CLOSE REGULAR */ start_time = CFAbsoluteTimeGetCurrent(); kernreturn = IOServiceClose(manager_connect); if (KERN_SUCCESS != kernreturn) { PMTestFail("IOServiceClose error %d closing user client.", kernreturn); closefailure++; } else { end_time = CFAbsoluteTimeGetCurrent(); elapsed_time = end_time - start_time; PMTestPass("User client closed successfully in %d.%02d seconds", (int)elapsed_time, (int)(100.0 * elapsed_time)%100); if (elapsed_time > kMaxSecondsUCOperation) { PMTestFail("Error - closing user client took %d.%02d, exceeding %d.%02d", (int)elapsed_time, (int)(100.0 * elapsed_time)%100, (int)kMaxSecondsUCOperation, (int)(100.0*kMaxSecondsUCOperation)%100); } } } ucOpenedCount++; } /* * Exclusive */ if (ucExclusiveOpenedCount < kUCExclusiveIterationsCount) { /* OPEN EXCLUSIVE */ start_time = CFAbsoluteTimeGetCurrent(); manager_connect = connectSmartBatteryManager(kBatteryExclusiveAccessType, &connectreturn); if (MACH_PORT_NULL == manager_connect) { //PMTestFail PMTestLog("IOServiceOpen error 0x%08x opening exclusive %s (This test requires root privileges; this may be a failure)", connectreturn, kBatteryManagerName); openfailure++; } else { end_time = CFAbsoluteTimeGetCurrent(); elapsed_time = end_time - start_time; PMTestPass("User client EXCLUSIVE opened successfully in %d.%02d seconds", (int)elapsed_time, (int)(100.0 * elapsed_time)%100); if (elapsed_time > kMaxSecondsUCOperation) { PMTestFail("Error - opening EXCLUSIVE user client took %d.%02d, exceeding %d.%02d", (int)elapsed_time, (int)(100.0 * elapsed_time)%100, (int)kMaxSecondsUCOperation, (int)(100.0*kMaxSecondsUCOperation)%100); } /* CLOSE EXCLUSIVE */ start_time = CFAbsoluteTimeGetCurrent(); kernreturn = IOServiceClose(manager_connect); if (KERN_SUCCESS != kernreturn) { PMTestFail("IOServiceClose error %d closing user client.", kernreturn); closefailure++; } else { end_time = CFAbsoluteTimeGetCurrent(); elapsed_time = end_time - start_time; PMTestPass("User client EXCLUSIVE closed successfully in %d.%02d seconds", (int)elapsed_time, (int)(100.0 * elapsed_time)%100); if (elapsed_time > kMaxSecondsUCOperation) { PMTestFail("Error - closing EXCLUSIVE user client took %d.%02d, exceeding %d.%02d", (int)elapsed_time, (int)(100.0 * elapsed_time)%100, (int)kMaxSecondsUCOperation, (int)(100.0*kMaxSecondsUCOperation)%100); } } } ucExclusiveOpenedCount++; } } PMTestLog("SmartBatteryUserClient test completed: opened %d clients and %d exclusive clients", ucOpenedCount, ucExclusiveOpenedCount); if (openfailure == 0 && closefailure == 0) { PMTestLog("Success."); } else { if (openfailure) { PMTestLog("Test completed with %d failures opening the user client.", openfailure); } if (closefailure) { PMTestLog("Test completed with %d failures closing the user client.", closefailure); } } PMTestLog("The test is over."); return 0; }
static void HIDGetDeviceInfo(io_object_t hidDevice, CFMutableDictionaryRef hidProperties, recDevice * pDevice) { CFMutableDictionaryRef usbProperties = 0; io_registry_entry_t parent1, parent2; /* Mac OS X currently is not mirroring all USB properties to HID page so need to look at USB device page also * get dictionary for usb properties: step up two levels and get CF dictionary for USB properties */ if ((KERN_SUCCESS == IORegistryEntryGetParentEntry(hidDevice, kIOServicePlane, &parent1)) && (KERN_SUCCESS == IORegistryEntryGetParentEntry(parent1, kIOServicePlane, &parent2)) && (KERN_SUCCESS == IORegistryEntryCreateCFProperties(parent2, &usbProperties, kCFAllocatorDefault, kNilOptions))) { if (usbProperties) { CFTypeRef refCF = 0; /* get device info * try hid dictionary first, if fail then go to usb dictionary */ /* get product name */ refCF = CFDictionaryGetValue(hidProperties, CFSTR(kIOHIDProductKey)); if (!refCF) refCF = CFDictionaryGetValue(usbProperties, CFSTR("USB Product Name")); if (refCF) { if (!CFStringGetCString (refCF, pDevice->product, 256, CFStringGetSystemEncoding())) SDL_SetError ("CFStringGetCString error retrieving pDevice->product."); } /* get usage page and usage */ refCF = CFDictionaryGetValue(hidProperties, CFSTR(kIOHIDPrimaryUsagePageKey)); if (refCF) { if (!CFNumberGetValue (refCF, kCFNumberLongType, &pDevice->usagePage)) SDL_SetError ("CFNumberGetValue error retrieving pDevice->usagePage."); refCF = CFDictionaryGetValue(hidProperties, CFSTR(kIOHIDPrimaryUsageKey)); if (refCF) if (!CFNumberGetValue (refCF, kCFNumberLongType, &pDevice->usage)) SDL_SetError ("CFNumberGetValue error retrieving pDevice->usage."); } if (NULL == refCF) { /* get top level element HID usage page or usage */ /* use top level element instead */ CFTypeRef refCFTopElement = 0; refCFTopElement = CFDictionaryGetValue(hidProperties, CFSTR(kIOHIDElementKey)); { /* refCFTopElement points to an array of element dictionaries */ CFRange range = { 0, CFArrayGetCount(refCFTopElement) }; CFArrayApplyFunction(refCFTopElement, range, HIDTopLevelElementHandler, pDevice); } } CFRelease(usbProperties); } else SDL_SetError ("IORegistryEntryCreateCFProperties failed to create usbProperties."); if (kIOReturnSuccess != IOObjectRelease(parent2)) SDL_SetError("IOObjectRelease error with parent2."); if (kIOReturnSuccess != IOObjectRelease(parent1)) SDL_SetError("IOObjectRelease error with parent1."); } }
void DarwinAddFloppyPrefs(void) { mach_port_t masterPort; // The way to talk to the kernel io_iterator_t allFloppies; // List of possible floppys CFMutableDictionaryRef classesToMatch; io_object_t nextFloppy; if ( IOMasterPort(MACH_PORT_NULL, &masterPort) != KERN_SUCCESS ) bug("IOMasterPort failed. Won't be able to do anything with floppy drives\n"); // This selects all partitions of all disks classesToMatch = IOServiceMatching(kIOMediaClass); if ( classesToMatch ) { // Skip drivers and partitions CFDictionarySetValue(classesToMatch, CFSTR(kIOMediaWholeKey), kCFBooleanTrue); // Skip fixed drives (hard disks?) CFDictionarySetValue(classesToMatch, CFSTR(kIOMediaEjectableKey), kCFBooleanTrue); } if ( IOServiceGetMatchingServices(masterPort, classesToMatch, &allFloppies) != KERN_SUCCESS ) { D(bug("IOServiceGetMatchingServices failed. No removable drives found?\n")); return; } // Iterate through each floppy while ( nextFloppy = IOIteratorNext(allFloppies)) { char bsdPath[MAXPATHLEN]; long size; CFTypeRef sizeAsCFNumber = IORegistryEntryCreateCFProperty(nextFloppy, CFSTR(kIOMediaSizeKey), kCFAllocatorDefault, 0); if ( CFNumberGetValue((CFNumberRef)sizeAsCFNumber, kCFNumberSInt32Type, &size) ) { D(bug("Got size of %ld\n", size)); if ( size < 800 * 1024 || size > 1440 * 1024 ) { D(puts("Device does not appear to be 800k or 1440k")); continue; } } else { D(puts("Couldn't get kIOMediaSizeKey of device")); continue; // if kIOMediaSizeKey is unavailable, we shouldn't use it anyway } if (get_device_path(nextFloppy, bsdPath, sizeof(bsdPath)) == KERN_SUCCESS) { PrefsAddString("floppy", bsdPath); } else { D(bug("Could not get BSD device path for floppy\n")); } } IOObjectRelease(nextFloppy); IOObjectRelease(allFloppies); }
/* Function to scan the system for joysticks. * Joystick 0 should be the system default joystick. * This function should return the number of available joysticks, or -1 * on an unrecoverable fatal error. */ int SDL_SYS_JoystickInit(void) { IOReturn result = kIOReturnSuccess; mach_port_t masterPort = 0; io_iterator_t hidObjectIterator = 0; CFMutableDictionaryRef hidMatchDictionary = NULL; recDevice *device, *lastDevice; io_object_t ioHIDDeviceObject = 0; SDL_numjoysticks = 0; if (gpDeviceList) { SDL_SetError("Joystick: Device list already inited."); return -1; } result = IOMasterPort(bootstrap_port, &masterPort); if (kIOReturnSuccess != result) { SDL_SetError("Joystick: IOMasterPort error with bootstrap_port."); return -1; } /* Set up a matching dictionary to search I/O Registry by class name for all HID class devices. */ hidMatchDictionary = IOServiceMatching(kIOHIDDeviceKey); if (hidMatchDictionary) { /* Add key for device type (joystick, in this case) to refine the matching dictionary. */ /* NOTE: we now perform this filtering later UInt32 usagePage = kHIDPage_GenericDesktop; UInt32 usage = kHIDUsage_GD_Joystick; CFNumberRef refUsage = NULL, refUsagePage = NULL; refUsage = CFNumberCreate (kCFAllocatorDefault, kCFNumberIntType, &usage); CFDictionarySetValue (hidMatchDictionary, CFSTR (kIOHIDPrimaryUsageKey), refUsage); refUsagePage = CFNumberCreate (kCFAllocatorDefault, kCFNumberIntType, &usagePage); CFDictionarySetValue (hidMatchDictionary, CFSTR (kIOHIDPrimaryUsagePageKey), refUsagePage); */ } else { SDL_SetError ("Joystick: Failed to get HID CFMutableDictionaryRef via IOServiceMatching."); return -1; } /*/ Now search I/O Registry for matching devices. */ result = IOServiceGetMatchingServices(masterPort, hidMatchDictionary, &hidObjectIterator); /* Check for errors */ if (kIOReturnSuccess != result) { SDL_SetError("Joystick: Couldn't create a HID object iterator."); return -1; } if (!hidObjectIterator) { /* there are no joysticks */ gpDeviceList = NULL; SDL_numjoysticks = 0; return 0; } /* IOServiceGetMatchingServices consumes a reference to the dictionary, so we don't need to release the dictionary ref. */ /* build flat linked list of devices from device iterator */ gpDeviceList = lastDevice = NULL; while ((ioHIDDeviceObject = IOIteratorNext(hidObjectIterator))) { /* build a device record */ device = HIDBuildDevice(ioHIDDeviceObject); if (!device) continue; /* Filter device list to non-keyboard/mouse stuff */ if ((device->usagePage != kHIDPage_GenericDesktop) || ((device->usage != kHIDUsage_GD_Joystick && device->usage != kHIDUsage_GD_GamePad && device->usage != kHIDUsage_GD_MultiAxisController))) { /* release memory for the device */ HIDDisposeDevice(&device); DisposePtr((Ptr) device); continue; } /* We have to do some storage of the io_service_t for * SDL_HapticOpenFromJoystick */ if (FFIsForceFeedback(ioHIDDeviceObject) == FF_OK) { device->ffservice = ioHIDDeviceObject; } else { device->ffservice = 0; } /* Add device to the end of the list */ if (lastDevice) lastDevice->pNext = device; else gpDeviceList = device; lastDevice = device; } result = IOObjectRelease(hidObjectIterator); /* release the iterator */ /* Count the total number of devices we found */ device = gpDeviceList; while (device) { SDL_numjoysticks++; device = device->pNext; } return SDL_numjoysticks; }
int manipulate_led(UInt32 whichLED, UInt32 value) { io_service_t hidService = (io_service_t)0; io_object_t hidDevice = (io_object_t)0; IOHIDDeviceInterface **hidDeviceInterface = NULL; IOReturn ioReturnValue = kIOReturnError; IOHIDElementCookie theCookie = (IOHIDElementCookie)0; IOHIDEventStruct theEvent; if (!(hidService = find_a_keyboard())) { //fprintf(stderr, "No keyboard found.\n"); return ioReturnValue; } hidDevice = (io_object_t)hidService; create_hid_interface(hidDevice, &hidDeviceInterface); find_led_cookies((IOHIDDeviceInterface122 **)hidDeviceInterface); ioReturnValue = IOObjectRelease(hidDevice); if (ioReturnValue != kIOReturnSuccess) { goto out; } ioReturnValue = kIOReturnError; if (hidDeviceInterface == NULL) { //fprintf(stderr, "Failed to create HID device interface.\n"); return ioReturnValue; } if (whichLED == kHIDUsage_LED_NumLock) { theCookie = numlock_cookie; } else if (whichLED == kHIDUsage_LED_CapsLock) { theCookie = capslock_cookie; } if (theCookie == 0) { ////fprintf(stderr, "Bad or missing LED cookie.\n"); goto out; } ioReturnValue = (*hidDeviceInterface)->open(hidDeviceInterface, 0); if (ioReturnValue != kIOReturnSuccess) { //fprintf(stderr, "Failed to open HID device interface.\n"); goto out; } ioReturnValue = (*hidDeviceInterface)->getElementValue(hidDeviceInterface, theCookie, &theEvent); if (ioReturnValue != kIOReturnSuccess) { (void)(*hidDeviceInterface)->close(hidDeviceInterface); goto out; } if (value != -1) { if (theEvent.value != value) { theEvent.value = value; ioReturnValue = (*hidDeviceInterface)->setElementValue( hidDeviceInterface, theCookie, &theEvent, 0, 0, 0, 0); if (ioReturnValue == kIOReturnSuccess) { //fprintf(stdout, "%s\n", (theEvent.value) ? "on" : "off"); } } } ioReturnValue = (*hidDeviceInterface)->close(hidDeviceInterface); out: (void)(*hidDeviceInterface)->Release(hidDeviceInterface); return ioReturnValue; }
void SerialPortLister::ListPorts(std::vector<std::string> &availablePorts) { #ifdef WIN32 availablePorts.clear(); std::auto_ptr<B100000> allDeviceNames (new B100000()); // on Windows the serial ports are devices that begin with "COM" int ret = QueryDosDevice( 0, allDeviceNames->buffer, MaxBuf); if( 0!= ret) { for( int ii = 0; ii < ret; ++ii) { if ( 0 == allDeviceNames->buffer[ii]) allDeviceNames->buffer[ii] = ' '; } std::string all(allDeviceNames->buffer, ret); std::vector<std::string> tokens; CDeviceUtils::Tokenize(all, tokens, " "); for( std::vector<std::string>::iterator jj = tokens.begin(); jj != tokens.end(); ++jj) { if( 0 == jj->substr(0,3).compare("COM")) availablePorts.push_back(*jj); } } #endif // WIN32 #ifdef linux // Look for /dev files with correct signature DIR* pdir = opendir("/dev"); struct dirent *pent; if (pdir) { while (pent = readdir(pdir)) { if ( (strstr(pent->d_name, "ttyS") != 0) || (strstr(pent->d_name, "ttyUSB") != 0) || (strstr(pent->d_name, "ttyACM") != 0)) { std::string p = ("/dev/"); p.append(pent->d_name); if (portAccessible(p.c_str())) availablePorts.push_back(p.c_str()); } } } #endif // linux #ifdef __APPLE__ // port discovery code for Darwin/Mac OS X // Derived from Apple's examples at: http://developer.apple.com/samplecode/SerialPortSample/SerialPortSample.html io_iterator_t serialPortIterator; char bsdPath[256]; kern_return_t kernResult; CFMutableDictionaryRef classesToMatch; // Serial devices are instances of class IOSerialBSDClient classesToMatch = IOServiceMatching(kIOSerialBSDServiceValue); if (classesToMatch == NULL) { printf("IOServiceMatching returned a NULL dictionary.\n"); } else { CFDictionarySetValue(classesToMatch, CFSTR(kIOSerialBSDTypeKey), CFSTR(kIOSerialBSDAllTypes)); } kernResult = IOServiceGetMatchingServices(kIOMasterPortDefault, classesToMatch, &serialPortIterator); if (KERN_SUCCESS != kernResult) { printf("IOServiceGetMatchingServices returned %d\n", kernResult); } // Given an iterator across a set of modems, return the BSD path to the first one. // If no modems are found the path name is set to an empty string. io_object_t modemService; // Initialize the returned path *bsdPath = '\0'; // Iterate across all modems found. while ( (modemService = IOIteratorNext(serialPortIterator)) ) { CFTypeRef bsdPathAsCFString; // Get the device's path (/dev/tty.xxxxx). bsdPathAsCFString = IORegistryEntryCreateCFProperty(modemService, CFSTR(kIODialinDeviceKey), kCFAllocatorDefault, 0); if (bsdPathAsCFString) { Boolean result; // Convert the path from a CFString to a C (NUL-terminated) string for use // with the POSIX open() call. result = CFStringGetCString( (const __CFString*) bsdPathAsCFString, bsdPath, sizeof(bsdPath), kCFStringEncodingUTF8); CFRelease(bsdPathAsCFString); // add the name to our vector<string> only when this is not a dialup port std::string rresult (bsdPath); std::string::size_type loc = rresult.find("DialupNetwork", 0); if (result && (loc == std::string::npos)) { bool blackListed = false; std::vector<std::string>::iterator it = g_BlackListedPorts.begin(); while (it < g_BlackListedPorts.end()) { if( bsdPath == (*it)) blackListed = true; } if (portAccessible(bsdPath) && ! blackListed) { availablePorts.push_back(bsdPath); } kernResult = KERN_SUCCESS; } } } // Release the io_service_t now that we are done with it. (void) IOObjectRelease(modemService); #endif // __APPLE }
static void get_via_generic_iokit (double *ret_capacity_full, /* {{{ */ double *ret_capacity_design, double *ret_current, double *ret_voltage) { kern_return_t status; io_iterator_t iterator; io_object_t io_obj; CFDictionaryRef bat_root_dict; CFArrayRef bat_info_arry; CFIndex bat_info_arry_len; CFDictionaryRef bat_info_dict; double temp_double; status = IOServiceGetMatchingServices (kIOMasterPortDefault, IOServiceNameMatching ("battery"), &iterator); if (status != kIOReturnSuccess) { DEBUG ("IOServiceGetMatchingServices failed."); return; } while ((io_obj = IOIteratorNext (iterator))) { status = IORegistryEntryCreateCFProperties (io_obj, (CFMutableDictionaryRef *) &bat_root_dict, kCFAllocatorDefault, kNilOptions); if (status != kIOReturnSuccess) { DEBUG ("IORegistryEntryCreateCFProperties failed."); continue; } bat_info_arry = (CFArrayRef) CFDictionaryGetValue (bat_root_dict, CFSTR ("IOBatteryInfo")); if (bat_info_arry == NULL) { CFRelease (bat_root_dict); continue; } bat_info_arry_len = CFArrayGetCount (bat_info_arry); for (CFIndex bat_info_arry_pos = 0; bat_info_arry_pos < bat_info_arry_len; bat_info_arry_pos++) { bat_info_dict = (CFDictionaryRef) CFArrayGetValueAtIndex (bat_info_arry, bat_info_arry_pos); if (isnan (*ret_capacity_full)) { temp_double = dict_get_double (bat_info_dict, "Capacity"); *ret_capacity_full = temp_double / 1000.0; } if (isnan (*ret_capacity_design)) { temp_double = dict_get_double (bat_info_dict, "AbsoluteMaxCapacity"); *ret_capacity_design = temp_double / 1000.0; } if (isnan (*ret_current)) { temp_double = dict_get_double (bat_info_dict, "Current"); *ret_current = temp_double / 1000.0; } if (isnan (*ret_voltage)) { temp_double = dict_get_double (bat_info_dict, "Voltage"); *ret_voltage = temp_double / 1000.0; } } CFRelease (bat_root_dict); } IOObjectRelease (iterator); } /* }}} void get_via_generic_iokit */
static int as_read(void) { kern_return_t status; io_iterator_t iterator; io_object_t io_obj; CFMutableDictionaryRef prop_dict; CFTypeRef property; char type[128]; char inst[128]; int value_int; double value_double; if (!io_master_port || (io_master_port == MACH_PORT_NULL)) return -1; status = IOServiceGetMatchingServices( io_master_port, IOServiceNameMatching("IOHWSensor"), &iterator); if (status != kIOReturnSuccess) { ERROR("IOServiceGetMatchingServices failed: %s", mach_error_string(status)); return -1; } while ((io_obj = IOIteratorNext(iterator))) { prop_dict = NULL; status = IORegistryEntryCreateCFProperties( io_obj, &prop_dict, kCFAllocatorDefault, kNilOptions); if (status != kIOReturnSuccess) { DEBUG("IORegistryEntryCreateCFProperties failed: %s", mach_error_string(status)); continue; } /* Copy the sensor type. */ property = NULL; if (!CFDictionaryGetValueIfPresent(prop_dict, CFSTR("type"), &property)) continue; if (CFGetTypeID(property) != CFStringGetTypeID()) continue; if (!CFStringGetCString(property, type, sizeof(type), kCFStringEncodingASCII)) continue; type[sizeof(type) - 1] = '\0'; /* Copy the sensor location. This will be used as `instance'. */ property = NULL; if (!CFDictionaryGetValueIfPresent(prop_dict, CFSTR("location"), &property)) continue; if (CFGetTypeID(property) != CFStringGetTypeID()) continue; if (!CFStringGetCString(property, inst, sizeof(inst), kCFStringEncodingASCII)) continue; inst[sizeof(inst) - 1] = '\0'; for (int i = 0; i < 128; i++) { if (inst[i] == '\0') break; else if (isalnum(inst[i])) inst[i] = (char)tolower(inst[i]); else inst[i] = '_'; } /* Get the actual value. Some computation, based on the `type' * is neccessary. */ property = NULL; if (!CFDictionaryGetValueIfPresent(prop_dict, CFSTR("current-value"), &property)) continue; if (CFGetTypeID(property) != CFNumberGetTypeID()) continue; if (!CFNumberGetValue(property, kCFNumberIntType, &value_int)) continue; /* Found e.g. in the 1.5GHz PowerBooks */ if (strcmp(type, "temperature") == 0) { value_double = ((double)value_int) / 65536.0; sstrncpy(type, "temperature", sizeof(type)); } else if (strcmp(type, "temp") == 0) { value_double = ((double)value_int) / 10.0; sstrncpy(type, "temperature", sizeof(type)); } else if (strcmp(type, "fanspeed") == 0) { value_double = ((double)value_int) / 65536.0; sstrncpy(type, "fanspeed", sizeof(type)); } else if (strcmp(type, "voltage") == 0) { /* Leave this to the battery plugin. */ continue; } else if (strcmp(type, "adc") == 0) { value_double = ((double)value_int) / 10.0; sstrncpy(type, "fanspeed", sizeof(type)); } else { DEBUG("apple_sensors: Read unknown sensor type: %s", type); value_double = (double)value_int; } as_submit(type, inst, value_double); CFRelease(prop_dict); IOObjectRelease(io_obj); } /* while (iterator) */ IOObjectRelease(iterator); return 0; } /* int as_read */
// Returns a pointer to an array of strings with the device names std::vector<std::string> cdio_get_devices() { io_object_t next_media; mach_port_t master_port; kern_return_t kern_result; io_iterator_t media_iterator; CFMutableDictionaryRef classes_to_match; std::vector<std::string> drives; kern_result = IOMasterPort( MACH_PORT_NULL, &master_port ); if( kern_result != KERN_SUCCESS ) return( drives ); classes_to_match = IOServiceMatching( kIOCDMediaClass ); if( classes_to_match == NULL ) return( drives ); CFDictionarySetValue( classes_to_match, CFSTR(kIOMediaEjectableKey), kCFBooleanTrue ); kern_result = IOServiceGetMatchingServices( master_port, classes_to_match, &media_iterator ); if( kern_result != KERN_SUCCESS) return( drives ); next_media = IOIteratorNext( media_iterator ); if( next_media != 0 ) { char psz_buf[0x32]; size_t dev_path_length; CFTypeRef str_bsd_path; do { str_bsd_path = IORegistryEntryCreateCFProperty( next_media, CFSTR( kIOBSDNameKey ), kCFAllocatorDefault, 0 ); if( str_bsd_path == NULL ) { IOObjectRelease( next_media ); continue; } // Below, by appending 'r' to the BSD node name, we indicate // a raw disk. Raw disks receive I/O requests directly and // don't go through a buffer cache. snprintf( psz_buf, sizeof(psz_buf), "%s%c", _PATH_DEV, 'r' ); dev_path_length = strlen( psz_buf ); if( CFStringGetCString( (CFStringRef)str_bsd_path, (char*)&psz_buf + dev_path_length, sizeof(psz_buf) - dev_path_length, kCFStringEncodingASCII)) { if(psz_buf != NULL) { std::string str = psz_buf; drives.push_back(str); } } CFRelease( str_bsd_path ); IOObjectRelease( next_media ); } while( ( next_media = IOIteratorNext( media_iterator ) ) != 0 ); } IOObjectRelease( media_iterator ); return drives; }
/** Initializes the USB system. Returns 0 on success, -1 on error. */ static int init_usb(ifc_match_func callback, usb_handle **handle) { int ret = -1; CFMutableDictionaryRef matchingDict; kern_return_t result; io_iterator_t iterator; usb_handle h; h.success = 0; h.callback = callback; /* * Create our matching dictionary to find appropriate devices. * IOServiceAddMatchingNotification consumes the reference, so we * do not need to release it. */ matchingDict = IOServiceMatching(kIOUSBDeviceClassName); if (matchingDict == NULL) { ERR("Couldn't create USB matching dictionary.\n"); return -1; } result = IOServiceGetMatchingServices( kIOMasterPortDefault, matchingDict, &iterator); if (result != 0) { ERR("Could not create iterator."); return -1; } for (;;) { if (! IOIteratorIsValid(iterator)) { /* * Apple documentation advises resetting the iterator if * it should become invalid during iteration. */ IOIteratorReset(iterator); continue; } io_service_t device = IOIteratorNext(iterator); if (device == 0) { break; } if (try_device(device, &h) != 0) { IOObjectRelease(device); ret = -1; break; } if (h.success) { *handle = calloc(1, sizeof(usb_handle)); memcpy(*handle, &h, sizeof(usb_handle)); ret = 0; break; } IOObjectRelease(device); } IOObjectRelease(iterator); return ret; }
/** * Implementation of VbglR3Init and VbglR3InitUser */ static int vbglR3Init(const char *pszDeviceName) { uint32_t cInits = ASMAtomicIncU32(&g_cInits); Assert(cInits > 0); if (cInits > 1) { /* * This will fail if two (or more) threads race each other calling VbglR3Init. * However it will work fine for single threaded or otherwise serialized * processed calling us more than once. */ #ifdef RT_OS_WINDOWS if (g_hFile == INVALID_HANDLE_VALUE) #elif !defined (VBOX_VBGLR3_XSERVER) if (g_File == NIL_RTFILE) #else if (g_File == -1) #endif return VERR_INTERNAL_ERROR; return VINF_SUCCESS; } #if defined(RT_OS_WINDOWS) if (g_hFile != INVALID_HANDLE_VALUE) #elif !defined(VBOX_VBGLR3_XSERVER) if (g_File != NIL_RTFILE) #else if (g_File != -1) #endif return VERR_INTERNAL_ERROR; #if defined(RT_OS_WINDOWS) /* * Have to use CreateFile here as we want to specify FILE_FLAG_OVERLAPPED * and possible some other bits not available thru iprt/file.h. */ HANDLE hFile = CreateFile(pszDeviceName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL); if (hFile == INVALID_HANDLE_VALUE) return VERR_OPEN_FAILED; g_hFile = hFile; #elif defined(RT_OS_OS2) /* * We might wish to compile this with Watcom, so stick to * the OS/2 APIs all the way. And in any case we have to use * DosDevIOCtl for the requests, why not use Dos* for everything. */ HFILE hf = NULLHANDLE; ULONG ulAction = 0; APIRET rc = DosOpen((PCSZ)pszDeviceName, &hf, &ulAction, 0, FILE_NORMAL, OPEN_ACTION_OPEN_IF_EXISTS, OPEN_FLAGS_FAIL_ON_ERROR | OPEN_FLAGS_NOINHERIT | OPEN_SHARE_DENYNONE | OPEN_ACCESS_READWRITE, NULL); if (rc) return RTErrConvertFromOS2(rc); if (hf < 16) { HFILE ahfs[16]; unsigned i; for (i = 0; i < RT_ELEMENTS(ahfs); i++) { ahfs[i] = 0xffffffff; rc = DosDupHandle(hf, &ahfs[i]); if (rc) break; } if (i-- > 1) { ULONG fulState = 0; rc = DosQueryFHState(ahfs[i], &fulState); if (!rc) { fulState |= OPEN_FLAGS_NOINHERIT; fulState &= OPEN_FLAGS_WRITE_THROUGH | OPEN_FLAGS_FAIL_ON_ERROR | OPEN_FLAGS_NO_CACHE | OPEN_FLAGS_NOINHERIT; /* Turn off non-participating bits. */ rc = DosSetFHState(ahfs[i], fulState); } if (!rc) { rc = DosClose(hf); AssertMsg(!rc, ("%ld\n", rc)); hf = ahfs[i]; } else i++; while (i-- > 0) DosClose(ahfs[i]); } } g_File = (RTFILE)hf; #elif defined(RT_OS_DARWIN) /* * Darwin is kind of special we need to engage the device via I/O first * before we open it via the BSD device node. */ mach_port_t MasterPort; kern_return_t kr = IOMasterPort(MACH_PORT_NULL, &MasterPort); if (kr != kIOReturnSuccess) return VERR_GENERAL_FAILURE; CFDictionaryRef ClassToMatch = IOServiceMatching("org_virtualbox_VBoxGuest"); if (!ClassToMatch) return VERR_GENERAL_FAILURE; io_service_t ServiceObject = IOServiceGetMatchingService(kIOMasterPortDefault, ClassToMatch); if (!ServiceObject) return VERR_NOT_FOUND; io_connect_t uConnection; kr = IOServiceOpen(ServiceObject, mach_task_self(), VBOXGUEST_DARWIN_IOSERVICE_COOKIE, &uConnection); IOObjectRelease(ServiceObject); if (kr != kIOReturnSuccess) return VERR_OPEN_FAILED; RTFILE hFile; int rc = RTFileOpen(&hFile, pszDeviceName, RTFILE_O_READWRITE | RTFILE_O_OPEN | RTFILE_O_DENY_NONE); if (RT_FAILURE(rc)) { IOServiceClose(uConnection); return rc; } g_File = hFile; g_uConnection = uConnection; #elif defined(VBOX_VBGLR3_XSERVER) int File = xf86open(pszDeviceName, XF86_O_RDWR); if (File == -1) return VERR_OPEN_FAILED; g_File = File; #else /* The default implementation. (linux, solaris, freebsd, haiku) */ RTFILE File; int rc = RTFileOpen(&File, pszDeviceName, RTFILE_O_READWRITE | RTFILE_O_OPEN | RTFILE_O_DENY_NONE); if (RT_FAILURE(rc)) return rc; g_File = File; #endif #ifndef VBOX_VBGLR3_XSERVER /* * Create release logger */ PRTLOGGER pReleaseLogger; static const char * const s_apszGroups[] = VBOX_LOGGROUP_NAMES; int rc2 = RTLogCreate(&pReleaseLogger, 0, "all", "VBOX_RELEASE_LOG", RT_ELEMENTS(s_apszGroups), &s_apszGroups[0], RTLOGDEST_USER, NULL); /* This may legitimately fail if we are using the mini-runtime. */ if (RT_SUCCESS(rc2)) RTLogRelSetDefaultInstance(pReleaseLogger); #endif return VINF_SUCCESS; }
/** Try out all the interfaces and see if there's a match. Returns 0 on * success, -1 on failure. */ static int try_interfaces(IOUSBDeviceInterface182 **dev, usb_handle *handle) { IOReturn kr; IOUSBFindInterfaceRequest request; io_iterator_t iterator; io_service_t usbInterface; IOCFPlugInInterface **plugInInterface; IOUSBInterfaceInterface190 **interface = NULL; HRESULT result; SInt32 score; UInt8 interfaceNumEndpoints; UInt8 endpoint; UInt8 configuration; // Placing the constant KIOUSBFindInterfaceDontCare into the following // fields of the IOUSBFindInterfaceRequest structure will allow us to // find all of the interfaces request.bInterfaceClass = kIOUSBFindInterfaceDontCare; request.bInterfaceSubClass = kIOUSBFindInterfaceDontCare; request.bInterfaceProtocol = kIOUSBFindInterfaceDontCare; request.bAlternateSetting = kIOUSBFindInterfaceDontCare; // SetConfiguration will kill an existing UMS connection, so let's // not do this if not necessary. configuration = 0; (*dev)->GetConfiguration(dev, &configuration); if (configuration != 1) (*dev)->SetConfiguration(dev, 1); // Get an iterator for the interfaces on the device kr = (*dev)->CreateInterfaceIterator(dev, &request, &iterator); if (kr != 0) { ERR("Couldn't create a device interface iterator: (%08x)\n", kr); return -1; } while ((usbInterface = IOIteratorNext(iterator))) { // Create an intermediate plugin kr = IOCreatePlugInInterfaceForService( usbInterface, kIOUSBInterfaceUserClientTypeID, kIOCFPlugInInterfaceID, &plugInInterface, &score); // No longer need the usbInterface object now that we have the plugin (void) IOObjectRelease(usbInterface); if ((kr != 0) || (!plugInInterface)) { WARN("Unable to create plugin (%08x)\n", kr); continue; } // Now create the interface interface for the interface result = (*plugInInterface)->QueryInterface( plugInInterface, CFUUIDGetUUIDBytes(kIOUSBInterfaceInterfaceID), (LPVOID) &interface); // No longer need the intermediate plugin (*plugInInterface)->Release(plugInInterface); if (result || !interface) { ERR("Couldn't create interface interface: (%08x)\n", (unsigned int) result); // continue so we can try the next interface continue; } /* * Now open the interface. This will cause the pipes * associated with the endpoints in the interface descriptor * to be instantiated. */ /* * TODO: Earlier comments here indicated that it was a bad * idea to just open any interface, because opening "mass * storage endpoints" is bad. However, the only way to find * out if an interface does bulk in or out is to open it, and * the framework in this application wants to be told about * bulk in / out before deciding whether it actually wants to * use the interface. Maybe something needs to be done about * this situation. */ kr = (*interface)->USBInterfaceOpen(interface); if (kr != 0) { WARN("Could not open interface: (%08x)\n", kr); (void) (*interface)->Release(interface); // continue so we can try the next interface continue; } // Get the number of endpoints associated with this interface. kr = (*interface)->GetNumEndpoints(interface, &interfaceNumEndpoints); if (kr != 0) { ERR("Unable to get number of endpoints: (%08x)\n", kr); goto next_interface; } // Get interface class, subclass and protocol if ((*interface)->GetInterfaceClass(interface, &handle->info.ifc_class) != 0 || (*interface)->GetInterfaceSubClass(interface, &handle->info.ifc_subclass) != 0 || (*interface)->GetInterfaceProtocol(interface, &handle->info.ifc_protocol) != 0) { ERR("Unable to get interface class, subclass and protocol\n"); goto next_interface; } handle->info.has_bulk_in = 0; handle->info.has_bulk_out = 0; // Iterate over the endpoints for this interface and see if there // are any that do bulk in/out. for (endpoint = 0; endpoint <= interfaceNumEndpoints; endpoint++) { UInt8 transferType; UInt16 maxPacketSize; UInt8 interval; UInt8 number; UInt8 direction; kr = (*interface)->GetPipeProperties(interface, endpoint, &direction, &number, &transferType, &maxPacketSize, &interval); if (kr == 0) { if (transferType != kUSBBulk) { continue; } if (direction == kUSBIn) { handle->info.has_bulk_in = 1; handle->bulkIn = endpoint; } else if (direction == kUSBOut) { handle->info.has_bulk_out = 1; handle->bulkOut = endpoint; } if (handle->info.ifc_protocol == 0x01) { handle->zero_mask = maxPacketSize - 1; } } else { ERR("could not get pipe properties\n"); } if (handle->info.has_bulk_in && handle->info.has_bulk_out) { break; } } if (handle->callback(&handle->info) == 0) { handle->interface = interface; handle->success = 1; /* * Clear both the endpoints, because it has been observed * that the Mac may otherwise (incorrectly) start out with * them in bad state. */ if (handle->info.has_bulk_in) { kr = (*interface)->ClearPipeStallBothEnds(interface, handle->bulkIn); if (kr != 0) { ERR("could not clear input pipe; result %x, ignoring...\n", kr); } } if (handle->info.has_bulk_out) { kr = (*interface)->ClearPipeStallBothEnds(interface, handle->bulkOut); if (kr != 0) { ERR("could not clear output pipe; result %x, ignoring....\n", kr); } } return 0; } next_interface: (*interface)->USBInterfaceClose(interface); (*interface)->Release(interface); } return 0; }
static IOReturn PrintSpeedForAllOpticalMedia ( void ) { IOReturn error = kIOReturnSuccess; io_iterator_t iter = MACH_PORT_NULL; io_object_t opticalMedia = MACH_PORT_NULL; bool foundOne = false; error = IOServiceGetMatchingServices ( kIOMasterPortDefault, IOServiceMatching ( kIOCDMediaClass ), &iter ); if ( error == kIOReturnSuccess ) { opticalMedia = IOIteratorNext ( iter ); while ( opticalMedia != MACH_PORT_NULL ) { error = PrintSpeedForDisc ( opticalMedia ); IOObjectRelease ( opticalMedia ); opticalMedia = IOIteratorNext ( iter ); if ( foundOne == false ) foundOne = true; } IOObjectRelease ( iter ); iter = NULL; } error = IOServiceGetMatchingServices ( kIOMasterPortDefault, IOServiceMatching ( kIODVDMediaClass ), &iter ); if ( error == kIOReturnSuccess ) { opticalMedia = IOIteratorNext ( iter ); while ( opticalMedia != MACH_PORT_NULL ) { error = PrintSpeedForDisc ( opticalMedia ); IOObjectRelease ( opticalMedia ); opticalMedia = IOIteratorNext ( iter ); if ( foundOne == false ) foundOne = true; } IOObjectRelease ( iter ); iter = NULL; } if ( foundOne == false ) { printf ( "No optical media found\n" ); } return error; }
int main(int argc, char * argv[]) { kern_return_t kr; io_iterator_t iter; io_service_t framebuffer; io_string_t path; uint32_t index; CFIndex idx; IODisplayModeInformation * modeInfo; IODetailedTimingInformationV2 *timingInfo; CFDictionaryRef dict; CFArrayRef modes; CFIndex count; CFDictionaryRef mode; CFDataRef data; CFNumberRef num; kr = IOServiceGetMatchingServices(kIOMasterPortDefault, IOServiceMatching( IOFRAMEBUFFER_CONFORMSTO), &iter); assert( KERN_SUCCESS == kr ); for ( index = 0; index++, (framebuffer = IOIteratorNext(iter)); IOObjectRelease(framebuffer)) { kr = IORegistryEntryGetPath(framebuffer, kIOServicePlane, path); assert( KERN_SUCCESS == kr ); fprintf(stderr, "\n%s\n", path); dict = IORegistryEntryCreateCFProperty(framebuffer, CFSTR(kIOFBConfigKey), kCFAllocatorDefault, kNilOptions); if (!dict) continue; modes = CFDictionaryGetValue(dict, CFSTR(kIOFBModesKey)); assert(modes); count = CFArrayGetCount(modes); for (idx = 0; idx < count; idx++) { mode = CFArrayGetValueAtIndex(modes, idx); data = CFDictionaryGetValue(mode, CFSTR(kIOFBModeDMKey)); if (!data) continue; modeInfo = (IODisplayModeInformation *) CFDataGetBytePtr(data); data = CFDictionaryGetValue(mode, CFSTR(kIOFBModeTMKey)); if (!data) continue; timingInfo = (IODetailedTimingInformationV2 *) CFDataGetBytePtr(data); IODisplayModeID modeID = 0; num = CFDictionaryGetValue(mode, CFSTR(kIOFBModeIDKey)); if (num) CFNumberGetValue(num, kCFNumberSInt32Type, &modeID ); printf("0x%x: %d x %d %d Hz - %d x %d - flags 0x%x\n", modeID, modeInfo->nominalWidth, modeInfo->nominalHeight, ((modeInfo->refreshRate + 0x8000) >> 16), modeInfo->imageWidth, modeInfo->imageHeight, modeInfo->flags); if (argc > 1) { printf(" horizontalScaledInset %d\n", timingInfo->horizontalScaledInset); printf(" verticalScaledInset %d\n", timingInfo->verticalScaledInset); printf(" scalerFlags 0x%x\n", timingInfo->scalerFlags); printf(" horizontalScaled %d\n", timingInfo->horizontalScaled); printf(" verticalScaled %d\n", timingInfo->verticalScaled); printf(" pixelClock %lld\n", timingInfo->pixelClock); printf(" minPixelClock %lld\n", timingInfo->minPixelClock); printf(" maxPixelClock %lld\n", timingInfo->maxPixelClock); printf(" horizontalActive %d\n", timingInfo->horizontalActive); printf(" horizontalBlanking %d\n", timingInfo->horizontalBlanking); printf(" horizontalSyncOffset %d\n", timingInfo->horizontalSyncOffset); printf(" horizontalSyncPulseWidth %d\n", timingInfo->horizontalSyncPulseWidth); printf(" verticalActive %d\n", timingInfo->verticalActive); printf(" verticalBlanking %d\n", timingInfo->verticalBlanking); printf(" verticalSyncOffset %d\n", timingInfo->verticalSyncOffset); printf(" verticalSyncPulseWidth %d\n", timingInfo->verticalSyncPulseWidth); printf(" horizontalBorderLeft %d\n", timingInfo->horizontalBorderLeft); printf(" horizontalBorderRight %d\n", timingInfo->horizontalBorderRight); printf(" verticalBorderTop %d\n", timingInfo->verticalBorderTop); printf(" verticalBorderBottom %d\n", timingInfo->verticalBorderBottom); printf(" horizontalSyncConfig %d\n", timingInfo->horizontalSyncConfig); printf(" horizontalSyncLevel %d\n", timingInfo->horizontalSyncLevel); printf(" verticalSyncConfig 0x%x\n", timingInfo->verticalSyncConfig); printf(" verticalSyncLevel %d\n", timingInfo->verticalSyncLevel); printf(" signalConfig 0x%x\n", timingInfo->signalConfig); printf(" signalLevels %d\n", timingInfo->signalLevels); printf(" numLinks %d\n", timingInfo->numLinks); } } CFRelease(dict); } IOObjectRelease(iter); exit(0); return(0); }
/**************************************************************************** * darwin_getTOC: get the TOC ****************************************************************************/ static CDTOC *darwin_getTOC( vlc_object_t * p_this, const vcddev_t *p_vcddev ) { mach_port_t port; char *psz_devname; kern_return_t ret; CDTOC *pTOC = NULL; io_iterator_t iterator; io_registry_entry_t service; CFMutableDictionaryRef properties; CFDataRef data; /* get the device name */ if( ( psz_devname = strrchr( p_vcddev->psz_dev, '/') ) != NULL ) ++psz_devname; else psz_devname = p_vcddev->psz_dev; /* unraw the device name */ if( *psz_devname == 'r' ) ++psz_devname; /* get port for IOKit communication */ if( ( ret = IOMasterPort( MACH_PORT_NULL, &port ) ) != KERN_SUCCESS ) { msg_Err( p_this, "IOMasterPort: 0x%08x", ret ); return( NULL ); } /* get service iterator for the device */ if( ( ret = IOServiceGetMatchingServices( port, IOBSDNameMatching( port, 0, psz_devname ), &iterator ) ) != KERN_SUCCESS ) { msg_Err( p_this, "IOServiceGetMatchingServices: 0x%08x", ret ); return( NULL ); } /* first service */ service = IOIteratorNext( iterator ); IOObjectRelease( iterator ); /* search for kIOCDMediaClass */ while( service && !IOObjectConformsTo( service, kIOCDMediaClass ) ) { if( ( ret = IORegistryEntryGetParentIterator( service, kIOServicePlane, &iterator ) ) != KERN_SUCCESS ) { msg_Err( p_this, "IORegistryEntryGetParentIterator: 0x%08x", ret ); IOObjectRelease( service ); return( NULL ); } IOObjectRelease( service ); service = IOIteratorNext( iterator ); IOObjectRelease( iterator ); } if( !service ) { msg_Err( p_this, "search for kIOCDMediaClass came up empty" ); return( NULL ); } /* create a CF dictionary containing the TOC */ if( ( ret = IORegistryEntryCreateCFProperties( service, &properties, kCFAllocatorDefault, kNilOptions ) ) != KERN_SUCCESS ) { msg_Err( p_this, "IORegistryEntryCreateCFProperties: 0x%08x", ret ); IOObjectRelease( service ); return( NULL ); } /* get the TOC from the dictionary */ if( ( data = (CFDataRef) CFDictionaryGetValue( properties, CFSTR(kIOCDMediaTOCKey) ) ) != NULL ) { CFRange range; CFIndex buf_len; buf_len = CFDataGetLength( data ) + 1; range = CFRangeMake( 0, buf_len ); if( ( pTOC = malloc( buf_len ) ) != NULL ) { CFDataGetBytes( data, range, (u_char *)pTOC ); } } else { msg_Err( p_this, "CFDictionaryGetValue failed" ); } CFRelease( properties ); IOObjectRelease( service ); return( pTOC ); }
// // Add Notification observer from Device Driver. // bool createDeviceNotification(const char *className, const io_name_t interestName, IOServiceInterestCallback callback, io_object_t *notification) { kern_return_t kernReturn; bool bResult = false; IONotificationPortRef notificationObject = NULL; CFRunLoopSourceRef notificationRunLoopSource = NULL; io_connect_t dataPort; io_service_t serviceObject; io_iterator_t iterator = 0; CFDictionaryRef classToMatch = NULL; // Obtain the device service. classToMatch = IOServiceMatching(className); if(classToMatch == NULL) { syslog(LOG_ERR, "IOServiceMatching returned a NULL dictionary."); return false; } notificationObject = IONotificationPortCreate(kIOMasterPortDefault); notificationRunLoopSource = IONotificationPortGetRunLoopSource(notificationObject); CFRetain(notificationRunLoopSource); CFRunLoopAddSource( CFRunLoopGetCurrent(), notificationRunLoopSource, kCFRunLoopCommonModes ); // Obtain the I/O Kit communication handle. kernReturn = IOMasterPort(MACH_PORT_NULL, &dataPort); if(kernReturn != KERN_SUCCESS) { syslog(LOG_ERR, "can't obtain I/O Kit's master port. %d\n", kernReturn); goto out; } kernReturn = IOServiceGetMatchingServices(dataPort, classToMatch, &iterator); classToMatch = NULL; // It will release by IOServiceGetMatchingServices if(kernReturn != KERN_SUCCESS) { syslog(LOG_ERR, "IOServiceGetMatchingServices returned. %d\n", kernReturn); goto out; } serviceObject = IOIteratorNext(iterator); /* kernReturn = IOServiceAddInterestNotification( notificationObject, serviceObject, kIOGeneralInterest, callback, NULL, ¬ification ); */ kernReturn = IOServiceAddInterestNotification( notificationObject, serviceObject, interestName, callback, NULL, notification ); if(kernReturn != KERN_SUCCESS) { syslog(LOG_ERR, "IOServiceAddInterestNotification returned. %d\n", kernReturn); goto out; } bResult = true; out: if(iterator) IOObjectRelease(iterator); if(notificationRunLoopSource) CFRelease(notificationRunLoopSource); if(classToMatch) CFRelease(classToMatch); return bResult; }