static gboolean volume_is_blank (GVolume *volume) { BraseroMediumMonitor *monitor; BraseroMedium *medium; BraseroDrive *drive; gchar *device; gboolean is_blank; is_blank = FALSE; device = g_volume_get_identifier (volume, G_VOLUME_IDENTIFIER_KIND_UNIX_DEVICE); if (!device) return FALSE; DEBUG_PRINT ("Got device: %s\n", device); monitor = brasero_medium_monitor_get_default (); drive = brasero_medium_monitor_get_drive (monitor, device); g_object_unref (monitor); g_free (device); if (drive == NULL) return FALSE; medium = brasero_drive_get_medium (drive); is_blank = (brasero_medium_get_status (medium) & BRASERO_MEDIUM_BLANK); g_object_unref (drive); return is_blank; }
static void tool_dialog_run (BraseroToolDialog *dialog, GtkWindow *toplevel, NautilusMenuItem *item) { char *device_path; BraseroDrive *drive; BraseroMediumMonitor *monitor; device_path = g_object_get_data (G_OBJECT (item), "drive_device_path"); if (!device_path) { g_warning ("Drive device path not specified"); return; } monitor = brasero_medium_monitor_get_default (); drive = brasero_medium_monitor_get_drive (monitor, device_path); g_object_unref (monitor); if (drive) { brasero_tool_dialog_set_medium (BRASERO_TOOL_DIALOG (dialog), brasero_drive_get_medium (drive)); g_object_unref (drive); } /* Get the icon for the window */ if (toplevel) gtk_window_set_icon_name (GTK_WINDOW (dialog), gtk_window_get_icon_name (toplevel)); else gtk_window_set_icon_name (GTK_WINDOW (dialog), "brasero"); gtk_dialog_run (GTK_DIALOG (dialog)); gtk_widget_destroy (GTK_WIDGET (dialog)); }
gboolean sj_metadata_helper_check_media (const char *cdrom, GError **error) { #ifndef USE_TOTEM_PL_PARSER BraseroMediumMonitor *monitor; BraseroMedium *medium; BraseroDrive *drive; /* This initialize the library if it isn't done yet */ monitor = brasero_medium_monitor_get_default (); if (brasero_medium_monitor_is_probing (monitor)) { /* FIXME: would be nicer to only check if "cdrom" is being probed, * but libbrasero doesn't seem to have an API for that */ g_set_error (error, SJ_ERROR, SJ_ERROR_CD_BUSY, _("Cannot read CD: %s"), _("Devices haven't been all probed yet")); return FALSE; } drive = brasero_medium_monitor_get_drive (monitor, cdrom); if (drive == NULL) { return FALSE; } medium = brasero_drive_get_medium (drive); g_object_unref (drive); if (!medium || !BRASERO_MEDIUM_VALID (brasero_medium_get_status (medium))) { char *msg; SjError err; if (access (cdrom, W_OK) == 0) { msg = g_strdup_printf (_("Device '%s' does not contain any media"), cdrom); err = SJ_ERROR_CD_NO_MEDIA; } else { msg = g_strdup_printf (_("Device '%s' could not be opened. Check the access permissions on the device."), cdrom); err = SJ_ERROR_CD_PERMISSION_ERROR; } g_set_error (error, SJ_ERROR, err, _("Cannot read CD: %s"), msg); g_free (msg); return FALSE; } #else GError *totem_error = NULL; totem_cd_detect_type (cdrom, &totem_error); if (totem_error != NULL) { g_set_error (error, SJ_ERROR, SJ_ERROR_CD_NO_MEDIA, _("Cannot read CD: %s"), totem_error->message); g_error_free (totem_error); return FALSE; } #endif /* !USE_TOTEM_PL_PARSER */ return TRUE; }
static gpointer brasero_dvdcss_write_image_thread (gpointer data) { guchar buf [DVDCSS_BLOCK_SIZE * BRASERO_DVDCSS_I_BLOCKS]; BraseroScrambledSectorRange *range = NULL; BraseroMedium *medium = NULL; BraseroVolFile *files = NULL; dvdcss_handle *handle = NULL; BraseroDrive *drive = NULL; BraseroDvdcssPrivate *priv; gint64 written_sectors = 0; BraseroDvdcss *self = data; BraseroTrack *track = NULL; guint64 remaining_sectors; FILE *output_fd = NULL; BraseroVolSrc *vol; gint64 volume_size; GQueue *map = NULL; brasero_job_set_use_average_rate (BRASERO_JOB (self), TRUE); brasero_job_set_current_action (BRASERO_JOB (self), BRASERO_BURN_ACTION_ANALYSING, _("Retrieving DVD keys"), FALSE); brasero_job_start_progress (BRASERO_JOB (self), FALSE); priv = BRASERO_DVDCSS_PRIVATE (self); /* get the contents of the DVD */ brasero_job_get_current_track (BRASERO_JOB (self), &track); drive = brasero_track_disc_get_drive (BRASERO_TRACK_DISC (track)); vol = brasero_volume_source_open_file (brasero_drive_get_device (drive), &priv->error); files = brasero_volume_get_files (vol, 0, NULL, NULL, NULL, &priv->error); brasero_volume_source_close (vol); if (!files) goto end; medium = brasero_drive_get_medium (drive); brasero_medium_get_data_size (medium, NULL, &volume_size); if (volume_size == -1) { priv->error = g_error_new (BRASERO_BURN_ERROR, BRASERO_BURN_ERROR_GENERAL, _("The size of the volume could not be retrieved")); goto end; } /* create a handle/open DVD */ handle = dvdcss_open (brasero_drive_get_device (drive)); if (!handle) { priv->error = g_error_new (BRASERO_BURN_ERROR, BRASERO_BURN_ERROR_GENERAL, _("Video DVD could not be opened")); goto end; } /* look through the files to get the ranges of encrypted sectors * and cache the CSS keys while at it. */ map = g_queue_new (); if (!brasero_dvdcss_create_scrambled_sectors_map (self, drive, map, handle, files, &priv->error)) goto end; BRASERO_JOB_LOG (self, "DVD map created (keys retrieved)"); g_queue_sort (map, brasero_dvdcss_sort_ranges, NULL); brasero_volume_file_free (files); files = NULL; if (dvdcss_seek (handle, 0, DVDCSS_NOFLAGS) < 0) { BRASERO_JOB_LOG (self, "Error initial seeking"); priv->error = g_error_new (BRASERO_BURN_ERROR, BRASERO_BURN_ERROR_GENERAL, _("Error while reading video DVD (%s)"), dvdcss_error (handle)); goto end; } brasero_job_set_current_action (BRASERO_JOB (self), BRASERO_BURN_ACTION_DRIVE_COPY, _("Copying video DVD"), FALSE); brasero_job_start_progress (BRASERO_JOB (self), TRUE); remaining_sectors = volume_size; range = g_queue_pop_head (map); if (brasero_job_get_fd_out (BRASERO_JOB (self), NULL) != BRASERO_BURN_OK) { gchar *output = NULL; brasero_job_get_image_output (BRASERO_JOB (self), &output, NULL); output_fd = fopen (output, "w"); if (!output_fd) { priv->error = g_error_new_literal (BRASERO_BURN_ERROR, BRASERO_BURN_ERROR_GENERAL, g_strerror (errno)); g_free (output); goto end; } g_free (output); } while (remaining_sectors) { gint flag; guint64 num_blocks, data_size; if (priv->cancel) break; num_blocks = BRASERO_DVDCSS_I_BLOCKS; /* see if we are approaching the end of the dvd */ if (num_blocks > remaining_sectors) num_blocks = remaining_sectors; /* see if we need to update the key */ if (!range || written_sectors < range->start) { /* this is in a non scrambled sectors range */ flag = DVDCSS_NOFLAGS; /* we don't want to mix scrambled and non scrambled sectors */ if (range && written_sectors + num_blocks > range->start) num_blocks = range->start - written_sectors; } else { /* this is in a scrambled sectors range */ flag = DVDCSS_READ_DECRYPT; /* see if we need to update the key */ if (written_sectors == range->start) { int pos; pos = dvdcss_seek (handle, written_sectors, DVDCSS_SEEK_KEY); if (pos < 0) { BRASERO_JOB_LOG (self, "Error seeking"); priv->error = g_error_new (BRASERO_BURN_ERROR, BRASERO_BURN_ERROR_GENERAL, _("Error while reading video DVD (%s)"), dvdcss_error (handle)); break; } } /* we don't want to mix scrambled and non scrambled sectors * NOTE: range->end address is the next non scrambled sector */ if (written_sectors + num_blocks > range->end) num_blocks = range->end - written_sectors; if (written_sectors + num_blocks == range->end) { /* update to get the next range of scrambled sectors */ g_free (range); range = g_queue_pop_head (map); } } num_blocks = dvdcss_read (handle, buf, num_blocks, flag); if (num_blocks < 0) { BRASERO_JOB_LOG (self, "Error reading"); priv->error = g_error_new (BRASERO_BURN_ERROR, BRASERO_BURN_ERROR_GENERAL, _("Error while reading video DVD (%s)"), dvdcss_error (handle)); break; } data_size = num_blocks * DVDCSS_BLOCK_SIZE; if (output_fd) { if (fwrite (buf, 1, data_size, output_fd) != data_size) { int errsv = errno; priv->error = g_error_new (BRASERO_BURN_ERROR, BRASERO_BURN_ERROR_GENERAL, _("Data could not be written (%s)"), g_strerror (errsv)); break; } } else { BraseroBurnResult result; result = brasero_dvdcss_write_sector_to_fd (self, buf, data_size); if (result != BRASERO_BURN_OK) break; } written_sectors += num_blocks; remaining_sectors -= num_blocks; brasero_job_set_written_track (BRASERO_JOB (self), written_sectors * DVDCSS_BLOCK_SIZE); } end: if (range) g_free (range); if (handle) dvdcss_close (handle); if (files) brasero_volume_file_free (files); if (output_fd) fclose (output_fd); if (map) { g_queue_foreach (map, (GFunc) g_free, NULL); g_queue_free (map); } if (!priv->cancel) priv->thread_id = g_idle_add (brasero_dvdcss_thread_finished, self); /* End thread */ g_mutex_lock (priv->mutex); priv->thread = NULL; g_cond_signal (priv->cond); g_mutex_unlock (priv->mutex); g_thread_exit (NULL); return NULL; }
static GList * nautilus_disc_burn_get_file_items (NautilusMenuProvider *provider, GtkWidget *window, GList *selection) { GList *items = NULL; NautilusMenuItem *item; NautilusFileInfo *file_info; GFile *file; GMount *mount; GVolume *volume; GDrive *drive; char *mime_type; gboolean is_iso; DEBUG_PRINT ("Getting file items\n"); if (!selection || selection->next != NULL) { return NULL; } file_info = NAUTILUS_FILE_INFO (selection->data); if (nautilus_file_info_is_gone (file_info)) { return NULL; } file = nautilus_file_info_get_location (file_info); if (file == NULL) { DEBUG_PRINT ("No file found\n"); return NULL; } mime_type = nautilus_file_info_get_mime_type (file_info); DEBUG_PRINT ("Mime type: %s\n", mime_type); if (! mime_type) { g_object_unref (file); return NULL; } is_iso = (strcmp (mime_type, "application/x-iso-image") == 0) || (strcmp (mime_type, "application/x-cd-image") == 0) || (strcmp (mime_type, "application/x-cue") == 0) || (strcmp (mime_type, "application/x-toc") == 0) || (strcmp (mime_type, "application/x-cdrdao-toc") == 0); if (is_iso) { /* Whether or not this file is local is not a problem */ item = nautilus_menu_item_new ("NautilusDiscBurn::write_iso", _("_Write to Disc…"), _("Write disc image to a CD or DVD"), "media-optical-data-new"); g_object_set_data (G_OBJECT (item), "file_info", file_info); g_object_set_data (G_OBJECT (item), "window", window); g_signal_connect (item, "activate", G_CALLBACK (write_iso_activate_cb), window); items = g_list_append (items, item); } /* * We handle two cases here. The selection is: * A) a volume * B) a drive * * This is because there is very little distinction between * the two for CD/DVD media */ drive = NULL; volume = NULL; mount = nautilus_file_info_get_mount (file_info); if (mount != NULL) { drive = g_mount_get_drive (mount); volume = g_mount_get_volume (mount); } else { char *uri = g_file_get_uri (file); DEBUG_PRINT ("Mount not found: %s\n", uri); g_free (uri); } if (drive == NULL && volume != NULL) { /* case A */ drive = g_volume_get_drive (volume); } else if (volume == NULL && drive != NULL) { /* case B */ volume = drive_get_first_volume (drive); if (volume == NULL) { DEBUG_PRINT ("Volume not found\n"); } } if (drive != NULL && volume != NULL && drive_is_cd_device (drive) && ! volume_is_blank (volume)) { char *device_path; BraseroMediumMonitor *monitor; BraseroDrive *bdrive; BraseroMedium *medium; BraseroMedia media; BraseroTrackType *type; /* Reminder: the following is not needed since it is already * called in drive_is_cd_device (). * ensure_initialized(); */ device_path = g_volume_get_identifier (volume, G_VOLUME_IDENTIFIER_KIND_UNIX_DEVICE); monitor = brasero_medium_monitor_get_default (); bdrive = brasero_medium_monitor_get_drive (monitor, device_path); g_object_unref (monitor); medium = brasero_drive_get_medium (bdrive); media = brasero_medium_get_status (medium); g_object_unref (bdrive); type = brasero_track_type_new (); brasero_track_type_set_has_medium (type); brasero_track_type_set_medium_type (type, media); if (brasero_burn_library_input_supported (type) == BRASERO_BURN_OK) { /* user may want to copy it ... */ item = nautilus_menu_item_new ("NautilusDiscBurn::copy_disc", _("_Copy Disc…"), _("Create a copy of this CD or DVD"), "media-optical-copy"); g_object_set_data (G_OBJECT (item), "file_info", file_info); g_object_set_data (G_OBJECT (item), "window", window); g_object_set_data_full (G_OBJECT (item), "drive_device_path", g_strdup (device_path), g_free); g_signal_connect (item, "activate", G_CALLBACK (copy_disc_activate_cb), window); items = g_list_append (items, item); } brasero_track_type_free (type); if (brasero_burn_library_get_media_capabilities (media) & BRASERO_MEDIUM_REWRITABLE) { /* ... or if it's a rewritable medium to blank it ... */ item = nautilus_menu_item_new ("NautilusDiscBurn::blank_disc", _("_Blank Disc…"), _("Blank this CD or DVD"), "media-optical-blank"); g_object_set_data (G_OBJECT (item), "file_info", file_info); g_object_set_data (G_OBJECT (item), "window", window); g_object_set_data_full (G_OBJECT (item), "drive_device_path", g_strdup (device_path), g_free); g_signal_connect (item, "activate", G_CALLBACK (blank_disc_activate_cb), window); items = g_list_append (items, item); } /* - library should be able to checksum * - disc must have a data session */ if (brasero_burn_library_can_checksum () && (media & BRASERO_MEDIUM_HAS_DATA)) { /* ... or verify medium. */ item = nautilus_menu_item_new ("NautilusDiscBurn::check_disc", _("_Check Disc…"), _("Check the data integrity on this CD or DVD"), NULL); g_object_set_data (G_OBJECT (item), "file_info", file_info); g_object_set_data (G_OBJECT (item), "window", window); g_object_set_data_full (G_OBJECT (item), "drive_device_path", g_strdup (device_path), g_free); g_signal_connect (item, "activate", G_CALLBACK (check_disc_activate_cb), window); items = g_list_append (items, item); } g_free (device_path); } g_object_unref (file); if (drive != NULL) { g_object_unref (drive); } if (volume != NULL) { g_object_unref (volume); } g_free (mime_type); DEBUG_PRINT ("Items returned\n"); return items; }
static BraseroBurnResult brasero_readom_set_argv (BraseroProcess *process, GPtrArray *argv, GError **error) { BraseroBurnResult result = FALSE; BraseroTrackType *output = NULL; BraseroImageFormat format; BraseroJobAction action; BraseroReadom *readom; BraseroMedium *medium; BraseroDrive *drive; BraseroTrack *track; BraseroMedia media; gchar *outfile_arg; gchar *dev_str; readom = BRASERO_READOM (process); /* This is a kind of shortcut */ brasero_job_get_action (BRASERO_JOB (process), &action); if (action == BRASERO_JOB_ACTION_SIZE) return brasero_readom_get_size (readom, error); g_ptr_array_add (argv, g_strdup ("readom")); brasero_job_get_current_track (BRASERO_JOB (readom), &track); drive = brasero_track_disc_get_drive (BRASERO_TRACK_DISC (track)); if (!brasero_drive_get_device (drive)) return BRASERO_BURN_ERR; dev_str = g_strdup_printf ("dev=%s", brasero_drive_get_device (drive)); g_ptr_array_add (argv, dev_str); g_ptr_array_add (argv, g_strdup ("-nocorr")); medium = brasero_drive_get_medium (drive); media = brasero_medium_get_status (medium); output = brasero_track_type_new (); brasero_job_get_output_type (BRASERO_JOB (readom), output); format = brasero_track_type_get_image_format (output); brasero_track_type_free (output); if ((media & BRASERO_MEDIUM_DVD) && format != BRASERO_IMAGE_FORMAT_BIN) { g_set_error (error, BRASERO_BURN_ERROR, BRASERO_BURN_ERROR_GENERAL, _("An internal error occurred")); return BRASERO_BURN_ERR; } if (format == BRASERO_IMAGE_FORMAT_CLONE) { /* NOTE: with this option the sector size is 2448 * because it is raw96 (2352+96) otherwise it is 2048 */ g_ptr_array_add (argv, g_strdup ("-clone")); } else if (format == BRASERO_IMAGE_FORMAT_BIN) { g_ptr_array_add (argv, g_strdup ("-noerror")); /* don't do it for clone since we need the entire disc */ result = brasero_readom_argv_set_iso_boundary (readom, argv, error); if (result != BRASERO_BURN_OK) return result; } else BRASERO_JOB_NOT_SUPPORTED (readom); if (brasero_job_get_fd_out (BRASERO_JOB (readom), NULL) != BRASERO_BURN_OK) { gchar *image; if (format != BRASERO_IMAGE_FORMAT_CLONE && format != BRASERO_IMAGE_FORMAT_BIN) BRASERO_JOB_NOT_SUPPORTED (readom); result = brasero_job_get_image_output (BRASERO_JOB (readom), &image, NULL); if (result != BRASERO_BURN_OK) return result; outfile_arg = g_strdup_printf ("-f=%s", image); g_ptr_array_add (argv, outfile_arg); g_free (image); } else if (format == BRASERO_IMAGE_FORMAT_BIN) { outfile_arg = g_strdup ("-f=-"); g_ptr_array_add (argv, outfile_arg); } else /* unfortunately raw images can't be piped out */ BRASERO_JOB_NOT_SUPPORTED (readom); brasero_job_set_use_average_rate (BRASERO_JOB (process), TRUE); return BRASERO_BURN_OK; }
static BraseroBurnResult brasero_readom_get_size (BraseroReadom *self, GError **error) { goffset blocks; GValue *value = NULL; BraseroTrack *track = NULL; BraseroTrackType *output = NULL; output = brasero_track_type_new (); brasero_job_get_output_type (BRASERO_JOB (self), output); if (!brasero_track_type_get_has_image (output)) { brasero_track_type_free (output); return BRASERO_BURN_ERR; } brasero_job_get_current_track (BRASERO_JOB (self), &track); brasero_track_tag_lookup (track, BRASERO_TRACK_MEDIUM_ADDRESS_START_TAG, &value); if (value) { guint64 start, end; /* we were given an address to start */ start = g_value_get_uint64 (value); /* get the length now */ value = NULL; brasero_track_tag_lookup (track, BRASERO_TRACK_MEDIUM_ADDRESS_END_TAG, &value); end = g_value_get_uint64 (value); blocks = end - start; } else if (brasero_track_disc_get_track_num (BRASERO_TRACK_DISC (track)) > 0) { BraseroDrive *drive; BraseroMedium *medium; drive = brasero_track_disc_get_drive (BRASERO_TRACK_DISC (track)); medium = brasero_drive_get_medium (drive); brasero_medium_get_track_space (medium, brasero_track_disc_get_track_num (BRASERO_TRACK_DISC (track)), NULL, &blocks); } else if (brasero_track_type_get_image_format (output) == BRASERO_IMAGE_FORMAT_BIN) { BraseroDrive *drive; BraseroMedium *medium; drive = brasero_track_disc_get_drive (BRASERO_TRACK_DISC (track)); medium = brasero_drive_get_medium (drive); brasero_medium_get_last_data_track_space (medium, NULL, &blocks); } else brasero_track_get_size (track, &blocks, NULL); if (brasero_track_type_get_image_format (output) == BRASERO_IMAGE_FORMAT_BIN) { brasero_job_set_output_size_for_current_track (BRASERO_JOB (self), blocks, blocks * 2048ULL); } else if (brasero_track_type_get_image_format (output) == BRASERO_IMAGE_FORMAT_CLONE) { brasero_job_set_output_size_for_current_track (BRASERO_JOB (self), blocks, blocks * 2448ULL); } else { brasero_track_type_free (output); return BRASERO_BURN_NOT_SUPPORTED; } brasero_track_type_free (output); /* no need to go any further */ return BRASERO_BURN_NOT_RUNNING; }
static BraseroBurnResult brasero_readom_argv_set_iso_boundary (BraseroReadom *readom, GPtrArray *argv, GError **error) { goffset nb_blocks; BraseroTrack *track; GValue *value = NULL; BraseroTrackType *output = NULL; brasero_job_get_current_track (BRASERO_JOB (readom), &track); output = brasero_track_type_new (); brasero_job_get_output_type (BRASERO_JOB (readom), output); brasero_track_tag_lookup (track, BRASERO_TRACK_MEDIUM_ADDRESS_START_TAG, &value); if (value) { guint64 start, end; /* we were given an address to start */ start = g_value_get_uint64 (value); /* get the length now */ value = NULL; brasero_track_tag_lookup (track, BRASERO_TRACK_MEDIUM_ADDRESS_END_TAG, &value); end = g_value_get_uint64 (value); BRASERO_JOB_LOG (readom, "reading from sector %lli to %lli", start, end); g_ptr_array_add (argv, g_strdup_printf ("-sectors=%"G_GINT64_FORMAT"-%"G_GINT64_FORMAT, start, end)); } /* 0 means all disc, -1 problem */ else if (brasero_track_disc_get_track_num (BRASERO_TRACK_DISC (track)) > 0) { goffset start; BraseroDrive *drive; BraseroMedium *medium; drive = brasero_track_disc_get_drive (BRASERO_TRACK_DISC (track)); medium = brasero_drive_get_medium (drive); brasero_medium_get_track_space (medium, brasero_track_disc_get_track_num (BRASERO_TRACK_DISC (track)), NULL, &nb_blocks); brasero_medium_get_track_address (medium, brasero_track_disc_get_track_num (BRASERO_TRACK_DISC (track)), NULL, &start); BRASERO_JOB_LOG (readom, "reading %i from sector %lli to %lli", brasero_track_disc_get_track_num (BRASERO_TRACK_DISC (track)), start, start + nb_blocks); g_ptr_array_add (argv, g_strdup_printf ("-sectors=%"G_GINT64_FORMAT"-%"G_GINT64_FORMAT, start, start + nb_blocks)); } /* if it's BIN output just read the last track */ else if (brasero_track_type_get_image_format (output) == BRASERO_IMAGE_FORMAT_BIN) { goffset start; BraseroDrive *drive; BraseroMedium *medium; drive = brasero_track_disc_get_drive (BRASERO_TRACK_DISC (track)); medium = brasero_drive_get_medium (drive); brasero_medium_get_last_data_track_space (medium, NULL, &nb_blocks); brasero_medium_get_last_data_track_address (medium, NULL, &start); BRASERO_JOB_LOG (readom, "reading last track from sector %"G_GINT64_FORMAT" to %"G_GINT64_FORMAT, start, start + nb_blocks); g_ptr_array_add (argv, g_strdup_printf ("-sectors=%"G_GINT64_FORMAT"-%"G_GINT64_FORMAT, start, start + nb_blocks)); } else { brasero_track_get_size (track, &nb_blocks, NULL); g_ptr_array_add (argv, g_strdup_printf ("-sectors=0-%"G_GINT64_FORMAT, nb_blocks)); } brasero_track_type_free (output); return BRASERO_BURN_OK; }