mirror of
				https://github.com/pbatard/rufus.git
				synced 2024-08-14 23:57:05 +00:00 
			
		
		
		
	[iso] align iso source to proposed libcdio sample
This commit is contained in:
		
							parent
							
								
									0cca99b0ef
								
							
						
					
					
						commit
						ff070755d5
					
				
					 3 changed files with 126 additions and 141 deletions
				
			
		
							
								
								
									
										231
									
								
								src/iso.c
									
										
									
									
									
								
							
							
						
						
									
										231
									
								
								src/iso.c
									
										
									
									
									
								
							|  | @ -27,20 +27,34 @@ | |||
| 
 | ||||
| #include <windows.h> | ||||
| #include <stdio.h> | ||||
| #include <string.h> | ||||
| #include <malloc.h> | ||||
| #include <io.h> | ||||
| #include <direct.h> | ||||
| #ifndef ISO_TEST | ||||
| #include "rufus.h" | ||||
| #else | ||||
| #define uprintf(...) printf(__VA_ARGS__) | ||||
| #endif | ||||
| #include <errno.h> | ||||
| 
 | ||||
| #include <cdio/cdio.h> | ||||
| #include <cdio/logging.h> | ||||
| #include <cdio/iso9660.h> | ||||
| #include <cdio/udf.h> | ||||
| 
 | ||||
| #if defined(_WIN32) | ||||
| #include <direct.h> | ||||
| #define snprintf _snprintf | ||||
| #else | ||||
| #include <sys/stat.h> | ||||
| #include <sys/types.h> | ||||
| #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); \ | ||||
|  | @ -49,10 +63,11 @@ | |||
|   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); | ||||
| 			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++) { | ||||
| 			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 ISO9660 file %s at LSN %lu\n", | ||||
| 						iso_filename, (long unsigned int)lsn); | ||||
| 						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; i<statbuf->size; 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(); | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
							
								
								
									
										12
									
								
								src/rufus.rc
									
										
									
									
									
								
							
							
						
						
									
										12
									
								
								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         "<a href=""http://rufus.akeo.ie"">http://rufus.akeo.ie</a>",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" | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue