From ff070755d5717248ccc29bb8104e9633f632de2b Mon Sep 17 00:00:00 2001 From: Pete Batard Date: Sun, 22 Jan 2012 20:54:58 +0000 Subject: [PATCH] [iso] align iso source to proposed libcdio sample --- src/iso.c | 251 +++++++++++++++------------------ src/libcdio/cdio/cdio_config.h | 4 + src/rufus.rc | 12 +- 3 files changed, 126 insertions(+), 141 deletions(-) diff --git a/src/iso.c b/src/iso.c index 1e5d1475..bf01ed50 100644 --- a/src/iso.c +++ b/src/iso.c @@ -27,32 +27,47 @@ #include #include +#include #include -#include -#include -#ifndef ISO_TEST -#include "rufus.h" -#else -#define uprintf(...) printf(__VA_ARGS__) -#endif +#include #include #include #include #include -#define print_vd_info(title, fn) \ - if (fn(p_iso, &psz_str)) { \ - uprintf(title ": %s\n", psz_str); \ - } \ - free(psz_str); \ - psz_str = NULL; +#if defined(_WIN32) +#include +#define snprintf _snprintf +#else +#include +#include +#define _mkdir(a) mkdir(a, S_IRWXU) +#endif + +#ifndef ISO_TEST +#include "rufus.h" +#else +#define uprintf printf +#endif + +#ifndef MIN +#define MIN(a,b) (((a) < (b)) ? (a) : (b)) +#endif + +#define print_vd_info(title, fn) \ + if (fn(p_iso, &psz_str)) { \ + uprintf(title ": %s\n", psz_str); \ + } \ + free(psz_str); \ + psz_str = NULL; /* Needed for UDF ISO access */ +// TODO: should be able to elmininate those with an alternate approach CdIo_t* cdio_open (const char *psz_source, driver_id_t driver_id) {return NULL;} void cdio_destroy (CdIo_t *p_cdio) {} -const char* extract_dir = "D:/tmp/iso"; +const char *psz_extract_dir = "D:/tmp/iso"; // TODO: Unicode support, timestamp preservation @@ -68,134 +83,145 @@ static void udf_print_file_info(const udf_dirent_t *p_udf_dirent, const char* ps (*psz_fname?psz_fname:"/"), ctime(&mod_time)); } -static void udf_list_files(udf_t *p_udf, udf_dirent_t *p_udf_dirent, const char *psz_path) +static int udf_extract_files(udf_t *p_udf, udf_dirent_t *p_udf_dirent, const char *psz_path) { FILE *fd = NULL; - int len; - char* fullpath; - const char* basename; + int i_length; + char* psz_fullpath; + const char* psz_basename; udf_dirent_t *p_udf_dirent2; uint8_t buf[UDF_BLOCKSIZE]; - int64_t i_read, file_len; + int64_t i_read, i_file_length; if ((p_udf_dirent == NULL) || (psz_path == NULL)) - return; + return 1; while (udf_readdir(p_udf_dirent)) { - basename = udf_get_filename(p_udf_dirent); - len = 3 + strlen(psz_path) + strlen(basename) + strlen(extract_dir); - fullpath = (char*)calloc(sizeof(char), len); - len = _snprintf(fullpath, len, "%s%s/%s", extract_dir, psz_path, basename); - if (len < 0) { - goto err; + psz_basename = udf_get_filename(p_udf_dirent); + i_length = 3 + strlen(psz_path) + strlen(psz_basename) + strlen(psz_extract_dir); + psz_fullpath = (char*)calloc(sizeof(char), i_length); + if (psz_fullpath == NULL) { + uprintf("Error allocating file name\n"); + goto out; } -uprintf("FULLPATH: %s\n", fullpath); + i_length = snprintf(psz_fullpath, i_length, "%s%s/%s", psz_extract_dir, psz_path, psz_basename); + if (i_length < 0) { + goto out; + } + uprintf("Extracting: %s\n", psz_fullpath); if (udf_is_dir(p_udf_dirent)) { - _mkdir(fullpath); + _mkdir(psz_fullpath); p_udf_dirent2 = udf_opendir(p_udf_dirent); if (p_udf_dirent2 != NULL) { - udf_list_files(p_udf, p_udf_dirent2, &fullpath[strlen(extract_dir)]); + if (udf_extract_files(p_udf, p_udf_dirent2, &psz_fullpath[strlen(psz_extract_dir)])) + goto out; } } else { - fd = fopen(fullpath, "wb"); + fd = fopen(psz_fullpath, "wb"); if (fd == NULL) { - uprintf("Unable to create file %s\n", fullpath); - goto err; + uprintf(" Unable to create file\n"); + goto out; } - file_len = udf_get_file_length(p_udf_dirent); - while (file_len > 0) { + i_file_length = udf_get_file_length(p_udf_dirent); + while (i_file_length > 0) { + memset(buf, 0, UDF_BLOCKSIZE); i_read = udf_read_block(p_udf_dirent, buf, 1); if (i_read < 0) { - uprintf("Error reading UDF file %s\n", &fullpath[strlen(extract_dir)]); - goto err; + uprintf(" Error reading UDF file %s\n", &psz_fullpath[strlen(psz_extract_dir)]); + goto out; } - fwrite(buf, (size_t)min(file_len, i_read), 1, fd); + fwrite(buf, (size_t)MIN(i_file_length, i_read), 1, fd); if (ferror(fd)) { - uprintf("Error writing file %s\n", fullpath); - goto err; + uprintf(" Error writing file\n"); + goto out; } - file_len -= i_read; + i_file_length -= i_read; } fclose(fd); fd = NULL; } - free(fullpath); + free(psz_fullpath); } - return; + return 0; -err: +out: if (fd != NULL) fclose(fd); - free(fullpath); + free(psz_fullpath); + return 1; } -static void iso_list_files(iso9660_t* p_iso, const char *psz_path) +static int iso_extract_files(iso9660_t* p_iso, const char *psz_path) { FILE *fd = NULL; - int len; - char filename[4096], *basename; - const char* iso_filename = &filename[strlen(extract_dir)]; + 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 file_len; + int64_t i_file_length; if ((p_iso == NULL) || (psz_path == NULL)) - return; + return 1; - len = _snprintf(filename, sizeof(filename), "%s%s/", extract_dir, psz_path); - if (len < 0) - return; - basename = &filename[len]; + 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) - return; + 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; // Eliminate . and .. entries - iso9660_name_translate(p_statbuf->filename, basename); - uprintf("%s [LSN %6d] %8u %s\n", (p_statbuf->type == _STAT_DIR)?"d":"-", - p_statbuf->lsn, p_statbuf->size, filename); + || (strcmp(p_statbuf->filename, "..") == 0) ) + continue; + iso9660_name_translate(p_statbuf->filename, psz_basename); if (p_statbuf->type == _STAT_DIR) { - _mkdir(filename); - iso_list_files(p_iso, iso_filename); + _mkdir(psz_fullpath); + if (iso_extract_files(p_iso, psz_iso_name)) + goto out; } else { - fd = fopen(filename, "wb"); + uprintf("Extracting: %s\n", psz_fullpath); + fd = fopen(psz_fullpath, "wb"); if (fd == NULL) { - uprintf("Unable to create file %s\n", filename); + uprintf(" Unable to create file\n"); goto out; } - file_len = p_statbuf->size; - for (i = 0; file_len > 0 ; i++) { - memset (buf, 0, ISO_BLOCKSIZE); + 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) { - uprintf("Error reading ISO 9660 file %s at LSN %lu\n", - iso_filename, (long unsigned int)lsn); + 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; } - fwrite (buf, (size_t)min(file_len, ISO_BLOCKSIZE), 1, fd); + fwrite(buf, (size_t)MIN(i_file_length, ISO_BLOCKSIZE), 1, fd); if (ferror(fd)) { - uprintf("Error writing file %s\n", filename); + uprintf(" Error writing file\n"); goto out; } - file_len -= ISO_BLOCKSIZE; + i_file_length -= ISO_BLOCKSIZE; } fclose(fd); fd = NULL; } } + r = 0; + out: if (fd != NULL) fclose(fd); _cdio_list_free(p_entlist, true); + return r; } BOOL ExtractISO(const char* src_iso, const char* dest_dir) @@ -209,37 +235,41 @@ BOOL ExtractISO(const char* src_iso, const char* dest_dir) char volset_id[UDF_VOLSET_ID_SIZE+1] = ""; cdio_loglevel_default = CDIO_LOG_DEBUG; + + /* First try to open as UDF - fallback to ISO if it failed */ p_udf = udf_open(src_iso); - if (p_udf == NULL) { - uprintf("Unable to open UDF image '%s'.\n", src_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; } 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) - uprintf("volume id: %s\n", vol_id); + uprintf("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'; - uprintf("volume set id: %s\n", volset_id); + uprintf("Volume set id: %s\n", volset_id); } - uprintf("partition number: %d\n", udf_get_part_number(p_udf)); - udf_list_files(p_udf, p_udf_root, ""); + uprintf("Partition number: %d\n", udf_get_part_number(p_udf)); + + /* Recursively extract files */ + r = udf_extract_files(p_udf, p_udf_root, ""); - r = TRUE; goto out; try_iso: p_iso = iso9660_open(src_iso); if (p_iso == NULL) { - uprintf("Unable to open ISO image '%s'.\n", src_iso); + uprintf("Unable to open image '%s'.\n", src_iso); goto out; } - /* Show basic CD info from the Primary Volume Descriptor. */ + /* 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); @@ -247,57 +277,8 @@ try_iso: print_vd_info("Volume ", iso9660_ifs_get_volume_id); print_vd_info("Volume Set ", iso9660_ifs_get_volumeset_id); - iso_list_files(p_iso, ""); - r = TRUE; + r = iso_extract_files(p_iso, ""); -#if 0 - iso9660_stat_t *statbuf; - FILE* outfd; - uint32_t i; - char file_name[] = "TEST.TST"; - char buf[ISO_BLOCKSIZE]; - - statbuf = iso9660_ifs_stat_translate(p_iso, file_name); - if (statbuf == NULL) { - uprintf("Could not get ISO-9660 file information for file %s.\n", file_name); - goto out2; - } - - if (!(outfd = fopen(file_name, "wb"))) { - uprintf("Could not open %s for writing\n", file_name); - goto out2; - } - - /* Copy the blocks from the ISO-9660 filesystem to the local filesystem. */ - for (i=0; isize; i+=ISO_BLOCKSIZE) { - memset (buf, 0, ISO_BLOCKSIZE); - if (iso9660_iso_seek_read(p_iso, buf, statbuf->lsn + (i / ISO_BLOCKSIZE), 1) != ISO_BLOCKSIZE) { - uprintf("Error reading ISO 9660 file at lsn %lu\n", (long unsigned int) statbuf->lsn + (i / ISO_BLOCKSIZE)); - goto out3; - } - - fwrite(buf, ISO_BLOCKSIZE, 1, outfd); - if (ferror (outfd)) { - uprintf("Error writing file\n"); - goto out3; - } - } - - fflush(outfd); - - /* Make sure the file size has the exact same byte size. Without the - * truncate below, the file will a multiple of ISO_BLOCKSIZE. */ - if (_chsize(_fileno(outfd), statbuf->size) != 0) { - uprintf("Error adjusting file size\n"); - goto out3; - } - - r = TRUE; - -out3: - fclose(outfd); -out2: -#endif out: if (p_iso != NULL) iso9660_close(p_iso); @@ -313,8 +294,8 @@ int main(int argc, char** argv) // ExtractISO("D:\\Incoming\\GRMSDKX_EN_DVD.iso", NULL); // ExtractISO("D:\\fd11src.iso", NULL); // ExtractISO("D:\\Incoming\\en_windows_driver_kit_3790.iso", NULL); - ExtractISO("D:\\Incoming\\en_windows_7_ultimate_with_sp1_x64_dvd_618240.iso", NULL); -// ExtractISO("D:\\Incoming\\Windows 8 Preview\\WindowsDeveloperPreview-64bit-English-Developer.iso", NULL); +// ExtractISO("D:\\Incoming\\en_windows_7_ultimate_with_sp1_x64_dvd_618240.iso", NULL); + ExtractISO("D:\\Incoming\\Windows 8 Preview\\WindowsDeveloperPreview-64bit-English-Developer.iso", NULL); #ifdef _CRTDBG_MAP_ALLOC _CrtDumpMemoryLeaks(); diff --git a/src/libcdio/cdio/cdio_config.h b/src/libcdio/cdio/cdio_config.h index b76f7c0d..f76fc8c5 100644 --- a/src/libcdio/cdio/cdio_config.h +++ b/src/libcdio/cdio/cdio_config.h @@ -97,6 +97,10 @@ /* Define to 1 if you have the ANSI C header files. */ #define STDC_HEADERS 1 +/* Number of bits in a file offset, on hosts where this is settable. */ +// TODO: should we use that for off64_t +#define _FILE_OFFSET_BITS 64 + /* Define to `__inline__' or `__inline' if that's what the C compiler calls it, or to nothing if 'inline' is not supported under any name. */ #define inline __inline diff --git a/src/rufus.rc b/src/rufus.rc index 67b7fecd..44c0b861 100644 --- a/src/rufus.rc +++ b/src/rufus.rc @@ -33,7 +33,7 @@ LANGUAGE LANG_ENGLISH, SUBLANG_NEUTRAL IDD_DIALOG DIALOGEX 12, 12, 206, 278 STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU EXSTYLE WS_EX_APPWINDOW -CAPTION "Rufus v1.0.7.142" +CAPTION "Rufus v1.0.7.143" FONT 8, "MS Shell Dlg", 400, 0, 0x1 BEGIN DEFPUSHBUTTON "Start",IDC_START,94,236,50,14 @@ -70,7 +70,7 @@ BEGIN DEFPUSHBUTTON "OK",IDOK,231,175,50,14,WS_GROUP CONTROL "http://rufus.akeo.ie",IDC_ABOUT_RUFUS_URL, "SysLink",WS_TABSTOP,46,47,114,9 - LTEXT "Version 1.0.7 (Build 142)",IDC_STATIC,46,19,78,8 + LTEXT "Version 1.0.7 (Build 143)",IDC_STATIC,46,19,78,8 PUSHBUTTON "License...",IDC_ABOUT_LICENSE,46,175,50,14,WS_GROUP EDITTEXT IDC_ABOUT_COPYRIGHTS,46,107,235,63,ES_MULTILINE | ES_READONLY | WS_VSCROLL LTEXT "Report bugs or request enhancements at:",IDC_STATIC,46,66,187,8 @@ -208,8 +208,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,0,7,142 - PRODUCTVERSION 1,0,7,142 + FILEVERSION 1,0,7,143 + PRODUCTVERSION 1,0,7,143 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -226,13 +226,13 @@ BEGIN BEGIN VALUE "CompanyName", "akeo.ie" VALUE "FileDescription", "Rufus" - VALUE "FileVersion", "1.0.7.142" + VALUE "FileVersion", "1.0.7.143" VALUE "InternalName", "Rufus" VALUE "LegalCopyright", "© 2011 Pete Batard (GPL v3)" VALUE "LegalTrademarks", "http://www.gnu.org/copyleft/gpl.html" VALUE "OriginalFilename", "rufus.exe" VALUE "ProductName", "Rufus" - VALUE "ProductVersion", "1.0.7.142" + VALUE "ProductVersion", "1.0.7.143" END END BLOCK "VarFileInfo"