libdmg-hfsplus/dmg/resources.c

878 строки
28 KiB
C

#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <dmg/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]));
}
}
/*
printf("fUDIFBlocksSignature: 0x%x\n", blkx->fUDIFBlocksSignature);
printf("infoVersion: 0x%x\n", blkx->infoVersion);
printf("firstSectorNumber: 0x%llx\n", blkx->firstSectorNumber);
printf("sectorCount: 0x%llx\n", blkx->sectorCount);
printf("dataStart: 0x%llx\n", blkx->dataStart);
printf("decompressBufferRequested: 0x%x\n", blkx->decompressBufferRequested);
printf("blocksDescriptor: 0x%x\n", blkx->blocksDescriptor);
printf("blocksRunCount: 0x%x\n", blkx->blocksRunCount);
for(i = 0; i < 0x20; i++)
{
printf("checksum[%d]: %x\n", i, blkx->checksum.data[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);
}