brasero r1821 - in trunk: . libbrasero-media src src/plugins/checksum



Author: philippr
Date: Sat Jan 24 06:31:48 2009
New Revision: 1821
URL: http://svn.gnome.org/viewvc/brasero?rev=1821&view=rev

Log:
2009-01-24  Philippe Rouquier  <ykw localhost localdomain>

	- Some minor leak fixes
	- Stop trying to mount media to check on disc file integrity. Rather read
	straight from the disc the files and check them without mounting as we
	do for images or when we merge checksum files in a multisession context.
	Otherwise,  in some cases, we'd try to unmount the media (which is not
	possible when it's blank and mounted by burn:// URI) then reload the
	media into the drive so as HAL realizes the changes that took place
	after burning. 

	It fixes long standing bugs
	#561006 â Unable to Mount Error
	#562740 â brasero errors on inability to mount disk after burning on a laptop
	which is also mentioned in:
	#564693 â Too Slow DVD Burning

	* libbrasero-media/scsi-read10.c (brasero_sbc_read10_block):
	* src/brasero-project-type-chooser.c
	(brasero_project_type_chooser_build_recent):
	* src/brasero-sum-dialog.c (brasero_sum_dialog_corruption_warning),
	(brasero_sum_dialog_check_disc_sum):
	* src/burn-process.c (brasero_process_check_path),
	(brasero_process_stop):
	* src/burn-session.c (brasero_burn_session_add_flag):
	* src/burn-track.c (brasero_track_set_checksum):
	* src/burn-track.h:
	* src/burn.c (brasero_burn_unlock_dest_media),
	(brasero_burn_check_real), (brasero_burn_check):
	* src/plugins/checksum/burn-checksum-files.c
	(brasero_checksum_files_merge_with_former_session),
	(brasero_checksum_files_sum_on_disc_file),
	(brasero_checksum_files_get_on_disc_checksum_type),
	(brasero_checksum_files_get_line_num),
	(brasero_checksum_files_check_files),
	(brasero_checksum_files_thread),
	(brasero_checksum_files_export_caps):
	* src/plugins/checksum/burn-volume-read.c
	(brasero_volume_file_open_direct),
	(brasero_volume_file_read_direct):
	* src/plugins/checksum/burn-volume-read.h:

Modified:
   trunk/ChangeLog
   trunk/libbrasero-media/scsi-read10.c
   trunk/src/brasero-project-type-chooser.c
   trunk/src/brasero-sum-dialog.c
   trunk/src/burn-process.c
   trunk/src/burn-session.c
   trunk/src/burn-track.c
   trunk/src/burn-track.h
   trunk/src/burn.c
   trunk/src/plugins/checksum/burn-checksum-files.c
   trunk/src/plugins/checksum/burn-volume-read.c
   trunk/src/plugins/checksum/burn-volume-read.h

Modified: trunk/libbrasero-media/scsi-read10.c
==============================================================================
--- trunk/libbrasero-media/scsi-read10.c	(original)
+++ trunk/libbrasero-media/scsi-read10.c	Sat Jan 24 06:31:48 2009
@@ -108,8 +108,9 @@
 	/* reladr should be 0 */
 	/* DPO should be 0 */
 
-	/* This is to force reading media ==> no caching */
-	cdb->FUA = 1;
+	/* This is to force reading media ==> no caching (set to 1) */
+	/* On the other hand caching improves dramatically the performances. */
+	cdb->FUA = 0;
 
 	memset (buffer, 0, buffer_size);
 	res = brasero_scsi_command_issue_sync (cdb,

Modified: trunk/src/brasero-project-type-chooser.c
==============================================================================
--- trunk/src/brasero-project-type-chooser.c	(original)
+++ trunk/src/brasero-project-type-chooser.c	Sat Jan 24 06:31:48 2009
@@ -365,6 +365,7 @@
 
 		gtk_size_group_add_widget (group, link);
 	}
+	g_object_unref (image_group);
 	g_object_unref (group);
 
 	if (!g_list_length (list)) {

Modified: trunk/src/brasero-sum-dialog.c
==============================================================================
--- trunk/src/brasero-sum-dialog.c	(original)
+++ trunk/src/brasero-sum-dialog.c	Sat Jan 24 06:31:48 2009
@@ -175,13 +175,15 @@
 	GtkCellRenderer *renderer;
 	GtkTreeViewColumn *column;
 
-	string = g_strdup_printf ("<b><big>%s</big></b>", _("The following files appear to be corrupted:"));
+	string = g_strdup_printf ("<b><big>%s</big></b>",
+				  _("The following files appear to be corrupted:"));
+
 	message = gtk_message_dialog_new_with_markup (GTK_WINDOW (self),
 						      GTK_DIALOG_MODAL |
 						      GTK_DIALOG_DESTROY_WITH_PARENT,
 						      GTK_MESSAGE_ERROR,
 						      GTK_BUTTONS_NONE,
-						      "%s", string);
+						      string);
 	g_free (string);
 
 	gtk_window_set_resizable (GTK_WINDOW (message), TRUE);
