brasero r705 - in trunk: . src src/plugins/checksum src/plugins/dvdcss



Author: philippr
Date: Sun Apr 13 14:03:53 2008
New Revision: 705
URL: http://svn.gnome.org/viewvc/brasero?rev=705&view=rev

Log:
	Add new functions to read file disc without mounting it
	Now the checksum-file plugin will include the previous session file checksums for a multi session CD

	* src/Makefile.am:
	* src/brasero-disc-option-dialog.c
	(brasero_disc_option_dialog_get_default_label):
	* src/burn-iso9660.c (brasero_iso9660_read_record_iso_name),
	(brasero_iso9660_read_record_rr_name),
	(brasero_iso9660_read_file_record),
	(brasero_iso9660_read_directory_records),
	(brasero_iso9660_lookup_directory_record),
	(brasero_iso9660_get_file):
	* src/burn-iso9660.h:
	* src/burn-volume-obj.c (brasero_volume_eject),
	(brasero_volume_get_name):
	* src/burn-volume-obj.h:
	* src/burn-volume.c (brasero_volume_file_free),
	(brasero_volume_get_file), (brasero_volume_file_size),
	(brasero_volume_file_merge):
	* src/burn-volume.h:
	* src/plugins/checksum/burn-checksum-files.c
	(brasero_checksum_file_process_former_line),
	(brasero_checksum_files_merge_with_former_session),
	(brasero_checksum_files_create_checksum):
	* src/plugins/dvdcss/burn-dvdcss.c
	(brasero_dvdcss_create_scrambled_sectors_map):

Modified:
   trunk/ChangeLog
   trunk/src/Makefile.am
   trunk/src/brasero-disc-option-dialog.c
   trunk/src/burn-iso9660.c
   trunk/src/burn-iso9660.h
   trunk/src/burn-volume-obj.c
   trunk/src/burn-volume-obj.h
   trunk/src/burn-volume.c
   trunk/src/burn-volume.h
   trunk/src/plugins/checksum/burn-checksum-files.c
   trunk/src/plugins/dvdcss/burn-dvdcss.c

Modified: trunk/src/Makefile.am
==============================================================================
--- trunk/src/Makefile.am	(original)
+++ trunk/src/Makefile.am	Sun Apr 13 14:03:53 2008
@@ -240,7 +240,9 @@
 	burn-volume-obj.h         \
 	scsi-eject.c         \
 	scsi-mech-status.c         \
-	scsi-mech-status.h 
+	scsi-mech-status.h         \
+	burn-volume-read.h         \
+	burn-volume-read.c
 
 if BUILD_INOTIFY
 brasero_SOURCES += brasero-file-monitor.c brasero-file-monitor.h

Modified: trunk/src/brasero-disc-option-dialog.c
==============================================================================
--- trunk/src/brasero-disc-option-dialog.c	(original)
+++ trunk/src/brasero-disc-option-dialog.c	Sun Apr 13 14:03:53 2008
@@ -156,8 +156,12 @@
 		BraseroBurnFlag flags;
 
 		flags = brasero_burn_session_get_flags (priv->session);
-		if (flags & BRASERO_BURN_FLAG_MERGE)
-			title_str = brasero_volume_get_display_label (BRASERO_VOLUME (drive), FALSE);
+		if (flags & BRASERO_BURN_FLAG_MERGE) {
+			BraseroMedium *medium;
+
+			medium = brasero_drive_get_medium (drive);
+			title_str = brasero_volume_get_name (BRASERO_VOLUME (medium));
+		}
 
 		if (!title_str || title_str [0] == '\0')
 			title_str = g_strdup_printf (_("Data disc (%s)"), buffer);

Modified: trunk/src/burn-iso9660.c
==============================================================================
--- trunk/src/burn-iso9660.c	(original)
+++ trunk/src/burn-iso9660.c	Sun Apr 13 14:03:53 2008
@@ -334,6 +334,53 @@
 	return BRASERO_ISO_ERROR;
 }
 
