Advertisement
Guest User

FileNVRAM.cpp

a guest
Oct 6th, 2015
178
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 21.21 KB | None | 0 0
  1. //
  2. //  FileNVRAM.c
  3. //  FileNVRAM
  4. //
  5. //  Created by Chris Morton on 1/11/13.
  6. //  Copyright (c) 2013 xZenue LLC. All rights reserved.
  7. //
  8. //  This work is licensed under the
  9. //  Creative Commons Attribution-NonCommercial 3.0 Unported License.
  10. //  To view a copy of this license, visit http://creativecommons.org/licenses/by-nc/3.0
  11. //  See also: http://www.opensource.apple.com/source/xnu/xnu-2422.90.20/iokit/Kernel/IONVRAM.cpp
  12. //  See also: http://www.opensource.apple.com/source/xnu/xnu-2050.48.11/iokit/Drivers/platform/drvAppleNVRAM/AppleNVRAM.cpp
  13.  
  14. #include "FileNVRAM.h"
  15. #include <sys/proc.h>
  16. #include <sys/vnode.h>
  17. #include <sys/fcntl.h>
  18. #include <IOKit/IOCommandGate.h>
  19. #include <IOKit/storage/IOMedia.h>
  20. #include <string.h>
  21. extern void kdb_printf(const char *fmt, ...);
  22. #define INFO(fmt, ...) { if (_shouldLog) ERROR("func: %s, " fmt, __FUNCTION__, ##__VA_ARGS__) }
  23. #define ERROR(fmt, ...) {\
  24.     char pname[256];\
  25.     proc_name(proc_pid(vfs_context_proc(vfs_context_current())), pname, sizeof(pname));\
  26.     IOLog("Caller: %s, line: %d, " fmt "\n", pname, __LINE__, ##__VA_ARGS__);\
  27. }
  28. #define kIOPMPowerOff 0
  29. #define POWER_STATE_OFF 0
  30. #define POWER_STATE_ON 1
  31.  
  32. static IOPMPowerState sPowerStates[] = {
  33.     {1, kIOPMPowerOff, kIOPMPowerOff, kIOPMPowerOff, 0, 0, 0, 0, 0, 0, 0, 0},
  34.     {1, kIOPMPowerOn, kIOPMPowerOn, kIOPMPowerOn, 0, 0, 0, 0, 0, 0, 0, 0}
  35. };
  36.  
  37. OSDefineMetaClassAndStructors(AppleNVRAM, super);
  38.  
  39. #pragma mark Statics
  40. static inline void gen_random(char *s, size_t len) {//TODO: Not all characters have the same prob
  41.     static const char alphanum[] =
  42.     "0123456789"
  43.     "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
  44.     while (len)
  45.         s[--len] = alphanum[random() % (sizeof(alphanum) - 1)];
  46. }
  47.  
  48. #pragma mark IORegistryEntry
  49. bool AppleNVRAM::init(OSDictionary *dictionary) {
  50.     return IOService::init(dictionary);
  51. }
  52.  
  53. bool AppleNVRAM::init(IORegistryEntry *old, const IORegistryPlane *plane) {
  54.     _shouldLog = true;
  55.     INFO("%p, %p", old, plane);
  56.     return IOService::init(old, plane);
  57. }
  58.  
  59. OSObject *AppleNVRAM::getProperty(const OSSymbol *aKey) const {
  60.     OSObject *value = IOService::getProperty(aKey);
  61.     if (_shouldLog) {
  62.         if (value) {
  63.             OSSerialize *s = OSSerialize::withCapacity(1000);
  64.             if (value->serialize(s))
  65.                 INFO("%s = %s", aKey->getCStringNoCopy(), s->text())
  66.             else
  67.                 INFO("%s = %p", aKey->getCStringNoCopy(), value);
  68.             s->release();
  69.         }
  70.         else
  71.             INFO("%s = NULL", aKey->getCStringNoCopy());
  72.     }
  73.     return value;
  74. }
  75.  
  76. OSObject *AppleNVRAM::getProperty(const char *aKey) const {
  77.     if (const OSSymbol *keySymbol = OSSymbol::withCStringNoCopy(aKey)) {
  78.         OSObject *theObject = getProperty(keySymbol);
  79.         keySymbol->release();
  80.         return theObject;
  81.     }
  82.     else
  83.         return NULL;
  84. }
  85.  
  86. OSObject *AppleNVRAM::copyProperty(const OSSymbol *aKey) const {
  87.     return IORegistryEntry::copyProperty(aKey);
  88. }
  89.  
  90. OSObject *AppleNVRAM::copyProperty(const char *aKey) const {
  91.     return IORegistryEntry::copyProperty(aKey);
  92. }
  93.  
  94. void AppleNVRAM::removeProperty(const OSSymbol *aKey) {
  95.     if (IOUserClient::clientHasPrivilege(current_task(), kIOClientPrivilegeAdministrator) == kIOReturnSuccess) {
  96.         INFO("%p", aKey);
  97.         IOService::removeProperty(aKey);
  98.         _changeCount++;
  99.     }
  100. }
  101.  
  102. bool AppleNVRAM::setProperty(const OSSymbol *aKey, OSObject *anObject) {
  103.     if (IOUserClient::clientHasPrivilege(current_task(), kIOClientPrivilegeAdministrator) != kIOReturnSuccess)
  104.         return false;
  105.     if (_shouldLog) {
  106.         OSSerialize *s = OSSerialize::withCapacity(1000);
  107.         if (anObject->serialize(s))
  108.             INFO("%s, (%s) %s", aKey->getCStringNoCopy(), anObject->getMetaClass()->getClassName(), s->text())
  109.         else
  110.             INFO("%s, (%s) %p", aKey->getCStringNoCopy(), anObject->getMetaClass()->getClassName(), anObject);
  111.         s->release();
  112.     }
  113.     static const char *legacy[] = { "boot-args", "boot-script", NULL };
  114.     int i = 0;
  115.     anObject->retain();
  116.     if (OSString *str = OSDynamicCast(OSString, aKey))
  117.         while (legacy[i])
  118.             if (str->isEqualTo(legacy[i++])) {
  119.                 INFO("Found legacy key %s", str->getCStringNoCopy());
  120.                 if (OSData *data = OSData::withData(OSDynamicCast(OSData, anObject))) {
  121.                     data->appendByte(0, 1);
  122.                     anObject->release();
  123.                     anObject = OSString::withCString((const char *)data->getBytesNoCopy());
  124.                     data->release();
  125.                 }
  126.                 break;
  127.             }
  128.     bool stat = IOService::setProperty(aKey, anObject);
  129.     anObject->release();
  130.     _changeCount++;
  131.     return stat;
  132. }
  133.  
  134. IOReturn AppleNVRAM::setProperties(OSObject *properties) {
  135.     OSDictionary *dict;
  136.     OSCollectionIterator *iter;
  137.     if (!(dict = OSDynamicCast(OSDictionary, properties)) || !(iter = OSCollectionIterator::withCollection(dict)))
  138.         return kIOReturnBadArgument;
  139.     bool result = true, syncNow = false;
  140.     while (result) {
  141.         const OSSymbol *key;
  142.         if (!(key = OSDynamicCast(OSSymbol, iter->getNextObject())))
  143.             break;
  144.         OSObject *object;
  145.         if (!(object = dict->getObject(key)))
  146.             continue;
  147.         const OSString *tmpStr;
  148.         if (key->isEqualTo(kIONVRAMDeletePropertyKey)) {
  149.             if ((result = tmpStr = OSDynamicCast(OSString, object))) {
  150.                 key = OSSymbol::withString(tmpStr);
  151.                 removeProperty(key);
  152.                 key->release();
  153.             }
  154.         }
  155.         else if (key->isEqualTo(kIONVRAMSyncNowPropertyKey)) {
  156.             if ((result = OSDynamicCast(OSString, object)))
  157.                 syncNow = true;
  158.         }
  159.         else
  160.             result = setProperty(key, object);
  161.     }
  162.     iter->release();
  163.     if (syncNow)
  164.         _commandGate->runCommand();
  165.     return result ? kIOReturnSuccess : kIOReturnError;
  166. }
  167.  
  168. bool AppleNVRAM::serializeProperties(OSSerialize *s) const {
  169.     bool result = IOService::serializeProperties(s);
  170.     INFO("%p = %s", s, s->text());
  171.     return result;
  172. }
  173.  
  174. #pragma mark IOService
  175. bool AppleNVRAM::start(IOService *provider) {
  176.     _shouldLog = true;
  177.     INFO("%d", _isReady);
  178.     if (_isReady)
  179.         return true;
  180.     if (!super::start(provider))
  181.         return false;
  182.     INFO("%d", _isReady);
  183.     _filePath = OSString::withCString(NVRAM_LOC_DEFAULT);
  184.     _panic = NULL;
  185.     if ((_commandGate = IOCommandGate::commandGate(this, _sync)))
  186.         getWorkLoop()->addEventSource(_commandGate);
  187.     if (OSDictionary *dict = OSDictionary::withCapacity(1)) {
  188.         setPropertyTable(dict);
  189.         dict->release();
  190.     }
  191.     else
  192.         return false;
  193.     IORegistryEntry *root = IORegistryEntry::fromPath("/", gIODTPlane);
  194.     if (IORegistryEntry *bootnvram = IORegistryEntry::fromPath(NVRAM_LOC_DT, gIODTPlane)) {
  195.         copyEntryProperties(NULL, bootnvram);
  196.         bootnvram->detachFromParent(root, gIODTPlane);
  197.         bootnvram->release();
  198.     }
  199.     if (!getProperty(NVRAM_KEY_MLB)) {
  200.         OSString *str = OSString::withCString(NVRAM_COMMAND_MLB);
  201.         handleSetting(str, kOSBooleanTrue);
  202.         str->release();
  203.     }
  204.     if (!getProperty(NVRAM_KEY_ROM)) {
  205.         OSString *str = OSString::withCString(NVRAM_COMMAND_ROM);
  206.         handleSetting(str, kOSBooleanTrue);
  207.         str->release();
  208.     }
  209.     _isReady = true;
  210.     PMinit();
  211.     registerPowerDriver(this, sPowerStates, sizeof(sPowerStates) / sizeof(*sPowerStates));
  212.     provider->joinPMtree(this);
  213.     _context = vfs_context_create(NULL);
  214.     _isAwake = true;
  215.     if (OSDictionary *m = nameMatching("IOBSD")) {
  216.         addMatchingNotification(gIOPublishNotification, m, BSDReady, this);
  217.         m->release();
  218.     }
  219.     setName("AppleEFINVRAM");
  220.     setName("options", gIODTPlane);
  221.     attachToParent(root, gIODTPlane);
  222.     root->release();
  223.     registerService();
  224.     if (const OSSymbol *funcSym = OSSymbol::withCString("RegisterNVRAM")) {
  225.         callPlatformFunction(funcSym, false, this, NULL, NULL, NULL);
  226.         funcSym->release();
  227.     }
  228.     return true;
  229. }
  230.  
  231. void AppleNVRAM::stop(IOService *provider) {
  232.     OSSafeReleaseNULL(_filePath);
  233.     if (_commandGate) {
  234.         getWorkLoop()->removeEventSource(_commandGate);
  235.         OSSafeReleaseNULL(_commandGate);
  236.     }
  237.     OSSafeReleaseNULL(_panic);
  238.     PMstop();
  239.     INFO("Attempting detachFromParent");
  240.     vfs_context_rele(_context);
  241.     if (IORegistryEntry *root = IORegistryEntry::fromPath("/", gIODTPlane)) {
  242.         detachFromParent(root, gIODTPlane);
  243.         root->release();
  244.     }
  245.     INFO("Passed the detach point");
  246. }
  247.  
  248. IOReturn AppleNVRAM::setPowerState(unsigned long whichState, IOService *whatDevice) {
  249.     INFO("state %lu", whichState);
  250.     switch (whichState) {
  251.         case POWER_STATE_OFF:
  252.             INFO("Entering sleep");
  253.             _isAwake = false;
  254.             break;
  255.         case POWER_STATE_ON:
  256.         default:
  257.             INFO("Waking");
  258.             _isAwake = true;
  259.             break;
  260.     }
  261.     return kIOPMAckImplied;
  262. }
  263.  
  264. bool AppleNVRAM::passiveMatch(OSDictionary *matching, bool changesOK) {
  265.     OSString *str = OSDynamicCast(OSString, matching->getObject(gIOProviderClassKey));
  266.     if (str)
  267.         INFO("%s", str->getCStringNoCopy());
  268.     return str && str->isEqualTo("AppleEFINVRAM") ?: super::passiveMatch(matching, changesOK);
  269. }
  270.  
  271. void AppleNVRAM::systemWillShutdown(IOOptionBits specifier) {
  272.     INFO("");
  273.     _commandGate->runCommand();
  274.     super::systemWillShutdown(specifier);
  275. }
  276.  
  277. #pragma mark IODTNVRAM
  278. void AppleNVRAM::sync(void) {
  279.     INFO("");
  280.     if (!safeToSync() || !getWorkLoop()->inGate())
  281.         return;
  282.     INFO("running");
  283.     OSDictionary *inputDict = dictionaryWithProperties();
  284.     if (!inputDict)
  285.         return;
  286.     OSCollectionIterator *iter = OSCollectionIterator::withCollection(inputDict);
  287.     if (!iter) {
  288.         ERROR("FAILURE! No iterator on input dictionary");
  289.         inputDict->release();
  290.         return;
  291.     }
  292.     OSDictionary *outputDict = OSDictionary::withCapacity(inputDict->getCount());
  293.     while (OSSymbol *key = OSDynamicCast(OSSymbol, iter->getNextObject())) {
  294.         OSObject *value = inputDict->getObject(key);
  295.         const char *keyChar = key->getCStringNoCopy();
  296.         if (const char *guidValueStr = strchr(keyChar, NVRAM_SEPARATOR)) {
  297.             char guidStr[guidValueStr - keyChar + 1];
  298.             strlcpy(guidStr, keyChar, sizeof(guidStr));
  299.             OSDictionary *guidDict = OSDynamicCast(OSDictionary, outputDict->getObject(guidStr));
  300.             if (!guidDict) {
  301.                 guidDict = OSDictionary::withCapacity(1);
  302.                 outputDict->setObject(guidStr, guidDict);
  303.                 guidDict->release();
  304.             }
  305.             if (OSString *nKey = OSString::withCString(guidValueStr + sizeof(NVRAM_SEPARATOR))) {
  306.                 guidDict->setObject(nKey, value);
  307.                 nKey->release();
  308.             }
  309.         }
  310.         else
  311.             outputDict->setObject(key, value);
  312.     }
  313.     inputDict->release();
  314.     iter->release();
  315.     _changeCount = 0;
  316.     OSSerialize *s = OSSerialize::withCapacity(10000);
  317.     s->addString("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
  318.                  "<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n"
  319.                  "<plist version=\"1.0\">\n");
  320.     outputDict->serialize(s);
  321.     outputDict->release();
  322.     s->addString("\n</plist>\n");
  323.     int error = 0;
  324.     vnode_t vp;
  325.     vnode_attr at = {};
  326.     VATTR_SET_ACTIVE(&at, va_data_size);
  327.     if ((error = vnode_open(_filePath->getCStringNoCopy(), (O_CREAT | FWRITE | O_NOFOLLOW), S_IRUSR | S_IRGRP | S_IROTH, VNODE_LOOKUP_NOFOLLOW, &vp, _context)))
  328.         ERROR("Error opening vnode at path %s, errno %d", _filePath->getCStringNoCopy(), error)
  329.     else if ((error = vnode_setattr(vp, &at, _context)))
  330.         ERROR("Error truncating vnode at path %s, errno %d", _filePath->getCStringNoCopy(), error)
  331.     else if ((error = vn_rdwr(UIO_WRITE, vp, s->text(), s->getLength(), 0, UIO_SYSSPACE, IO_NOCACHE | IO_NODELOCKED | IO_UNIT, vfs_context_ucred(_context), (int *)0, vfs_context_proc(_context))))
  332.         ERROR("Error writing to vnode at path %s, errno %d", _filePath->getCStringNoCopy(), error)
  333.     else if ((error = vnode_close(vp, FWASWRITTEN, _context)))
  334.         ERROR("Error closing vnode errno %d", error);
  335.     s->release();
  336.     return;
  337. }
  338.  
  339. bool AppleNVRAM::safeToSync(void) {
  340.     INFO("");
  341.     return _isReady && _filePath && _isAwake && _changeCount;
  342. }
  343.  
  344. IOByteCount AppleNVRAM::savePanicInfo(UInt8 *buffer, IOByteCount length) {
  345. //    kdb_printf("Handling panic(%p, %lu)", buffer, length);
  346. //    IOAddressRange r[2] = {{(IOVirtualAddress)buffer, length}, {(IOVirtualAddress)&length, sizeof(length)}};
  347. //    IOStorageAttributes o = {kIOStorageOptionForceUnitAccess};
  348. //    kdb_printf(", creating descriptor");
  349. //    IOMemoryDescriptor *d = IOMemoryDescriptor::withAddressRanges(r, 2, 0, NULL);
  350. //    kdb_printf(", writing");
  351. //    _panic->write(this, _panicSize - length - sizeof(length), d, &o, (UInt64 *)NULL);
  352. //    kdb_printf(", synchronizing");
  353. //    OSSynchronizeIO();
  354. //    kdb_printf(", releasing\n");
  355. //    d->release();
  356. //    vnode_t _panic;
  357. //    size_t n = strlen(NVRAM_LOC_PANIC) + 5;
  358. //    char *panic = (char *)IOMalloc(n);
  359. //    snprintf(panic, n, "%s.%u", NVRAM_LOC_PANIC, random() % 1000);
  360. //    int error = vnode_open(panic, (O_TRUNC | O_CREAT | FWRITE | O_NOFOLLOW), S_IRUSR | S_IRGRP | S_IROTH, VNODE_LOOKUP_NOFOLLOW, &_panic, _context);
  361. //    if (error)
  362. //        ERROR("failed opening vnode at path %s, errno %d", panic, error)
  363. //        IOFree(panic, n);
  364. //    uio_t u = uio_create(2, 0, UIO_SYSSPACE, UIO_WRITE);
  365. //    uio_addiov(u, (user_addr_t)&length, sizeof(length));
  366. //    uio_addiov(u, (user_addr_t)buffer, length);
  367. //    VNOP_WRITE(_panic, u, IO_NOCACHE|IO_NODELOCKED|IO_UNIT|IO_SYNC|IO_NOAUTH, _context);
  368. //    uio_free(u);
  369. //    vnode_close(_panic, FWASWRITTEN, _context);
  370.     return length;
  371. }
  372.  
  373. IOReturn AppleNVRAM::syncOFVariables(void) {
  374.     INFO("");
  375.     return kIOReturnSuccess;
  376. }
  377.  
  378. void AppleNVRAM::registerNVRAMController(IONVRAMController *nvram) {
  379.     INFO("%p", nvram);
  380. }
  381.  
  382. IOReturn AppleNVRAM::readXPRAM(IOByteCount offset, UInt8 *buffer, IOByteCount length) {
  383.     INFO("%zu, %p, %zu", (size_t)offset, buffer, (size_t)length);
  384.     return kIOReturnUnsupported;
  385. }
  386.  
  387. IOReturn AppleNVRAM::writeXPRAM(IOByteCount offset, UInt8 *buffer, IOByteCount length) {
  388.     INFO("%zu, %p, %zu", (size_t)offset, buffer, (size_t)length);
  389.     return kIOReturnUnsupported;
  390. }
  391.  
  392. IOReturn AppleNVRAM::readNVRAMProperty(IORegistryEntry *entry, const OSSymbol **name, OSData **value) {
  393.     INFO("%s, %p, %p", entry->getName(), name, value);
  394.     return kIOReturnUnsupported;
  395. }
  396.  
  397. IOReturn AppleNVRAM::writeNVRAMProperty(IORegistryEntry *entry, const OSSymbol *name, OSData *value) {
  398.     INFO("%s, %s, %p", entry->getName(), name->getCStringNoCopy(), value);
  399.     return kIOReturnUnsupported;
  400. }
  401.  
  402. OSDictionary *AppleNVRAM::getNVRAMPartitions(void) {
  403.     INFO("");
  404.     return 0;
  405. }
  406.  
  407. IOReturn AppleNVRAM::readNVRAMPartition(const OSSymbol *partitionID, IOByteCount offset, UInt8 *buffer, IOByteCount length) {
  408.     INFO("%s, %zu, %p, %zu", partitionID->getCStringNoCopy(), (size_t)offset, buffer, (size_t)length);
  409.     return kIOReturnNotFound;
  410. }
  411.  
  412. IOReturn AppleNVRAM::writeNVRAMPartition(const OSSymbol *partitionID, IOByteCount offset, UInt8 *buffer, IOByteCount length) {
  413.     INFO("%s, %zu, %p, %zu", partitionID->getCStringNoCopy(), (size_t)offset, buffer, (size_t)length);
  414.     return kIOReturnSuccess;
  415. }
  416.  
  417. #pragma mark Private
  418. bool AppleNVRAM::BSDReady(void *target, void *refCon, IOService *newService, IONotifier *notifier) {
  419.     notifier->remove();
  420.     AppleNVRAM *it = (AppleNVRAM *)target;
  421.     if (OSDictionary *n = nameMatching("disk0s1")) {
  422.         if (IOMedia *m = OSDynamicCast(IOMedia, copyMatchingService(n))) {
  423.             it->_panic = m->getProvider();
  424.             it->_panicSize = m->getSize();
  425.             m->release();
  426.         }
  427.         n->release();
  428.         return true;
  429.     }
  430.     return false;
  431. }
  432.  
  433. IOReturn AppleNVRAM::_sync(OSObject *owner, void *arg0, void *arg1, void *arg2, void *arg3) {
  434.     ((AppleNVRAM *)owner)->sync();
  435.     return kIOReturnSuccess;
  436. }
  437.  
  438. void AppleNVRAM::copyEntryProperties(const char *prefix, IORegistryEntry *entry) {
  439.     IORegistryEntry *child;
  440.     if (!entry)
  441.         return;
  442.     if (OSIterator *iterator = entry->getChildIterator(gIODTPlane)) {
  443.         while ((child = OSDynamicCast(IORegistryEntry, iterator->getNextObject())) != NULL) {
  444.             const char *name = child->getName();
  445.             if (prefix) {
  446.                 if (strcmp(NVRAM_KEY_UID, prefix)) {
  447.                     size_t size = strlen(prefix) + sizeof(NVRAM_SEPARATOR) + strlen(name) + 1;
  448.                     char *newPrefix = (char *)IOMalloc(size);
  449.                     snprintf(newPrefix, size, "%s%c%s", prefix, NVRAM_SEPARATOR, name);
  450.                     copyEntryProperties(newPrefix, child);
  451.                     IOFree(newPrefix, size);
  452.                 }
  453.                 else {
  454.                     OSString *key = OSString::withCString(child->getName());
  455.                     handleSetting(key, kOSBooleanTrue);
  456.                     key->release();
  457.                 }
  458.             }
  459.             else
  460.                 copyEntryProperties(name, child);
  461.         }
  462.         iterator->release();
  463.     }
  464.     OSDictionary *properties = entry->dictionaryWithProperties();
  465.     OSCollectionIterator *iter;
  466.     if (!(iter = OSCollectionIterator::withCollection(properties))) {
  467.         OSSafeRelease(properties);
  468.         return;
  469.     }
  470.     bool result = true;
  471.     while (result) {
  472.         const OSSymbol *key;
  473.         if (!(key = OSDynamicCast(OSSymbol, iter->getNextObject())))
  474.             break;
  475.         if (key->isEqualTo("name"))
  476.             continue;
  477.         OSObject *object;
  478.         if (!(object = properties->getObject(key)))
  479.             continue;
  480.         if (prefix) {
  481.             if (strcmp(NVRAM_KEY_UID, prefix)) {
  482.                 size_t size = strlen(prefix) + sizeof(NVRAM_SEPARATOR) + strlen(key->getCStringNoCopy()) + 1;
  483.                 char *newKey = (char *)IOMalloc(size);
  484.                 snprintf(newKey, size, "%s%c%s", prefix, NVRAM_SEPARATOR, key->getCStringNoCopy());
  485.                 setProperty(OSSymbol::withCString(newKey), object);
  486.                 IOFree(newKey, size);
  487.             }
  488.             else
  489.                 handleSetting(key, object);
  490.         }
  491.         else
  492.             setProperty(key, object);
  493.     }
  494.     iter->release();
  495.     properties->release();
  496. }
  497.  
  498. void AppleNVRAM::handleSetting(const OSObject *object, const OSObject *value) {
  499.     OSString *key = OSDynamicCast(OSString, object);
  500.     if (key)
  501.         INFO("Handling key %s", key->getCStringNoCopy())
  502.     else {
  503.         ERROR("Unknown key");
  504.         return;
  505.     }
  506.     if (key->isEqualTo(NVRAM_COMMAND_FILE)) {
  507.         OSString *str;
  508.         if ((str = OSDynamicCast(OSString, value)))
  509.             str->retain();
  510.         else if (OSData *dat = OSDynamicCast(OSData, value))
  511.             str = OSString::withCString((const char *)dat->getBytesNoCopy());
  512.         else
  513.             return;
  514.         INFO("Setting path to %s", str->getCStringNoCopy());
  515.         OSString *filepath = _filePath;
  516.         _filePath = str;
  517.         OSSafeRelease(filepath);
  518.     }
  519.     else if (key->isEqualTo(NVRAM_COMMAND_MLB)) {
  520.         OSBoolean *shouldgen = OSDynamicCast(OSBoolean, value);
  521.         if (shouldgen && shouldgen->isTrue()) {
  522.             INFO("Generating MLB");
  523.             IORegistryEntry *root = IORegistryEntry::fromPath("/", gIODTPlane);
  524.             if (!root)
  525.                 return;
  526.             OSString *serial = OSDynamicCast(OSString, root->getProperty(kIOPlatformSerialNumberKey));
  527.             root->release();
  528.             if (!serial)
  529.                 return;
  530.             size_t serialLen = strlen(serial->getCStringNoCopy()), mlbLen = serialLen == 11 ? 13 : serialLen == 12 ? 17 : serialLen;
  531.             char buffer[mlbLen + 1];
  532.             strlcpy(buffer, serial->getCStringNoCopy(), sizeof(buffer));
  533.             gen_random(buffer + serialLen, mlbLen - serialLen);
  534.             const OSSymbol *sym = OSSymbol::withCString(NVRAM_KEY_MLB);
  535.             OSData *value = OSData::withBytes(buffer, (int)sizeof(buffer));
  536.             setProperty(sym, value);
  537.             sym->release();
  538.             value->release();
  539.         }
  540.     }
  541.     else if (key->isEqualTo(NVRAM_COMMAND_ROM)) {
  542.         OSBoolean *shouldgen = OSDynamicCast(OSBoolean, value);
  543.         if (shouldgen && shouldgen->isTrue()) {
  544.             INFO("Generating ROM");
  545.             char buffer[6] = {(char)random(), (char)random(), (char)random(), (char)random(), (char)random(), (char)random()};
  546.             const OSSymbol *sym = OSSymbol::withCString(NVRAM_KEY_ROM);
  547.             OSData *value = OSData::withBytes(buffer, sizeof(buffer));
  548.             setProperty(sym, value);
  549.             sym->release();
  550.             value->release();
  551.         }
  552.     }
  553.     else if (key->isEqualTo(NVRAM_COMMAND_LOG)) {
  554.         if (OSBoolean *shouldlog = OSDynamicCast(OSBoolean, value)) {
  555.             _shouldLog = shouldlog == kOSBooleanTrue;
  556.             INFO("Setting logging to %s", _shouldLog ? "enabled" : "disabled");
  557.         }
  558.     }
  559. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement