예제 #1
0
파일: cdda.c 프로젝트: menghun3/aqualung
void *
cdda_scanner(void * arg) {

	int i = 0;

	cdio_log_set_handler(cdda_log_handler);
	AQUALUNG_MUTEX_LOCK(cdda_mutex)
	cdda_scan_all_drives();
	AQUALUNG_MUTEX_UNLOCK(cdda_mutex)

	while (cdda_scanner_working) {
		g_usleep(100000);

		if (i == 50) { /* scan every 5 seconds */
			AQUALUNG_MUTEX_LOCK(cdda_mutex)
			cdda_scan_all_drives();
			AQUALUNG_MUTEX_UNLOCK(cdda_mutex)
			i = 0;
		}
		++i;
	}

	AQUALUNG_MUTEX_LOCK(cdda_mutex)
	for (i = 0; i < CDDA_DRIVES_MAX; i++) {
		if (cdda_drives[i].cdio != NULL) {
			cdio_destroy(cdda_drives[i].cdio);
			memset(cdda_drives + i, 0, sizeof(cdda_drive_t));
		}
	}
	AQUALUNG_MUTEX_UNLOCK(cdda_mutex)

	return NULL;
}
예제 #2
0
파일: cdda.c 프로젝트: kfihihc/xmms2-devel
/*
 * Private stuff
 */
static CdIo_t *
open_cd (xmms_xform_t *xform)
{
	CdIo_t *cdio;
	xmms_config_property_t *val;
	const gchar *device;
	const gchar *accessmode;

	cdio_log_set_handler (log_handler);

	val = xmms_xform_config_lookup (xform, "device");
	device = xmms_config_property_get_string (val);

	val = xmms_xform_config_lookup (xform, "accessmode");
	accessmode = xmms_config_property_get_string (val);

	XMMS_DBG ("Trying to open device '%s', using '%s' access mode.",
	          device, accessmode);

	if (g_ascii_strcasecmp (accessmode, "default") == 0) {
		cdio = cdio_open (device, DRIVER_UNKNOWN);
	} else {
		cdio = cdio_open_am (device, DRIVER_UNKNOWN, accessmode);
	}

	if (!cdio) {
		xmms_log_error ("Failed to open device '%s'.", device);
	} else {
		cdio_set_speed (cdio, 1);
		xmms_log_info ("Opened device '%s'.", device);
	}

	return cdio;
}
예제 #3
0
파일: drives.c 프로젝트: suborb/reelvdr
int
main(int argc, const char *argv[])
{
  char **ppsz_cd_drives=NULL, **c;
  
  cdio_log_set_handler (log_handler);

  /* Print out a list of CD-drives */
  ppsz_cd_drives = cdio_get_devices(DRIVER_DEVICE);
  if (NULL != ppsz_cd_drives) 
    for( c = ppsz_cd_drives; *c != NULL; c++ ) {
      printf("Drive %s\n", *c);
    }

  cdio_free_device_list(ppsz_cd_drives);
  ppsz_cd_drives = NULL;
  
  printf("-----\n");

  /* Print out a list of CD-drives the harder way. */
  ppsz_cd_drives = cdio_get_devices_with_cap(NULL, CDIO_FS_MATCH_ALL, false);

  if (NULL != ppsz_cd_drives) {
    for( c = ppsz_cd_drives; *c != NULL; c++ ) {
      printf("Drive %s\n", *c);
    }
    
  }
  cdio_free_device_list(ppsz_cd_drives);

  printf("-----\n");
  printf("CD-DA drives...\n");
  ppsz_cd_drives = NULL;
  /* Print out a list of CD-drives with CD-DA's in them. */
  ppsz_cd_drives = cdio_get_devices_with_cap(NULL,  CDIO_FS_AUDIO, false);

  if (NULL != ppsz_cd_drives) {
    for( c = ppsz_cd_drives; *c != NULL; c++ ) {
      printf("drive: %s\n", *c);
    }
  }
  cdio_free_device_list(ppsz_cd_drives);
    
  printf("-----\n");
  ppsz_cd_drives = NULL;
  printf("VCD drives...\n");
  /* Print out a list of CD-drives with VCD's in them. */
  ppsz_cd_drives = cdio_get_devices_with_cap(NULL, 
(CDIO_FS_ANAL_SVCD|CDIO_FS_ANAL_CVD|CDIO_FS_ANAL_VIDEOCD|CDIO_FS_UNKNOWN),
					true);
  if (NULL != ppsz_cd_drives) {
    for( c = ppsz_cd_drives; *c != NULL; c++ ) {
      printf("drive: %s\n", *c);
    }
  }

  cdio_free_device_list(ppsz_cd_drives);
  return 0;
  
}
예제 #4
0
int
main(int argc, const char *argv[])
{
  char **ppsz_cd_drives=NULL, **c;
  
  cdio_log_set_handler (log_handler);

  /* Print out a list of CD-drives */
  printf("All CD-ROM/DVD drives...\n");
  ppsz_cd_drives = getDevices();
  if (NULL != ppsz_cd_drives) 
    for( c = ppsz_cd_drives; *c != NULL; c++ ) {
      printf("Drive %s\n", *c);
    }

  freeDeviceList(ppsz_cd_drives);

  print_drive_class("All CD-ROM drives (again)", CDIO_FS_MATCH_ALL);
  print_drive_class("CD-ROM drives with a CD-DA loaded...", CDIO_FS_AUDIO);
  print_drive_class("CD-ROM drives with some sort of ISO 9660 filesystem...", 
		    CDIO_FS_ANAL_ISO9660_ANY, true);
  print_drive_class("(S)VCD drives...", CDIO_FS_ANAL_VCD_ANY, true);
  return 0;
  
}
예제 #5
0
파일: cdrom.c 프로젝트: forthyen/SDesk
/*****************************************************************************
 * ioctl_Open: Opens a VCD device or file and returns an opaque handle
 *****************************************************************************/