+static gboolean
+brasero_iso9660_read_record_iso_name (BraseroIsoCtx *ctx,
+				      BraseroIsoDirRec *record,
+				      gchar *iso_name)
+{
+	if (record->id_size > record->record_size - sizeof (BraseroIsoDirRec)) {
+		ctx->error = g_error_new (BRASERO_BURN_ERROR,
+					  BRASERO_BURN_ERROR_GENERAL,
+					  _("file name is too long"));
+		return FALSE;
+	}
+
+	memcpy (iso_name, record->id, record->id_size);
+	iso_name [record->id_size] = '\0';
+
+	return TRUE;
+}
+
+static gboolean
+brasero_iso9660_read_record_rr_name (BraseroIsoCtx *ctx,
+				     BraseroIsoDirRec *record,
+				     gchar *rr_name)
+{
+	gchar *susp;
+	gint susp_len;
+	BraseroSuspCtx susp_ctx;
+
+	if (!ctx->has_susp)
+		return FALSE;
+
+	BRASERO_BURN_LOG ("Directory with susp area");
+
+	susp = brasero_iso9660_get_susp (ctx, record, &susp_len);
+	if (!brasero_susp_read (&susp_ctx, susp, susp_len)) {
+		BRASERO_BURN_LOG ("Could not read susp area");
+		return FALSE;
+	}
+
+	if (susp_ctx.rr_name) {
+		BRASERO_BURN_LOG ("Got a susp (RR) %s", susp_ctx.rr_name);
+		strcpy (rr_name, susp_ctx.rr_name);
+	}
+
+	brasero_susp_ctx_clean (&susp_ctx);
+	return TRUE;
+}
+
 static BraseroVolFile *
 brasero_iso9660_read_file_record (BraseroIsoCtx *ctx,
 				  BraseroIsoDirRec *record)
@@ -342,6 +389,7 @@
 	gint susp_len;
 	BraseroVolFile *file;
 	BraseroSuspCtx susp_ctx;
+	BraseroVolFileExtent *extent;
 
 	if (record->id_size > record->record_size - sizeof (BraseroIsoDirRec)) {
 		ctx->error = g_error_new (BRASERO_BURN_ERROR,
@@ -356,7 +404,12 @@
 	memcpy (file->name, record->id, record->id_size);
 
 	file->specific.file.size_bytes = brasero_iso9660_get_733_val (record->file_size);
-	file->specific.file.address_block = brasero_iso9660_get_733_val (record->address);
+
+	/* NOTE a file can be in multiple places */
+	extent = g_new (BraseroVolFileExtent, 1);
+	extent->block = brasero_iso9660_get_733_val (record->address);
+	extent->size = brasero_iso9660_get_733_val (record->file_size);
+	file->specific.file.extents = g_slist_prepend (file->specific.file.extents, extent);
 
 	/* see if we've got a susp area */
 	if (!ctx->has_susp) {
@@ -533,9 +586,9 @@
 
 				last = parent->specific.dir.children->data;
 				if (!last->isdir && !strcmp (BRASERO_VOLUME_FILE_NAME (last), BRASERO_VOLUME_FILE_NAME (entry))) {
-					last->specific.file.size_bytes += entry->specific.file.size_bytes;
+					/* add size and addresses */
 					ctx->data_blocks += ISO9660_BYTES_TO_BLOCKS (entry->specific.file.size_bytes);
-					brasero_volume_file_free (entry);
+					last = brasero_volume_file_merge (last, entry);
 					BRASERO_BURN_LOG ("Multi extent file");
 					continue;
 				}
@@ -614,3 +667,173 @@
 
 	return volfile;
 }
+
+static BraseroVolFile *
+brasero_iso9660_lookup_directory_record (BraseroIsoCtx *ctx,
+					 const gchar *path,
+					 gint address)
+{
+	guint len;
+	gchar *end;
+	gint max_block;
+	gint max_record_size;
+	BraseroIsoResult result;
+	BraseroIsoDirRec *record;
+	BraseroVolFile *file = NULL;
+
+	BRASERO_BURN_LOG ("Reading directory record");
+
+	result = brasero_iso9660_seek (ctx, address);
+	if (result != BRASERO_ISO_OK)
+		return NULL;
+
+	/* "." */
+	result = brasero_iso9660_next_record (ctx, &record);
+	if (result != BRASERO_ISO_OK)
+		return NULL;
+
+	/* look for "SP" SUSP if it's root directory */
+	if (ctx->is_root) {
+		BraseroSuspCtx susp_ctx;
+		gint susp_len;
+		gchar *susp;
+
+		susp = brasero_iso9660_get_susp (ctx, record, &susp_len);
+		brasero_susp_read (&susp_ctx, susp, susp_len);
+
+		ctx->has_susp = susp_ctx.has_SP;
+		ctx->susp_skip = susp_ctx.skip;
+		ctx->is_root = FALSE;
+
+		brasero_susp_ctx_clean (&susp_ctx);
+	}
+
+	max_record_size = brasero_iso9660_get_733_val (record->file_size);
+	max_block = ISO9660_BYTES_TO_BLOCKS (max_record_size);
+	BRASERO_BURN_LOG ("Maximum directory record length %i block (= %i bytes)", max_block, max_record_size);
+
+	/* skip ".." */
+	result = brasero_iso9660_next_record (ctx, &record);
+	if (result != BRASERO_ISO_OK)
+		return NULL;
+
+	BRASERO_BURN_LOG ("Skipped '.' and '..'");
+
+	end = strchr (path, '/');
+	if (!end)
+		/* reached the final file */
+		len = 0;
+	else
+		len = end - path;
+
+	while (1) {
+		BraseroIsoResult result;
+		gchar record_name [256];
+
+		result = brasero_iso9660_next_record (ctx, &record);
+		if (result == BRASERO_ISO_END) {
+			if (ctx->num_blocks >= max_block) {
+				BRASERO_BURN_LOG ("Reached the end of directory record");
+				break;
+			}
+
+			result = brasero_iso9660_next_block (ctx);
+			if (result != BRASERO_ISO_OK) {
+				BRASERO_BURN_LOG ("Failed to load next block");
+				return NULL;
+			}
+
+			continue;
+		}
+		else if (result == BRASERO_ISO_ERROR) {
+			BRASERO_BURN_LOG ("Error retrieving next record");
+			return NULL;
+		}
+
+		if (!record) {
+			BRASERO_BURN_LOG ("No record !!!");
+			break;
+		}
+
+		if (!brasero_iso9660_read_record_rr_name (ctx, record, record_name)
+		&&  !brasero_iso9660_read_record_iso_name (ctx, record, record_name))
+			continue;
+
+		/* if it's a directory, keep the record for later (we don't 
+		 * want to change the reading offset for the moment) */
+		if (!len && !(record->flags & BRASERO_ISO_FILE_DIRECTORY)) {
+			BraseroVolFile *entry;
+
+			/* see if we are looking for a file */
+			if (len)
+				continue;
+
+			/* see if that the record we're looking for */
+			if (strcmp (record_name, path))
+				continue;
+
+			/* carry on with the search in case there are other extents */
+			entry = brasero_iso9660_read_file_record (ctx, record);
+			if (!entry)
+				return NULL;
+
+			if (file) {
+				/* add size and addresses */
+				file = brasero_volume_file_merge (file, entry);
+				BRASERO_BURN_LOG ("Multi extent file");
+			}
+			else
+				file = entry;
+
+			continue;
+		}
+
+		if (len && !strncmp (record_name, path, len)) {
+			gint address;
+
+			/* move path forward */
+			path += len;
+			path ++;
+
+			address = brasero_iso9660_get_733_val (record->address);
+			file = brasero_iso9660_lookup_directory_record (ctx,
+									path,
+									address);
+			break;
+		}
+	}
+
+	return file;
+}
+
+BraseroVolFile *
+brasero_iso9660_get_file (FILE *file,
+			  const gchar *path,
+			  const gchar *block,
+			  GError **error)
+{
+	BraseroIsoPrimary *primary;
+	BraseroIsoDirRec *root;
+	BraseroVolFile *entry;
+	BraseroIsoCtx ctx;
+	gint address;
+
+	primary = (BraseroIsoPrimary *) block;
+	root = primary->root_rec;
+	address = brasero_iso9660_get_733_val (root->address);
+
+	brasero_iso9660_ctx_init (&ctx, file);
+
+	/* now that we have root block address, skip first "/" and go. */
+	path ++;
+	entry = brasero_iso9660_lookup_directory_record (&ctx, path, address);
+
+	/* clean context */
+	if (ctx.spare_record)
+		g_free (ctx.spare_record);
+
+	if (error && ctx.error)
+		g_propagate_error (error, ctx.error);
+
+	return entry;
+}

Modified: trunk/src/burn-iso9660.h
==============================================================================
--- trunk/src/burn-iso9660.h	(original)
+++ trunk/src/burn-iso9660.h	Sun Apr 13 14:03:53 2008
@@ -59,6 +59,12 @@
 			      gint64 *nb_blocks,
 			      GError **error);
 
+BraseroVolFile *
+brasero_iso9660_get_file (FILE *file,
+			  const gchar *path,
+			  const gchar *block,
+			  GError **error);
+
 G_END_DECLS
 
 #endif /* _BURN_ISO9660_H */

Modified: trunk/src/burn-volume-obj.c
==============================================================================
--- trunk/src/burn-volume-obj.c	(original)
+++ trunk/src/burn-volume-obj.c	Sun Apr 13 14:03:53 2008
@@ -432,7 +432,12 @@
 			       priv->cancel,
 			       brasero_volume_eject_finish,
 			       self);
