Fixed bugs and implemented iso to dmg conversion
This commit is contained in:
Родитель
780984d5dd
Коммит
a5a0490222
115
dmg/dmg.c
115
dmg/dmg.c
|
@ -262,6 +262,9 @@ int convertToDMG(const char* source, const char* dest) {
|
||||||
|
|
||||||
char partitionName[512];
|
char partitionName[512];
|
||||||
|
|
||||||
|
off_t fileLength;
|
||||||
|
|
||||||
|
|
||||||
numSectors = 0;
|
numSectors = 0;
|
||||||
|
|
||||||
resources = NULL;
|
resources = NULL;
|
||||||
|
@ -274,54 +277,95 @@ int convertToDMG(const char* source, const char* dest) {
|
||||||
ASSERT(file = fopen(source, "rb"), "fopen");
|
ASSERT(file = fopen(source, "rb"), "fopen");
|
||||||
ASSERT(outFile = fopen(dest, "wb"), "fopen");
|
ASSERT(outFile = fopen(dest, "wb"), "fopen");
|
||||||
|
|
||||||
printf("Writing DDM...\n"); fflush(stdout);
|
printf("Processing DDM...\n"); fflush(stdout);
|
||||||
DDM = (DriverDescriptorRecord*) malloc(SECTOR_SIZE);
|
DDM = (DriverDescriptorRecord*) malloc(SECTOR_SIZE);
|
||||||
fseeko(file, 0, SEEK_SET);
|
fseeko(file, 0, SEEK_SET);
|
||||||
ASSERT(fread(DDM, SECTOR_SIZE, 1, file) == 1, "fread");
|
ASSERT(fread(DDM, SECTOR_SIZE, 1, file) == 1, "fread");
|
||||||
flipDriverDescriptorRecord(DDM, FALSE);
|
flipDriverDescriptorRecord(DDM, FALSE);
|
||||||
|
|
||||||
writeDriverDescriptorMap(outFile, DDM, &CRCProxy, (void*) (&dataForkToken), &resources);
|
if(DDM->sbSig == 0x4552) {
|
||||||
free(DDM);
|
writeDriverDescriptorMap(outFile, DDM, &CRCProxy, (void*) (&dataForkToken), &resources);
|
||||||
|
free(DDM);
|
||||||
printf("Reading partition map...\n"); fflush(stdout);
|
|
||||||
|
printf("Processing partition map...\n"); fflush(stdout);
|
||||||
fseeko(file, SECTOR_SIZE, SEEK_SET);
|
|
||||||
ASSERT(fread(partitions, SECTOR_SIZE, 1, file) == 1, "fread");
|
fseeko(file, SECTOR_SIZE, SEEK_SET);
|
||||||
flipPartition(partitions, FALSE);
|
ASSERT(fread(partitions, SECTOR_SIZE, 1, file) == 1, "fread");
|
||||||
|
flipPartition(partitions, FALSE);
|
||||||
partitions = (Partition*) realloc(partitions, SECTOR_SIZE * partitions->pmMapBlkCnt);
|
|
||||||
|
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");
|
fseeko(file, SECTOR_SIZE, SEEK_SET);
|
||||||
flipPartition(partitions, FALSE);
|
ASSERT(fread(partitions, SECTOR_SIZE * partitions->pmMapBlkCnt, 1, file) == 1, "fread");
|
||||||
|
flipPartition(partitions, FALSE);
|
||||||
printf("Writing blkx...\n"); fflush(stdout);
|
|
||||||
|
printf("Writing blkx...\n"); fflush(stdout);
|
||||||
for(i = 0; i < partitions->pmPartBlkCnt; i++) {
|
|
||||||
if(partitions[i].pmSig != APPLE_PARTITION_MAP_SIGNATURE) {
|
for(i = 0; i < partitions->pmPartBlkCnt; i++) {
|
||||||
break;
|
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, 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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("Processing blkx %d...\n", i); fflush(stdout);
|
koly.fUDIFImageVariant = kUDIFDeviceImageType;
|
||||||
|
} else {
|
||||||
|
printf("No DDM! Just doing one huge blkx then...\n"); fflush(stdout);
|
||||||
|
|
||||||
sprintf(partitionName, "%s (%s : %d)", partitions[i].pmPartName, partitions[i].pmParType, i + 1);
|
fseeko(file, 0, SEEK_END);
|
||||||
|
fileLength = ftello(file);
|
||||||
|
|
||||||
memset(&uncompressedToken, 0, sizeof(uncompressedToken));
|
memset(&uncompressedToken, 0, sizeof(uncompressedToken));
|
||||||
|
|
||||||
fseeko(file, partitions[i].pmPyPartStart * SECTOR_SIZE, SEEK_SET);
|
fseeko(file, 0, SEEK_SET);
|
||||||
blkx = insertBLKX(outFile, (void*) file, partitions[i].pmPyPartStart * SECTOR_SIZE, partitions[i].pmPartBlkCnt, i, CHECKSUM_CRC32, &freadWrapper, &fseekWrapper, &ftellWrapper,
|
blkx = insertBLKX(outFile, (void*) file, 0, fileLength/SECTOR_SIZE, ENTIRE_DEVICE_DESCRIPTOR, CHECKSUM_CRC32, &freadWrapper, &fseekWrapper, &ftellWrapper,
|
||||||
&BlockCRC, &uncompressedToken, &CRCProxy, &dataForkToken, NULL);
|
&BlockCRC, &uncompressedToken, &CRCProxy, &dataForkToken, NULL);
|
||||||
|
resources = insertData(resources, "blkx", 0, "whole disk (unknown partition : 0)", (const char*) blkx, sizeof(BLKXTable) + (blkx->blocksRunCount * sizeof(BLKXRun)), ATTRIBUTE_HDIUTIL);
|
||||||
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);
|
free(blkx);
|
||||||
|
|
||||||
memset(&csum, 0, sizeof(CSumResource));
|
memset(&csum, 0, sizeof(CSumResource));
|
||||||
csum.version = 1;
|
csum.version = 1;
|
||||||
csum.type = CHECKSUM_MKBLOCK;
|
csum.type = CHECKSUM_MKBLOCK;
|
||||||
csum.checksum = uncompressedToken.block;
|
csum.checksum = uncompressedToken.block;
|
||||||
resources = insertData(resources, "cSum", i, "", (const char*) (&csum), sizeof(csum), 0);
|
resources = insertData(resources, "cSum", 0, "", (const char*) (&csum), sizeof(csum), 0);
|
||||||
|
|
||||||
if(nsiz == NULL) {
|
if(nsiz == NULL) {
|
||||||
nsiz = myNSiz = (NSizResource*) malloc(sizeof(NSizResource));
|
nsiz = myNSiz = (NSizResource*) malloc(sizeof(NSizResource));
|
||||||
} else {
|
} else {
|
||||||
|
@ -332,13 +376,11 @@ int convertToDMG(const char* source, const char* dest) {
|
||||||
memset(myNSiz, 0, sizeof(NSizResource));
|
memset(myNSiz, 0, sizeof(NSizResource));
|
||||||
myNSiz->isVolume = FALSE;
|
myNSiz->isVolume = FALSE;
|
||||||
myNSiz->blockChecksum2 = uncompressedToken.block;
|
myNSiz->blockChecksum2 = uncompressedToken.block;
|
||||||
myNSiz->partitionNumber = i;
|
myNSiz->partitionNumber = 0;
|
||||||
myNSiz->version = 6;
|
myNSiz->version = 6;
|
||||||
myNSiz->next = NULL;
|
myNSiz->next = NULL;
|
||||||
|
|
||||||
if((partitions[i].pmPyPartStart + partitions[i].pmPartBlkCnt) > numSectors) {
|
koly.fUDIFImageVariant = kUDIFPartitionImageType;
|
||||||
numSectors = partitions[i].pmPyPartStart + partitions[i].pmPartBlkCnt;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dataForkChecksum = dataForkToken.crc;
|
dataForkChecksum = dataForkToken.crc;
|
||||||
|
@ -389,7 +431,6 @@ int convertToDMG(const char* source, const char* dest) {
|
||||||
koly.fUDIFMasterChecksum.data[0] = calculateMasterChecksum(resources);
|
koly.fUDIFMasterChecksum.data[0] = calculateMasterChecksum(resources);
|
||||||
printf("Master checksum: %x\n", koly.fUDIFMasterChecksum.data[0]); fflush(stdout);
|
printf("Master checksum: %x\n", koly.fUDIFMasterChecksum.data[0]); fflush(stdout);
|
||||||
|
|
||||||
koly.fUDIFImageVariant = kUDIFDeviceImageType;
|
|
||||||
koly.fUDIFSectorCount = numSectors;
|
koly.fUDIFSectorCount = numSectors;
|
||||||
koly.reserved2 = 0;
|
koly.reserved2 = 0;
|
||||||
koly.reserved3 = 0;
|
koly.reserved3 = 0;
|
||||||
|
@ -402,7 +443,7 @@ int convertToDMG(const char* source, const char* dest) {
|
||||||
printf("Cleaning up...\n"); fflush(stdout);
|
printf("Cleaning up...\n"); fflush(stdout);
|
||||||
|
|
||||||
releaseResources(resources);
|
releaseResources(resources);
|
||||||
|
|
||||||
fclose(file);
|
fclose(file);
|
||||||
free(partitions);
|
free(partitions);
|
||||||
|
|
||||||
|
|
315
dmg/dmg.h
315
dmg/dmg.h
|
@ -40,177 +40,178 @@
|
||||||
#define BOOTCODE_GOON 0x676F6F6E
|
#define BOOTCODE_GOON 0x676F6F6E
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
kUDIFFlagsFlattened = 1
|
kUDIFFlagsFlattened = 1
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
kUDIFDeviceImageType = 1
|
kUDIFDeviceImageType = 1,
|
||||||
|
kUDIFPartitionImageType = 2
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t type;
|
uint32_t type;
|
||||||
uint32_t size;
|
uint32_t size;
|
||||||
uint32_t data[0x20];
|
uint32_t data[0x20];
|
||||||
} __attribute__((__packed__)) UDIFChecksum;
|
} __attribute__((__packed__)) UDIFChecksum;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t data1; /* smallest */
|
uint32_t data1; /* smallest */
|
||||||
uint32_t data2;
|
uint32_t data2;
|
||||||
uint32_t data3;
|
uint32_t data3;
|
||||||
uint32_t data4; /* largest */
|
uint32_t data4; /* largest */
|
||||||
} __attribute__((__packed__)) UDIFID;
|
} __attribute__((__packed__)) UDIFID;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t fUDIFSignature;
|
uint32_t fUDIFSignature;
|
||||||
uint32_t fUDIFVersion;
|
uint32_t fUDIFVersion;
|
||||||
uint32_t fUDIFHeaderSize;
|
uint32_t fUDIFHeaderSize;
|
||||||
uint32_t fUDIFFlags;
|
uint32_t fUDIFFlags;
|
||||||
|
|
||||||
uint64_t fUDIFRunningDataForkOffset;
|
uint64_t fUDIFRunningDataForkOffset;
|
||||||
uint64_t fUDIFDataForkOffset;
|
uint64_t fUDIFDataForkOffset;
|
||||||
uint64_t fUDIFDataForkLength;
|
uint64_t fUDIFDataForkLength;
|
||||||
uint64_t fUDIFRsrcForkOffset;
|
uint64_t fUDIFRsrcForkOffset;
|
||||||
uint64_t fUDIFRsrcForkLength;
|
uint64_t fUDIFRsrcForkLength;
|
||||||
|
|
||||||
uint32_t fUDIFSegmentNumber;
|
uint32_t fUDIFSegmentNumber;
|
||||||
uint32_t fUDIFSegmentCount;
|
uint32_t fUDIFSegmentCount;
|
||||||
UDIFID fUDIFSegmentID; /* a 128-bit number like a GUID, but does not seem to be a OSF GUID, since it doesn't have the proper versioning byte */
|
UDIFID fUDIFSegmentID; /* a 128-bit number like a GUID, but does not seem to be a OSF GUID, since it doesn't have the proper versioning byte */
|
||||||
|
|
||||||
UDIFChecksum fUDIFDataForkChecksum;
|
UDIFChecksum fUDIFDataForkChecksum;
|
||||||
|
|
||||||
uint64_t fUDIFXMLOffset;
|
uint64_t fUDIFXMLOffset;
|
||||||
uint64_t fUDIFXMLLength;
|
uint64_t fUDIFXMLLength;
|
||||||
|
|
||||||
uint8_t reserved1[0x78]; /* this is actually the perfect amount of space to store every thing in this struct until the checksum */
|
uint8_t reserved1[0x78]; /* this is actually the perfect amount of space to store every thing in this struct until the checksum */
|
||||||
|
|
||||||
UDIFChecksum fUDIFMasterChecksum;
|
UDIFChecksum fUDIFMasterChecksum;
|
||||||
|
|
||||||
uint32_t fUDIFImageVariant;
|
uint32_t fUDIFImageVariant;
|
||||||
uint64_t fUDIFSectorCount;
|
uint64_t fUDIFSectorCount;
|
||||||
|
|
||||||
uint32_t reserved2;
|
uint32_t reserved2;
|
||||||
uint32_t reserved3;
|
uint32_t reserved3;
|
||||||
uint32_t reserved4;
|
uint32_t reserved4;
|
||||||
|
|
||||||
} __attribute__((__packed__)) UDIFResourceFile;
|
} __attribute__((__packed__)) UDIFResourceFile;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t type;
|
uint32_t type;
|
||||||
uint32_t reserved;
|
uint32_t reserved;
|
||||||
uint64_t sectorStart;
|
uint64_t sectorStart;
|
||||||
uint64_t sectorCount;
|
uint64_t sectorCount;
|
||||||
uint64_t compOffset;
|
uint64_t compOffset;
|
||||||
uint64_t compLength;
|
uint64_t compLength;
|
||||||
} __attribute__((__packed__)) BLKXRun;
|
} __attribute__((__packed__)) BLKXRun;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint16_t version; /* set to 5 */
|
uint16_t version; /* set to 5 */
|
||||||
uint32_t isHFS; /* first dword of v53(ImageInfoRec): Set to 1 if it's a HFS or HFS+ partition -- duh. */
|
uint32_t isHFS; /* first dword of v53(ImageInfoRec): Set to 1 if it's a HFS or HFS+ partition -- duh. */
|
||||||
uint32_t unknown1; /* second dword of v53: seems to be garbage if it's HFS+, stuff related to HFS embedded if it's that*/
|
uint32_t unknown1; /* second dword of v53: seems to be garbage if it's HFS+, stuff related to HFS embedded if it's that*/
|
||||||
uint8_t dataLen; /* length of data that proceeds, comes right before the data in ImageInfoRec. Always set to 0 for HFS, HFS+ */
|
uint8_t dataLen; /* length of data that proceeds, comes right before the data in ImageInfoRec. Always set to 0 for HFS, HFS+ */
|
||||||
uint8_t data[255]; /* other data from v53, dataLen + 1 bytes, the rest NULL filled... a string? Not set for HFS, HFS+ */
|
uint8_t data[255]; /* other data from v53, dataLen + 1 bytes, the rest NULL filled... a string? Not set for HFS, HFS+ */
|
||||||
uint32_t unknown2; /* 8 bytes before volumeModified in v53, seems to be always set to 0 for HFS, HFS+ */
|
uint32_t unknown2; /* 8 bytes before volumeModified in v53, seems to be always set to 0 for HFS, HFS+ */
|
||||||
uint32_t unknown3; /* 4 bytes before volumeModified in v53, seems to be always set to 0 for HFS, HFS+ */
|
uint32_t unknown3; /* 4 bytes before volumeModified in v53, seems to be always set to 0 for HFS, HFS+ */
|
||||||
uint32_t volumeModified; /* offset 272 in v53 */
|
uint32_t volumeModified; /* offset 272 in v53 */
|
||||||
uint32_t unknown4; /* always seems to be 0 for UDIF */
|
uint32_t unknown4; /* always seems to be 0 for UDIF */
|
||||||
uint16_t volumeSignature; /* HX in our case */
|
uint16_t volumeSignature; /* HX in our case */
|
||||||
uint16_t sizePresent; /* always set to 1 */
|
uint16_t sizePresent; /* always set to 1 */
|
||||||
} __attribute__((__packed__)) SizeResource;
|
} __attribute__((__packed__)) SizeResource;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint16_t version; /* set to 1 */
|
uint16_t version; /* set to 1 */
|
||||||
uint32_t type; /* set to 0x2 for MKBlockChecksum */
|
uint32_t type; /* set to 0x2 for MKBlockChecksum */
|
||||||
uint32_t checksum;
|
uint32_t checksum;
|
||||||
} __attribute__((__packed__)) CSumResource;
|
} __attribute__((__packed__)) CSumResource;
|
||||||
|
|
||||||
typedef struct NSizResource {
|
typedef struct NSizResource {
|
||||||
char isVolume;
|
char isVolume;
|
||||||
unsigned char* sha1Digest;
|
unsigned char* sha1Digest;
|
||||||
uint32_t blockChecksum2;
|
uint32_t blockChecksum2;
|
||||||
uint32_t bytes;
|
uint32_t bytes;
|
||||||
uint32_t modifyDate;
|
uint32_t modifyDate;
|
||||||
uint32_t partitionNumber;
|
uint32_t partitionNumber;
|
||||||
uint32_t version;
|
uint32_t version;
|
||||||
uint32_t volumeSignature;
|
uint32_t volumeSignature;
|
||||||
struct NSizResource* next;
|
struct NSizResource* next;
|
||||||
} NSizResource;
|
} NSizResource;
|
||||||
|
|
||||||
#define DDM_DESCRIPTOR 0xFFFFFFFF
|
#define DDM_DESCRIPTOR 0xFFFFFFFF
|
||||||
#define ENTIRE_DEVICE_DESCRIPTOR 0xFFFFFFFE
|
#define ENTIRE_DEVICE_DESCRIPTOR 0xFFFFFFFE
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t fUDIFBlocksSignature;
|
uint32_t fUDIFBlocksSignature;
|
||||||
uint32_t infoVersion;
|
uint32_t infoVersion;
|
||||||
uint64_t firstSectorNumber;
|
uint64_t firstSectorNumber;
|
||||||
uint64_t sectorCount;
|
uint64_t sectorCount;
|
||||||
|
|
||||||
uint64_t dataStart;
|
uint64_t dataStart;
|
||||||
uint32_t decompressBufferRequested;
|
uint32_t decompressBufferRequested;
|
||||||
uint32_t blocksDescriptor;
|
uint32_t blocksDescriptor;
|
||||||
|
|
||||||
uint32_t reserved1;
|
uint32_t reserved1;
|
||||||
uint32_t reserved2;
|
uint32_t reserved2;
|
||||||
uint32_t reserved3;
|
uint32_t reserved3;
|
||||||
uint32_t reserved4;
|
uint32_t reserved4;
|
||||||
uint32_t reserved5;
|
uint32_t reserved5;
|
||||||
uint32_t reserved6;
|
uint32_t reserved6;
|
||||||
|
|
||||||
UDIFChecksum checksum;
|
UDIFChecksum checksum;
|
||||||
|
|
||||||
uint32_t blocksRunCount;
|
uint32_t blocksRunCount;
|
||||||
BLKXRun runs[0];
|
BLKXRun runs[0];
|
||||||
} __attribute__((__packed__)) BLKXTable;
|
} __attribute__((__packed__)) BLKXTable;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t ddBlock;
|
uint32_t ddBlock;
|
||||||
uint16_t ddSize;
|
uint16_t ddSize;
|
||||||
uint16_t ddType;
|
uint16_t ddType;
|
||||||
} __attribute__((__packed__)) DriverDescriptor;
|
} __attribute__((__packed__)) DriverDescriptor;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint16_t pmSig;
|
uint16_t pmSig;
|
||||||
uint16_t pmSigPad;
|
uint16_t pmSigPad;
|
||||||
uint32_t pmMapBlkCnt;
|
uint32_t pmMapBlkCnt;
|
||||||
uint32_t pmPyPartStart;
|
uint32_t pmPyPartStart;
|
||||||
uint32_t pmPartBlkCnt;
|
uint32_t pmPartBlkCnt;
|
||||||
unsigned char pmPartName[32];
|
unsigned char pmPartName[32];
|
||||||
unsigned char pmParType[32];
|
unsigned char pmParType[32];
|
||||||
uint32_t pmLgDataStart;
|
uint32_t pmLgDataStart;
|
||||||
uint32_t pmDataCnt;
|
uint32_t pmDataCnt;
|
||||||
uint32_t pmPartStatus;
|
uint32_t pmPartStatus;
|
||||||
uint32_t pmLgBootStart;
|
uint32_t pmLgBootStart;
|
||||||
uint32_t pmBootSize;
|
uint32_t pmBootSize;
|
||||||
uint32_t pmBootAddr;
|
uint32_t pmBootAddr;
|
||||||
uint32_t pmBootAddr2;
|
uint32_t pmBootAddr2;
|
||||||
uint32_t pmBootEntry;
|
uint32_t pmBootEntry;
|
||||||
uint32_t pmBootEntry2;
|
uint32_t pmBootEntry2;
|
||||||
uint32_t pmBootCksum;
|
uint32_t pmBootCksum;
|
||||||
unsigned char pmProcessor[16];
|
unsigned char pmProcessor[16];
|
||||||
uint32_t bootCode;
|
uint32_t bootCode;
|
||||||
uint16_t pmPad[186];
|
uint16_t pmPad[186];
|
||||||
} __attribute__((__packed__)) Partition;
|
} __attribute__((__packed__)) Partition;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint16_t sbSig;
|
uint16_t sbSig;
|
||||||
uint16_t sbBlkSize;
|
uint16_t sbBlkSize;
|
||||||
uint32_t sbBlkCount;
|
uint32_t sbBlkCount;
|
||||||
uint16_t sbDevType;
|
uint16_t sbDevType;
|
||||||
uint16_t sbDevId;
|
uint16_t sbDevId;
|
||||||
uint32_t sbData;
|
uint32_t sbData;
|
||||||
uint16_t sbDrvrCount;
|
uint16_t sbDrvrCount;
|
||||||
uint32_t ddBlock;
|
uint32_t ddBlock;
|
||||||
uint16_t ddSize;
|
uint16_t ddSize;
|
||||||
uint16_t ddType;
|
uint16_t ddType;
|
||||||
DriverDescriptor ddPad[0];
|
DriverDescriptor ddPad[0];
|
||||||
} __attribute__((__packed__)) DriverDescriptorRecord;
|
} __attribute__((__packed__)) DriverDescriptorRecord;
|
||||||
|
|
||||||
typedef struct ResourceData {
|
typedef struct ResourceData {
|
||||||
uint32_t attributes;
|
uint32_t attributes;
|
||||||
unsigned char* data;
|
unsigned char* data;
|
||||||
size_t dataLength;
|
size_t dataLength;
|
||||||
int id;
|
int id;
|
||||||
unsigned char* name;
|
unsigned char* name;
|
||||||
struct ResourceData* next;
|
struct ResourceData* next;
|
||||||
} ResourceData;
|
} ResourceData;
|
||||||
|
|
||||||
typedef void (*FlipDataFunc)(unsigned char* data, char out);
|
typedef void (*FlipDataFunc)(unsigned char* data, char out);
|
||||||
|
@ -222,16 +223,16 @@ typedef int (*SeekFunc)(void* token, off_t offset);
|
||||||
typedef off_t (*TellFunc)(void* token);
|
typedef off_t (*TellFunc)(void* token);
|
||||||
|
|
||||||
typedef struct ResourceKey {
|
typedef struct ResourceKey {
|
||||||
unsigned char* key;
|
unsigned char* key;
|
||||||
ResourceData* data;
|
ResourceData* data;
|
||||||
struct ResourceKey* next;
|
struct ResourceKey* next;
|
||||||
FlipDataFunc flipData;
|
FlipDataFunc flipData;
|
||||||
} ResourceKey;
|
} ResourceKey;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
size_t offset;
|
size_t offset;
|
||||||
unsigned char* buffer;
|
unsigned char* buffer;
|
||||||
size_t bufferSize;
|
size_t bufferSize;
|
||||||
} MemWrapperInfo;
|
} MemWrapperInfo;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -241,37 +242,37 @@ typedef struct {
|
||||||
} SHA1_CTX;
|
} SHA1_CTX;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t block;
|
uint32_t block;
|
||||||
uint32_t crc;
|
uint32_t crc;
|
||||||
SHA1_CTX sha1;
|
SHA1_CTX sha1;
|
||||||
} ChecksumToken;
|
} ChecksumToken;
|
||||||
|
|
||||||
static inline uint32_t readUInt32(FILE* file) {
|
static inline uint32_t readUInt32(FILE* file) {
|
||||||
uint32_t data;
|
uint32_t data;
|
||||||
|
|
||||||
ASSERT(fread(&data, sizeof(data), 1, file) == 1, "fread");
|
ASSERT(fread(&data, sizeof(data), 1, file) == 1, "fread");
|
||||||
FLIPENDIAN(data);
|
FLIPENDIAN(data);
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void writeUInt32(FILE* file, uint32_t data) {
|
static inline void writeUInt32(FILE* file, uint32_t data) {
|
||||||
FLIPENDIAN(data);
|
FLIPENDIAN(data);
|
||||||
ASSERT(fwrite(&data, sizeof(data), 1, file) == 1, "fwrite");
|
ASSERT(fwrite(&data, sizeof(data), 1, file) == 1, "fwrite");
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint32_t readUInt64(FILE* file) {
|
static inline uint32_t readUInt64(FILE* file) {
|
||||||
uint64_t data;
|
uint64_t data;
|
||||||
|
|
||||||
ASSERT(fread(&data, sizeof(data), 1, file) == 1, "fread");
|
ASSERT(fread(&data, sizeof(data), 1, file) == 1, "fread");
|
||||||
FLIPENDIAN(data);
|
FLIPENDIAN(data);
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void writeUInt64(FILE* file, uint64_t data) {
|
static inline void writeUInt64(FILE* file, uint64_t data) {
|
||||||
FLIPENDIAN(data);
|
FLIPENDIAN(data);
|
||||||
ASSERT(fwrite(&data, sizeof(data), 1, file) == 1, "fwrite");
|
ASSERT(fwrite(&data, sizeof(data), 1, file) == 1, "fwrite");
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned char* decodeBase64(char* toDecode, size_t* dataLength);
|
unsigned char* decodeBase64(char* toDecode, size_t* dataLength);
|
||||||
|
@ -343,8 +344,8 @@ off_t memTell(void* token);
|
||||||
|
|
||||||
void extractBLKX(FILE* in, void* out, BLKXTable* blkx, WriteFunc mWrite, SeekFunc mSeek, TellFunc mTell);
|
void extractBLKX(FILE* in, void* out, BLKXTable* blkx, WriteFunc mWrite, SeekFunc mSeek, TellFunc mTell);
|
||||||
BLKXTable* insertBLKX(FILE* out, void* in, uint32_t firstSectorNumber, uint32_t numSectors, uint32_t blocksDescriptor, uint32_t checksumType,
|
BLKXTable* insertBLKX(FILE* out, void* in, uint32_t firstSectorNumber, uint32_t numSectors, uint32_t blocksDescriptor, uint32_t checksumType,
|
||||||
ReadFunc mRead, SeekFunc mSeek, TellFunc mTell,
|
ReadFunc mRead, SeekFunc mSeek, TellFunc mTell,
|
||||||
ChecksumFunc uncompressedChk, void* uncompressedChkToken, ChecksumFunc compressedChk, void* compressedChkToken, Volume* volume);
|
ChecksumFunc uncompressedChk, void* uncompressedChkToken, ChecksumFunc compressedChk, void* compressedChkToken, Volume* volume);
|
||||||
|
|
||||||
int extractDmg(const char* source, const char* dest, int partNum);
|
int extractDmg(const char* source, const char* dest, int partNum);
|
||||||
int buildDmg(const char* source, const char* dest);
|
int buildDmg(const char* source, const char* dest);
|
||||||
|
|
Загрузка…
Ссылка в новой задаче