Fixed block descriptor bug (didn't seem to affect anything in practice). Partial implementation of iso to dmg
This commit is contained in:
Родитель
78422cd0b4
Коммит
780984d5dd
190
dmg/dmg.c
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;
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче