コード例 #1
0
ファイル: iso.c プロジェクト: ShaRose/rufus
uint32_t GetInstallWimVersion(const char* iso)
{
	char *wim_path = NULL, *p, buf[UDF_BLOCKSIZE] = { 0 };
	uint32_t* wim_header = (uint32_t*)buf, r = 0xffffffff;
	iso9660_t* p_iso = NULL;
	udf_t* p_udf = NULL;
	udf_dirent_t *p_udf_root = NULL, *p_udf_file = NULL;
	iso9660_stat_t *p_statbuf = NULL;

	wim_path = safe_strdup(&img_report.install_wim_path[2]);
	if (wim_path == NULL)
		goto out;
	// UDF indiscriminately accepts slash or backslash delimiters,
	// but ISO-9660 requires slash
	for (p = wim_path; *p != 0; p++)
		if (*p == '\\') *p = '/';

	// First try to open as UDF - fallback to ISO if it failed
	p_udf = udf_open(iso);
	if (p_udf == NULL)
		goto try_iso;

	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;
	}
	p_udf_file = udf_fopen(p_udf_root, wim_path);
	if (!p_udf_file) {
		uprintf("Could not locate file %s in ISO image\n", wim_path);
		goto out;
	}
	if (udf_read_block(p_udf_file, buf, 1) != UDF_BLOCKSIZE) {
		uprintf("Error reading UDF file %s\n", wim_path);
		goto out;
	}
	r = wim_header[3];
	goto out;

try_iso:
	p_iso = iso9660_open(iso);
	if (p_iso == NULL) {
		uprintf("Unable to open image '%s'.\n", iso);
		goto out;
	}
	p_statbuf = iso9660_ifs_stat_translate(p_iso, wim_path);
	if (p_statbuf == NULL) {
		uprintf("Could not get ISO-9660 file information for file %s\n", wim_path);
		goto out;
	}
	if (iso9660_iso_seek_read(p_iso, buf, p_statbuf->lsn, 1) != ISO_BLOCKSIZE) {
		uprintf("Error reading ISO9660 file %s at LSN %lu\n", wim_path, (long unsigned int)p_statbuf->lsn);
		goto out;
	}
	r = wim_header[3];