+
+		g_object_ref (self);
 		result = brasero_volume_wait_for_operation_end (self, error);
+		g_object_unref (self);
+
+		/* NOTE: from this point on self is no longer valid */
 
 		g_signal_handler_disconnect (drive, eject_sig);
 	}
@@ -464,6 +469,29 @@
 }
 
 gchar *
+brasero_volume_get_name (BraseroVolume *self)
+{
+	BraseroVolumePrivate *priv;
+	BraseroMedia media;
+	GVolume *volume;
+	gchar *name;
+
+	priv = BRASERO_VOLUME_PRIVATE (self);
+
+	media = brasero_medium_get_status (BRASERO_MEDIUM (self));
+	if (media & BRASERO_MEDIUM_FILE) {
+		/* FIXME: here let's read the image label ?*/
+		return NULL;
+	}
+
+	volume = brasero_volume_get_gvolume (self);
+	name = g_volume_get_name (volume);
+	g_object_unref (volume);
+
+	return name;
+}
+
+gchar *
 brasero_volume_get_display_label (BraseroVolume *self,
 				  gboolean with_markup)
 {

Modified: trunk/src/burn-volume-obj.h
==============================================================================
--- trunk/src/burn-volume-obj.h	(original)
+++ trunk/src/burn-volume-obj.h	Sun Apr 13 14:03:53 2008
@@ -58,6 +58,9 @@
 		    const gchar *udi);
 
 gchar *
+brasero_volume_get_name (BraseroVolume *self);
+
+gchar *
 brasero_volume_get_display_label (BraseroVolume *volume,
 				  gboolean with_markup);
 

Modified: trunk/src/burn-volume.c
==============================================================================
--- trunk/src/burn-volume.c	(original)
+++ trunk/src/burn-volume.c	Sun Apr 13 14:03:53 2008
@@ -77,6 +77,12 @@
 
 		g_list_free (file->specific.dir.children);
 	}
