Permalink
Find file
Fetching contributors…
Cannot retrieve contributors at this time
911 lines (755 sloc) 27.5 KB
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "dmg.h"
static char plstData[1032] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
const char *plistHeader =
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC "
"\"-//Apple//DTD PLIST 1.0//EN\" "
"\"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist "
"version=\"1.0\">\n<dict>\n";
const char *plistFooter = "</dict>\n</plist>\n";
static void flipSizeResource(unsigned char *data, char out) {
SizeResource *size;
size = (SizeResource *)data;
FLIPENDIANLE(size->version);
FLIPENDIANLE(size->isHFS);
FLIPENDIANLE(size->unknown2);
FLIPENDIANLE(size->unknown3);
FLIPENDIANLE(size->volumeModified);
FLIPENDIANLE(size->unknown4);
FLIPENDIANLE(size->volumeSignature);
FLIPENDIANLE(size->sizePresent);
}
static void flipCSumResource(unsigned char *data, char out) {
CSumResource *cSum;
cSum = (CSumResource *)data;
FLIPENDIANLE(cSum->version);
FLIPENDIANLE(cSum->type);
FLIPENDIANLE(cSum->checksum);
}
static void flipBLKXRun(BLKXRun *data) {
BLKXRun *run;
run = (BLKXRun *)data;
FLIPENDIAN(run->type);
FLIPENDIAN(run->reserved);
FLIPENDIAN(run->sectorStart);
FLIPENDIAN(run->sectorCount);
FLIPENDIAN(run->compOffset);
FLIPENDIAN(run->compLength);
}
static void flipBLKX(unsigned char *data, char out) {
BLKXTable *blkx;
uint32_t i;
blkx = (BLKXTable *)data;
FLIPENDIAN(blkx->fUDIFBlocksSignature);
FLIPENDIAN(blkx->infoVersion);
FLIPENDIAN(blkx->firstSectorNumber);
FLIPENDIAN(blkx->sectorCount);
FLIPENDIAN(blkx->dataStart);
FLIPENDIAN(blkx->decompressBufferRequested);
FLIPENDIAN(blkx->blocksDescriptor);
FLIPENDIAN(blkx->reserved1);
FLIPENDIAN(blkx->reserved2);
FLIPENDIAN(blkx->reserved3);
FLIPENDIAN(blkx->reserved4);
FLIPENDIAN(blkx->reserved5);
FLIPENDIAN(blkx->reserved6);
flipUDIFChecksum(&(blkx->checksum), out);
if (out) {
for (i = 0; i < blkx->blocksRunCount; i++) {
flipBLKXRun(&(blkx->runs[i]));
}
FLIPENDIAN(blkx->blocksRunCount);
} else {
FLIPENDIAN(blkx->blocksRunCount);
for (i = 0; i < blkx->blocksRunCount; i++) {
flipBLKXRun(&(blkx->runs[i]));
}
}
}
static char *getXMLString(char **location) {
char *curLoc;
char *tagEnd;
char *toReturn;
size_t strLen;
curLoc = *location;
curLoc = strstr(curLoc, "<string>");
if (!curLoc) {
return NULL;
}
curLoc += sizeof("<string>") - 1;
tagEnd = strstr(curLoc, "</string>");
strLen = (size_t)(tagEnd - curLoc);
toReturn = (char *)malloc(strLen + 1);
memcpy(toReturn, curLoc, strLen);
toReturn[strLen] = '\0';
curLoc = tagEnd + sizeof("</string>") - 1;
*location = curLoc;
return toReturn;
}
static uint32_t getXMLInteger(char **location) {
char *curLoc;
char *tagEnd;
char *buffer;
uint32_t toReturn;
size_t strLen;
curLoc = *location;
curLoc = strstr(curLoc, "<integer>");
if (!curLoc) {
return 0;
}
curLoc += sizeof("<integer>") - 1;
tagEnd = strstr(curLoc, "</integer>");
strLen = (size_t)(tagEnd - curLoc);
buffer = (char *)malloc(strLen + 1);
memcpy(buffer, curLoc, strLen);
buffer[strLen] = '\0';
curLoc = tagEnd + sizeof("</integer>") - 1;
sscanf(buffer, "%d", (int32_t *)(&toReturn));
free(buffer);
*location = curLoc;
return toReturn;
}
static unsigned char *getXMLData(char **location, size_t *dataLength) {
char *curLoc;
char *tagEnd;
char *encodedData;
unsigned char *toReturn;
size_t strLen;
curLoc = *location;
curLoc = strstr(curLoc, "<data>");
if (!curLoc) {
return NULL;
}
curLoc += sizeof("<data>") - 1;
tagEnd = strstr(curLoc, "</data>");
strLen = (size_t)(tagEnd - curLoc);
encodedData = (char *)malloc(strLen + 1);
memcpy(encodedData, curLoc, strLen);
encodedData[strLen] = '\0';
curLoc = tagEnd + sizeof("</data>") - 1;
*location = curLoc;
toReturn = decodeBase64(encodedData, dataLength);
free(encodedData);
return toReturn;
}
static void readResourceData(ResourceData *data, char **location,
FlipDataFunc flipData) {
char *curLoc;
char *tagBegin;
char *tagEnd;
char *dictEnd;
size_t strLen;
char *buffer;
curLoc = *location;
data->name = NULL;
data->attributes = 0;
data->id = 0;
data->data = NULL;
curLoc = strstr(curLoc, "<dict>");
dictEnd = strstr(
curLoc,
"</dict>"); /* hope there's not a dict type in this resource data! */
while (curLoc != NULL && curLoc < dictEnd) {
curLoc = strstr(curLoc, "<key>");
if (!curLoc) {
break;
}
curLoc += sizeof("<key>") - 1;
tagEnd = strstr(curLoc, "</key>");
strLen = (size_t)(tagEnd - curLoc);
tagBegin = curLoc;
curLoc = tagEnd + sizeof("</key>") - 1;
if (strncmp(tagBegin, "Attributes", strLen) == 0) {
buffer = getXMLString(&curLoc);
sscanf(buffer, "0x%x", &(data->attributes));
free(buffer);
} else if (strncmp(tagBegin, "Data", strLen) == 0) {
data->data = getXMLData(&curLoc, &(data->dataLength));
if (flipData) {
(*flipData)(data->data, 0);
}
} else if (strncmp(tagBegin, "ID", strLen) == 0) {
buffer = getXMLString(&curLoc);
sscanf(buffer, "%d", &(data->id));
free(buffer);
} else if (strncmp(tagBegin, "Name", strLen) == 0) {
data->name = getXMLString(&curLoc);
}
}
curLoc = dictEnd + sizeof("</dict>") - 1;
*location = curLoc;
}
static void readNSizResource(NSizResource *data, char **location) {
char *curLoc;
char *tagBegin;
char *tagEnd;
char *dictEnd;
size_t strLen;
size_t dummy;
curLoc = *location;
data->isVolume = FALSE;
data->sha1Digest = NULL;
data->blockChecksum2 = 0;
data->bytes = 0;
data->modifyDate = 0;
data->partitionNumber = 0;
data->version = 0;
data->volumeSignature = 0;
curLoc = strstr(curLoc, "<dict>");
dictEnd = strstr(
curLoc,
"</dict>"); /* hope there's not a dict type in this resource data! */
while (curLoc != NULL && curLoc < dictEnd) {
curLoc = strstr(curLoc, "<key>");
if (!curLoc) {
break;
}
curLoc += sizeof("<key>") - 1;
tagEnd = strstr(curLoc, "</key>");
strLen = (size_t)(tagEnd - curLoc);
tagBegin = curLoc;
curLoc = tagEnd + sizeof("</key>") - 1;
if (strncmp(tagBegin, "SHA-1-digest", strLen) == 0) {
data->sha1Digest = getXMLData(&curLoc, &dummy);
;
/*flipEndian(data->sha1Digest, 4);*/
} else if (strncmp(tagBegin, "block-checksum-2", strLen) == 0) {
data->blockChecksum2 = getXMLInteger(&curLoc);
} else if (strncmp(tagBegin, "bytes", strLen) == 0) {
data->bytes = getXMLInteger(&curLoc);
} else if (strncmp(tagBegin, "date", strLen) == 0) {
data->modifyDate = getXMLInteger(&curLoc);
} else if (strncmp(tagBegin, "part-num", strLen) == 0) {
data->partitionNumber = getXMLInteger(&curLoc);
} else if (strncmp(tagBegin, "version", strLen) == 0) {
data->version = getXMLInteger(&curLoc);
} else if (strncmp(tagBegin, "volume-signature", strLen) == 0) {
data->volumeSignature = getXMLInteger(&curLoc);
data->isVolume = TRUE;
}
}
curLoc = dictEnd + sizeof("</dict>") - 1;
*location = curLoc;
}
static void writeNSizResource(NSizResource *data, char *buffer) {
char itemBuffer[1024];
char *sha1Buffer;
(*buffer) = '\0';
itemBuffer[0] = '\0';
strcat(buffer, plistHeader);
if (data->sha1Digest != NULL) {
sha1Buffer = convertBase64(data->sha1Digest, 20, 1, 42);
sprintf(itemBuffer, "\t<key>SHA-1-digest</key>\n\t<data>\n%s\t</data>\n",
sha1Buffer);
free(sha1Buffer);
strcat(buffer, itemBuffer);
}
sprintf(itemBuffer,
"\t<key>block-checksum-2</key>\n\t<integer>%d</integer>\n",
(int32_t)(data->blockChecksum2));
strcat(buffer, itemBuffer);
if (data->isVolume) {
sprintf(itemBuffer, "\t<key>bytes</key>\n\t<integer>%d</integer>\n",
(int32_t)(data->bytes));
strcat(buffer, itemBuffer);
sprintf(itemBuffer, "\t<key>date</key>\n\t<integer>%d</integer>\n",
(int32_t)(data->modifyDate));
strcat(buffer, itemBuffer);
}
sprintf(itemBuffer, "\t<key>part-num</key>\n\t<integer>%d</integer>\n",
(int32_t)(data->partitionNumber));
strcat(buffer, itemBuffer);
sprintf(itemBuffer, "\t<key>version</key>\n\t<integer>%d</integer>\n",
(int32_t)(data->version));
strcat(buffer, itemBuffer);
if (data->isVolume) {
sprintf(itemBuffer,
"\t<key>volume-signature</key>\n\t<integer>%d</integer>\n",
(int32_t)(data->volumeSignature));
strcat(buffer, itemBuffer);
}
strcat(buffer, plistFooter);
}
NSizResource *readNSiz(ResourceKey *resources) {
ResourceData *curData;
NSizResource *toReturn;
NSizResource *curNSiz;
char *curLoc;
uint32_t modifyDate;
curData = getResourceByKey(resources, "nsiz")->data;
toReturn = NULL;
while (curData != NULL) {
curLoc = (char *)curData->data;
if (toReturn == NULL) {
toReturn = (NSizResource *)malloc(sizeof(NSizResource));
curNSiz = toReturn;
} else {
curNSiz->next = (NSizResource *)malloc(sizeof(NSizResource));
curNSiz = curNSiz->next;
}
curNSiz->next = NULL;
readNSizResource(curNSiz, &curLoc);
printf("block-checksum-2:\t0x%x\n", curNSiz->blockChecksum2);
printf("part-num:\t\t0x%x\n", curNSiz->partitionNumber);
printf("version:\t\t0x%x\n", curNSiz->version);
if (curNSiz->isVolume) {
printf("has SHA1:\t\t%d\n", curNSiz->sha1Digest != NULL);
printf("bytes:\t\t\t0x%x\n", curNSiz->bytes);
modifyDate = APPLE_TO_UNIX_TIME(curNSiz->modifyDate);
printf("date:\t\t\t%s", ctime((time_t *)(&modifyDate)));
printf("volume-signature:\t0x%x\n", curNSiz->volumeSignature);
}
printf("\n");
curData = curData->next;
}
return toReturn;
}
ResourceKey *writeNSiz(NSizResource *nSiz) {
NSizResource *curNSiz;
ResourceKey *key;
ResourceData *curData;
char buffer[1024];
curNSiz = nSiz;
key = (ResourceKey *)malloc(sizeof(ResourceKey));
key->key = (unsigned char *)malloc(sizeof("nsiz") + 1);
strcpy((char *)key->key, "nsiz");
key->next = NULL;
key->flipData = NULL;
key->data = NULL;
while (curNSiz != NULL) {
writeNSizResource(curNSiz, buffer);
if (key->data == NULL) {
key->data = (ResourceData *)malloc(sizeof(ResourceData));
curData = key->data;
} else {
curData->next = (ResourceData *)malloc(sizeof(ResourceData));
curData = curData->next;
}
curData->attributes = 0;
curData->id = curNSiz->partitionNumber;
curData->name = (char *)malloc(sizeof(char));
curData->name[0] = '\0';
curData->next = NULL;
curData->dataLength = sizeof(char) * strlen(buffer);
curData->data = (unsigned char *)malloc(curData->dataLength);
memcpy(curData->data, buffer, curData->dataLength);
curNSiz = curNSiz->next;
}
return key;
}
void releaseNSiz(NSizResource *nSiz) {
NSizResource *curNSiz;
NSizResource *toRemove;
curNSiz = nSiz;
while (curNSiz != NULL) {
if (curNSiz->sha1Digest != NULL) {
free(curNSiz->sha1Digest);
}
toRemove = curNSiz;
curNSiz = curNSiz->next;
free(toRemove);
}
}
void outResources(AbstractFile *file, AbstractFile *out) {
char *xml;
UDIFResourceFile resourceFile;
off_t fileLength;
fileLength = file->getLength(file);
file->seek(file, fileLength - sizeof(UDIFResourceFile));
readUDIFResourceFile(file, &resourceFile);
xml = (char *)malloc((size_t)resourceFile.fUDIFXMLLength);
file->seek(file, (off_t)(resourceFile.fUDIFXMLOffset));
ASSERT(file->read(file, xml, (size_t)resourceFile.fUDIFXMLLength) ==
(size_t)resourceFile.fUDIFXMLLength,
"fread");
ASSERT(out->write(out, xml, (size_t)resourceFile.fUDIFXMLLength) ==
(size_t)resourceFile.fUDIFXMLLength,
"fwrite");
file->close(file);
out->close(out);
}
ResourceKey *readResources(AbstractFile *file, UDIFResourceFile *resourceFile) {
char *xml;
char *curLoc;
char *tagEnd;
size_t strLen;
ResourceKey *toReturn;
ResourceKey *curResource;
ResourceData *curData;
xml = (char *)malloc((size_t)resourceFile->fUDIFXMLLength +
1); /* we're not going to handle over 32-bit resource
files, that'd be insane */
xml[(size_t)resourceFile->fUDIFXMLLength] = '\0';
if (!xml) {
return NULL;
}
toReturn = NULL;
curResource = NULL;
curData = NULL;
file->seek(file, (off_t)(resourceFile->fUDIFXMLOffset));
ASSERT(file->read(file, xml, (size_t)resourceFile->fUDIFXMLLength) ==
(size_t)resourceFile->fUDIFXMLLength,
"fread");
curLoc = strstr(xml, "<key>resource-fork</key>");
if (!curLoc) {
return NULL;
}
curLoc += sizeof("<key>resource-fork</key>") - 1;
curLoc = strstr(curLoc, "<dict>");
if (!curLoc) {
return NULL;
}
curLoc += sizeof("<dict>") - 1;
while (TRUE) {
curLoc = strstr(curLoc, "<key>");
if (!curLoc) {
break;
}
curLoc += sizeof("<key>") - 1;
tagEnd = strstr(curLoc, "</key>");
if (!tagEnd) {
break;
}
if (toReturn == NULL) {
toReturn = (ResourceKey *)malloc(sizeof(ResourceKey));
curResource = toReturn;
} else {
curResource->next = (ResourceKey *)malloc(sizeof(ResourceKey));
curResource = curResource->next;
}
curResource->data = NULL;
curResource->next = NULL;
curResource->flipData = NULL;
strLen = (size_t)(tagEnd - curLoc);
curResource->key = (unsigned char *)malloc(strLen + 1);
memcpy(curResource->key, curLoc, strLen);
curResource->key[strLen] = '\0';
curLoc = tagEnd + sizeof("</key>") - 1;
curLoc = strstr(curLoc, "<array>");
if (!curLoc) {
return NULL;
}
curLoc += sizeof("<array>") - 1;
tagEnd = strstr(curLoc, "</array>");
if (!tagEnd) {
break;
}
if (strcmp((char *)curResource->key, "blkx") == 0) {
curResource->flipData = &flipBLKX;
} else if (strcmp((char *)curResource->key, "size") == 0) {
curResource->flipData = &flipSizeResource;
} else if (strcmp((char *)curResource->key, "cSum") == 0) {
curResource->flipData = &flipCSumResource;
}
curLoc = strstr(curLoc, "<dict>");
while (curLoc != NULL && curLoc < tagEnd) {
if (curResource->data == NULL) {
curResource->data = (ResourceData *)malloc(sizeof(ResourceData));
curData = curResource->data;
} else {
curData->next = (ResourceData *)malloc(sizeof(ResourceData));
curData = curData->next;
}
curData->next = NULL;
readResourceData(curData, &curLoc, curResource->flipData);
curLoc = strstr(curLoc, "<dict>");
}
curLoc = tagEnd + sizeof("</array>") - 1;
}
free(xml);
return toReturn;
}
static void writeResourceData(AbstractFile *file, ResourceData *data,
ResourceKey *curResource, FlipDataFunc flipData,
int tabLength) {
unsigned char *dataBuf;
char *tabs;
int i;
tabs = (char *)malloc(sizeof(char) * (tabLength + 1));
for (i = 0; i < tabLength; i++) {
tabs[i] = '\t';
}
tabs[tabLength] = '\0';
abstractFilePrint(file, "%s<dict>\n", tabs);
abstractFilePrint(file,
"%s\t<key>Attributes</key>\n%s\t<string>0x%04x</string>\n",
tabs, tabs, data->attributes);
if (strcmp((char *)curResource->key, "blkx") == 0) {
abstractFilePrint(file, "%s\t<key>CFName</key>\n%s\t<string>%s</string>\n",
tabs, tabs, data->name);
}
abstractFilePrint(file, "%s\t<key>Data</key>\n%s\t<data>\n", tabs, tabs);
if (flipData) {
dataBuf = (unsigned char *)malloc(data->dataLength);
memcpy(dataBuf, data->data, data->dataLength);
(*flipData)(dataBuf, 1);
writeBase64(file, dataBuf, data->dataLength, tabLength + 1, 43);
free(dataBuf);
} else {
writeBase64(file, data->data, data->dataLength, tabLength + 1, 43);
}
abstractFilePrint(file, "%s\t</data>\n", tabs);
abstractFilePrint(file, "%s\t<key>ID</key>\n%s\t<string>%d</string>\n", tabs,
tabs, data->id);
abstractFilePrint(file, "%s\t<key>Name</key>\n%s\t<string>%s</string>\n",
tabs, tabs, data->name);
abstractFilePrint(file, "%s</dict>\n", tabs);
free(tabs);
}
void writeResources(AbstractFile *file, ResourceKey *resources) {
ResourceKey *curResource;
ResourceData *curData;
abstractFilePrint(file, plistHeader);
abstractFilePrint(file, "\t<key>resource-fork</key>\n\t<dict>\n");
curResource = resources;
while (curResource != NULL) {
abstractFilePrint(file, "\t\t<key>%s</key>\n\t\t<array>\n",
curResource->key);
curData = curResource->data;
while (curData != NULL) {
writeResourceData(file, curData, curResource, curResource->flipData, 3);
curData = curData->next;
}
abstractFilePrint(file, "\t\t</array>\n", curResource->key);
curResource = curResource->next;
}
abstractFilePrint(file, "\t</dict>\n");
abstractFilePrint(file, plistFooter);
}
static void releaseResourceData(ResourceData *data) {
ResourceData *curData;
ResourceData *nextData;
nextData = data;
while (nextData != NULL) {
curData = nextData;
if (curData->name) {
free(curData->name);
}
if (curData->data) {
free(curData->data);
}
nextData = nextData->next;
free(curData);
}
}
void releaseResources(ResourceKey *resources) {
ResourceKey *curResource;
ResourceKey *nextResource;
nextResource = resources;
while (nextResource != NULL) {
curResource = nextResource;
free(curResource->key);
releaseResourceData(curResource->data);
nextResource = nextResource->next;
free(curResource);
}
}
ResourceKey *getResourceByKey(ResourceKey *resources, const char *key) {
ResourceKey *curResource;
curResource = resources;
while (curResource != NULL) {
if (strcmp((char *)curResource->key, key) == 0) {
return curResource;
}
curResource = curResource->next;
}
return NULL;
}
ResourceData *getDataByID(ResourceKey *resource, int id) {
ResourceData *curData;
curData = resource->data;
while (curData != NULL) {
if (curData->id == id) {
return curData;
}
curData = curData->next;
}
return NULL;
}
ResourceKey *insertData(ResourceKey *resources, const char *key, int id,
const char *name, const char *data, size_t dataLength,
uint32_t attributes) {
ResourceKey *curResource;
ResourceKey *lastResource;
ResourceData *curData;
lastResource = resources;
curResource = resources;
while (curResource != NULL) {
if (strcmp((char *)curResource->key, key) == 0) {
break;
}
lastResource = curResource;
curResource = curResource->next;
}
if (curResource == NULL) {
if (lastResource == NULL) {
curResource = (ResourceKey *)malloc(sizeof(ResourceKey));
} else {
lastResource->next = (ResourceKey *)malloc(sizeof(ResourceKey));
curResource = lastResource->next;
}
curResource->key = (unsigned char *)malloc(strlen(key) + 1);
strcpy((char *)curResource->key, key);
curResource->next = NULL;
if (strcmp((char *)curResource->key, "blkx") == 0) {
curResource->flipData = &flipBLKX;
} else if (strcmp((char *)curResource->key, "size") == 0) {
printf("we know to flip this size resource\n");
curResource->flipData = &flipSizeResource;
} else if (strcmp((char *)curResource->key, "cSum") == 0) {
curResource->flipData = &flipCSumResource;
} else {
curResource->flipData = NULL;
}
curResource->data = NULL;
}
if (curResource->data == NULL) {
curData = (ResourceData *)malloc(sizeof(ResourceData));
curResource->data = curData;
curData->next = NULL;
} else {
curData = curResource->data;
while (curData->next != NULL) {
if (curData->id == id) {
break;
}
curData = curData->next;
}
if (curData->id != id) {
curData->next = (ResourceData *)malloc(sizeof(ResourceData));
curData = curData->next;
curData->next = NULL;
} else {
free(curData->data);
free(curData->name);
}
}
curData->attributes = attributes;
curData->dataLength = dataLength;
curData->id = id;
curData->name = (char *)malloc(strlen(name) + 1);
strcpy((char *)curData->name, name);
curData->data = (unsigned char *)malloc(dataLength);
memcpy(curData->data, data, dataLength);
int i = 0;
if (resources) {
curResource = resources;
while (curResource) {
curResource = curResource->next;
i++;
}
return resources;
} else {
return curResource;
}
}
ResourceKey *makePlst() {
return insertData(NULL, "plst", 0, "", plstData, sizeof(plstData),
ATTRIBUTE_HDIUTIL);
}
ResourceKey *makeSize(HFSPlusVolumeHeader *volumeHeader) {
SizeResource size;
memset(&size, 0, sizeof(SizeResource));
size.version = 5;
size.isHFS = 1;
size.unknown1 = 0;
size.unknown2 = 0;
size.unknown3 = 0;
size.volumeModified = volumeHeader->modifyDate;
size.unknown4 = 0;
size.volumeSignature = volumeHeader->signature;
size.sizePresent = 1;
printf("making size data\n");
return insertData(NULL, "size", 2, "", (const char *)(&size),
sizeof(SizeResource), 0);
}