| 21 | #ifdef __APPLE__ |
| 22 | |
| 23 | std::vector<std::string> GetDriveListFromClasses(CFMutableDictionaryRef classes) |
| 24 | { |
| 25 | io_iterator_t iterator = IO_OBJECT_NULL; |
| 26 | kern_return_t result; |
| 27 | std::vector<std::string> drives; |
| 28 | |
| 29 | CFDictionarySetValue(classes, CFSTR(kIOMediaEjectableKey), kCFBooleanTrue); |
| 30 | result = IOServiceGetMatchingServices(kIOMasterPortDefault, classes, &iterator); |
| 31 | if (result != KERN_SUCCESS) |
| 32 | return drives; |
| 33 | while (io_object_t media = IOIteratorNext(iterator)) |
| 34 | { |
| 35 | CFTypeRef path_cfstr = IORegistryEntryCreateCFProperty(media, CFSTR(kIOBSDNameKey), kCFAllocatorDefault, 0); |
| 36 | if (path_cfstr) |
| 37 | { |
| 38 | char path[PATH_MAX] = {0}; |
| 39 | strlcpy(path, "/dev/r", PATH_MAX); |
| 40 | size_t path_prefix_len = strnlen(path, PATH_MAX); |
| 41 | result = CFStringGetCString((CFStringRef)path_cfstr, path + path_prefix_len, PATH_MAX - path_prefix_len, kCFStringEncodingUTF8); |
| 42 | if (result) |
| 43 | { |
| 44 | drives.emplace_back(path); |
| 45 | } |
| 46 | CFRelease(path_cfstr); |
| 47 | } |
| 48 | IOObjectRelease(media); |
| 49 | } |
| 50 | IOObjectRelease(iterator); |
| 51 | return drives; |
| 52 | } |
| 53 | |
| 54 | #endif |
| 55 |
no outgoing calls
no test coverage detected