//--------------------------------------------------------------------------- // _io_ups_send_command // // This routine allow remote processes to issue commands to the UPS. It is // expected that command will come in as a serialized CFDictionaryRef. //--------------------------------------------------------------------------- kern_return_t _io_ups_send_command( mach_port_t server, int upsID, void * commandBuffer, IOByteCount commandSize) { CFDictionaryRef command; CFMutableDataRef data; UPSDataRef upsDataRef; IOReturn res = kIOReturnError; command = (CFDictionaryRef)IOCFUnserialize(commandBuffer, kCFAllocatorDefault, kNilOptions, NULL); if (command) { if (!gUPSDataArrayRef || (upsID >= CFArrayGetCount(gUPSDataArrayRef))) { res = kIOReturnBadArgument; } else { data = (CFMutableDataRef)CFArrayGetValueAtIndex(gUPSDataArrayRef, upsID); upsDataRef =(UPSDataRef)CFDataGetMutableBytePtr(data); if (upsDataRef && upsDataRef->upsPlugInInterface) res = (*upsDataRef->upsPlugInInterface)->sendCommand(upsDataRef->upsPlugInInterface, command); } CFRelease(command); } return res; }
IOReturn IOUPSGetCapabilities(mach_port_t connect, int upsID, CFSetRef *capabilities) { IOReturn ret; void * buffer = NULL; IOByteCount bufferSize; if (!connect || !capabilities) return kIOReturnBadArgument; ret = io_ups_get_capabilities(connect, upsID, (vm_offset_t *)&buffer, (mach_msg_type_number_t *)&bufferSize); if ( ret != kIOReturnSuccess ) return ret; *capabilities = IOCFUnserialize(buffer, kCFAllocatorDefault, kNilOptions, NULL); vm_deallocate(mach_task_self(), (vm_address_t)buffer, bufferSize); return ret; }
static bool switchPartition(char * diskName, char * partitionType) { char wholeDevicePath[256]; sprintf(wholeDevicePath, "/dev/%s", diskName); unsigned int partitionNumber = 0; char * c = wholeDevicePath + 5 + 4; // skip over "/dev/disk" while (*c != 's' && *c++); // look for 's' if (*c == 's') { *c = 0; // clip off remainder sscanf(c+1, "%u", &partitionNumber); // get partition number } if (!partitionNumber) return true; // just assume it is a raid disk #define LIVERAID #ifdef LIVERAID char * optionString = "<dict> <key>Writable</key> <true/> <key>Shared Writer</key> <true/></dict>"; #else char * optionString = "<dict> <key>Writable</key> <true/> </dict>"; #endif CFDictionaryRef options = IOCFUnserialize(optionString, kCFAllocatorDefault, 0, NULL); if (!options) exit(1); int32_t err; MKMediaRef device = MKMediaCreateWithPath(nil, wholeDevicePath, options, &err); CFRelease(options); if (!device || err) return false; options = NULL; MKStatus err2; CFMutableDictionaryRef media = MKCFReadMedia(options, device, &err2); if (!media || err2) goto Failure; // find and extract the 'Schemes' array CFMutableArrayRef Schemes = (CFMutableArrayRef) CFDictionaryGetValue(media, CFSTR("Schemes")); if (!Schemes) goto Failure; // DMTool just grabs the first "default" scheme, so do the same CFMutableDictionaryRef Scheme = (CFMutableDictionaryRef) CFArrayGetValueAtIndex(Schemes, 0); if (!Scheme) goto Failure; // Then find and extract the 'Sections' array of that scheme: CFMutableArrayRef Sections = (CFMutableArrayRef) CFDictionaryGetValue(Scheme, CFSTR("Sections")); if (!Sections) goto Failure; // Every scheme can have multiple sections to it, we need to find the 'MAP' section: CFMutableDictionaryRef Section = (CFMutableDictionaryRef) CFArrayDictionarySearch(Sections, CFSTR("ID"), CFSTR("MAP")); if (!Section) goto Failure; // Then find and extract the 'Partitions' array of that section: CFMutableArrayRef Partitions = (CFMutableArrayRef) CFDictionaryGetValue(Section, CFSTR("Partitions")); if (!Partitions) goto Failure; CFNumberRef partitionIndex = CFNumberCreate(nil, kCFNumberSInt32Type, &partitionNumber); if (!partitionIndex) goto Failure; CFMutableDictionaryRef Partition = (CFMutableDictionaryRef) CFArrayDictionarySearch(Partitions, CFSTR("Partition ID"), partitionIndex); if (!Partition) goto Failure; // change the partition type (finally!) CFStringRef Type = CFStringCreateWithCString(nil, partitionType, kCFStringEncodingUTF8); if (!Type) goto Failure; CFDictionarySetValue(Partition, CFSTR("Type"), Type); CFMutableDictionaryRef woptions = CFDictionaryCreateMutable(kCFAllocatorDefault, 2, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); if (!woptions) goto Failure; CFDictionarySetValue(woptions, CFSTR("Retain existing content"), kCFBooleanTrue); CFDictionarySetValue(woptions, CFSTR("Direct Mode"), kCFBooleanTrue); err2 = MKCFWriteMedia(media, nil, nil, woptions, device); MKCFDisposeMedia(media); CFRelease(woptions); CFRelease(device); return !err2; Failure: if (media) MKCFDisposeMedia(media); if (device) CFRelease(device); return false; }
int main(int argc, char * const argv[]) { ExitStatus result = EX_SOFTWARE; KctoolArgs toolArgs; int kernelcache_fd = -1; // must close() void * fat_header = NULL; // must unmapFatHeaderPage() struct fat_arch * fat_arch = NULL; CFDataRef rawKernelcache = NULL; // must release CFDataRef kernelcacheImage = NULL; // must release void * prelinkInfoSect = NULL; const char * prelinkInfoBytes = NULL; CFPropertyListRef prelinkInfoPlist = NULL; // must release bzero(&toolArgs, sizeof(toolArgs)); /***** * Find out what the program was invoked as. */ progname = rindex(argv[0], '/'); if (progname) { progname++; // go past the '/' } else { progname = (char *)argv[0]; } /* Set the OSKext log callback right away. */ OSKextSetLogOutputFunction(&tool_log); /***** * Process args & check for permission to load. */ result = readArgs(&argc, &argv, &toolArgs); if (result != EX_OK) { if (result == kKctoolExitHelp) { result = EX_OK; } goto finish; } kernelcache_fd = open(toolArgs.kernelcachePath, O_RDONLY); if (kernelcache_fd == -1) { OSKextLog(/* kext */ NULL, kOSKextLogErrorLevel | kOSKextLogGeneralFlag, "Can't open %s: %s.", toolArgs.kernelcachePath, strerror(errno)); result = EX_OSERR; goto finish; } fat_header = mapAndSwapFatHeaderPage(kernelcache_fd); if (!fat_header) { OSKextLog(/* kext */ NULL, kOSKextLogErrorLevel | kOSKextLogGeneralFlag, "Can't map %s: %s.", toolArgs.kernelcachePath, strerror(errno)); result = EX_OSERR; goto finish; } fat_arch = getFirstFatArch(fat_header); if (fat_arch && !toolArgs.archInfo) { toolArgs.archInfo = NXGetArchInfoFromCpuType(fat_arch->cputype, fat_arch->cpusubtype); } rawKernelcache = readMachOSliceForArch(toolArgs.kernelcachePath, toolArgs.archInfo, /* checkArch */ FALSE); if (!rawKernelcache) { OSKextLog(/* kext */ NULL, kOSKextLogErrorLevel | kOSKextLogGeneralFlag, "Can't read arch %s from %s.", toolArgs.archInfo->name, toolArgs.kernelcachePath); goto finish; } if (MAGIC32(CFDataGetBytePtr(rawKernelcache)) == OSSwapHostToBigInt32('comp')) { kernelcacheImage = uncompressPrelinkedSlice(rawKernelcache); if (!kernelcacheImage) { OSKextLog(/* kext */ NULL, kOSKextLogErrorLevel | kOSKextLogGeneralFlag, "Can't uncompress kernelcache slice."); goto finish; } } else { kernelcacheImage = CFRetain(rawKernelcache); } toolArgs.kernelcacheImageBytes = CFDataGetBytePtr(kernelcacheImage); if (ISMACHO64(MAGIC32(toolArgs.kernelcacheImageBytes))) { prelinkInfoSect = (void *)macho_get_section_by_name_64( (struct mach_header_64 *)toolArgs.kernelcacheImageBytes, "__PRELINK_INFO", "__info"); } else { prelinkInfoSect = (void *)macho_get_section_by_name( (struct mach_header *)toolArgs.kernelcacheImageBytes, "__PRELINK_INFO", "__info"); } if (!prelinkInfoSect) { OSKextLog(/* kext */ NULL, kOSKextLogErrorLevel | kOSKextLogGeneralFlag, "Can't find prelink info section."); goto finish; } if (ISMACHO64(MAGIC32(toolArgs.kernelcacheImageBytes))) { prelinkInfoBytes = ((char *)toolArgs.kernelcacheImageBytes) + ((struct section_64 *)prelinkInfoSect)->offset; } else { prelinkInfoBytes = ((char *)toolArgs.kernelcacheImageBytes) + ((struct section *)prelinkInfoSect)->offset; } toolArgs.kernelcacheInfoPlist = (CFPropertyListRef)IOCFUnserialize(prelinkInfoBytes, kCFAllocatorDefault, /* options */ 0, /* errorString */ NULL); if (!toolArgs.kernelcacheInfoPlist) { OSKextLog(/* kext */ NULL, kOSKextLogErrorLevel | kOSKextLogGeneralFlag, "Can't unserialize prelink info."); goto finish; } result = printKextInfo(&toolArgs); if (result != EX_OK) { goto finish; } result = EX_OK; finish: SAFE_RELEASE(toolArgs.kernelcacheInfoPlist); SAFE_RELEASE(kernelcacheImage); SAFE_RELEASE(rawKernelcache); if (fat_header) { unmapFatHeaderPage(fat_header); } if (kernelcache_fd != -1) { close(kernelcache_fd); } return result; }