There's a bug in the original xboxdumper code:
CODE
if(!nCreate) {
*(u_int64_t *)&partitionInfo[0x0008] = 0x00000020; // Clustersize in 512 bytes
} else {
*(u_int64_t *)&partitionInfo[0x0008] = 0x00000004; // Clustersize in 512 bytes
}
*(u_int16_t *)&partitionInfo[0x000C] = 0x0001; //Number of active FATs (always 1) (?)
u_int64_t occupies too many bytes and partitionInfo[0x0008] will override the next value at partitionInfo[0x000C].
It's fixed at
http://sourceforge.net/projects/xboxhdm2/f...ar.bz2/download.
CODE
FATXPartition* createPartition(char *szFileName, u_int64_t partitionOffset,
u_int64_t partitionSize, int nCreate) {
FATXPartition* partition;
unsigned char partitionInfo[FATX_PARTITION_HEADERSIZE];
unsigned char *clusterData;
char szBuffer[1024];
long lRet;
u_int64_t i;
u_int32_t eocMarker;
u_int32_t rootFatMarker;
memset(szBuffer,0,1024);
partition = (FATXPartition*) malloc(sizeof(FATXPartition));
if (partition == NULL) {
printf("createPartition -> Out of memory\n");
return NULL;
}
memset(partitionInfo,0,FATX_PARTITION_HEADERSIZE);
*(u_int64_t *)partitionInfo = FATX_PARTITION_MAGIC;
*(u_int64_t *)&partitionInfo[0x0004] = (u_int64_t) time(NULL); // Volume id
if(!nCreate) {
*(u_int64_t *)&partitionInfo[0x0008] = 0x00000020; // Clustersize in 512 bytes
} else {
*(u_int64_t *)&partitionInfo[0x0008] = 0x00000004; // Clustersize in 512 bytes
}
*(u_int16_t *)&partitionInfo[0x000C] = 0x0001; //Number of active FATs (always 1) (?)
*(u_int32_t *)&partitionInfo[0x000E] = 0x00000000; //Unknown (always set to 0)
memset(&partitionInfo[0x0012],0xff,0xfee); //Unknown (usually set to 0xff, or 0). Probably padding.
memset(partition,0,sizeof(FATXPartition));
if(!nCreate) {
partition->sourceFd = fopen(szFileName,"r+");
} else {
partition->sourceFd = fopen(szFileName,"w+");
partition->partitionSize = partitionSize * 1024 *1024;
}
if(partition->sourceFd == NULL) {
printf("createPartition -> Error creating File %s\n",szFileName);
return NULL;
}
if(!nCreate && (partitionSize == 0)) {
fseeko(partition->sourceFd,0L,SEEK_END);
partition->partitionSize = ftello(partition->sourceFd);
fseeko(partition->sourceFd,0L,SEEK_SET);
} else if(!nCreate && (partitionSize != 0)) {
partition->partitionSize = partitionSize;
}
partition->partitionStart = partitionOffset;
//partition->clusterSize = 0x4000;
if ((partition->partitionSize >= 256ULL*1024ULL*1024ULL*1024ULL) && !nCreate){
if (partition->partitionSize >= 512ULL*1024ULL*1024ULL*1024ULL){ //more than 512GB
*(u_int64_t *)&partitionInfo[0x0008] = 0x00000080; // Clustersize in 512 bytes
partition->clusterSize = 0x10000; // 64k clustersize
}
else
{ // between 256GB and 512GB
*(u_int64_t *)&partitionInfo[0x0008] = 0x00000040; // Clustersize in 512 bytes
partition->clusterSize = 0x8000; // 32k clustersize
}
}
else
partition->clusterSize = 0x4000; // 16k clustersize
partition->clusterCount = partition->partitionSize / partition->clusterSize;
partition->chainMapEntrySize = (partition->clusterCount >= 0xfff4) ? 4 : 2;
/*if (partition->clusterCount >= 0xfffffff4)
partition->chainMapEntrySize = 8;
else if (partition->clusterCount >= 0xfff4)
partition->chainMapEntrySize = 4;
else
partition->chainMapEntrySize = 2;
*/
if(nCreate) {
memset(szBuffer,0x00,1024);
for(i = 0; i < (partitionSize * 1024);i++) {
lRet = fwrite(szBuffer, 1024, 1, partition->sourceFd);
}
}
fseeko(partition->sourceFd,partition->partitionStart,SEEK_SET);
*(u_int16_t *)&partitionInfo[0x000C] = 0x0001; //Number of active FATs (always 1) (?)
// Write the header
fwrite(partitionInfo, FATX_PARTITION_HEADERSIZE, 1, partition->sourceFd);
partition->chainTableSize = partition->clusterCount * partition->chainMapEntrySize;
if (partition->chainTableSize % FATX_CHAINTABLE_BLOCKSIZE) {
// round up to nearest FATX_CHAINTABLE_BLOCKSIZE bytes
partition->chainTableSize = ((partition->chainTableSize / FATX_CHAINTABLE_BLOCKSIZE) + 1)
* FATX_CHAINTABLE_BLOCKSIZE;
}
// Create empty chain map table
partition->clusterChainMap.words = (u_int16_t*) malloc(partition->chainTableSize);
if (partition->clusterChainMap.words == NULL) {
error("Out of memory");
}
memset(partition->clusterChainMap.words,0x00,partition->chainTableSize);
if (partition->chainMapEntrySize == 2) {
rootFatMarker = 0xfff8;
eocMarker = 0xffff;
partition->clusterChainMap.words[0] = rootFatMarker;
partition->clusterChainMap.words[1] = eocMarker;
} else {
rootFatMarker = 0xfffffff8;
eocMarker = 0xffffffff;
partition->clusterChainMap.dwords[0] = rootFatMarker;
partition->clusterChainMap.dwords[1] = eocMarker;
}
// writing the new chaintable
writeChainMap(partition);
// Address of the first cluster
partition->cluster1Address = partitionOffset + FATX_PARTITION_HEADERSIZE + partition->chainTableSize;
fseeko(partition->sourceFd, partition->cluster1Address, SEEK_SET);
// clearing the first cluster
clusterData = (unsigned char *)malloc(partition->clusterSize);
memset(clusterData,0xFF,partition->clusterSize);
writeCluster(partition, 1, clusterData);
// first direcory or file
printf("createPartition : Filename : %s\n",szFileName);
printf("createPartition : clusters %ld\n",(unsigned long)partition->clusterCount);
printf("createPartition : start %lld\n",partition->partitionStart);
printf("createPartition : size %lld\n",partition->partitionSize);
printf("createPartition : chainMapSize %ld\n",(unsigned long)partition->chainMapEntrySize);
printf("createPartition : clusterSize %ld\n",partition->clusterSize);
return partition;
}