Fixed block descriptor bug (didn't seem to affect anything in practice). Partial implementation of iso to dmg

This commit is contained in:
planetbeing 2008-04-24 10:42:09 -04:00
Родитель 78422cd0b4
Коммит 780984d5dd
4 изменённых файлов: 192 добавлений и 10 удалений

190
dmg/dmg.c
Просмотреть файл

@ -117,7 +117,7 @@ int buildDmg(const char* source, const char* dest) {
printf("Writing main data blkx...\n"); fflush(stdout);
fseeko(file, 0, SEEK_SET);
blkx = insertBLKX(outFile, (void*) file, USER_OFFSET, (volumeHeader->totalBlocks * volumeHeader->blockSize)/SECTOR_SIZE, 0, CHECKSUM_CRC32, &freadWrapper, &fseekWrapper, &ftellWrapper,
blkx = insertBLKX(outFile, (void*) file, USER_OFFSET, (volumeHeader->totalBlocks * volumeHeader->blockSize)/SECTOR_SIZE, 2, CHECKSUM_CRC32, &freadWrapper, &fseekWrapper, &ftellWrapper,
&BlockSHA1CRC, &uncompressedToken, &CRCProxy, &dataForkToken, volume);
blkx->checksum.data[0] = uncompressedToken.crc;
@ -216,9 +216,9 @@ int buildDmg(const char* source, const char* dest) {
koly.reserved2 = 0;
koly.reserved3 = 0;
koly.reserved4 = 0;
printf("Writing out UDIF resource file...\n"); fflush(stdout);
writeUDIFResourceFile(outFile, &koly);
printf("Cleaning up...\n"); fflush(stdout);
@ -235,6 +235,182 @@ int buildDmg(const char* source, const char* dest) {
return TRUE;
}
int convertToDMG(const char* source, const char* dest) {
FILE* file;
FILE* outFile;
Partition* partitions;
DriverDescriptorRecord* DDM;
int i;
BLKXTable* blkx;
ResourceKey* resources;
ResourceKey* curResource;
ChecksumToken dataForkToken;
ChecksumToken uncompressedToken;
NSizResource* nsiz;
NSizResource* myNSiz;
CSumResource csum;
off_t plistOffset;
uint32_t plistSize;
uint32_t dataForkChecksum;
uint64_t numSectors;
UDIFResourceFile koly;
char partitionName[512];
numSectors = 0;
resources = NULL;
nsiz = NULL;
myNSiz = NULL;
memset(&dataForkToken, 0, sizeof(ChecksumToken));
partitions = (Partition*) malloc(SECTOR_SIZE);
ASSERT(file = fopen(source, "rb"), "fopen");
ASSERT(outFile = fopen(dest, "wb"), "fopen");
printf("Writing DDM...\n"); fflush(stdout);
DDM = (DriverDescriptorRecord*) malloc(SECTOR_SIZE);
fseeko(file, 0, SEEK_SET);
ASSERT(fread(DDM, SECTOR_SIZE, 1, file) == 1, "fread");
flipDriverDescriptorRecord(DDM, FALSE);
writeDriverDescriptorMap(outFile, DDM, &CRCProxy, (void*) (&dataForkToken), &resources);
free(DDM);
printf("Reading partition map...\n"); fflush(stdout);
fseeko(file, SECTOR_SIZE, SEEK_SET);
ASSERT(fread(partitions, SECTOR_SIZE, 1, file) == 1, "fread");
flipPartition(partitions, FALSE);
partitions = (Partition*) realloc(partitions, SECTOR_SIZE * partitions->pmMapBlkCnt);
fseeko(file, SECTOR_SIZE, SEEK_SET);
ASSERT(fread(partitions, SECTOR_SIZE * partitions->pmMapBlkCnt, 1, file) == 1, "fread");
flipPartition(partitions, FALSE);
printf("Writing blkx...\n"); fflush(stdout);
for(i = 0; i < partitions->pmPartBlkCnt; i++) {
if(partitions[i].pmSig != APPLE_PARTITION_MAP_SIGNATURE) {
break;
}
printf("Processing blkx %d...\n", i); fflush(stdout);
sprintf(partitionName, "%s (%s : %d)", partitions[i].pmPartName, partitions[i].pmParType, i + 1);
memset(&uncompressedToken, 0, sizeof(uncompressedToken));
fseeko(file, partitions[i].pmPyPartStart * SECTOR_SIZE, SEEK_SET);
blkx = insertBLKX(outFile, (void*) file, partitions[i].pmPyPartStart * SECTOR_SIZE, partitions[i].pmPartBlkCnt, i, CHECKSUM_CRC32, &freadWrapper, &fseekWrapper, &ftellWrapper,
&BlockCRC, &uncompressedToken, &CRCProxy, &dataForkToken, NULL);
blkx->checksum.data[0] = uncompressedToken.crc;
resources = insertData(resources, "blkx", i, partitionName, (const char*) blkx, sizeof(BLKXTable) + (blkx->blocksRunCount * sizeof(BLKXRun)), ATTRIBUTE_HDIUTIL);
free(blkx);
memset(&csum, 0, sizeof(CSumResource));
csum.version = 1;
csum.type = CHECKSUM_MKBLOCK;
csum.checksum = uncompressedToken.block;
resources = insertData(resources, "cSum", i, "", (const char*) (&csum), sizeof(csum), 0);
if(nsiz == NULL) {
nsiz = myNSiz = (NSizResource*) malloc(sizeof(NSizResource));
} else {
myNSiz->next = (NSizResource*) malloc(sizeof(NSizResource));
myNSiz = myNSiz->next;
}
memset(myNSiz, 0, sizeof(NSizResource));
myNSiz->isVolume = FALSE;
myNSiz->blockChecksum2 = uncompressedToken.block;
myNSiz->partitionNumber = i;
myNSiz->version = 6;
myNSiz->next = NULL;
if((partitions[i].pmPyPartStart + partitions[i].pmPartBlkCnt) > numSectors) {
numSectors = partitions[i].pmPyPartStart + partitions[i].pmPartBlkCnt;
}
}
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);
curResource->next = makePlst();
curResource = curResource->next;
plistOffset = ftello(outFile);
writeResources(outFile, resources);
plistSize = ftello(outFile) - plistOffset;
printf("Generating UDIF metadata...\n"); fflush(stdout);
koly.fUDIFSignature = KOLY_SIGNATURE;
koly.fUDIFVersion = 4;
koly.fUDIFHeaderSize = sizeof(koly);
koly.fUDIFFlags = kUDIFFlagsFlattened;
koly.fUDIFRunningDataForkOffset = 0;
koly.fUDIFDataForkOffset = 0;
koly.fUDIFDataForkLength = plistOffset;
koly.fUDIFRsrcForkOffset = 0;
koly.fUDIFRsrcForkLength = 0;
koly.fUDIFSegmentNumber = 1;
koly.fUDIFSegmentCount = 1;
koly.fUDIFSegmentID.data1 = rand();
koly.fUDIFSegmentID.data2 = rand();
koly.fUDIFSegmentID.data3 = rand();
koly.fUDIFSegmentID.data4 = rand();
koly.fUDIFDataForkChecksum.type = CHECKSUM_CRC32;
koly.fUDIFDataForkChecksum.size = 0x20;
koly.fUDIFDataForkChecksum.data[0] = dataForkChecksum;
koly.fUDIFXMLOffset = plistOffset;
koly.fUDIFXMLLength = plistSize;
memset(&(koly.reserved1), 0, 0x78);
koly.fUDIFMasterChecksum.type = CHECKSUM_CRC32;
koly.fUDIFMasterChecksum.size = 0x20;
koly.fUDIFMasterChecksum.data[0] = calculateMasterChecksum(resources);
printf("Master checksum: %x\n", koly.fUDIFMasterChecksum.data[0]); fflush(stdout);
koly.fUDIFImageVariant = kUDIFDeviceImageType;
koly.fUDIFSectorCount = numSectors;
koly.reserved2 = 0;
koly.reserved3 = 0;
koly.reserved4 = 0;
printf("Writing out UDIF resource file...\n"); fflush(stdout);
writeUDIFResourceFile(outFile, &koly);
printf("Cleaning up...\n"); fflush(stdout);
releaseResources(resources);
fclose(file);
free(partitions);
printf("Done\n"); fflush(stdout);
return TRUE;
}
int convertToISO(const char* source, const char* dest) {
FILE* file;
FILE* outFile;
@ -267,9 +443,9 @@ int convertToISO(const char* source, const char* dest) {
}
blkx = (getResourceByKey(resources, "blkx"))->data;
printf("Writing out data..\n"); fflush(stdout);
while(blkx != NULL) {
blkxTable = (BLKXTable*)(blkx->data);
fseeko(outFile, blkxTable->firstSectorNumber * 512, SEEK_SET);
@ -283,7 +459,7 @@ int convertToISO(const char* source, const char* dest) {
fclose(file);
return TRUE;
}
int extractDmg(const char* source, const char* dest, int partNum) {
@ -348,6 +524,8 @@ int main(int argc, char* argv[]) {
buildDmg(argv[2], argv[3]);
} else if(strcmp(argv[1], "iso") == 0) {
convertToISO(argv[2], argv[3]);
} else if(strcmp(argv[1], "dmg") == 0) {
convertToDMG(argv[2], argv[3]);
}
return 0;

Просмотреть файл

@ -315,6 +315,9 @@ ResourceKey* insertData(ResourceKey* resources, const char* key, int id, const c
ResourceKey* makePlst();
ResourceKey* makeSize(HFSPlusVolumeHeader* volumeHeader);
void flipDriverDescriptorRecord(DriverDescriptorRecord* record, char out);
void flipPartition(Partition* partition, char out);
void readDriverDescriptorMap(FILE* file, ResourceKey* resources);
DriverDescriptorRecord* createDriverDescriptorMap(uint32_t numSectors);
void writeDriverDescriptorMap(FILE* file, DriverDescriptorRecord* DDM, ChecksumFunc dataForkChecksum, void* dataForkToken, ResourceKey **resources);
@ -346,4 +349,5 @@ BLKXTable* insertBLKX(FILE* out, void* in, uint32_t firstSectorNumber, uint32_t
int extractDmg(const char* source, const char* dest, int partNum);
int buildDmg(const char* source, const char* dest);
int convertToISO(const char* source, const char* dest);
int convertToDMG(const char* source, const char* dest);

Просмотреть файл

@ -354,7 +354,7 @@ static void flipDriverDescriptor(DriverDescriptor* descriptor) {
FLIPENDIAN(descriptor->ddType);
}
static void flipDriverDescriptorRecord(DriverDescriptorRecord* record, char out) {
void flipDriverDescriptorRecord(DriverDescriptorRecord* record, char out) {
int i;
FLIPENDIAN(record->sbSig);
@ -380,7 +380,7 @@ static void flipDriverDescriptorRecord(DriverDescriptorRecord* record, char out)
}
}
static void flipPartition(Partition* partition, char out) {
void flipPartition(Partition* partition, char out) {
int i;
int numPartitions;
@ -564,7 +564,7 @@ void writeATAPI(FILE* file, ChecksumFunc dataForkChecksum, void* dataForkToken,
info.bufferSize = PARTITION_SIZE * SECTOR_SIZE;
info.buffer = (unsigned char*) atapi_data;
blkx = insertBLKX(file, (void*) (&info), ATAPI_OFFSET, ATAPI_SIZE, 0, CHECKSUM_CRC32, &memRead, &memSeek, &memTell,
blkx = insertBLKX(file, (void*) (&info), ATAPI_OFFSET, ATAPI_SIZE, 1, CHECKSUM_CRC32, &memRead, &memSeek, &memTell,
&BlockCRC, &uncompressedToken, dataForkChecksum, dataForkToken, NULL);
blkx->checksum.data[0] = uncompressedToken.crc;

Просмотреть файл

@ -19,7 +19,7 @@
#define APPLE_TO_UNIX_TIME(x) ((x) - TIME_OFFSET_FROM_UNIX)
#define UNIX_TO_APPLE_TIME(x) ((x) + TIME_OFFSET_FROM_UNIX)
#define ASSERT(x, m) if(!(x)) { fflush(stdout); fprintf(stderr, "error: %s\n", m); fflush(stderr); exit(1); }
#define ASSERT(x, m) if(!(x)) { fflush(stdout); fprintf(stderr, "error: %s\n", m); perror("error"); fflush(stderr); exit(1); }
extern char endianness;