Zotty
9th February 2008, 19:09
To dive right into it; I've been working on some code to get to volume ID of HD DVD discs without using AACS authentication. To do this I've been using the CDB commands specified in the Mt Fuji specs. The READ_DISK_STRUCTURE command (with format code 0x15) to be more precise. Since this is highly related to AACS decryption I'm posting this here in hopes someone knows what I'm talking about.
Reading the BCA (with first part of Volume ID), manufacturing info, physical format info and so on all work fine (and the data looks valid and consistent). But the last thing that's standing in my way is the copyright data section. I'm having trouble reading it as no matter what I do there is no valid data coming back from the drive. Keep getting invalid data. And since the specs say this is where the 2nd part of the volume ID is located, it must contain some data.
When sending the command to an xbox360 HD DVD drive it responds by making reading noises and it is obviously doing something. It takes a few seconds of buzzing and humming before the data is returned. Also tested with various discs, so that can be ruled out aswell.
According to the specs it shouldn't be a problem reading this data, but somehow the data is not returned. Are there any barriers in place here? Any similair experiences? Why does it keep returning invalid data? Atm I'm stuck, so time to call in some reinforcements ;)
Here's part of the code that should take care of this for review:
void HDDrive::ReadCopyrightDataSection()
{
unsigned short iBufferSize = 31 * 2048 + 4;
uint8_t* pDataBuffer = new uint8_t[iBufferSize];
if (!ReadDiscStructure(pDataBuffer, 0x15, 0x00, iBufferSize))
{
throw std::runtime_error("Error reading copyright data section from lead-in");
}
m_iCopyrightDataSectionSize = (pDataBuffer[0] * 0x100 | pDataBuffer[1]) - 2;
m_pCopyrightDataSection = new uint8_t[m_iCopyrightDataSectionSize];
memset(m_pCopyrightDataSection, 0x00, m_iCopyrightDataSectionSize);
memcpy(m_pCopyrightDataSection, pDataBuffer + 4, m_iCopyrightDataSectionSize);
delete[] pDataBuffer;
}
bool HDDrive::ReadDiscStructure(uint8_t* buffer, uint8_t iFormatCode, uint8_t AGID, unsigned short iLength)
{
memset(buffer, 0x00, iLength);
memset(m_cmd, 0x00, CDROM_PACKET_SIZE);
// prepare CDB
m_cmd[0] = 0xAD; // operation code
m_cmd[1] = m_eMediaType; // media type
m_cmd[7] = iFormatCode; // format code
m_cmd[8] = (iLength >> 8) & 0xFF; // allocation length (MSB)
m_cmd[9] = iLength & 0xFF; // allocation length (LSB)
// only use AGID when needed
// This field is used only when the Format field contains 2h, 6h, 7h, 80h, 81h, or 82h with Address field of 00000000h, for all other values it is reserved.
if (iFormatCode == 0x02 || iFormatCode == 0x06 || iFormatCode == 0x07 ||
iFormatCode == 0x80 || iFormatCode == 0x81 || iFormatCode == 0x82)
{
m_cmd[10] = (AGID << 6) & 0xC0; // AGID
}
// send command to drive
return (send_cmd(m_hHandle, m_cmd, buffer, 0, iLength) == 0);
}
I hope this makes any sense. If not, I'll try to clarify.
Reading the BCA (with first part of Volume ID), manufacturing info, physical format info and so on all work fine (and the data looks valid and consistent). But the last thing that's standing in my way is the copyright data section. I'm having trouble reading it as no matter what I do there is no valid data coming back from the drive. Keep getting invalid data. And since the specs say this is where the 2nd part of the volume ID is located, it must contain some data.
When sending the command to an xbox360 HD DVD drive it responds by making reading noises and it is obviously doing something. It takes a few seconds of buzzing and humming before the data is returned. Also tested with various discs, so that can be ruled out aswell.
According to the specs it shouldn't be a problem reading this data, but somehow the data is not returned. Are there any barriers in place here? Any similair experiences? Why does it keep returning invalid data? Atm I'm stuck, so time to call in some reinforcements ;)
Here's part of the code that should take care of this for review:
void HDDrive::ReadCopyrightDataSection()
{
unsigned short iBufferSize = 31 * 2048 + 4;
uint8_t* pDataBuffer = new uint8_t[iBufferSize];
if (!ReadDiscStructure(pDataBuffer, 0x15, 0x00, iBufferSize))
{
throw std::runtime_error("Error reading copyright data section from lead-in");
}
m_iCopyrightDataSectionSize = (pDataBuffer[0] * 0x100 | pDataBuffer[1]) - 2;
m_pCopyrightDataSection = new uint8_t[m_iCopyrightDataSectionSize];
memset(m_pCopyrightDataSection, 0x00, m_iCopyrightDataSectionSize);
memcpy(m_pCopyrightDataSection, pDataBuffer + 4, m_iCopyrightDataSectionSize);
delete[] pDataBuffer;
}
bool HDDrive::ReadDiscStructure(uint8_t* buffer, uint8_t iFormatCode, uint8_t AGID, unsigned short iLength)
{
memset(buffer, 0x00, iLength);
memset(m_cmd, 0x00, CDROM_PACKET_SIZE);
// prepare CDB
m_cmd[0] = 0xAD; // operation code
m_cmd[1] = m_eMediaType; // media type
m_cmd[7] = iFormatCode; // format code
m_cmd[8] = (iLength >> 8) & 0xFF; // allocation length (MSB)
m_cmd[9] = iLength & 0xFF; // allocation length (LSB)
// only use AGID when needed
// This field is used only when the Format field contains 2h, 6h, 7h, 80h, 81h, or 82h with Address field of 00000000h, for all other values it is reserved.
if (iFormatCode == 0x02 || iFormatCode == 0x06 || iFormatCode == 0x07 ||
iFormatCode == 0x80 || iFormatCode == 0x81 || iFormatCode == 0x82)
{
m_cmd[10] = (AGID << 6) & 0xC0; // AGID
}
// send command to drive
return (send_cmd(m_hHandle, m_cmd, buffer, 0, iLength) == 0);
}
I hope this makes any sense. If not, I'll try to clarify.