SdErrorCode initCard() { if (!sd_raw_init()) { if (!sd_raw_available()) { reset(); return SD_ERR_NO_CARD_PRESENT; } else { reset(); return SD_ERR_INIT_FAILED; } } else if (!openPartition()) { reset(); return SD_ERR_PARTITION_READ; } else if (!openFilesys()) { reset(); return SD_ERR_OPEN_FILESYSTEM; } else if (!openRoot()) { reset(); return SD_ERR_NO_ROOT; /* we need to keep locked as the last check */ } else if (sd_raw_locked()) { return SD_ERR_CARD_LOCKED; } return SD_SUCCESS; }
ZExport (ZProfile &) ZProfile::getValues (ZStringlist & aList) { ZFUNCTRACE_DEVELOP ("ZProfile::getValues(ZStringlist& aList)"); aList.drop (); #ifdef ZC_WIN openPath (zFalse); char buffer[MAX_PATH]; long bufsize; for (unsigned long key = 0;; key++) { bufsize = sizeof (buffer); if (RegEnumValue ((HKEY) iPathHandle, key, buffer, (LPDWORD) & bufsize, NULL, NULL, NULL, NULL) != ERROR_SUCCESS) break; aList.addAsLast (buffer); } // for #endif #ifdef ZC_OS2 if (!iPath.size ()) return *this; // os/2 has no values at this level openRoot (); // get size of list (not including the terminating 0) unsigned long size; if (!PrfQueryProfileSize (iRootHandle, iPath, 0, &size)) throwSysErr (PrfQueryProfileSizeName); if (size) { // create buffer ZString buf (0, size++); // read list of values if (!PrfQueryProfileData (iRootHandle, iPath, 0, buf, &size)) throwSysErr (PrfQueryProfileDataName); // parse values into stringlist char *s = buf; while (size) { ZString key; while (*s && size) { key += *s++; size--; } if (key.size ()) aList.addAsLast (key); if (size) { s++; size--; } } // while } // if #endif return *this; } // getValues
BlockId NodeSystem::cascadeUpdate(const FUSE::Path& path, BlockId newId) { printf("Performing cascade for path %s.\n", path.toString().c_str()); std::stack<HandleRef> refStack; refStack.push(HandleRef(*this, openRoot())); for (size_t i = 1; i < path.size(); i++) { refStack.push(HandleRef(*this, openChild(refStack.top().get(), path.at(i - 1)))); } BlockId blockId = newId; for (size_t i = 0; i < path.size(); i++) { const size_t pos = path.size() - i - 1; printf("Updating block ID for component %llu.\n", (unsigned long long) pos); printf("Updating block ID for component %llu: '%s'.\n", (unsigned long long) pos, path.at(pos).c_str()); auto& parentNode = getNodeInfo(refStack.top().get()).node; Directory directory(parentNode); directory.updateChild(path.at(pos), blockId); parentNode.flush(); blockId = parentNode.blockId(); refStack.pop(); } return blockId; }
void ScanGallery::openRoots() { /* standard root always exists, ImgRoot creates it */ KUrl rootUrl(KookaPref::galleryRoot()); kDebug() << "Standard root" << rootUrl.url(); m_defaultBranch = openRoot(rootUrl, i18n("Kooka Gallery")); m_defaultBranch->setOpen(true); /* open more configurable image repositories, configuration TODO */ //openRoot(KUrl(getenv("HOME")), i18n("Home Directory")); }
void ZProfile::openPath (ZBoolean aCreate) { ZFUNCTRACE_DEVELOP ("ZProfile::openPath(ZBoolean aCreate)"); if (iPathHandle == 0 || (aCreate && iPathReadOnly)) { closePath (); openRoot (aCreate); if (iPath.size ()) iPathHandle = openHandle ((HKEY) iRootHandle, iPath, aCreate); else iPathHandle = iRootHandle; iPathReadOnly = !aCreate; } // if } // openPath
ZExport (ZProfile &) ZProfile::deleteValue (const ZString & aValueName) { ZFUNCTRACE_DEVELOP ("ZProfile::deleteValue(const ZString& aValueName)"); #ifdef ZC_WIN openPath (zFalse); RegDeleteValue ((HKEY) iPathHandle, aValueName); #endif #ifdef ZC_OS2 if (!iPath.size ()) ZTHROWEXC (MissingPath); if (!aValueName.size ()) ZTHROWEXC (MissingValueName); openRoot (); if (!PrfWriteProfileString (iRootHandle, iPath, aValueName, 0)) throwSysErr (PrfWriteProfileStringName); #endif return *this; } // deleteValue
ZExport (ZBoolean) ZProfile::valueExists (const ZString & aValueName) { ZFUNCTRACE_DEVELOP ("ZProfile::valueExists(const ZString& aValueName)"); #ifdef ZC_WIN try { openPath (zFalse); } catch (const ZException & exc) { return zFalse; } // catch #endif #ifdef ZC_OS2 openRoot (); #endif ZStringlist list; getValues (list); return list.find (aValueName) >= 0; } // valueExists
FileHDF5::FileHDF5(const string &name, FileMode mode, Compression compression, OpenFlags flags) { if (!fileExists(name)) { mode = FileMode::Overwrite; } this->mode = mode; this->compr = compression; //we want hdf5 to keep track of the order in which links were created so that //the order for indexed based accessors is stable cf. issue #387 H5Object fcpl = H5Pcreate(H5P_FILE_CREATE); fcpl.check("Could not create file creation plist"); HErr res = H5Pset_link_creation_order(fcpl.h5id(), H5P_CRT_ORDER_TRACKED|H5P_CRT_ORDER_INDEXED); res.check("Unable to create file (H5Pset_link_creation_order failed.)"); unsigned int h5mode = map_file_mode(mode); bool is_create = !fileExists(name) || h5mode == H5F_ACC_TRUNC; if (is_create) { hid = H5Fcreate(name.c_str(), h5mode, fcpl.h5id(), H5P_DEFAULT); } else { hid = H5Fopen(name.c_str(), h5mode, H5P_DEFAULT); } if (!H5Iis_valid(hid)) { throw H5Exception("Could not open/create file"); } openRoot(); if (is_create) { createHeader(); } else if (!checkHeader(mode) && (flags & OpenFlags::Force) != OpenFlags::Force) { throw nix::InvalidFile("FileHDF5::open_existing!"); } metadata = root.openGroup("metadata"); data = root.openGroup("data"); setCreatedAt(); setUpdatedAt(); }
ZExport (ZProfile &) ZProfile::deleteKey (const ZString & aKeyName) { ZFUNCTRACE_DEVELOP ("ZProfile::deleteKey(const ZString& aKeyName)"); #ifdef ZC_WIN // delete all values and subkeys first ZString oldPath (iPath); try { setPath (iPath + (char) ZC_PATHSEPARATOR + aKeyName); openPath (zFalse); ZStringlist list; int i; // delete all values setValue (ZString ()); // just clear out default value getValues (list); for (i = 0; i < list.count (); i++) if (list[i].size ()) { deleteValue (list[i]); } // if // delete all subkeys getKeys (list); for (i = 0; i < list.count (); i++) deleteKey (list[i]); } // try catch (const ZException & exc) { setPath (oldPath); throw; } // catch setPath (oldPath); openPath (zFalse); RegDeleteKey ((HKEY) iPathHandle, aKeyName); #endif #ifdef ZC_OS2 if (iPath.size () && aKeyName.size ()) return *this; // no keys at this level openRoot (); if (!iPath.size () && !aKeyName.size ()) { // delete all applications: // will only do this if not the system- or user profile! if (iRootHandle == HINI_SYSTEMPROFILE || iRootHandle == HINI_USERPROFILE) return *this; ZStringlist apps; getKeys (apps); for (long i = 0; i < apps.count (); i++) if (!PrfWriteProfileString (iRootHandle, apps[i], 0, 0)) throwSysErr (PrfWriteProfileStringName); } else { if (!PrfWriteProfileString (iRootHandle, iPath.size ()? iPath : aKeyName, 0, 0)) throwSysErr (PrfWriteProfileStringName); } // if #endif return *this; } // deleteKey
ZExport (ZProfile &) ZProfile::setValue (const ZString & aValue, const ZString & aValueName, int aType) { ZFUNCTRACE_DEVELOP ("ZProfile::setValue(const ZString& aValue, const ZString& aValueName, int aType)"); // find out type if auto if (aType == Auto) { ZString v (aValue); if (ZString (v.strip ().asLong ()) == v) aType = Integer; else { if (aValue.isPrintable ()) aType = String; else aType = Binary; } // if } // if #ifdef ZC_WIN long dataType; switch (aType) { case String: dataType = 1; // String break; case Integer: return setValue (aValue.asLong (), aValueName); default: dataType = 3; // Binary } // switch openPath (zTrue); if (valueExists (aValueName)) deleteValue (aValueName); if (!RegSetValueEx ((HKEY) iPathHandle, aValueName, 0, dataType, (LPBYTE) (const char *) aValue, aValue.size ()) == ERROR_SUCCESS) throwSysErr (SRegSetValueEx); #endif #ifdef ZC_OS2 if (!iPath.size ()) ZTHROWEXC (MissingPath); if (!aValueName.size ()) ZTHROWEXC (MissingValueName); openRoot (); switch (aType) { case String: if (!PrfWriteProfileString (iRootHandle, iPath, aValueName, ZString::exp (aValue))) throwSysErr (PrfWriteProfileStringName); break; case Integer: { ZString v (aValue); if (!PrfWriteProfileString (iRootHandle, iPath, aValueName, ZString (v.strip ().asLong ()))) throwSysErr (PrfWriteProfileStringName); break; } // Integer default: { ZString val (aValue); if (!PrfWriteProfileData (iRootHandle, iPath, aValueName, (char *) val, val.size ())) throwSysErr (PrfWriteProfileDataName); } // default } // switch #endif return *this; } // setValue
ZExport (ZString) ZProfile::value (const ZString & aValueName) { ZFUNCTRACE_DEVELOP ("ZProfile::value(const ZString& aValueName)"); #ifdef ZC_WIN openPath (zFalse); DWORD dataType, size; if (!RegQueryValueEx ((HKEY) iPathHandle, aValueName, 0, &dataType, NULL, &size) == ERROR_SUCCESS) ZTHROWEXC (ValueNotFound); if (size) { ZString str (0, size); RegQueryValueEx ((HKEY) iPathHandle, aValueName, 0, NULL, (LPBYTE) (char *) str, (LPDWORD) & size); switch (dataType) { case 1: // String case 2: // ExpandString case 7: // MultiString if (str.size () > 0 && str[str.size ()] == 0) return str.subString (1, str.size ()); default:; } // switch } // if #endif #ifdef ZC_OS2 if (!iPath.size ()) ZTHROWEXC (MissingPath); if (!aValueName.size ()) ZTHROWEXC (MissingValueName); openRoot (); // query size of data unsigned long size; if (!PrfQueryProfileSize (iRootHandle, iPath, aValueName, &size)) throwSysErr (PrfQueryProfileSizeName); if (size > 0) { ZString buf (0, size++); // try to get as string first PrfQueryProfileString (iRootHandle, iPath, aValueName, "", buf, size); ERRORID err = WinGetLastError (iHab); if (err == 0) { if (buf[buf.size ()] == 0 && buf.subString (1, buf.size () - 1).isPrintable ()) return buf.subString (1, buf.size () - 1); return buf; } // if if (ERRORIDERROR (err) != PMERR_INVALID_ASCIIZ) throwSysErr (PrfQueryProfileStringName); // try to get binary data if (!PrfQueryProfileData (iRootHandle, iPath, aValueName, buf, &size)) throwSysErr (PrfQueryProfileDataName); return buf; } // if #endif return ZString (); } // value
int main(int argc, char* argv[]) { init_libxpwn(); Dictionary* info; Dictionary* firmwarePatches; Dictionary* patchDict; ArrayValue* patchArray; void* buffer; StringValue* actionValue; StringValue* pathValue; StringValue* fileValue; StringValue* patchValue; char* patchPath; char* rootFSPathInIPSW; io_func* rootFS; Volume* rootVolume; size_t rootSize; size_t preferredRootSize = 0; size_t minimumRootSize = 0; char* ramdiskFSPathInIPSW; unsigned int ramdiskKey[16]; unsigned int ramdiskIV[16]; unsigned int* pRamdiskKey = NULL; unsigned int* pRamdiskIV = NULL; io_func* ramdiskFS; Volume* ramdiskVolume; char* updateRamdiskFSPathInIPSW = NULL; int i; OutputState* outputState; char* bundlePath; char* bundleRoot = "FirmwareBundles/"; int mergePaths; char* outputIPSW; void* imageBuffer; size_t imageSize; AbstractFile* bootloader39 = NULL; AbstractFile* bootloader46 = NULL; AbstractFile* applelogo = NULL; AbstractFile* recoverymode = NULL; char noWipe = FALSE; char unlockBaseband = FALSE; char selfDestruct = FALSE; char use39 = FALSE; char use46 = FALSE; char doBootNeuter = FALSE; char updateBB = FALSE; char useMemory = FALSE; unsigned int key[16]; unsigned int iv[16]; unsigned int* pKey = NULL; unsigned int* pIV = NULL; if(argc < 3) { XLOG(0, "usage %s <input.ipsw> <target.ipsw> [-b <bootimage.png>] [-r <recoveryimage.png>] [-s <system partition size>] [-memory] [-bbupdate] [-nowipe] [-e \"<action to exclude>\"] [[-unlock] [-use39] [-use46] [-cleanup] -3 <bootloader 3.9 file> -4 <bootloader 4.6 file>] <package1.tar> <package2.tar>...\n", argv[0]); return 0; } outputIPSW = argv[2]; int* toRemove = NULL; int numToRemove = 0; for(i = 3; i < argc; i++) { if(argv[i][0] != '-') { break; } if(strcmp(argv[i], "-memory") == 0) { useMemory = TRUE; continue; } if(strcmp(argv[i], "-s") == 0) { int size; sscanf(argv[i + 1], "%d", &size); preferredRootSize = size; i++; continue; } if(strcmp(argv[i], "-nowipe") == 0) { noWipe = TRUE; continue; } if(strcmp(argv[i], "-bbupdate") == 0) { updateBB = TRUE; continue; } if(strcmp(argv[i], "-e") == 0) { numToRemove++; toRemove = realloc(toRemove, numToRemove * sizeof(int)); toRemove[numToRemove - 1] = i + 1; i++; continue; } if(strcmp(argv[i], "-unlock") == 0) { unlockBaseband = TRUE; continue; } if(strcmp(argv[i], "-cleanup") == 0) { selfDestruct = TRUE; continue; } if(strcmp(argv[i], "-use39") == 0) { if(use46) { XLOG(0, "error: select only one of -use39 and -use46\n"); exit(1); } use39 = TRUE; continue; } if(strcmp(argv[i], "-use46") == 0) { if(use39) { XLOG(0, "error: select only one of -use39 and -use46\n"); exit(1); } use46 = TRUE; continue; } if(strcmp(argv[i], "-b") == 0) { applelogo = createAbstractFileFromFile(fopen(argv[i + 1], "rb")); if(!applelogo) { XLOG(0, "cannot open %s\n", argv[i + 1]); exit(1); } i++; continue; } if(strcmp(argv[i], "-r") == 0) { recoverymode = createAbstractFileFromFile(fopen(argv[i + 1], "rb")); if(!recoverymode) { XLOG(0, "cannot open %s\n", argv[i + 1]); exit(1); } i++; continue; } if(strcmp(argv[i], "-3") == 0) { bootloader39 = createAbstractFileFromFile(fopen(argv[i + 1], "rb")); if(!bootloader39) { XLOG(0, "cannot open %s\n", argv[i + 1]); exit(1); } i++; continue; } if(strcmp(argv[i], "-4") == 0) { bootloader46 = createAbstractFileFromFile(fopen(argv[i + 1], "rb")); if(!bootloader46) { XLOG(0, "cannot open %s\n", argv[i + 1]); exit(1); } i++; continue; } } mergePaths = i; if(use39 || use46 || unlockBaseband || selfDestruct || bootloader39 || bootloader46) { if(!(bootloader39) || !(bootloader46)) { XLOG(0, "error: you must specify both bootloader files.\n"); exit(1); } else { doBootNeuter = TRUE; } } info = parseIPSW2(argv[1], bundleRoot, &bundlePath, &outputState, useMemory); if(info == NULL) { XLOG(0, "error: Could not load IPSW\n"); exit(1); } firmwarePatches = (Dictionary*)getValueByKey(info, "FilesystemPatches"); int j; for(j = 0; j < numToRemove; j++) { removeKey(firmwarePatches, argv[toRemove[j]]); } free(toRemove); firmwarePatches = (Dictionary*)getValueByKey(info, "FirmwarePatches"); patchDict = (Dictionary*) firmwarePatches->values; while(patchDict != NULL) { fileValue = (StringValue*) getValueByKey(patchDict, "File"); StringValue* keyValue = (StringValue*) getValueByKey(patchDict, "Key"); StringValue* ivValue = (StringValue*) getValueByKey(patchDict, "IV"); pKey = NULL; pIV = NULL; if(keyValue) { sscanf(keyValue->value, "%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x", &key[0], &key[1], &key[2], &key[3], &key[4], &key[5], &key[6], &key[7], &key[8], &key[9], &key[10], &key[11], &key[12], &key[13], &key[14], &key[15]); pKey = key; } if(ivValue) { sscanf(ivValue->value, "%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x", &iv[0], &iv[1], &iv[2], &iv[3], &iv[4], &iv[5], &iv[6], &iv[7], &iv[8], &iv[9], &iv[10], &iv[11], &iv[12], &iv[13], &iv[14], &iv[15]); pIV = iv; } if(strcmp(patchDict->dValue.key, "Restore Ramdisk") == 0) { ramdiskFSPathInIPSW = fileValue->value; if(pKey) { memcpy(ramdiskKey, key, sizeof(key)); memcpy(ramdiskIV, iv, sizeof(iv)); pRamdiskKey = ramdiskKey; pRamdiskIV = ramdiskIV; } else { pRamdiskKey = NULL; pRamdiskIV = NULL; } } if(strcmp(patchDict->dValue.key, "Update Ramdisk") == 0) { updateRamdiskFSPathInIPSW = fileValue->value; } patchValue = (StringValue*) getValueByKey(patchDict, "Patch2"); if(patchValue) { if(noWipe) { XLOG(0, "%s: ", patchDict->dValue.key); fflush(stdout); doPatch(patchValue, fileValue, bundlePath, &outputState, pKey, pIV, useMemory); patchDict = (Dictionary*) patchDict->dValue.next; continue; /* skip over the normal Patch */ } } patchValue = (StringValue*) getValueByKey(patchDict, "Patch"); if(patchValue) { XLOG(0, "%s: ", patchDict->dValue.key); fflush(stdout); doPatch(patchValue, fileValue, bundlePath, &outputState, pKey, pIV, useMemory); } if(strcmp(patchDict->dValue.key, "AppleLogo") == 0 && applelogo) { XLOG(0, "replacing %s\n", fileValue->value); fflush(stdout); ASSERT((imageBuffer = replaceBootImage(getFileFromOutputState(&outputState, fileValue->value), pKey, pIV, applelogo, &imageSize)) != NULL, "failed to use new image"); addToOutput(&outputState, fileValue->value, imageBuffer, imageSize); } if(strcmp(patchDict->dValue.key, "RecoveryMode") == 0 && recoverymode) { XLOG(0, "replacing %s\n", fileValue->value); fflush(stdout); ASSERT((imageBuffer = replaceBootImage(getFileFromOutputState(&outputState, fileValue->value), pKey, pIV, recoverymode, &imageSize)) != NULL, "failed to use new image"); addToOutput(&outputState, fileValue->value, imageBuffer, imageSize); } patchDict = (Dictionary*) patchDict->dValue.next; } fileValue = (StringValue*) getValueByKey(info, "RootFilesystem"); rootFSPathInIPSW = fileValue->value; size_t defaultRootSize = ((IntegerValue*) getValueByKey(info, "RootFilesystemSize"))->value; minimumRootSize = defaultRootSize * 1000 * 1000; minimumRootSize -= minimumRootSize % 512; if(preferredRootSize == 0) { preferredRootSize = defaultRootSize; } rootSize = preferredRootSize * 1000 * 1000; rootSize -= rootSize % 512; if(useMemory) { buffer = malloc(rootSize); } else { buffer = NULL; } if(buffer == NULL) { XLOG(2, "using filesystem backed temporary storage\n"); } extractDmg( createAbstractFileFromFileVault(getFileFromOutputState(&outputState, rootFSPathInIPSW), ((StringValue*)getValueByKey(info, "RootFilesystemKey"))->value), openRoot((void**)&buffer, &rootSize), -1); rootFS = IOFuncFromAbstractFile(openRoot((void**)&buffer, &rootSize)); rootVolume = openVolume(rootFS); XLOG(0, "Growing root to minimum: %ld\n", (long) defaultRootSize); fflush(stdout); grow_hfs(rootVolume, minimumRootSize); if(rootSize > minimumRootSize) { XLOG(0, "Growing root: %ld\n", (long) preferredRootSize); fflush(stdout); grow_hfs(rootVolume, rootSize); } firmwarePatches = (Dictionary*)getValueByKey(info, "FilesystemPatches"); patchArray = (ArrayValue*) firmwarePatches->values; while(patchArray != NULL) { for(i = 0; i < patchArray->size; i++) { patchDict = (Dictionary*) patchArray->values[i]; fileValue = (StringValue*) getValueByKey(patchDict, "File"); actionValue = (StringValue*) getValueByKey(patchDict, "Action"); if(strcmp(actionValue->value, "ReplaceKernel") == 0) { pathValue = (StringValue*) getValueByKey(patchDict, "Path"); XLOG(0, "replacing kernel... %s -> %s\n", fileValue->value, pathValue->value); fflush(stdout); add_hfs(rootVolume, getFileFromOutputState(&outputState, fileValue->value), pathValue->value); } if(strcmp(actionValue->value, "Patch") == 0) { patchValue = (StringValue*) getValueByKey(patchDict, "Patch"); patchPath = (char*) malloc(sizeof(char) * (strlen(bundlePath) + strlen(patchValue->value) + 2)); strcpy(patchPath, bundlePath); strcat(patchPath, "/"); strcat(patchPath, patchValue->value); XLOG(0, "patching %s (%s)... ", fileValue->value, patchPath); doPatchInPlace(rootVolume, fileValue->value, patchPath); free(patchPath); } } patchArray = (ArrayValue*) patchArray->dValue.next; } for(; mergePaths < argc; mergePaths++) { XLOG(0, "merging %s\n", argv[mergePaths]); AbstractFile* tarFile = createAbstractFileFromFile(fopen(argv[mergePaths], "rb")); if(tarFile == NULL) { XLOG(1, "cannot find %s, make sure your slashes are in the right direction\n", argv[mergePaths]); releaseOutput(&outputState); closeRoot(buffer); exit(0); } hfs_untar(rootVolume, tarFile); tarFile->close(tarFile); } if(pRamdiskKey) { ramdiskFS = IOFuncFromAbstractFile(openAbstractFile2(getFileFromOutputStateForOverwrite(&outputState, ramdiskFSPathInIPSW), pRamdiskKey, pRamdiskIV)); } else { XLOG(0, "unencrypted ramdisk\n"); ramdiskFS = IOFuncFromAbstractFile(openAbstractFile(getFileFromOutputStateForOverwrite(&outputState, ramdiskFSPathInIPSW))); } ramdiskVolume = openVolume(ramdiskFS); XLOG(0, "growing ramdisk: %d -> %d\n", ramdiskVolume->volumeHeader->totalBlocks * ramdiskVolume->volumeHeader->blockSize, (ramdiskVolume->volumeHeader->totalBlocks + 4) * ramdiskVolume->volumeHeader->blockSize); grow_hfs(ramdiskVolume, (ramdiskVolume->volumeHeader->totalBlocks + 4) * ramdiskVolume->volumeHeader->blockSize); if(doBootNeuter) { firmwarePatches = (Dictionary*)getValueByKey(info, "BasebandPatches"); if(firmwarePatches != NULL) { patchDict = (Dictionary*) firmwarePatches->values; while(patchDict != NULL) { pathValue = (StringValue*) getValueByKey(patchDict, "Path"); fileValue = (StringValue*) getValueByKey(patchDict, "File"); if(fileValue) { XLOG(0, "copying %s -> %s... ", fileValue->value, pathValue->value); fflush(stdout); if(copyAcrossVolumes(ramdiskVolume, rootVolume, fileValue->value, pathValue->value)) { patchValue = (StringValue*) getValueByKey(patchDict, "Patch"); if(patchValue) { patchPath = malloc(sizeof(char) * (strlen(bundlePath) + strlen(patchValue->value) + 2)); strcpy(patchPath, bundlePath); strcat(patchPath, "/"); strcat(patchPath, patchValue->value); XLOG(0, "patching %s (%s)... ", pathValue->value, patchPath); fflush(stdout); doPatchInPlace(rootVolume, pathValue->value, patchPath); free(patchPath); } } } if(strcmp(patchDict->dValue.key, "Bootloader 3.9") == 0 && bootloader39 != NULL) { add_hfs(rootVolume, bootloader39, pathValue->value); } if(strcmp(patchDict->dValue.key, "Bootloader 4.6") == 0 && bootloader46 != NULL) { add_hfs(rootVolume, bootloader46, pathValue->value); } patchDict = (Dictionary*) patchDict->dValue.next; } } fixupBootNeuterArgs(rootVolume, unlockBaseband, selfDestruct, use39, use46); } createRestoreOptions(ramdiskVolume, preferredRootSize, updateBB); closeVolume(ramdiskVolume); CLOSE(ramdiskFS); if(updateRamdiskFSPathInIPSW) removeFileFromOutputState(&outputState, updateRamdiskFSPathInIPSW); closeVolume(rootVolume); CLOSE(rootFS); buildDmg(openRoot((void**)&buffer, &rootSize), getFileFromOutputStateForReplace(&outputState, rootFSPathInIPSW)); closeRoot(buffer); writeOutput(&outputState, outputIPSW); releaseDictionary(info); free(bundlePath); return 0; }