@@ -512,84 +514,10 @@
 	return brasero_sum_dialog_success (self);
 }
 
-static BraseroChecksumType
-brasero_sum_dialog_set_track_checksum_type (BraseroSumDialog *self,
-					    BraseroDrive *drive,
-					    BraseroTrack *track,
-					    GError **error)
-{
-	BraseroMedium *medium;
-	gboolean retval;
-	gchar *filename;
-	gchar *root;
-
-	medium = brasero_drive_get_medium (drive);
-
-	retval = brasero_volume_mount (BRASERO_VOLUME (medium),
-				       GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (self))),
-				       TRUE,
-				       error);
-	if (!retval)
-		return BRASERO_CHECKSUM_NONE;
-
-	root = brasero_volume_get_mount_point (BRASERO_VOLUME (medium), error);
-	if (!root)
-		return BRASERO_CHECKSUM_NONE;
-
-	filename = g_build_path (G_DIR_SEPARATOR_S, root, BRASERO_MD5_FILE, NULL);
-
-	if (g_file_test (filename, G_FILE_TEST_EXISTS)) {
-		g_free (filename);
-		g_free (root);
-
-		brasero_track_set_checksum (track,
-					    BRASERO_CHECKSUM_MD5_FILE,
-					    BRASERO_MD5_FILE);
-
-		return BRASERO_CHECKSUM_MD5_FILE;
-	}
-	g_free (filename);
-
-	filename = g_build_path (G_DIR_SEPARATOR_S, root, BRASERO_SHA1_FILE, NULL);
-	if (g_file_test (filename, G_FILE_TEST_EXISTS)) {
-		g_free (filename);
-		g_free (root);
-
-		brasero_track_set_checksum (track,
-					    BRASERO_CHECKSUM_SHA1_FILE,
-					    BRASERO_SHA1_FILE);
-
-		return BRASERO_CHECKSUM_SHA1_FILE;
-	}
-	g_free (filename);
-
-	filename = g_build_path (G_DIR_SEPARATOR_S, root, BRASERO_SHA256_FILE, NULL);
-	if (g_file_test (filename, G_FILE_TEST_EXISTS)) {
-		g_free (filename);
-		g_free (root);
-
-		brasero_track_set_checksum (track,
-					    BRASERO_CHECKSUM_SHA256_FILE,
-					    BRASERO_SHA256_FILE);
-
-		return BRASERO_CHECKSUM_SHA256_FILE;
-	}
-	g_free (filename);
-	g_free (root);
-
-	g_set_error (error,
-		     BRASERO_ERROR,
-		     BRASERO_ERROR_GENERAL,
-		     _("No checksum file could be found on the disc"));
-
-	return BRASERO_CHECKSUM_NONE;
-}
-
 static gboolean
 brasero_sum_dialog_check_disc_sum (BraseroSumDialog *self,
 				   BraseroDrive *drive)
 {
-	BraseroChecksumType checksum_type;
 	BraseroBurnResult result;
 	GError *error = NULL;
 	GValue *value = NULL;
@@ -597,28 +525,14 @@
 	BraseroBurn *burn;
 	gboolean retval;
 
-	/* get the checksum */
+	/* make track */
 	track = brasero_track_new (BRASERO_TRACK_TYPE_DISC);
 	brasero_track_set_drive_source (track, drive);
+	brasero_track_set_checksum (track, BRASERO_CHECKSUM_DETECT, NULL);
+	brasero_burn_session_add_track (self->priv->session, track);
 
-	checksum_type = brasero_sum_dialog_set_track_checksum_type (self,
-								    drive,
-								    track,
-								    &error);
-
-	if (checksum_type == BRASERO_CHECKSUM_NONE) {
-		retval = brasero_sum_dialog_message_error (self, error);
-		brasero_track_unref (track);
-
-		if (error)
-			g_error_free (error);
-
-		return retval;
-	}
-
-	/* no eject at the end (it's default) */
+	/* no eject at the end (it should be default) */
 	brasero_burn_session_remove_flag (self->priv->session, BRASERO_BURN_FLAG_EJECT);
-	brasero_burn_session_add_track (self->priv->session, track);
 
 	/* It's good practice to unref the track afterwards as we don't need it
 	 * anymore. BraseroBurnSession refs it. */

Modified: trunk/src/burn-process.c
==============================================================================
--- trunk/src/burn-process.c	(original)
+++ trunk/src/burn-process.c	Sat Jan 24 06:31:48 2009
@@ -118,6 +118,7 @@
 	 * the end it didn't work. So forbid all symlink. */
 	if (g_file_test (prog_path, G_FILE_TEST_IS_SYMLINK)) {
 		*error = g_strdup_printf (_("\"%s\" is a symlink pointing to another program. Use the target program instead"), name);
+		g_free (prog_path);
 		return BRASERO_BURN_ERR;
 	}
 	/* Make sure it's a regular file */
@@ -665,7 +666,7 @@
 
 		/* Reminder: -1 is here to send the signal to all children of
 		 * the process with pid as well */
-		if (kill ((-1) * pid, SIGTERM) == -1 && errno != ESRCH) {
+		if (pid > 0 && kill ((-1) * pid, SIGTERM) == -1 && errno != ESRCH) {
 			BRASERO_JOB_LOG (process, 
 					 "process (%s) couldn't be killed: terminating",
 					 g_strerror (errno));

Modified: trunk/src/burn-session.c
==============================================================================
--- trunk/src/burn-session.c	(original)
+++ trunk/src/burn-session.c	Sat Jan 24 06:31:48 2009
@@ -913,6 +913,8 @@
 
 	g_return_if_fail (BRASERO_IS_BURN_SESSION (self));
 
+	if (flag & BRASERO_BURN_FLAG_BURNPROOF)
+		g_warning ("REACHEd\n");
 	priv = BRASERO_BURN_SESSION_PRIVATE (self);
 	priv->settings->flags |= flag;
 }

Modified: trunk/src/burn-track.c
==============================================================================
--- trunk/src/burn-track.c	(original)
+++ trunk/src/burn-track.c	Sat Jan 24 06:31:48 2009
@@ -923,10 +923,8 @@
 	BraseroBurnResult result = BRASERO_BURN_OK;
 
 	if (type == track->checksum_type
-	&& (type == BRASERO_CHECKSUM_MD5
-	||  type == BRASERO_CHECKSUM_SHA1
-	||  type == BRASERO_CHECKSUM_SHA256)
-	&&  strcmp (checksum, track->checksum))
+	&& (type == BRASERO_CHECKSUM_MD5 || type == BRASERO_CHECKSUM_SHA1 || type == BRASERO_CHECKSUM_SHA256)
+	&&  checksum && strcmp (checksum, track->checksum))
 		result = BRASERO_BURN_ERR;
 
 	if (track->checksum)

Modified: trunk/src/burn-track.h
==============================================================================
--- trunk/src/burn-track.h	(original)
+++ trunk/src/burn-track.h	Sat Jan 24 06:31:48 2009
@@ -81,12 +81,13 @@
 
 typedef enum {
 	BRASERO_CHECKSUM_NONE			= 0,
-	BRASERO_CHECKSUM_MD5			= 1,
-	BRASERO_CHECKSUM_MD5_FILE		= 1 << 1,
-	BRASERO_CHECKSUM_SHA1			= 1 << 2,
-	BRASERO_CHECKSUM_SHA1_FILE		= 1 << 3,
-	BRASERO_CHECKSUM_SHA256			= 1 << 4,
-	BRASERO_CHECKSUM_SHA256_FILE		= 1 << 5
+	BRASERO_CHECKSUM_DETECT			= 1,		/* means the plugin handles detection of checksum type */
+	BRASERO_CHECKSUM_MD5			= 1 << 1,
+	BRASERO_CHECKSUM_MD5_FILE		= 1 << 2,
+	BRASERO_CHECKSUM_SHA1			= 1 << 3,
+	BRASERO_CHECKSUM_SHA1_FILE		= 1 << 4,
+	BRASERO_CHECKSUM_SHA256			= 1 << 5,
+	BRASERO_CHECKSUM_SHA256_FILE		= 1 << 6,
 } BraseroChecksumType;
 
 #define	BRASERO_MIN_AUDIO_TRACK_LENGTH		((gint64) 6 * 1000000000)

Modified: trunk/src/burn.c
==============================================================================
--- trunk/src/burn.c	(original)
+++ trunk/src/burn.c	Sat Jan 24 06:31:48 2009
@@ -981,47 +981,6 @@
 }
 
 static BraseroBurnResult