cddev_t *ioctl_Open( vlc_object_t *p_this, const char *psz_dev )
{
    cddev_t *p_cddev;

    if( !psz_dev ) return NULL;

    /*
     *  Initialize structure with default values
     */
    p_cddev = (cddev_t *)malloc( sizeof(cddev_t) );
    if( p_cddev == NULL )
    {
        msg_Err( p_this, "out of memory" );
        return NULL;
    }

    /* Set where to log errors messages from libcdio. */
    cdio_log_set_handler ( cd_log_handler );

    p_cddev->cdio = cdio_open(psz_dev, DRIVER_UNKNOWN);

    if( p_cddev->cdio == NULL )
    {
        free( p_cddev );
        p_cddev = NULL;
    }

    return p_cddev;
}
예제 #6
0
파일: drives.c 프로젝트: 3aychonok/libcdio
int
main(int argc, const char *argv[])
{
  char **ppsz_cd_drives=NULL, **c;
  
  cdio_log_set_handler (log_handler);

  /* Print out a list of CD-drives */
  ppsz_cd_drives = cdio_get_devices(DRIVER_DEVICE);
  if (NULL != ppsz_cd_drives) 
    for( c = ppsz_cd_drives; *c != NULL; c++ ) {
      printf("-- Drive %s\n", *c);
    }

  cdio_free_device_list(ppsz_cd_drives);
  ppsz_cd_drives = NULL;
  
  printf("-----\n");

  /* Print out a list of CD-drives the harder way. */
  print_drive_class("-- All CD-ROM drives (again)", CDIO_FS_MATCH_ALL, false);
  print_drive_class("-- CD-ROM drives with a CD-DA loaded...",
		    CDIO_FS_AUDIO, false);
  print_drive_class("-- CD-ROM drives with some sort of ISO 9660 filesystem...", 
		    CDIO_FS_ANAL_ISO9660_ANY, true);
  print_drive_class("-- (S)VCD drives...", CDIO_FS_ANAL_VCD_ANY, true);
  return 0;
  
}
예제 #7
0
파일: cd-drive.c 프로젝트: AaronDnz/xbmc
/* Initialize global variables. */
static void 
init(void) 
{
  gl_default_cdio_log_handler = cdio_log_set_handler (_log_handler);

  /* Default option values. */
  opts.silent        = false;
  opts.debug_level   = 0;
  opts.source_image  = DRIVER_UNKNOWN;
}
예제 #8
0
CddaImpl::CddaImpl(const std::string& device) :
   Cdda(),
   _device(device),
   _is_open(false),
   _cdio(NULL),
   _cdrom(NULL),
   _disk_id(0),
   _audio_length(0)
{
   cdio_log_set_handler(log_handler);
}
예제 #9
0
static gboolean
plugin_init (GstPlugin * plugin)
{
  if (!gst_element_register (plugin, "cdiocddasrc", GST_RANK_SECONDARY - 1,
          GST_TYPE_CDIO_CDDA_SRC))
    return FALSE;

  cdio_log_set_handler (gst_cdio_log_handler);

  GST_DEBUG_CATEGORY_INIT (gst_cdio_debug, "cdio", 0, "libcdio elements");

  return TRUE;
}
예제 #10
0
파일: cd-read.c 프로젝트: Crome/libcdio
static void 
init(void) 
{
  opts.debug_level   = 0;
  opts.start_lsn     = CDIO_INVALID_LSN;
  opts.end_lsn       = CDIO_INVALID_LSN;
  opts.num_sectors   = 0;
  opts.read_mode     = READ_MODE_UNINIT;
  opts.source_image  = INPUT_UNKNOWN;
  opts.hexdump       = 2;         /* Not set. */

  gl_default_cdio_log_handler = cdio_log_set_handler (log_handler);
}
예제 #11
0
int
main(int argc, const char *argv[])
{
  CdIo_t *cdObj;
  track_t i_track;
  lsn_t lsn;

  cdio_log_set_handler (log_handler);

  if (cdio_have_driver(DRIVER_BINCUE)) {
      cdObj = cdio_open(DATA_DIR "/cdda.cue", DRIVER_UNKNOWN);
  } else if (cdio_have_driver(DRIVER_CDRDAO)) {
      cdObj = cdio_open(DATA_DIR "/cdda.toc", DRIVER_UNKNOWN);
  } else {
    printf("-- You don't have enough drivers for this test\n");
    return 77;
  }

  i_track = cdio_get_track(cdObj, 1000);
  if (i_track != CDIO_INVALID_TRACK) {
      printf("LSN 1000 is too large should have gotten CDIO_INVALID_TRACK back\n");
      return 1;
  }

  for(lsn=0; lsn<10; lsn++) {
      i_track = cdio_get_track(cdObj, lsn);
      if (i_track != 1) {
	  printf("LSN %d should return 1. Got %d\n", lsn, i_track);
	  return 3;
      }
  }

  i_track = cdio_get_track(cdObj, 302);
  if (i_track != CDIO_CDROM_LEADOUT_TRACK) {
      printf("LSN %d should return leadout. Got %d\n", 302, i_track);
      return 4;
  }

  for(lsn=301; lsn > 300; lsn--) {
      i_track = cdio_get_track(cdObj, lsn);
      if (i_track != 1) {
	  printf("LSN %d should return 1. Got %d\n", lsn, i_track);
	  return 4;
      }
  }

  cdio_destroy(cdObj);

  return 0;
}
예제 #12
0
// Open a cdio device
static CdIo_t * openCdio(const QString& name)
{
    // Setup log handler
    static int s_logging;
    if (!s_logging)
    {
        s_logging = 1;
        cdio_log_set_handler(&logger);
    }

    CdIo_t *cdio = cdio_open(name.toAscii(), DRIVER_DEVICE);
    if (!cdio)
    {
        LOG(VB_MEDIA, LOG_INFO, QString("CdDecoder: cdio_open(%1) failed").
            arg(name));
    }
    return cdio;
}
예제 #13
0
int
main(int argc, const char *argv[])
{
  CdIo_t *cdObj;
  const char *image;
  lsn_t pregap;
  int i;
  int rc = 0;
  
  cdio_log_set_handler (log_handler);

  if (! (cdio_have_driver(DRIVER_NRG) && cdio_have_driver(DRIVER_BINCUE)
   && cdio_have_driver(DRIVER_CDRDAO)) )  {
    printf("You don't have enough drivers for this test\n");
    exit(77);
  }

  for (i = 0;  i < NELEMS(pregapList);  ++i) {

    image = pregapList[i].image;

    cdObj = cdio_open(image, DRIVER_UNKNOWN);
    if (!cdObj) {
      printf("unrecognized image: %s\n", image);
      return 50;
    }

    pregap = cdio_get_track_pregap_lsn(cdObj, pregapList[i].track);
    if (pregap != pregapList[i].pregap) {
      printf("%s should have had pregap of lsn=%d instead of lsn=%d\n",
       image, pregapList[i].pregap, pregap);
      rc = i + 1;
    } else {
      printf("%s had expected pregap\n", image);
    }

    cdio_destroy(cdObj);
  }

  return rc;
}
예제 #14
0
파일: access.c 프로젝트: BtbN/vlc
/*****************************************************************************
  VCDOpen: open VCD.
  read in meta-information about VCD: the number of tracks, segments,
  entries, size and starting information. Then set up state variables so
  that we read/seek starting at the location specified.

  On success we return VLC_SUCCESS, on memory exhausted VLC_ENOMEM,
  and VLC_EGENERIC for some other error.
 *****************************************************************************/
