diff --git a/third_party/libdmg-hfsplus/src/dmg/dmg.c b/third_party/libdmg-hfsplus/src/dmg/dmg.c index 511e2f5e8037b..029dd1137306f 100644 --- a/third_party/libdmg-hfsplus/src/dmg/dmg.c +++ b/third_party/libdmg-hfsplus/src/dmg/dmg.c @@ -47,7 +47,7 @@ void usage(const char *name) { printf("\t--compression, -c compressor name (%s)\n", compressionNames()); printf("\t--level, -l compression level\n"); printf("\t--run-sectors, -r run size (in sectors)\n"); - printf("\t--data-format, -d encoding format for attribution or sentinel data (attribute command only)\n"); + printf("\t--data-format, -d encoding format for attribution or sentinel data (attribute and build commands only)\n"); printf("\t supported formats: %s\n", dataFormats); exit(2); } @@ -128,11 +128,14 @@ int main(int argc, char* argv[]) { } extractDmg(in, out, partNum); } else if(strcmp(cmd, "build") == 0) { - char *anchor = NULL; + SizedBuf *anchor = NULL; if (optind < argc) { - anchor = argv[optind++]; + anchor = data_param_parser(argv[optind++]); + } + buildDmgWithSentinelBuf(in, out, SECTOR_SIZE, anchor, &comp, runSectors); + if (anchor) { + free(anchor); } - buildDmg(in, out, SECTOR_SIZE, anchor, &comp, runSectors); } else if(strcmp(cmd, "build2048") == 0) { buildDmg(in, out, 2048, NULL, &comp, runSectors); } else if(strcmp(cmd, "res") == 0) { diff --git a/third_party/libdmg-hfsplus/src/dmg/dmglib.c b/third_party/libdmg-hfsplus/src/dmg/dmglib.c index 1f160562131e5..0c5e538f189b9 100644 --- a/third_party/libdmg-hfsplus/src/dmg/dmglib.c +++ b/third_party/libdmg-hfsplus/src/dmg/dmglib.c @@ -4,6 +4,7 @@ #include #include #include +#include "sizedbuf.h" uint32_t calculateMasterChecksum(ResourceKey* resources); @@ -89,6 +90,13 @@ uint32_t calculateMasterChecksum(ResourceKey* resources) { } int buildDmg(AbstractFile* abstractIn, AbstractFile* abstractOut, unsigned int BlockSize, const char* sentinel, Compressor *comp, size_t runSectors) { + SizedBuf* sentinelBuf = AllocBufCopyString(sentinel); + int ret = buildDmgWithSentinelBuf(abstractIn, abstractOut, BlockSize, sentinelBuf, comp, runSectors); + free(sentinelBuf); + return ret; +} + +int buildDmgWithSentinelBuf(AbstractFile* abstractIn, AbstractFile* abstractOut, unsigned int BlockSize, const SizedBuf* sentinel, Compressor *comp, size_t runSectors) { io_func* io; Volume* volume; @@ -151,7 +159,7 @@ int buildDmg(AbstractFile* abstractIn, AbstractFile* abstractOut, unsigned int B AbstractAttribution* attribution = NULL; if (sentinel) { - attribution = createAbstractAttributionPreservingSentinel(sentinel); + attribution = createAbstractAttributionPreservingSentinelBuf(sentinel); } if (attribution) { diff --git a/third_party/libdmg-hfsplus/src/includes/dmg/dmg.h b/third_party/libdmg-hfsplus/src/includes/dmg/dmg.h index f7db35209e8da..27b1292720ee0 100644 --- a/third_party/libdmg-hfsplus/src/includes/dmg/dmg.h +++ b/third_party/libdmg-hfsplus/src/includes/dmg/dmg.h @@ -351,7 +351,28 @@ extern "C" { int extractDmg(AbstractFile* abstractIn, AbstractFile* abstractOut, int partNum); + + // Convert the uncompressed raw UDIF represented by `abstractIn` into a + // (potentially) compressed fully structured DMG using compression defined + // by `comp`. The first chunk, or consecutive pair of chunks, containing + // the exact binary content in `sentinel` is left uncompressed, and + // information to support DMG re-attribution (around the sentinel) is + // embeded in the DMG's resources. To skip this behavior, pass NULL for + // `sentinel`. + // + // `BlockSize` specifies the block size to use for the simulated disk. + // `runSectors` specifies how many blocks are contained per DMG "chunk" and + // compressed together. Longer runs compress better but require more CPU + // effort to compress and decompress, and create a larger uncompressed + // region around a sentinel. + int buildDmgWithSentinelBuf(AbstractFile* abstractIn, AbstractFile* abstractOut, unsigned int BlockSize, const SizedBuf* sentinel, Compressor *comp, size_t runSectors); + + // buildDmg is equivalent to buildDmgWithSentinelBuf, but sentinel must be a + // literal C string and therefore cannot contain any bytes with value zero. + // + // Prefer buildDmgWithSentinelBuf for new uses. int buildDmg(AbstractFile* abstractIn, AbstractFile* abstractOut, unsigned int BlockSize, const char* sentinel, Compressor *comp, size_t runSectors); + int convertToISO(AbstractFile* abstractIn, AbstractFile* abstractOut); int convertToDMG(AbstractFile* abstractIn, AbstractFile* abstractOut, Compressor* comp, size_t runSectors); #ifdef __cplusplus