-brasero_burn_mount_media (BraseroBurn *self,
-			  GError **error)
-{
-	guint retries = 0;
-	BraseroMedium *medium;
-	BraseroBurnPrivate *priv;
-
-	priv = BRASERO_BURN_PRIVATE (self);
-
-	/* get the mount point */
-	g_signal_emit (self,
-		       brasero_burn_signals [ACTION_CHANGED_SIGNAL],
-		       0,
-		       BRASERO_BURN_ACTION_CHECKSUM);
-
-	medium = brasero_drive_get_medium (priv->dest);
-	while (!brasero_volume_is_mounted (BRASERO_VOLUME (medium))) {
-		if (retries++ > MAX_MOUNT_ATTEMPTS) {
-			/* FIXME: there is a spelling mistake */
-			g_set_error (error,
-				     BRASERO_BURN_ERROR,
-				     BRASERO_BURN_ERROR_GENERAL,
-				     _("The disc could not be mounted (max attemps reached)"));
-			return BRASERO_BURN_ERR;
-		}
-
-		BRASERO_BURN_LOG ("Trying to mount medium");
-
-		/* NOTE: we don't really care about the return value */
-		/* NOTE: brasero_app_get_default () wouldn't work here as we 
-		 * want to have it split soon */
-		brasero_volume_mount (BRASERO_VOLUME (medium), NULL, FALSE, NULL);
-		priv->mounted_by_us = TRUE;
-
-		brasero_burn_sleep (self, MOUNT_TIMEOUT);
-	}
-
-	return BRASERO_BURN_OK;
-}
-
-static BraseroBurnResult
 brasero_burn_lock_checksum_media (BraseroBurn *burn,
 				  GError **error)
 {
@@ -1148,7 +1107,6 @@
 			gdrive = brasero_drive_get_gdrive (priv->dest);
 
 			/* reprobe the contents of the drive system wide */
-			BRASERO_BURN_LOG ("Reprobring drive %s", brasero_drive_get_display_name (priv->dest));
 			g_drive_poll_for_media (gdrive, NULL, NULL, NULL);
 			g_object_unref (gdrive);
 
@@ -1870,17 +1828,9 @@
 	checksum_type = brasero_track_get_checksum_type (track);
 	brasero_track_get_type (track, &type);
 
-	/* if the input is a DISC, ask/mount/unmount and lock it (as dest) */
+	/* if the input is a DISC and there isn't any checksum specified that 
+	 * means the checksum file is on the disc. */
 	medium = brasero_drive_get_medium (priv->dest);
-	if (type.type == BRASERO_TRACK_TYPE_DISC
-	&& (checksum_type == BRASERO_CHECKSUM_MD5_FILE
-	||  checksum_type == BRASERO_CHECKSUM_SHA1_FILE
-	||  checksum_type == BRASERO_CHECKSUM_SHA256_FILE)
-	&& !brasero_volume_is_mounted (BRASERO_VOLUME (medium))) {
-		result = brasero_burn_mount_media (self, error);
-		if (result != BRASERO_BURN_OK)
-			return result;
-	}
 
 	/* get the task and run it */
 	priv->task = brasero_burn_caps_new_checksuming_task (priv->caps,
@@ -1901,20 +1851,19 @@
 
 		/* make sure one last time it is not mounted IF and only IF the
 		 * checksum type is NOT FILE_MD5 */
-		if (priv->dest
-		&& (checksum_type == BRASERO_CHECKSUM_MD5
-		||  checksum_type == BRASERO_CHECKSUM_SHA1
-		||  checksum_type == BRASERO_CHECKSUM_SHA256)
-		&&  brasero_volume_is_mounted (BRASERO_VOLUME (medium))
-		&& !brasero_volume_umount (BRASERO_VOLUME (medium), TRUE, NULL)) {
-			g_set_error (error,
-				     BRASERO_BURN_ERROR,
-				     BRASERO_BURN_ERROR_DRIVE_BUSY,
-				     "%s. %s",
-				     _("The drive is busy"),
-				     _("Make sure another application is not using it"));
-			return BRASERO_BURN_ERR;
-		}
+		/* it seems to work without unmounting ... */
+		/* if (medium
+		 * &&  brasero_volume_is_mounted (BRASERO_VOLUME (medium))
+		 * && !brasero_volume_umount (BRASERO_VOLUME (medium), TRUE, NULL)) {
+		 *	g_set_error (error,
+		 *		     BRASERO_BURN_ERROR,
+		 *		     BRASERO_BURN_ERROR_DRIVE_BUSY,
+		 *		     "%s. %s",
+		 *		     _("The drive is busy"),
+		 *		     _("Make sure another application is not using it"));
+		 *	return BRASERO_BURN_ERR;
+		 * }
+		 */
 
 		result = brasero_task_run (priv->task, error);
 		g_signal_emit (self,
@@ -1932,7 +1881,7 @@
 		priv->task = NULL;
 	}
 	else {
-		BRASERO_BURN_LOG ("the track cannot be checked");
+		BRASERO_BURN_LOG ("The track cannot be checked");
 		result = BRASERO_BURN_NOT_SUPPORTED;
 	}
 
@@ -2317,7 +2266,7 @@
 	track = tracks->data;
 	brasero_track_get_type (track, &type);
 
-	/* if the input is a DISC, ask/mount/unmount and lock it (as dest) */
+	/* if the input is a DISC, ask/check there is one and lock it (as dest) */
 	if (type.type == BRASERO_TRACK_TYPE_DISC) {
 		/* make sure there is a disc. If not, ask one and lock it */
 		result = brasero_burn_lock_checksum_media (self, error);

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	Sat Jan 24 06:31:48 2009
@@ -446,7 +446,7 @@
 		return BRASERO_BURN_OK;
 	}
 
-	BRASERO_JOB_LOG (self, "Found file %s", file);
+	BRASERO_JOB_LOG (self, "Found file %p", file);
 	handle = brasero_volume_file_open (vol, file);
 	brasero_volume_source_close (vol);
 
@@ -668,98 +668,196 @@
 	return result;
 }
 
+static BraseroBurnResult
+brasero_checksum_files_sum_on_disc_file (BraseroChecksumFiles *self,
+					 GChecksumType type,
+					 BraseroVolSrc *src,
+					 BraseroVolFile *file,
+					 gchar **checksum_string,
+					 GError **error)
+{
+	guchar buffer [64 * 2048];
+	BraseroChecksumFilesPrivate *priv;
+	BraseroVolFileHandle *handle;
+	GChecksum *checksum;
+	gint read_bytes;
+
+	priv = BRASERO_CHECKSUM_FILES_PRIVATE (self);
+
+	handle = brasero_volume_file_open_direct (src, file);
+	if (!handle)
+		return BRASERO_BURN_ERR;
+
+	checksum = g_checksum_new (type);
+
+	read_bytes = brasero_volume_file_read_direct (handle,
+						      buffer,
+						      64);
+	g_checksum_update (checksum, buffer, read_bytes);
+
+	while (read_bytes == sizeof (buffer)) {
+		if (priv->cancel) {
+			brasero_volume_file_close (handle);
+			return BRASERO_BURN_CANCEL;
+		}
+
+		read_bytes = brasero_volume_file_read_direct (handle,
+							      buffer,
+							      64);
+		g_checksum_update (checksum, buffer, read_bytes);
+	}
+
+	*checksum_string = g_strdup (g_checksum_get_string (checksum));
+	g_checksum_free (checksum);
+
+	brasero_volume_file_close (handle);
+
+	return BRASERO_BURN_OK;
+}
+
+static BraseroVolFile *
+brasero_checksum_files_get_on_disc_checksum_type (BraseroChecksumFiles *self,
+						  BraseroVolSrc *vol,
+						  guint start_block)
+{
+	BraseroVolFile *file;
+	BraseroChecksumFilesPrivate *priv;
+
+	priv = BRASERO_CHECKSUM_FILES_PRIVATE (self);
+
+
+	file = brasero_volume_get_file (vol,
+					"/"BRASERO_MD5_FILE,
+					start_block,
+					NULL);
+
+	if (!file) {
+		file = brasero_volume_get_file (vol,
+						"/"BRASERO_SHA1_FILE,
+						start_block,
+						NULL);
+		if (!file) {
+			file = brasero_volume_get_file (vol,
+							"/"BRASERO_SHA256_FILE,
+							start_block,
+							NULL);
+			if (!file || !(priv->checksum_type & (BRASERO_CHECKSUM_SHA256_FILE|BRASERO_CHECKSUM_DETECT))) {
+				BRASERO_JOB_LOG (self, "no checksum file found");
+				if (file)
+					brasero_volume_file_free (file);
+
+				return NULL;
+			}
+			priv->checksum_type = BRASERO_CHECKSUM_SHA256_FILE;
+		}
+		else if (priv->checksum_type & (BRASERO_CHECKSUM_SHA1_FILE|BRASERO_CHECKSUM_DETECT))
+			priv->checksum_type = BRASERO_CHECKSUM_SHA1_FILE;
+		else {
+			brasero_volume_file_free (file);
+			file = NULL;
+		}
+	}
+	else if (priv->checksum_type & (BRASERO_CHECKSUM_MD5_FILE|BRASERO_CHECKSUM_DETECT))
+		priv->checksum_type = BRASERO_CHECKSUM_MD5_FILE;
+	else {
+		brasero_volume_file_free (file);
+		file = NULL;
+	}
+
+	BRASERO_JOB_LOG (self, "Found file %p", file);
+	return file;
+}
+
 static gint
 brasero_checksum_files_get_line_num (BraseroChecksumFiles *self,
-				     FILE *file,
-				     GError **error)
+				     BraseroVolFileHandle *handle)
 {
-	gint c;
-	gint num = 0;
+	BraseroBurnResult result;
+	int num = 0;
 
-	while ((c = getc (file)) != EOF) {
-		if (c == '\n')
-			num ++;
-	}
+	while ((result = brasero_volume_file_read_line (handle, NULL, 0)) == BRASERO_BURN_RETRY)
+		num ++;
 
-	if (!feof (file)) {
-		g_set_error (error,
-			     BRASERO_BURN_ERROR,
-			     BRASERO_BURN_ERROR_GENERAL,
-			     "%s",
-			     g_strerror (errno));
+	if (result == BRASERO_BURN_ERR)
 		return -1;
-	}
 
-	rewind (file);
+	brasero_volume_file_rewind (handle);
 	return num;
 }
 
 static BraseroBurnResult
 brasero_checksum_files_check_files (BraseroChecksumFiles *self,
-				    BraseroChecksumType checksum_type,
 				    GError **error)
 {
-	gchar *root;
-	gchar *path;
-	gint root_len;
+	GValue *value;
 	guint file_nb;
 	guint file_num;
-	FILE *file = NULL;
-	const gchar *name;
 	gint checksum_len;
+	BraseroVolSrc *vol;
+	gint64 start_block;
 	BraseroTrack *track;
-	GValue *value = NULL;
+	const gchar *device;
+	BraseroVolFile *file;
 	BraseroMedium *medium;
+	BraseroVolFileHandle *handle;
 	GChecksumType gchecksum_type;
 	GArray *wrong_checksums = NULL;
-	gchar filename [MAXPATHLEN + 1];
+	BraseroDeviceHandle *dev_handle;
 	BraseroChecksumFilesPrivate *priv;
 	BraseroBurnResult result = BRASERO_BURN_OK;
 
 	priv = BRASERO_CHECKSUM_FILES_PRIVATE (self);
 
+	/* get medium */
 	brasero_job_get_current_track (BRASERO_JOB (self), &track);
 	medium = brasero_track_get_medium_source (track);
-	root = brasero_volume_get_mount_point (BRASERO_VOLUME (medium), FALSE);
-	if (!root)
+	/* open volume */
+	if (!brasero_medium_get_last_data_track_address (medium, NULL, &start_block))
 		return BRASERO_BURN_ERR;
 
-	root_len = strlen (root);
-	memcpy (filename, root, root_len);
-	filename [root_len ++ ] = '/';
-
-	name = brasero_track_get_checksum (track);
-	path = g_build_path (G_DIR_SEPARATOR_S, root, name, NULL);
-
-	file = fopen (path, "r");
-	g_free (root);
-	g_free (path);
+	device = brasero_drive_get_device (brasero_medium_get_drive (medium));
+	dev_handle = brasero_device_handle_open (device, FALSE, NULL);
+	vol = brasero_volume_source_open_device_handle (dev_handle, error);
+
+	/* open checksum file */
+	file = brasero_checksum_files_get_on_disc_checksum_type (self,
+								 vol,
+								 start_block);
 	if (!file) {
 		g_set_error (error,
 			     BRASERO_BURN_ERROR,
 			     BRASERO_BURN_ERROR_GENERAL,
-			     "%s",
-			     g_strerror (errno));
-		return BRASERO_BURN_ERR;
+			     _("No checksum file could be found on the disc"));
+
+		BRASERO_JOB_LOG (self, "No checksum file");
+		result = BRASERO_BURN_ERR;
+		goto end;
+	}
+
+	handle = brasero_volume_file_open (vol, file);
+	if (!handle) {
+		BRASERO_JOB_LOG (self, "Cannot open checksum file");
+		/* FIXME: error here ? */
+		result = BRASERO_BURN_ERR;
+		goto end;
 	}
 