out:
	if (p_statbuf != NULL)
		safe_free(p_statbuf->rr.psz_symlink);
	safe_free(p_statbuf);
	if (p_udf_root != NULL)
		udf_dirent_free(p_udf_root);
	if (p_udf_file != NULL)
		udf_dirent_free(p_udf_file);
	if (p_iso != NULL)
		iso9660_close(p_iso);
	if (p_udf != NULL)
		udf_close(p_udf);
	safe_free(wim_path);
	return bswap_uint32(r);
}
コード例 #2
0
ファイル: iso.c プロジェクト: JBTech/rufus
int64_t ExtractISOFile(const char* iso, const char* iso_file, const char* dest_file)
{
	size_t i;
	ssize_t read_size;
	int64_t file_length, r = 0;
	char buf[UDF_BLOCKSIZE];
	DWORD buf_size, wr_size;
	BOOL s;
	iso9660_t* p_iso = NULL;
	udf_t* p_udf = NULL; 
	udf_dirent_t *p_udf_root = NULL, *p_udf_file = NULL;
	iso9660_stat_t *p_statbuf = NULL;
	lsn_t lsn;
	HANDLE file_handle = INVALID_HANDLE_VALUE;

	file_handle = CreateFileU(dest_file, GENERIC_READ | GENERIC_WRITE,
		FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
	if (file_handle == INVALID_HANDLE_VALUE) {
		uprintf("  Unable to create file %s: %s\n", dest_file, WindowsErrorString());
		goto out;
	}

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

	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;
	}
	p_udf_file = udf_fopen(p_udf_root, iso_file);
	if (!p_udf_file) {
		uprintf("Couldn't locate file %s in ISO image\n", iso_file);
		goto out;
	}
	file_length = udf_get_file_length(p_udf_file);
	while (file_length > 0) {
		memset(buf, 0, UDF_BLOCKSIZE);
		read_size = udf_read_block(p_udf_file, buf, 1);
		if (read_size < 0) {
			uprintf("Error reading UDF file %s\n", iso_file);
			goto out;
		}
		buf_size = (DWORD)MIN(file_length, read_size);
		s = WriteFile(file_handle, buf, buf_size, &wr_size, NULL);
		if ((!s) || (buf_size != wr_size)) {
			uprintf("  Error writing file %s: %s\n", dest_file, WindowsErrorString());
			goto out;
		}
		file_length -= read_size;
		r += read_size;
	}
	goto out;

try_iso:
	p_iso = iso9660_open(iso);
	if (p_iso == NULL) {
		uprintf("Unable to open image '%s'.\n", iso);
		goto out;
	}

	p_statbuf = iso9660_ifs_stat_translate(p_iso, iso_file);
	if (p_statbuf == NULL) {
		uprintf("Could not get ISO-9660 file information for file %s\n", iso_file);
		goto out;
	}

	file_length = p_statbuf->size;
	for (i = 0; file_length > 0; i++) {
		memset(buf, 0, ISO_BLOCKSIZE);
		lsn = p_statbuf->lsn + (lsn_t)i;
		if (iso9660_iso_seek_read(p_iso, buf, lsn, 1) != ISO_BLOCKSIZE) {
			uprintf("  Error reading ISO9660 file %s at LSN %lu\n", iso_file, (long unsigned int)lsn);
			goto out;
		}
		buf_size = (DWORD)MIN(file_length, ISO_BLOCKSIZE);
		s = WriteFile(file_handle, buf, buf_size, &wr_size, NULL);
		if ((!s) || (buf_size != wr_size)) {
			uprintf("  Error writing file %s: %s\n", dest_file, WindowsErrorString());
			goto out;
		}
		file_length -= ISO_BLOCKSIZE;
		r += ISO_BLOCKSIZE;
	}

out:
	safe_closehandle(file_handle);
	if (p_statbuf != NULL)
		safe_free(p_statbuf->rr.psz_symlink);
	safe_free(p_statbuf);
	if (p_udf_root != NULL)
		udf_dirent_free(p_udf_root);
	if (p_udf_file != NULL)
		udf_dirent_free(p_udf_file);
	if (p_iso != NULL)
		iso9660_close(p_iso);
	if (p_udf != NULL)
		udf_close(p_udf);
	return r;
}
コード例 #3
0
ファイル: udffile.c プロジェクト: 3aychonok/libcdio
int
main(int argc, const char *argv[])
{
  udf_t *p_udf;
  FILE *p_outfd;
  char const *psz_udf_image;
  char const *psz_udf_fname;
  char const *psz_local_fname;

  if (argc > 1) 
    psz_udf_image = argv[1];
  else 
    psz_udf_image = UDF_IMAGE;

  if (argc > 2) 
    psz_udf_fname = argv[2];
  else 
    psz_udf_fname = UDF_FILENAME;

  if (argc > 3) 
    psz_local_fname = argv[3];
  else 
    psz_local_fname = LOCAL_FILENAME;


  p_udf = udf_open (psz_udf_image);
  
  if (NULL == p_udf) {
    fprintf(stderr, "Sorry, couldn't open %s as something using UDF\n", 
	    psz_udf_image);
    return 1;
  } else {
    udf_dirent_t *p_udf_root = udf_get_root(p_udf, true, 0);
    udf_dirent_t *p_udf_file = NULL;
    if (NULL == p_udf_root) {
      fprintf(stderr, "Sorry, couldn't find / in %s\n", 
	      psz_udf_image);
      return 1;
    }
    
    p_udf_file = udf_fopen(p_udf_root, psz_udf_fname);
    if (!p_udf_file) {
      fprintf(stderr, "Sorry, couldn't find %s in %s\n", 
	      psz_udf_fname, psz_udf_image);
      return 2;
      
    }

    if (!(p_outfd = fopen (psz_local_fname, "wb")))
      {
	perror ("fopen()");
	return 3;
    }

    {
      uint64_t i_file_length = udf_get_file_length(p_udf_file);
      const unsigned int i_blocks = (unsigned int) CEILING(i_file_length, UDF_BLOCKSIZE);
      unsigned int i;
      for (i = 0; i < i_blocks ; i++) {
	char buf[UDF_BLOCKSIZE] = {'\0',};
	ssize_t i_read = udf_read_block(p_udf_file, buf, 1);

	if ( i_read < 0 ) {
	  fprintf(stderr, "Error reading UDF file %s at block %u\n",
		  psz_local_fname, i);
	  return 4;
	}

	fwrite (buf, i_read, 1, p_outfd);

	if (ferror (p_outfd)) {
	  perror ("fwrite()");
	  return 5;
	}
      }

      fflush (p_outfd);
      udf_dirent_free(p_udf_root);
      udf_close(p_udf);
      /* Make sure the file size has the exact same byte size. Without the
	 truncate below, the file will a multiple of UDF_BLOCKSIZE.
      */
      if (ftruncate (fileno (p_outfd), i_file_length))
	perror ("ftruncate()");
      
      printf("Extraction of file '%s' from %s successful.\n", 
	     psz_local_fname, psz_udf_image);
      
      return 0;
    }
  }
}