diff options
Diffstat (limited to 'sysutils/brasero/files/patch-src_burn-medium.c')
-rw-r--r-- | sysutils/brasero/files/patch-src_burn-medium.c | 2073 |
1 files changed, 0 insertions, 2073 deletions
diff --git a/sysutils/brasero/files/patch-src_burn-medium.c b/sysutils/brasero/files/patch-src_burn-medium.c deleted file mode 100644 index accb659e2..000000000 --- a/sysutils/brasero/files/patch-src_burn-medium.c +++ /dev/null @@ -1,2073 +0,0 @@ ---- src/burn-medium.c.orig 2008-01-27 10:25:14.000000000 -0500 -+++ src/burn-medium.c 2008-02-06 01:55:21.000000000 -0500 -@@ -1,2070 +0,0 @@ --/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ --/* -- * brasero -- * Copyright (C) Philippe Rouquier 2007 <bonfire-app@wanadoo.fr> -- * -- * 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 <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 "scsi-mmc1.h" --#include "scsi-mmc2.h" --#include "scsi-mmc3.h" --#include "scsi-spc1.h" --#include "scsi-utils.h" --#include "scsi-mode-pages.h" --#include "scsi-status-page.h" --#include "scsi-q-subchannel.h" --#include "scsi-dvd-structures.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)) -- --/** -- * Try to open the drive exclusively but don't block; if drive can't be opened -- * exclusively then retry every second until we're shut or the drive state -- * changes to not busy. -- * No exclusive at the moment since when the medium is mounted we can't use excl -- */ -- --#define OPEN_FLAGS O_RDONLY /*|O_EXCL */|O_NONBLOCK --#define BUSY_RETRY_TIME 1000 -- --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, -- int fd, -- BraseroScsiErrCode *code) --{ -- BraseroScsiAtipData *atip_data = NULL; -- BraseroMediumPrivate *priv; -- BraseroScsiResult result; -- int size = 0; -- -- priv = BRASERO_MEDIUM_PRIVATE (self); -- -- BRASERO_BURN_LOG ("Retrieving capacity from atip"); -- -- result = brasero_mmc1_read_atip (fd, -- &atip_data, -- &size, -- NULL); -- -- if (result != BRASERO_SCSI_OK) { -- BRASERO_BURN_LOG ("READ ATIP failed (scsi error)"); -- return BRASERO_BURN_ERR; -- } -- -- /* 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; -- } -- -- priv->block_num = BRASERO_MSF_TO_LBA (atip_data->desc->leadout_mn, -- atip_data->desc->leadout_sec, -- atip_data->desc->leadout_frame); -- 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, -- int fd, -- BraseroScsiErrCode *code) --{ -- BraseroScsiFormatCapacitiesHdr *hdr = NULL; -- BraseroScsiMaxCapacityDesc *current; -- BraseroMediumPrivate *priv; -- BraseroScsiResult result; -- gint size; -- -- BRASERO_BURN_LOG ("Retrieving format capacity"); -- -- priv = BRASERO_MEDIUM_PRIVATE (self); -- result = brasero_mmc2_read_format_capacities (fd, -- &hdr, -- &size, -- code); -- if (result != BRASERO_SCSI_OK) { -- g_free (hdr); -- -- BRASERO_BURN_LOG ("READ FORMAT CAPACITIES failed"); -- return BRASERO_BURN_ERR; -- } -- -- current = hdr->max_caps; -- -- /* see if the media is already formatted */ -- if (current->type != BRASERO_SCSI_DESC_FORMATTED) { -- int i, max; -- BraseroScsiFormattableCapacityDesc *desc; -- -- max = (hdr->len - -- sizeof (BraseroScsiMaxCapacityDesc)) / -- sizeof (BraseroScsiFormattableCapacityDesc); -- -- desc = hdr->desc; -- for (i = 0; i < max; i ++, desc ++) { -- /* search for the correct descriptor */ -- if (BRASERO_MEDIUM_IS (priv->info, BRASERO_MEDIUM_DVDRW_PLUS)) { -- if (desc->format_type == BRASERO_SCSI_DVDRW_PLUS) { -- priv->block_num = BRASERO_GET_32 (desc->blocks_num); -- priv->block_size = BRASERO_GET_24 (desc->type_param); -- -- /* that can happen */ -- if (!priv->block_size) -- priv->block_size = 2048; -- break; -- } -- } -- else if (desc->format_type == BRASERO_SCSI_BLOCK_SIZE_DEFAULT_AND_DB) { -- priv->block_num = BRASERO_GET_32 (desc->blocks_num); -- priv->block_size = BRASERO_GET_24 (desc->type_param); -- break; -- } -- } -- } -- else { -- priv->block_num = BRASERO_GET_32 (current->blocks_num); -- priv->block_size = BRASERO_GET_24 (current->block_size); -- } -- -- 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, -- int fd, -- BraseroScsiErrCode *code) --{ -- 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, fd, code); -- else -- brasero_medium_get_capacity_DVD_RW (self, fd, code); -- -- return BRASERO_BURN_OK; --} -- --/** -- * Functions to retrieve the speed -- */ -- --static BraseroBurnResult --brasero_medium_get_speed_mmc3 (BraseroMedium *self, -- int fd, -- BraseroScsiErrCode *code) --{ -- int size; -- int num_desc, i; -- gint max_rd, max_wrt; -- BraseroScsiResult result; -- BraseroMediumPrivate *priv; -- BraseroScsiWrtSpdDesc *desc; -- BraseroScsiGetPerfData *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_mmc3_get_performance_wrt_spd_desc (fd, -- &wrt_perf, -- &size, -- code); -- -- if (result != BRASERO_SCSI_OK) { -- g_free (wrt_perf); -- -- BRASERO_BURN_LOG ("GET PERFORMANCE failed"); -- return BRASERO_BURN_ERR; -- } -- -- num_desc = (size - sizeof (BraseroScsiGetPerfHdr)) / -- sizeof (BraseroScsiWrtSpdDesc); -- -- 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 = (BraseroScsiWrtSpdDesc*) &wrt_perf->data; -- for (i = 0; i < num_desc; i ++, desc ++) { -- priv->rd_speeds [i] = BRASERO_GET_32 (desc->rd_speed); -- priv->wr_speeds [i] = BRASERO_GET_32 (desc->wr_speed); -- -- 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, -- int fd, -- BraseroScsiErrCode *code) --{ -- BraseroScsiStatusPage *page_2A = NULL; -- BraseroScsiStatusWrSpdDesc *desc; -- BraseroScsiModeData *data = NULL; -- BraseroMediumPrivate *priv; -- BraseroScsiResult result; -- gint desc_num, i; -- gint max_wrt = 0; -- gint max_num; -- int size = 0; -- -- BRASERO_BURN_LOG ("Retrieving speed (2A speeds)"); -- -- priv = BRASERO_MEDIUM_PRIVATE (self); -- result = brasero_spc1_mode_sense_get_page (fd, -- BRASERO_SPC_PAGE_STATUS, -- &data, -- &size, -- code); -- if (result != BRASERO_SCSI_OK) { -- g_free (data); -- -- BRASERO_BURN_LOG ("MODE SENSE failed"); -- return BRASERO_BURN_ERR; -- } -- -- page_2A = (BraseroScsiStatusPage *) &data->page; -- -- /* FIXME: the following is not necessarily true */ -- if (size < sizeof (BraseroScsiStatusPage)) { -- g_free (data); -- -- BRASERO_BURN_LOG ("wrong size in page"); -- return BRASERO_BURN_ERR; -- } -- -- desc_num = BRASERO_GET_16 (page_2A->wr_speed_desc_num); -- max_num = size - -- sizeof (BraseroScsiStatusPage) - -- sizeof (BraseroScsiModeHdr); -- max_num /= sizeof (BraseroScsiWrtSpdDesc); -- -- if (max_num < 0) -- max_num = 0; -- -- if (desc_num > max_num) -- desc_num = max_num; -- -- priv->wr_speeds = g_new0 (gint, desc_num + 1); -- desc = page_2A->wr_spd_desc; -- for (i = 0; i < desc_num; i ++, desc ++) { -- priv->wr_speeds [i] = BRASERO_GET_16 (desc->speed); -- max_wrt = MAX (max_wrt, priv->wr_speeds [i]); -- } -- -- if (!max_wrt) -- priv->max_wrt = BRASERO_GET_16 (page_2A->wr_max_speed); -- else -- priv->max_wrt = max_wrt; -- -- priv->max_rd = BRASERO_GET_16 (page_2A->rd_max_speed); -- g_free (data); -- -- return BRASERO_BURN_OK; --} -- --static BraseroBurnResult --brasero_medium_get_page_2A_max_speed (BraseroMedium *self, -- int fd, -- BraseroScsiErrCode *code) --{ -- BraseroScsiStatusPage *page_2A = NULL; -- BraseroScsiModeData *data = NULL; -- BraseroMediumPrivate *priv; -- BraseroScsiResult result; -- int size = 0; -- -- BRASERO_BURN_LOG ("Retrieving speed (2A max)"); -- -- priv = BRASERO_MEDIUM_PRIVATE (self); -- -- result = brasero_spc1_mode_sense_get_page (fd, -- BRASERO_SPC_PAGE_STATUS, -- &data, -- &size, -- code); -- if (result != BRASERO_SCSI_OK) { -- g_free (data); -- -- BRASERO_BURN_LOG ("MODE SENSE failed"); -- return BRASERO_BURN_ERR; -- } -- -- page_2A = (BraseroScsiStatusPage *) &data->page; -- -- if (size < 0x14) { -- g_free (data); -- -- BRASERO_BURN_LOG ("wrong page size"); -- return BRASERO_BURN_ERR; -- } -- -- priv->max_rd = BRASERO_GET_16 (page_2A->rd_max_speed); -- priv->max_wrt = BRASERO_GET_16 (page_2A->wr_max_speed); -- -- g_free (data); -- return BRASERO_BURN_OK; --} -- --static BraseroBurnResult --brasero_medium_get_medium_type (BraseroMedium *self, -- int fd, -- BraseroScsiErrCode *code) --{ -- BraseroScsiGetConfigHdr *hdr = NULL; -- BraseroMediumPrivate *priv; -- BraseroScsiResult result; -- int size; -- -- BRASERO_BURN_LOG ("Retrieving media profile"); -- -- priv = BRASERO_MEDIUM_PRIVATE (self); -- result = brasero_mmc2_get_configuration_feature (fd, -- BRASERO_SCSI_FEAT_REAL_TIME_STREAM, -- &hdr, -- &size, -- code); -- if (result != BRASERO_SCSI_OK) { -- BraseroScsiAtipData *data = NULL; -- int size = 0; -- -- 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. -- * No need to set error code since we consider that it's a ROM -- * if a failure happens. */ -- result = brasero_mmc1_read_atip (fd, -- &data, -- &size, -- NULL); -- if (result != BRASERO_SCSI_OK) { -- /* 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 */ -- if (size < 8) { -- if (size) -- g_free (data); -- -- BRASERO_BURN_LOG ("READ ATIP failed (wrong size)"); -- return BRASERO_BURN_ERR; -- } -- -- if (data->desc->erasable) { -- /* 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, -- fd, -- code); -- return result; -- } -- -- switch (BRASERO_GET_16 (hdr->current_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; -- } -- -- /* try all SCSI functions to get write/read speeds in order */ -- if (hdr->desc->add_len >= sizeof (BraseroScsiRTStreamDesc)) { -- BraseroScsiRTStreamDesc *stream; -- -- /* means it's at least an MMC3 drive */ -- stream = (BraseroScsiRTStreamDesc *) hdr->desc->data; -- if (stream->wrt_spd) { -- result = brasero_medium_get_speed_mmc3 (self, fd, code); -- if (result == BRASERO_BURN_OK) -- goto end; -- } -- -- if (stream->mp2a) { -- result = brasero_medium_get_page_2A_write_speed_desc (self, fd, code); -- if (result == BRASERO_BURN_OK) -- goto end; -- } -- } -- -- /* fallback for speeds */ -- result = brasero_medium_get_page_2A_max_speed (self, fd, code); -- --end: -- -- g_free (hdr); -- -- if (result != BRASERO_BURN_OK) -- return result; -- -- return BRASERO_BURN_OK; --} -- --static BraseroBurnResult --brasero_medium_get_css_feature (BraseroMedium *self, -- int fd, -- BraseroScsiErrCode *code) --{ -- BraseroScsiGetConfigHdr *hdr = NULL; -- BraseroMediumPrivate *priv; -- BraseroScsiResult result; -- int size; -- -- priv = BRASERO_MEDIUM_PRIVATE (self); -- -- BRASERO_BURN_LOG ("Testing for Css encrypted media"); -- result = brasero_mmc2_get_configuration_feature (fd, -- BRASERO_SCSI_FEAT_DVD_CSS, -- &hdr, -- &size, -- code); -- if (result != BRASERO_SCSI_OK) { -- g_free (hdr); -- -- BRASERO_BURN_LOG ("GET CONFIGURATION failed"); -- return BRASERO_BURN_ERR; -- } -- -- if (hdr->desc->add_len < sizeof (BraseroScsiDVDCssDesc)) { -- g_free (hdr); -- return BRASERO_BURN_OK; -- } -- -- /* here we just need to see if this feature is current or not */ -- if (hdr->desc->current) { -- 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, -- int fd) --{ -- 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 (fd, -- 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, -- int fd, -- BraseroScsiErrCode *code) --{ -- BraseroScsiTrackInfo track_info; -- BraseroMediumPrivate *priv; -- BraseroScsiResult result; -- int size; -- -- 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_mmc1_read_track_info (fd, -- track_num, -- &track_info, -- &size, -- code); -- -- if (result != BRASERO_SCSI_OK) { -- BRASERO_BURN_LOG ("READ TRACK INFO failed"); -- return BRASERO_BURN_ERR; -- } -- -- track->blocks_num = BRASERO_GET_32 (track_info.track_size); -- track->session = BRASERO_SCSI_SESSION_NUM (track_info); -- -- /* 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, fd); -- } -- -- if (track_info.next_wrt_address_valid) -- priv->next_wr_add = BRASERO_GET_32 (track_info.next_wrt_address); -- -- 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, -- int fd, -- BraseroScsiRawTocDesc *desc, -- guint num, -- BraseroScsiErrCode *code) --{ -- guint i; -- int size; -- guint leadout = 0; -- guint track_num = 0; -- gboolean use_BCD = TRUE; -- gboolean use_HEX = TRUE; -- BraseroScsiResult result; -- BraseroScsiTrackInfo track_info; -- guint start_BCD, start_LBA, track_start; -- -- /* first check if all values are valid BCD numbers in the descriptors */ -- for (i = 0; i < num; i++) { -- if (desc [i].adr == 1 && desc [i].point <= BRASERO_SCSI_Q_SUB_CHANNEL_TRACK_START) { -- if (!BRASERO_IS_BCD_VALID (desc [i].p_min) -- || !BRASERO_IS_BCD_VALID (desc [i].p_sec) -- || !BRASERO_IS_BCD_VALID (desc [i].p_frame)) { -- use_BCD = FALSE; -- break; -- } -- } -- else if (desc [i].point == BRASERO_SCSI_Q_SUB_CHANNEL_LEADOUT_START) { -- if (!BRASERO_IS_BCD_VALID (desc [i].p_min) -- || !BRASERO_IS_BCD_VALID (desc [i].p_sec) -- || !BRASERO_IS_BCD_VALID (desc [i].p_frame)) { -- use_BCD = FALSE; -- break; -- } -- } -- } -- -- /* then check if there are valid Hex values */ -- for (i = 0; i < num; i++) { -- if (desc [i].adr != 1 || desc [i].point > BRASERO_SCSI_Q_SUB_CHANNEL_TRACK_START) -- continue; -- -- if (desc [i].p_min > 99 -- || desc [i].p_sec > 59 -- || desc [i].p_frame > 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"); -- -- for (i = 0; i < num; i++) { -- if (desc [i].adr == BRASERO_SCSI_Q_SUB_CHANNEL_LEADIN_MODE5 -- && desc [i].point == BRASERO_SCSI_Q_SUB_CHANNEL_MULTI_NEXT_SESSION) { -- /* store the leadout number just in case */ -- leadout = i; -- continue; -- } -- -- if (desc [i].adr != 1 || desc [i].point > BRASERO_SCSI_Q_SUB_CHANNEL_TRACK_START) -- continue; -- -- track_num ++; -- -- start_BCD = BRASERO_MSF_TO_LBA (BRASERO_GET_BCD (desc [i].p_min), -- BRASERO_GET_BCD (desc [i].p_sec), -- BRASERO_GET_BCD (desc [i].p_frame)); -- -- start_LBA = BRASERO_MSF_TO_LBA (desc [i].p_min, -- desc [i].p_sec, -- desc [i].p_frame); -- -- 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_mmc1_read_track_info (fd, -- track_num, -- &track_info, -- &size, -- code); -- -- if (result != BRASERO_SCSI_OK) { -- BRASERO_BURN_LOG ("READ TRACK INFO failed"); -- /* Fallback to formatted toc */ -- return 0; -- } -- -- track_start = BRASERO_GET_32 (track_info.start_lba); -- 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. */ -- start_BCD = BRASERO_MSF_TO_LBA (BRASERO_GET_BCD (desc [leadout].min), -- BRASERO_GET_BCD (desc [leadout].sec), -- BRASERO_GET_BCD (desc [leadout].frame)); -- -- start_LBA = BRASERO_MSF_TO_LBA (desc [leadout].min, -- desc [leadout].sec, -- desc [leadout].frame); -- -- BRASERO_BURN_LOG ("Comparing to track information from READ TRACK INFO for leadout"); -- -- size = 36; -- -- /* leadout number is number of tracks + 1 */ -- result = brasero_mmc1_read_track_info (fd, -- track_num + 1, -- &track_info, -- &size, -- code); -- -- if (result != BRASERO_SCSI_OK) { -- BRASERO_BURN_LOG ("READ TRACK INFO failed for leadout"); -- /* Fallback to formatted toc */ -- return 0; -- } -- -- track_start = BRASERO_GET_32 (track_info.start_lba); -- 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, -- int fd, -- BraseroScsiErrCode *code) --{ -- gint use_bcd; -- GSList *iter; -- int num, i, size; -- gint leadout_start = 0; -- BraseroScsiResult result; -- BraseroMediumPrivate *priv; -- BraseroScsiRawTocDesc *desc; -- BraseroScsiRawTocData *toc = NULL; -- -- BRASERO_BURN_LOG ("Reading Raw Toc"); -- -- priv = BRASERO_MEDIUM_PRIVATE (self); -- -- size = 0; -- result = brasero_mmc1_read_toc_raw (fd, -- 0, -- &toc, -- &size, -- code); -- if (result != BRASERO_SCSI_OK) { -- BRASERO_BURN_LOG ("READ TOC failed"); -- return BRASERO_BURN_ERR; -- } -- -- num = (size - sizeof (BraseroScsiRawTocData)) / -- sizeof (BraseroScsiRawTocDesc); -- -- BRASERO_BURN_LOG ("%i track(s) found", num); -- -- desc = toc->desc; -- use_bcd = brasero_medium_check_BCD_use (self, fd, desc, num, code); -- 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 ++) { -- BraseroMediumTrack *track; -- -- track = NULL; -- if (desc->adr == 1 && desc->point <= BRASERO_SCSI_Q_SUB_CHANNEL_TRACK_START) { -- track = g_new0 (BraseroMediumTrack, 1); -- track->session = desc->session_num; -- -- brasero_medium_set_track_type (self, track, desc->control); -- if (use_bcd) -- track->start = BRASERO_MSF_TO_LBA (BRASERO_GET_BCD (desc->p_min), -- BRASERO_GET_BCD (desc->p_sec), -- BRASERO_GET_BCD (desc->p_frame)); -- else -- track->start = BRASERO_MSF_TO_LBA (desc->p_min, -- desc->p_sec, -- desc->p_frame); -- -- 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->point == 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->p_min), -- BRASERO_GET_BCD (desc->p_sec), -- BRASERO_GET_BCD (desc->p_frame)); -- else -- leadout_start = BRASERO_MSF_TO_LBA (desc->p_min, -- desc->p_sec, -- desc->p_frame); -- 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), fd, code); -- } -- -- 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, fd); -- } -- -- 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, -- int fd, -- BraseroScsiErrCode *code) --{ -- int num, i, size; -- BraseroScsiResult result; -- BraseroScsiTocDesc *desc; -- BraseroMediumPrivate *priv; -- BraseroScsiFormattedTocData *toc = NULL; -- -- BRASERO_BURN_LOG ("Reading Toc"); -- -- priv = BRASERO_MEDIUM_PRIVATE (self); -- result = brasero_mmc1_read_toc_formatted (fd, -- 0, -- &toc, -- &size, -- code); -- if (result != BRASERO_SCSI_OK) { -- g_free (toc); -- -- BRASERO_BURN_LOG ("READ TOC failed"); -- return BRASERO_BURN_ERR; -- } -- -- num = (size - sizeof (BraseroScsiFormattedTocData)) / -- sizeof (BraseroScsiTocDesc); -- -- BRASERO_BURN_LOG ("%i track(s) found", num); -- -- desc = toc->desc; -- for (i = 0; i < num; i ++, desc ++) { -- BraseroMediumTrack *track; -- -- if (desc->track_num == BRASERO_SCSI_TRACK_LEADOUT_START) -- break; -- -- track = g_new0 (BraseroMediumTrack, 1); -- priv->tracks = g_slist_prepend (priv->tracks, track); -- track->start = BRASERO_GET_32 (desc->track_start); -- -- /* 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), -- fd, -- code); -- -- if (desc->control & BRASERO_SCSI_TRACK_COPY) -- track->type |= BRASERO_MEDIUM_TRACK_COPY; -- -- if (!(desc->control & BRASERO_SCSI_TRACK_DATA)) { -- track->type |= BRASERO_MEDIUM_TRACK_AUDIO; -- priv->info |= BRASERO_MEDIUM_HAS_AUDIO; -- -- if (desc->control & BRASERO_SCSI_TRACK_PREEMP) -- track->type |= BRASERO_MEDIUM_TRACK_PREEMP; -- -- if (desc->control & 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, -- fd); -- if (result == BRASERO_BURN_OK) { -- track->type |= BRASERO_MEDIUM_TRACK_DATA; -- priv->info |= BRASERO_MEDIUM_HAS_DATA; -- -- priv->next_wr_add = 0; -- -- if (desc->control & 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->control & 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); -- -- 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, BRASERO_GET_32 (desc->track_start)); -- 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 = BRASERO_GET_32 (desc->track_start); -- track->type = BRASERO_MEDIUM_TRACK_LEADOUT; -- -- brasero_medium_track_get_info (self, -- track, -- g_slist_length (priv->tracks), -- fd, -- code); -- } -- -- g_free (toc); -- -- return BRASERO_BURN_OK; --} -- --static BraseroBurnResult --brasero_medium_get_contents (BraseroMedium *self, -- int fd, -- BraseroScsiErrCode *code) --{ -- int size; -- BraseroScsiResult result; -- BraseroMediumPrivate *priv; -- BraseroScsiDiscInfoStd *info = NULL; -- -- BRASERO_BURN_LOG ("Retrieving media status"); -- -- priv = BRASERO_MEDIUM_PRIVATE (self); -- -- result = brasero_mmc1_read_disc_information_std (fd, -- &info, -- &size, -- code); -- if (result != BRASERO_SCSI_OK) { -- g_free (info); -- -- BRASERO_BURN_LOG ("READ DISC INFORMATION failed"); -- return BRASERO_BURN_ERR; -- } -- -- if (info->erasable) -- priv->info |= BRASERO_MEDIUM_REWRITABLE; -- -- if (info->status == BRASERO_SCSI_DISC_EMPTY) { -- 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, -- fd, -- code); -- } -- goto end; -- } -- -- if (info->status == BRASERO_SCSI_DISC_INCOMPLETE) { -- priv->info |= BRASERO_MEDIUM_APPENDABLE; -- BRASERO_BURN_LOG ("Appendable media"); -- } -- else if (info->status == BRASERO_SCSI_DISC_FINALIZED) { -- priv->info |= BRASERO_MEDIUM_CLOSED; -- BRASERO_BURN_LOG ("Closed media"); -- } -- -- if (priv->info & BRASERO_MEDIUM_CD) { -- result = brasero_medium_get_CD_sessions_info (self, fd, code); -- if (result != BRASERO_BURN_OK) -- result = brasero_medium_get_sessions_info (self, fd, code); -- } -- else -- result = brasero_medium_get_sessions_info (self, fd, code); -- -- if (result != BRASERO_BURN_OK) -- goto end; -- --end: -- -- g_free (info); -- return BRASERO_BURN_OK; --} -- --static void --brasero_medium_init_real (BraseroMedium *object, int fd) --{ -- gchar *name; -- BraseroBurnResult result; -- BraseroMediumPrivate *priv; -- BraseroScsiErrCode code = 0; -- -- 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, fd, &code); -- if (result != BRASERO_BURN_OK) -- return; -- -- brasero_medium_get_capacity_by_type (object, fd, &code); -- -- result = brasero_medium_get_contents (object, fd, &code); -- 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, fd, &code); -- -- BRASERO_BURN_LOG_DISC_TYPE (priv->info, "media is "); --} -- --static gboolean --brasero_medium_retry_open (gpointer object) --{ -- int fd; -- const gchar *path; -- BraseroMedium *self; -- BraseroMediumPrivate *priv; -- -- self = BRASERO_MEDIUM (object); -- priv = BRASERO_MEDIUM_PRIVATE (object); -- path = nautilus_burn_drive_get_device (priv->drive); -- -- BRASERO_BURN_LOG ("Retrying to open device %s", path); -- fd = open (path, OPEN_FLAGS); -- if (fd < 0) { -- if (errno == EBUSY -- || errno == EAGAIN -- || errno == EWOULDBLOCK) { -- BRASERO_BURN_LOG ("Device busy"); -- /* we'll retry in a second */ -- return TRUE; -- } -- -- BRASERO_BURN_LOG ("Open () failed"); -- priv->info = BRASERO_MEDIUM_UNSUPPORTED; -- priv->retry_id = 0; -- return FALSE; -- } -- -- BRASERO_BURN_LOG ("Open () succeeded\n"); -- priv->info = BRASERO_MEDIUM_NONE; -- priv->icon = icons [0]; -- -- priv->retry_id = 0; -- -- brasero_medium_init_real (self, fd); -- close (fd); -- -- return FALSE; --} -- --static void --brasero_medium_try_open (BraseroMedium *self) --{ -- int fd; -- const gchar *path; -- BraseroMediumPrivate *priv; -- -- priv = BRASERO_MEDIUM_PRIVATE (self); -- path = nautilus_burn_drive_get_device (priv->drive); -- -- /* the drive might be busy (a burning is going on) so we don't block -- * but we re-try to open it every second */ -- BRASERO_BURN_LOG ("Trying to open device %s", path); -- fd = open (path, OPEN_FLAGS); -- if (fd < 0) { -- if (errno == EAGAIN -- || errno == EWOULDBLOCK -- || errno == EBUSY) { -- BRASERO_BURN_LOG ("Device busy"); -- priv->info = BRASERO_MEDIUM_BUSY; -- priv->icon = icons [0]; -- -- priv->retry_id = g_timeout_add (BUSY_RETRY_TIME, -- brasero_medium_retry_open, -- self); -- } -- -- BRASERO_BURN_LOG ("Open () failed"); -- return; -- } -- -- BRASERO_BURN_LOG ("Open () succeeded"); -- brasero_medium_init_real (self, fd); -- close (fd); --} -- --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)); --} |