-	/* we need to get the number of files at this time and rewind */
-	file_nb = brasero_checksum_files_get_line_num (self, file, error);
+	/* get the number of files at this time and rewind */
+	file_nb = brasero_checksum_files_get_line_num (self, handle);
 	if (file_nb == 0) {
-		fclose (file);
-		return BRASERO_BURN_OK;
+		BRASERO_JOB_LOG (self, "Empty checksum file");
+		result = BRASERO_BURN_OK;
+		goto end;
 	}
 
 	if (file_nb < 0) {
-		g_set_error (error,
-			     BRASERO_BURN_ERROR,
-			     BRASERO_BURN_ERROR_GENERAL,
-			     "%s",
-			     g_strerror (errno));
-		fclose (file);
-		return BRASERO_BURN_ERR;
+		/* An error here */
+		BRASERO_JOB_LOG (self, "Failed to retrieve the number of lines");
+		result = BRASERO_BURN_ERR;
+		goto end;
 	}
 
+	/* signal we're ready to start */
 	file_num = 0;
 	brasero_job_set_current_action (BRASERO_JOB (self),
 				        BRASERO_BURN_ACTION_CHECKSUM,
@@ -768,7 +866,7 @@
 	brasero_job_start_progress (BRASERO_JOB (self), FALSE);
 
 	/* Get the checksum type */
-	switch (checksum_type) {
+	switch (priv->checksum_type) {
 	case BRASERO_CHECKSUM_MD5_FILE:
 		gchecksum_type = G_CHECKSUM_MD5;
 		break;
@@ -785,22 +883,26 @@
 
 	checksum_len = g_checksum_type_get_length (gchecksum_type) * 2;
 	while (1) {
-		gchar checksum_file [512];
+		gchar file_path [MAXPATHLEN + 1];
+		gchar checksum_file [512 + 1];
+		BraseroVolFile *disc_file;
 		gchar *checksum_real;
-		gint i;
-		int c;
+		gint read_bytes;
 
 		if (priv->cancel)
 			break;
 
-		/* first read the checksum string */
-		if (fread (checksum_file, 1, checksum_len, file) != checksum_len) {
-			if (!feof (file))
-				g_set_error (error,
-					     BRASERO_BURN_ERROR,
-					     BRASERO_BURN_ERROR_GENERAL,
-					     "%s",
-					     g_strerror (errno));
+		/* first read the checksum */
+		read_bytes = brasero_volume_file_read (handle,
+						       checksum_file,
+						       checksum_len);
+		if (read_bytes == 0)
+			break;
+
+		if (read_bytes != checksum_len) {
+			/* FIXME: an error here */
+			BRASERO_JOB_LOG (self, "Impossible to read the checksum from file");
+			result = BRASERO_BURN_ERR;
 			break;
 		}
 		checksum_file [checksum_len] = '\0';
@@ -810,74 +912,78 @@
 
 		/* skip spaces in between */
 		while (1) {
-			c = fgetc (file);
+			gchar c [2];
 
-			if (c == EOF) {
-				if (feof (file))
-					goto end;
-
-				if (errno == EAGAIN || errno == EINTR)
-					continue;
-
-				g_set_error (error,
-					     BRASERO_BURN_ERROR,
-					     BRASERO_BURN_ERROR_GENERAL,
-					     "%s",
-					     g_strerror (errno));
+			read_bytes = brasero_volume_file_read (handle, c, 1);
+			if (read_bytes == 0) {
+				result = BRASERO_BURN_OK;
 				goto end;
 			}
 
-			if (!isspace (c)) {
-				filename [root_len] = c;
-				break;
-			}
-		}
-
-		/* get the filename */
-		i = root_len + 1;
-		while (1) {
-			c = fgetc (file);
-			if (c == EOF) {
-				if (feof (file))
-					goto end;
-
-				if (errno == EAGAIN || errno == EINTR)
-					continue;
-
-				g_set_error (error,
-					     BRASERO_BURN_ERROR,
-					     BRASERO_BURN_ERROR_GENERAL,
-					     "%s",
-					     g_strerror (errno));
+			if (read_bytes < 0) {
+				/* FIXME: an error here */
+				BRASERO_JOB_LOG (self, "Impossible to read checksum file");
+				result = BRASERO_BURN_ERR;
 				goto end;
 			}
 
-			if (c == '\n')
+			if (!isspace (c [0])) {
+				file_path [0] = '/';
+				file_path [1] = c [0];
 				break;
-
-			if (i < MAXPATHLEN)
-				filename [i ++] = c;
+			}
 		}
 
-		if (i > MAXPATHLEN) {
-			/* we ignore paths that are too long */
-			continue;
+		/* get the filename */
+		result = brasero_volume_file_read_line (handle, file_path + 2, sizeof (file_path) - 2);
+
+		/* FIXME: an error here */
+		if (result == BRASERO_BURN_ERR) {
+			BRASERO_JOB_LOG (self, "Impossible to read checksum file");
+			break;
 		}
 
-		filename [i] = 0;
 		checksum_real = NULL;
 
-		/* we certainly don't want to checksum anything but regular file */
-		if (!g_file_test (filename, G_FILE_TEST_IS_REGULAR))
-			continue;
+		/* get the file handle itself */
+		BRASERO_JOB_LOG (self, "Getting file %s", file_path);
+		disc_file = brasero_volume_get_file (vol,
+						     file_path,
+						     start_block,
+						     NULL);
+		if (!disc_file) {
+			g_set_error (error,
+				     BRASERO_BURN_ERROR,
+				     BRASERO_BURN_ERROR_GENERAL,
+				     _("File \"%s\" could not be opened"),
+				     file_path);
+			result = BRASERO_BURN_ERR;
+			break;
+		}
 
-		result = brasero_checksum_files_get_file_checksum (self,
-								   gchecksum_type,
-								   filename,
-								   &checksum_real,
-								   error);
-		if (result == BRASERO_BURN_RETRY)
-			continue;
+		/* we certainly don't want to checksum anything but regular file
+		 * if (!g_file_test (filename, G_FILE_TEST_IS_REGULAR)) {
+		 *	brasero_volume_file_free (disc_file);
+		 *	continue;
+		 * }
+		 */
+
+		/* checksum the file */
+		result = brasero_checksum_files_sum_on_disc_file (self,
+								  gchecksum_type,
+								  vol,
+								  disc_file,
+								  &checksum_real,
+								  error);
+		brasero_volume_file_free (disc_file);
+		if (result == BRASERO_BURN_ERR) {
+			g_set_error (error,
+				     BRASERO_BURN_ERROR,
+				     BRASERO_BURN_ERROR_GENERAL,
+				     _("File \"%s\" could not be opened"),
+				     file_path);
+			break;
+		}
 
 		if (result != BRASERO_BURN_OK)
 			break;
@@ -888,18 +994,19 @@
 					  (gdouble) file_nb);
 		BRASERO_JOB_LOG (self,
 				 "comparing checksums for file %s : %s (from md5 file) / %s (current)",
-				 filename, checksum_file, checksum_real);
+				 file_path, checksum_file, checksum_real);
 
 		if (strcmp (checksum_file, checksum_real)) {
 			gchar *string;
+
+			BRASERO_JOB_LOG (self, "Wrong checksum");
 			if (!wrong_checksums)
 				wrong_checksums = g_array_new (TRUE,
 							       TRUE, 
 							       sizeof (gchar *));
 
-			string = g_strdup (filename);
-			wrong_checksums = g_array_append_val (wrong_checksums,
-							      string);
+			string = g_strdup (file_path);
+			wrong_checksums = g_array_append_val (wrong_checksums, string);
 		}
 
 		g_free (checksum_real);
@@ -908,11 +1015,27 @@
 	}
 
 end:
+
+	if (handle)
+		brasero_volume_file_close (handle);
+
 	if (file)
-		fclose (file);
+		brasero_volume_file_free (file);
+
+	if (vol)
+		brasero_volume_source_close (vol);
 
-	if (result != BRASERO_BURN_OK)
+	if (dev_handle)
+		brasero_device_handle_close (dev_handle);
+
+	if (result != BRASERO_BURN_OK) {
+		BRASERO_JOB_LOG (self, "Ended with an error");
+		if (wrong_checksums) {
+			g_strfreev ((gchar **) wrong_checksums->data);
+			g_array_free (wrong_checksums, FALSE);
+		}
 		return result;
+	}
 
 	if (!wrong_checksums)
 		return BRASERO_BURN_OK;
@@ -1083,15 +1206,13 @@
 
 	/* check DISC types and add checksums for DATA and IMAGE-bin types */
 	brasero_job_get_action (BRASERO_JOB (self), &action);
-
 	if (action == BRASERO_JOB_ACTION_CHECKSUM) {
-		BraseroChecksumType type;
 		BraseroTrack *track;
 
 		brasero_job_get_current_track (BRASERO_JOB (self), &track);
-		type = brasero_track_get_checksum_type (track);
-		if (type & (BRASERO_CHECKSUM_MD5_FILE|BRASERO_CHECKSUM_SHA1_FILE|BRASERO_CHECKSUM_SHA256))
-			result = brasero_checksum_files_check_files (self, type, &error);
+		priv->checksum_type = brasero_track_get_checksum_type (track);
+		if (priv->checksum_type & (BRASERO_CHECKSUM_MD5_FILE|BRASERO_CHECKSUM_SHA1_FILE|BRASERO_CHECKSUM_SHA256_FILE|BRASERO_CHECKSUM_DETECT))
+			result = brasero_checksum_files_check_files (self, &error);
 		else
 			result = BRASERO_BURN_ERR;
 	}
@@ -1345,6 +1466,7 @@
 				       BRASERO_MEDIUM_APPENDABLE|
 				       BRASERO_MEDIUM_HAS_DATA);
 	brasero_plugin_check_caps (plugin,
+				   BRASERO_CHECKSUM_DETECT|				   
 				   BRASERO_CHECKSUM_MD5_FILE|
 				   BRASERO_CHECKSUM_SHA1_FILE|
 				   BRASERO_CHECKSUM_SHA256_FILE,

Modified: trunk/src/plugins/checksum/burn-volume-read.c
==============================================================================
--- trunk/src/plugins/checksum/burn-volume-read.c	(original)
+++ trunk/src/plugins/checksum/burn-volume-read.c	Sat Jan 24 06:31:48 2009
@@ -30,7 +30,8 @@
 #include "burn-volume-read.h"
 
 struct _BraseroVolFileHandle {
-	guchar buffer [2048 * 4];
+	/* 64 is an empirical value based on one of my drives. */
+	guchar buffer [2048 * 64];
 	guint buffer_max;
 
 	/* position in buffer */
@@ -321,3 +322,71 @@
 
 	return brasero_volume_file_check_state (handle);
 }
+
+BraseroVolFileHandle *
+brasero_volume_file_open_direct (BraseroVolSrc *src,
+				 BraseroVolFile *file)
+{
+	BraseroVolFileHandle *handle;
+
+	if (file->isdir)
+		return NULL;
+
+	handle = g_new0 (BraseroVolFileHandle, 1);
+	handle->src = src;
+	brasero_volume_source_ref (src);
+
+	handle->extents_forward = g_slist_copy (file->specific.file.extents);
+
+	/* Here the buffer stays unused, we copy straight to the buffer passed
+	 * in the read direct function. */
+	if (!brasero_volume_file_next_extent (handle)) {
+		brasero_volume_file_close (handle);
+		return NULL;
+	}
+
+	return handle;
+}
+
+gint64
+brasero_volume_file_read_direct (BraseroVolFileHandle *handle,
+				 guchar *buffer,
+				 guint blocks)
+{
+	gboolean result;
+	guint block2read;
+	guint readblocks = 0;
+
+start:
+
+	block2read = MIN (blocks - readblocks, handle->extent_last - handle->position);
+	if (!block2read)
+		return readblocks * 2048;
+
+	result = BRASERO_VOL_SRC_READ (handle->src,
+				       (char *) buffer + readblocks * 2048,
+				       block2read,
+				       NULL);
+	if (!result)
+		return -1;
+
+	handle->position += block2read;
+	readblocks += block2read;
+
+	if (handle->position == handle->extent_last) {
+		/* we are at the end of current extent try to find another */
+		if (!handle->extents_forward) {
+			/* we reached the end of our file */
+			return (readblocks - 1) * 2048 +
+				handle->extent_size % 2048;
+		}
+
+		if (!brasero_volume_file_next_extent (handle))
+			return -1;
+
+		goto start;
+	}
+
+	return readblocks * 2048;
+}
+

Modified: trunk/src/plugins/checksum/burn-volume-read.h
==============================================================================
--- trunk/src/plugins/checksum/burn-volume-read.h	(original)
+++ trunk/src/plugins/checksum/burn-volume-read.h	Sat Jan 24 06:31:48 2009
@@ -56,6 +56,15 @@
 			       gchar *buffer,
 			       guint len);
 
+BraseroVolFileHandle *
+brasero_volume_file_open_direct (BraseroVolSrc *src,
+				 BraseroVolFile *file);
+
+gint64
+brasero_volume_file_read_direct (BraseroVolFileHandle *handle,
+				 guchar *buffer,
+				 guint blocks);
+
 G_END_DECLS
 
 #endif /* BRASERO_MEDIUM_HANDLE_H */



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