Permalink
Browse files

Imported a lot of stuff from dev team branch

  • Loading branch information...
1 parent 35b51a0 commit 5c8b07519892de6a3a057aa0755b2e368d2a47db @planetbeing planetbeing committed Jul 18, 2009
View
@@ -232,6 +232,7 @@ size_t memFileWrite(AbstractFile* file, const void* data, size_t len) {
}
if((info->offset + (size_t)len) > (*(info->bufferSize))) {
+ memset(((uint8_t*)(*(info->buffer))) + *(info->bufferSize), 0, (info->offset + (size_t)len) - *(info->bufferSize));
*(info->bufferSize) = info->offset + (size_t)len;
}
View
@@ -41,7 +41,7 @@ int main(int argc, char* argv[]) {
TestByteOrder();
if(argc < 4) {
- printf("usage: %s [extract|build|iso|dmg] <in> <out> (-k <key>) (partition)\n", argv[0]);
+ printf("usage: %s [extract|build|build2048|res|iso|dmg] <in> <out> (-k <key>) (partition)\n", argv[0]);
return 0;
}
@@ -72,7 +72,11 @@ int main(int argc, char* argv[]) {
}
extractDmg(in, out, partNum);
} else if(strcmp(argv[1], "build") == 0) {
- buildDmg(in, out);
+ buildDmg(in, out, SECTOR_SIZE);
+ } else if(strcmp(argv[1], "build2048") == 0) {
+ buildDmg(in, out, 2048);
+ } else if(strcmp(argv[1], "res") == 0) {
+ outResources(in, out);
} else if(strcmp(argv[1], "iso") == 0) {
convertToISO(in, out);
} else if(strcmp(argv[1], "dmg") == 0) {
View
@@ -85,7 +85,7 @@ uint32_t calculateMasterChecksum(ResourceKey* resources) {
return result;
}
-int buildDmg(AbstractFile* abstractIn, AbstractFile* abstractOut) {
+int buildDmg(AbstractFile* abstractIn, AbstractFile* abstractOut, unsigned int BlockSize) {
io_func* io;
Volume* volume;
@@ -127,15 +127,15 @@ int buildDmg(AbstractFile* abstractIn, AbstractFile* abstractOut) {
printf("Creating and writing DDM and partition map...\n"); fflush(stdout);
- DDM = createDriverDescriptorMap((volumeHeader->totalBlocks * volumeHeader->blockSize)/SECTOR_SIZE);
+ DDM = createDriverDescriptorMap((volumeHeader->totalBlocks * volumeHeader->blockSize)/SECTOR_SIZE, BlockSize);
- partitions = createApplePartitionMap((volumeHeader->totalBlocks * volumeHeader->blockSize)/SECTOR_SIZE, HFSX_VOLUME_TYPE);
+ partitions = createApplePartitionMap((volumeHeader->totalBlocks * volumeHeader->blockSize)/SECTOR_SIZE, HFSX_VOLUME_TYPE, BlockSize);
- writeDriverDescriptorMap(abstractOut, DDM, &CRCProxy, (void*) (&dataForkToken), &resources);
+ int pNum = writeDriverDescriptorMap(-1, abstractOut, DDM, BlockSize, &CRCProxy, (void*) (&dataForkToken), &resources);
free(DDM);
- writeApplePartitionMap(abstractOut, partitions, &CRCProxy, (void*) (&dataForkToken), &resources, &nsiz);
+ pNum = writeApplePartitionMap(pNum, abstractOut, partitions, BlockSize, &CRCProxy, (void*) (&dataForkToken), &resources, &nsiz);
free(partitions);
- writeATAPI(abstractOut, &CRCProxy, (void*) (&dataForkToken), &resources, &nsiz);
+ pNum = writeATAPI(pNum, abstractOut, BlockSize, &CRCProxy, (void*) (&dataForkToken), &resources, &nsiz);
memset(&uncompressedToken, 0, sizeof(uncompressedToken));
SHA1Init(&(uncompressedToken.sha1));
@@ -144,15 +144,16 @@ int buildDmg(AbstractFile* abstractIn, AbstractFile* abstractOut) {
abstractIn->seek(abstractIn, 0);
blkx = insertBLKX(abstractOut, abstractIn, USER_OFFSET, (volumeHeader->totalBlocks * volumeHeader->blockSize)/SECTOR_SIZE,
- 2, CHECKSUM_CRC32, &BlockSHA1CRC, &uncompressedToken, &CRCProxy, &dataForkToken, volume);
+ pNum, CHECKSUM_CRC32, &BlockSHA1CRC, &uncompressedToken, &CRCProxy, &dataForkToken, volume, 1);
blkx->checksum.data[0] = uncompressedToken.crc;
printf("Inserting main blkx...\n"); fflush(stdout);
-
- resources = insertData(resources, "blkx", 2, "Mac_OS_X (Apple_HFSX : 3)", (const char*) blkx, sizeof(BLKXTable) + (blkx->blocksRunCount * sizeof(BLKXRun)), ATTRIBUTE_HDIUTIL);
+
+ char pName[100];
+ sprintf(pName, "Mac_OS_X (Apple_HFSX : %d)", pNum + 1);
+ resources = insertData(resources, "blkx", pNum, pName, (const char*) blkx, sizeof(BLKXTable) + (blkx->blocksRunCount * sizeof(BLKXRun)), ATTRIBUTE_HDIUTIL);
free(blkx);
-
-
+
printf("Inserting cSum data...\n"); fflush(stdout);
csum.version = 1;
@@ -178,21 +179,28 @@ int buildDmg(AbstractFile* abstractIn, AbstractFile* abstractOut) {
if(nsiz == NULL) {
nsiz = myNSiz;
} else {
- myNSiz->next = nsiz->next;
- nsiz->next = myNSiz;
+ NSizResource* curNsiz = nsiz;
+ while(curNsiz->next != NULL)
+ {
+ curNsiz = curNsiz->next;
+ }
+ curNsiz->next = myNSiz;
}
+ pNum++;
+
printf("Writing free partition...\n"); fflush(stdout);
- writeFreePartition(abstractOut, (volumeHeader->totalBlocks * volumeHeader->blockSize)/SECTOR_SIZE, &resources);
+ pNum = writeFreePartition(pNum, abstractOut, USER_OFFSET + (volumeHeader->totalBlocks * volumeHeader->blockSize)/SECTOR_SIZE,
+ (FREE_SIZE + (BlockSize / SECTOR_SIZE / 2)) / (BlockSize / SECTOR_SIZE) * (BlockSize / SECTOR_SIZE), &resources);
dataForkChecksum = dataForkToken.crc;
printf("Writing XML data...\n"); fflush(stdout);
curResource = resources;
while(curResource->next != NULL)
curResource = curResource->next;
-
+
curResource->next = writeNSiz(nsiz);
curResource = curResource->next;
releaseNSiz(nsiz);
@@ -238,7 +246,8 @@ int buildDmg(AbstractFile* abstractIn, AbstractFile* abstractOut) {
printf("Master checksum: %x\n", koly.fUDIFMasterChecksum.data[0]); fflush(stdout);
koly.fUDIFImageVariant = kUDIFDeviceImageType;
- koly.fUDIFSectorCount = EXTRA_SIZE + (volumeHeader->totalBlocks * volumeHeader->blockSize)/SECTOR_SIZE;
+ koly.fUDIFSectorCount = (volumeHeader->totalBlocks * volumeHeader->blockSize)/SECTOR_SIZE
+ + ((EXTRA_SIZE + (BlockSize / SECTOR_SIZE / 2)) / (BlockSize / SECTOR_SIZE) * (BlockSize / SECTOR_SIZE));
koly.reserved2 = 0;
koly.reserved3 = 0;
koly.reserved4 = 0;
@@ -307,7 +316,7 @@ int convertToDMG(AbstractFile* abstractIn, AbstractFile* abstractOut) {
if(DDM->sbSig == DRIVER_DESCRIPTOR_SIGNATURE) {
BlockSize = DDM->sbBlkSize;
- writeDriverDescriptorMap(abstractOut, DDM, &CRCProxy, (void*) (&dataForkToken), &resources);
+ int pNum = writeDriverDescriptorMap(-1, abstractOut, DDM, BlockSize, &CRCProxy, (void*) (&dataForkToken), &resources);
free(DDM);
printf("Processing partition map...\n"); fflush(stdout);
@@ -338,7 +347,7 @@ int convertToDMG(AbstractFile* abstractIn, AbstractFile* abstractOut) {
abstractIn->seek(abstractIn, partitions[i].pmPyPartStart * BlockSize);
blkx = insertBLKX(abstractOut, abstractIn, partitions[i].pmPyPartStart, partitions[i].pmPartBlkCnt, i, CHECKSUM_CRC32,
- &BlockCRC, &uncompressedToken, &CRCProxy, &dataForkToken, NULL);
+ &BlockCRC, &uncompressedToken, &CRCProxy, &dataForkToken, NULL, 1);
blkx->checksum.data[0] = uncompressedToken.crc;
resources = insertData(resources, "blkx", i, partitionName, (const char*) blkx, sizeof(BLKXTable) + (blkx->blocksRunCount * sizeof(BLKXRun)), ATTRIBUTE_HDIUTIL);
@@ -379,7 +388,7 @@ int convertToDMG(AbstractFile* abstractIn, AbstractFile* abstractOut) {
abstractIn->seek(abstractIn, 0);
blkx = insertBLKX(abstractOut, abstractIn, 0, fileLength/SECTOR_SIZE, ENTIRE_DEVICE_DESCRIPTOR, CHECKSUM_CRC32,
- &BlockCRC, &uncompressedToken, &CRCProxy, &dataForkToken, NULL);
+ &BlockCRC, &uncompressedToken, &CRCProxy, &dataForkToken, NULL, 1);
resources = insertData(resources, "blkx", 0, "whole disk (unknown partition : 0)", (const char*) blkx, sizeof(BLKXTable) + (blkx->blocksRunCount * sizeof(BLKXRun)), ATTRIBUTE_HDIUTIL);
free(blkx);
View
153 dmg/io.c
@@ -8,9 +8,20 @@
#define SECTORS_AT_A_TIME 0x200
+// Okay, this value sucks. You shouldn't touch it because it affects how many ignore sections get added to the blkx list
+// If the blkx list gets too fragmented with ignore sections, then the copy list in certain versions of the iPhone's
+// asr becomes too big. Due to Apple's BUGGY CODE, this causes asr to segfault! This is because the copy list becomes
+// too large for the initial buffer allocated, and realloc is called by asr. Unfortunately, after the realloc, the initial
+// pointer is still used by asr for a little while! Frakking noob mistake.
+
+// The only reason why it works at all is their really idiotic algorithm to determine where to put ignore blocks. It's
+// certainly nothing reasonable like "put in an ignore block if you encounter more than X blank sectors" (like mine)
+// There's always a large-ish one at the end, and a tiny 2 sector one at the end too, to take care of the space after
+// the backup volume header. No frakking clue how they go about determining how to do that.
+
BLKXTable* insertBLKX(AbstractFile* out, AbstractFile* in, uint32_t firstSectorNumber, uint32_t numSectors, uint32_t blocksDescriptor,
uint32_t checksumType, ChecksumFunc uncompressedChk, void* uncompressedChkToken, ChecksumFunc compressedChk,
- void* compressedChkToken, Volume* volume) {
+ void* compressedChkToken, Volume* volume, int addComment) {
BLKXTable* blkx;
uint32_t roomForRuns;
@@ -23,8 +34,9 @@ BLKXTable* insertBLKX(AbstractFile* out, AbstractFile* in, uint32_t firstSectorN
size_t have;
int ret;
- z_stream strm;
-
+ int IGNORE_THRESHOLD = 100000;
+
+ z_stream strm;
blkx = (BLKXTable*) malloc(sizeof(BLKXTable) + (2 * sizeof(BLKXRun)));
roomForRuns = 2;
@@ -56,6 +68,24 @@ BLKXTable* insertBLKX(AbstractFile* out, AbstractFile* in, uint32_t firstSectorN
curRun = 0;
curSector = 0;
+ uint64_t startOff = in->tell(in);
+
+ if(addComment)
+ {
+ blkx->runs[curRun].type = BLOCK_COMMENT;
+ blkx->runs[curRun].reserved = 0x2B626567;
+ blkx->runs[curRun].sectorStart = curSector;
+ blkx->runs[curRun].sectorCount = 0;
+ blkx->runs[curRun].compOffset = out->tell(out) - blkx->dataStart;
+ blkx->runs[curRun].compLength = 0;
+ curRun++;
+
+ if(curRun >= roomForRuns) {
+ roomForRuns <<= 1;
+ blkx = (BLKXTable*) realloc(blkx, sizeof(BLKXTable) + (roomForRuns * sizeof(BLKXRun)));
+ }
+ }
+
while(numSectors > 0) {
if(curRun >= roomForRuns) {
roomForRuns <<= 1;
@@ -72,11 +102,102 @@ BLKXTable* insertBLKX(AbstractFile* out, AbstractFile* in, uint32_t firstSectorN
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
+ int amountRead;
+ {
+ size_t sectorsToSkip = 0;
+ size_t processed = 0;
+
+ while(processed < numSectors)
+ {
+ blkx->runs[curRun].sectorCount = ((numSectors - processed) > SECTORS_AT_A_TIME) ? SECTORS_AT_A_TIME : (numSectors - processed);
+
+ //printf("Currently at %" PRId64 "\n", curOff);
+ in->seek(in, startOff + (blkx->sectorCount - numSectors + processed) * SECTOR_SIZE);
+ ASSERT((amountRead = in->read(in, inBuffer, blkx->runs[curRun].sectorCount * SECTOR_SIZE)) == (blkx->runs[curRun].sectorCount * SECTOR_SIZE), "mRead");
+
+ if(!addComment)
+ break;
+
+ processed += amountRead / SECTOR_SIZE;
+
+ size_t* checkBuffer = (size_t*) inBuffer;
+ size_t counter;
+ size_t counter_max = amountRead / sizeof(size_t);
+ for(counter = 0; counter < counter_max; counter++)
+ {
+ if(checkBuffer[counter] != 0) {
+ //printf("Not empty at %" PRId64 " / %" PRId64 "\n", (int64_t)(counter * sizeof(size_t)) + curOff, (int64_t)((counter * sizeof(size_t)) / SECTOR_SIZE + sectorsToSkip + blkx->runs[curRun].sectorStart));
+ break;
+ }
+ }
+
+ size_t skipInBuffer = (counter * sizeof(size_t)) / SECTOR_SIZE;
+ sectorsToSkip += skipInBuffer;
+
+ //printf("sectorsToSkip: %d\n", sectorsToSkip);
+
+ if(counter < counter_max)
+ {
+ if(sectorsToSkip > IGNORE_THRESHOLD)
+ {
+ //printf("Seeking back to %" PRId64 "\n", curOff + (skipInBuffer * SECTOR_SIZE));
+ //in->seek(in, curOff + (skipInBuffer * SECTOR_SIZE));
+ } else {
+ //printf("Breaking out: %d / %d\n", (size_t) counter, (size_t) counter_max);
+ }
+ break;
+ }
+ }
+
+ if(sectorsToSkip > IGNORE_THRESHOLD)
+ {
+ int remainder = sectorsToSkip & 0xf;
+
+ if(sectorsToSkip != remainder)
+ {
+ blkx->runs[curRun].type = BLOCK_IGNORE;
+ blkx->runs[curRun].reserved = 0;
+ blkx->runs[curRun].sectorStart = curSector;
+ blkx->runs[curRun].sectorCount = sectorsToSkip - remainder;
+ blkx->runs[curRun].compOffset = out->tell(out) - blkx->dataStart;
+ blkx->runs[curRun].compLength = 0;
+
+ printf("run %d: skipping sectors=%" PRId64 ", left=%d\n", curRun, (int64_t) sectorsToSkip, numSectors);
+
+ curSector += blkx->runs[curRun].sectorCount;
+ numSectors -= blkx->runs[curRun].sectorCount;
+
+ curRun++;
+ }
+
+ if(remainder > 0)
+ {
+ blkx->runs[curRun].type = BLOCK_IGNORE;
+ blkx->runs[curRun].reserved = 0;
+ blkx->runs[curRun].sectorStart = curSector;
+ blkx->runs[curRun].sectorCount = remainder;
+ blkx->runs[curRun].compOffset = out->tell(out) - blkx->dataStart;
+ blkx->runs[curRun].compLength = 0;
+
+ printf("run %d: skipping sectors=%" PRId64 ", left=%d\n", curRun, (int64_t) sectorsToSkip, numSectors);
+
+ curSector += blkx->runs[curRun].sectorCount;
+ numSectors -= blkx->runs[curRun].sectorCount;
+
+ curRun++;
+ }
+
+ IGNORE_THRESHOLD = 0;
+
+ continue;
+ }
+ }
+
printf("run %d: sectors=%" PRId64 ", left=%d\n", curRun, blkx->runs[curRun].sectorCount, numSectors);
+
+ ASSERT(deflateInit(&strm, 1) == Z_OK, "deflateInit");
- ASSERT(deflateInit(&strm, Z_DEFAULT_COMPRESSION) == Z_OK, "deflateInit");
-
- ASSERT((strm.avail_in = in->read(in, inBuffer, blkx->runs[curRun].sectorCount * SECTOR_SIZE)) == (blkx->runs[curRun].sectorCount * SECTOR_SIZE), "mRead");
+ strm.avail_in = amountRead;
strm.next_in = inBuffer;
if(uncompressedChk)
@@ -94,7 +215,7 @@ BLKXTable* insertBLKX(AbstractFile* out, AbstractFile* in, uint32_t firstSectorN
}
have = bufferSize - strm.avail_out;
- if((have / SECTOR_SIZE) > blkx->runs[curRun].sectorCount) {
+ if((have / SECTOR_SIZE) >= (blkx->runs[curRun].sectorCount - 15)) {
blkx->runs[curRun].type = BLOCK_RAW;
ASSERT(out->write(out, inBuffer, blkx->runs[curRun].sectorCount * SECTOR_SIZE) == (blkx->runs[curRun].sectorCount * SECTOR_SIZE), "fwrite");
blkx->runs[curRun].compLength += blkx->runs[curRun].sectorCount * SECTOR_SIZE;
@@ -122,7 +243,23 @@ BLKXTable* insertBLKX(AbstractFile* out, AbstractFile* in, uint32_t firstSectorN
roomForRuns <<= 1;
blkx = (BLKXTable*) realloc(blkx, sizeof(BLKXTable) + (roomForRuns * sizeof(BLKXRun)));
}
-
+
+ if(addComment)
+ {
+ blkx->runs[curRun].type = BLOCK_COMMENT;
+ blkx->runs[curRun].reserved = 0x2B656E64;
+ blkx->runs[curRun].sectorStart = curSector;
+ blkx->runs[curRun].sectorCount = 0;
+ blkx->runs[curRun].compOffset = out->tell(out) - blkx->dataStart;
+ blkx->runs[curRun].compLength = 0;
+ curRun++;
+
+ if(curRun >= roomForRuns) {
+ roomForRuns <<= 1;
+ blkx = (BLKXTable*) realloc(blkx, sizeof(BLKXTable) + (roomForRuns * sizeof(BLKXRun)));
+ }
+ }
+
blkx->runs[curRun].type = BLOCK_TERMINATOR;
blkx->runs[curRun].reserved = 0;
blkx->runs[curRun].sectorStart = curSector;
Oops, something went wrong.

0 comments on commit 5c8b075

Please sign in to comment.