325 lines
9.4 KiB
Plaintext
325 lines
9.4 KiB
Plaintext
$OpenBSD: patch-src_vm_vm_c,v 1.1 2012/09/26 00:04:09 brad Exp $
|
|
|
|
- Reset the vm if necessary
|
|
- Use vm_close() w/in vm.c where appropriate
|
|
- Add the static function vm_close()
|
|
- Check the return value of dvd_read_name
|
|
- Rewrite dvd_read_name to return a value
|
|
- Prevent general CPP macro from causing strange behavior
|
|
- Replace assert w/ a conditional and a null return
|
|
- Initialize link_values
|
|
- Pointer validation fixing
|
|
- Return 0 instead of an assert
|
|
|
|
--- src/vm/vm.c.orig Wed Sep 5 14:18:33 2012
|
|
+++ src/vm/vm.c Wed Sep 5 14:18:50 2012
|
|
@@ -59,7 +59,7 @@
|
|
#endif
|
|
|
|
/*
|
|
-#define STRICT
|
|
+#define DVDNAV_STRICT
|
|
*/
|
|
|
|
/* Local prototypes */
|
|
@@ -101,8 +101,8 @@ static int get_PGCN(vm_t *vm);
|
|
static pgcit_t* get_MENU_PGCIT(vm_t *vm, ifo_handle_t *h, uint16_t lang);
|
|
static pgcit_t* get_PGCIT(vm_t *vm);
|
|
|
|
-
|
|
/* Helper functions */
|
|
+static void vm_close(vm_t *vm);
|
|
|
|
#ifdef TRACE
|
|
static void vm_print_current_domain_state(vm_t *vm) {
|
|
@@ -162,64 +162,86 @@ static int os2_open(const char *name, int oflag)
|
|
}
|
|
#endif
|
|
|
|
-static void dvd_read_name(char *name, char *serial, const char *device) {
|
|
- /* Because we are compiling with _FILE_OFFSET_BITS=64
|
|
- * all off_t are 64bit.
|
|
- */
|
|
- off_t off;
|
|
- int fd, i;
|
|
- uint8_t data[DVD_VIDEO_LB_LEN];
|
|
+static int dvd_read_name(char *name, char *serial, const char *device) {
|
|
+ /* Because we are compiling with _FILE_OFFSET_BITS=64
|
|
+ * all off_t are 64bit.
|
|
+ */
|
|
+ off_t off;
|
|
+ ssize_t read_size = 0;
|
|
+ int fd = -1, i;
|
|
+ uint8_t data[DVD_VIDEO_LB_LEN];
|
|
|
|
- /* Read DVD name */
|
|
- fd = open(device, O_RDONLY);
|
|
- if (fd > 0) {
|
|
- off = lseek( fd, 32 * (off_t) DVD_VIDEO_LB_LEN, SEEK_SET );
|
|
- if( off == ( 32 * (off_t) DVD_VIDEO_LB_LEN ) ) {
|
|
- off = read( fd, data, DVD_VIDEO_LB_LEN );
|
|
- close(fd);
|
|
- if (off == ( (off_t) DVD_VIDEO_LB_LEN )) {
|
|
- fprintf(MSG_OUT, "libdvdnav: DVD Title: ");
|
|
- for(i=25; i < 73; i++ ) {
|
|
- if((data[i] == 0)) break;
|
|
- if((data[i] > 32) && (data[i] < 127)) {
|
|
- fprintf(MSG_OUT, "%c", data[i]);
|
|
- } else {
|
|
- fprintf(MSG_OUT, " ");
|
|
- }
|
|
- }
|
|
- strncpy(name, (char*) &data[25], 48);
|
|
- name[48] = 0;
|
|
- fprintf(MSG_OUT, "\nlibdvdnav: DVD Serial Number: ");
|
|
- for(i=73; i < 89; i++ ) {
|
|
- if((data[i] == 0)) break;
|
|
- if((data[i] > 32) && (data[i] < 127)) {
|
|
- fprintf(MSG_OUT, "%c", data[i]);
|
|
- } else {
|
|
- fprintf(MSG_OUT, " ");
|
|
- }
|
|
- }
|
|
- strncpy(serial, (char*) &data[73], (i-73));
|
|
- serial[14] = 0;
|
|
- fprintf(MSG_OUT, "\nlibdvdnav: DVD Title (Alternative): ");
|
|
- for(i=89; i < 128; i++ ) {
|
|
- if((data[i] == 0)) break;
|
|
- if((data[i] > 32) && (data[i] < 127)) {
|
|
- fprintf(MSG_OUT, "%c", data[i]);
|
|
- } else {
|
|
- fprintf(MSG_OUT, " ");
|
|
- }
|
|
- }
|
|
- fprintf(MSG_OUT, "\n");
|
|
- } else {
|
|
- fprintf(MSG_OUT, "libdvdnav: Can't read name block. Probably not a DVD-ROM device.\n");
|
|
- }
|
|
- } else {
|
|
- fprintf(MSG_OUT, "libdvdnav: Can't seek to block %u\n", 32 );
|
|
- }
|
|
- close(fd);
|
|
+ /* Read DVD name */
|
|
+ if (device == NULL) {
|
|
+ fprintf(MSG_OUT, "libdvdnav: Device name string NULL\n");
|
|
+ goto fail;
|
|
+ }
|
|
+ if ((fd = open(device, O_RDONLY)) == -1) {
|
|
+ fprintf(MSG_OUT, "libdvdnav: Unable to open device file %s.\n", device);
|
|
+ goto fail;
|
|
+ }
|
|
+
|
|
+ if ((off = lseek( fd, 32 * (off_t) DVD_VIDEO_LB_LEN, SEEK_SET )) == (off_t) - 1) {
|
|
+ fprintf(MSG_OUT, "libdvdnav: Unable to seek to the title block %u.\n", 32);
|
|
+ goto fail;
|
|
+ }
|
|
+
|
|
+ if( off != ( 32 * (off_t) DVD_VIDEO_LB_LEN ) ) {
|
|
+ fprintf(MSG_OUT, "libdvdnav: Can't seek to block %u\n", 32 );
|
|
+ goto fail;
|
|
+ }
|
|
+
|
|
+ if ((read_size = read( fd, data, DVD_VIDEO_LB_LEN )) == -1) {
|
|
+ fprintf(MSG_OUT, "libdvdnav: Can't read name block. Probably not a DVD-ROM device.\n");
|
|
+ goto fail;
|
|
+ }
|
|
+
|
|
+ close(fd);
|
|
+ fd = -1;
|
|
+ if (read_size != DVD_VIDEO_LB_LEN) {
|
|
+ fprintf(MSG_OUT, "libdvdnav: Can't read name block. Probably not a DVD-ROM device.\n");
|
|
+ goto fail;
|
|
+ }
|
|
+
|
|
+ fprintf(MSG_OUT, "libdvdnav: DVD Title: ");
|
|
+ for(i=25; i < 73; i++ ) {
|
|
+ if((data[i] == 0)) break;
|
|
+ if((data[i] > 32) && (data[i] < 127)) {
|
|
+ fprintf(MSG_OUT, "%c", data[i]);
|
|
} else {
|
|
- fprintf(MSG_OUT, "NAME OPEN FAILED\n");
|
|
+ fprintf(MSG_OUT, " ");
|
|
+ }
|
|
}
|
|
+ strncpy(name, (char*) &data[25], 48);
|
|
+ name[48] = 0;
|
|
+ fprintf(MSG_OUT, "\nlibdvdnav: DVD Serial Number: ");
|
|
+ for(i=73; i < 89; i++ ) {
|
|
+ if((data[i] == 0)) break;
|
|
+ if((data[i] > 32) && (data[i] < 127)) {
|
|
+ fprintf(MSG_OUT, "%c", data[i]);
|
|
+ } else {
|
|
+ fprintf(MSG_OUT, " ");
|
|
+ }
|
|
+ }
|
|
+ strncpy(serial, (char*) &data[73], (i-73));
|
|
+ serial[14] = 0;
|
|
+ fprintf(MSG_OUT, "\nlibdvdnav: DVD Title (Alternative): ");
|
|
+ for(i=89; i < 128; i++ ) {
|
|
+ if((data[i] == 0)) break;
|
|
+ if((data[i] > 32) && (data[i] < 127)) {
|
|
+ fprintf(MSG_OUT, "%c", data[i]);
|
|
+ } else {
|
|
+ fprintf(MSG_OUT, " ");
|
|
+ }
|
|
+ }
|
|
+ fprintf(MSG_OUT, "\n");
|
|
+ return 1;
|
|
+
|
|
+fail:
|
|
+ if (fd >= 0)
|
|
+ close(fd);
|
|
+
|
|
+ return 0;
|
|
}
|
|
|
|
static int ifoOpenNewVTSI(vm_t *vm, dvd_reader_t *dvd, int vtsN) {
|
|
@@ -268,7 +290,7 @@ vm_t* vm_new_vm() {
|
|
}
|
|
|
|
void vm_free_vm(vm_t *vm) {
|
|
- vm_stop(vm);
|
|
+ vm_close(vm);
|
|
free(vm);
|
|
}
|
|
|
|
@@ -294,6 +316,12 @@ dvd_reader_t *vm_get_dvd_reader(vm_t *vm) {
|
|
/* Basic Handling */
|
|
|
|
int vm_start(vm_t *vm) {
|
|
+ if (vm->stopped) {
|
|
+ if (!vm_reset(vm, NULL))
|
|
+ return 0;
|
|
+
|
|
+ vm->stopped = 0;
|
|
+ }
|
|
/* Set pgc to FP (First Play) pgc */
|
|
set_FP_PGC(vm);
|
|
process_command(vm, play_PGC(vm));
|
|
@@ -301,6 +329,10 @@ int vm_start(vm_t *vm) {
|
|
}
|
|
|
|
void vm_stop(vm_t *vm) {
|
|
+ vm->stopped = 1;
|
|
+}
|
|
+
|
|
+static void vm_close(vm_t *vm) {
|
|
if(vm->vmgi) {
|
|
ifoClose(vm->vmgi);
|
|
vm->vmgi=NULL;
|
|
@@ -352,7 +384,7 @@ int vm_reset(vm_t *vm, const char *dvdroot) {
|
|
|
|
if (vm->dvd && dvdroot) {
|
|
/* a new dvd device has been requested */
|
|
- vm_stop(vm);
|
|
+ vm_close(vm);
|
|
}
|
|
if (!vm->dvd) {
|
|
vm->dvd = DVDOpen(dvdroot);
|
|
@@ -390,8 +422,8 @@ int vm_reset(vm_t *vm, const char *dvdroot) {
|
|
/* return 0; Not really used for now.. */
|
|
}
|
|
/* ifoRead_TXTDT_MGI(vmgi); Not implemented yet */
|
|
- dvd_read_name(vm->dvd_name, vm->dvd_serial, dvdroot);
|
|
- vm->map = remap_loadmap(vm->dvd_name);
|
|
+ if (dvd_read_name(vm->dvd_name, vm->dvd_serial, dvdroot) == 1)
|
|
+ vm->map = remap_loadmap(vm->dvd_name);
|
|
}
|
|
if (vm->vmgi) {
|
|
int i, mask;
|
|
@@ -414,7 +446,8 @@ vm_t *vm_new_copy(vm_t *source) {
|
|
int pgcN = get_PGCN(source);
|
|
int pgN = (source->state).pgN;
|
|
|
|
- assert(pgcN);
|
|
+ if (target == NULL || pgcN == 0)
|
|
+ goto fail;
|
|
|
|
memcpy(target, source, sizeof(vm_t));
|
|
|
|
@@ -424,15 +457,22 @@ vm_t *vm_new_copy(vm_t *source) {
|
|
if (vtsN > 0) {
|
|
(target->state).vtsN = 0;
|
|
if (!ifoOpenNewVTSI(target, target->dvd, vtsN))
|
|
- assert(0);
|
|
+ goto fail;
|
|
|
|
/* restore pgc pointer into the new vtsi */
|
|
if (!set_PGCN(target, pgcN))
|
|
- assert(0);
|
|
+ goto fail;
|
|
+
|
|
(target->state).pgN = pgN;
|
|
}
|
|
|
|
return target;
|
|
+
|
|
+fail:
|
|
+ if (target != NULL)
|
|
+ vm_free_vm(target);
|
|
+
|
|
+ return NULL;
|
|
}
|
|
|
|
void vm_merge(vm_t *target, vm_t *source) {
|
|
@@ -1050,7 +1090,7 @@ static link_t play_PGC_PG(vm_t *vm, int pgN) {
|
|
}
|
|
|
|
static link_t play_PGC_post(vm_t *vm) {
|
|
- link_t link_values;
|
|
+ link_t link_values = { LinkNoLink, 0, 0, 0 };
|
|
|
|
#ifdef TRACE
|
|
fprintf(MSG_OUT, "libdvdnav: play_PGC_post:\n");
|
|
@@ -1129,7 +1169,7 @@ static link_t play_Cell(vm_t *vm) {
|
|
case 1: /* Angle block */
|
|
/* Loop and check each cell instead? So we don't get outside the block? */
|
|
(vm->state).cellN += (vm->state).AGL_REG - 1;
|
|
-#ifdef STRICT
|
|
+#ifdef DVDNAV_STRICT
|
|
assert((vm->state).cellN <= (vm->state).pgc->nr_of_cells);
|
|
assert((vm->state).pgc->cell_playback[(vm->state).cellN - 1].block_mode != 0);
|
|
assert((vm->state).pgc->cell_playback[(vm->state).cellN - 1].block_type == 1);
|
|
@@ -1187,15 +1227,6 @@ static link_t play_Cell_post(vm_t *vm) {
|
|
if(cell->cell_cmd_nr != 0) {
|
|
link_t link_values;
|
|
|
|
-/* These asserts are now not needed.
|
|
- * Some DVDs have no cell commands listed in the PGC,
|
|
- * but the Cell itself points to a cell command that does not exist.
|
|
- * For this situation, just ignore the cell command and continue.
|
|
- *
|
|
- * assert((vm->state).pgc->command_tbl != NULL);
|
|
- * assert((vm->state).pgc->command_tbl->nr_of_cell >= cell->cell_cmd_nr);
|
|
- */
|
|
-
|
|
if ((vm->state).pgc->command_tbl != NULL &&
|
|
(vm->state).pgc->command_tbl->nr_of_cell >= cell->cell_cmd_nr) {
|
|
#ifdef TRACE
|
|
@@ -1762,7 +1793,8 @@ static int set_PGCN(vm_t *vm, int pgcN) {
|
|
pgcit_t *pgcit;
|
|
|
|
pgcit = get_PGCIT(vm);
|
|
- assert(pgcit != NULL); /* ?? Make this return -1 instead */
|
|
+ if (pgcit == NULL)
|
|
+ return 0;
|
|
|
|
if(pgcN < 1 || pgcN > pgcit->nr_of_pgci_srp) {
|
|
#ifdef TRACE
|
|
@@ -1797,12 +1829,11 @@ static int set_PGN(vm_t *vm) {
|
|
(vm->state).pgN = new_pgN;
|
|
|
|
if((vm->state).domain == VTS_DOMAIN) {
|
|
- playback_type_t *pb_ty;
|
|
if((vm->state).TTN_REG > vm->vmgi->tt_srpt->nr_of_srpts)
|
|
return 0; /* ?? */
|
|
- pb_ty = &vm->vmgi->tt_srpt->title[(vm->state).TTN_REG - 1].pb_ty;
|
|
- vm_get_current_title_part(vm, &dummy, &part);
|
|
- (vm->state).PTTN_REG = part;
|
|
+
|
|
+ vm_get_current_title_part(vm, &dummy, &part);
|
|
+ (vm->state).PTTN_REG = part;
|
|
}
|
|
return 1;
|
|
}
|