mirror of
https://github.com/aaru-dps/libaaruformat.git
synced 2026-07-08 18:06:18 +00:00
Add raw blu-ray and aacs tags
This commit is contained in:
@@ -161,6 +161,7 @@ typedef enum
|
||||
BDRE = 62, ///< BD-RE
|
||||
BDRXL = 63, ///< BD-R XL
|
||||
BDREXL = 64, ///< BD-RE XL
|
||||
UHDBD = 65, ///< Ultra HD Blu-ray
|
||||
// Standard Blu-ray formats, types 60 to 69
|
||||
|
||||
// Rare or uncommon optical standards, types 70 to 79
|
||||
@@ -211,6 +212,7 @@ typedef enum
|
||||
PS4BD = 117, ///< Sony PlayStation 4 game Blu-ray
|
||||
UMD = 118, ///< Sony PlayStation Portable Universal Media Disc (ECMA-365)
|
||||
PlayStationVitaGameCard = 119, ///< PS Vita NV memory card (proprietary flash)
|
||||
PS5BD = 120, ///< Sony PlayStation 5 game Blu-ray
|
||||
// Sony game media, types 110 to 129
|
||||
|
||||
// Microsoft game media, types 130 to 149
|
||||
@@ -977,6 +979,7 @@ typedef enum
|
||||
kSectorTagDvdSectorEdc = 19, ///< DVD sector EDC, 4 bytes
|
||||
kSectorTagAppleProfile = 20, ///< Apple's Profile sector tags, 20 bytes
|
||||
kSectorTagPriamDataTower = 21, ///< Priam DataTower sector tags, 24 bytes
|
||||
kSectorTagBdSectorEdc = 22, ///< Blu-ray sector EDC, 4 bytes
|
||||
MaxSectorTag = kSectorTagPriamDataTower
|
||||
} SectorTagType;
|
||||
|
||||
@@ -1082,6 +1085,8 @@ typedef enum
|
||||
kMediaTagWiiUPartitionKeyMap = 82, ///< Nintendo Wii U partition-to-key mapping with regions
|
||||
kMediaTagWiiPartitionKeyMap = 83, ///< Nintendo Wii partition-to-key mapping with regions
|
||||
kMediaTagNgcwJunkMap = 84, ///< Nintendo GameCube/Wii junk region map with LFG seeds
|
||||
kMediaTagAacsMediaKey = 85, ///< AACS Media Key
|
||||
kMediaTagAacsVolumeUniqueKey = 86, ///< AACS Volume Unique Key
|
||||
MaxMediaTag = kMediaTagNgcwJunkMap
|
||||
} MediaTagType;
|
||||
|
||||
|
||||
@@ -145,6 +145,9 @@ typedef enum
|
||||
kDataTypeWiiUPartitionKeyMap = 98, ///< Nintendo Wii U partition-to-key mapping with regions
|
||||
kDataTypeWiiPartitionKeyMap = 99, ///< Nintendo Wii partition-to-key mapping with regions
|
||||
kDataTypeNgcwJunkMap = 100, ///< Nintendo GameCube/Wii junk region map with LFG seeds
|
||||
kDataTypeAacsMediaKey = 101, ///< AACS Media Key
|
||||
kDataTypeAacsVolumeUniqueKey = 102, ///< AACS Volume Unique Key
|
||||
kDataTypeBdSectorEdc = 103, ///< Blu-ray Sector EDC
|
||||
} DataType;
|
||||
|
||||
/**
|
||||
|
||||
@@ -480,6 +480,10 @@ int32_t process_data_block(aaruformat_context *ctx, IndexEntry *entry)
|
||||
ctx->sector_decrypted_title_key = data;
|
||||
ctx->readableSectorTags[kSectorTagDvdTitleKeyDecrypted] = true;
|
||||
break;
|
||||
case kDataTypeBdSectorEdc:
|
||||
ctx->sector_edc = data;
|
||||
ctx->readableSectorTags[kSectorTagBdSectorEdc] = true;
|
||||
break;
|
||||
default:
|
||||
media_tag = (mediaTagEntry *)malloc(sizeof(mediaTagEntry));
|
||||
|
||||
|
||||
@@ -202,6 +202,10 @@ AARU_LOCAL int32_t AARU_CALL aaruf_get_media_tag_type_for_datatype(const int32_t
|
||||
return kMediaTagWiiPartitionKeyMap;
|
||||
case kDataTypeNgcwJunkMap:
|
||||
return kMediaTagNgcwJunkMap;
|
||||
case kDataTypeAacsMediaKey:
|
||||
return kMediaTagAacsMediaKey;
|
||||
case kDataTypeAacsVolumeUniqueKey:
|
||||
return kMediaTagAacsVolumeUniqueKey;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
@@ -382,6 +386,10 @@ AARU_LOCAL int32_t AARU_CALL aaruf_get_datatype_for_media_tag_type(const int32_t
|
||||
return kDataTypeWiiPartitionKeyMap;
|
||||
case kMediaTagNgcwJunkMap:
|
||||
return kDataTypeNgcwJunkMap;
|
||||
case kMediaTagAacsMediaKey:
|
||||
return kDataTypeAacsMediaKey;
|
||||
case kMediaTagAacsVolumeUniqueKey:
|
||||
return kDataTypeAacsVolumeUniqueKey;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
192
src/read.c
192
src/read.c
@@ -1542,70 +1542,134 @@ AARU_EXPORT int32_t AARU_CALL aaruf_read_sector_long(void *context, const uint64
|
||||
}
|
||||
|
||||
if(ctx->image_info.MediaType == GOD || ctx->image_info.MediaType == WOD)
|
||||
{
|
||||
if(ctx->sector_id == NULL || ctx->sector_ied == NULL || ctx->sector_cpr_mai == NULL ||
|
||||
ctx->sector_edc == NULL)
|
||||
return aaruf_read_sector(context, sector_address, negative, data, length, sector_status);
|
||||
|
||||
if(*length < 2064 || data == NULL)
|
||||
{
|
||||
*length = 2064;
|
||||
FATAL("Buffer too small for sector, required %u bytes", *length);
|
||||
|
||||
TRACE("Exiting aaruf_read_sector_long() = AARUF_ERROR_BUFFER_TOO_SMALL");
|
||||
return AARUF_ERROR_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
bare_length = 0;
|
||||
query_status = aaruf_read_sector(context, sector_address, negative, NULL, &bare_length, sector_status);
|
||||
|
||||
if(query_status != AARUF_ERROR_BUFFER_TOO_SMALL && query_status != AARUF_STATUS_OK)
|
||||
{
|
||||
TRACE("Exiting aaruf_read_sector_long() = %d", query_status);
|
||||
return query_status;
|
||||
}
|
||||
|
||||
if(bare_length == 0)
|
||||
{
|
||||
FATAL("Invalid bare sector length (0)");
|
||||
|
||||
TRACE("Exiting aaruf_read_sector_long() = AARUF_ERROR_INCORRECT_DATA_SIZE");
|
||||
return AARUF_ERROR_INCORRECT_DATA_SIZE;
|
||||
}
|
||||
|
||||
TRACE("Allocating memory for bare data");
|
||||
bare_data = (uint8_t *)malloc(bare_length);
|
||||
|
||||
if(bare_data == NULL)
|
||||
{
|
||||
FATAL("Could not allocate memory for bare data");
|
||||
|
||||
TRACE("Exiting aaruf_read_sector_long() = AARUF_ERROR_NOT_ENOUGH_MEMORY");
|
||||
return AARUF_ERROR_NOT_ENOUGH_MEMORY;
|
||||
}
|
||||
|
||||
res = aaruf_read_sector(context, sector_address, negative, bare_data, &bare_length, sector_status);
|
||||
|
||||
if(res != AARUF_STATUS_OK)
|
||||
{
|
||||
*length = 2064;
|
||||
free(bare_data);
|
||||
|
||||
TRACE("Exiting aaruf_read_sector_long() = %d", res);
|
||||
return res;
|
||||
}
|
||||
|
||||
memcpy(data, ctx->sector_id + corrected_sector_address * 4, 4);
|
||||
memcpy(data + 4, ctx->sector_ied + corrected_sector_address * 2, 2);
|
||||
memcpy(data + 6, bare_data, 2048);
|
||||
memcpy(data + 2054, ctx->sector_cpr_mai + corrected_sector_address * 6, 6);
|
||||
memcpy(data + 2060, ctx->sector_edc + corrected_sector_address * 4, 4);
|
||||
|
||||
*length = 2064;
|
||||
|
||||
free(bare_data);
|
||||
return AARUF_STATUS_OK;
|
||||
}
|
||||
{
|
||||
if(ctx->sector_id == NULL || ctx->sector_ied == NULL || ctx->sector_cpr_mai == NULL ||
|
||||
ctx->sector_edc == NULL)
|
||||
return aaruf_read_sector(context, sector_address, negative, data, length, sector_status);
|
||||
|
||||
if(*length < 2064 || data == NULL)
|
||||
{
|
||||
*length = 2064;
|
||||
FATAL("Buffer too small for sector, required %u bytes", *length);
|
||||
|
||||
TRACE("Exiting aaruf_read_sector_long() = AARUF_ERROR_BUFFER_TOO_SMALL");
|
||||
return AARUF_ERROR_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
bare_length = 0;
|
||||
query_status = aaruf_read_sector(context, sector_address, negative, NULL, &bare_length, sector_status);
|
||||
|
||||
if(query_status != AARUF_ERROR_BUFFER_TOO_SMALL && query_status != AARUF_STATUS_OK)
|
||||
{
|
||||
TRACE("Exiting aaruf_read_sector_long() = %d", query_status);
|
||||
return query_status;
|
||||
}
|
||||
|
||||
if(bare_length == 0)
|
||||
{
|
||||
FATAL("Invalid bare sector length (0)");
|
||||
|
||||
TRACE("Exiting aaruf_read_sector_long() = AARUF_ERROR_INCORRECT_DATA_SIZE");
|
||||
return AARUF_ERROR_INCORRECT_DATA_SIZE;
|
||||
}
|
||||
|
||||
TRACE("Allocating memory for bare data");
|
||||
bare_data = (uint8_t *)malloc(bare_length);
|
||||
|
||||
if(bare_data == NULL)
|
||||
{
|
||||
FATAL("Could not allocate memory for bare data");
|
||||
|
||||
TRACE("Exiting aaruf_read_sector_long() = AARUF_ERROR_NOT_ENOUGH_MEMORY");
|
||||
return AARUF_ERROR_NOT_ENOUGH_MEMORY;
|
||||
}
|
||||
|
||||
res = aaruf_read_sector(context, sector_address, negative, bare_data, &bare_length, sector_status);
|
||||
|
||||
if(res != AARUF_STATUS_OK)
|
||||
{
|
||||
*length = 2064;
|
||||
free(bare_data);
|
||||
|
||||
TRACE("Exiting aaruf_read_sector_long() = %d", res);
|
||||
return res;
|
||||
}
|
||||
|
||||
memcpy(data, ctx->sector_id + corrected_sector_address * 4, 4);
|
||||
memcpy(data + 4, ctx->sector_ied + corrected_sector_address * 2, 2);
|
||||
memcpy(data + 6, bare_data, 2048);
|
||||
memcpy(data + 2054, ctx->sector_cpr_mai + corrected_sector_address * 6, 6);
|
||||
memcpy(data + 2060, ctx->sector_edc + corrected_sector_address * 4, 4);
|
||||
|
||||
*length = 2064;
|
||||
|
||||
free(bare_data);
|
||||
return AARUF_STATUS_OK;
|
||||
}
|
||||
|
||||
if(ctx->image_info.MediaType == BDROM || ctx->image_info.MediaType == BDR ||
|
||||
ctx->image_info.MediaType == BDRE || ctx->image_info.MediaType == BDRXL ||
|
||||
ctx->image_info.MediaType == BDREXL || ctx->image_info.MediaType == UHDBD ||
|
||||
ctx->image_info.MediaType == XGD4 || ctx->image_info.MediaType == PS3BD ||
|
||||
ctx->image_info.MediaType == PS4BD || ctx->image_info.MediaType == PS5BD)
|
||||
{
|
||||
if(ctx->sector_edc == NULL) return aaruf_read_sector(context, sector_address, negative, data, length, sector_status);
|
||||
|
||||
if(*length < 2052 || data == NULL)
|
||||
{
|
||||
*length = 2052;
|
||||
FATAL("Buffer too small for sector, required %u bytes", *length);
|
||||
|
||||
TRACE("Exiting aaruf_read_sector_long() = AARUF_ERROR_BUFFER_TOO_SMALL");
|
||||
return AARUF_ERROR_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
bare_length = 0;
|
||||
query_status = aaruf_read_sector(context, sector_address, negative, NULL, &bare_length, sector_status);
|
||||
|
||||
if(query_status != AARUF_ERROR_BUFFER_TOO_SMALL && query_status != AARUF_STATUS_OK)
|
||||
{
|
||||
TRACE("Exiting aaruf_read_sector_long() = %d", query_status);
|
||||
return query_status;
|
||||
}
|
||||
|
||||
if(bare_length == 0)
|
||||
{
|
||||
FATAL("Invalid bare sector length (0)");
|
||||
|
||||
TRACE("Exiting aaruf_read_sector_long() = AARUF_ERROR_INCORRECT_DATA_SIZE");
|
||||
return AARUF_ERROR_INCORRECT_DATA_SIZE;
|
||||
}
|
||||
|
||||
TRACE("Allocating memory for bare data");
|
||||
bare_data = (uint8_t *)malloc(bare_length);
|
||||
|
||||
if(bare_data == NULL)
|
||||
{
|
||||
FATAL("Could not allocate memory for bare data");
|
||||
|
||||
TRACE("Exiting aaruf_read_sector_long() = AARUF_ERROR_NOT_ENOUGH_MEMORY");
|
||||
return AARUF_ERROR_NOT_ENOUGH_MEMORY;
|
||||
}
|
||||
|
||||
res = aaruf_read_sector(context, sector_address, negative, bare_data, &bare_length, sector_status);
|
||||
|
||||
if(res != AARUF_STATUS_OK)
|
||||
{
|
||||
free(bare_data);
|
||||
|
||||
TRACE("Exiting aaruf_read_sector_long() = %d", res);
|
||||
return res;
|
||||
}
|
||||
|
||||
memcpy(data, bare_data, 2048);
|
||||
memcpy(data + 2048, ctx->sector_edc + corrected_sector_address * 4, 4);
|
||||
|
||||
*length = 2052;
|
||||
|
||||
free(bare_data);
|
||||
return AARUF_STATUS_OK;
|
||||
}
|
||||
|
||||
if(*length < 2352 || data == NULL)
|
||||
{
|
||||
|
||||
14
src/write.c
14
src/write.c
@@ -735,6 +735,20 @@ AARU_EXPORT int32_t AARU_CALL aaruf_write_sector_long(void *context, uint64_t se
|
||||
return aaruf_write_sector(context, sector_address, negative, data + 6, sector_status, 2048);
|
||||
}
|
||||
|
||||
// Blu-ray long sector
|
||||
if(length == 2052 && (ctx->image_info.MediaType == BDROM || ctx->image_info.MediaType == BDR ||
|
||||
ctx->image_info.MediaType == BDRE || ctx->image_info.MediaType == BDRXL ||
|
||||
ctx->image_info.MediaType == BDREXL || ctx->image_info.MediaType == UHDBD ||
|
||||
ctx->image_info.MediaType == XGD4 || ctx->image_info.MediaType == PS3BD ||
|
||||
ctx->image_info.MediaType == PS4BD || ctx->image_info.MediaType == PS5BD))
|
||||
{
|
||||
if(ctx->sector_edc == NULL) ctx->sector_edc = calloc(1, 4 * total_sectors);
|
||||
|
||||
memcpy(ctx->sector_edc + corrected_sector_address * 4, data + 2048, 4);
|
||||
|
||||
return aaruf_write_sector(context, sector_address, negative, data, sector_status, 2048);
|
||||
}
|
||||
|
||||
if(length != 2352)
|
||||
{
|
||||
FATAL("Incorrect sector size");
|
||||
|
||||
@@ -206,6 +206,10 @@ const char *media_tag_type_to_string(int32_t type)
|
||||
return "DVD Physical Format Information (2nd layer)";
|
||||
case kMediaTagFloppyWriteProtect:
|
||||
return "Floppy Write-Protect Status";
|
||||
case kMediaTagAacsMediaKey:
|
||||
return "AACS Media Key";
|
||||
case kMediaTagAacsVolumeUniqueKey:
|
||||
return "AACS Volume Unique Key";
|
||||
default:
|
||||
return "Unknown Media Tag";
|
||||
}
|
||||
@@ -391,6 +395,12 @@ const char *data_type_to_string(uint16_t type)
|
||||
return "DVD Physical Format Info (2nd layer)";
|
||||
case kDataTypeFloppyWriteProtect:
|
||||
return "Floppy Write-Protect Status";
|
||||
case kDataTypeAacsMediaKey:
|
||||
return "AACS Media Key";
|
||||
case kDataTypeAacsVolumeUniqueKey:
|
||||
return "AACS Volume Unique Key";
|
||||
case kDataTypeBdSectorEdc:
|
||||
return "Blu-ray Sector EDC";
|
||||
default:
|
||||
return "Unknown Data Type";
|
||||
}
|
||||
@@ -1587,6 +1597,8 @@ const char *sector_tag_type_to_string(int32_t type)
|
||||
return "Apple Profile Tag";
|
||||
case kSectorTagPriamDataTower:
|
||||
return "Priam DataTower Tag";
|
||||
case kSectorTagBdSectorEdc:
|
||||
return "Blu-ray Sector EDC";
|
||||
default:
|
||||
return "Unknown Sector Tag";
|
||||
}
|
||||
|
||||
@@ -134,6 +134,8 @@ static const MediaTagTypeMapping media_tag_mappings[] = {
|
||||
{"kMediaTagDvdDiscKeyDecrypted", kMediaTagDvdDiscKeyDecrypted},
|
||||
{"kMediaTagDvdPfi2ndLayer", kMediaTagDvdPfi2ndLayer},
|
||||
{"kMediaTagFloppyWriteProtect", kMediaTagFloppyWriteProtect},
|
||||
{"kMediaTagAacsMediaKey", kMediaTagAacsMediaKey},
|
||||
{"kMediaTagAacsVolumeUniqueKey", kMediaTagAacsVolumeUniqueKey},
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
@@ -290,6 +292,10 @@ static int32_t get_datatype_for_media_tag_type(MediaTagType tag_type)
|
||||
return kDataTypeDvdDiscKeyDecrypted;
|
||||
case kMediaTagFloppyWriteProtect:
|
||||
return kDataTypeFloppyWriteProtect;
|
||||
case kMediaTagAacsMediaKey:
|
||||
return kDataTypeAacsMediaKey;
|
||||
case kMediaTagAacsVolumeUniqueKey:
|
||||
return kDataTypeAacsVolumeUniqueKey;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user