in hfs/rawfile.c [406:477]
int readExtents(RawFile* rawFile) {
uint32_t blocksLeft;
HFSPlusForkData* forkData;
uint32_t currentBlock;
Extent* extent;
Extent* lastExtent;
HFSPlusExtentDescriptor* descriptor;
int currentExtent;
HFSPlusExtentKey extentKey;
int exact;
extentKey.keyLength = sizeof(HFSPlusExtentKey) - sizeof(extentKey.keyLength);
extentKey.forkType = 0;
extentKey.fileID = rawFile->id;
forkData = rawFile->forkData;
blocksLeft = forkData->totalBlocks;
currentExtent = 0;
currentBlock = 0;
descriptor = (HFSPlusExtentDescriptor*) forkData->extents;
lastExtent = NULL;
while(blocksLeft > 0) {
extent = (Extent*) malloc(sizeof(Extent));
if(currentExtent == 8) {
if(rawFile->volume->extentsTree == NULL) {
hfs_panic("no extents overflow file loaded yet!");
return FALSE;
}
if(descriptor != ((HFSPlusExtentDescriptor*) forkData->extents)) {
free(descriptor);
}
extentKey.startBlock = currentBlock;
descriptor = (HFSPlusExtentDescriptor*) search(rawFile->volume->extentsTree, (BTKey*)(&extentKey), &exact, NULL, NULL);
if(descriptor == NULL || exact == FALSE) {
hfs_panic("inconsistent extents information!");
return FALSE;
} else {
currentExtent = 0;
continue;
}
}
extent->startBlock = descriptor[currentExtent].startBlock;
extent->blockCount = descriptor[currentExtent].blockCount;
extent->next = NULL;
currentBlock += extent->blockCount;
blocksLeft -= extent->blockCount;
currentExtent++;
if(lastExtent == NULL) {
rawFile->extents = extent;
} else {
lastExtent->next = extent;
}
lastExtent = extent;
}
if(descriptor != ((HFSPlusExtentDescriptor*) forkData->extents)) {
free(descriptor);
}
return TRUE;
}