+	else {
+		g_slist_foreach (file->specific.file.extents,
+				 (GFunc) g_free,
+				 NULL);
+		g_slist_free (file->specific.file.extents);
+	}
 
 	g_free (file->rr_name);
 	g_free (file->name);
@@ -360,6 +366,51 @@
 	return volroot;
 }
 
+BraseroVolFile *
+brasero_volume_get_file (const gchar *medium,
+			 const gchar *path,
+			 gint64 volume_start_block,
+			 GError **error)
+{
+	gchar buffer [ISO9660_BLOCK_SIZE];
+	BraseroVolFile *volfile;
+	FILE *file;
+
+	file = fopen (medium, "r");
+	if (!file) {
+		BRASERO_BURN_LOG ("fopen () failed (%s)", strerror (errno));
+		g_set_error (error,
+			     BRASERO_BURN_ERROR,
+			     BRASERO_BURN_ERROR_GENERAL,
+			     strerror (errno));
+		return NULL;
+	}
+
+	if (fseek (file, volume_start_block * ISO9660_BLOCK_SIZE, SEEK_SET) == -1) {
+		BRASERO_BURN_LOG ("fseek () failed at block %lli (%s)", volume_start_block, strerror (errno));
+		g_set_error (error,
+			     BRASERO_BURN_ERROR,
+			     BRASERO_BURN_ERROR_GENERAL,
+			     strerror (errno));
+		return NULL;
+	}
+
+	if (!brasero_volume_get_primary_from_file (file, buffer, error)) {
+		fclose (file);
+		return NULL;
+	}
+
+	if (!brasero_iso9660_is_primary_descriptor (buffer, error)) {
+		fclose (file);
+		return NULL;
+	}
+
+	volfile = brasero_iso9660_get_file (file, path, buffer, error);
+	fclose (file);
+
+	return volfile;
+}
+
 gchar *
 brasero_volume_file_to_path (BraseroVolFile *file)
 {
@@ -438,8 +489,17 @@
 	GList *iter;
 	gint64 size = 0;
 
-	if (!file->isdir)
-		return BRASERO_SIZE_TO_SECTORS (file->specific.file.size_bytes, 2048);
+	if (!file->isdir) {
+		GSList *extents;
+
+		for (extents = file->specific.file.extents; extents; extents = extents->next) {
+			BraseroVolFileExtent *extent;
+
+			extent = extents->data;
+			size += extent->size;
+		}
+		return BRASERO_SIZE_TO_SECTORS (size, 2048);
+	}
 
 	for (iter = file->specific.dir.children; iter; iter = iter->next) {
 		file = iter->data;
@@ -452,3 +512,18 @@
 
 	return size;
 }
+
+BraseroVolFile *
+brasero_volume_file_merge (BraseroVolFile *file1,
+			   BraseroVolFile *file2)
+{
+	file1->specific.file.size_bytes += file2->specific.file.size_bytes;
+	file1->specific.file.extents = g_slist_concat (file1->specific.file.extents,
+							     file2->specific.file.extents);
+
+	file2->specific.file.extents = NULL;
+	brasero_volume_file_free (file2);
+
+	return file1;
+}
+

Modified: trunk/src/burn-volume.h
==============================================================================
--- trunk/src/burn-volume.h	(original)
+++ trunk/src/burn-volume.h	Sun Apr 13 14:03:53 2008
@@ -36,6 +36,12 @@
 };
 typedef struct _BraseroVolDesc BraseroVolDesc;
 
+struct _BraseroVolFileExtent {
+	guint block;
+	guint size;
+};
+typedef struct _BraseroVolFileExtent BraseroVolFileExtent;
+
 typedef struct _BraseroVolFile BraseroVolFile;
 struct _BraseroVolFile {
 	BraseroVolFile *parent;
@@ -46,7 +52,7 @@
 	union {
 
 	struct {
-		gint address_block;
+		GSList *extents;
 		guint64 size_bytes;
 	} file;
 
@@ -54,7 +60,7 @@
 		GList *children;
 
 		/* FIXME: rr_children isn't needed here apparently it could be 
-		 * replaced by address_block. */
+		 * replaced by extents. */
 		GList *rr_children;
 	} dir;
 
@@ -63,12 +69,6 @@
 	guint isdir:1;
 };
 
