static gboolean
volume_is_blank (GVolume *volume)
{
        BraseroMediumMonitor *monitor;
        BraseroMedium        *medium;
        BraseroDrive         *drive;
        gchar                *device;
        gboolean              is_blank;

        is_blank = FALSE;

        device = g_volume_get_identifier (volume, G_VOLUME_IDENTIFIER_KIND_UNIX_DEVICE);
        if (!device)
                return FALSE;

        DEBUG_PRINT ("Got device: %s\n", device);

        monitor = brasero_medium_monitor_get_default ();
        drive = brasero_medium_monitor_get_drive (monitor, device);
        g_object_unref (monitor);
        g_free (device);

        if (drive == NULL)
                return FALSE;

        medium = brasero_drive_get_medium (drive);
        is_blank = (brasero_medium_get_status (medium) & BRASERO_MEDIUM_BLANK);
        g_object_unref (drive);

        return is_blank;
}
static void
tool_dialog_run (BraseroToolDialog	*dialog,
		 GtkWindow		*toplevel,
		 NautilusMenuItem	*item)
{
	char			*device_path;
	BraseroDrive		*drive;
	BraseroMediumMonitor	*monitor;

	device_path = g_object_get_data (G_OBJECT (item), "drive_device_path");
	if (!device_path) {
		g_warning ("Drive device path not specified");
		return;
	}

	monitor = brasero_medium_monitor_get_default ();
	drive = brasero_medium_monitor_get_drive (monitor, device_path);
	g_object_unref (monitor);

	if (drive) {
		brasero_tool_dialog_set_medium (BRASERO_TOOL_DIALOG (dialog),
						brasero_drive_get_medium (drive));
		g_object_unref (drive);
	}

	/* Get the icon for the window */
	if (toplevel)
		gtk_window_set_icon_name (GTK_WINDOW (dialog), gtk_window_get_icon_name (toplevel));
	else
		gtk_window_set_icon_name (GTK_WINDOW (dialog), "brasero");

	gtk_dialog_run (GTK_DIALOG (dialog));
	gtk_widget_destroy (GTK_WIDGET (dialog));
}
Esempio n. 3
0
gboolean
sj_metadata_helper_check_media (const char *cdrom, GError **error)
{
#ifndef USE_TOTEM_PL_PARSER
  BraseroMediumMonitor *monitor;
  BraseroMedium *medium;
  BraseroDrive *drive;


  /* This initialize the library if it isn't done yet */
  monitor = brasero_medium_monitor_get_default ();
  if (brasero_medium_monitor_is_probing (monitor)) {
      /* FIXME: would be nicer to only check if "cdrom" is being probed,
       * but libbrasero doesn't seem to have an API for that
       */
      g_set_error (error, SJ_ERROR, SJ_ERROR_CD_BUSY, _("Cannot read CD: %s"),
                   _("Devices haven't been all probed yet"));
      return FALSE;
  }
  drive = brasero_medium_monitor_get_drive (monitor, cdrom);
  if (drive == NULL) {
    return FALSE;
  }

  medium = brasero_drive_get_medium (drive);
  g_object_unref (drive);

  if (!medium || !BRASERO_MEDIUM_VALID (brasero_medium_get_status (medium))) {
    char *msg;
    SjError err;

    if (access (cdrom, W_OK) == 0) {
      msg = g_strdup_printf (_("Device '%s' does not contain any media"), cdrom);
      err = SJ_ERROR_CD_NO_MEDIA;
    } else {
      msg = g_strdup_printf (_("Device '%s' could not be opened. Check the access permissions on the device."), cdrom);
      err = SJ_ERROR_CD_PERMISSION_ERROR;
    }
    g_set_error (error, SJ_ERROR, err, _("Cannot read CD: %s"), msg);
    g_free (msg);

    return FALSE;
  }
#else
  GError *totem_error = NULL;

  totem_cd_detect_type (cdrom, &totem_error);

  if (totem_error != NULL) {
    g_set_error (error, SJ_ERROR, SJ_ERROR_CD_NO_MEDIA, _("Cannot read CD: %s"), totem_error->message);
    g_error_free (totem_error);

    return FALSE;
  }
#endif /* !USE_TOTEM_PL_PARSER */

  return TRUE;
}
Esempio n. 4
0
static gpointer
brasero_dvdcss_write_image_thread (gpointer data)
{
	guchar buf [DVDCSS_BLOCK_SIZE * BRASERO_DVDCSS_I_BLOCKS];
	BraseroScrambledSectorRange *range = NULL;
	BraseroMedium *medium = NULL;
	BraseroVolFile *files = NULL;
	dvdcss_handle *handle = NULL;
	BraseroDrive *drive = NULL;
	BraseroDvdcssPrivate *priv;
	gint64 written_sectors = 0;
	BraseroDvdcss *self = data;
	BraseroTrack *track = NULL;
	guint64 remaining_sectors;
	FILE *output_fd = NULL;
	BraseroVolSrc *vol;
	gint64 volume_size;
	GQueue *map = NULL;

	brasero_job_set_use_average_rate (BRASERO_JOB (self), TRUE);
	brasero_job_set_current_action (BRASERO_JOB (self),
					BRASERO_BURN_ACTION_ANALYSING,
					_("Retrieving DVD keys"),
					FALSE);
	brasero_job_start_progress (BRASERO_JOB (self), FALSE);

	priv = BRASERO_DVDCSS_PRIVATE (self);

	/* get the contents of the DVD */
	brasero_job_get_current_track (BRASERO_JOB (self), &track);
	drive = brasero_track_disc_get_drive (BRASERO_TRACK_DISC (track));

	vol = brasero_volume_source_open_file (brasero_drive_get_device (drive), &priv->error);
	files = brasero_volume_get_files (vol,
					  0,
					  NULL,
					  NULL,
					  NULL,
					  &priv->error);
	brasero_volume_source_close (vol);
	if (!files)
		goto end;

	medium = brasero_drive_get_medium (drive);
	brasero_medium_get_data_size (medium, NULL, &volume_size);
	if (volume_size == -1) {
		priv->error = g_error_new (BRASERO_BURN_ERROR,
					   BRASERO_BURN_ERROR_GENERAL,
					   _("The size of the volume could not be retrieved"));
		goto end;
	}

	/* create a handle/open DVD */
	handle = dvdcss_open (brasero_drive_get_device (drive));
	if (!handle) {
		priv->error = g_error_new (BRASERO_BURN_ERROR,
					   BRASERO_BURN_ERROR_GENERAL,
					   _("Video DVD could not be opened"));
		goto end;
	}

	/* look through the files to get the ranges of encrypted sectors
	 * and cache the CSS keys while at it. */
	map = g_queue_new ();
	if (!brasero_dvdcss_create_scrambled_sectors_map (self, drive, map, handle, files, &priv->error))
		goto end;

	BRASERO_JOB_LOG (self, "DVD map created (keys retrieved)");

	g_queue_sort (map, brasero_dvdcss_sort_ranges, NULL);

	brasero_volume_file_free (files);
	files = NULL;

	if (dvdcss_seek (handle, 0, DVDCSS_NOFLAGS) < 0) {
		BRASERO_JOB_LOG (self, "Error initial seeking");
		priv->error = g_error_new (BRASERO_BURN_ERROR,
					   BRASERO_BURN_ERROR_GENERAL,
					   _("Error while reading video DVD (%s)"),
					   dvdcss_error (handle));
		goto end;
	}

	brasero_job_set_current_action (BRASERO_JOB (self),
					BRASERO_BURN_ACTION_DRIVE_COPY,
					_("Copying video DVD"),
					FALSE);

	brasero_job_start_progress (BRASERO_JOB (self), TRUE);

	remaining_sectors = volume_size;
	range = g_queue_pop_head (map);

	if (brasero_job_get_fd_out (BRASERO_JOB (self), NULL) != BRASERO_BURN_OK) {
		gchar *output = NULL;

		brasero_job_get_image_output (BRASERO_JOB (self), &output, NULL);
		output_fd = fopen (output, "w");
		if (!output_fd) {
			priv->error = g_error_new_literal (BRASERO_BURN_ERROR,
							   BRASERO_BURN_ERROR_GENERAL,
							   g_strerror (errno));
			g_free (output);
			goto end;
		}
		g_free (output);
	}

	while (remaining_sectors) {
		gint flag;
		guint64 num_blocks, data_size;

		if (priv->cancel)
			break;

		num_blocks = BRASERO_DVDCSS_I_BLOCKS;

		/* see if we are approaching the end of the dvd */
		if (num_blocks > remaining_sectors)
			num_blocks = remaining_sectors;

		/* see if we need to update the key */
		if (!range || written_sectors < range->start) {
			/* this is in a non scrambled sectors range */
			flag = DVDCSS_NOFLAGS;
	
			/* we don't want to mix scrambled and non scrambled sectors */
			if (range && written_sectors + num_blocks > range->start)
				num_blocks = range->start - written_sectors;
		}
		else {
			/* this is in a scrambled sectors range */
			flag = DVDCSS_READ_DECRYPT;

			/* see if we need to update the key */
			if (written_sectors == range->start) {
				int pos;

				pos = dvdcss_seek (handle, written_sectors, DVDCSS_SEEK_KEY);
				if (pos < 0) {
					BRASERO_JOB_LOG (self, "Error seeking");
					priv->error = g_error_new (BRASERO_BURN_ERROR,
								   BRASERO_BURN_ERROR_GENERAL,
								   _("Error while reading video DVD (%s)"),
								   dvdcss_error (handle));
					break;
				}
			}

			/* we don't want to mix scrambled and non scrambled sectors
			 * NOTE: range->end address is the next non scrambled sector */
			if (written_sectors + num_blocks > range->end)
				num_blocks = range->end - written_sectors;

			if (written_sectors + num_blocks == range->end) {
				/* update to get the next range of scrambled sectors */
				g_free (range);
				range = g_queue_pop_head (map);
			}
		}

		num_blocks = dvdcss_read (handle, buf, num_blocks, flag);
		if (num_blocks < 0) {
			BRASERO_JOB_LOG (self, "Error reading");
			priv->error = g_error_new (BRASERO_BURN_ERROR,
						   BRASERO_BURN_ERROR_GENERAL,
						   _("Error while reading video DVD (%s)"),
						   dvdcss_error (handle));
			break;
		}

		data_size = num_blocks * DVDCSS_BLOCK_SIZE;
		if (output_fd) {
			if (fwrite (buf, 1, data_size, output_fd) != data_size) {
                                int errsv = errno;

				priv->error = g_error_new (BRASERO_BURN_ERROR,
							   BRASERO_BURN_ERROR_GENERAL,
							   _("Data could not be written (%s)"),
							   g_strerror (errsv));
				break;
			}
		}
		else {
			BraseroBurnResult result;

			result = brasero_dvdcss_write_sector_to_fd (self,
								    buf,
								    data_size);
			if (result != BRASERO_BURN_OK)
				break;
		}

		written_sectors += num_blocks;
		remaining_sectors -= num_blocks;
		brasero_job_set_written_track (BRASERO_JOB (self), written_sectors * DVDCSS_BLOCK_SIZE);
	}

end:

	if (range)
		g_free (range);

	if (handle)
		dvdcss_close (handle);

	if (files)
		brasero_volume_file_free (files);

	if (output_fd)
		fclose (output_fd);

	if (map) {
		g_queue_foreach (map, (GFunc) g_free, NULL);
		g_queue_free (map);
	}

	if (!priv->cancel)
		priv->thread_id = g_idle_add (brasero_dvdcss_thread_finished, self);

	/* End thread */
	g_mutex_lock (priv->mutex);
	priv->thread = NULL;
	g_cond_signal (priv->cond);
	g_mutex_unlock (priv->mutex);

	g_thread_exit (NULL);

	return NULL;
}
static GList *
nautilus_disc_burn_get_file_items (NautilusMenuProvider *provider,
                                   GtkWidget            *window,
                                   GList                *selection)
{
        GList            *items = NULL;
        NautilusMenuItem *item;
        NautilusFileInfo *file_info;
        GFile            *file;
        GMount           *mount;
        GVolume          *volume;
        GDrive           *drive;
        char             *mime_type;
        gboolean          is_iso;

        DEBUG_PRINT ("Getting file items\n");

        if (!selection || selection->next != NULL) {
                return NULL;
        }

        file_info = NAUTILUS_FILE_INFO (selection->data);

        if (nautilus_file_info_is_gone (file_info)) {
                return NULL;
        }

        file = nautilus_file_info_get_location (file_info);

        if (file == NULL) {
                DEBUG_PRINT ("No file found\n");
                return NULL;
        }

        mime_type = nautilus_file_info_get_mime_type (file_info);
        DEBUG_PRINT ("Mime type: %s\n", mime_type);
        if (! mime_type) {
                g_object_unref (file);
                return NULL;
        }

        is_iso = (strcmp (mime_type, "application/x-iso-image") == 0)
                || (strcmp (mime_type, "application/x-cd-image") == 0)
                || (strcmp (mime_type, "application/x-cue") == 0)
                || (strcmp (mime_type, "application/x-toc") == 0)
                || (strcmp (mime_type, "application/x-cdrdao-toc") == 0);

        if (is_iso) {
                /* Whether or not this file is local is not a problem */
                item = nautilus_menu_item_new ("NautilusDiscBurn::write_iso",
                                               _("_Write to Disc…"),
                                               _("Write disc image to a CD or DVD"),
                                               "media-optical-data-new");
                g_object_set_data (G_OBJECT (item), "file_info", file_info);
                g_object_set_data (G_OBJECT (item), "window", window);
                g_signal_connect (item, "activate",
                                  G_CALLBACK (write_iso_activate_cb), window);
                items = g_list_append (items, item);
        }

        /*
         * We handle two cases here.  The selection is:
         *  A) a volume
         *  B) a drive
         *
         * This is because there is very little distinction between
         * the two for CD/DVD media
         */

        drive = NULL;
        volume = NULL;

        mount = nautilus_file_info_get_mount (file_info);
        if (mount != NULL) {
                drive = g_mount_get_drive (mount);
                volume = g_mount_get_volume (mount);
        } else {
                char *uri = g_file_get_uri (file);
                DEBUG_PRINT ("Mount not found: %s\n", uri);
                g_free (uri);
        }

        if (drive == NULL && volume != NULL) {
                /* case A */
                drive = g_volume_get_drive (volume);
        } else if (volume == NULL && drive != NULL) {
                /* case B */
                volume = drive_get_first_volume (drive);
                if (volume == NULL) {
                        DEBUG_PRINT ("Volume not found\n");
                }
        }

        if (drive != NULL
            && volume != NULL
            && drive_is_cd_device (drive)
            && ! volume_is_blank (volume)) {
                char			*device_path;
		BraseroMediumMonitor	*monitor;
		BraseroDrive		*bdrive;
		BraseroMedium		*medium;
		BraseroMedia		 media;
		BraseroTrackType	*type;

		/* Reminder: the following is not needed since it is already 
		 * called in drive_is_cd_device ().
		 * ensure_initialized();
		 */

                device_path = g_volume_get_identifier (volume, G_VOLUME_IDENTIFIER_KIND_UNIX_DEVICE);
		monitor = brasero_medium_monitor_get_default ();
		bdrive = brasero_medium_monitor_get_drive (monitor, device_path);
		g_object_unref (monitor);

		medium = brasero_drive_get_medium (bdrive);
		media = brasero_medium_get_status (medium);
		g_object_unref (bdrive);

		type = brasero_track_type_new ();
		brasero_track_type_set_has_medium (type);
		brasero_track_type_set_medium_type (type, media);
		if (brasero_burn_library_input_supported (type) == BRASERO_BURN_OK) {
			/* user may want to copy it ... */
			item = nautilus_menu_item_new ("NautilusDiscBurn::copy_disc",
						       _("_Copy Disc…"),
						       _("Create a copy of this CD or DVD"),
						       "media-optical-copy");
			g_object_set_data (G_OBJECT (item), "file_info", file_info);
			g_object_set_data (G_OBJECT (item), "window", window);
			g_object_set_data_full (G_OBJECT (item), "drive_device_path", g_strdup (device_path), g_free);
			g_signal_connect (item, "activate", G_CALLBACK (copy_disc_activate_cb), window);
			items = g_list_append (items, item);
		}
		brasero_track_type_free (type);

		if (brasero_burn_library_get_media_capabilities (media) & BRASERO_MEDIUM_REWRITABLE) {
			/* ... or if it's a rewritable medium to blank it ... */
			item = nautilus_menu_item_new ("NautilusDiscBurn::blank_disc",
						       _("_Blank Disc…"),
						       _("Blank this CD or DVD"),
						       "media-optical-blank");
			g_object_set_data (G_OBJECT (item), "file_info", file_info);
			g_object_set_data (G_OBJECT (item), "window", window);
			g_object_set_data_full (G_OBJECT (item), "drive_device_path", g_strdup (device_path), g_free);
			g_signal_connect (item, "activate",
					  G_CALLBACK (blank_disc_activate_cb), window);
			items = g_list_append (items, item);
		}

		/* - library should be able to checksum
		 * - disc must have a data session */
		if (brasero_burn_library_can_checksum ()
		&& (media & BRASERO_MEDIUM_HAS_DATA)) {
			/* ... or verify medium. */
			item = nautilus_menu_item_new ("NautilusDiscBurn::check_disc",
						       _("_Check Disc…"),
						       _("Check the data integrity on this CD or DVD"),
						       NULL);
			g_object_set_data (G_OBJECT (item), "file_info", file_info);
			g_object_set_data (G_OBJECT (item), "window", window);
			g_object_set_data_full (G_OBJECT (item), "drive_device_path", g_strdup (device_path), g_free);
			g_signal_connect (item, "activate",
					  G_CALLBACK (check_disc_activate_cb),
			                  window);
			items = g_list_append (items, item);
		}

                g_free (device_path);
        }

        g_object_unref (file);

        if (drive != NULL) {
                g_object_unref (drive);
        }
        if (volume != NULL) {
                g_object_unref (volume);
        }

        g_free (mime_type);

        DEBUG_PRINT ("Items returned\n");
        return items;
}
Esempio n. 6
0
static BraseroBurnResult
brasero_readom_set_argv (BraseroProcess *process,
			 GPtrArray *argv,
			 GError **error)
{
	BraseroBurnResult result = FALSE;
	BraseroTrackType *output = NULL;
	BraseroImageFormat format;
	BraseroJobAction action;
	BraseroReadom *readom;
	BraseroMedium *medium;
	BraseroDrive *drive;
	BraseroTrack *track;
	BraseroMedia media;
	gchar *outfile_arg;
	gchar *dev_str;

	readom = BRASERO_READOM (process);

	/* This is a kind of shortcut */
	brasero_job_get_action (BRASERO_JOB (process), &action);
	if (action == BRASERO_JOB_ACTION_SIZE)
		return brasero_readom_get_size (readom, error);

	g_ptr_array_add (argv, g_strdup ("readom"));

	brasero_job_get_current_track (BRASERO_JOB (readom), &track);
	drive = brasero_track_disc_get_drive (BRASERO_TRACK_DISC (track));
	if (!brasero_drive_get_device (drive))
		return BRASERO_BURN_ERR;

	dev_str = g_strdup_printf ("dev=%s", brasero_drive_get_device (drive));
	g_ptr_array_add (argv, dev_str);

	g_ptr_array_add (argv, g_strdup ("-nocorr"));

	medium = brasero_drive_get_medium (drive);
	media = brasero_medium_get_status (medium);

	output = brasero_track_type_new ();
	brasero_job_get_output_type (BRASERO_JOB (readom), output);
	format = brasero_track_type_get_image_format (output);
	brasero_track_type_free (output);

	if ((media & BRASERO_MEDIUM_DVD)
	&&   format != BRASERO_IMAGE_FORMAT_BIN) {
		g_set_error (error,
			     BRASERO_BURN_ERROR,
			     BRASERO_BURN_ERROR_GENERAL,
			     _("An internal error occurred"));
		return BRASERO_BURN_ERR;
	}

	if (format == BRASERO_IMAGE_FORMAT_CLONE) {
		/* NOTE: with this option the sector size is 2448 
		 * because it is raw96 (2352+96) otherwise it is 2048  */
		g_ptr_array_add (argv, g_strdup ("-clone"));
	}
	else if (format == BRASERO_IMAGE_FORMAT_BIN) {
		g_ptr_array_add (argv, g_strdup ("-noerror"));

		/* don't do it for clone since we need the entire disc */
		result = brasero_readom_argv_set_iso_boundary (readom, argv, error);
		if (result != BRASERO_BURN_OK)
			return result;
	}
	else
		BRASERO_JOB_NOT_SUPPORTED (readom);

	if (brasero_job_get_fd_out (BRASERO_JOB (readom), NULL) != BRASERO_BURN_OK) {
		gchar *image;

		if (format != BRASERO_IMAGE_FORMAT_CLONE
		&&  format != BRASERO_IMAGE_FORMAT_BIN)
			BRASERO_JOB_NOT_SUPPORTED (readom);

		result = brasero_job_get_image_output (BRASERO_JOB (readom),
						       &image,
						       NULL);
		if (result != BRASERO_BURN_OK)
			return result;

		outfile_arg = g_strdup_printf ("-f=%s", image);
		g_ptr_array_add (argv, outfile_arg);
		g_free (image);
	}
	else if (format == BRASERO_IMAGE_FORMAT_BIN) {
		outfile_arg = g_strdup ("-f=-");
		g_ptr_array_add (argv, outfile_arg);
	}
	else 	/* unfortunately raw images can't be piped out */
		BRASERO_JOB_NOT_SUPPORTED (readom);

	brasero_job_set_use_average_rate (BRASERO_JOB (process), TRUE);
	return BRASERO_BURN_OK;
}
Esempio n. 7
0
static BraseroBurnResult
brasero_readom_get_size (BraseroReadom *self,
			 GError **error)
{
	goffset blocks;
	GValue *value = NULL;
	BraseroTrack *track = NULL;
	BraseroTrackType *output = NULL;

	output = brasero_track_type_new ();
	brasero_job_get_output_type (BRASERO_JOB (self), output);

	if (!brasero_track_type_get_has_image (output)) {
		brasero_track_type_free (output);
		return BRASERO_BURN_ERR;
	}

	brasero_job_get_current_track (BRASERO_JOB (self), &track);
	brasero_track_tag_lookup (track,
				  BRASERO_TRACK_MEDIUM_ADDRESS_START_TAG,
				  &value);
	if (value) {
		guint64 start, end;

		/* we were given an address to start */
		start = g_value_get_uint64 (value);

		/* get the length now */
		value = NULL;
		brasero_track_tag_lookup (track,
					  BRASERO_TRACK_MEDIUM_ADDRESS_END_TAG,
					  &value);

		end = g_value_get_uint64 (value);
		blocks = end - start;
	}
	else if (brasero_track_disc_get_track_num (BRASERO_TRACK_DISC (track)) > 0) {
		BraseroDrive *drive;
		BraseroMedium *medium;

		drive = brasero_track_disc_get_drive (BRASERO_TRACK_DISC (track));
		medium = brasero_drive_get_medium (drive);
		brasero_medium_get_track_space (medium,
						brasero_track_disc_get_track_num (BRASERO_TRACK_DISC (track)),
						NULL,
						&blocks);
	}
	else if (brasero_track_type_get_image_format (output) == BRASERO_IMAGE_FORMAT_BIN) {
		BraseroDrive *drive;
		BraseroMedium *medium;

		drive = brasero_track_disc_get_drive (BRASERO_TRACK_DISC (track));
		medium = brasero_drive_get_medium (drive);
		brasero_medium_get_last_data_track_space (medium,
							  NULL,
							  &blocks);
	}
	else
		brasero_track_get_size (track, &blocks, NULL);

	if (brasero_track_type_get_image_format (output) == BRASERO_IMAGE_FORMAT_BIN) {
		brasero_job_set_output_size_for_current_track (BRASERO_JOB (self),
							       blocks,
							       blocks * 2048ULL);
	}
	else if (brasero_track_type_get_image_format (output) == BRASERO_IMAGE_FORMAT_CLONE) {
		brasero_job_set_output_size_for_current_track (BRASERO_JOB (self),
							       blocks,
							       blocks * 2448ULL);
	}
	else {
		brasero_track_type_free (output);
		return BRASERO_BURN_NOT_SUPPORTED;
	}

	brasero_track_type_free (output);

	/* no need to go any further */
	return BRASERO_BURN_NOT_RUNNING;
}
Esempio n. 8
0
static BraseroBurnResult
brasero_readom_argv_set_iso_boundary (BraseroReadom *readom,
				      GPtrArray *argv,
				      GError **error)
{
	goffset nb_blocks;
	BraseroTrack *track;
	GValue *value = NULL;
	BraseroTrackType *output = NULL;

	brasero_job_get_current_track (BRASERO_JOB (readom), &track);

	output = brasero_track_type_new ();
	brasero_job_get_output_type (BRASERO_JOB (readom), output);

	brasero_track_tag_lookup (track,
				  BRASERO_TRACK_MEDIUM_ADDRESS_START_TAG,
				  &value);
	if (value) {
		guint64 start, end;

		/* we were given an address to start */
		start = g_value_get_uint64 (value);

		/* get the length now */
		value = NULL;
		brasero_track_tag_lookup (track,
					  BRASERO_TRACK_MEDIUM_ADDRESS_END_TAG,
					  &value);

		end = g_value_get_uint64 (value);

		BRASERO_JOB_LOG (readom,
				 "reading from sector %lli to %lli",
				 start,
				 end);
		g_ptr_array_add (argv, g_strdup_printf ("-sectors=%"G_GINT64_FORMAT"-%"G_GINT64_FORMAT,
							start,
							end));
	}
	/* 0 means all disc, -1 problem */
	else if (brasero_track_disc_get_track_num (BRASERO_TRACK_DISC (track)) > 0) {
		goffset start;
		BraseroDrive *drive;
		BraseroMedium *medium;

		drive = brasero_track_disc_get_drive (BRASERO_TRACK_DISC (track));
		medium = brasero_drive_get_medium (drive);
		brasero_medium_get_track_space (medium,
						brasero_track_disc_get_track_num (BRASERO_TRACK_DISC (track)),
						NULL,
						&nb_blocks);
		brasero_medium_get_track_address (medium,
						  brasero_track_disc_get_track_num (BRASERO_TRACK_DISC (track)),
						  NULL,
						  &start);

		BRASERO_JOB_LOG (readom,
				 "reading %i from sector %lli to %lli",
				 brasero_track_disc_get_track_num (BRASERO_TRACK_DISC (track)),
				 start,
				 start + nb_blocks);
		g_ptr_array_add (argv, g_strdup_printf ("-sectors=%"G_GINT64_FORMAT"-%"G_GINT64_FORMAT,
							start,
							start + nb_blocks));
	}
	/* if it's BIN output just read the last track */
	else if (brasero_track_type_get_image_format (output) == BRASERO_IMAGE_FORMAT_BIN) {
		goffset start;
		BraseroDrive *drive;
		BraseroMedium *medium;

		drive = brasero_track_disc_get_drive (BRASERO_TRACK_DISC (track));
		medium = brasero_drive_get_medium (drive);
		brasero_medium_get_last_data_track_space (medium,
							  NULL,
							  &nb_blocks);
		brasero_medium_get_last_data_track_address (medium,
							    NULL,
							    &start);
		BRASERO_JOB_LOG (readom,
				 "reading last track from sector %"G_GINT64_FORMAT" to %"G_GINT64_FORMAT,
				 start,
				 start + nb_blocks);
		g_ptr_array_add (argv, g_strdup_printf ("-sectors=%"G_GINT64_FORMAT"-%"G_GINT64_FORMAT,
							start,
							start + nb_blocks));
	}
	else {
		brasero_track_get_size (track, &nb_blocks, NULL);
		g_ptr_array_add (argv, g_strdup_printf ("-sectors=0-%"G_GINT64_FORMAT, nb_blocks));
	}

	brasero_track_type_free (output);

	return BRASERO_BURN_OK;
}