|
Packit |
5e46da |
/*
|
|
Packit |
5e46da |
* This file is part of libbluray
|
|
Packit |
5e46da |
* Copyright (C) 2012-2017 Petri Hintukainen <phintuka@users.sourceforge.net>
|
|
Packit |
5e46da |
*
|
|
Packit |
5e46da |
* This library is free software; you can redistribute it and/or
|
|
Packit |
5e46da |
* modify it under the terms of the GNU Lesser General Public
|
|
Packit |
5e46da |
* License as published by the Free Software Foundation; either
|
|
Packit |
5e46da |
* version 2.1 of the License, or (at your option) any later version.
|
|
Packit |
5e46da |
*
|
|
Packit |
5e46da |
* This library is distributed in the hope that it will be useful,
|
|
Packit |
5e46da |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
5e46da |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Packit |
5e46da |
* Lesser General Public License for more details.
|
|
Packit |
5e46da |
*
|
|
Packit |
5e46da |
* You should have received a copy of the GNU Lesser General Public
|
|
Packit |
5e46da |
* License along with this library. If not, see
|
|
Packit |
5e46da |
* <http://www.gnu.org/licenses/>.
|
|
Packit |
5e46da |
*/
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
#if HAVE_CONFIG_H
|
|
Packit |
5e46da |
#include "config.h"
|
|
Packit |
5e46da |
#endif
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
#include "bdid_parse.h"
|
|
Packit |
5e46da |
#include "bdmv_parse.h"
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
#include "disc/disc.h"
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
#include "file/file.h"
|
|
Packit |
5e46da |
#include "util/bits.h"
|
|
Packit |
5e46da |
#include "util/logging.h"
|
|
Packit |
5e46da |
#include "util/macro.h"
|
|
Packit |
5e46da |
#include "util/strutl.h"
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
#include <stdlib.h>
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
#define BDID_SIG1 ('B' << 24 | 'D' << 16 | 'I' << 8 | 'D')
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
static int _parse_header(BITSTREAM *bs, uint32_t *data_start, uint32_t *extension_data_start)
|
|
Packit |
5e46da |
{
|
|
Packit |
5e46da |
if (!bdmv_parse_header(bs, BDID_SIG1, NULL)) {
|
|
Packit |
5e46da |
return 0;
|
|
Packit |
5e46da |
}
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
*data_start = bs_read(bs, 32);
|
|
Packit |
5e46da |
*extension_data_start = bs_read(bs, 32);
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
return 1;
|
|
Packit |
5e46da |
}
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
static BDID_DATA *_bdid_parse(BD_FILE_H *fp)
|
|
Packit |
5e46da |
{
|
|
Packit |
5e46da |
BITSTREAM bs;
|
|
Packit |
5e46da |
BDID_DATA *bdid = NULL;
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
uint32_t data_start, extension_data_start;
|
|
Packit |
5e46da |
uint8_t tmp[16];
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
if (bs_init(&bs, fp) < 0) {
|
|
Packit |
5e46da |
BD_DEBUG(DBG_NAV, "id.bdmv: read error\n");
|
|
Packit |
5e46da |
return NULL;
|
|
Packit |
5e46da |
}
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
if (!_parse_header(&bs, &data_start, &extension_data_start)) {
|
|
Packit |
5e46da |
BD_DEBUG(DBG_NAV | DBG_CRIT, "id.bdmv: invalid header\n");
|
|
Packit |
5e46da |
return NULL;
|
|
Packit |
5e46da |
}
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
if (bs_seek_byte(&bs, 40) < 0) {
|
|
Packit |
5e46da |
BD_DEBUG(DBG_NAV, "id.bdmv: read error\n");
|
|
Packit |
5e46da |
return NULL;
|
|
Packit |
5e46da |
}
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
bdid = calloc(1, sizeof(BDID_DATA));
|
|
Packit |
5e46da |
if (!bdid) {
|
|
Packit |
5e46da |
BD_DEBUG(DBG_CRIT, "out of memory\n");
|
|
Packit |
5e46da |
return NULL;
|
|
Packit |
5e46da |
}
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
bs_read_bytes(&bs, tmp, 4);
|
|
Packit |
5e46da |
str_print_hex(bdid->org_id, tmp, 4);
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
bs_read_bytes(&bs, tmp, 16);
|
|
Packit |
5e46da |
str_print_hex(bdid->disc_id, tmp, 16);
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
if (extension_data_start) {
|
|
Packit |
5e46da |
BD_DEBUG(DBG_NAV | DBG_CRIT, "id.bdmv: ignoring unknown extension data\n");
|
|
Packit |
5e46da |
}
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
return bdid;
|
|
Packit |
5e46da |
}
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
static BDID_DATA *_bdid_get(BD_DISC *disc, const char *path)
|
|
Packit |
5e46da |
{
|
|
Packit |
5e46da |
BD_FILE_H *fp;
|
|
Packit |
5e46da |
BDID_DATA *bdid;
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
fp = disc_open_path(disc, path);
|
|
Packit |
5e46da |
if (!fp) {
|
|
Packit |
5e46da |
return NULL;
|
|
Packit |
5e46da |
}
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
bdid = _bdid_parse(fp);
|
|
Packit |
5e46da |
file_close(fp);
|
|
Packit |
5e46da |
return bdid;
|
|
Packit |
5e46da |
}
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
BDID_DATA *bdid_get(BD_DISC *disc)
|
|
Packit |
5e46da |
{
|
|
Packit |
5e46da |
BDID_DATA *bdid;
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
bdid = _bdid_get(disc, "CERTIFICATE" DIR_SEP "id.bdmv");
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
/* if failed, try backup file */
|
|
Packit |
5e46da |
if (!bdid) {
|
|
Packit |
5e46da |
bdid = _bdid_get(disc, "CERTIFICATE" DIR_SEP "BACKUP" DIR_SEP "id.bdmv");
|
|
Packit |
5e46da |
}
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
return bdid;
|
|
Packit |
5e46da |
}
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
void bdid_free(BDID_DATA **p)
|
|
Packit |
5e46da |
{
|
|
Packit |
5e46da |
if (p && *p) {
|
|
Packit |
5e46da |
X_FREE(*p);
|
|
Packit |
5e46da |
}
|
|
Packit |
5e46da |
}
|