summaryrefslogtreecommitdiffstats
path: root/sysutils/brasero/files/patch-src_burn-medium-cam.c
diff options
context:
space:
mode:
Diffstat (limited to 'sysutils/brasero/files/patch-src_burn-medium-cam.c')
-rw-r--r--sysutils/brasero/files/patch-src_burn-medium-cam.c1928
1 files changed, 0 insertions, 1928 deletions
diff --git a/sysutils/brasero/files/patch-src_burn-medium-cam.c b/sysutils/brasero/files/patch-src_burn-medium-cam.c
deleted file mode 100644
index 2db8d00ca..000000000
--- a/sysutils/brasero/files/patch-src_burn-medium-cam.c
+++ /dev/null
@@ -1,1928 +0,0 @@
---- src/burn-medium-cam.c.orig 2008-02-06 01:53:39.000000000 -0500
-+++ src/burn-medium-cam.c 2008-02-06 01:56:01.000000000 -0500
-@@ -0,0 +1,1925 @@
-+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
-+/*
-+ * brasero
-+ * Copyright (C) Philippe Rouquier 2007 <bonfire-app@wanadoo.fr>
-+ * Joe Marcus Clarke 2007 <marcus@FreeBSD.org>
-+ *
-+ * brasero is free software.
-+ *
-+ * You may redistribute it and/or modify it under the terms of the
-+ * GNU General Public License, as published by the Free Software
-+ * Foundation; either version 2 of the License, or (at your option)
-+ * any later version.
-+ *
-+ * brasero is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-+ * See the GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with brasero. If not, write to:
-+ * The Free Software Foundation, Inc.,
-+ * 51 Franklin Street, Fifth Floor
-+ * Boston, MA 02110-1301, USA.
-+ */
-+
-+#ifdef HAVE_CONFIG_H
-+# include <config.h>
-+#endif
-+
-+#include <sys/types.h>
-+#include <sys/stat.h>
-+#include <stdlib.h>
-+#include <fcntl.h>
-+#include <errno.h>
-+
-+#include <glib.h>
-+#include <glib/gi18n-lib.h>
-+
-+#include <nautilus-burn-drive.h>
-+
-+#include "burn-basics.h"
-+#include "burn-debug.h"
-+#include "burn-medium.h"
-+#include "cam-cdrom.h"
-+#include "scsi-read-format-capacities.h"
-+#include "scsi-read-toc-pma-atip.h"
-+#include "scsi-get-configuration.h"
-+#include "scsi-q-subchannel.h"
-+#include "scsi-utils.h"
-+#include "freebsd_dvd_rw_utils.h"
-+#include "burn-volume.h"
-+#include "brasero-ncb.h"
-+
-+const gchar *icons [] = { "gnome-dev-removable",
-+ "gnome-dev-cdrom",
-+ "gnome-dev-disc-cdr",
-+ "gnome-dev-disc-cdrw",
-+ "gnome-dev-disc-dvdrom",
-+ "gnome-dev-disc-dvdr",
-+ "gnome-dev-disc-dvdrw",
-+ "gnome-dev-disc-dvdr-plus",
-+ "gnome-dev-disc-dvdram",
-+ NULL };
-+const gchar *types [] = { N_("file"),
-+ N_("CDROM"),
-+ N_("CD-R"),
-+ N_("CD-RW"),
-+ N_("DVDROM"),
-+ N_("DVD-R"),
-+ N_("DVD-RW"),
-+ N_("DVD+R"),
-+ N_("DVD+RW"),
-+ N_("DVD+R dual layer"),
-+ N_("DVD+RW dual layer"),
-+ N_("DVD-R dual layer"),
-+ N_("DVD-RAM"),
-+ N_("Blu-ray disc"),
-+ N_("Writable Blu-ray disc"),
-+ N_("Rewritable Blu-ray disc"),
-+ NULL };
-+
-+
-+typedef struct _BraseroMediumPrivate BraseroMediumPrivate;
-+struct _BraseroMediumPrivate
-+{
-+ gint retry_id;
-+
-+ GSList * tracks;
-+
-+ const gchar *type;
-+ const gchar *icon;
-+
-+ gint max_rd;
-+ gint max_wrt;
-+
-+ gint *rd_speeds;
-+ gint *wr_speeds;
-+
-+ gint64 block_num;
-+ gint64 block_size;
-+
-+ guint64 next_wr_add;
-+ BraseroMedia info;
-+ NautilusBurnDrive * drive;
-+};
-+
-+#define BRASERO_MEDIUM_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), BRASERO_TYPE_MEDIUM, BraseroMediumPrivate))
-+
-+enum
-+{
-+ PROP_0,
-+ PROP_DRIVE
-+};
-+
-+static GObjectClass* parent_class = NULL;
-+
-+const gchar *
-+brasero_medium_get_type_string (BraseroMedium *medium)
-+{
-+ BraseroMediumPrivate *priv;
-+
-+ priv = BRASERO_MEDIUM_PRIVATE (medium);
-+ return priv->type;
-+}
-+
-+const gchar *
-+brasero_medium_get_icon (BraseroMedium *medium)
-+{
-+ BraseroMediumPrivate *priv;
-+
-+ priv = BRASERO_MEDIUM_PRIVATE (medium);
-+ return priv->icon;
-+}
-+
-+BraseroMedia
-+brasero_medium_get_status (BraseroMedium *medium)
-+{
-+ BraseroMediumPrivate *priv;
-+
-+ priv = BRASERO_MEDIUM_PRIVATE (medium);
-+ return priv->info;
-+}
-+
-+GSList *
-+brasero_medium_get_tracks (BraseroMedium *medium)
-+{
-+ BraseroMediumPrivate *priv;
-+
-+ priv = BRASERO_MEDIUM_PRIVATE (medium);
-+ return g_slist_copy (priv->tracks);
-+}
-+
-+gboolean
-+brasero_medium_get_last_data_track_address (BraseroMedium *medium,
-+ gint64 *byte,
-+ gint64 *sector)
-+{
-+ GSList *iter;
-+ BraseroMediumPrivate *priv;
-+ BraseroMediumTrack *track = NULL;
-+
-+ priv = BRASERO_MEDIUM_PRIVATE (medium);
-+
-+ for (iter = priv->tracks; iter; iter = iter->next) {
-+ BraseroMediumTrack *current;
-+
-+ current = iter->data;
-+ if (current->type & BRASERO_MEDIUM_TRACK_DATA)
-+ track = current;
-+ }
-+
-+ if (!track) {
-+ if (byte)
-+ *byte = -1;
-+ if (sector)
-+ *sector = -1;
-+ return FALSE;
-+ }
-+
-+ if (byte)
-+ *byte = track->start * priv->block_size;
-+
-+ if (sector)
-+ *sector = track->start;
-+
-+ return TRUE;
-+}
-+
-+gboolean
-+brasero_medium_get_last_data_track_space (BraseroMedium *medium,
-+ gint64 *size,
-+ gint64 *blocks)
-+{
-+ GSList *iter;
-+ BraseroMediumPrivate *priv;
-+ BraseroMediumTrack *track = NULL;
-+
-+ priv = BRASERO_MEDIUM_PRIVATE (medium);
-+
-+ for (iter = priv->tracks; iter; iter = iter->next) {
-+ BraseroMediumTrack *current;
-+
-+ current = iter->data;
-+ if (current->type & BRASERO_MEDIUM_TRACK_DATA)
-+ track = current;
-+ }
-+
-+ if (!track) {
-+ if (size)
-+ *size = -1;
-+ if (blocks)
-+ *blocks = -1;
-+ return FALSE;
-+ }
-+
-+ if (size)
-+ *size = track->blocks_num * priv->block_size;
-+ if (blocks)
-+ *blocks = track->blocks_num;
-+
-+ return TRUE;
-+}
-+
-+guint
-+brasero_medium_get_track_num (BraseroMedium *medium)
-+{
-+ guint retval = 0;
-+ GSList *iter;
-+ BraseroMediumPrivate *priv;
-+
-+ priv = BRASERO_MEDIUM_PRIVATE (medium);
-+ for (iter = priv->tracks; iter; iter = iter->next) {
-+ BraseroMediumTrack *current;
-+
-+ current = iter->data;
-+ if (current->type & BRASERO_MEDIUM_TRACK_LEADOUT)
-+ break;
-+
-+ retval ++;
-+ }
-+
-+ return retval;
-+}
-+
-+static BraseroMediumTrack *
-+brasero_medium_get_track (BraseroMedium *medium,
-+ guint num)
-+{
-+ guint i = 1;
-+ GSList *iter;
-+ BraseroMediumPrivate *priv;
-+
-+ priv = BRASERO_MEDIUM_PRIVATE (medium);
-+
-+ for (iter = priv->tracks; iter; iter = iter->next) {
-+ BraseroMediumTrack *current;
-+
-+ current = iter->data;
-+ if (current->type == BRASERO_MEDIUM_TRACK_LEADOUT)
-+ break;
-+
-+ if (i == num)
-+ return current;
-+
-+ i++;
-+ }
-+
-+ return NULL;
-+}
-+
-+gboolean
-+brasero_medium_get_track_space (BraseroMedium *medium,
-+ guint num,
-+ gint64 *size,
-+ gint64 *blocks)
-+{
-+ BraseroMediumPrivate *priv;
-+ BraseroMediumTrack *track;
-+
-+ priv = BRASERO_MEDIUM_PRIVATE (medium);
-+
-+ track = brasero_medium_get_track (medium, num);
-+ if (!track) {
-+ if (size)
-+ *size = -1;
-+ if (blocks)
-+ *blocks = -1;
-+ return FALSE;
-+ }
-+
-+ if (size)
-+ *size = track->blocks_num * priv->block_size;
-+ if (blocks)
-+ *blocks = track->blocks_num;
-+
-+ return TRUE;
-+}
-+
-+gboolean
-+brasero_medium_get_track_address (BraseroMedium *medium,
-+ guint num,
-+ gint64 *byte,
-+ gint64 *sector)
-+{
-+ BraseroMediumPrivate *priv;
-+ BraseroMediumTrack *track;
-+
-+ priv = BRASERO_MEDIUM_PRIVATE (medium);
-+
-+ track = brasero_medium_get_track (medium, num);
-+ if (!track) {
-+ if (byte)
-+ *byte = -1;
-+ if (sector)
-+ *sector = -1;
-+ return FALSE;
-+ }
-+
-+ if (byte)
-+ *byte = track->start * priv->block_size;
-+ if (sector)
-+ *sector = track->start;
-+
-+ return TRUE;
-+}
-+
-+gint64
-+brasero_medium_get_next_writable_address (BraseroMedium *medium)
-+{
-+ BraseroMediumPrivate *priv;
-+
-+ priv = BRASERO_MEDIUM_PRIVATE (medium);
-+ return priv->next_wr_add;
-+}
-+
-+gint64
-+brasero_medium_get_max_write_speed (BraseroMedium *medium)
-+{
-+ BraseroMediumPrivate *priv;
-+
-+ priv = BRASERO_MEDIUM_PRIVATE (medium);
-+ return priv->max_wrt * 1024;
-+}
-+
-+/**
-+ * NOTEs about the following functions:
-+ * for all closed media (including ROM types) capacity == size of data and
-+ * should be the size of all data on the disc, free space is 0
-+ * for all blank -R types capacity == free space and size of data == 0
-+ * for all multisession -R types capacity == free space since having the real
-+ * capacity of the media would be useless as we can only use this type of media
-+ * to append more data
-+ * for all -RW types capacity = free space + size of data. Here they can be
-+ * appended (use free space) or rewritten (whole capacity).
-+ *
-+ * Usually:
-+ * the free space is the size of the leadout track
-+ * the size of data is the sum of track sizes (excluding leadout)
-+ * the capacity depends on the media:
-+ * for closed discs == sum of track sizes
-+ * for multisession discs == free space (leadout size)
-+ * for blank discs == (free space) leadout size
-+ * for rewritable/blank == use SCSI functions to get capacity (see below)
-+ *
-+ * In fact we should really need the size of data in DVD+/-RW cases since the
-+ * session is always equal to the size of the disc.
-+ */
-+
-+void
-+brasero_medium_get_data_size (BraseroMedium *medium,
-+ gint64 *size,
-+ gint64 *blocks)
-+{
-+ GSList *iter;
-+ BraseroMediumPrivate *priv;
-+ BraseroMediumTrack *track = NULL;
-+
-+ priv = BRASERO_MEDIUM_PRIVATE (medium);
-+
-+ if (!priv->tracks) {
-+ /* that's probably because it wasn't possible to retrieve info */
-+ if (size)
-+ *size = 0;
-+
-+ if (blocks)
-+ *blocks = 0;
-+
-+ return;
-+ }
-+
-+ for (iter = priv->tracks; iter; iter = iter->next) {
-+ BraseroMediumTrack *tmp;
-+
-+ tmp = iter->data;
-+ if (tmp->type == BRASERO_MEDIUM_TRACK_LEADOUT)
-+ break;
-+
-+ track = iter->data;
-+ }
-+
-+ if (size)
-+ *size = track ? (track->start + track->blocks_num) * priv->block_size: 0;
-+
-+ if (blocks)
-+ *blocks = track ? track->start + track->blocks_num: 0;
-+}
-+
-+void
-+brasero_medium_get_free_space (BraseroMedium *medium,
-+ gint64 *size,
-+ gint64 *blocks)
-+{
-+ GSList *iter;
-+ BraseroMediumPrivate *priv;
-+ BraseroMediumTrack *track = NULL;
-+
-+ priv = BRASERO_MEDIUM_PRIVATE (medium);
-+
-+ if (!priv->tracks) {
-+ /* that's probably because it wasn't possible to retrieve info.
-+ * maybe it also happens with unformatted DVD+RW */
-+
-+ if (priv->info & BRASERO_MEDIUM_CLOSED) {
-+ if (size)
-+ *size = 0;
-+
-+ if (blocks)
-+ *blocks = 0;
-+ }
-+ else {
-+ if (size)
-+ *size = priv->block_num * priv->block_size;
-+
-+ if (blocks)
-+ *blocks = priv->block_num;
-+ }
-+
-+ return;
-+ }
-+
-+ for (iter = priv->tracks; iter; iter = iter->next) {
-+ BraseroMediumTrack *tmp;
-+
-+ tmp = iter->data;
-+ if (tmp->type == BRASERO_MEDIUM_TRACK_LEADOUT) {
-+ track = iter->data;
-+ break;
-+ }
-+ }
-+
-+ if (size) {
-+ if (!track) {
-+ /* No leadout was found so the disc is probably closed:
-+ * no free space left. */
-+ *size = 0;
-+ }
-+ else if (track->blocks_num <= 0)
-+ *size = (priv->block_num - track->start) * priv->block_size;
-+ else
-+ *size = track->blocks_num * priv->block_size;
-+ }
-+
-+ if (blocks) {
-+ if (!track) {
-+ /* No leadout was found so the disc is probably closed:
-+ * no free space left. */
-+ *blocks = 0;
-+ }
-+ else if (track->blocks_num <= 0)
-+ *blocks = priv->block_num - track->blocks_num;
-+ else
-+ *blocks = track->blocks_num;
-+ }
-+}
-+
-+void
-+brasero_medium_get_capacity (BraseroMedium *medium,
-+ gint64 *size,
-+ gint64 *blocks)
-+{
-+ BraseroMediumPrivate *priv;
-+
-+ priv = BRASERO_MEDIUM_PRIVATE (medium);
-+
-+ if (priv->info & BRASERO_MEDIUM_REWRITABLE) {
-+ if (size)
-+ *size = priv->block_num * priv->block_size;
-+
-+ if (blocks)
-+ *blocks = priv->block_num;
-+ }
-+ else if (priv->info & BRASERO_MEDIUM_CLOSED)
-+ brasero_medium_get_data_size (medium, size, blocks);
-+ else
-+ brasero_medium_get_free_space (medium, size, blocks);
-+}
-+
-+/**
-+ * Function to retrieve the capacity of a media
-+ */
-+
-+static BraseroBurnResult
-+brasero_medium_get_capacity_CD_RW (BraseroMedium *self,
-+ BRASEROCDROM *cdrom)
-+{
-+ unsigned char *atip_data = NULL;
-+ unsigned char *desc;
-+ BraseroMediumPrivate *priv;
-+ int result;
-+ int size;
-+
-+ priv = BRASERO_MEDIUM_PRIVATE (self);
-+
-+ BRASERO_BURN_LOG ("Retrieving capacity from atip");
-+
-+ result = brasero_cdrom_read_atip (cdrom, &atip_data);
-+
-+ if (result != 0) {
-+ g_free (atip_data);
-+
-+ BRASERO_BURN_LOG ("READ ATIP failed (scsi error)");
-+ return BRASERO_BURN_ERR;
-+ }
-+
-+ size = (atip_data[0] << 8 | atip_data[1]) - 2;
-+
-+ /* check the size of the structure: it must be at least 16 bytes long */
-+ if (size < 16) {
-+ if (size)
-+ g_free (atip_data);
-+
-+ BRASERO_BURN_LOG ("READ ATIP failed (wrong size)");
-+ return BRASERO_BURN_ERR;
-+ }
-+
-+ desc = atip_data + 8;
-+
-+ priv->block_num = BRASERO_MSF_TO_LBA (desc[8], desc[9], desc[10]);
-+ g_free (atip_data);
-+
-+ BRASERO_BURN_LOG ("Format capacity %lli %lli",
-+ priv->block_num,
-+ priv->block_size);
-+
-+ return BRASERO_BURN_OK;
-+}
-+
-+static BraseroBurnResult
-+brasero_medium_get_capacity_DVD_RW (BraseroMedium *self,
-+ BRASEROCDROM *cdrom)
-+{
-+ unsigned char *hdr = NULL;
-+ unsigned char *current;
-+ BraseroMediumPrivate *priv;
-+ int result;
-+
-+ BRASERO_BURN_LOG ("Retrieving format capacity");
-+
-+ priv = BRASERO_MEDIUM_PRIVATE (self);
-+ result = brasero_cdrom_read_format_capacities (cdrom, &hdr);
-+ if (result != 0) {
-+ g_free (hdr);
-+
-+ BRASERO_BURN_LOG ("READ FORMAT CAPACITIES failed");
-+ return BRASERO_BURN_ERR;
-+ }
-+
-+ current = hdr + 5;
-+
-+ /* see if the media is already formatted */
-+ if ((current[4] & 3) != BRASERO_SCSI_DESC_FORMATTED) {
-+ int i, max;
-+ unsigned char *desc;
-+
-+ max = (hdr[4] - 8) / 8;
-+
-+ desc = hdr + 5;
-+ for (i = 0; i < max; i ++, desc += 8) {
-+ /* search for the correct descriptor */
-+ if (BRASERO_MEDIUM_IS (priv->info, BRASERO_MEDIUM_DVDRW_PLUS)) {
-+ if ((desc[4] >> 2) == BRASERO_SCSI_DVDRW_PLUS) {
-+ priv->block_num = (desc[0] << 24 | desc[1] << 16 | desc[2] << 8 | desc[3]);
-+ priv->block_size = (desc[5] << 16 | desc[6] << 8 | desc[7]);
-+
-+ /* that can happen */
-+ if (!priv->block_size)
-+ priv->block_size = 2048;
-+ break;
-+ }
-+ }
-+ else if ((desc[4] >> 2) == BRASERO_SCSI_BLOCK_SIZE_DEFAULT_AND_DB) {
-+ priv->block_num = (desc[0] << 24 | desc[1] << 16 | desc[2] << 8 | desc[3]);
-+ priv->block_size = (desc[5] << 16 | desc[6] << 8 | desc[7]);
-+ break;
-+ }
-+ }
-+ }
-+ else {
-+ priv->block_num = (current[0] << 24 | current[1] << 16 | current[2] << 8 | current[3]);
-+ priv->block_size = (current[5] << 16 | current[6] << 8 | current[7]);
-+ }
-+
-+ BRASERO_BURN_LOG ("Format capacity %lli %lli",
-+ priv->block_num,
-+ priv->block_size);
-+
-+ g_free (hdr);
-+ return BRASERO_BURN_OK;
-+}
-+
-+static BraseroBurnResult
-+brasero_medium_get_capacity_by_type (BraseroMedium *self,
-+ BRASEROCDROM *cdrom)
-+{
-+ BraseroMediumPrivate *priv;
-+
-+ priv = BRASERO_MEDIUM_PRIVATE (self);
-+
-+ priv->block_size = 2048;
-+
-+ if (!(priv->info & BRASERO_MEDIUM_REWRITABLE))
-+ return BRASERO_BURN_OK;
-+
-+ if (priv->info & BRASERO_MEDIUM_CD)
-+ brasero_medium_get_capacity_CD_RW (self, cdrom);
-+ else
-+ brasero_medium_get_capacity_DVD_RW (self, cdrom);
-+
-+ return BRASERO_BURN_OK;
-+}
-+
-+/**
-+ * Functions to retrieve the speed
-+ */
-+
-+static BraseroBurnResult
-+brasero_medium_get_speed_mmc3 (BraseroMedium *self,
-+ BRASEROCDROM *cdrom)
-+{
-+ int size;
-+ int num_desc, i;
-+ gint max_rd, max_wrt;
-+ int result;
-+ BraseroMediumPrivate *priv;
-+ unsigned char *desc;
-+ unsigned char *wrt_perf = NULL;
-+
-+ BRASERO_BURN_LOG ("Retrieving speed (Get Performance)");
-+
-+ /* NOTE: this only work if there is RT streaming feature with
-+ * wspd bit set to 1. At least an MMC3 drive. */
-+ priv = BRASERO_MEDIUM_PRIVATE (self);
-+ result = brasero_cdrom_get_performance_wrt_spd_desc (cdrom, &wrt_perf);
-+
-+ if (result != 0) {
-+ g_free (wrt_perf);
-+
-+ BRASERO_BURN_LOG ("GET PERFORMANCE failed");
-+ return BRASERO_BURN_ERR;
-+ }
-+
-+ size = 4 + (wrt_perf[0] << 24 | wrt_perf[1] << 16 | wrt_perf[2] << 8 | wrt_perf[3]);
-+
-+ num_desc = (size - 8) / 16;
-+
-+ if (num_desc <= 0)
-+ goto end;
-+
-+ priv->rd_speeds = g_new0 (gint, num_desc + 1);
-+ priv->wr_speeds = g_new0 (gint, num_desc + 1);
-+
-+ max_rd = 0;
-+ max_wrt = 0;
-+
-+ desc = wrt_perf + 8;
-+ for (i = 0; i < num_desc; i ++, desc += 16) {
-+ priv->rd_speeds [i] = (desc[8] << 24 | desc[9] << 16 | desc[10] << 8 || desc[11]);
-+ priv->wr_speeds [i] = (desc[12] << 24 | desc[13] << 16 | desc[14] << 8 | desc[15]);
-+
-+ max_rd = MAX (max_rd, priv->rd_speeds [i]);
-+ max_wrt = MAX (max_wrt, priv->wr_speeds [i]);
-+ }
-+
-+ priv->max_rd = max_rd;
-+ priv->max_wrt = max_wrt;
-+
-+end:
-+
-+ g_free (wrt_perf);
-+
-+ /* strangely there are so drives (I know one case) which support this
-+ * function but don't report any speed. So if our top speed is 0 then
-+ * use the other way to get the speed. It was a Teac */
-+ if (!priv->max_wrt)
-+ return BRASERO_BURN_ERR;
-+
-+ return BRASERO_BURN_OK;
-+}
-+
-+static BraseroBurnResult
-+brasero_medium_get_page_2A_write_speed_desc (BraseroMedium *self,
-+ BRASEROCDROM *cdrom)
-+{
-+ BraseroMediumPrivate *priv;
-+ int result;
-+ char *wspeeds;
-+ int rspeed, wspeed;
-+
-+ BRASERO_BURN_LOG ("Retrieving speed (2A speeds)");
-+
-+ priv = BRASERO_MEDIUM_PRIVATE (self);
-+ result = brasero_cdrom_get_read_write_speed (cdrom, &rspeed, &wspeed, &wspeeds);
-+
-+ if (result != 0) {
-+ BRASERO_BURN_LOG ("MODE SENSE failed");
-+ return BRASERO_BURN_ERR;
-+ }
-+
-+ if (wspeeds != NULL) {
-+ char **speedv;
-+ int i;
-+
-+ speedv = g_strsplit_set (wspeeds, ",", 0);
-+ g_free (wspeeds);
-+ priv->wr_speeds = g_new0 (gint, g_strv_length (speedv) + 1);
-+ for (i = 0; speedv[i] != NULL; i++) {
-+ if (*(speedv[i]))
-+ priv->wr_speeds[i] = atoi (speedv[i]);
-+ }
-+ g_strfreev (speedv);
-+ }
-+
-+ priv->max_wrt = wspeed;
-+ priv->max_rd = rspeed;
-+
-+ return BRASERO_BURN_OK;
-+}
-+
-+static BraseroBurnResult
-+brasero_medium_get_page_2A_max_speed (BraseroMedium *self,
-+ BRASEROCDROM *cdrom)
-+{
-+ BraseroMediumPrivate *priv;
-+ int result;
-+ int rspeed, wspeed;
-+ char *wspeeds;
-+
-+ BRASERO_BURN_LOG ("Retrieving speed (2A max)");
-+
-+ priv = BRASERO_MEDIUM_PRIVATE (self);
-+
-+ result = brasero_cdrom_get_read_write_speed (cdrom, &rspeed, &wspeed, &wspeeds);
-+
-+ if (result != 0) {
-+ BRASERO_BURN_LOG ("MODE SENSE failed");
-+ return BRASERO_BURN_ERR;
-+ }
-+
-+ priv->max_rd = rspeed;
-+ priv->max_wrt = wspeed;
-+
-+ g_free (wspeeds);
-+
-+ return BRASERO_BURN_OK;
-+}
-+
-+static BraseroBurnResult
-+brasero_medium_get_medium_type (BraseroMedium *self,
-+ BRASEROCDROM *cdrom)
-+{
-+ unsigned char *hdr = NULL;
-+ unsigned char *confdesc;
-+ BraseroMediumPrivate *priv;
-+ BraseroBurnResult result;
-+ int profile;
-+ int res;
-+
-+ BRASERO_BURN_LOG ("Retrieving media profile");
-+
-+ priv = BRASERO_MEDIUM_PRIVATE (self);
-+ res = brasero_cdrom_get_configuration_feature (cdrom,
-+ BRASERO_SCSI_FEAT_REAL_TIME_STREAM,
-+ &hdr);
-+ if (res != 0) {
-+ unsigned char *data = NULL;
-+ unsigned char *desc;
-+ int size;
-+
-+ BRASERO_BURN_LOG ("GET CONFIGURATION failed");
-+
-+ /* This could be a MMC1 drive since this command was
-+ * introduced in MMC2 and is supported onward. So it
-+ * has to be a CD (R/RW). The rest of the information
-+ * will be provided by read_disc_information. */
-+
-+ /* The only thing here left to determine is if that's a WRITABLE
-+ * or a REWRITABLE. To determine that information, we need to
-+ * read TocPmaAtip. It if fails that's a ROM, if it succeeds.
-+ */
-+ res = brasero_cdrom_read_atip (cdrom, &data);
-+ if (res != 0) {
-+ /* CDROM */
-+ priv->info = BRASERO_MEDIUM_CDROM;
-+ priv->type = types [1];
-+ priv->icon = icons [1];
-+ }
-+ else {
-+ /* check the size of the structure: it must be at least 8 bytes long */
-+ size = (data[0] << 8 | data[1]) - 2;
-+ if (size < 8) {
-+ if (size)
-+ g_free (data);
-+
-+ BRASERO_BURN_LOG ("READ ATIP failed (wrong size)");
-+ return BRASERO_BURN_ERR;
-+ }
-+
-+ desc = data + 4;
-+
-+ if ((desc[2] >> 6) & 1) {
-+ /* CDRW */
-+ priv->info = BRASERO_MEDIUM_CDRW;
-+ priv->type = types [3];
-+ priv->icon = icons [3];
-+ }
-+ else {
-+ /* CDR */
-+ priv->info = BRASERO_MEDIUM_CDR;
-+ priv->type = types [2];
-+ priv->icon = icons [2];
-+ }
-+
-+ g_free (data);
-+ }
-+
-+ /* retrieve the speed */
-+ result = brasero_medium_get_page_2A_max_speed (self, cdrom);
-+ return result;
-+ }
-+
-+ profile = (hdr[6] << 8 | hdr[7]);
-+
-+ switch (profile) {
-+ case BRASERO_SCSI_PROF_CDROM:
-+ priv->info = BRASERO_MEDIUM_CDROM;
-+ priv->type = types [1];
-+ priv->icon = icons [1];
-+ break;
-+
-+ case BRASERO_SCSI_PROF_CDR:
-+ priv->info = BRASERO_MEDIUM_CDR;
-+ priv->type = types [2];
-+ priv->icon = icons [2];
-+ break;
-+
-+ case BRASERO_SCSI_PROF_CDRW:
-+ priv->info = BRASERO_MEDIUM_CDRW;
-+ priv->type = types [3];
-+ priv->icon = icons [3];
-+ break;
-+
-+ case BRASERO_SCSI_PROF_DVD_ROM:
-+ priv->info = BRASERO_MEDIUM_DVD_ROM;
-+ priv->type = types [4];
-+ priv->icon = icons [4];
-+ break;
-+
-+ case BRASERO_SCSI_PROF_DVD_R:
-+ priv->info = BRASERO_MEDIUM_DVDR;
-+ priv->type = types [5];
-+ priv->icon = icons [5];
-+ break;
-+
-+ case BRASERO_SCSI_PROF_DVD_RW_RESTRICTED:
-+ priv->info = BRASERO_MEDIUM_DVDRW_RESTRICTED;
-+ priv->type = types [6];
-+ priv->icon = icons [6];
-+ break;
-+
-+ case BRASERO_SCSI_PROF_DVD_RW_SEQUENTIAL:
-+ priv->info = BRASERO_MEDIUM_DVDRW;
-+ priv->type = types [6];
-+ priv->icon = icons [6];
-+ break;
-+
-+ case BRASERO_SCSI_PROF_DVD_R_PLUS:
-+ priv->info = BRASERO_MEDIUM_DVDR_PLUS;
-+ priv->type = types [7];
-+ priv->icon = icons [7];
-+ break;
-+
-+ case BRASERO_SCSI_PROF_DVD_RW_PLUS:
-+ priv->info = BRASERO_MEDIUM_DVDRW_PLUS;
-+ priv->type = types [8];
-+ priv->icon = icons [7];
-+ break;
-+
-+ /* WARNING: these types are recognized, no more */
-+ case BRASERO_SCSI_PROF_DVD_R_PLUS_DL:
-+ priv->info = BRASERO_MEDIUM_DVDR_PLUS_DL;
-+ priv->type = types [9];
-+ priv->icon = icons [7];
-+ break;
-+
-+ case BRASERO_SCSI_PROF_DVD_RW_PLUS_DL:
-+ priv->info = BRASERO_MEDIUM_DVDRW_PLUS_DL;
-+ priv->type = types [10];
-+ priv->icon = icons [7];
-+ break;
-+
-+ case BRASERO_SCSI_PROF_DVD_R_DL_SEQUENTIAL:
-+ priv->info = BRASERO_MEDIUM_DVDR_DL;
-+ priv->type = types [11];
-+ priv->icon = icons [5];
-+ break;
-+
-+ case BRASERO_SCSI_PROF_DVD_R_DL_JUMP:
-+ priv->info = BRASERO_MEDIUM_DVDR_JUMP_DL;
-+ priv->type = types [11];
-+ priv->icon = icons [5];
-+ break;
-+
-+ case BRASERO_SCSI_PROF_DVD_RAM:
-+ priv->info = BRASERO_MEDIUM_DVD_RAM;
-+ priv->type = types [12];
-+ priv->icon = icons [8];
-+ break;
-+
-+ case BRASERO_SCSI_PROF_BD_ROM:
-+ priv->info = BRASERO_MEDIUM_BD_ROM;
-+ priv->type = types [13];
-+ priv->icon = icons [4];
-+ break;
-+
-+ case BRASERO_SCSI_PROF_BR_R_SEQUENTIAL:
-+ priv->info = BRASERO_MEDIUM_BDR;
-+ priv->type = types [14];
-+ priv->icon = icons [5];
-+ break;
-+
-+ case BRASERO_SCSI_PROF_BR_R_RANDOM:
-+ priv->info = BRASERO_MEDIUM_BDR_RANDOM;
-+ priv->type = types [14];
-+ priv->icon = icons [5];
-+ break;
-+
-+ case BRASERO_SCSI_PROF_BD_RW:
-+ priv->info = BRASERO_MEDIUM_BDRW;
-+ priv->type = types [15];
-+ priv->icon = icons [6];
-+ break;
-+
-+ case BRASERO_SCSI_PROF_NON_REMOVABLE:
-+ case BRASERO_SCSI_PROF_REMOVABLE:
-+ case BRASERO_SCSI_PROF_MO_ERASABLE:
-+ case BRASERO_SCSI_PROF_MO_WRITE_ONCE:
-+ case BRASERO_SCSI_PROF_MO_ADVANCED_STORAGE:
-+ case BRASERO_SCSI_PROF_DDCD_ROM:
-+ case BRASERO_SCSI_PROF_DDCD_R:
-+ case BRASERO_SCSI_PROF_DDCD_RW:
-+ case BRASERO_SCSI_PROF_HD_DVD_ROM:
-+ case BRASERO_SCSI_PROF_HD_DVD_R:
-+ case BRASERO_SCSI_PROF_HD_DVD_RAM:
-+ priv->info = BRASERO_MEDIUM_UNSUPPORTED;
-+ priv->icon = icons [0];
-+ g_free (hdr);
-+ return BRASERO_BURN_NOT_SUPPORTED;
-+ }
-+
-+ confdesc = hdr + 8;
-+
-+ /* try all SCSI functions to get write/read speeds in order */
-+ if (confdesc[4] >= 4) {
-+ unsigned char *stream;
-+
-+ /* means it's at least an MMC3 drive */
-+ stream = confdesc + 5;
-+ if ((stream[0] >> 1) & 1) {
-+ result = brasero_medium_get_speed_mmc3 (self, cdrom);
-+ if (result == BRASERO_BURN_OK)
-+ goto end;
-+ }
-+
-+ if ((stream[0] >> 2) & 1) {
-+ result = brasero_medium_get_page_2A_write_speed_desc (self, cdrom);
-+ if (result == BRASERO_BURN_OK)
-+ goto end;
-+ }
-+ }
-+
-+ /* fallback for speeds */
-+ result = brasero_medium_get_page_2A_max_speed (self, cdrom);
-+
-+end:
-+
-+ g_free (hdr);
-+
-+ if (result != BRASERO_BURN_OK)
-+ return result;
-+
-+ return BRASERO_BURN_OK;
-+}
-+
-+static BraseroBurnResult
-+brasero_medium_get_css_feature (BraseroMedium *self,
-+ BRASEROCDROM *cdrom)
-+{
-+ unsigned char *hdr = NULL;
-+ BraseroMediumPrivate *priv;
-+ int result;
-+ int size;
-+
-+ priv = BRASERO_MEDIUM_PRIVATE (self);
-+
-+ BRASERO_BURN_LOG ("Testing for Css encrypted media");
-+ result = brasero_cdrom_get_configuration_feature (cdrom,
-+ BRASERO_SCSI_FEAT_DVD_CSS,
-+ &hdr);
-+ if (result != 0) {
-+ g_free (hdr);
-+
-+ BRASERO_BURN_LOG ("GET CONFIGURATION failed");
-+ return BRASERO_BURN_ERR;
-+ }
-+
-+ size = 4 + (hdr[0] << 24 | hdr[1] << 16 | hdr[2] << 8 | hdr[3]);
-+
-+ if (size < 9 || hdr[12] < 4) {
-+ g_free (hdr);
-+ return BRASERO_BURN_OK;
-+ }
-+
-+ /* here we just need to see if this feature is current or not */
-+ if (hdr[11] & 1) {
-+ priv->info |= BRASERO_MEDIUM_PROTECTED;
-+ BRASERO_BURN_LOG ("media is Css protected");
-+ }
-+
-+ g_free (hdr);
-+ return BRASERO_BURN_OK;
-+}
-+
-+/**
-+ * Functions to get information about disc contents
-+ */
-+
-+static void
-+brasero_medium_set_track_type (BraseroMedium *self,
-+ BraseroMediumTrack *track,
-+ guchar control)
-+{
-+ BraseroMediumPrivate *priv;
-+
-+ priv = BRASERO_MEDIUM_PRIVATE (self);
-+
-+ if (control & BRASERO_SCSI_TRACK_COPY)
-+ track->type |= BRASERO_MEDIUM_TRACK_COPY;
-+
-+ if (!(control & BRASERO_SCSI_TRACK_DATA)) {
-+ track->type |= BRASERO_MEDIUM_TRACK_AUDIO;
-+ priv->info |= BRASERO_MEDIUM_HAS_AUDIO;
-+
-+ if (control & BRASERO_SCSI_TRACK_PREEMP)
-+ track->type |= BRASERO_MEDIUM_TRACK_PREEMP;
-+
-+ if (control & BRASERO_SCSI_TRACK_4_CHANNELS)
-+ track->type |= BRASERO_MEDIUM_TRACK_4_CHANNELS;
-+ }
-+ else {
-+ track->type |= BRASERO_MEDIUM_TRACK_DATA;
-+ priv->info |= BRASERO_MEDIUM_HAS_DATA;
-+
-+ if (control & BRASERO_SCSI_TRACK_DATA_INCREMENTAL)
-+ track->type |= BRASERO_MEDIUM_TRACK_INCREMENTAL;
-+ }
-+}
-+
-+static BraseroBurnResult
-+brasero_medium_track_volume_size (BraseroMedium *self,
-+ BraseroMediumTrack *track,
-+ BRASEROCDROM *cdrom)
-+{
-+ BraseroMediumPrivate *priv;
-+ BraseroBurnResult res;
-+ GError *error = NULL;
-+ gint64 nb_blocks;
-+
-+ if (!track)
-+ return BRASERO_BURN_ERR;
-+
-+ priv = BRASERO_MEDIUM_PRIVATE (self);
-+
-+ /* This is a special case. For DVD+RW and DVD-RW in restricted
-+ * mode, there is only one session that takes the whole disc size
-+ * once formatted. That doesn't necessarily means they have data
-+ * Note also that they are reported as complete though you can
-+ * still add data (with growisofs). It is nevertheless on the
-+ * condition that the fs is valid.
-+ * So we check if their first and only volume is valid.
-+ * That's also used when the track size is reported a 300 Kio
-+ * see below */
-+ res = brasero_volume_get_size_fd (brasero_cdrom_get_fd (cdrom),
-+ track->start,
-+ &nb_blocks,
-+ NULL);
-+ if (!res) {
-+ BRASERO_BURN_LOG ("Failed to retrieve the volume size: %s",
-+ error && error->message ?
-+ error->message:"unknown error");
-+
-+ if (error)
-+ g_error_free (error);
-+ return BRASERO_BURN_ERR;
-+ }
-+
-+ track->blocks_num = nb_blocks;
-+ return BRASERO_BURN_OK;
-+}
-+
-+static BraseroBurnResult
-+brasero_medium_track_get_info (BraseroMedium *self,
-+ BraseroMediumTrack *track,
-+ int track_num,
-+ BRASEROCDROM *cdrom)
-+{
-+ unsigned char track_info[48];
-+ BraseroMediumPrivate *priv;
-+ int result;
-+ int size;
-+ int next_wrt;
-+
-+ BRASERO_BURN_LOG ("Retrieving track information for %i", track_num);
-+
-+ priv = BRASERO_MEDIUM_PRIVATE (self);
-+
-+ /* at this point we know the type of the disc that's why we set the
-+ * size according to this type. That may help to avoid outrange address
-+ * errors. */
-+ if (BRASERO_MEDIUM_IS (priv->info, BRASERO_MEDIUM_DL|BRASERO_MEDIUM_WRITABLE))
-+ size = 48;
-+ else if (BRASERO_MEDIUM_IS (priv->info, BRASERO_MEDIUM_PLUS|BRASERO_MEDIUM_WRITABLE))
-+ size = 40;
-+ else
-+ size = 36;
-+
-+ result = brasero_cdrom_read_track_info (cdrom, track_num, track_info, size);
-+
-+ if (result != 0) {
-+ BRASERO_BURN_LOG ("READ TRACK INFO failed");
-+ return BRASERO_BURN_ERR;
-+ }
-+
-+ track->blocks_num = (track_info[24] << 24 | track_info[25] << 16 | track_info[26] << 8 | track_info[27]);
-+ track->session = (track_info[33] << 8 | track_info[3]);
-+
-+ /* Now here is a potential bug: we can write tracks (data or not)
-+ * shorter than 300 Kio /2 sec but they will be padded to reach this
-+ * floor value. That means that is blocks_num is 300 blocks that may
-+ * mean that the data length on the track is actually shorter.
-+ * So we read the volume descriptor. If it works, good otherwise
-+ * use the old value.
-+ * That's important for checksuming to have a perfect account of the
-+ * data size. */
-+ if (track->blocks_num <= 300) {
-+ BRASERO_BURN_LOG ("300 sectors size. Checking for real size");
-+ brasero_medium_track_volume_size (self, track, cdrom);
-+ }
-+
-+ next_wrt = (track_info[12] << 24 | track_info[13] << 16 | track_info[14] << 7 | track_info[15]);
-+
-+ if (next_wrt);
-+ priv->next_wr_add = next_wrt;
-+
-+ BRASERO_BURN_LOG ("Track %i (session %i): type = %i start = %llu size = %llu",
-+ track_num,
-+ track->session,
-+ track->type,
-+ track->start,
-+ track->blocks_num);
-+
-+ return BRASERO_BURN_OK;
-+}
-+
-+/**
-+ * return :
-+ * 0 when it's not possible to determine (fallback to formatted toc)
-+ * -1 for BCD
-+ * 1 for HEX */
-+static guint
-+brasero_medium_check_BCD_use (BraseroMedium *self,
-+ BRASEROCDROM *cdrom,
-+ unsigned char *desc,
-+ guint num)
-+{
-+ guint i;
-+ int size;
-+ guint leadout = 0;
-+ guint track_num = 0;
-+ gboolean use_BCD = TRUE;
-+ gboolean use_HEX = TRUE;
-+ int result;
-+ unsigned char *dptr;
-+ unsigned char track_info[48];
-+ guint start_BCD, start_LBA, track_start;
-+
-+ /* first check if all values are valid BCD numbers in the descriptors */
-+ dptr = desc;
-+ for (i = 0; i < num; i++, dptr += 11) {
-+ if ((dptr[1] >> 4) == 1 && dptr[3] <= BRASERO_SCSI_Q_SUB_CHANNEL_TRACK_START) {
-+ if (!BRASERO_IS_BCD_VALID (dptr[8])
-+ || !BRASERO_IS_BCD_VALID (dptr[9])
-+ || !BRASERO_IS_BCD_VALID (dptr[10])) {
-+ use_BCD = FALSE;
-+ break;
-+ }
-+ }
-+ else if (dptr[3] == BRASERO_SCSI_Q_SUB_CHANNEL_LEADOUT_START) {
-+ if (!BRASERO_IS_BCD_VALID (dptr[8])
-+ || !BRASERO_IS_BCD_VALID (dptr[9])
-+ || !BRASERO_IS_BCD_VALID (dptr[10])) {
-+ use_BCD = FALSE;
-+ break;
-+ }
-+ }
-+ }
-+
-+ /* then check if there are valid Hex values */
-+ dptr = desc;
-+ for (i = 0; i < num; i++, dptr += 11) {
-+ if ((dptr[i] >> 4) != 1 || dptr[3] > BRASERO_SCSI_Q_SUB_CHANNEL_TRACK_START)
-+ continue;
-+
-+ if (dptr[8] > 99
-+ || dptr[9] > 59
-+ || dptr[10] > 74) {
-+ use_HEX = FALSE;
-+ break;
-+ }
-+ }
-+
-+ if (use_BCD != use_HEX) {
-+ if (use_BCD)
-+ return -1;
-+
-+ return 1;
-+ }
-+
-+ /* To check if the drive uses BCD values or HEX values we ask for the
-+ * track information that contains also the start for the track but in
-+ * HEX values. If values are the same then it works. */
-+
-+ /* NOTE: there could be another way to do it: get first track, in LBA
-+ * and BCD it must be 150. */
-+
-+ /* First find the first track and get track start address in BCD */
-+ BRASERO_BURN_LOG ("Retrieving track information to determine number format");
-+
-+ dptr = desc;
-+ for (i = 0; i < num; i++, dptr += 11) {
-+ if ((dptr[1] >> 4) == BRASERO_SCSI_Q_SUB_CHANNEL_LEADIN_MODE5
-+ && dptr[3] == BRASERO_SCSI_Q_SUB_CHANNEL_MULTI_NEXT_SESSION) {
-+ /* store the leadout number just in case */
-+ leadout = i;
-+ continue;
-+ }
-+
-+ if ((dptr[1] >> 4) != 1 || dptr[3] > BRASERO_SCSI_Q_SUB_CHANNEL_TRACK_START)
-+ continue;
-+
-+ track_num ++;
-+
-+ start_BCD = BRASERO_MSF_TO_LBA (BRASERO_GET_BCD (dptr[8]),
-+ BRASERO_GET_BCD (dptr[9]),
-+ BRASERO_GET_BCD (dptr[10]));
-+
-+ start_LBA = BRASERO_MSF_TO_LBA (dptr[8], dptr[9], dptr[10]);
-+
-+ BRASERO_BURN_LOG ("Comparing to track information from READ TRACK INFO for track %i", track_num);
-+
-+ size = 36;
-+ start_LBA -= 150;
-+ start_BCD -= 150;
-+
-+ result = brasero_cdrom_read_track_info (cdrom,
-+ track_num,
-+ track_info,
-+ size);
-+
-+ if (result != 0) {
-+ BRASERO_BURN_LOG ("READ TRACK INFO failed");
-+ /* Fallback to formatted toc */
-+ return 0;
-+ }
-+
-+ track_start = (track_info[8] << 24 | track_info[9] << 16 | track_info[10] << 8 | track_info[11]);
-+ BRASERO_BURN_LOG ("comparing DCB %i and LBA %i to real start address %i",
-+ start_BCD, start_LBA, track_start);
-+
-+ /* try to find a conclusive match */
-+ if (track_start == start_BCD && track_start != start_LBA)
-+ return -1;
-+
-+ if (track_start == start_LBA && track_start != start_BCD)
-+ return 1;
-+ }
-+
-+ /* Our last chance, the leadout.
-+ * NOTE: no need to remove 150 sectors here. */
-+ dptr = desc + (leadout * 11);
-+ start_BCD = BRASERO_MSF_TO_LBA (BRASERO_GET_BCD (dptr[4]),
-+ BRASERO_GET_BCD (dptr[5]),
-+ BRASERO_GET_BCD (dptr[6]));
-+
-+ start_LBA = BRASERO_MSF_TO_LBA (dptr[4], dptr[5], dptr[6]);
-+
-+ BRASERO_BURN_LOG ("Comparing to track information from READ TRACK INFO for leadout");
-+
-+ size = 36;
-+
-+ /* leadout number is number of tracks + 1 */
-+ result = brasero_cdrom_read_track_info (cdrom,
-+ track_num + 1,
-+ track_info,
-+ size);
-+
-+ if (result != 0) {
-+ BRASERO_BURN_LOG ("READ TRACK INFO failed for leadout");
-+ /* Fallback to formatted toc */
-+ return 0;
-+ }
-+
-+ track_start = (track_info[8] << 24 | track_info[9] << 16 | track_info[10] << 8 | track_info[11]);
-+ BRASERO_BURN_LOG ("comparing DCB %i and LBA %i to real start address %i",
-+ start_BCD, start_LBA, track_start);
-+
-+ /* try to find a conclusive match */
-+ if (track_start == start_BCD && track_start != start_LBA)
-+ return -1;
-+
-+ if (track_start == start_LBA && track_start != start_BCD)
-+ return 1;
-+
-+ /* fallback to formatted toc */
-+ return 0;
-+}
-+
-+/**
-+ * The reason why we use this perhaps more lengthy method is that with
-+ * multisession discs, the first track is reported to be two sectors shorter
-+ * than it should. As I don't know why and since the following works we use
-+ * this one. */
-+static BraseroBurnResult
-+brasero_medium_get_CD_sessions_info (BraseroMedium *self,
-+ BRASEROCDROM *cdrom)
-+{
-+ gint use_bcd;
-+ GSList *iter;
-+ int num, i, size, res;
-+ gint leadout_start = 0;
-+ BraseroMediumPrivate *priv;
-+ unsigned char *desc;
-+ unsigned char *toc = NULL;
-+
-+ BRASERO_BURN_LOG ("Reading Raw Toc");
-+
-+ priv = BRASERO_MEDIUM_PRIVATE (self);
-+
-+ res = brasero_cdrom_read_toc_raw (cdrom, 0, &toc);
-+ if (res != 0) {
-+ BRASERO_BURN_LOG ("READ TOC failed");
-+ return BRASERO_BURN_ERR;
-+ }
-+
-+ size = (toc[0] << 8 | toc[1]) - 2;
-+ num = size / 11;
-+
-+ BRASERO_BURN_LOG ("%i track(s) found", num);
-+
-+ desc = toc + 4;
-+ use_bcd = brasero_medium_check_BCD_use (self, cdrom, desc, num);
-+ if (!use_bcd) {
-+ g_free (toc);
-+
-+ BRASERO_BURN_LOG ("Fallback to formatted toc");
-+ return BRASERO_BURN_ERR;
-+ }
-+
-+ if (use_bcd > 0)
-+ use_bcd = 0;
-+
-+ if (use_bcd) {
-+ BRASERO_BURN_LOG ("Using BCD format");
-+ }
-+ else {
-+ BRASERO_BURN_LOG ("Using HEX format");
-+ }
-+
-+ for (i = 0; i < num; i++, desc += 11) {
-+ BraseroMediumTrack *track;
-+
-+ track = NULL;
-+ if ((desc[1] >> 4) == 1 && desc[3] <= BRASERO_SCSI_Q_SUB_CHANNEL_TRACK_START) {
-+ track = g_new0 (BraseroMediumTrack, 1);
-+ track->session = desc[0];
-+
-+ brasero_medium_set_track_type (self, track, (desc[1] & 15));
-+ if (use_bcd)
-+ track->start = BRASERO_MSF_TO_LBA (BRASERO_GET_BCD (desc[8]),
-+ BRASERO_GET_BCD (desc[9]),
-+ BRASERO_GET_BCD (desc[10]));
-+ else
-+ track->start = BRASERO_MSF_TO_LBA (desc[8],
-+ desc[9],
-+ desc[10]);
-+
-+ track->start -= 150;
-+
-+ /* if there are tracks and the last previously added track is in
-+ * the same session then set the size */
-+ if (priv->tracks) {
-+ BraseroMediumTrack *last_track;
-+
-+ last_track = priv->tracks->data;
-+ if (last_track->session == track->session)
-+ last_track->blocks_num = track->start - last_track->start;
-+ }
-+
-+ priv->tracks = g_slist_prepend (priv->tracks, track);
-+ }
-+ else if (desc[3] == BRASERO_SCSI_Q_SUB_CHANNEL_LEADOUT_START) {
-+ /* NOTE: the leadout session is first in the list. So if
-+ * we have tracks in the list set the last session track
-+ * size when we reach a new leadout (and therefore a new
-+ * session). */
-+
-+ if (priv->tracks) {
-+ BraseroMediumTrack *last_track;
-+
-+ last_track = priv->tracks->data;
-+ last_track->blocks_num = leadout_start - last_track->start;
-+ }
-+
-+ if (use_bcd)
-+ leadout_start = BRASERO_MSF_TO_LBA (BRASERO_GET_BCD (desc[8]),
-+ BRASERO_GET_BCD (desc[9]),
-+ BRASERO_GET_BCD (desc[10]));
-+ else
-+ leadout_start = BRASERO_MSF_TO_LBA (desc[8],
-+ desc[9],
-+ desc[10]);
-+ leadout_start -= 150;
-+ }
-+ }
-+
-+ if (priv->tracks) {
-+ BraseroMediumTrack *last_track;
-+
-+ /* set the last found track size */
-+ last_track = priv->tracks->data;
-+ last_track->blocks_num = leadout_start - last_track->start;
-+ }
-+
-+ /* Add a leadout */
-+ if (!(priv->info & BRASERO_MEDIUM_CLOSED)) {
-+ BraseroMediumTrack *track;
-+
-+ /* we shouldn't request info on leadout if the disc is closed */
-+ track = g_new0 (BraseroMediumTrack, 1);
-+ priv->tracks = g_slist_prepend (priv->tracks, track);
-+ track->start = leadout_start;
-+ track->type = BRASERO_MEDIUM_TRACK_LEADOUT;
-+
-+ brasero_medium_track_get_info (self, track, g_slist_length (priv->tracks), cdrom);
-+ }
-+
-+ priv->tracks = g_slist_reverse (priv->tracks);
-+
-+ for (iter = priv->tracks; iter; iter = iter->next) {
-+ BraseroMediumTrack *track;
-+
-+ track = iter->data;
-+
-+ /* check for tracks less that 300 sectors */
-+ if (track->blocks_num <= 300 && track->type != BRASERO_MEDIUM_TRACK_LEADOUT) {
-+ BRASERO_BURN_LOG ("300 sectors size. Checking for real size");
-+ brasero_medium_track_volume_size (self, track, cdrom);
-+ }
-+
-+ BRASERO_BURN_LOG ("Track %i: type = %i start = %llu size = %llu",
-+ g_slist_index (priv->tracks, track),
-+ track->type,
-+ track->start,
-+ track->blocks_num);
-+ }
-+
-+ g_free (toc);
-+ return BRASERO_BURN_OK;
-+}
-+
-+/**
-+ * NOTE: for DVD-R multisession we lose 28688 blocks for each session
-+ * so the capacity is the addition of all session sizes + 28688 for each
-+ * For all multisession DVD-/+R and CDR-RW the remaining size is given
-+ * in the leadout. One exception though with DVD+/-RW.
-+ */
-+
-+static void
-+brasero_medium_add_DVD_plus_RW_leadout (BraseroMedium *self,
-+ gint32 start)
-+{
-+ BraseroMediumTrack *leadout;
-+ BraseroMediumPrivate *priv;
-+
-+ priv = BRASERO_MEDIUM_PRIVATE (self);
-+
-+ leadout = g_new0 (BraseroMediumTrack, 1);
-+ priv->tracks = g_slist_append (priv->tracks, leadout);
-+
-+ leadout->start = start;
-+ leadout->type = BRASERO_MEDIUM_TRACK_LEADOUT;
-+
-+ /* we fabricate the leadout here. We don't really need one in
-+ * fact since it is always at the last sector whatever the
-+ * amount of data written. So we need in fact to read the file
-+ * system and get the last sector from it. Hopefully it won't be
-+ * buggy */
-+ priv->next_wr_add = 0;
-+
-+ leadout->blocks_num = priv->block_num;
-+ if (g_slist_length (priv->tracks) > 1) {
-+ BraseroMediumTrack *track;
-+
-+ track = priv->tracks->data;
-+ leadout->blocks_num -= ((track->blocks_num > 300) ? track->blocks_num : 300);
-+ }
-+ BRASERO_BURN_LOG ("Adding fabricated leadout start = %llu length = %llu",
-+ leadout->start,
-+ leadout->blocks_num);
-+}
-+
-+static BraseroBurnResult
-+brasero_medium_get_sessions_info (BraseroMedium *self,
-+ BRASEROCDROM *cdrom)
-+{
-+ int num, i, size, res;
-+ gint32 tstart;
-+ unsigned char *toc = NULL;
-+ unsigned char *desc;
-+ BraseroMediumPrivate *priv;
-+
-+ BRASERO_BURN_LOG ("Reading Toc");
-+
-+ priv = BRASERO_MEDIUM_PRIVATE (self);
-+ res = brasero_cdrom_read_toc_formatted (cdrom, 0, &toc);
-+ if (res != 0) {
-+ g_free (toc);
-+
-+ BRASERO_BURN_LOG ("READ TOC failed");
-+ return BRASERO_BURN_ERR;
-+ }
-+
-+ size = (toc[0] << 8 | toc[1]) - 2;
-+
-+ num = size / 8; /* Each track description is 8 bytes. */
-+
-+ BRASERO_BURN_LOG ("%i track(s) found", num);
-+
-+ for (desc = toc + 4, i = 0; i < num; i ++, desc += 8) {
-+ BraseroMediumTrack *track;
-+
-+ if (desc[2] == BRASERO_SCSI_TRACK_LEADOUT_START)
-+ break;
-+
-+ tstart = (desc[4] << 24 | desc[5] << 16 | desc[6] << 8 | desc[7]);
-+
-+ track = g_new0 (BraseroMediumTrack, 1);
-+ priv->tracks = g_slist_prepend (priv->tracks, track);
-+ track->start = tstart;
-+
-+ /* we shouldn't request info on a track if the disc is closed */
-+ brasero_medium_track_get_info (self,
-+ track,
-+ g_slist_length (priv->tracks),
-+ cdrom);
-+
-+ if ((desc[1] & 15) & BRASERO_SCSI_TRACK_COPY)
-+ track->type |= BRASERO_MEDIUM_TRACK_COPY;
-+
-+ if (!((desc[1] & 15) & BRASERO_SCSI_TRACK_DATA)) {
-+ track->type |= BRASERO_MEDIUM_TRACK_AUDIO;
-+ priv->info |= BRASERO_MEDIUM_HAS_AUDIO;
-+
-+ if ((desc[1] & 15) & BRASERO_SCSI_TRACK_PREEMP)
-+ track->type |= BRASERO_MEDIUM_TRACK_PREEMP;
-+
-+ if ((desc[1] & 15) & BRASERO_SCSI_TRACK_4_CHANNELS)
-+ track->type |= BRASERO_MEDIUM_TRACK_4_CHANNELS;
-+ }
-+ else if (BRASERO_MEDIUM_IS (priv->info, BRASERO_MEDIUM_DVDRW_PLUS)
-+ || BRASERO_MEDIUM_IS (priv->info, BRASERO_MEDIUM_DVDRW_RESTRICTED)) {
-+ BraseroBurnResult result;
-+
-+ /* a special case for these two kinds of media (DVD+RW)
-+ * which have only one track: the first. */
-+ result = brasero_medium_track_volume_size (self,
-+ track,
-+ cdrom);
-+ if (result == BRASERO_BURN_OK) {
-+ track->type |= BRASERO_MEDIUM_TRACK_DATA;
-+ priv->info |= BRASERO_MEDIUM_HAS_DATA;
-+
-+ priv->next_wr_add = 0;
-+
-+ if ((desc[1] & 15) & BRASERO_SCSI_TRACK_DATA_INCREMENTAL)
-+ track->type |= BRASERO_MEDIUM_TRACK_INCREMENTAL;
-+ }
-+ else {
-+ priv->tracks = g_slist_remove (priv->tracks, track);
-+ g_free (track);
-+
-+ priv->info |= BRASERO_MEDIUM_BLANK;
-+ priv->info &= ~BRASERO_MEDIUM_CLOSED;
-+ }
-+ }
-+ else {
-+ track->type |= BRASERO_MEDIUM_TRACK_DATA;
-+ priv->info |= BRASERO_MEDIUM_HAS_DATA;
-+
-+ if ((desc[1] & 15) & BRASERO_SCSI_TRACK_DATA_INCREMENTAL)
-+ track->type |= BRASERO_MEDIUM_TRACK_INCREMENTAL;
-+ }
-+ }
-+
-+ /* put the tracks in the right order */
-+ priv->tracks = g_slist_reverse (priv->tracks);
-+ tstart = (desc[4] << 24 | desc[5] << 16 | desc[6] << 8 | desc[7]);
-+
-+ if (BRASERO_MEDIUM_IS (priv->info, BRASERO_MEDIUM_DVDRW_PLUS)
-+ || BRASERO_MEDIUM_IS (priv->info, BRASERO_MEDIUM_DVDRW_RESTRICTED))
-+ brasero_medium_add_DVD_plus_RW_leadout (self, tstart);
-+ else if (!(priv->info & BRASERO_MEDIUM_CLOSED)) {
-+ BraseroMediumTrack *track;
-+
-+ /* we shouldn't request info on leadout if the disc is closed
-+ * (except for DVD+/- (restricted) RW (see above) */
-+ track = g_new0 (BraseroMediumTrack, 1);
-+ priv->tracks = g_slist_append (priv->tracks, track);
-+ track->start = tstart;
-+ track->type = BRASERO_MEDIUM_TRACK_LEADOUT;
-+
-+ brasero_medium_track_get_info (self,
-+ track,
-+ g_slist_length (priv->tracks),
-+ cdrom);
-+ }
-+
-+ g_free (toc);
-+
-+ return BRASERO_BURN_OK;
-+}
-+
-+static BraseroBurnResult
-+brasero_medium_get_contents (BraseroMedium *self,
-+ BRASEROCDROM *cdrom)
-+{
-+ BraseroBurnResult result;
-+ int res;
-+ BraseroMediumPrivate *priv;
-+ unsigned char buf[32];
-+
-+ BRASERO_BURN_LOG ("Retrieving media status");
-+
-+ priv = BRASERO_MEDIUM_PRIVATE (self);
-+
-+ res = brasero_cdrom_read_disc_information_std (cdrom, buf);
-+ if (res != 0) {
-+ BRASERO_BURN_LOG ("READ DISC INFORMATION failed");
-+ return BRASERO_BURN_ERR;
-+ }
-+
-+ if (buf[2] & 16) /* Erasable */
-+ priv->info |= BRASERO_MEDIUM_REWRITABLE;
-+
-+ if ((buf[2] & 3) == 0) { /* Empty disc */
-+ BraseroMediumTrack *track;
-+
-+ BRASERO_BURN_LOG ("Empty media");
-+
-+ priv->info |= BRASERO_MEDIUM_BLANK;
-+ priv->block_size = 2048;
-+
-+ if (BRASERO_MEDIUM_IS (priv->info, BRASERO_MEDIUM_DVDRW_PLUS)
-+ || BRASERO_MEDIUM_IS (priv->info, BRASERO_MEDIUM_DVDRW_RESTRICTED))
-+ brasero_medium_add_DVD_plus_RW_leadout (self, 0);
-+ else {
-+ track = g_new0 (BraseroMediumTrack, 1);
-+ track->start = 0;
-+ track->type = BRASERO_MEDIUM_TRACK_LEADOUT;
-+ priv->tracks = g_slist_prepend (priv->tracks, track);
-+
-+ brasero_medium_track_get_info (self,
-+ track,
-+ 1,
-+ cdrom);
-+ }
-+ goto end;
-+ }
-+
-+ if (buf[2] & 1) { /* Appendable */
-+ priv->info |= BRASERO_MEDIUM_APPENDABLE;
-+ BRASERO_BURN_LOG ("Appendable media");
-+ }
-+ else if (buf[2] & 2) { /* Complete */
-+ priv->info |= BRASERO_MEDIUM_CLOSED;
-+ BRASERO_BURN_LOG ("Closed media");
-+ }
-+
-+ if (priv->info & BRASERO_MEDIUM_CD) {
-+ result = brasero_medium_get_CD_sessions_info (self, cdrom);
-+ if (result != BRASERO_BURN_OK)
-+ result = brasero_medium_get_sessions_info (self, cdrom);
-+ }
-+ else
-+ result = brasero_medium_get_sessions_info (self, cdrom);
-+
-+ if (result != BRASERO_BURN_OK)
-+ goto end;
-+
-+end:
-+
-+ return BRASERO_BURN_OK;
-+}
-+
-+static void
-+brasero_medium_init_real (BraseroMedium *object, BRASEROCDROM *cdrom)
-+{
-+ gchar *name;
-+ BraseroBurnResult result;
-+ BraseroMediumPrivate *priv;
-+
-+ priv = BRASERO_MEDIUM_PRIVATE (object);
-+
-+ name = nautilus_burn_drive_get_name_for_display (priv->drive);
-+ BRASERO_BURN_LOG ("Initializing information for medium in %s", name);
-+ g_free (name);
-+
-+ result = brasero_medium_get_medium_type (object, cdrom);
-+ if (result != BRASERO_BURN_OK)
-+ return;
-+
-+ brasero_medium_get_capacity_by_type (object, cdrom);
-+
-+ result = brasero_medium_get_contents (object, cdrom);
-+ if (result != BRASERO_BURN_OK)
-+ return;
-+
-+ /* assume that css feature is only for DVD-ROM which might be wrong but
-+ * some drives wrongly reports that css is enabled for blank DVD+R/W */
-+ if (BRASERO_MEDIUM_IS (priv->info, (BRASERO_MEDIUM_DVD|BRASERO_MEDIUM_ROM)))
-+ brasero_medium_get_css_feature (object, cdrom);
-+
-+ BRASERO_BURN_LOG_DISC_TYPE (priv->info, "media is ");
-+}
-+
-+static void
-+brasero_medium_try_open (BraseroMedium *self)
-+{
-+ const gchar *path;
-+ BRASEROCDROM *cdrom;
-+ BraseroMediumPrivate *priv;
-+
-+ priv = BRASERO_MEDIUM_PRIVATE (self);
-+ path = nautilus_burn_drive_get_device (priv->drive);
-+
-+ BRASERO_BURN_LOG ("Trying to create BRASERCDROM for device %s", path);
-+ cdrom = brasero_cdrom_new (path);
-+ if (cdrom == NULL) {
-+ BRASERO_BURN_LOG ("Creation failed");
-+ return;
-+ }
-+
-+ BRASERO_BURN_LOG ("Creation succeeded");
-+ brasero_medium_init_real (self, cdrom);
-+ brasero_cdrom_free (cdrom);
-+}
-+
-+static void
-+brasero_medium_init (BraseroMedium *object)
-+{
-+ BraseroMediumPrivate *priv;
-+
-+ priv = BRASERO_MEDIUM_PRIVATE (object);
-+ priv->next_wr_add = -1;
-+
-+ /* we can't do anything here since properties haven't been set yet */
-+}
-+
-+static void
-+brasero_medium_finalize (GObject *object)
-+{
-+ BraseroMediumPrivate *priv;
-+
-+ priv = BRASERO_MEDIUM_PRIVATE (object);
-+
-+ if (priv->retry_id) {
-+ g_source_remove (priv->retry_id);
-+ priv->retry_id = 0;
-+ }
-+
-+ g_free (priv->rd_speeds);
-+ priv->rd_speeds = NULL;
-+
-+ g_free (priv->wr_speeds);
-+ priv->wr_speeds = NULL;
-+
-+ g_slist_foreach (priv->tracks, (GFunc) g_free, NULL);
-+ g_slist_free (priv->tracks);
-+ priv->tracks = NULL;
-+
-+ nautilus_burn_drive_unref (priv->drive);
-+ priv->drive = NULL;
-+
-+ G_OBJECT_CLASS (parent_class)->finalize (object);
-+}
-+
-+static void
-+brasero_medium_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
-+{
-+ BraseroMediumPrivate *priv;
-+
-+ g_return_if_fail (BRASERO_IS_MEDIUM (object));
-+
-+ priv = BRASERO_MEDIUM_PRIVATE (object);
-+
-+ switch (prop_id)
-+ {
-+ case PROP_DRIVE:
-+ priv->drive = g_value_get_object (value);
-+ nautilus_burn_drive_ref (priv->drive);
-+ brasero_medium_try_open (BRASERO_MEDIUM (object));
-+ break;
-+ default:
-+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-+ break;
-+ }
-+}
-+
-+static void
-+brasero_medium_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
-+{
-+ BraseroMediumPrivate *priv;
-+
-+ g_return_if_fail (BRASERO_IS_MEDIUM (object));
-+
-+ priv = BRASERO_MEDIUM_PRIVATE (object);
-+
-+ switch (prop_id)
-+ {
-+ case PROP_DRIVE:
-+ nautilus_burn_drive_ref (priv->drive);
-+ g_value_set_object (value, priv->drive);
-+ break;
-+ default:
-+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-+ break;
-+ }
-+}
-+
-+static void
-+brasero_medium_class_init (BraseroMediumClass *klass)
-+{
-+ GObjectClass* object_class = G_OBJECT_CLASS (klass);
-+ parent_class = G_OBJECT_CLASS (g_type_class_peek_parent (klass));
-+
-+ g_type_class_add_private (klass, sizeof (BraseroMediumPrivate));
-+
-+ object_class->finalize = brasero_medium_finalize;
-+ object_class->set_property = brasero_medium_set_property;
-+ object_class->get_property = brasero_medium_get_property;
-+
-+ g_object_class_install_property (object_class,
-+ PROP_DRIVE,
-+ g_param_spec_object ("drive",
-+ "drive",
-+ "drive in which medium is inserted",
-+ NAUTILUS_BURN_TYPE_DRIVE,
-+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
-+}
-+
-+GType
-+brasero_medium_get_type (void)
-+{
-+ static GType our_type = 0;
-+
-+ if (our_type == 0)
-+ {
-+ static const GTypeInfo our_info =
-+ {
-+ sizeof (BraseroMediumClass), /* class_size */
-+ (GBaseInitFunc) NULL, /* base_init */
-+ (GBaseFinalizeFunc) NULL, /* base_finalize */
-+ (GClassInitFunc) brasero_medium_class_init, /* class_init */
-+ (GClassFinalizeFunc) NULL, /* class_finalize */
-+ NULL /* class_data */,
-+ sizeof (BraseroMedium), /* instance_size */
-+ 0, /* n_preallocs */
-+ (GInstanceInitFunc) brasero_medium_init, /* instance_init */
-+ NULL /* value_table */
-+ };
-+
-+ our_type = g_type_register_static (G_TYPE_OBJECT, "BraseroMedium",
-+ &our_info, 0);
-+ }
-+
-+ return our_type;
-+}
-+
-+BraseroMedium *
-+brasero_medium_new (NautilusBurnDrive *drive)
-+{
-+ g_return_val_if_fail (drive != NULL, NULL);
-+ return BRASERO_MEDIUM (g_object_new (BRASERO_TYPE_MEDIUM,
-+ "drive", drive,
-+ NULL));
-+}