int
VCDOpen ( vlc_object_t *p_this )
{
    access_t         *p_access = (access_t *)p_this;
    vcdplayer_t      *p_vcdplayer;
    char             *psz_source;
    vcdinfo_itemid_t  itemid;
    bool        play_single_item = false;

    p_access->pf_read          = NULL;
    p_access->pf_block         = VCDReadBlock;
    p_access->pf_control       = VCDControl;
    p_access->pf_seek          = VCDSeek;

    p_access->info.i_update    = 0;
    p_access->info.i_pos       = 0;
    p_access->info.b_eof       = false;
    p_access->info.i_title     = 0;
    p_access->info.i_seekpoint = 0;

    p_vcdplayer = malloc( sizeof(vcdplayer_t) );

    if( p_vcdplayer == NULL )
        return VLC_ENOMEM;

    p_vcdplayer->i_debug = var_InheritInteger( p_this, MODULE_STRING "-debug" );
    p_access->p_sys = (access_sys_t *) p_vcdplayer;
    p_vcdplayer->size = 0;

    /* Set where to log errors messages from libcdio. */
    p_vcd_access = p_access;
    cdio_log_set_handler ( cdio_log_handler );
    vcd_log_set_handler ( vcd_log_handler );

    psz_source = VCDParse( p_access, &itemid, &play_single_item );

    if ( NULL == psz_source )
    {
        free( p_vcdplayer );
        return( VLC_EGENERIC );
    }

    dbg_print( (INPUT_DBG_CALL|INPUT_DBG_EXT), "source: %s: mrl: %s",
               psz_source, p_access->psz_location );

    p_vcdplayer->psz_source        = strdup(psz_source);
    p_vcdplayer->i_blocks_per_read = var_InheritInteger( p_this, MODULE_STRING
                                                    "-blocks-per-read" );
    p_vcdplayer->b_track_length    = var_InheritInteger( p_this, MODULE_STRING
                                                    "-track-length" );
    p_vcdplayer->in_still          = false;
    p_vcdplayer->play_item.type    = VCDINFO_ITEM_TYPE_NOTFOUND;
    p_vcdplayer->p_input           = access_GetParentInput( p_access );
//    p_vcdplayer->p_meta            = vlc_meta_New();
    p_vcdplayer->p_segments        = NULL;
    p_vcdplayer->p_entries         = NULL;

    /* set up input  */

    if( !(p_vcdplayer->vcd = vcd_Open( p_this, psz_source )) )
    {
        goto err_exit;
    }

    p_vcdplayer->b_svd = vcdinfo_get_tracksSVD(p_vcdplayer->vcd);

    /* Get track information. */
    p_vcdplayer->i_tracks = vcdinfo_get_num_tracks(p_vcdplayer->vcd);

    if( p_vcdplayer->i_tracks<1 || CDIO_INVALID_TRACK==p_vcdplayer->i_tracks )
    {
        vcdinfo_close( p_vcdplayer->vcd );
        LOG_ERR ("no movie tracks found" );
        goto err_exit;
    }

    /* Build Navigation Title table for the tracks. */
    VCDTitles( p_access );

    /* Add into the above entry points as "Chapters". */
    if( ! VCDEntryPoints( p_access ) )
    {
        msg_Warn( p_access, "could not read entry points, will not use them" );
        p_vcdplayer->b_valid_ep = false;
    }

    /* Initialize LID info and add that as a menu item */
    if( ! VCDLIDs( p_access ) )
    {
        msg_Warn( p_access, "could not read entry LIDs" );
    }

    /* Do we set PBC (via LID) on? */
    p_vcdplayer->i_lid =
      ( VCDINFO_ITEM_TYPE_LID == itemid.type
        && p_vcdplayer->i_lids > itemid.num )
      ? itemid.num
      :  VCDINFO_INVALID_ENTRY;

    /* Initialize segment information and add that a "Track". */
    VCDSegments( p_access );

    vcdplayer_play( p_access, itemid );

    free( p_access->psz_demux );
    p_access->psz_demux = strdup( "ps" );

#ifdef FIXED
    if( play_single_item )
        VCDFixupPlayList(p_access,p_vcd,psz_source,&itemid,play_single_item);
#endif

    p_vcdplayer->p_access = p_access;

    free( psz_source );

    return VLC_SUCCESS;
 err_exit:
    if( p_vcdplayer->p_input ) vlc_object_release( p_vcdplayer->p_input );
    free( psz_source );
    free( p_vcdplayer->psz_source );
    free( p_vcdplayer );
    return VLC_EGENERIC;
}
예제 #15
0
int
main(int argc, const char *argv[])
{
  cdio_log_set_handler (log_handler);
#if defined(__MINGW32__)
  printf("testgetdevices test skipped until drive recording testing issues resolved\n");
  return 77;
#else
  char **nrg_images=NULL;
  char **bincue_images=NULL;
  char **imgs;
  unsigned int i;
  int ret=0;

  const char *cue_files[2] = {"cdda.cue", "isofs-m1.cue"};
  const char *nrg_files[1] = {"videocd.nrg"};


  if (cdio_have_driver(-1) != false)
    {
      fprintf(stderr, "Bogus driver number -1 should be rejected\n");
      return 5;
    }

#ifdef HAVE_SYS_UTSNAME_H
  {
    struct utsname utsname;
    if (0 == uname(&utsname))
      {
	if (0 == strncmp("Linux", utsname.sysname, sizeof("Linux")))
	  {
	    if (!cdio_have_driver(DRIVER_LINUX))
	      {
		fprintf(stderr,
			"You should have been able to get GNU/Linux driver\n");
		return 6;
	      } else {
		printf("-- Good! You have the GNU/Linux driver installed.\n");
	      }

	  }
	else if (0 == strncmp("CYGWIN", utsname.sysname, sizeof("CYGWIN")))
	  {
	    if (!cdio_have_driver(DRIVER_WIN32))
	      {
		fprintf(stderr,
			"You should have been able to get Win32 driver\n");
		return 6;
	      } else {
		printf("-- Good! You have the Win32 driver installed.\n");
	      }
	  }
	else if (0 == strncmp("Darwin", utsname.sysname, sizeof("Darwin")))
	  {
	    if (!cdio_have_driver(DRIVER_OSX))
	      {
		fprintf(stderr,
			"You should have been able to get OS/X driver\n");
		return 6;
	      } else {
		printf("-- Good! You have the OS/X driver installed.\n");
	      }
	  }
	else if (0 == strncmp("NetBSD", utsname.sysname, sizeof("NetBSD")))
	  {
	    if (!cdio_have_driver(DRIVER_NETBSD))
	      {
		fprintf(stderr,
			"You should have been able to get NetBSD driver\n");
		return 6;
	      } else {
		printf("-- Good! You have the OS/X driver installed.\n");
	      }
	  }
      }
  }
#endif

  if (! (cdio_have_driver(DRIVER_NRG) && cdio_have_driver(DRIVER_BINCUE)) )  {
    printf("You don't have enough drivers for this test\n");
    exit(77);
  }

  bincue_images = cdio_get_devices(DRIVER_BINCUE);

  for (imgs=bincue_images; *imgs != NULL; imgs++) {
    printf("-- bincue image %s\n", *imgs);
  }

  if (ret != 0) return ret;

  if (0 == chdir(DATA_DIR)) {
     nrg_images = cdio_get_devices(DRIVER_NRG);

     for (imgs=nrg_images; *imgs != NULL; imgs++) {
       printf("-- NRG image %s\n", *imgs);
     }

     if (!is_in(nrg_images, nrg_files[0])) {
       cdio_free_device_list(nrg_images);
       return 10;
     }

     for (i=0; i<2; i++) {
       if (is_in(bincue_images, cue_files[i])) {
	   printf("-- %s parses as a CDRWIN BIN/CUE csheet.\n",
		  cue_files[i]);
       } else {
         printf("-- %s doesn't parse as a CDRWIN BIN/CUE csheet.\n",
		cue_files[i]);
         ret = i+1;
       }
     }

  }

  cdio_free_device_list(nrg_images);
  cdio_free_device_list(bincue_images);
  return 0;
#endif
}
예제 #16
0
int main(int argc, char** argv)
{
  iso9660_t* p_iso = NULL;
  udf_t* p_udf = NULL;
  udf_dirent_t* p_udf_root;
  char *psz_str = NULL;
  char vol_id[UDF_VOLID_SIZE] = "";
  char volset_id[UDF_VOLSET_ID_SIZE+1] = "";
  int r = 0;

  cdio_log_set_handler (log_handler);

  if (argc < 3) {
    fprintf(stderr, "Usage: extract <iso_image> <extraction_dir>\n");
    return 1;
  }

  /* Warn if LFS doesn't appear to be enabled */
  if (sizeof(off_t) < 8) {
    fprintf(stderr, "INFO: Large File Support not detected (required for files >2GB)\n");
  }

  psz_extract_dir = argv[2];
  if (_mkdir(psz_extract_dir) == 0) {
    printf("-- Creating directory: %s\n", psz_extract_dir);
  } else if (errno != EEXIST) {
    fprintf(stderr, "Unable to create extraction directory %s\n", psz_extract_dir);
    return 1;
  }

  /* First try to open as UDF - fallback to ISO if it failed */
  p_udf = udf_open(argv[1]);
  if (p_udf == NULL)
    goto try_iso;

  p_udf_root = udf_get_root(p_udf, true, 0);
  if (p_udf_root == NULL) {
    fprintf(stderr, "Couldn't locate UDF root directory\n");
    goto out;
  }
  vol_id[0] = 0; volset_id[0] = 0;

  /* Show basic UDF Volume info */
  if (udf_get_volume_id(p_udf, vol_id, sizeof(vol_id)) > 0)
    printf("-- Volume id: %s\n", vol_id);
  if (udf_get_volume_id(p_udf, volset_id, sizeof(volset_id)) >0 ) {
    volset_id[UDF_VOLSET_ID_SIZE]='\0';
    printf("-- Volume set id: %s\n", volset_id);
  }
  printf("-- Partition number: %d\n", udf_get_part_number(p_udf));

  /* Recursively extract files */
  r = udf_extract_files(p_udf, p_udf_root, "");

  goto out;

try_iso:
  p_iso = iso9660_open_ext(argv[1], ISO_EXTENSION_ALL);
  if (p_iso == NULL) {
    fprintf(stderr, "Unable to open image '%s'.\n", argv[1]);
    r = 1;
    goto out;
  }
  i_joliet_level = iso9660_ifs_get_joliet_level(p_iso);

  /* Show basic ISO9660 info from the Primary Volume Descriptor. */
  print_vd_info("Application", iso9660_ifs_get_application_id);
  print_vd_info("Preparer   ", iso9660_ifs_get_preparer_id);
  print_vd_info("Publisher  ", iso9660_ifs_get_publisher_id);
  print_vd_info("System     ", iso9660_ifs_get_system_id);
  print_vd_info("Volume     ", iso9660_ifs_get_volume_id);
  print_vd_info("Volume Set ", iso9660_ifs_get_volumeset_id);

  r = iso_extract_files(p_iso, "");

out:
  if (p_iso != NULL)
    iso9660_close(p_iso);
  if (p_udf != NULL)
    udf_close(p_udf);

  return r;
}
예제 #17
0
int
main(int argc, const char *argv[])
{
  char **nrg_images=NULL;
  char **bincue_images=NULL;
  char **imgs;
  char **c;
  unsigned int i;
  int ret=0;

  const char *cue_files[2] = {"cdda.cue", "isofs-m1.cue"};
  const char *nrg_files[1] = {"videocd.nrg"};
  
  cdio_log_set_handler (log_handler);

  if (cdio_have_driver(-1) != false) 
    {
      printf("Bogus driver number -1 should be regexted\n");
      return 5;
    }
  

  if (! (cdio_have_driver(DRIVER_NRG) && cdio_have_driver(DRIVER_BINCUE)) )  {
    printf("You don't have enough drivers for this test\n");
    exit(77);
  }

  nrg_images = cdio_get_devices(DRIVER_NRG);

  for (imgs=nrg_images; *imgs != NULL; imgs++) {
    printf("NRG image %s\n", *imgs);
  }

  if (!is_in(nrg_images, nrg_files[0])) {
    cdio_free_device_list(nrg_images);
    return 10;
  }
      
  bincue_images = cdio_get_devices(DRIVER_BINCUE);
  
  for (imgs=bincue_images; *imgs != NULL; imgs++) {
    printf("bincue image %s\n", *imgs);
  }
  
  for (i=0; i<2; i++) {
    if (is_in(bincue_images, cue_files[i])) {
      printf("%s parses as a CDRWIN BIN/CUE csheet.\n", cue_files[i]);
    } else {
      printf("%s doesn't parse as a CDRWIN BIN/CUE csheet.\n", cue_files[i]);
      ret = i+1;
    }
  }

  if (ret != 0) return ret;
    
  printf("-----\n");
  printf("ISO 9660 images...\n");
  imgs = NULL;
  /* Print out a list of CDDA-drives. */
  imgs = cdio_get_devices_with_cap(bincue_images, CDIO_FS_ISO_9660, false);

  if (NULL == imgs || *imgs == NULL) {
    printf("Failed to find an ISO 9660 image\n");
    return 11;
  }
    
  for( c = imgs; *c != NULL; c++ ) {
    printf("%s\n", *c);
  }
    
  cdio_free_device_list(imgs);
  free(imgs);
  
  
  printf("-----\n");
  printf("CD-DA images...\n");
  imgs = NULL;
  /* Print out a list of CDDA-drives. */
  imgs = cdio_get_devices_with_cap(bincue_images, CDIO_FS_AUDIO, false);

  if (NULL == imgs || *imgs == NULL) {
    printf("Failed to find CDDA image\n");
    return 12;
  }
    
  for( c = imgs; *c != NULL; c++ ) {
    printf("%s\n", *c);
  }
    
  cdio_free_device_list(imgs);
  free(imgs);
  
  
  printf("-----\n");
  imgs = NULL;
  printf("VCD images...\n");
  /* Print out a list of CD-drives with VCD's in them. */
  imgs = cdio_get_devices_with_cap(nrg_images, 
(CDIO_FS_ANAL_SVCD|CDIO_FS_ANAL_CVD|CDIO_FS_ANAL_VIDEOCD|CDIO_FS_UNKNOWN),
					true);
  if (NULL == imgs || *imgs == NULL) {
    printf("Failed to find VCD image\n");
    return 13;
  }
    
  for( c = imgs; *c != NULL; c++ ) {
    printf("image: %s\n", *c);
  }

  cdio_free_device_list(imgs);
  free(imgs);

  imgs = NULL;
  /* Print out a list of CDDA-drives. */
  imgs = cdio_get_devices_with_cap(bincue_images, CDIO_FS_HIGH_SIERRA, false);

  if (NULL != imgs && *imgs != NULL) {
    printf("Found erroneous High Sierra image\n");
    return 14;
  }
    
  imgs = NULL;
  /* Print out a list of CDDA-drives. */
  imgs = cdio_get_devices_with_cap(bincue_images, CDIO_FS_UFS, true);

  if (NULL != imgs && *imgs != NULL) {
    printf("Found erroneous UFS image\n");
    return 15;
  }
    
  cdio_free_device_list(nrg_images);
  cdio_free_device_list(bincue_images);
  cdio_free_device_list(imgs);
  return 0;
  
}
예제 #18
0
int
main(int argc, const char *argv[])
{
  CdIo_t *p_cdio;
  cdio_fs_anal_t fs=0;

  track_t num_tracks;
  track_t first_track_num;
  lsn_t start_track;          /* first sector of track */
  lsn_t data_start =0;        /* start of data area */

  int first_data = -1;        /* # of first data track */
  int first_audio = -1;       /* # of first audio track */
  unsigned int num_data  = 0; /* # of data tracks */
  unsigned int num_audio = 0; /* # of audio tracks */
  unsigned int i;
  char *cd_image_name = NULL;

  if (argc > 1)
    cd_image_name = strdup(argv[1]);

  cdio_log_set_handler (log_handler);

  p_cdio = cdio_open (cd_image_name, DRIVER_UNKNOWN);

  if (NULL == p_cdio) {
    printf("-- Problem in trying to find a driver.\n\n");
    free(cd_image_name);
    return 77;
  }

  first_track_num = cdio_get_first_track_num(p_cdio);
  num_tracks      = cdio_get_num_tracks(p_cdio);

  /* Count the number of data and audio tracks. */
  for (i = first_track_num; i <= num_tracks; i++) {
    if (TRACK_FORMAT_AUDIO == cdio_get_track_format(p_cdio, i)) {
      num_audio++;
      if (-1 == first_audio) first_audio = i;
    } else {
      num_data++;
      if (-1 == first_data)  first_data = i;
    }
  }

  /* try to find out what sort of CD we have */
  if (0 == num_data) {
    printf("-- Audio CD\n");
  } else {
    /* we have data track(s) */
    cdio_iso_analysis_t cdio_iso_analysis;

    memset(&cdio_iso_analysis, 0, sizeof(cdio_iso_analysis));

    for (i = first_data; i <= num_tracks; i++) {
      lsn_t lsn;
      track_format_t track_format = cdio_get_track_format(p_cdio, i);

      lsn = cdio_get_track_lsn(p_cdio, i);

      switch ( track_format ) {
      case TRACK_FORMAT_AUDIO:
      case TRACK_FORMAT_ERROR:
	break;
      case TRACK_FORMAT_CDI:
      case TRACK_FORMAT_XA:
      case TRACK_FORMAT_DATA:
      case TRACK_FORMAT_PSX:
	;
      }

      start_track = (i == 1) ? 0 : lsn;

      /* save the start of the data area */
      if (i == first_data)
	data_start = start_track;

      /* skip tracks which belong to the current walked session */
      if (start_track < data_start + cdio_iso_analysis.isofs_size)
	continue;

      fs = cdio_guess_cd_type(p_cdio, start_track, i, &cdio_iso_analysis);

      print_analysis(cdio_iso_analysis, fs, first_data, num_audio);

      if ( !(CDIO_FSTYPE(fs) == CDIO_FS_ISO_9660 ||
	     CDIO_FSTYPE(fs) == CDIO_FS_ISO_HFS  ||
	     CDIO_FSTYPE(fs) == CDIO_FS_ISO_9660_INTERACTIVE) )
	/* no method for non-ISO9660 multisessions */
	break;
    }
  }
  free(cd_image_name);
  cdio_destroy(p_cdio);
  return 0;
}
예제 #19
0
파일: iso.c 프로젝트: hanji/rufus
BOOL ExtractISO(const char* src_iso, const char* dest_dir, bool scan)
{
	size_t i;
	int j;
	FILE* fd;
	BOOL r = FALSE;
	iso9660_t* p_iso = NULL;
	udf_t* p_udf = NULL; 
	udf_dirent_t* p_udf_root;
	LONG progress_style;
	char* tmp;
	char path[64];
	const char* scan_text = "Scanning ISO image...";
	const char* basedir[] = { "i386", "minint" };
	const char* tmp_sif = ".\\txtsetup.sif~";

	if ((src_iso == NULL) || (dest_dir == NULL))
		return FALSE;

	scan_only = scan;
	cdio_log_set_handler(log_handler);
	psz_extract_dir = dest_dir;
	progress_style = GetWindowLong(hISOProgressBar, GWL_STYLE);
	if (scan_only) {
		total_blocks = 0;
		memset(&iso_report, 0, sizeof(iso_report));
		// String array of all isolinux/syslinux locations
		StrArrayCreate(&config_path, 8);
		// Change the Window title and static text
		SetWindowTextU(hISOProgressDlg, scan_text);
		SetWindowTextU(hISOFileName, scan_text);
		// Change progress style to marquee for scanning
		SetWindowLong(hISOProgressBar, GWL_STYLE, progress_style | PBS_MARQUEE);
		SendMessage(hISOProgressBar, PBM_SETMARQUEE, TRUE, 0);
	} else {
		uprintf("Extracting files...\n");
		if (total_blocks == 0) {
			uprintf("Error: ISO has not been properly scanned.\n");
			FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR(ERROR_ISO_SCAN);
			goto out;
		}
		nb_blocks = 0;
		iso_blocking_status = 0;
		SetWindowLong(hISOProgressBar, GWL_STYLE, progress_style & (~PBS_MARQUEE));
		SendMessage(hISOProgressBar, PBM_SETPOS, 0, 0);
	}
	ShowWindow(hISOProgressDlg, SW_SHOW);
	UpdateWindow(hISOProgressDlg);

	/* First try to open as UDF - fallback to ISO if it failed */
	p_udf = udf_open(src_iso);
	if (p_udf == NULL)
		goto try_iso;
	uprintf("Disc image is an UDF image\n");

	p_udf_root = udf_get_root(p_udf, true, 0);
	if (p_udf_root == NULL) {
		uprintf("Couldn't locate UDF root directory\n");
		goto out;
	}
	if (scan_only) {
		if (udf_get_logical_volume_id(p_udf, iso_report.label, sizeof(iso_report.label)) <= 0)
			iso_report.label[0] = 0;
	}
	r = udf_extract_files(p_udf, p_udf_root, "");
	goto out;

try_iso:
	p_iso = iso9660_open_ext(src_iso, ISO_EXTENSION_ALL);
	if (p_iso == NULL) {
		uprintf("Unable to open image '%s'.\n", src_iso);
		goto out;
	}
	i_joliet_level = iso9660_ifs_get_joliet_level(p_iso);
	uprintf("Disc image is an ISO9660 image\n");
	if (scan_only) {
		if (iso9660_ifs_get_volume_id(p_iso, &tmp)) {
			safe_strcpy(iso_report.label, sizeof(iso_report.label), tmp);
			safe_free(tmp);
		} else
			iso_report.label[0] = 0;
	}
	r = iso_extract_files(p_iso, "");

out:
	iso_blocking_status = -1;
	if (scan_only) {
		// Remove trailing spaces from the label
		for (j=safe_strlen(iso_report.label)-1; ((j>=0)&&(isspace(iso_report.label[j]))); j--)
			iso_report.label[j] = 0;
		// We use the fact that UDF_BLOCKSIZE and ISO_BLOCKSIZE are the same here
		iso_report.projected_size = total_blocks * ISO_BLOCKSIZE;
		// We will link the existing isolinux.cfg from a syslinux.cfg we create
		// If multiple config file exist, choose the one with the shortest path
		if (iso_report.has_isolinux) {
			safe_strcpy(iso_report.cfg_path, sizeof(iso_report.cfg_path), config_path.Table[0]);
			for (i=1; i<config_path.Index; i++) {
				if (safe_strlen(iso_report.cfg_path) > safe_strlen(config_path.Table[i]))
					safe_strcpy(iso_report.cfg_path, sizeof(iso_report.cfg_path), config_path.Table[i]);
			}
			uprintf("Will use %s for Syslinux\n", iso_report.cfg_path);
		}
		if (IS_WINPE(iso_report.winpe)) {
			// In case we have a WinPE 1.x based iso, we extract and parse txtsetup.sif
			// during scan, to see if /minint was provided for OsLoadOptions, as it decides
			// whether we should use 0x80 or 0x81 as the disk ID in the MBR
			safe_sprintf(path, sizeof(path), "/%s/txtsetup.sif", 
				basedir[((iso_report.winpe&WINPE_I386) == WINPE_I386)?0:1]);
			ExtractISOFile(src_iso, path, tmp_sif);
			tmp = get_token_data(tmp_sif, "OsLoadOptions");
			if (tmp != NULL) {
				for (i=0; i<strlen(tmp); i++)
					tmp[i] = (char)tolower(tmp[i]);
				uprintf("Checking txtsetup.sif:\n  OsLoadOptions = %s\n", tmp);
				iso_report.uses_minint = (strstr(tmp, "/minint") != NULL);
			}
			_unlink(tmp_sif);
			safe_free(tmp);
		}
		StrArrayDestroy(&config_path);
	} else if (iso_report.has_isolinux) {
		safe_sprintf(path, sizeof(path), "%s\\syslinux.cfg", dest_dir);
		// Create a /syslinux.cfg (if none exists) that points to the existing isolinux cfg
		fd = fopen(path, "r");
		if (fd == NULL) {
			fd = fopen(path, "w");	// No "/syslinux.cfg" => create a new one
			if (fd == NULL) {
				uprintf("Unable to create %s - booting from USB will not work\n", path);
				r = 1;
			} else {
				fprintf(fd, "DEFAULT loadconfig\n\nLABEL loadconfig\n  CONFIG %s\n", iso_report.cfg_path);
				for (i=safe_strlen(iso_report.cfg_path); (i>0)&&(iso_report.cfg_path[i]!='/'); i--);
				if (i>0) {
					iso_report.cfg_path[i] = 0;
					fprintf(fd, "  APPEND %s/\n", iso_report.cfg_path);
					iso_report.cfg_path[i] = '/';
				}
				uprintf("Created: %s\n", path);
			}
		}
		if (fd != NULL)
			fclose(fd);
	}
	ShowWindow(hISOProgressDlg, SW_HIDE);
	if (p_iso != NULL)
		iso9660_close(p_iso);
	if (p_udf != NULL)
		udf_close(p_udf);
	if ((r != 0) && (FormatStatus == 0))
		FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR((scan_only?ERROR_ISO_SCAN:ERROR_ISO_EXTRACT));
	return (r == 0);
}
예제 #20
0
파일: iso.c 프로젝트: DesignD/rufus
BOOL ExtractISO(const char* src_iso, const char* dest_dir, BOOL scan)
{
	size_t i, size;
	int j;
	uint16_t sl_version;
	FILE* fd;
	int r = 1;
	iso9660_t* p_iso = NULL;
	udf_t* p_udf = NULL; 
	udf_dirent_t* p_udf_root;
	char *tmp, *buf, *ext;
	char path[MAX_PATH], path2[16];
	const char* basedir[] = { "i386", "minint" };
	const char* tmp_sif = ".\\txtsetup.sif~";
	iso_extension_mask_t iso_extension_mask = ISO_EXTENSION_ALL;

	if ((!enable_iso) || (src_iso == NULL) || (dest_dir == NULL))
		return FALSE;

	scan_only = scan;
	cdio_log_set_handler(log_handler);
	psz_extract_dir = dest_dir;
	// Change progress style to marquee for scanning
	if (scan_only) {
		SendMessage(hMainDialog, UM_PROGRESS_INIT, PBS_MARQUEE, 0);
		total_blocks = 0;
		memset(&iso_report, 0, sizeof(iso_report));
		has_ldlinux_c32 = FALSE;
		// String array of all isolinux/syslinux locations
		StrArrayCreate(&config_path, 8);
		StrArrayCreate(&isolinux_path, 8);
		PrintInfo(0, MSG_202);
	} else {
		uprintf("Extracting files...\n");
		IGNORE_RETVAL(_chdirU(app_dir));
		PrintInfo(0, MSG_231);
		if (total_blocks == 0) {
			uprintf("Error: ISO has not been properly scanned.\n");
			FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR(ERROR_ISO_SCAN);
			goto out;
		}
		nb_blocks = 0;
		iso_blocking_status = 0;
	}

	/* First try to open as UDF - fallback to ISO if it failed */
	p_udf = udf_open(src_iso);
	if (p_udf == NULL)
		goto try_iso;
	uprintf("Disc image is an UDF image\n");

	p_udf_root = udf_get_root(p_udf, true, 0);
	if (p_udf_root == NULL) {
		uprintf("Could not locate UDF root directory\n");
		goto out;
	}
	if (scan_only) {
		if (udf_get_logical_volume_id(p_udf, iso_report.label, sizeof(iso_report.label)) <= 0)
			iso_report.label[0] = 0;
	}
	r = udf_extract_files(p_udf, p_udf_root, "");
	goto out;

try_iso:
	// Perform our first scan with Joliet disabled (if Rock Ridge is enabled), so that we can find if
	// there exists a Rock Ridge file with a name > 64 chars or if there are symlinks. If that is the
	// case then we also disable Joliet during the extract phase.
	if ((!enable_joliet) || (enable_rockridge && (scan_only || iso_report.has_long_filename || iso_report.has_symlinks))) {
		iso_extension_mask &= ~ISO_EXTENSION_JOLIET;
	}
	if (!enable_rockridge) {
		iso_extension_mask &= ~ISO_EXTENSION_ROCK_RIDGE;
	}

	p_iso = iso9660_open_ext(src_iso, iso_extension_mask);
	if (p_iso == NULL) {
		uprintf("'%s' doesn't look like an ISO image\n", src_iso);
		r = 1;
		goto out;
	}
	uprintf("Disc image is an ISO9660 image\n");
	i_joliet_level = iso9660_ifs_get_joliet_level(p_iso);
	if (scan_only) {
		if (iso9660_ifs_get_volume_id(p_iso, &tmp)) {
			safe_strcpy(iso_report.label, sizeof(iso_report.label), tmp);
			safe_free(tmp);
		} else
			iso_report.label[0] = 0;
	} else {
		if (iso_extension_mask & (ISO_EXTENSION_JOLIET|ISO_EXTENSION_ROCK_RIDGE))
			uprintf("This image will be extracted using %s extensions (if present)", 
				(iso_extension_mask & ISO_EXTENSION_JOLIET)?"Joliet":"Rock Ridge");
		else
			uprintf("This image will not be extracted using any ISO extensions");
	}
	r = iso_extract_files(p_iso, "");

out:
	iso_blocking_status = -1;
	if (scan_only) {
		// Remove trailing spaces from the label
		for (j=(int)safe_strlen(iso_report.label)-1; ((j>=0)&&(isspaceU(iso_report.label[j]))); j--)
			iso_report.label[j] = 0;
		// We use the fact that UDF_BLOCKSIZE and ISO_BLOCKSIZE are the same here
		iso_report.projected_size = total_blocks * ISO_BLOCKSIZE;
		// We will link the existing isolinux.cfg from a syslinux.cfg we create
		// If multiple config files exist, choose the one with the shortest path
		// (so that a '/syslinux.cfg' is preferred over a '/isolinux/isolinux.cfg')
		if (!IsStrArrayEmpty(config_path)) {
			// Set the iso_report.cfg_path string to maximum length, so that we don't have to
			// do a special case for StrArray entry 0.
			memset(iso_report.cfg_path, '_', sizeof(iso_report.cfg_path)-1);
			iso_report.cfg_path[sizeof(iso_report.cfg_path)-1] = 0;
			for (i=0; i<config_path.Index; i++) {
				// OpenSuse based Live image have a /syslinux.cfg that doesn't work, so we enforce
				// the use of the one in '/boot/[i386|x86_64]/loader/isolinux.cfg' if present.
				// Note that, because the openSuse live script are not designed to handle anything but
				// an ISO9660 filesystem for the live device, this still won't allow for proper boot.
				// See https://github.com/openSUSE/kiwi/issues/354
				if ( (_stricmp(config_path.String[i], "/boot/i386/loader/isolinux.cfg") == 0) ||
					 (_stricmp(config_path.String[i], "/boot/x86_64/loader/isolinux.cfg") == 0)) {
					safe_strcpy(iso_report.cfg_path, sizeof(iso_report.cfg_path), config_path.String[i]);
					iso_report.needs_syslinux_overwrite = TRUE;
					break;
				}
				// Tails uses an '/EFI/BOOT/isolinux.cfg' along with a '/isolinux/isolinux.cfg'
				// which are the exact same length. However, only the /isolinux one will work,
				// so for now, at equal length, always pick the latest.
				// We may have to revisit this and prefer a path that contains '/isolinux' if
				// this hack is not enough for other images.
				if (safe_strlen(iso_report.cfg_path) >= safe_strlen(config_path.String[i]))
					safe_strcpy(iso_report.cfg_path, sizeof(iso_report.cfg_path), config_path.String[i]);
			}
			uprintf("Will use '%s' for Syslinux\n", iso_report.cfg_path);
			// Extract all of the isolinux.bin files we found to identify their versions
			for (i=0; i<isolinux_path.Index; i++) {
				size = (size_t)ExtractISOFile(src_iso, isolinux_path.String[i], dot_isolinux_bin, FILE_ATTRIBUTE_NORMAL);
				if (size == 0) {
					uprintf("Could not access %s\n", isolinux_path.String[i]);
				} else {
					buf = (char*)calloc(size, 1);
					if (buf == NULL) break;
					fd = fopen(dot_isolinux_bin, "rb");
					if (fd == NULL) {
						free(buf);
						continue;
					}
					fread(buf, 1, size, fd);
					fclose(fd);
					sl_version = GetSyslinuxVersion(buf, size, &ext);
					if (iso_report.sl_version == 0) {
						safe_strcpy(iso_report.sl_version_ext, sizeof(iso_report.sl_version_ext), ext);
						iso_report.sl_version = sl_version;
						j = (int)i;
					} else if ((iso_report.sl_version != sl_version) || (safe_strcmp(iso_report.sl_version_ext, ext) != 0)) {
						uprintf("Found conflicting %s versions:\n  '%s' (%d.%02d%s) vs '%s' (%d.%02d%s)\n", isolinux_bin,
							isolinux_path.String[j], SL_MAJOR(iso_report.sl_version), SL_MINOR(iso_report.sl_version),
							iso_report.sl_version_ext, isolinux_path.String[i], SL_MAJOR(sl_version), SL_MINOR(sl_version), ext);
					}
					free(buf);
					_unlink(dot_isolinux_bin);
				}
			}
			if (iso_report.sl_version != 0) {
				static_sprintf(iso_report.sl_version_str, "%d.%02d",
					SL_MAJOR(iso_report.sl_version), SL_MINOR(iso_report.sl_version));
				uprintf("Detected Isolinux version: %s%s (from '%s')",
					iso_report.sl_version_str, iso_report.sl_version_ext, isolinux_path.String[j]);
				if ( (has_ldlinux_c32 && (SL_MAJOR(iso_report.sl_version) < 5))
				  || (!has_ldlinux_c32 && (SL_MAJOR(iso_report.sl_version) >= 5)) )
					uprintf("Warning: Conflict between Isolinux version and the presence of ldlinux.c32...\n");
			} else {
				// Couldn't find a version from isolinux.bin. Force set to the versions we embed
				iso_report.sl_version = embedded_sl_version[has_ldlinux_c32?1:0];
				static_sprintf(iso_report.sl_version_str, "%d.%02d",
					SL_MAJOR(iso_report.sl_version), SL_MINOR(iso_report.sl_version));
				uprintf("Warning: Could not detect Isolinux version - Forcing to %s (embedded)",
					iso_report.sl_version_str);
			}
		}
		if (IS_WINPE(iso_report.winpe)) {
			// In case we have a WinPE 1.x based iso, we extract and parse txtsetup.sif
			// during scan, to see if /minint was provided for OsLoadOptions, as it decides
			// whether we should use 0x80 or 0x81 as the disk ID in the MBR
			safe_sprintf(path, sizeof(path), "/%s/txtsetup.sif", 
				basedir[((iso_report.winpe&WINPE_I386) == WINPE_I386)?0:1]);
			ExtractISOFile(src_iso, path, tmp_sif, FILE_ATTRIBUTE_NORMAL);
			tmp = get_token_data_file("OsLoadOptions", tmp_sif);
			if (tmp != NULL) {
				for (i=0; i<strlen(tmp); i++)
					tmp[i] = (char)tolower(tmp[i]);
				uprintf("Checking txtsetup.sif:\n  OsLoadOptions = %s\n", tmp);
				iso_report.uses_minint = (strstr(tmp, "/minint") != NULL);
			}
			_unlink(tmp_sif);
			safe_free(tmp);
		}
		if (iso_report.has_grub2) {
			// In case we have a GRUB2 based iso, we extract boot/grub/i386-pc/normal.mod to parse its version
			iso_report.grub2_version[0] = 0;
			if ((GetTempPathU(sizeof(path), path) != 0) && (GetTempFileNameU(path, APPLICATION_NAME, 0, path) != 0)) {
				size = (size_t)ExtractISOFile(src_iso, "boot/grub/i386-pc/normal.mod", path, FILE_ATTRIBUTE_NORMAL);
				buf = (char*)calloc(size, 1);
				fd = fopen(path, "rb");
				if ((size == 0) || (buf == NULL) || (fd == NULL)) {
					uprintf("Could not read Grub version from 'boot/grub/i386-pc/normal.mod'");
				} else {
					fread(buf, 1, size, fd);
					fclose(fd);
					GetGrubVersion(buf, size);
				}
				free(buf);
				_unlink(path);
			}
			if (iso_report.grub2_version[0] != 0)
				uprintf("Detected Grub version: %s", iso_report.grub2_version);
			else {
				uprintf("Could not detect Grub version");
				iso_report.has_grub2 = FALSE;
			}
		}
		StrArrayDestroy(&config_path);
		StrArrayDestroy(&isolinux_path);
		SendMessage(hMainDialog, UM_PROGRESS_EXIT, 0, 0);
	} else if (HAS_SYSLINUX(iso_report)) {
		safe_sprintf(path, sizeof(path), "%s\\syslinux.cfg", dest_dir);
		// Create a /syslinux.cfg (if none exists) that points to the existing isolinux cfg
		fd = fopen(path, "r");
		if (fd != NULL && iso_report.needs_syslinux_overwrite) {
			fclose(fd);
			fd = NULL;
			safe_sprintf(path2, sizeof(path2), "%s\\syslinux.org", dest_dir);
			uprintf("Renaming: %s ⇨ %s", path, path2);
			IGNORE_RETVAL(rename(path, path2));
		}
		if (fd == NULL) {
			fd = fopen(path, "w");	// No "/syslinux.cfg" => create a new one
			if (fd == NULL) {
				uprintf("Unable to create %s - booting from USB will not work\n", path);
				r = 1;
			} else {
				fprintf(fd, "DEFAULT loadconfig\n\nLABEL loadconfig\n  CONFIG %s\n", iso_report.cfg_path);
				for (i=safe_strlen(iso_report.cfg_path); (i>0)&&(iso_report.cfg_path[i]!='/'); i--);
				if (i>0) {
					iso_report.cfg_path[i] = 0;
					fprintf(fd, "  APPEND %s/\n", iso_report.cfg_path);
					iso_report.cfg_path[i] = '/';
				}
				uprintf("Created: %s\n", path);
			}
		}
		if (fd != NULL)
			fclose(fd);
	}
	if (p_iso != NULL)
		iso9660_close(p_iso);
	if (p_udf != NULL)
		udf_close(p_udf);
	if ((r != 0) && (FormatStatus == 0))
		FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR((scan_only?ERROR_ISO_SCAN:ERROR_ISO_EXTRACT));
	return (r == 0);
}
예제 #21
-2
파일: iso.c 프로젝트: JBTech/rufus
BOOL ExtractISO(const char* src_iso, const char* dest_dir, BOOL scan)
{
	size_t i, k, size;
	int j;
	uint16_t sl_version;
	FILE* fd;
	int r = 1;
	iso9660_t* p_iso = NULL;
	udf_t* p_udf = NULL; 
	udf_dirent_t* p_udf_root;
	LONG progress_style;
	char *tmp, *buf;
	char path[MAX_PATH];
	const char* basedir[] = { "i386", "minint" };
	const char* tmp_sif = ".\\txtsetup.sif~";
	const char ISOLINUX[] = { 'I', 'S', 'O', 'L', 'I', 'N', 'U', 'X', ' ' };
	iso_extension_mask_t iso_extension_mask = ISO_EXTENSION_ALL;

	if ((src_iso == NULL) || (dest_dir == NULL))
		return FALSE;

	scan_only = scan;
	cdio_log_set_handler(log_handler);
	psz_extract_dir = dest_dir;
	progress_style = GetWindowLong(hISOProgressBar, GWL_STYLE);
	if (scan_only) {
		total_blocks = 0;
		memset(&iso_report, 0, sizeof(iso_report));
		has_ldlinux_c32 = FALSE;
		// String array of all isolinux/syslinux locations
		StrArrayCreate(&config_path, 8);
		StrArrayCreate(&isolinux_path, 8);
		// Change the Window title and static text
		SetWindowTextU(hISOProgressDlg, lmprintf(MSG_202));
		SetWindowTextU(hISOFileName, lmprintf(MSG_202));
		// Change progress style to marquee for scanning
		SetWindowLong(hISOProgressBar, GWL_STYLE, progress_style | PBS_MARQUEE);
		SendMessage(hISOProgressBar, PBM_SETMARQUEE, TRUE, 0);
	} else {
		uprintf("Extracting files...\n");
		IGNORE_RETVAL(_chdirU(app_dir));
		SetWindowTextU(hISOProgressDlg, lmprintf(MSG_231));
		if (total_blocks == 0) {
			uprintf("Error: ISO has not been properly scanned.\n");
			FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR(ERROR_ISO_SCAN);
			goto out;
		}
		nb_blocks = 0;
		iso_blocking_status = 0;
		SetWindowLong(hISOProgressBar, GWL_STYLE, progress_style & (~PBS_MARQUEE));
		SendMessage(hISOProgressBar, PBM_SETPOS, 0, 0);
	}
	SendMessage(hISOProgressDlg, UM_ISO_INIT, 0, 0);

	/* First try to open as UDF - fallback to ISO if it failed */
	p_udf = udf_open(src_iso);
	if (p_udf == NULL)
		goto try_iso;
	uprintf("Disc image is an UDF image\n");

	p_udf_root = udf_get_root(p_udf, true, 0);
	if (p_udf_root == NULL) {
		uprintf("Couldn't locate UDF root directory\n");
		goto out;
	}
	if (scan_only) {
		if (udf_get_logical_volume_id(p_udf, iso_report.label, sizeof(iso_report.label)) <= 0)
			iso_report.label[0] = 0;
	}
	r = udf_extract_files(p_udf, p_udf_root, "");
	goto out;

try_iso:
	// Perform our first scan with Joliet disabled (if Rock Ridge is enabled), so that we can find if
	// there exists a Rock Ridge file with a name > 64 chars or if there are symlinks. If that is the
	// case then we also disable Joliet during the extract phase.
	if ((!enable_joliet) || (enable_rockridge && (scan_only || iso_report.has_long_filename || iso_report.has_symlinks))) {
		iso_extension_mask &= ~ISO_EXTENSION_JOLIET;
	}
	if (!enable_rockridge) {
		iso_extension_mask &= ~ISO_EXTENSION_ROCK_RIDGE;
	}

	p_iso = iso9660_open_ext(src_iso, iso_extension_mask);
	if (p_iso == NULL) {
		uprintf("Unable to open '%s' as an ISO image.\n", src_iso);
		r = 1;
		goto out;
	}
	uprintf("Disc image is an ISO9660 image\n");
	i_joliet_level = iso9660_ifs_get_joliet_level(p_iso);
	if (scan_only) {
		if (iso9660_ifs_get_volume_id(p_iso, &tmp)) {
			safe_strcpy(iso_report.label, sizeof(iso_report.label), tmp);
			safe_free(tmp);
		} else
			iso_report.label[0] = 0;
	} else {
		if (iso_extension_mask & (ISO_EXTENSION_JOLIET|ISO_EXTENSION_ROCK_RIDGE))
			uprintf("This image will be extracted using %s extensions (if present)", 
				(iso_extension_mask & ISO_EXTENSION_JOLIET)?"Joliet":"Rock Ridge");
		else
			uprintf("This image will not be extracted using any ISO extensions");
	}
	r = iso_extract_files(p_iso, "");

out:
	iso_blocking_status = -1;
	if (scan_only) {
		// Remove trailing spaces from the label
		for (j=(int)safe_strlen(iso_report.label)-1; ((j>=0)&&(isspaceU(iso_report.label[j]))); j--)
			iso_report.label[j] = 0;
		// We use the fact that UDF_BLOCKSIZE and ISO_BLOCKSIZE are the same here
		iso_report.projected_size = total_blocks * ISO_BLOCKSIZE;
		// We will link the existing isolinux.cfg from a syslinux.cfg we create
		// If multiple config files exist, choose the one with the shortest path
		// (so that a '/syslinux.cfg' is preferred over a '/isolinux/isolinux.cfg')
		if (!IsStrArrayEmpty(config_path)) {
			safe_strcpy(iso_report.cfg_path, sizeof(iso_report.cfg_path), config_path.String[0]);
			for (i=1; i<config_path.Index; i++) {
				if (safe_strlen(iso_report.cfg_path) > safe_strlen(config_path.String[i]))
					safe_strcpy(iso_report.cfg_path, sizeof(iso_report.cfg_path), config_path.String[i]);
			}
			uprintf("Will use %s for Syslinux\n", iso_report.cfg_path);
			// Extract all of the isolinux.bin files we found to identify their versions
			for (i=0; i<isolinux_path.Index; i++) {
				size = (size_t)ExtractISOFile(src_iso, isolinux_path.String[i], dot_isolinux_bin);
				if (size == 0) {
					uprintf("Could not access %s\n", isolinux_path.String[i]);
				} else {
					buf = (char*)calloc(size, 1);
					if (buf == NULL) break;
					fd = fopen(dot_isolinux_bin, "rb");
					if (fd == NULL) {
						free(buf);
						continue;
					}
					fread(buf, 1, size, fd);
					fclose(fd);
					for (k=0; k<size-16; k++) {
						if (memcmp(&buf[k], ISOLINUX, sizeof(ISOLINUX)) == 0) {
							k += sizeof(ISOLINUX);
							sl_version = (((uint8_t)strtoul(&buf[k], &tmp, 10))<<8) + (uint8_t)strtoul(&tmp[1], NULL, 10);
							if (iso_report.sl_version == 0) {
								iso_report.sl_version = sl_version;
								j = (int)i;
							} else if (iso_report.sl_version != sl_version) {
								uprintf("Found conflicting %s versions:\n  '%s' (%d.%02d) vs '%s' (%d.%02d)\n", isolinux_bin,
									isolinux_path.String[j], SL_MAJOR(iso_report.sl_version), SL_MINOR(iso_report.sl_version),
									isolinux_path.String[i], SL_MAJOR(sl_version), SL_MINOR(sl_version));
							}
							break;
						}
					}
					free(buf);
					_unlink(dot_isolinux_bin);
				}
			}
			if (iso_report.sl_version != 0) {
				static_sprintf(iso_report.sl_version_str, "%d.%02d",
					SL_MAJOR(iso_report.sl_version), SL_MINOR(iso_report.sl_version));
				uprintf("Detected Isolinux version: %s (from '%s')",
					iso_report.sl_version_str, isolinux_path.String[j]);
				if ( (has_ldlinux_c32 && (SL_MAJOR(iso_report.sl_version) < 5))
				  || (!has_ldlinux_c32 && (SL_MAJOR(iso_report.sl_version) >= 5)) )
					uprintf("Warning: Conflict between Isolinux version and the presence of ldlinux.c32...\n");
			} else {
				// Couldn't find a version from isolinux.bin. Force set to the versions we embed
				iso_report.sl_version = embedded_sl_version[has_ldlinux_c32?1:0];
				static_sprintf(iso_report.sl_version_str, "%d.%02d",
					SL_MAJOR(iso_report.sl_version), SL_MINOR(iso_report.sl_version));
				uprintf("Warning: Could not detect Isolinux version - Forcing to %s (embedded)",
					iso_report.sl_version_str);
			}
		}
		if (IS_WINPE(iso_report.winpe)) {
			// In case we have a WinPE 1.x based iso, we extract and parse txtsetup.sif
			// during scan, to see if /minint was provided for OsLoadOptions, as it decides
			// whether we should use 0x80 or 0x81 as the disk ID in the MBR
			safe_sprintf(path, sizeof(path), "/%s/txtsetup.sif", 
				basedir[((iso_report.winpe&WINPE_I386) == WINPE_I386)?0:1]);
			ExtractISOFile(src_iso, path, tmp_sif);
			tmp = get_token_data_file("OsLoadOptions", tmp_sif);
			if (tmp != NULL) {
				for (i=0; i<strlen(tmp); i++)
					tmp[i] = (char)tolower(tmp[i]);
				uprintf("Checking txtsetup.sif:\n  OsLoadOptions = %s\n", tmp);
				iso_report.uses_minint = (strstr(tmp, "/minint") != NULL);
			}
			_unlink(tmp_sif);
			safe_free(tmp);
		}
		StrArrayDestroy(&config_path);
		StrArrayDestroy(&isolinux_path);
	} else if (HAS_SYSLINUX(iso_report)) {
		safe_sprintf(path, sizeof(path), "%s\\syslinux.cfg", dest_dir);
		// Create a /syslinux.cfg (if none exists) that points to the existing isolinux cfg
		fd = fopen(path, "r");
		if (fd == NULL) {
			fd = fopen(path, "w");	// No "/syslinux.cfg" => create a new one
			if (fd == NULL) {
				uprintf("Unable to create %s - booting from USB will not work\n", path);
				r = 1;
			} else {
				fprintf(fd, "DEFAULT loadconfig\n\nLABEL loadconfig\n  CONFIG %s\n", iso_report.cfg_path);
				for (i=safe_strlen(iso_report.cfg_path); (i>0)&&(iso_report.cfg_path[i]!='/'); i--);
				if (i>0) {
					iso_report.cfg_path[i] = 0;
					fprintf(fd, "  APPEND %s/\n", iso_report.cfg_path);
					iso_report.cfg_path[i] = '/';
				}
				uprintf("Created: %s\n", path);
			}
		}
		if (fd != NULL)
			fclose(fd);
	}
	SendMessage(hISOProgressDlg, UM_ISO_EXIT, 0, 0);
	if (p_iso != NULL)
		iso9660_close(p_iso);
	if (p_udf != NULL)
		udf_close(p_udf);
	if ((r != 0) && (FormatStatus == 0))
		FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR((scan_only?ERROR_ISO_SCAN:ERROR_ISO_EXTRACT));
	return (r == 0);
}