-#define BRASERO_VOLUME_FILE_NAME(file)			((file)->rr_name?(file)->rr_name:(file)->name)
-#define BRASERO_VOLUME_FILE_SIZE(file)			((file)->isdir?0:(file)->specific.file.size_bytes)
-
-void
-brasero_volume_file_free (BraseroVolFile *file);
-
 gboolean
 brasero_volume_is_valid (const gchar *path,
 			 GError **error);
@@ -93,6 +93,7 @@
 brasero_volume_get_label (const gchar *path,
 			  gchar **label,
 			  GError **error);
+
 BraseroVolFile *
 brasero_volume_get_files (const gchar *path,
 			  gint64 block,
@@ -101,6 +102,19 @@
 			  gint64 *data_blocks,
 			  GError **error);
 
+BraseroVolFile *
+brasero_volume_get_file (const gchar *medium,
+			 const gchar *path,
+			 gint64 volume_start_block,
+			 GError **error);
+
+
+#define BRASERO_VOLUME_FILE_NAME(file)			((file)->rr_name?(file)->rr_name:(file)->name)
+#define BRASERO_VOLUME_FILE_SIZE(file)			((file)->isdir?0:(file)->specific.file.size_bytes)
+
+void
+brasero_volume_file_free (BraseroVolFile *file);
+
 gchar *
 brasero_volume_file_to_path (BraseroVolFile *file);
 
@@ -111,6 +125,10 @@
 gint64
 brasero_volume_file_size (BraseroVolFile *file);
 
+BraseroVolFile *
+brasero_volume_file_merge (BraseroVolFile *file1,
+			   BraseroVolFile *file2);
+
 G_END_DECLS
 
 #endif /* BURN_VOLUME_H */

Modified: trunk/src/plugins/checksum/burn-checksum-files.c
==============================================================================
--- trunk/src/plugins/checksum/burn-checksum-files.c	(original)
+++ trunk/src/plugins/checksum/burn-checksum-files.c	Sun Apr 13 14:03:53 2008
@@ -47,6 +47,7 @@
 #include "burn-volume.h"
 #include "burn-drive.h"
 #include "burn-volume-obj.h"
+#include "burn-volume-read.h"
 
 BRASERO_PLUGIN_BOILERPLATE (BraseroChecksumFiles, brasero_checksum_files, BRASERO_TYPE_JOB, BraseroJob);
 
@@ -279,8 +280,182 @@
 }
 
 static BraseroBurnResult
