static void
listdir_recur(const char *psz_path, struct iso9660_archive_file *context)
{
    iso9660_t *iso = context->iso;
    CdioList_t *entlist;
    CdioListNode_t *entnode;
    iso9660_stat_t *statbuf;
    char pathname[4096];

    entlist = iso9660_ifs_readdir (iso, psz_path);
    if (!entlist) {
        return;
    }
    /* Iterate over the list of nodes that iso9660_ifs_readdir gives  */
    _CDIO_LIST_FOREACH (entnode, entlist) {
        statbuf = (iso9660_stat_t *) _cdio_list_node_data (entnode);

        strcpy(pathname, psz_path);
        strcat(pathname, statbuf->filename);

        if (_STAT_DIR == statbuf->type ) {
            if (strcmp(statbuf->filename, ".") && strcmp(statbuf->filename, "..")) {
                strcat(pathname, "/");
                listdir_recur(pathname, context);
            }
        } else {
            //remove leading /
            context->list = g_slist_prepend( context->list,
                                             g_strdup(pathname + 1));
        }
    }
예제 #2
0
파일: iso1.c 프로젝트: AaronDnz/xbmc
int
main(int argc, const char *argv[])
{
  CdioList_t *entlist;
  CdioListNode_t *entnode;

  iso9660_t *p_iso = iso9660_open (ISO9660_IMAGE);
  
  if (NULL == p_iso) {
    fprintf(stderr, "Sorry, couldn't open ISO 9660 image %s\n", ISO9660_IMAGE);
    return 1;
  }

  entlist = iso9660_ifs_readdir (p_iso, "/");
    
  /* Iterate over the list of nodes that iso9660_ifs_readdir gives  */
  
  _CDIO_LIST_FOREACH (entnode, entlist)
    {
      char filename[4096];
      iso9660_stat_t *p_statbuf = 
	(iso9660_stat_t *) _cdio_list_node_data (entnode);
      iso9660_name_translate(p_statbuf->filename, filename);
      printf ("/%s\n", filename);
    }
예제 #3
0
파일: isolist.c 프로젝트: 3aychonok/libcdio
int
main(int argc, const char *argv[])
{
  CdioList_t *p_entlist;
  CdioListNode_t *p_entnode;
  char const *psz_fname;
  iso9660_t *p_iso;
  const char *psz_path="/";

  if (argc > 1) 
    psz_fname = argv[1];
  else 
    psz_fname = ISO9660_IMAGE;

  p_iso = iso9660_open (psz_fname);
  
  if (NULL == p_iso) {
    fprintf(stderr, "Sorry, couldn't open %s as an ISO-9660 image\n", 
	    psz_fname);
    return 1;
  }

  /* Show basic CD info from the Primary Volume Descriptor. */
  {
    char *psz_str = NULL;
    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);
  }
    
  p_entlist = iso9660_ifs_readdir (p_iso, psz_path);
    
  /* Iterate over the list of nodes that iso9660_ifs_readdir gives  */
  
  if (p_entlist) {
    _CDIO_LIST_FOREACH (p_entnode, p_entlist)
    {
      char filename[4096];
      iso9660_stat_t *p_statbuf = 
	(iso9660_stat_t *) _cdio_list_node_data (p_entnode);
      iso9660_name_translate(p_statbuf->filename, filename);
      printf ("%s [LSN %6d] %8u %s%s\n", 
	      _STAT_DIR == p_statbuf->type ? "d" : "-",
	      p_statbuf->lsn, p_statbuf->size, psz_path, filename);
    }
    
    _cdio_list_free (p_entlist, true);
  }
예제 #4
0
void DVDRipper::find_start_blocks() {
   CdioList_t *p_entlist;
   CdioListNode_t *p_entnode;
   
   if (!p_iso)
      return;
   
   p_entlist = iso9660_ifs_readdir (p_iso, "/video_ts/");
   
   if (p_entlist) {
      _CDIO_LIST_FOREACH (p_entnode, p_entlist) {
	 unsigned long long start;
	 unsigned long long blocks;
	 
	 char filename[4096];
	 int len;
	 
	 iso9660_stat_t *p_statbuf =
	    (iso9660_stat_t *) _cdio_list_node_data (p_entnode);
	 iso9660_name_translate(p_statbuf->filename, filename);
	 len = strlen(filename);
	 
	 if (!(2 == p_statbuf->type) ) {
	    if (! strcmp(filename + (len-3), "vob")) {
	       start = p_statbuf->lsn;
	       blocks = CEILING(p_statbuf->size, DVDCSS_BLOCK_SIZE);
	       
	       start_map[start] = strdup(filename);

	       if (blocks == 0) {
		  //file length of 0 would result in a blocks of 0, and don't want
		  //to subtract one from it.
		  end_blocks[start] = start;
	       } else {
		  //-1 as start block is included in count of blocks
		  end_blocks[start] = start - 1 + blocks;
	       }
	       
	       printf("%s: %llu->%llu (%llu blocks)\n", filename, start, end_blocks[start], blocks);
	       
	       if (blocks) {
		  if (find(start_blocks.begin(), start_blocks.end(), start) == start_blocks.end()) {
		     start_blocks.push_back(start);
		  }
	       }
	    }
	 }
      }
      
      _cdio_list_free (p_entlist, true);
   }
예제 #5
0
파일: isofuzzy.c 프로젝트: flyingtime/boxee
int
main(int argc, const char *argv[])
{
  CdioList_t *entlist;
  CdioListNode_t *entnode;
  char const *psz_fname;
  iso9660_t *p_iso;

  if (argc > 1) 
    psz_fname = argv[1];
  else 
    psz_fname = ISO9660_IMAGE;

  p_iso = iso9660_open_fuzzy (psz_fname, 5);
  
  if (NULL == p_iso) {
    fprintf(stderr, "Sorry, could not find an ISO 9660 image from %s\n", 
	    psz_fname);
    return 1;
  }

  entlist = iso9660_ifs_readdir (p_iso, "/");
    
  /* Iterate over the list of nodes that iso9660_ifs_readdir gives  */

  if (entlist) {
    _CDIO_LIST_FOREACH (entnode, entlist)
    {
      char filename[4096];
      iso9660_stat_t *p_statbuf = 
	(iso9660_stat_t *) _cdio_list_node_data (entnode);
      iso9660_name_translate(p_statbuf->filename, filename);
      printf ("/%s\n", filename);
    }

    _cdio_list_free (entlist, true);
  }
예제 #6
0
파일: iso.c 프로젝트: JBTech/rufus
// Returns 0 on success, nonzero on error
static int iso_extract_files(iso9660_t* p_iso, const char *psz_path)
{
	HANDLE file_handle = NULL;
	DWORD buf_size, wr_size, err;
	BOOL s, is_syslinux_cfg, is_old_c32[NB_OLD_C32], is_symlink;
	int i_length, r = 1;
	char tmp[128], psz_fullpath[1024], *psz_basename;
	const char *psz_iso_name = &psz_fullpath[strlen(psz_extract_dir)];
	unsigned char buf[ISO_BLOCKSIZE];
	CdioListNode_t* p_entnode;
	iso9660_stat_t *p_statbuf;
	CdioList_t* p_entlist;
	size_t i, j, nul_pos;
	lsn_t lsn;
	int64_t i_file_length;

	if ((p_iso == NULL) || (psz_path == NULL))
		return 1;

	i_length = _snprintf(psz_fullpath, sizeof(psz_fullpath), "%s%s/", psz_extract_dir, psz_path);
	if (i_length < 0)
		return 1;
	psz_basename = &psz_fullpath[i_length];

	p_entlist = iso9660_ifs_readdir(p_iso, psz_path);
	if (!p_entlist) {
		uprintf("Could not access directory %s\n", psz_path);
		return 1;
	}

	_CDIO_LIST_FOREACH(p_entnode, p_entlist) {
		if (FormatStatus) goto out;
		p_statbuf = (iso9660_stat_t*) _cdio_list_node_data(p_entnode);
		// Eliminate . and .. entries
		if ( (strcmp(p_statbuf->filename, ".") == 0)
			|| (strcmp(p_statbuf->filename, "..") == 0) )
			continue;
		// Rock Ridge requires an exception
		is_symlink = FALSE;
		if ((p_statbuf->rr.b3_rock == yep) && enable_rockridge) {
			safe_strcpy(psz_basename, sizeof(psz_fullpath)-i_length-1, p_statbuf->filename);
			if (safe_strlen(p_statbuf->filename) > 64)
				iso_report.has_long_filename = TRUE;
			// libcdio has a memleak for Rock Ridge symlinks. It doesn't look like there's an easy fix there as
			// a generic list that's unaware of RR extensions is being used, so we prevent that memleak ourselves
			is_symlink = (p_statbuf->rr.psz_symlink != NULL);
			if (is_symlink)
				iso_report.has_symlinks = TRUE;
			if (scan_only)
				safe_free(p_statbuf->rr.psz_symlink);
		} else {
			iso9660_name_translate_ext(p_statbuf->filename, psz_basename, i_joliet_level);
		}
		if (p_statbuf->type == _STAT_DIR) {
			if (!scan_only) _mkdirU(psz_fullpath);
			if (iso_extract_files(p_iso, psz_iso_name))
				goto out;
		} else {
			i_file_length = p_statbuf->size;
			if (check_iso_props(psz_path, &is_syslinux_cfg, is_old_c32, i_file_length, psz_basename, psz_fullpath)) {
				continue;
			}
			// Replace slashes with backslashes and append the size to the path for UI display
			nul_pos = safe_strlen(psz_fullpath);
			for (i=0; i<nul_pos; i++)
				if (psz_fullpath[i] == '/') psz_fullpath[i] = '\\';
			safe_sprintf(&psz_fullpath[nul_pos], 24, " (%s)", SizeToHumanReadable(i_file_length, TRUE, FALSE));
			uprintf("Extracting: %s\n", psz_fullpath);
			safe_sprintf(&psz_fullpath[nul_pos], 24, " (%s)", SizeToHumanReadable(i_file_length, FALSE, FALSE));
			SetWindowTextU(hISOFileName, psz_fullpath);
			// ISO9660 cannot handle backslashes
			for (i=0; i<nul_pos; i++) if (psz_fullpath[i] == '\\') psz_fullpath[i] = '/';
			psz_fullpath[nul_pos] = 0;
			for (i=0; i<NB_OLD_C32; i++) {
				if (is_old_c32[i] && use_own_c32[i]) {
					static_sprintf(tmp, "%s/syslinux-%s/%s", FILES_DIR, embedded_sl_version_str[0], old_c32_name[i]);
					if (CopyFileA(tmp, psz_fullpath, FALSE)) {
						uprintf("  Replaced with local version\n");
						break;
					}
					uprintf("  Could not replace file: %s\n", WindowsErrorString());
				}
			}
			if (i < NB_OLD_C32)
				continue;
			if (sanitize_filename(psz_fullpath))
				uprintf("  File name sanitized to '%s'\n", psz_fullpath);
			if (is_symlink) {
				if (i_file_length == 0)
					uprintf("  Ignoring Rock Ridge symbolic link to '%s'\n", p_statbuf->rr.psz_symlink);
				safe_free(p_statbuf->rr.psz_symlink);
			}
			file_handle = CreateFileU(psz_fullpath, GENERIC_READ | GENERIC_WRITE,
				FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
			if (file_handle == INVALID_HANDLE_VALUE) {
				err = GetLastError();
				uprintf("  Unable to create file: %s\n", WindowsErrorString());
				if ((err == ERROR_ACCESS_DENIED) && (safe_strcmp(&psz_fullpath[3], autorun_name) == 0))
					uprintf(stupid_antivirus);
				else
					goto out;
			} else for (i=0; i_file_length>0; i++) {
				if (FormatStatus) goto out;
				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",
						psz_iso_name, (long unsigned int)lsn);
					goto out;
				}
				buf_size = (DWORD)MIN(i_file_length, ISO_BLOCKSIZE);
				for (j=0; j<WRITE_RETRIES; j++) {
					ISO_BLOCKING(s = WriteFile(file_handle, buf, buf_size, &wr_size, NULL));
					if ((!s) || (buf_size != wr_size)) {
						uprintf("  Error writing file: %s", WindowsErrorString());
						if (j < WRITE_RETRIES-1)
							uprintf("  RETRYING...\n");
					} else {
						break;
					}
				}
				if (j >= WRITE_RETRIES) goto out;
				i_file_length -= ISO_BLOCKSIZE;
				if (nb_blocks++ % PROGRESS_THRESHOLD == 0) {
					SendMessage(hISOProgressBar, PBM_SETPOS, (WPARAM)((MAX_PROGRESS*nb_blocks)/total_blocks), 0);
					UpdateProgress(OP_DOS, 100.0f*nb_blocks/total_blocks);
				}
			}
			ISO_BLOCKING(safe_closehandle(file_handle));
			if (is_syslinux_cfg) {
				if (replace_in_token_data(psz_fullpath, "append", iso_report.label, iso_report.usb_label, TRUE) != NULL)
					uprintf("Patched %s: '%s' -> '%s'\n", psz_fullpath, iso_report.label, iso_report.usb_label);
			}
		}
	}
	r = 0;

out:
	ISO_BLOCKING(safe_closehandle(file_handle));
	_cdio_list_free(p_entlist, true);
	return r;
}
예제 #7
0
static int iso_extract_files(iso9660_t* p_iso, const char *psz_path)
{
  FILE *fd = NULL;
  int i_length, r = 1;
  char psz_fullpath[4096], *psz_basename;
  const char *psz_iso_name = &psz_fullpath[strlen(psz_extract_dir)];
  unsigned char buf[ISO_BLOCKSIZE];
  CdioListNode_t* p_entnode;
  iso9660_stat_t *p_statbuf;
  CdioList_t* p_entlist;
  size_t i;
  lsn_t lsn;
  int64_t i_file_length;

  if ((p_iso == NULL) || (psz_path == NULL))
    return 1;

  i_length = snprintf(psz_fullpath, sizeof(psz_fullpath), "%s%s/", psz_extract_dir, psz_path);
  if (i_length < 0)
    return 1;
  psz_basename = &psz_fullpath[i_length];

  p_entlist = iso9660_ifs_readdir(p_iso, psz_path);
  if (!p_entlist) {
    printf("Could not access %s\n", psz_path);
    return 1;
  }

  _CDIO_LIST_FOREACH (p_entnode, p_entlist) {
    p_statbuf = (iso9660_stat_t*) _cdio_list_node_data(p_entnode);
    /* Eliminate . and .. entries */
    if ( (strcmp(p_statbuf->filename, ".") == 0)
      || (strcmp(p_statbuf->filename, "..") == 0) )
      continue;
    iso9660_name_translate_ext(p_statbuf->filename, psz_basename, i_joliet_level);
    if (p_statbuf->type == _STAT_DIR) {
      _mkdir(psz_fullpath);
      if (iso_extract_files(p_iso, psz_iso_name))
        goto out;
    } else {
      printf("Extracting: %s\n", psz_fullpath);
      fd = fopen(psz_fullpath, "wb");
      if (fd == NULL) {
        fprintf(stderr, "  Unable to create file\n");
        goto out;
      }
      i_file_length = p_statbuf->size;
      for (i = 0; i_file_length > 0; i++) {
        memset(buf, 0, ISO_BLOCKSIZE);
        lsn = p_statbuf->lsn + i;
        if (iso9660_iso_seek_read(p_iso, buf, lsn, 1) != ISO_BLOCKSIZE) {
          fprintf(stderr, "  Error reading ISO9660 file %s at LSN %lu\n",
            psz_iso_name, (long unsigned int)lsn);
          goto out;
        }
        fwrite(buf, (size_t)MIN(i_file_length, ISO_BLOCKSIZE), 1, fd);
        if (ferror(fd)) {
	  fprintf(stderr, "  Error writing file %s: %s\n", psz_iso_name,
		  strerror(errno));
          goto out;
        }
        i_file_length -= ISO_BLOCKSIZE;
      }
      fclose(fd);
      fd = NULL;
    }
  }
예제 #8
0
파일: iso-info.c 프로젝트: Crome/libcdio
static void
print_iso9660_recurse (iso9660_t *p_iso, const char psz_path[])
{
  CdioList_t *entlist;
  CdioList_t *dirlist =  _cdio_list_new ();
  CdioListNode_t *entnode;
  uint8_t i_joliet_level = iso9660_ifs_get_joliet_level(p_iso);
  char *translated_name = (char *) malloc(4096);
  size_t translated_name_size = 4096;
  entlist = iso9660_ifs_readdir (p_iso, psz_path);
    
  if (opts.print_iso9660) {
    printf ("%s:\n", psz_path);
  }

  if (NULL == entlist) {
    report( stderr, "Error getting above directory information\n" );
    return;
  }

  /* Iterate over files in this directory */
  
  _CDIO_LIST_FOREACH (entnode, entlist)
    {
      iso9660_stat_t *p_statbuf = _cdio_list_node_data (entnode);
      char *psz_iso_name = p_statbuf->filename;
      char _fullname[4096] = { 0, };
       if (strlen(psz_iso_name) >= translated_name_size) {
         translated_name_size = strlen(psz_iso_name)+1;
         free(translated_name);
         translated_name = (char *) malloc(translated_name_size);
         if (!translated_name) {
           report( stderr, "Error allocating memory\n" );
           return;
         }
       }

      if (yep != p_statbuf->rr.b3_rock || 1 == opts.no_rock_ridge) {
	iso9660_name_translate_ext(psz_iso_name, translated_name, 
				   i_joliet_level);
	snprintf (_fullname, sizeof (_fullname), "%s%s", psz_path, 
		  translated_name);
      } else {
	snprintf (_fullname, sizeof (_fullname), "%s%s", psz_path, 
		  psz_iso_name);
      }
      
      strncat (_fullname, "/", sizeof (_fullname));

      if (p_statbuf->type == _STAT_DIR
          && strcmp (psz_iso_name, ".") 
          && strcmp (psz_iso_name, ".."))
        _cdio_list_append (dirlist, strdup (_fullname));

      if (opts.print_iso9660) {
	print_fs_attrs(p_statbuf, 
		       0 == opts.no_rock_ridge,
		       iso9660_ifs_is_xa(p_iso) && 0 == opts.no_xa,
		       psz_iso_name, translated_name);
      } else 
	if ( strcmp (psz_iso_name, ".") && strcmp (psz_iso_name, ".."))
	  printf("%9u %s%s\n", (unsigned int) p_statbuf->size, psz_path, 
		 yep == p_statbuf->rr.b3_rock 
		 ? psz_iso_name : translated_name);
      if (p_statbuf->rr.i_symlink) {
	free(p_statbuf->rr.psz_symlink);
	p_statbuf->rr.i_symlink = 0;
      }
    }
예제 #9
0
파일: iso.c 프로젝트: ShaRose/rufus
// Returns 0 on success, nonzero on error
static int iso_extract_files(iso9660_t* p_iso, const char *psz_path)
{
	HANDLE file_handle = NULL;
	DWORD buf_size, wr_size, err;
	EXTRACT_PROPS props;
	BOOL is_symlink, is_identical;
	int i_length, r = 1;
	char tmp[128], psz_fullpath[MAX_PATH], *psz_basename, *psz_sanpath;
	const char *psz_iso_name = &psz_fullpath[strlen(psz_extract_dir)];
	unsigned char buf[ISO_BLOCKSIZE];
	CdioListNode_t* p_entnode;
	iso9660_stat_t *p_statbuf;
	CdioList_t* p_entlist;
	size_t i;
	lsn_t lsn;
	int64_t i_file_length;

	if ((p_iso == NULL) || (psz_path == NULL))
		return 1;

	i_length = _snprintf(psz_fullpath, sizeof(psz_fullpath), "%s%s/", psz_extract_dir, psz_path);
	if (i_length < 0)
		return 1;
	psz_basename = &psz_fullpath[i_length];

	p_entlist = iso9660_ifs_readdir(p_iso, psz_path);
	if (!p_entlist) {
		uprintf("Could not access directory %s", psz_path);
		return 1;
	}

	_CDIO_LIST_FOREACH(p_entnode, p_entlist) {
		if (FormatStatus) goto out;
		p_statbuf = (iso9660_stat_t*) _cdio_list_node_data(p_entnode);
		// Eliminate . and .. entries
		if ( (strcmp(p_statbuf->filename, ".") == 0)
			|| (strcmp(p_statbuf->filename, "..") == 0) )
			continue;
		// Rock Ridge requires an exception
		is_symlink = FALSE;
		if ((p_statbuf->rr.b3_rock == yep) && enable_rockridge) {
			safe_strcpy(psz_basename, sizeof(psz_fullpath)-i_length-1, p_statbuf->filename);
			if (safe_strlen(p_statbuf->filename) > 64)
				img_report.has_long_filename = TRUE;
			// libcdio has a memleak for Rock Ridge symlinks. It doesn't look like there's an easy fix there as
			// a generic list that's unaware of RR extensions is being used, so we prevent that memleak ourselves
			is_symlink = (p_statbuf->rr.psz_symlink != NULL);
			if (is_symlink)
				img_report.has_symlinks = TRUE;
			if (scan_only)
				safe_free(p_statbuf->rr.psz_symlink);
		} else {
			iso9660_name_translate_ext(p_statbuf->filename, psz_basename, i_joliet_level);
		}
		if (p_statbuf->type == _STAT_DIR) {
			if (!scan_only) {
				psz_sanpath = sanitize_filename(psz_fullpath, &is_identical);
				IGNORE_RETVAL(_mkdirU(psz_sanpath));
				if (preserve_timestamps) {
					LPFILETIME ft = to_filetime(mktime(&p_statbuf->tm));
					set_directory_timestamp(psz_sanpath, ft, ft, ft);
				}
				safe_free(psz_sanpath);
			}
			if (iso_extract_files(p_iso, psz_iso_name))
				goto out;
		} else {
			i_file_length = p_statbuf->size;
			if (check_iso_props(psz_path, i_file_length, psz_basename, psz_fullpath, &props)) {
				continue;
			}
			print_extracted_file(psz_fullpath, i_file_length);
			for (i=0; i<NB_OLD_C32; i++) {
				if (props.is_old_c32[i] && use_own_c32[i]) {
					static_sprintf(tmp, "%s/syslinux-%s/%s", FILES_DIR, embedded_sl_version_str[0], old_c32_name[i]);
					if (CopyFileU(tmp, psz_fullpath, FALSE)) {
						uprintf("  Replaced with local version %s", IsFileInDB(tmp)?"✓":"✗");
						break;
					}
					uprintf("  Could not replace file: %s", WindowsErrorString());
				}
			}
			if (i < NB_OLD_C32)
				continue;
			psz_sanpath = sanitize_filename(psz_fullpath, &is_identical);
			if (!is_identical)
				uprintf("  File name sanitized to '%s'", psz_sanpath);
			if (is_symlink) {
				if (i_file_length == 0)
					uprintf("  Ignoring Rock Ridge symbolic link to '%s'", p_statbuf->rr.psz_symlink);
				safe_free(p_statbuf->rr.psz_symlink);
			}
			file_handle = CreateFileU(psz_sanpath, GENERIC_READ | GENERIC_WRITE,
				FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
			if (file_handle == INVALID_HANDLE_VALUE) {
				err = GetLastError();
				uprintf("  Unable to create file: %s", WindowsErrorString());
				if ((err == ERROR_ACCESS_DENIED) && (safe_strcmp(&psz_sanpath[3], autorun_name) == 0))
					uprintf(stupid_antivirus);
				else
					goto out;
			} else for (i=0; i_file_length>0; i++) {
				if (FormatStatus) goto out;
				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",
						psz_iso_name, (long unsigned int)lsn);
					goto out;
				}
				buf_size = (DWORD)MIN(i_file_length, ISO_BLOCKSIZE);
				ISO_BLOCKING(r = WriteFileWithRetry(file_handle, buf, buf_size, &wr_size, WRITE_RETRIES));
				if (!r) {
					uprintf("  Error writing file: %s", WindowsErrorString());
					goto out;
				}
				i_file_length -= ISO_BLOCKSIZE;
				if (nb_blocks++ % PROGRESS_THRESHOLD == 0)
					UpdateProgress(OP_DOS, 100.0f*nb_blocks/total_blocks);
			}
			if (preserve_timestamps) {
				LPFILETIME ft = to_filetime(mktime(&p_statbuf->tm));
				if (!SetFileTime(file_handle, ft, ft, ft))
					uprintf("  Could not set timestamp: %s", WindowsErrorString());
			}
			ISO_BLOCKING(safe_closehandle(file_handle));
			if (props.is_syslinux_cfg || props.is_grub_cfg)
				fix_config(psz_sanpath, psz_path, psz_basename, &props);
			safe_free(psz_sanpath);
		}
	}
	r = 0;

out:
	ISO_BLOCKING(safe_closehandle(file_handle));
	_cdio_list_free(p_entlist, true);
	return r;
}
예제 #10
0
파일: iso.c 프로젝트: hanji/rufus
// Returns 0 on success, nonzero on error
static int iso_extract_files(iso9660_t* p_iso, const char *psz_path)
{
	HANDLE file_handle = NULL;
	DWORD buf_size, wr_size;
	BOOL s, is_syslinux_cfg, is_old_vesamenu;
	int i_length, r = 1;
	char psz_fullpath[1024], *psz_basename;
	const char *psz_iso_name = &psz_fullpath[strlen(psz_extract_dir)];
	unsigned char buf[ISO_BLOCKSIZE];
	CdioListNode_t* p_entnode;
	iso9660_stat_t *p_statbuf;
	CdioList_t* p_entlist;
	size_t i, nul_pos;
	lsn_t lsn;
	int64_t i_file_length;

	if ((p_iso == NULL) || (psz_path == NULL))
		return 1;

	i_length = safe_sprintf(psz_fullpath, sizeof(psz_fullpath), "%s%s/", psz_extract_dir, psz_path);
	if (i_length < 0)
		return 1;
	psz_basename = &psz_fullpath[i_length];

	p_entlist = iso9660_ifs_readdir(p_iso, psz_path);
	if (!p_entlist) {
		uprintf("Could not access directory %s\n", psz_path);
		return 1;
	}

	_CDIO_LIST_FOREACH(p_entnode, p_entlist) {
		if (FormatStatus) goto out;
		p_statbuf = (iso9660_stat_t*) _cdio_list_node_data(p_entnode);
		/* Eliminate . and .. entries */
		if ( (strcmp(p_statbuf->filename, ".") == 0)
			|| (strcmp(p_statbuf->filename, "..") == 0) )
			continue;
		iso9660_name_translate_ext(p_statbuf->filename, psz_basename, i_joliet_level);
		if (p_statbuf->type == _STAT_DIR) {
			if (!scan_only) _mkdirU(psz_fullpath);
			if (iso_extract_files(p_iso, psz_iso_name))
				goto out;
		} else {
			i_file_length = p_statbuf->size;
			if (check_iso_props(psz_path, &is_syslinux_cfg, &is_old_vesamenu, i_file_length, psz_basename, psz_fullpath)) {
				continue;
			}
			// Replace slashes with backslashes and append the size to the path for UI display
			nul_pos = safe_strlen(psz_fullpath);
			for (i=0; i<nul_pos; i++) if (psz_fullpath[i] == '/') psz_fullpath[i] = '\\';
			safe_strcpy(&psz_fullpath[nul_pos], 24, size_to_hr(i_file_length));
			uprintf("Extracting: %s\n", psz_fullpath);
			SetWindowTextU(hISOFileName, psz_fullpath);
			// ISO9660 cannot handle backslashes
			for (i=0; i<nul_pos; i++) if (psz_fullpath[i] == '\\') psz_fullpath[i] = '/';
			psz_fullpath[nul_pos] = 0;
			if (is_old_vesamenu && use_own_vesamenu) {
				if (CopyFileA("vesamenu.c32", psz_fullpath, FALSE)) {
					uprintf("  Replaced with local version\n");
					continue;
				}
				uprintf("  Could not replace file: %s\n", WindowsErrorString());
			}
			file_handle = CreateFileU(psz_fullpath, 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\n", WindowsErrorString());
				goto out;
			}
			for (i = 0; i_file_length > 0; i++) {
				if (FormatStatus) goto out;
				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",
						psz_iso_name, (long unsigned int)lsn);
					goto out;
				}
				buf_size = (DWORD)MIN(i_file_length, ISO_BLOCKSIZE);
				ISO_BLOCKING(s = WriteFile(file_handle, buf, buf_size, &wr_size, NULL));
				if ((!s) || (buf_size != wr_size)) {
					uprintf("  Error writing file: %s\n", WindowsErrorString());
					goto out;
				}
				i_file_length -= ISO_BLOCKSIZE;
				if (nb_blocks++ % PROGRESS_THRESHOLD == 0) {
					SendMessage(hISOProgressBar, PBM_SETPOS, (WPARAM)((MAX_PROGRESS*nb_blocks)/total_blocks), 0);
					UpdateProgress(OP_DOS, 100.0f*nb_blocks/total_blocks);
				}
			}
			ISO_BLOCKING(safe_closehandle(file_handle));
			if (is_syslinux_cfg) {
				if (replace_in_token_data(psz_fullpath, "append", iso_report.label, iso_report.usb_label, TRUE) != NULL)
					uprintf("Patched %s: '%s' -> '%s'\n", psz_fullpath, iso_report.label, iso_report.usb_label);
			}
		}
	}
	r = 0;

out:
	ISO_BLOCKING(safe_closehandle(file_handle));
	_cdio_list_free(p_entlist, true);
	return r;
}