Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions xtaf/xtaf.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,8 @@ struct _x_hdd_security_sector_s {
unsigned char ms_logo_hash[0x14];
uint32_t number_of_sector;
unsigned char signature[0x100];
uint32_t ms_logo_size;
void * ms_logo;
};
unsigned char padding[0xa4];
}; // size 0x200

/**
* The file flags and the date and time fields are in the same format as the one used in the FAT file system.
Expand Down
8 changes: 8 additions & 0 deletions xtaf/xtaf_endian.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,14 @@ static inline uint32_t host2be32(uint32_t val) {
#endif
}

static inline uint32_t le32tohost(uint32_t val) {
#ifndef LITTLE_ENDIAN
return bswap32(val);
#else
return val;
#endif
}

static inline uint16_t host2be16(uint16_t val) {
#ifdef LITTLE_ENDIAN
return bswap32(val);
Expand Down
59 changes: 57 additions & 2 deletions xtaf/xtaf_partition.c
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,39 @@ int check_devkit_hdd(DISC_INTERFACE * disc) {
return 1;
}

/** return 1 if hdd has valid security sector, 0 if invalid. out_num_sectors populated with sector size **/
int check_security_sector(DISC_INTERFACE * disc, unsigned int *out_num_sectors) {
int r = 0;

if (out_num_sectors != NULL)
*out_num_sectors = 0;

uint8_t *sectorBuffer = _XTAF_mem_allocate(XENON_DISK_SECTOR_SIZE);
if (sectorBuffer == NULL)
return 0;

// read the security sector off the disk
if (!_XTAF_disc_readSectors(disc,0x10,1,sectorBuffer))
goto end;

// compare serial, firmware and revision of the drive to the security sector
struct _x_hdd_security_sector_s *security_sector = (struct _x_hdd_security_sector_s *)sectorBuffer;
if (memcmp(security_sector->serial_number, ata.serial, sizeof(security_sector->serial_number)) != 0)
goto end;
if (memcmp(security_sector->firmware_revision, ata.rev, sizeof(security_sector->firmware_revision)) != 0)
goto end;
if (memcmp(security_sector->model_number, ata.model, sizeof(security_sector->model_number)) != 0)
goto end;

r = 1;
if (out_num_sectors != NULL)
*out_num_sectors = le32tohost(security_sector->number_of_sector);

end:
_XTAF_mem_free(sectorBuffer);
return r;
}

xtaf_partition_private * xtaf_mount(void * disc, uint32_t start_sector, uint32_t num_sectors, uint32_t cacheSize, uint32_t sectorsPerPage, uint8_t *sectorBuffer ) {
bool err;
static int partition_nbr = 0;
Expand Down Expand Up @@ -270,8 +303,11 @@ int xtaf_init(struct xtaf_context *ctx, DISC_INTERFACE * disc) {

if (check_devkit_hdd(disc) == 1)
xprintf("DEVKIT HDD detected!\r\n");

uint8_t *sectorBuffer = (uint8_t*) _XTAF_mem_allocate(XENON_DISK_SECTOR_SIZE);

unsigned int real_disk_sector_count = 0;
check_security_sector(disc, &real_disk_sector_count);

uint8_t *sectorBuffer = (uint8_t*) _XTAF_mem_allocate(XENON_DISK_SECTOR_SIZE);

int found = 0;

Expand All @@ -287,6 +323,25 @@ int xtaf_init(struct xtaf_context *ctx, DISC_INTERFACE * disc) {
//num_sectors = (uint32_t) (312581808) - start_sector;
extern struct xenon_ata_device ata;
num_sectors = (uint32_t) (ata.size) - start_sector;
if (real_disk_sector_count > 0)
{
// Restrict the number of sectors used for the data partition to what the MS security sector says.
// This matches the behaviour of the official OS. There is a problem here, though...
//
// If a drive has a legitimate security sector, and the drive's true ending LBA is greater than what is specified,
// (e.g. an SSD that has been flashed with a fake model/serial, and a real drive's secruity sector written to it)
// then pre-Sep2026 xebuild patches and pre-Sep2026 libxtaf will see a completely different FAT from the drive
// compared to retail consoles, or post-Sep2026 xebuild patches/libxtaf.
//
// We're going to assume that, since if a security sector exists you want to use the drive on a retail console,
// that we should read the partition as if it is a retail console and use the same XTAF extents.
// There are no good solutions here, but I think using the retail OS behaviour is the most well-intentioned solution.
if (real_disk_sector_count < ata.size)
{
printf("XTAF sector count mismatch! (0x%x->0x%x)\n", ata.size, real_disk_sector_count);
}
num_sectors = real_disk_sector_count - start_sector;
}
#else
num_sectors = (20003880960 / XENON_DISK_SECTOR_SIZE) - start_sector; // hdd_dump file size
#endif
Expand Down
Loading