+brasero_checksum_file_process_former_line (BraseroChecksumFiles *self,
+					   BraseroTrack *track,
+					   const gchar *line,
+					   GError **error)
+{
+	guint i;
+	gchar *path;
+	GSList *grafts;
+	gchar *checksum;
+	guint written_bytes;
+	BraseroChecksumFilesPrivate *priv;
+
+	priv = BRASERO_CHECKSUM_FILES_PRIVATE (self);
+
+	/* first read the checksum string */
+	i = 0;
+	while (!isspace (line [i])) i ++;
+
+	checksum = g_strndup (line, i);
+
+	/* skip white spaces */
+	while (isspace (line [i])) i ++;
+
+	/* get the path string */
+	path = g_strdup (line + i);
+
+	for (grafts = brasero_track_get_data_grafts_source (track); grafts; grafts = grafts->next) {
+		BraseroGraftPt *graft;
+		guint len;
+
+		/* NOTE: graft->path + 1 is because in the checksum files on the 
+		 * disc there is not first "/" so if we want to compare ... */
+		graft = grafts->data;
+		if (!strcmp (graft->path + 1, path))
+			return BRASERO_BURN_OK;
+
+		len = strlen (graft->path + 1);
+		if (!strncmp (graft->path + 1, path, len)
+		&&   path [len] == G_DIR_SEPARATOR)
+			return BRASERO_BURN_OK;
+	}
+
+	/* write the whole line in the new file */
+	written_bytes = fwrite (line, 1, strlen (line), priv->file);
+	if (written_bytes != strlen (line)) {
+		g_set_error (error,
+			     BRASERO_BURN_ERROR,
+			     BRASERO_BURN_ERROR_GENERAL,
+			     strerror (errno));
+		return BRASERO_BURN_ERR;
+	}
+
+	if (!fwrite ("\n", 1, 1, priv->file)) {
+		g_set_error (error,
+			     BRASERO_BURN_ERROR,
+			     BRASERO_BURN_ERROR_GENERAL,
+			     strerror (errno));
+		return BRASERO_BURN_ERR;
+	}
+
+	return BRASERO_BURN_OK;
+}
+
+static BraseroBurnResult
+brasero_checksum_files_merge_with_former_session (BraseroChecksumFiles *self,
+						  GError **error)
+{
+	BraseroBurnFlag flags = BRASERO_BURN_FLAG_NONE;
+	BraseroChecksumFilesPrivate *priv;
+	BraseroVolFileHandle *handle;
+	BraseroBurnResult result;
+	BraseroVolFile *file;
+	BraseroTrack *track;
+	gchar buffer [2048];
+	gint64 start_block;
+	gchar *device;
+
+	priv = BRASERO_CHECKSUM_FILES_PRIVATE (self);
+
+	/* Now we need to know if we're merging. If so, we need to merge the
+	 * former checksum file with the new ones. */
+	brasero_job_get_flags (BRASERO_JOB (self), &flags);
+	if (!(flags & BRASERO_BURN_FLAG_MERGE))
+		return BRASERO_BURN_OK;
+
+	/* get the former file */
+	result = brasero_job_get_last_session_address (BRASERO_JOB (self), &start_block);
+	if (result != BRASERO_BURN_OK)
+		return result;
+
+	brasero_job_get_device (BRASERO_JOB (self), &device);
+
+	/* try every file and make sure they are of the same type */
+	/* FIXME: if not we could make a new checksum ... */
+	file = brasero_volume_get_file (device,
+					"/"BRASERO_MD5_FILE,
+					start_block,
+					NULL);
+	if (!file) {
+		file = brasero_volume_get_file (device,
+						"/"BRASERO_SHA1_FILE,
+						start_block,
+						NULL);
+		if (!file) {
+			file = brasero_volume_get_file (device,
+							"/"BRASERO_SHA256_FILE,
+							start_block,
+							NULL);
+			if (!file) {
+				g_free (device);
+				BRASERO_JOB_LOG (self, "no checksum file found");
+				return BRASERO_BURN_OK;
+			}
+			else if (priv->checksum_type != BRASERO_CHECKSUM_SHA256_FILE) {
+				g_free (device);
+				BRASERO_JOB_LOG (self, "checksum type mismatch (%i against %i)",
+						 priv->checksum_type,
+						 BRASERO_CHECKSUM_SHA256_FILE);
+				return BRASERO_BURN_OK;
+			}
+		}
+		else if (priv->checksum_type != BRASERO_CHECKSUM_SHA1_FILE) {
+			BRASERO_JOB_LOG (self, "checksum type mismatch (%i against %i)",
+					 priv->checksum_type,
+					 BRASERO_CHECKSUM_SHA1_FILE);
+			g_free (device);
+			return BRASERO_BURN_OK;
+		}
+	}
+	else if (priv->checksum_type != BRASERO_CHECKSUM_MD5_FILE) {
+		g_free (device);
+		BRASERO_JOB_LOG (self, "checksum type mismatch (%i against %i)",
+				 priv->checksum_type,
+				 BRASERO_CHECKSUM_MD5_FILE);
+		return BRASERO_BURN_OK;
+	}
+
+	BRASERO_JOB_LOG (self, "Found file %s on %s", file, device);
+	handle = brasero_volume_file_open (device, file);
+	g_free (device);
+
+	if (!handle) {
+		BRASERO_JOB_LOG (self, "Failed to open file");
+		return BRASERO_BURN_ERR;
+	}
+
+	brasero_job_get_current_track (BRASERO_JOB (self), &track);
+
+	/* Now check the files that have been replaced; to do that check the 
+	 * paths of the new image whenever a read path from former file is a
+	 * child of one of the new paths, then it must not be included. */
+	result = brasero_volume_file_read_line (handle, buffer, sizeof (buffer));
+	while (result == BRASERO_BURN_RETRY) {
+		if (priv->cancel) {
+			brasero_volume_file_close (handle);
+			return BRASERO_BURN_CANCEL;
+		}
+
+		result = brasero_checksum_file_process_former_line (self, track, buffer, error);
+		if (result != BRASERO_BURN_OK) {
+			brasero_volume_file_close (handle);
+			return result;
+		}
+
+		result = brasero_volume_file_read_line (handle, buffer, sizeof (buffer));
+	}
+
+	result = brasero_checksum_file_process_former_line (self, track, buffer, error);
+	brasero_volume_file_close (handle);
+
+	return result;
+}
+
+static BraseroBurnResult
 brasero_checksum_files_create_checksum (BraseroChecksumFiles *self,
-				     GError **error)
+					GError **error)
 {
 	GSList *iter;
 	gint64 file_nb;
@@ -432,6 +607,9 @@
 
 	g_hash_table_destroy (excludedH);
 
+	if (result == BRASERO_BURN_OK)
+		result = brasero_checksum_files_merge_with_former_session (self, error);
+
 	/* that's finished we close the file */
 	fclose (priv->file);
 	priv->file = NULL;

Modified: trunk/src/plugins/dvdcss/burn-dvdcss.c
==============================================================================
--- trunk/src/plugins/dvdcss/burn-dvdcss.c	(original)
+++ trunk/src/plugins/dvdcss/burn-dvdcss.c	Sun Apr 13 14:03:53 2008
@@ -247,20 +247,31 @@
 		if (!file->isdir) {
 			if (!strncmp (file->name + strlen (file->name) - 6, ".VOB", 4)) {
 				BraseroScrambledSectorRange *range;
+				GSList *extents;
 
 				range = g_new0 (BraseroScrambledSectorRange, 1);
-				range->start = file->specific.file.address_block;
-				range->end = range->start + (file->specific.file.size_bytes / DVDCSS_BLOCK_SIZE);
 
-				g_queue_push_head (map, range);
-
-				if (dvdcss_seek (handle, range->start, DVDCSS_SEEK_KEY) != range->start) {
-					g_set_error (error,
-						     BRASERO_BURN_ERROR,
-						     BRASERO_BURN_ERROR_GENERAL,
-						     _("Error reading video DVD (%s)"),
-						     dvdcss_error (handle));
+				/* take the first address for each extent of the file */
+				if (!file->specific.file.extents)
 					return FALSE;
+
+				for (extents = file->specific.file.extents; extents; extents = extents->next) {
+					BraseroVolFileExtent *extent;
+
+					extent = extents->data;
+					range->start = extent->block;
+					range->end = extent->block + BRASERO_SIZE_TO_SECTORS (extent->size, DVDCSS_BLOCK_SIZE);
+
+					g_queue_push_head (map, range);
+
+					if (dvdcss_seek (handle, range->start, DVDCSS_SEEK_KEY) != range->start) {
+						g_set_error (error,
+							     BRASERO_BURN_ERROR,
+							     BRASERO_BURN_ERROR_GENERAL,
+							     _("Error reading video DVD (%s)"),
+							     dvdcss_error (handle));
+						return FALSE;
+					}
 				}
 			}
 		}



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]