mirror of
				https://github.com/pbatard/rufus.git
				synced 2024-08-14 23:57:05 +00:00 
			
		
		
		
	Merge remote-tracking branch 'pbatard/rufus'
This commit is contained in:
		
						commit
						d14029310f
					
				
					 20 changed files with 661 additions and 342 deletions
				
			
		
							
								
								
									
										20
									
								
								configure
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										20
									
								
								configure
									
										
									
									
										vendored
									
									
								
							|  | @ -1,6 +1,6 @@ | |||
| #! /bin/sh | ||||
| # Guess values for system-dependent variables and create Makefiles. | ||||
| # Generated by GNU Autoconf 2.69 for rufus 3.1. | ||||
| # Generated by GNU Autoconf 2.69 for rufus 3.2. | ||||
| # | ||||
| # Report bugs to <https://github.com/pbatard/rufus/issues>. | ||||
| # | ||||
|  | @ -580,8 +580,8 @@ MAKEFLAGS= | |||
| # Identity of this package. | ||||
| PACKAGE_NAME='rufus' | ||||
| PACKAGE_TARNAME='rufus' | ||||
| PACKAGE_VERSION='3.1' | ||||
| PACKAGE_STRING='rufus 3.1' | ||||
| PACKAGE_VERSION='3.2' | ||||
| PACKAGE_STRING='rufus 3.2' | ||||
| PACKAGE_BUGREPORT='https://github.com/pbatard/rufus/issues' | ||||
| PACKAGE_URL='https://rufus.akeo.ie' | ||||
| 
 | ||||
|  | @ -1228,7 +1228,7 @@ if test "$ac_init_help" = "long"; then | |||
|   # Omit some internal or obsolete options to make the list less imposing. | ||||
|   # This message is too long to be a string in the A/UX 3.1 sh. | ||||
|   cat <<_ACEOF | ||||
| \`configure' configures rufus 3.1 to adapt to many kinds of systems. | ||||
| \`configure' configures rufus 3.2 to adapt to many kinds of systems. | ||||
| 
 | ||||
| Usage: $0 [OPTION]... [VAR=VALUE]... | ||||
| 
 | ||||
|  | @ -1294,7 +1294,7 @@ fi | |||
| 
 | ||||
| if test -n "$ac_init_help"; then | ||||
|   case $ac_init_help in | ||||
|      short | recursive ) echo "Configuration of rufus 3.1:";; | ||||
|      short | recursive ) echo "Configuration of rufus 3.2:";; | ||||
|    esac | ||||
|   cat <<\_ACEOF | ||||
| 
 | ||||
|  | @ -1385,7 +1385,7 @@ fi | |||
| test -n "$ac_init_help" && exit $ac_status | ||||
| if $ac_init_version; then | ||||
|   cat <<\_ACEOF | ||||
| rufus configure 3.1 | ||||
| rufus configure 3.2 | ||||
| generated by GNU Autoconf 2.69 | ||||
| 
 | ||||
| Copyright (C) 2012 Free Software Foundation, Inc. | ||||
|  | @ -1440,7 +1440,7 @@ cat >config.log <<_ACEOF | |||
| This file contains any messages produced by compilers while | ||||
| running configure, to aid debugging if configure makes a mistake. | ||||
| 
 | ||||
| It was created by rufus $as_me 3.1, which was | ||||
| It was created by rufus $as_me 3.2, which was | ||||
| generated by GNU Autoconf 2.69.  Invocation command line was | ||||
| 
 | ||||
|   $ $0 $@ | ||||
|  | @ -2303,7 +2303,7 @@ fi | |||
| 
 | ||||
| # Define the identity of the package. | ||||
|  PACKAGE='rufus' | ||||
|  VERSION='3.1' | ||||
|  VERSION='3.2' | ||||
| 
 | ||||
| 
 | ||||
| cat >>confdefs.h <<_ACEOF | ||||
|  | @ -4481,7 +4481,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 | |||
| # report actual input values of CONFIG_FILES etc. instead of their | ||||
| # values after options handling. | ||||
| ac_log=" | ||||
| This file was extended by rufus $as_me 3.1, which was | ||||
| This file was extended by rufus $as_me 3.2, which was | ||||
| generated by GNU Autoconf 2.69.  Invocation command line was | ||||
| 
 | ||||
|   CONFIG_FILES    = $CONFIG_FILES | ||||
|  | @ -4535,7 +4535,7 @@ _ACEOF | |||
| cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 | ||||
| ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" | ||||
| ac_cs_version="\\ | ||||
| rufus config.status 3.1 | ||||
| rufus config.status 3.2 | ||||
| configured by $0, generated by GNU Autoconf 2.69, | ||||
|   with options \\"\$ac_cs_config\\" | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,4 +1,4 @@ | |||
| AC_INIT([rufus], [3.1], [https://github.com/pbatard/rufus/issues], [rufus], [https://rufus.akeo.ie]) | ||||
| AC_INIT([rufus], [3.2], [https://github.com/pbatard/rufus/issues], [rufus], [https://rufus.akeo.ie]) | ||||
| AM_INIT_AUTOMAKE([-Wno-portability foreign no-dist no-dependencies]) | ||||
| AC_CONFIG_SRCDIR([src/rufus.c]) | ||||
| AC_CONFIG_MACRO_DIR([m4]) | ||||
|  |  | |||
|  | @ -8,7 +8,7 @@ | |||
|        for an interesting struggle, when you also happen to have a comma in one of the fields... --> | ||||
|   <Identity | ||||
|    Name="Rufus" | ||||
|    Version="3.1.1320.0" | ||||
|    Version="3.2.1320.0" | ||||
|    ProcessorArchitecture="x86" | ||||
|    Publisher='CN=Akeo Consulting, O=Akeo Consulting, STREET=24 Grey Rock, L=Milford, S=Co. Donegal, PostalCode=F92 D667, C=IE' /> | ||||
|     <Properties> | ||||
|  |  | |||
|  | @ -1,5 +1,5 @@ | |||
| @echo off | ||||
| set VERSION=3.1 | ||||
| set VERSION=3.2 | ||||
| 
 | ||||
| rem Make sure you don't have anything you don't want included in the package, as anything residing in the | ||||
| rem current directory will be included, including any previous .appx, which makes for nice recursion... | ||||
|  |  | |||
|  | @ -15,7 +15,11 @@ content. PLEASE, do not just look at this Changelog when updating your | |||
| translation, but always use the English section of rufus.loc as your base. | ||||
| For instance, MSG_114, that was introduced in v1.0.8 is MORE than one line! | ||||
| 
 | ||||
| o Version 1.0.23 (2018.??.??) | ||||
| o Version 1.0.24 (2018.??.??) | ||||
|   - *NEW*      MSG_087 | ||||
|   - *NEW*      MSG_172 | ||||
| 
 | ||||
| o Version 1.0.23 (2018.03.27) | ||||
|   - All positioning ('m', 's') has now been removed as well as some controls, for the 3.0 UI redesign | ||||
|   - *NEW*      IDS_DRIVE_PROPERTIES_TXT "Drive Properties" | ||||
|   - *NEW*      IDS_BOOT_SELECTION_TXT "Boot selection" | ||||
|  |  | |||
|  | @ -208,7 +208,7 @@ t MSG_032 "UEFI (non CSM)" | |||
| t MSG_033 "BIOS or UEFI" | ||||
| # Number of bad block check passes (singular for 1 pass, plural for 2 or more passes) | ||||
| t MSG_034 "%d pass" | ||||
| t MSG_035 "%d passes" | ||||
| t MSG_035 "%d passes %s" | ||||
| t MSG_036 "ISO Image" | ||||
| t MSG_037 "Application" | ||||
| t MSG_038 "Abort" | ||||
|  | @ -277,6 +277,7 @@ t MSG_084 "This ISO image seems to use an obsolete version of '%s'.\n" | |||
| 	"'%s' exists there, it will be reused automatically." | ||||
| t MSG_085 "Downloading '%s'" | ||||
| t MSG_086 "No image selected" | ||||
| t MSG_087 "for %s devices" | ||||
| t MSG_088 "Image is too big" | ||||
| t MSG_089 "The image is too big for the selected target." | ||||
| t MSG_090 "Unsupported ISO" | ||||
|  | @ -386,6 +387,7 @@ t MSG_169 "Create an extra hidden partition and try to align partitions boundari | |||
| 	"This can improve boot detection for older BIOSes" | ||||
| t MSG_170 "Enable the listing of USB Hard Drive enclosures. USE AT YOUR OWN RISKS!!!" | ||||
| t MSG_171 "Start the formatting operation.\nThis will DESTROY any data on the target!" | ||||
| t MSG_172 "Invalid download signature" | ||||
| t MSG_173 "Click to select..." | ||||
| # The following will appear in the about dialog | ||||
| t MSG_174 "Rufus - The Reliable USB Formatting Utility" | ||||
|  | @ -684,7 +686,7 @@ t MSG_032 "UEFI (بدون CSM)" | |||
| t MSG_033 "BIOS أو UEFI" | ||||
| # Number of bad block check passes (singular for 1 pass, plural for 2 or more passes) | ||||
| t MSG_034 "%d تجاوز" | ||||
| t MSG_035 "%d تجاوزات" | ||||
| t MSG_035 "%d تجاوزات %s" | ||||
| t MSG_036 "ISO صورة" | ||||
| t MSG_037 "تطبيق" | ||||
| t MSG_038 "توقف" | ||||
|  | @ -1136,7 +1138,7 @@ t MSG_032 "UEFI (yox CSM)" | |||
| t MSG_033 "BIOS və ya UEFI" | ||||
| # Number of bad block check passes (singular for 1 pass, plural for 2 or more passes) | ||||
| t MSG_034 "%d Keçid" | ||||
| t MSG_035 "%d Keçid" | ||||
| t MSG_035 "%d Keçid %s" | ||||
| t MSG_036 "ISO Əksi" | ||||
| t MSG_037 "Proqram" | ||||
| t MSG_038 "İmtina et" | ||||
|  | @ -1583,7 +1585,7 @@ t MSG_030 "%s (Стандартно)" | |||
| #t MSG_033 "%s дялова схема за UEFI" | ||||
| # Number of bad block check passes (singular for 1 pass, plural for 2 or more passes) | ||||
| t MSG_034 "%d Пробег" | ||||
| t MSG_035 "%d Пробега" | ||||
| t MSG_035 "%d Пробега %s" | ||||
| t MSG_036 "ISO образ" | ||||
| t MSG_037 "Приложение" | ||||
| t MSG_038 "Прекрати" | ||||
|  | @ -2028,7 +2030,7 @@ t MSG_032 "UEFI (非 CSM)" | |||
| t MSG_033 "BIOS 或 UEFI" | ||||
| # Number of bad block check passes (singular for 1 pass, plural for 2 or more passes) | ||||
| t MSG_034 "%d 遍" | ||||
| t MSG_035 "%d 遍" | ||||
| t MSG_035 "%d 遍 %s" | ||||
| t MSG_036 "ISO 镜像" | ||||
| t MSG_037 "程序" | ||||
| t MSG_038 "中止" | ||||
|  | @ -2471,7 +2473,7 @@ t MSG_032 "UEFI (無 CSM)" | |||
| t MSG_033 "BIOS 或 UEFI" | ||||
| # Number of bad block check passes (singular for 1 pass, plural for 2 or more passes) | ||||
| t MSG_034 "%d 回" | ||||
| t MSG_035 "%d 回" | ||||
| t MSG_035 "%d 回 %s" | ||||
| t MSG_036 "ISO 映像" | ||||
| t MSG_037 "程式" | ||||
| t MSG_038 "終止" | ||||
|  | @ -2885,7 +2887,7 @@ t MSG_032 "UEFI (bez CSM)" | |||
| t MSG_033 "BIOS ili UEFI" | ||||
| # Number of bad block check passes (singular for 1 pass, plural for 2 or more passes) | ||||
| t MSG_034 "%d prolaz" | ||||
| t MSG_035 "%d prolaza" | ||||
| t MSG_035 "%d prolaza %s" | ||||
| t MSG_036 "ISO slika" | ||||
| t MSG_037 "Aplikacija" | ||||
| t MSG_038 "Prekini" | ||||
|  | @ -3340,7 +3342,7 @@ t MSG_032 "UEFI (ne CSM)" | |||
| t MSG_033 "BIOS nebo UEFI" | ||||
| # Number of bad block check passes (singular for 1 pass, plural for 2 or more passes) | ||||
| t MSG_034 "%d pokus" | ||||
| t MSG_035 "%d pokusy" | ||||
| t MSG_035 "%d pokusy %s" | ||||
| t MSG_036 "Obraz ISO" | ||||
| t MSG_037 "Aplikace" | ||||
| t MSG_038 "Přerušit" | ||||
|  | @ -3792,7 +3794,7 @@ t MSG_032 "UEFI (ikke CSM)" | |||
| t MSG_033 "BIOS eller UEFI" | ||||
| # Number of bad block check passes (singular for 1 pass, plural for 2 or more passes) | ||||
| t MSG_034 "%d gennemløb" | ||||
| t MSG_035 "%d gennemløb" | ||||
| t MSG_035 "%d gennemløb %s" | ||||
| t MSG_036 "ISO-image" | ||||
| t MSG_037 "Applikation" | ||||
| t MSG_038 "Annuller" | ||||
|  | @ -4228,7 +4230,7 @@ t MSG_032 "UEFI (geen CSM)" | |||
| t MSG_033 "BIOS of UEFI" | ||||
| # Number of bad block check passes (singular for 1 pass, plural for 2 or more passes) | ||||
| t MSG_034 "%d Ronde" | ||||
| t MSG_035 "%d Rondes" | ||||
| t MSG_035 "%d Rondes %s" | ||||
| t MSG_036 "ISO image" | ||||
| t MSG_037 "Applicatie" | ||||
| t MSG_038 "Afbreken" | ||||
|  | @ -4667,7 +4669,7 @@ t MSG_032 "UEFI (ei-CSM)" | |||
| t MSG_033 "BIOS tai UEFI" | ||||
| # Number of bad block check passes (singular for 1 pass, plural for 2 or more passes) | ||||
| t MSG_034 "%d testi" | ||||
| t MSG_035 "%d testiä" | ||||
| t MSG_035 "%d testiä %s" | ||||
| t MSG_036 "ISO-kuva" | ||||
| t MSG_037 "Sovellus" | ||||
| t MSG_038 "Keskeytä" | ||||
|  | @ -5105,7 +5107,7 @@ t MSG_031 "BIOS (ou UEFI-CSM)" | |||
| t MSG_032 "UEFI (non CSM)" | ||||
| t MSG_033 "BIOS ou UEFI" | ||||
| t MSG_034 "%d passe" | ||||
| t MSG_035 "%d passes" | ||||
| t MSG_035 "%d passes %s" | ||||
| t MSG_036 "Image ISO" | ||||
| t MSG_037 "Application" | ||||
| t MSG_038 "Annuler" | ||||
|  | @ -5528,7 +5530,7 @@ t MSG_032 "UEFI (ohne CSM)" | |||
| t MSG_033 "BIOS oder UEFI" | ||||
| # Number of bad block check passes (singular for 1 pass, plural for 2 or more passes) | ||||
| t MSG_034 "%d Durchgang" | ||||
| t MSG_035 "%d Durchgänge" | ||||
| t MSG_035 "%d Durchgänge %s" | ||||
| t MSG_036 "ISO-Abbild" | ||||
| t MSG_037 "Programm" | ||||
| t MSG_038 "Abbruch" | ||||
|  | @ -5956,7 +5958,7 @@ t MSG_032 "UEFI (εκτός από CSM)" | |||
| t MSG_033 "BIOS ή UEFI" | ||||
| # Number of bad block check passes (singular for 1 pass, plural for 2 or more passes) | ||||
| t MSG_034 "%d Πέρασμα" | ||||
| t MSG_035 "%d Περάσματα" | ||||
| t MSG_035 "%d Περάσματα %s" | ||||
| t MSG_036 "Είδωλο ISO" | ||||
| t MSG_037 "Εφαρμογή" | ||||
| t MSG_038 "Τερματισμός" | ||||
|  | @ -6412,7 +6414,7 @@ t MSG_032 "UEFI (שאינו CSM)" | |||
| t MSG_033 "BIOS או UEFI" | ||||
| # Number of bad block check passes (singular for 1 pass, plural for 2 or more passes) | ||||
| t MSG_034 "מעבר אחד" | ||||
| t MSG_035 "%d מעברים" | ||||
| t MSG_035 "%d מעברים %s" | ||||
| t MSG_036 "קובץ ISO" | ||||
| t MSG_037 "יישום" | ||||
| t MSG_038 "ביטול" | ||||
|  | @ -6889,7 +6891,7 @@ t MSG_032 "UEFI (nem CSM)" | |||
| t MSG_033 "BIOS vagy UEFI" | ||||
| # Number of bad block check passes (singular for 1 pass, plural for 2 or more passes) | ||||
| t MSG_034 "%d vizsgálva" | ||||
| t MSG_035 "%d vizsgálva" | ||||
| t MSG_035 "%d vizsgálva %s" | ||||
| t MSG_036 "ISO kép" | ||||
| t MSG_037 "Alkalmazás" | ||||
| t MSG_038 "Megszakít" | ||||
|  | @ -7341,7 +7343,7 @@ t MSG_032 "UEFI (non CSM)" | |||
| t MSG_033 "BIOS atau UEFI" | ||||
| # Number of bad block check passes (singular for 1 pass, plural for 2 or more passes) | ||||
| t MSG_034 "%d kali uji" | ||||
| t MSG_035 "%d kali uji" | ||||
| t MSG_035 "%d kali uji %s" | ||||
| t MSG_036 "ISO Image" | ||||
| t MSG_037 "Aplikasi" | ||||
| t MSG_038 "Batal" | ||||
|  | @ -7789,7 +7791,7 @@ t MSG_031 "BIOS (o UEFI CSM)" | |||
| t MSG_032 "UEFI (non CSM)" | ||||
| t MSG_033 "BIOS o UEFI" | ||||
| t MSG_034 "%d test" | ||||
| t MSG_035 "%d test" | ||||
| t MSG_035 "%d test %s" | ||||
| t MSG_036 "Immagine ISO" | ||||
| t MSG_037 "Applicazione" | ||||
| t MSG_038 "Annulla" | ||||
|  | @ -8229,7 +8231,7 @@ t MSG_032 "UEFI (CSM無効)" | |||
| t MSG_033 "BIOSまたはUEFI" | ||||
| # Number of bad block check passes (singular for 1 pass, plural for 2 or more passes) | ||||
| t MSG_034 "%d パス" | ||||
| t MSG_035 "%d パス" | ||||
| t MSG_035 "%d パス %s" | ||||
| t MSG_036 "ISOイメージ" | ||||
| t MSG_037 "アプリケーション" | ||||
| t MSG_038 "中止" | ||||
|  | @ -8698,7 +8700,7 @@ t MSG_032 "UEFI (CSM 지원 안 됨)" | |||
| t MSG_033 "BIOS 또는 UEFI" | ||||
| # Number of bad block check passes (singular for 1 pass, plural for 2 or more passes) | ||||
| t MSG_034 "한번만 검사" | ||||
| t MSG_035 "%d회 검사" | ||||
| t MSG_035 "%d회 검사 %s" | ||||
| t MSG_036 "ISO 이미지" | ||||
| t MSG_037 "프로그램" | ||||
| t MSG_038 "취소" | ||||
|  | @ -9146,7 +9148,7 @@ t MSG_032 "BIOS (bez CSM)" | |||
| t MSG_033 "BIOS vai UEFI" | ||||
| # Number of bad block check passes (singular for 1 pass, plural for 2 or more passes) | ||||
| t MSG_034 "%d mēģ." | ||||
| t MSG_035 "%d mēģ." | ||||
| t MSG_035 "%d mēģ. %s" | ||||
| t MSG_036 "ISO virtuālais attēls" | ||||
| t MSG_037 "Programma" | ||||
| t MSG_038 "Pārtraukt" | ||||
|  | @ -9596,7 +9598,7 @@ t MSG_032 "UEFI (ne CSM)" | |||
| t MSG_033 "BIOS arba UEFI" | ||||
| # Number of bad block check passes (singular for 1 pass, plural for 2 or more passes) | ||||
| t MSG_034 "%d bandymas" | ||||
| t MSG_035 "%d bandymai" | ||||
| t MSG_035 "%d bandymai %s" | ||||
| t MSG_036 "ISO atvaizdas" | ||||
| t MSG_037 "Programa" | ||||
| t MSG_038 "Nutraukti" | ||||
|  | @ -10051,7 +10053,7 @@ t MSG_030 "%s (Lalai)" | |||
| 
 | ||||
| # Number of bad block check passes (singular for 1 pass, plural for 2 or more passes) | ||||
| t MSG_034 "%d kali lulus" | ||||
| t MSG_035 "%d kali lulus" | ||||
| t MSG_035 "%d kali lulus %s" | ||||
| t MSG_036 "Imej ISO" | ||||
| t MSG_037 "Aplikasi" | ||||
| t MSG_038 "Batal" | ||||
|  | @ -10480,7 +10482,7 @@ t MSG_032 "UEFI (ikke CSM)" | |||
| t MSG_033 "BIOS eller UEFI" | ||||
| # Number of bad block check passes (singular for 1 pass, plural for 2 or more passes) | ||||
| t MSG_034 "%d Passering" | ||||
| t MSG_035 "%d Passeringer" | ||||
| t MSG_035 "%d Passeringer %s" | ||||
| t MSG_036 "ISO-bilde" | ||||
| t MSG_037 "Applikasjon" | ||||
| t MSG_038 "Avbryt" | ||||
|  | @ -10959,7 +10961,7 @@ t MSG_032 "UEFI (non CSM)" | |||
| t MSG_033 "BIOS یا UEFI" | ||||
| # Number of bad block check passes (singular for 1 pass, plural for 2 or more passes) | ||||
| t MSG_034 "%d گذره" | ||||
| t MSG_035 "%d گذره" | ||||
| t MSG_035 "%d گذره %s" | ||||
| t MSG_036 "ایمیج ISO" | ||||
| t MSG_037 "برنامه" | ||||
| t MSG_038 "لغو" | ||||
|  | @ -11427,7 +11429,7 @@ t MSG_032 "UEFI (bez CSM)" | |||
| t MSG_033 "BIOS lub UEFI" | ||||
| # Number of bad block check passes (singular for 1 pass, plural for 2 or more passes) | ||||
| t MSG_034 "%d Przebieg" | ||||
| t MSG_035 "%d Przebiegi" | ||||
| t MSG_035 "%d Przebiegi %s" | ||||
| t MSG_036 "Obraz ISO" | ||||
| t MSG_037 "Aplikacja" | ||||
| t MSG_038 "Przerwij" | ||||
|  | @ -11891,7 +11893,7 @@ t MSG_032 "UEFI (não CSM)" | |||
| t MSG_033 "BIOS ou UEFI" | ||||
| # Number of bad block check passes (singular for 1 pass, plural for 2 or more passes) | ||||
| t MSG_034 "%d passo" | ||||
| t MSG_035 "%d passos" | ||||
| t MSG_035 "%d passos %s" | ||||
| t MSG_036 "Imagem ISO" | ||||
| t MSG_037 "Aplicativo" | ||||
| t MSG_038 "Abortar" | ||||
|  | @ -12364,7 +12366,7 @@ t MSG_032 "UEFI (não CSM)" | |||
| t MSG_033 "BIOS ou UEFI" | ||||
| # Number of bad block check passes (singular for 1 pass, plural for 2 or more passes) | ||||
| t MSG_034 "%d passo" | ||||
| t MSG_035 "%d passos" | ||||
| t MSG_035 "%d passos %s" | ||||
| t MSG_036 "Imagem ISO" | ||||
| t MSG_037 "Aplicação" | ||||
| t MSG_038 "Abortar" | ||||
|  | @ -12808,7 +12810,7 @@ t MSG_031 "BIOS (sau UEFI-CSM)" | |||
| t MSG_032 "UEFI (non CSM)" | ||||
| t MSG_033 "BIOS sau UEFI" | ||||
| t MSG_034 "%d pas" | ||||
| t MSG_035 "%d pași" | ||||
| t MSG_035 "%d pași %s" | ||||
| t MSG_036 "Imagine ISO" | ||||
| t MSG_037 "Cerere" | ||||
| t MSG_038 "Anulează" | ||||
|  | @ -13233,7 +13235,7 @@ t MSG_032 "UEFI (non-CSM)" | |||
| t MSG_033 "BIOS или UEFI" | ||||
| # Number of bad block check passes (singular for 1 pass, plural for 2 or more passes) | ||||
| t MSG_034 "%d проход" | ||||
| t MSG_035 "%d прохода" | ||||
| t MSG_035 "%d прохода %s" | ||||
| t MSG_036 "ISO-образ" | ||||
| t MSG_037 "Приложение" | ||||
| t MSG_038 "Отменить" | ||||
|  | @ -13675,7 +13677,7 @@ t MSG_030 "%s (Uobičajeno)" | |||
| #t MSG_033 "%s particijska šema za UEFI" | ||||
| # Number of bad block check passes (singular for 1 pass, plural for 2 or more passes) | ||||
| t MSG_034 "%d sekvenca" | ||||
| t MSG_035 "%d sekvence" | ||||
| t MSG_035 "%d sekvence %s" | ||||
| t MSG_036 "ISO datoteke" | ||||
| t MSG_037 "Aplikacija" | ||||
| t MSG_038 "Prekini" | ||||
|  | @ -14122,7 +14124,7 @@ t MSG_032 "UEFI (bez CSM)" | |||
| t MSG_033 "BIOS alebo UEFI" | ||||
| # Number of bad block check passes (singular for 1 pass, plural for 2 or more passes) | ||||
| t MSG_034 "%d pokus" | ||||
| t MSG_035 "%d pokusy" | ||||
| t MSG_035 "%d pokusy %s" | ||||
| t MSG_036 "Obraz ISO" | ||||
| t MSG_037 "Aplikácia" | ||||
| t MSG_038 "Ukončiť" | ||||
|  | @ -14576,7 +14578,7 @@ t MSG_032 "UEFI (brez CSM)" | |||
| t MSG_033 "BIOS ali UEFI" | ||||
| # Number of bad block check passes (singular for 1 pass, plural for 2 or more passes) | ||||
| t MSG_034 "%d prehod" | ||||
| t MSG_035 "%d prehoda/-i" | ||||
| t MSG_035 "%d prehoda/-i %s" | ||||
| t MSG_036 "sliko ISO" | ||||
| t MSG_037 "Aplikacija" | ||||
| t MSG_038 "Prekini" | ||||
|  | @ -15010,7 +15012,7 @@ t MSG_032 "UEFI (no CSM)" | |||
| t MSG_033 "BIOS o UEFI" | ||||
| # Number of bad block check passes (singular for 1 pass, plural for 2 or more passes) | ||||
| t MSG_034 "%d paso" | ||||
| t MSG_035 "%d pasos" | ||||
| t MSG_035 "%d pasos %s" | ||||
| t MSG_036 "Imagen ISO" | ||||
| t MSG_037 "Aplicación" | ||||
| t MSG_038 "Abortar" | ||||
|  | @ -15467,7 +15469,7 @@ t MSG_032 "UEFI (icke CSM)" | |||
| t MSG_033 "BIOS eller UEFI" | ||||
| # Number of bad block check passes (singular for 1 pass, plural for 2 or more passes) | ||||
| t MSG_034 "%d gång" | ||||
| t MSG_035 "%d gånger" | ||||
| t MSG_035 "%d gånger %s" | ||||
| t MSG_036 "ISO-avbild" | ||||
| t MSG_037 "Program" | ||||
| t MSG_038 "Avbryt" | ||||
|  | @ -15926,7 +15928,7 @@ t MSG_032 "UEFI (ที่ไม่ใช่ CSM)" | |||
| t MSG_033 "BIOS หรือ UEFI" | ||||
| # Number of bad block check passes (singular for 1 pass, plural for 2 or more passes) | ||||
| t MSG_034 "%d รอบ" | ||||
| t MSG_035 "%d รอบ" | ||||
| t MSG_035 "%d รอบ %s" | ||||
| t MSG_036 "อิมเมจ ISO" | ||||
| t MSG_037 "แอพพลิเคชั่น" | ||||
| t MSG_038 "ยกเลิก" | ||||
|  | @ -16393,7 +16395,7 @@ t MSG_032 "UEFI (CSM yok)" | |||
| t MSG_033 "BIOS ya da UEFI" | ||||
| # Number of bad block check passes (singular for 1 pass, plural for 2 or more passes) | ||||
| t MSG_034 "%d Geçiş" | ||||
| t MSG_035 "%d Geçiş" | ||||
| t MSG_035 "%d Geçiş %s" | ||||
| t MSG_036 "ISO Yansıması" | ||||
| t MSG_037 "Uygulama" | ||||
| t MSG_038 "Vazgeç" | ||||
|  | @ -16847,7 +16849,7 @@ t MSG_032 "UEFI (без CSM)" | |||
| t MSG_033 "BIOS чи UEFI" | ||||
| # Number of bad block check passes (singular for 1 pass, plural for 2 or more passes) | ||||
| t MSG_034 "%d прохід" | ||||
| t MSG_035 "%d проходи" | ||||
| t MSG_035 "%d проходи %s" | ||||
| t MSG_036 "ISO-образ" | ||||
| t MSG_037 "Додаток" | ||||
| t MSG_038 "Відмінити" | ||||
|  | @ -17283,7 +17285,7 @@ t MSG_030 "%s (Mặc định)" | |||
| #t MSG_033 "Sắp xếp phân vùng %s cho UEFI" | ||||
| # Number of bad block check passes (singular for 1 pass, plural for 2 or more passes) | ||||
| t MSG_034 "Qua %d lần" | ||||
| t MSG_035 "Qua %d lần" | ||||
| t MSG_035 "Qua %d lần %s" | ||||
| t MSG_036 "Ảnh ISO" | ||||
| t MSG_037 "Ứng dụng" | ||||
| t MSG_038 "Huỷ bỏ" | ||||
|  |  | |||
|  | @ -7,7 +7,7 @@ | |||
|  * | ||||
|  * Copyright 1995, 1996, 1997, 1998, 1999 by Theodore Ts'o | ||||
|  * Copyright 1999 by David Beattie | ||||
|  * Copyright 2011-2016 by Pete Batard | ||||
|  * Copyright 2011-2018 by Pete Batard | ||||
|  * | ||||
|  * This file is based on the minix file system programs fsck and mkfs | ||||
|  * written and copyrighted by Linus Torvalds <Linus.Torvalds@cs.helsinki.fi> | ||||
|  | @ -350,13 +350,14 @@ static void pattern_fill(unsigned char *buffer, unsigned int pattern, | |||
| 	unsigned char	bpattern[sizeof(pattern)], *ptr; | ||||
| 
 | ||||
| 	if (pattern == (unsigned int) ~0) { | ||||
| 		PrintInfo(3500, MSG_236); | ||||
| 		srand((unsigned int)GetTickCount64()); | ||||
| 		for (ptr = buffer; ptr < buffer + n; ptr++) { | ||||
| 			// coverity[dont_call]
 | ||||
| 			(*ptr) = rand() % (1 << (8 * sizeof(char))); | ||||
| 		} | ||||
| 		PrintInfo(3500, MSG_236); | ||||
| 	} else { | ||||
| 		PrintInfo(3500, MSG_237, pattern); | ||||
| 		bpattern[0] = 0; | ||||
| 		for (i = 0; i < sizeof(bpattern); i++) { | ||||
| 			if (pattern == 0) | ||||
|  | @ -372,7 +373,6 @@ static void pattern_fill(unsigned char *buffer, unsigned int pattern, | |||
| 			else | ||||
| 				i--; | ||||
| 		} | ||||
| 		PrintInfo(3500, MSG_237, bpattern[i]); | ||||
| 		cur_pattern++; | ||||
| 	} | ||||
| } | ||||
|  | @ -422,16 +422,22 @@ static int64_t do_write(HANDLE hDrive, unsigned char * buffer, uint64_t tryout, | |||
| } | ||||
| 
 | ||||
| static unsigned int test_rw(HANDLE hDrive, blk_t last_block, size_t block_size, blk_t first_block, | ||||
| 	size_t blocks_at_once, int nb_passes) | ||||
| 	size_t blocks_at_once, int pattern_type, int nb_passes) | ||||
| { | ||||
| 	const unsigned int pattern[BADLOCKS_PATTERN_TYPES][BADBLOCK_PATTERN_COUNT] = | ||||
| 		{ BADBLOCK_PATTERN_SLC, BADCLOCK_PATTERN_MLC, BADBLOCK_PATTERN_TLC }; | ||||
| 	unsigned char *buffer = NULL, *read_buffer; | ||||
| 	const unsigned int pattern[] = BADBLOCK_PATTERNS; | ||||
| 	int i, pat_idx; | ||||
| 	unsigned int bb_count = 0; | ||||
| 	blk_t got, tryout, recover_block = ~0, *blk_id; | ||||
| 	size_t id_offset; | ||||
| 	size_t id_offset = 0; | ||||
| 
 | ||||
| 	if ((nb_passes < 1) || (nb_passes > 4)) { | ||||
| 	if ((pattern_type < 0) || (pattern_type >= BADLOCKS_PATTERN_TYPES)) { | ||||
| 		uprintf("%sInvalid pattern type\n", bb_prefix); | ||||
| 		cancel_ops = -1; | ||||
| 		return 0; | ||||
| 	} | ||||
| 	if ((nb_passes < 1) || (nb_passes > BADBLOCK_PATTERN_COUNT)) { | ||||
| 		uprintf("%sInvalid number of passes\n", bb_prefix); | ||||
| 		cancel_ops = -1; | ||||
| 		return 0; | ||||
|  | @ -446,26 +452,31 @@ static unsigned int test_rw(HANDLE hDrive, blk_t last_block, size_t block_size, | |||
| 		return 0; | ||||
| 	} | ||||
| 
 | ||||
| 	uprintf("%sChecking from block %lu to %lu\n", bb_prefix, | ||||
| 		(unsigned long) first_block, (unsigned long) last_block - 1); | ||||
| 	uprintf("%sChecking from block %lu to %lu (1 block = %s)\n", bb_prefix, | ||||
| 		(unsigned long) first_block, (unsigned long) last_block - 1, | ||||
| 		SizeToHumanReadable(BADBLOCK_BLOCK_SIZE, FALSE, FALSE)); | ||||
| 	nr_pattern = nb_passes; | ||||
| 	cur_pattern = 0; | ||||
| 
 | ||||
| 	for (pat_idx = 0; pat_idx < nb_passes; pat_idx++) { | ||||
| 		srand((unsigned int)GetTickCount64()); | ||||
| 		if (cancel_ops) goto out; | ||||
| 		if (cancel_ops) | ||||
| 			goto out; | ||||
| 		if (detect_fakes && (pat_idx == 0)) { | ||||
| 			srand((unsigned int)GetTickCount64()); | ||||
| 			id_offset = rand() * (block_size - sizeof(blk_t)) / RAND_MAX; | ||||
| 			uprintf("%sUsing offset %d for fake device check\n", bb_prefix, id_offset); | ||||
| 		} | ||||
| 		// coverity[dont_call]
 | ||||
| 		id_offset = rand() * (block_size-sizeof(blk_t)) / RAND_MAX; | ||||
| 		pattern_fill(buffer, pattern[pat_idx], blocks_at_once * block_size); | ||||
| 		uprintf("%sUsing offset %d for fake device check\n", bb_prefix, id_offset); | ||||
| 		pattern_fill(buffer, pattern[pattern_type][pat_idx], blocks_at_once * block_size); | ||||
| 		num_blocks = last_block - 1; | ||||
| 		currently_testing = first_block; | ||||
| 		if (s_flag | v_flag) | ||||
| 			uprintf("%sWriting test pattern 0x%02X\n", bb_prefix, pattern[pat_idx]); | ||||
| 			uprintf("%sWriting test pattern 0x%02X\n", bb_prefix, pattern[pattern_type][pat_idx]); | ||||
| 		cur_op = OP_WRITE; | ||||
| 		tryout = blocks_at_once; | ||||
| 		while (currently_testing < last_block) { | ||||
| 			if (cancel_ops) goto out; | ||||
| 			if (cancel_ops) | ||||
| 				goto out; | ||||
| 			if (max_bb && bb_count >= max_bb) { | ||||
| 				if (s_flag || v_flag) { | ||||
| 					uprintf(abort_msg); | ||||
|  | @ -477,7 +488,7 @@ static unsigned int test_rw(HANDLE hDrive, blk_t last_block, size_t block_size, | |||
| 			} | ||||
| 			if (currently_testing + tryout > last_block) | ||||
| 				tryout = last_block - currently_testing; | ||||
| 			if (detect_fakes) { | ||||
| 			if (detect_fakes && (pat_idx == 0)) { | ||||
| 				/* Add the block number at a fixed (random) offset during each pass to
 | ||||
| 				   allow for the detection of 'fake' media (eg. 2GB USB masquerading as 16GB) */ | ||||
| 				for (i=0; i<(int)blocks_at_once; i++) { | ||||
|  | @ -525,7 +536,7 @@ static unsigned int test_rw(HANDLE hDrive, blk_t last_block, size_t block_size, | |||
| 			} | ||||
| 			if (currently_testing + tryout > last_block) | ||||
| 				tryout = last_block - currently_testing; | ||||
| 			if (detect_fakes) { | ||||
| 			if (detect_fakes && (pat_idx == 0)) { | ||||
| 				for (i=0; i<(int)blocks_at_once; i++) { | ||||
| 					blk_id = (blk_t*)(intptr_t)(buffer + id_offset+ i*block_size); | ||||
| 					*blk_id = (blk_t)(currently_testing + i); | ||||
|  | @ -563,11 +574,11 @@ out: | |||
| 	return bb_count; | ||||
| } | ||||
| 
 | ||||
| BOOL BadBlocks(HANDLE hPhysicalDrive, ULONGLONG disk_size, size_t block_size, | ||||
| 	int nb_passes, badblocks_report *report, FILE* fd) | ||||
| BOOL BadBlocks(HANDLE hPhysicalDrive, ULONGLONG disk_size, int nb_passes, | ||||
| 	int flash_type, badblocks_report *report, FILE* fd) | ||||
| { | ||||
| 	errcode_t error_code; | ||||
| 	blk_t first_block = 0, last_block = disk_size/block_size; | ||||
| 	blk_t last_block = disk_size / BADBLOCK_BLOCK_SIZE; | ||||
| 
 | ||||
| 	if (report == NULL) return FALSE; | ||||
| 	num_read_errors = 0; | ||||
|  | @ -589,7 +600,7 @@ BOOL BadBlocks(HANDLE hPhysicalDrive, ULONGLONG disk_size, size_t block_size, | |||
| 	cancel_ops = 0; | ||||
| 	/* use a timer to update status every second */ | ||||
| 	SetTimer(hMainDialog, TID_BADBLOCKS_UPDATE, 1000, alarm_intr); | ||||
| 	report->bb_count = test_rw(hPhysicalDrive, last_block, block_size, first_block, BB_BLOCKS_AT_ONCE, nb_passes); | ||||
| 	report->bb_count = test_rw(hPhysicalDrive, last_block, BADBLOCK_BLOCK_SIZE, 0, BB_BLOCKS_AT_ONCE, flash_type, nb_passes); | ||||
| 	KillTimer(hMainDialog, TID_BADBLOCKS_UPDATE); | ||||
| 	free(bb_list->list); | ||||
| 	free(bb_list); | ||||
|  |  | |||
|  | @ -7,7 +7,7 @@ | |||
|  * | ||||
|  * Copyright 1995, 1996, 1997, 1998, 1999 by Theodore Ts'o | ||||
|  * Copyright 1999 by David Beattie | ||||
|  * Copyright 2011-2013 by Pete Batard | ||||
|  * Copyright 2011-2018 by Pete Batard | ||||
|  * | ||||
|  * This file is based on the minix file system programs fsck and mkfs | ||||
|  * written and copyrighted by Linus Torvalds <Linus.Torvalds@cs.helsinki.fi> | ||||
|  | @ -55,5 +55,5 @@ typedef struct { | |||
| /*
 | ||||
|  * Shared prototypes | ||||
|  */ | ||||
| BOOL BadBlocks(HANDLE hPhysicalDrive, ULONGLONG disk_size, size_t block_size, | ||||
| 	int test_type, badblocks_report *report, FILE* fd); | ||||
| BOOL BadBlocks(HANDLE hPhysicalDrive, ULONGLONG disk_size, int nb_passes, | ||||
| 	int flash_type, badblocks_report *report, FILE* fd); | ||||
|  |  | |||
							
								
								
									
										17
									
								
								src/dev.c
									
										
									
									
									
								
							
							
						
						
									
										17
									
								
								src/dev.c
									
										
									
									
									
								
							|  | @ -32,6 +32,7 @@ | |||
| #include <inttypes.h> | ||||
| #include <commctrl.h> | ||||
| #include <setupapi.h> | ||||
| #include <assert.h> | ||||
| 
 | ||||
| #include "rufus.h" | ||||
| #include "missing.h" | ||||
|  | @ -452,16 +453,12 @@ BOOL GetDevices(DWORD devnum) | |||
| 		if (strcmp(genstor_name[s], "SD") == 0) | ||||
| 			card_start = s; | ||||
| 	} | ||||
| 	// Overkill, but better safe than sorry. And yeah, we could have used
 | ||||
| 	// arrays of arrays to avoid this, but it's more readable this way.
 | ||||
| 	if ((uasp_start <= 0) || (uasp_start >= ARRAYSIZE(usbstor_name))) { | ||||
| 		uprintf("Spock gone crazy error in %s:%d", __FILE__, __LINE__); | ||||
| 		goto out; | ||||
| 	} | ||||
| 	if ((card_start <= 0) || (card_start >= ARRAYSIZE(genstor_name))) { | ||||
| 		uprintf("Spock gone crazy error in %s:%d", __FILE__, __LINE__); | ||||
| 		goto out; | ||||
| 	} | ||||
| 
 | ||||
| 	// Better safe than sorry. And yeah, we could have used arrays of
 | ||||
| 	// arrays to avoid this, but it's more readable this way.
 | ||||
| 	assert((uasp_start > 0) && (uasp_start < ARRAYSIZE(usbstor_name))); | ||||
| 	assert((card_start > 0) && (card_start < ARRAYSIZE(genstor_name))); | ||||
| 
 | ||||
| 	devid_list = NULL; | ||||
| 	if (full_list_size != 0) { | ||||
| 		full_list_size += 1;	// add extra NUL terminator
 | ||||
|  |  | |||
|  | @ -26,6 +26,7 @@ | |||
| #include <windows.h> | ||||
| #include <stdio.h> | ||||
| #include <string.h> | ||||
| #include <assert.h> | ||||
| 
 | ||||
| #include "rufus.h" | ||||
| 
 | ||||
|  | @ -288,8 +289,8 @@ static const char* kb_to_hr(const char* kb) | |||
| 		} | ||||
| 	} | ||||
| 	// Should never happen, so let's try to get some attention here
 | ||||
| 	MessageBoxA(hMainDialog, "YO BNLA #1", "UHAHAHHA?", MB_OKCANCEL|MB_ICONWARNING); | ||||
| 	return "Someone missed a keyboard!"; | ||||
| 	assert(i < ARRAYSIZE(kb_hr_list)); | ||||
| 	return NULL; | ||||
| } | ||||
| 
 | ||||
| typedef struct { | ||||
|  | @ -425,8 +426,8 @@ static const char* cp_to_hr(ULONG cp) | |||
| 		} | ||||
| 	} | ||||
| 	// Should never happen, so this oughta get some attention
 | ||||
| 	MessageBoxA(hMainDialog, "YO BNLA #2", "UHAHAHHA?", MB_OKCANCEL|MB_ICONWARNING); | ||||
| 	return "Someone missed a codepage!"; | ||||
| 	assert(i < ARRAYSIZE(cp_hr_list)); | ||||
| 	return NULL; | ||||
| } | ||||
| 
 | ||||
| // http://blogs.msdn.com/b/michkap/archive/2004/12/05/275231.aspx
 | ||||
|  |  | |||
|  | @ -25,6 +25,7 @@ | |||
| #include <stdio.h> | ||||
| #include <string.h> | ||||
| #include <ctype.h> | ||||
| #include <assert.h> | ||||
| 
 | ||||
| #include "rufus.h" | ||||
| #include "missing.h" | ||||
|  | @ -109,11 +110,9 @@ BOOL GetAutoMount(BOOL* enabled) | |||
|  * clear the MBR of!), so we mitigate the risk by forcing our indexes to belong to | ||||
|  * the specific range [DRIVE_INDEX_MIN; DRIVE_INDEX_MAX]. | ||||
|  */ | ||||
| #define CheckDriveIndex(DriveIndex) do { \ | ||||
| 	if ((DriveIndex < DRIVE_INDEX_MIN) || (DriveIndex > DRIVE_INDEX_MAX)) { \ | ||||
| 		uprintf("ERROR: Bad index value %d. Please check the code!", DriveIndex); \ | ||||
| 		goto out; \ | ||||
| 	} \ | ||||
| #define CheckDriveIndex(DriveIndex) do {                                            \ | ||||
| 	assert((DriveIndex >= DRIVE_INDEX_MIN) && (DriveIndex <= DRIVE_INDEX_MAX));     \ | ||||
| 	if ((DriveIndex < DRIVE_INDEX_MIN) || (DriveIndex > DRIVE_INDEX_MAX)) goto out; \ | ||||
| 	DriveIndex -= DRIVE_INDEX_MIN; } while (0) | ||||
| 
 | ||||
| /*
 | ||||
|  |  | |||
|  | @ -31,6 +31,7 @@ | |||
| #include <stddef.h> | ||||
| #include <ctype.h> | ||||
| #include <locale.h> | ||||
| #include <assert.h> | ||||
| 
 | ||||
| #include "rufus.h" | ||||
| #include "missing.h" | ||||
|  | @ -1856,6 +1857,7 @@ DWORD WINAPI FormatThread(void* param) | |||
| 
 | ||||
| 	if (IsChecked(IDC_BAD_BLOCKS)) { | ||||
| 		do { | ||||
| 			int sel = ComboBox_GetCurSel(hNBPasses); | ||||
| 			// create a log file for bad blocks report. Since %USERPROFILE% may
 | ||||
| 			// have localized characters, we use the UTF-8 API.
 | ||||
| 			userdir = getenvU("USERPROFILE"); | ||||
|  | @ -1874,8 +1876,8 @@ DWORD WINAPI FormatThread(void* param) | |||
| 				fflush(log_fd); | ||||
| 			} | ||||
| 
 | ||||
| 			if (!BadBlocks(hPhysicalDrive, SelectedDrive.DiskSize, SelectedDrive.SectorSize, | ||||
| 				ComboBox_GetCurSel(hNBPasses)+1, &report, log_fd)) { | ||||
| 			if (!BadBlocks(hPhysicalDrive, SelectedDrive.DiskSize, (sel >= 2) ? 4 : sel +1, | ||||
| 				(sel < 2) ? 0 : sel - 2, &report, log_fd)) { | ||||
| 				uprintf("Bad blocks: Check failed.\n"); | ||||
| 				if (!IS_ERROR(FormatStatus)) | ||||
| 					FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR(ERROR_BADBLOCKS_FAILURE); | ||||
|  | @ -2029,8 +2031,8 @@ DWORD WINAPI FormatThread(void* param) | |||
| 			// All good
 | ||||
| 		} else if (tt == TT_UEFI) { | ||||
| 			// For once, no need to do anything - just check our sanity
 | ||||
| 			assert((bt == BT_IMAGE) && IS_EFI_BOOTABLE(img_report) && (fs <= FS_NTFS)); | ||||
| 			if ( (bt != BT_IMAGE) || !IS_EFI_BOOTABLE(img_report) || (fs > FS_NTFS) ) { | ||||
| 				uprintf("Spock gone crazy error in %s:%d", __FILE__, __LINE__); | ||||
| 				FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_INSTALL_FAILURE; | ||||
| 				goto out; | ||||
| 			} | ||||
|  |  | |||
|  | @ -512,6 +512,22 @@ static __inline int PathGetDriveNumberU(char* lpPath) | |||
| 	return ret; | ||||
| } | ||||
| 
 | ||||
| // This one is tricky since we can't blindly convert a
 | ||||
| // UTF-16 position to a UTF-8 one. So we do it manually.
 | ||||
| static __inline const char* PathFindFileNameU(const char* szPath) | ||||
| { | ||||
| 	size_t i; | ||||
| 	if (szPath == NULL) | ||||
| 		return NULL; | ||||
| 	for (i = strlen(szPath); i != 0; i--) { | ||||
| 		if ((szPath[i] == '/') || (szPath[i] == '\\')) { | ||||
| 			i++; | ||||
| 			break; | ||||
| 		} | ||||
| 	} | ||||
| 	return &szPath[i]; | ||||
| } | ||||
| 
 | ||||
| // This function differs from regular GetTextExtentPoint in that it uses a zero terminated string
 | ||||
| static __inline BOOL GetTextExtentPointU(HDC hdc, const char* lpString, LPSIZE lpSize) | ||||
| { | ||||
|  |  | |||
							
								
								
									
										261
									
								
								src/net.c
									
										
									
									
									
								
							
							
						
						
									
										261
									
								
								src/net.c
									
										
									
									
									
								
							|  | @ -29,6 +29,7 @@ | |||
| #include <malloc.h> | ||||
| #include <string.h> | ||||
| #include <inttypes.h> | ||||
| #include <assert.h> | ||||
| 
 | ||||
| #include "rufus.h" | ||||
| #include "missing.h" | ||||
|  | @ -44,7 +45,6 @@ | |||
| #define DEFAULT_UPDATE_INTERVAL (24*3600) | ||||
| 
 | ||||
| DWORD DownloadStatus; | ||||
| BOOL PromptOnError = TRUE; | ||||
| 
 | ||||
| extern BOOL force_update; | ||||
| static DWORD error_code; | ||||
|  | @ -216,13 +216,14 @@ const char* WinInetErrorString(void) | |||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * Download a file from an URL | ||||
|  * Download a file or fill a buffer from an URL | ||||
|  * Mostly taken from http://support.microsoft.com/kb/234913
 | ||||
|  * If file is NULL, a buffer is allocated for the download (that needs to be freed by the caller) | ||||
|  * If hProgressDialog is not NULL, this function will send INIT and EXIT messages | ||||
|  * to the dialog in question, with WPARAM being set to nonzero for EXIT on success | ||||
|  * and also attempt to indicate progress using an IDC_PROGRESS control | ||||
|  */ | ||||
| DWORD DownloadFile(const char* url, const char* file, HWND hProgressDialog) | ||||
| static DWORD DownloadToFileOrBuffer(const char* url, const char* file, BYTE** buffer, HWND hProgressDialog) | ||||
| { | ||||
| 	HWND hProgressBar = NULL; | ||||
| 	BOOL r = FALSE; | ||||
|  | @ -234,8 +235,8 @@ DWORD DownloadFile(const char* url, const char* file, HWND hProgressDialog) | |||
| 	HINTERNET hSession = NULL, hConnection = NULL, hRequest = NULL; | ||||
| 	URL_COMPONENTSA UrlParts = {sizeof(URL_COMPONENTSA), NULL, 1, (INTERNET_SCHEME)0, | ||||
| 		hostname, sizeof(hostname), 0, NULL, 1, urlpath, sizeof(urlpath), NULL, 1}; | ||||
| 	size_t last_slash; | ||||
| 	int i; | ||||
| 	const char* short_name; | ||||
| 	size_t i; | ||||
| 
 | ||||
| 	// Can't link with wininet.lib because of sideloading issues
 | ||||
| 	PF_TYPE_DECL(WINAPI, BOOL, InternetCrackUrlA, (LPCSTR, DWORD, DWORD, LPURL_COMPONENTSA)); | ||||
|  | @ -257,7 +258,8 @@ DWORD DownloadFile(const char* url, const char* file, HWND hProgressDialog) | |||
| 	PF_INIT_OR_OUT(HttpSendRequestA, WinInet); | ||||
| 	PF_INIT_OR_OUT(HttpQueryInfoA, WinInet); | ||||
| 
 | ||||
| 	DownloadStatus = 0; | ||||
| 	FormatStatus = 0; | ||||
| 	DownloadStatus = 404; | ||||
| 	if (hProgressDialog != NULL) { | ||||
| 		// Use the progress control provided, if any
 | ||||
| 		hProgressBar = GetDlgItem(hProgressDialog, IDC_PROGRESS); | ||||
|  | @ -268,22 +270,18 @@ DWORD DownloadFile(const char* url, const char* file, HWND hProgressDialog) | |||
| 		SendMessage(hProgressDialog, UM_PROGRESS_INIT, 0, 0); | ||||
| 	} | ||||
| 
 | ||||
| 	if (file == NULL) | ||||
| 		goto out; | ||||
| 	assert(url != NULL); | ||||
| 
 | ||||
| 	for (last_slash = safe_strlen(file); last_slash != 0; last_slash--) { | ||||
| 		if ((file[last_slash] == '/') || (file[last_slash] == '\\')) { | ||||
| 			last_slash++; | ||||
| 			break; | ||||
| 		} | ||||
| 	short_name = (file != NULL) ? PathFindFileNameU(file) : PathFindFileNameU(url); | ||||
| 
 | ||||
| 	if (hProgressDialog != NULL) { | ||||
| 		PrintInfo(0, MSG_085, short_name); | ||||
| 		uprintf("Downloading %s", url); | ||||
| 	} | ||||
| 
 | ||||
| 	PrintInfo(0, MSG_085, &file[last_slash]); | ||||
| 	uprintf("Downloading '%s' from %s\n", &file[last_slash], url); | ||||
| 
 | ||||
| 	if ( (!pfInternetCrackUrlA(url, (DWORD)safe_strlen(url), 0, &UrlParts)) | ||||
| 	  || (UrlParts.lpszHostName == NULL) || (UrlParts.lpszUrlPath == NULL)) { | ||||
| 		uprintf("Unable to decode URL: %s\n", WinInetErrorString()); | ||||
| 		uprintf("Unable to decode URL: %s", WinInetErrorString()); | ||||
| 		goto out; | ||||
| 	} | ||||
| 	hostname[sizeof(hostname)-1] = 0; | ||||
|  | @ -295,7 +293,7 @@ DWORD DownloadFile(const char* url, const char* file, HWND hProgressDialog) | |||
| 	if (i <= 0) { | ||||
| 		// http://msdn.microsoft.com/en-us/library/windows/desktop/aa384702.aspx is wrong...
 | ||||
| 		SetLastError(ERROR_INTERNET_NOT_INITIALIZED); | ||||
| 		uprintf("Network is unavailable: %s\n", WinInetErrorString()); | ||||
| 		uprintf("Network is unavailable: %s", WinInetErrorString()); | ||||
| 		goto out; | ||||
| 	} | ||||
| 	static_sprintf(agent, APPLICATION_NAME "/%d.%d.%d (Windows NT %d.%d%s)", | ||||
|  | @ -303,13 +301,13 @@ DWORD DownloadFile(const char* url, const char* file, HWND hProgressDialog) | |||
| 		nWindowsVersion>>4, nWindowsVersion&0x0F, is_x64()?"; WOW64":""); | ||||
| 	hSession = pfInternetOpenA(agent, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0); | ||||
| 	if (hSession == NULL) { | ||||
| 		uprintf("Could not open Internet session: %s\n", WinInetErrorString()); | ||||
| 		uprintf("Could not open Internet session: %s", WinInetErrorString()); | ||||
| 		goto out; | ||||
| 	} | ||||
| 
 | ||||
| 	hConnection = pfInternetConnectA(hSession, UrlParts.lpszHostName, UrlParts.nPort, NULL, NULL, INTERNET_SERVICE_HTTP, 0, (DWORD_PTR)NULL); | ||||
| 	if (hConnection == NULL) { | ||||
| 		uprintf("Could not connect to server %s:%d: %s\n", UrlParts.lpszHostName, UrlParts.nPort, WinInetErrorString()); | ||||
| 		uprintf("Could not connect to server %s:%d: %s", UrlParts.lpszHostName, UrlParts.nPort, WinInetErrorString()); | ||||
| 		goto out; | ||||
| 	} | ||||
| 
 | ||||
|  | @ -318,84 +316,97 @@ DWORD DownloadFile(const char* url, const char* file, HWND hProgressDialog) | |||
| 		INTERNET_FLAG_NO_COOKIES|INTERNET_FLAG_NO_UI|INTERNET_FLAG_NO_CACHE_WRITE|INTERNET_FLAG_HYPERLINK| | ||||
| 		((UrlParts.nScheme==INTERNET_SCHEME_HTTPS)?INTERNET_FLAG_SECURE:0), (DWORD_PTR)NULL); | ||||
| 	if (hRequest == NULL) { | ||||
| 		uprintf("Could not open URL %s: %s\n", url, WinInetErrorString()); | ||||
| 		uprintf("Could not open URL %s: %s", url, WinInetErrorString()); | ||||
| 		goto out; | ||||
| 	} | ||||
| 
 | ||||
| 	if (!pfHttpSendRequestA(hRequest, NULL, 0, NULL, 0)) { | ||||
| 		uprintf("Unable to send request: %s\n", WinInetErrorString()); | ||||
| 		uprintf("Unable to send request: %s", WinInetErrorString()); | ||||
| 		goto out; | ||||
| 	} | ||||
| 
 | ||||
| 	// Get the file size
 | ||||
| 	dwSize = sizeof(DownloadStatus); | ||||
| 	DownloadStatus = 404; | ||||
| 	pfHttpQueryInfoA(hRequest, HTTP_QUERY_STATUS_CODE|HTTP_QUERY_FLAG_NUMBER, (LPVOID)&DownloadStatus, &dwSize, NULL); | ||||
| 	if (DownloadStatus != 200) { | ||||
| 		error_code = ERROR_INTERNET_ITEM_NOT_FOUND; | ||||
| 		uprintf("Unable to access file: %d\n", DownloadStatus); | ||||
| 		uprintf("Unable to access file: %d", DownloadStatus); | ||||
| 		goto out; | ||||
| 	} | ||||
| 	dwSize = sizeof(dwTotalSize); | ||||
| 	if (!pfHttpQueryInfoA(hRequest, HTTP_QUERY_CONTENT_LENGTH|HTTP_QUERY_FLAG_NUMBER, (LPVOID)&dwTotalSize, &dwSize, NULL)) { | ||||
| 		uprintf("Unable to retrieve file length: %s\n", WinInetErrorString()); | ||||
| 		uprintf("Unable to retrieve file length: %s", WinInetErrorString()); | ||||
| 		goto out; | ||||
| 	} | ||||
| 	uprintf("File length: %d bytes\n", dwTotalSize); | ||||
| 	if (hProgressDialog != NULL) | ||||
| 		uprintf("File length: %d bytes", dwTotalSize); | ||||
| 
 | ||||
| 	hFile = CreateFileU(file, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); | ||||
| 	if (hFile == INVALID_HANDLE_VALUE) { | ||||
| 		uprintf("Unable to create file '%s': %s\n", &file[last_slash], WinInetErrorString()); | ||||
| 		goto out; | ||||
| 	if (file != NULL) { | ||||
| 		hFile = CreateFileU(file, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); | ||||
| 		if (hFile == INVALID_HANDLE_VALUE) { | ||||
| 			uprintf("Unable to create file '%s': %s", short_name, WinInetErrorString()); | ||||
| 			goto out; | ||||
| 		} | ||||
| 	} else { | ||||
| 		if (buffer == NULL) { | ||||
| 			uprintf("No buffer pointer provided for download"); | ||||
| 			goto out; | ||||
| 		} | ||||
| 		*buffer = malloc(dwTotalSize); | ||||
| 		if (*buffer == NULL) { | ||||
| 			uprintf("Could not allocate buffer for download"); | ||||
| 			goto out; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	// Keep checking for data until there is nothing left.
 | ||||
| 	dwSize = 0; | ||||
| 	while (1) { | ||||
| 		// User may have cancelled the download
 | ||||
| 		if (IS_ERROR(FormatStatus)) | ||||
| 			goto out; | ||||
| 
 | ||||
| 		if (!pfInternetReadFile(hRequest, buf, sizeof(buf), &dwDownloaded) || (dwDownloaded == 0)) | ||||
| 			break; | ||||
| 		dwSize += dwDownloaded; | ||||
| 		SendMessage(hProgressBar, PBM_SETPOS, (WPARAM)(MAX_PROGRESS*((1.0f*dwSize)/(1.0f*dwTotalSize))), 0); | ||||
| 		PrintInfo(0, MSG_241, (100.0f*dwSize)/(1.0f*dwTotalSize)); | ||||
| 		if (!WriteFile(hFile, buf, dwDownloaded, &dwWritten, NULL)) { | ||||
| 			uprintf("Error writing file '%s': %s\n", &file[last_slash], WinInetErrorString()); | ||||
| 			goto out; | ||||
| 		} else if (dwDownloaded != dwWritten) { | ||||
| 			uprintf("Error writing file '%s': Only %d/%d bytes written\n", dwWritten, dwDownloaded); | ||||
| 			goto out; | ||||
| 		if (hProgressDialog != NULL) { | ||||
| 			SendMessage(hProgressBar, PBM_SETPOS, (WPARAM)(MAX_PROGRESS*((1.0f*dwSize) / (1.0f*dwTotalSize))), 0); | ||||
| 			PrintInfo(0, MSG_241, (100.0f*dwSize) / (1.0f*dwTotalSize)); | ||||
| 		} | ||||
| 		if (file != NULL) { | ||||
| 			if (!WriteFile(hFile, buf, dwDownloaded, &dwWritten, NULL)) { | ||||
| 				uprintf("Error writing file '%s': %s", short_name, WinInetErrorString()); | ||||
| 				goto out; | ||||
| 			} else if (dwDownloaded != dwWritten) { | ||||
| 				uprintf("Error writing file '%s': Only %d/%d bytes written", short_name, dwWritten, dwDownloaded); | ||||
| 				goto out; | ||||
| 			} | ||||
| 		} else { | ||||
| 			memcpy(&(*buffer)[dwSize], buf, dwDownloaded); | ||||
| 		} | ||||
| 		dwSize += dwDownloaded; | ||||
| 	} | ||||
| 
 | ||||
| 	if (dwSize != dwTotalSize) { | ||||
| 		uprintf("Could not download complete file - read: %d bytes, expected: %d bytes\n", dwSize, dwTotalSize); | ||||
| 		uprintf("Could not download complete file - read: %d bytes, expected: %d bytes", dwSize, dwTotalSize); | ||||
| 		FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_WRITE_FAULT; | ||||
| 		goto out; | ||||
| 	} else { | ||||
| 		DownloadStatus = 200; | ||||
| 		r = TRUE; | ||||
| 		uprintf("Successfully downloaded '%s'\n", &file[last_slash]); | ||||
| 		if (hProgressDialog != NULL) { | ||||
| 			uprintf("Successfully downloaded '%s'", short_name); | ||||
| 			SendMessage(hProgressBar, PBM_SETPOS, (WPARAM)MAX_PROGRESS, 0); | ||||
| 			PrintInfo(0, MSG_241, 100.0f); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| out: | ||||
| 	if (hProgressDialog != NULL) | ||||
| 		SendMessage(hProgressDialog, UM_PROGRESS_EXIT, (WPARAM)r, 0); | ||||
| 	if (hFile != INVALID_HANDLE_VALUE) { | ||||
| 		// Force a flush - May help with the PKI API trying to process downloaded updates too early...
 | ||||
| 		FlushFileBuffers(hFile); | ||||
| 		CloseHandle(hFile); | ||||
| 	} | ||||
| 	if (!r) { | ||||
| 		if (file != NULL) | ||||
| 			_unlinkU(file); | ||||
| 		if (PromptOnError) { | ||||
| 			PrintInfo(0, MSG_242); | ||||
| 			SetLastError(error_code); | ||||
| 			MessageBoxExU(hMainDialog, IS_ERROR(FormatStatus)?StrError(FormatStatus, FALSE):WinInetErrorString(), | ||||
| 			lmprintf(MSG_044), MB_OK|MB_ICONERROR|MB_IS_RTL, selected_langid); | ||||
| 		} | ||||
| 	} | ||||
| 	if ((!r) && (file != NULL)) | ||||
| 		_unlinkU(file); | ||||
| 	if (hRequest) | ||||
| 		pfInternetCloseHandle(hRequest); | ||||
| 	if (hConnection) | ||||
|  | @ -403,23 +414,95 @@ out: | |||
| 	if (hSession) | ||||
| 		pfInternetCloseHandle(hSession); | ||||
| 
 | ||||
| 	return r?dwSize:0; | ||||
| 	return r ? dwSize : 0; | ||||
| } | ||||
| 
 | ||||
| // Download and validate a signed file. The file must have a corresponding '.sig' on the server.
 | ||||
| DWORD DownloadSignedFile(const char* url, const char* file, HWND hProgressDialog, BOOL bPromptOnError) | ||||
| { | ||||
| 	char* url_sig = NULL; | ||||
| 	BYTE *buf = NULL, *sig = NULL; | ||||
| 	DWORD buf_len = 0, sig_len = 0; | ||||
| 	DWORD ret = 0; | ||||
| 	HANDLE hFile = INVALID_HANDLE_VALUE; | ||||
| 
 | ||||
| 	assert(url != NULL); | ||||
| 
 | ||||
| 	url_sig = malloc(strlen(url) + 5); | ||||
| 	if (url_sig == NULL) { | ||||
| 		uprintf("Could not allocate signature URL"); | ||||
| 		goto out; | ||||
| 	} | ||||
| 	strcpy(url_sig, url); | ||||
| 	strcat(url_sig, ".sig"); | ||||
| 
 | ||||
| 	buf_len = DownloadToFileOrBuffer(url, NULL, &buf, hProgressDialog); | ||||
| 	if (buf_len == 0) | ||||
| 		goto out; | ||||
| 	sig_len = DownloadToFileOrBuffer(url_sig, NULL, &sig, NULL); | ||||
| 	if ((sig_len != RSA_SIGNATURE_SIZE) || (!ValidateOpensslSignature(buf, buf_len, sig, sig_len))) { | ||||
| 		uprintf("FATAL: Download signature is invalid ✗"); | ||||
| 		DownloadStatus = 403;	// Forbidden
 | ||||
| 		FormatStatus = ERROR_SEVERITY_ERROR | FAC(FACILITY_STORAGE) | APPERR(ERROR_BAD_SIGNATURE); | ||||
| 		goto out; | ||||
| 	} | ||||
| 
 | ||||
| 	uprintf("Download signature is valid ✓"); | ||||
| 	DownloadStatus = 206;	// Partial content
 | ||||
| 	hFile = CreateFileU(file, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); | ||||
| 	if (hFile == INVALID_HANDLE_VALUE) { | ||||
| 		uprintf("Unable to create file '%s': %s", PathFindFileNameU(file), WinInetErrorString()); | ||||
| 		goto out; | ||||
| 	} | ||||
| 	if (!WriteFile(hFile, buf, buf_len, &ret, NULL)) { | ||||
| 		uprintf("Error writing file '%s': %s", PathFindFileNameU(file), WinInetErrorString()); | ||||
| 		ret = 0; | ||||
| 		goto out; | ||||
| 	} else if (ret != buf_len) { | ||||
| 		uprintf("Error writing file '%s': Only %d/%d bytes written", PathFindFileNameU(file), ret, buf_len); | ||||
| 		ret = 0; | ||||
| 		goto out; | ||||
| 	} | ||||
| 	DownloadStatus = 200;	// Full content
 | ||||
| 
 | ||||
| out: | ||||
| 	if (hProgressDialog != NULL) | ||||
| 		SendMessage(hProgressDialog, UM_PROGRESS_EXIT, (WPARAM)ret, 0); | ||||
| 	if ((bPromptOnError) && (DownloadStatus != 200)) { | ||||
| 		PrintInfo(0, MSG_242); | ||||
| 		SetLastError(error_code); | ||||
| 		MessageBoxExU(hMainDialog, IS_ERROR(FormatStatus) ? StrError(FormatStatus, FALSE) : WinInetErrorString(), | ||||
| 			lmprintf(MSG_044), MB_OK | MB_ICONERROR | MB_IS_RTL, selected_langid); | ||||
| 	} | ||||
| 	safe_closehandle(hFile); | ||||
| 	free(url_sig); | ||||
| 	free(buf); | ||||
| 	free(sig); | ||||
| 	return ret; | ||||
| } | ||||
| 
 | ||||
| /* Threaded download */ | ||||
| static const char *_url, *_file; | ||||
| static HWND _hProgressDialog; | ||||
| static DWORD WINAPI _DownloadFileThread(LPVOID param) | ||||
| typedef struct { | ||||
| 	const char* url; | ||||
| 	const char* file; | ||||
| 	HWND hProgressDialog; | ||||
| 	BOOL bPromptOnError; | ||||
| } DownloadSignedFileThreadArgs; | ||||
| 
 | ||||
| static DWORD WINAPI DownloadSignedFileThread(LPVOID param) | ||||
| { | ||||
| 	ExitThread(DownloadFile(_url, _file, _hProgressDialog) != 0); | ||||
| 	DownloadSignedFileThreadArgs* args = (DownloadSignedFileThreadArgs*)param; | ||||
| 	ExitThread(DownloadSignedFile(args->url, args->file, args->hProgressDialog, args->bPromptOnError)); | ||||
| } | ||||
| 
 | ||||
| HANDLE DownloadFileThreaded(const char* url, const char* file, HWND hProgressDialog) | ||||
| HANDLE DownloadSignedFileThreaded(const char* url, const char* file, HWND hProgressDialog, BOOL bPromptOnError) | ||||
| { | ||||
| 	_url = url; | ||||
| 	_file = file; | ||||
| 	_hProgressDialog = hProgressDialog; | ||||
| 	return CreateThread(NULL, 0, _DownloadFileThread, NULL, 0, NULL); | ||||
| 	static DownloadSignedFileThreadArgs args; | ||||
| 	args.url = url; | ||||
| 	args.file = file; | ||||
| 	args.hProgressDialog = hProgressDialog; | ||||
| 	args.bPromptOnError = bPromptOnError; | ||||
| 	return CreateThread(NULL, 0, DownloadSignedFileThread, &args, 0, NULL); | ||||
| } | ||||
| 
 | ||||
| static __inline uint64_t to_uint64_t(uint16_t x[4]) { | ||||
|  | @ -443,8 +526,9 @@ static DWORD WINAPI CheckForUpdatesThread(LPVOID param) | |||
| 	static const char* channel[] = {"release", "beta", "test"};		// release channel
 | ||||
| 	const char* accept_types[] = {"*/*\0", NULL}; | ||||
| 	DWORD dwFlags, dwSize, dwDownloaded, dwTotalSize, dwStatus; | ||||
| 	BYTE *sig = NULL; | ||||
| 	char* buf = NULL; | ||||
| 	char agent[64], hostname[64], urlpath[128], mime[32]; | ||||
| 	char agent[64], hostname[64], urlpath[128], sigpath[256], mime[32]; | ||||
| 	OSVERSIONINFOA os_version = {sizeof(OSVERSIONINFOA), 0, 0, 0, 0, ""}; | ||||
| 	HINTERNET hSession = NULL, hConnection = NULL, hRequest = NULL; | ||||
| 	URL_COMPONENTSA UrlParts = {sizeof(URL_COMPONENTSA), NULL, 1, (INTERNET_SCHEME)0, | ||||
|  | @ -487,7 +571,7 @@ static DWORD WINAPI CheckForUpdatesThread(LPVOID param) | |||
| 		} while ((!force_update_check) && ((iso_op_in_progress || format_op_in_progress || (dialog_showing>0)))); | ||||
| 		if (!force_update_check) { | ||||
| 			if ((ReadSetting32(SETTING_UPDATE_INTERVAL) == -1)) { | ||||
| 				vuprintf("Check for updates disabled, as per settings.\n"); | ||||
| 				vuprintf("Check for updates disabled, as per settings."); | ||||
| 				goto out; | ||||
| 			} | ||||
| 			reg_time = ReadSetting64(SETTING_LAST_UPDATE); | ||||
|  | @ -500,9 +584,9 @@ static DWORD WINAPI CheckForUpdatesThread(LPVOID param) | |||
| 			if (!SystemTimeToFileTime(&LocalTime, &FileTime)) | ||||
| 				goto out; | ||||
| 			local_time = ((((int64_t)FileTime.dwHighDateTime)<<32) + FileTime.dwLowDateTime) / 10000000; | ||||
| 			vvuprintf("Local time: %" PRId64 "\n", local_time); | ||||
| 			vvuprintf("Local time: %" PRId64, local_time); | ||||
| 			if (local_time < reg_time + update_interval) { | ||||
| 				vuprintf("Next update check in %" PRId64 " seconds.\n", reg_time + update_interval - local_time); | ||||
| 				vuprintf("Next update check in %" PRId64 " seconds.", reg_time + update_interval - local_time); | ||||
| 				goto out; | ||||
| 			} | ||||
| 		} | ||||
|  | @ -512,7 +596,7 @@ static DWORD WINAPI CheckForUpdatesThread(LPVOID param) | |||
| 	status++;	// 1
 | ||||
| 
 | ||||
| 	if (!GetVersionExA(&os_version)) { | ||||
| 		uprintf("Could not read Windows version - Check for updates cancelled.\n"); | ||||
| 		uprintf("Could not read Windows version - Check for updates cancelled."); | ||||
| 		goto out; | ||||
| 	} | ||||
| 
 | ||||
|  | @ -540,7 +624,7 @@ static DWORD WINAPI CheckForUpdatesThread(LPVOID param) | |||
| 	max_channel = releases_only ? 1 : (int)ARRAYSIZE(channel) - 1; | ||||
| #endif | ||||
| 	for (k=0; (k<max_channel) && (!found_new_version); k++) { | ||||
| 		uprintf("Checking %s channel...\n", channel[k]); | ||||
| 		uprintf("Checking %s channel...", channel[k]); | ||||
| 		// At this stage we can query the server for various update version files.
 | ||||
| 		// We first try to lookup for "<appname>_<os_arch>_<os_version_major>_<os_version_minor>.ver"
 | ||||
| 		// and then remove each each of the <os_> components until we find our match. For instance, we may first
 | ||||
|  | @ -548,21 +632,18 @@ static DWORD WINAPI CheckForUpdatesThread(LPVOID param) | |||
| 		// This allows sunsetting OS versions (eg XP) or providing different downloads for different archs/groups.
 | ||||
| 		static_sprintf(urlpath, "%s%s%s_%s_%lu.%lu.ver", APPLICATION_NAME, (k==0)?"":"_", | ||||
| 			(k==0)?"":channel[k], archname[is_x64()?1:0], os_version.dwMajorVersion, os_version.dwMinorVersion); | ||||
| 		vuprintf("Base update check: %s\n", urlpath); | ||||
| 		vuprintf("Base update check: %s", urlpath); | ||||
| 		for (i=0, j=(int)safe_strlen(urlpath)-5; (j>0)&&(i<ARRAYSIZE(verpos)); j--) { | ||||
| 			if ((urlpath[j] == '.') || (urlpath[j] == '_')) { | ||||
| 				verpos[i++] = j; | ||||
| 			} | ||||
| 		} | ||||
| 		if (i != ARRAYSIZE(verpos)) { | ||||
| 			uprintf("Broken code in CheckForUpdatesThread()!\n"); | ||||
| 			goto out; | ||||
| 		} | ||||
| 		assert(i == ARRAYSIZE(verpos)); | ||||
| 
 | ||||
| 		UrlParts.lpszUrlPath = urlpath; | ||||
| 		UrlParts.dwUrlPathLength = sizeof(urlpath); | ||||
| 		for (i=0; i<ARRAYSIZE(verpos); i++) { | ||||
| 			vvuprintf("Trying %s\n", UrlParts.lpszUrlPath); | ||||
| 			vvuprintf("Trying %s", UrlParts.lpszUrlPath); | ||||
| 			hRequest = pfHttpOpenRequestA(hConnection, "GET", UrlParts.lpszUrlPath, NULL, NULL, accept_types, | ||||
| 				INTERNET_FLAG_IGNORE_REDIRECT_TO_HTTP|INTERNET_FLAG_IGNORE_REDIRECT_TO_HTTPS| | ||||
| 				INTERNET_FLAG_NO_COOKIES|INTERNET_FLAG_NO_UI|INTERNET_FLAG_NO_CACHE_WRITE|INTERNET_FLAG_HYPERLINK| | ||||
|  | @ -607,7 +688,7 @@ static DWORD WINAPI CheckForUpdatesThread(LPVOID param) | |||
| 			|| (!SystemTimeToFileTime(&ServerTime, &FileTime)) ) | ||||
| 			goto out; | ||||
| 		server_time = ((((int64_t)FileTime.dwHighDateTime)<<32) + FileTime.dwLowDateTime) / 10000000; | ||||
| 		vvuprintf("Server time: %" PRId64 "\n", server_time); | ||||
| 		vvuprintf("Server time: %" PRId64, server_time); | ||||
| 		// Always store the server response time - the only clock we trust!
 | ||||
| 		WriteSetting64(SETTING_LAST_UPDATE, server_time); | ||||
| 		// Might as well let the user know
 | ||||
|  | @ -625,29 +706,39 @@ static DWORD WINAPI CheckForUpdatesThread(LPVOID param) | |||
| 		safe_free(buf); | ||||
| 		// Make sure the file is NUL terminated
 | ||||
| 		buf = (char*)calloc(dwTotalSize+1, 1); | ||||
| 		if (buf == NULL) goto out; | ||||
| 		if (buf == NULL) | ||||
| 			goto out; | ||||
| 		// This is a version file - we should be able to gulp it down in one go
 | ||||
| 		if (!pfInternetReadFile(hRequest, buf, dwTotalSize, &dwDownloaded) || (dwDownloaded != dwTotalSize)) | ||||
| 			goto out; | ||||
| 		vuprintf("Successfully downloaded version file (%d bytes)", dwTotalSize); | ||||
| 
 | ||||
| 		// Now download the signature file
 | ||||
| 		static_sprintf(sigpath, "%s/%s.sig", server_url, urlpath); | ||||
| 		dwDownloaded = DownloadToFileOrBuffer(sigpath, NULL, &sig, NULL); | ||||
| 		if ((dwDownloaded != RSA_SIGNATURE_SIZE) || (!ValidateOpensslSignature(buf, dwTotalSize, sig, dwDownloaded))) { | ||||
| 			uprintf("FATAL: Version signature is invalid!"); | ||||
| 			goto out; | ||||
| 		} | ||||
| 		vuprintf("Version signature is valid"); | ||||
| 
 | ||||
| 		status++; | ||||
| 		vuprintf("Successfully downloaded version file (%d bytes)\n", dwTotalSize); | ||||
| 
 | ||||
| 		parse_update(buf, dwTotalSize+1); | ||||
| 
 | ||||
| 		vuprintf("UPDATE DATA:\n"); | ||||
| 		vuprintf("  version: %d.%d.%d (%s)\n", update.version[0], update.version[1], update.version[2], channel[k]); | ||||
| 		vuprintf("  platform_min: %d.%d\n", update.platform_min[0], update.platform_min[1]); | ||||
| 		vuprintf("  url: %s\n", update.download_url); | ||||
| 		vuprintf("UPDATE DATA:"); | ||||
| 		vuprintf("  version: %d.%d.%d (%s)", update.version[0], update.version[1], update.version[2], channel[k]); | ||||
| 		vuprintf("  platform_min: %d.%d", update.platform_min[0], update.platform_min[1]); | ||||
| 		vuprintf("  url: %s", update.download_url); | ||||
| 
 | ||||
| 		found_new_version = ((to_uint64_t(update.version) > to_uint64_t(rufus_version)) || (force_update)) | ||||
| 			&& ( (os_version.dwMajorVersion > update.platform_min[0]) | ||||
| 			  || ( (os_version.dwMajorVersion == update.platform_min[0]) && (os_version.dwMinorVersion >= update.platform_min[1])) ); | ||||
| 		uprintf("N%sew %s version found%c\n", found_new_version?"":"o n", channel[k], found_new_version?'!':'.'); | ||||
| 		uprintf("N%sew %s version found%c", found_new_version?"":"o n", channel[k], found_new_version?'!':'.'); | ||||
| 	} | ||||
| 
 | ||||
| out: | ||||
| 	safe_free(buf); | ||||
| 	safe_free(sig); | ||||
| 	if (hRequest) | ||||
| 		pfInternetCloseHandle(hRequest); | ||||
| 	if (hConnection) | ||||
|  |  | |||
							
								
								
									
										146
									
								
								src/pki.c
									
										
									
									
									
								
							
							
						
						
									
										146
									
								
								src/pki.c
									
										
									
									
									
								
							|  | @ -27,6 +27,7 @@ | |||
| #include <stdio.h> | ||||
| #include <wincrypt.h> | ||||
| #include <wintrust.h> | ||||
| #include <assert.h> | ||||
| 
 | ||||
| #include "rufus.h" | ||||
| #include "resource.h" | ||||
|  | @ -52,6 +53,63 @@ typedef struct { | |||
| 	LPWSTR lpszMoreInfoLink; | ||||
| } SPROG_PUBLISHERINFO, *PSPROG_PUBLISHERINFO; | ||||
| 
 | ||||
| // https://msdn.microsoft.com/en-us/library/ee442238.aspx
 | ||||
| typedef struct { | ||||
| 	BLOBHEADER BlobHeader; | ||||
| 	RSAPUBKEY  RsaHeader; | ||||
| 	BYTE       Modulus[256];	// 2048 bit modulus
 | ||||
| } RSA_2048_PUBKEY; | ||||
| 
 | ||||
| // The RSA public key modulus for the private key we use to sign the files on the server.
 | ||||
| // NOTE 1: This openssl modulus must be *REVERSED* to be usable with Microsoft APIs
 | ||||
| // NOTE 2: Also, this modulus is 2052 bits, and not 2048, because openssl adds an extra
 | ||||
| // 0x00 at the beginning to force an integer sign. These extra 8 bits *MUST* be removed.
 | ||||
| static uint8_t rsa_pubkey_modulus[] = { | ||||
| 	/*
 | ||||
| 		$ openssl genrsa -aes256 -out private.pem 2048 | ||||
| 		$ openssl rsa -in private.pem -pubout -out public.pem | ||||
| 		$ openssl rsa -pubin -inform PEM -text -noout < public.pem | ||||
| 		Public-Key: (2048 bit) | ||||
| 		Modulus: | ||||
| 			00:b6:40:7d:d1:98:7b:81:9e:be:23:0f:32:5d:55: | ||||
| 			60:c6:bf:b4:41:bb:43:1b:f1:e1:e6:f9:2b:d6:dd: | ||||
| 			11:50:e8:b9:3f:19:97:5e:a7:8b:4a:30:c6:76:58: | ||||
| 			72:1c:ac:ff:a1:f8:96:6c:51:5d:13:11:e3:5b:11: | ||||
| 			82:f5:9a:69:e4:28:97:0f:ca:1f:02:ea:1f:7d:dc: | ||||
| 			f9:fc:79:2f:61:ff:8e:45:60:65:ba:37:9b:de:49: | ||||
| 			05:6a:a8:fd:70:d0:0c:79:b6:d7:81:aa:54:c3:c6: | ||||
| 			4a:87:a0:45:ee:ca:d5:d5:c5:c2:ac:86:42:b3:58: | ||||
| 			27:d2:43:b9:37:f2:e6:75:66:17:53:d0:38:d0:c6: | ||||
| 			57:c2:55:36:a2:43:87:ea:24:f0:96:ec:34:dd:79: | ||||
| 			4d:80:54:9d:84:81:a7:cf:0c:a5:7c:d6:63:fa:7a: | ||||
| 			66:30:a9:50:ee:f0:e5:f8:a2:2d:ac:fc:24:21:fe: | ||||
| 			ef:e8:d3:6f:0e:27:b0:64:22:95:3e:6d:a6:66:97: | ||||
| 			c6:98:c2:47:b3:98:69:4d:b1:b5:d3:6f:43:f5:d7: | ||||
| 			a5:13:5e:8c:28:4f:62:4e:01:48:0a:63:89:e7:ca: | ||||
| 			34:aa:7d:2f:bb:70:e0:31:bb:39:49:a3:d2:c9:2e: | ||||
| 			a6:30:54:9a:5c:4d:58:17:d9:fc:3a:43:e6:8e:2a: | ||||
| 			18:e9 | ||||
| 		Exponent: 65537 (0x10001) | ||||
| 	*/ | ||||
| 	0x00, 0xb6, 0x40, 0x7d, 0xd1, 0x98, 0x7b, 0x81, 0x9e, 0xbe, 0x23, 0x0f, 0x32, 0x5d, 0x55, | ||||
| 	0x60, 0xc6, 0xbf, 0xb4, 0x41, 0xbb, 0x43, 0x1b, 0xf1, 0xe1, 0xe6, 0xf9, 0x2b, 0xd6, 0xdd, | ||||
| 	0x11, 0x50, 0xe8, 0xb9, 0x3f, 0x19, 0x97, 0x5e, 0xa7, 0x8b, 0x4a, 0x30, 0xc6, 0x76, 0x58, | ||||
| 	0x72, 0x1c, 0xac, 0xff, 0xa1, 0xf8, 0x96, 0x6c, 0x51, 0x5d, 0x13, 0x11, 0xe3, 0x5b, 0x11, | ||||
| 	0x82, 0xf5, 0x9a, 0x69, 0xe4, 0x28, 0x97, 0x0f, 0xca, 0x1f, 0x02, 0xea, 0x1f, 0x7d, 0xdc, | ||||
| 	0xf9, 0xfc, 0x79, 0x2f, 0x61, 0xff, 0x8e, 0x45, 0x60, 0x65, 0xba, 0x37, 0x9b, 0xde, 0x49, | ||||
| 	0x05, 0x6a, 0xa8, 0xfd, 0x70, 0xd0, 0x0c, 0x79, 0xb6, 0xd7, 0x81, 0xaa, 0x54, 0xc3, 0xc6, | ||||
| 	0x4a, 0x87, 0xa0, 0x45, 0xee, 0xca, 0xd5, 0xd5, 0xc5, 0xc2, 0xac, 0x86, 0x42, 0xb3, 0x58, | ||||
| 	0x27, 0xd2, 0x43, 0xb9, 0x37, 0xf2, 0xe6, 0x75, 0x66, 0x17, 0x53, 0xd0, 0x38, 0xd0, 0xc6, | ||||
| 	0x57, 0xc2, 0x55, 0x36, 0xa2, 0x43, 0x87, 0xea, 0x24, 0xf0, 0x96, 0xec, 0x34, 0xdd, 0x79, | ||||
| 	0x4d, 0x80, 0x54, 0x9d, 0x84, 0x81, 0xa7, 0xcf, 0x0c, 0xa5, 0x7c, 0xd6, 0x63, 0xfa, 0x7a, | ||||
| 	0x66, 0x30, 0xa9, 0x50, 0xee, 0xf0, 0xe5, 0xf8, 0xa2, 0x2d, 0xac, 0xfc, 0x24, 0x21, 0xfe, | ||||
| 	0xef, 0xe8, 0xd3, 0x6f, 0x0e, 0x27, 0xb0, 0x64, 0x22, 0x95, 0x3e, 0x6d, 0xa6, 0x66, 0x97, | ||||
| 	0xc6, 0x98, 0xc2, 0x47, 0xb3, 0x98, 0x69, 0x4d, 0xb1, 0xb5, 0xd3, 0x6f, 0x43, 0xf5, 0xd7, | ||||
| 	0xa5, 0x13, 0x5e, 0x8c, 0x28, 0x4f, 0x62, 0x4e, 0x01, 0x48, 0x0a, 0x63, 0x89, 0xe7, 0xca, | ||||
| 	0x34, 0xaa, 0x7d, 0x2f, 0xbb, 0x70, 0xe0, 0x31, 0xbb, 0x39, 0x49, 0xa3, 0xd2, 0xc9, 0x2e, | ||||
| 	0xa6, 0x30, 0x54, 0x9a, 0x5c, 0x4d, 0x58, 0x17, 0xd9, 0xfc, 0x3a, 0x43, 0xe6, 0x8e, 0x2a, | ||||
| 	0x18, 0xe9 | ||||
| }; | ||||
| 
 | ||||
| /*
 | ||||
|  * FormatMessage does not handle PKI errors | ||||
|  | @ -65,8 +123,19 @@ const char* WinPKIErrorString(void) | |||
| 		return WindowsErrorString(); | ||||
| 
 | ||||
| 	switch (error_code) { | ||||
| 	// See also https://docs.microsoft.com/en-gb/windows/desktop/com/com-error-codes-4
 | ||||
| 	case NTE_BAD_UID: | ||||
| 		return "Bad UID."; | ||||
| 	case NTE_NO_KEY: | ||||
| 		return "Key does not exist."; | ||||
| 	case NTE_BAD_KEYSET: | ||||
| 		return "Keyset does not exist."; | ||||
| 	case NTE_BAD_ALGID: | ||||
| 		return "Invalid algorithm specified."; | ||||
| 	case NTE_BAD_VER: | ||||
| 		return "Bad version of provider."; | ||||
| 	case NTE_BAD_SIGNATURE: | ||||
| 		return "Invalid Signature."; | ||||
| 	case CRYPT_E_MSG_ERROR: | ||||
| 		return "An error occurred while performing an operation on a cryptographic message."; | ||||
| 	case CRYPT_E_UNKNOWN_ALGO: | ||||
|  | @ -581,3 +650,80 @@ LONG ValidateSignature(HWND hDlg, const char* path) | |||
| 
 | ||||
| 	return r; | ||||
| } | ||||
| 
 | ||||
| // Why-oh-why am I the only one on github doing this openssl vs MS signature validation?!?
 | ||||
| // For once, I'd like to find code samples from *OTHER PEOPLE* who went through this ordeal first...
 | ||||
| BOOL ValidateOpensslSignature(BYTE* pbBuffer, DWORD dwBufferLen, BYTE* pbSignature, DWORD dwSigLen) | ||||
| { | ||||
| 	HCRYPTPROV hProv = 0; | ||||
| 	HCRYPTHASH hHash = 0; | ||||
| 	HCRYPTKEY hPubKey; | ||||
| 	// We could load and convert an openssl PEM, but since we know what we need...
 | ||||
| 	RSA_2048_PUBKEY pbMyPubKey = { | ||||
| 		{ PUBLICKEYBLOB, CUR_BLOB_VERSION, 0, CALG_RSA_KEYX }, | ||||
| 		// $ openssl genrsa -aes256 -out private.pem 2048
 | ||||
| 		// Generating RSA private key, 2048 bit long modulus
 | ||||
| 		// e is 65537 (0x010001)
 | ||||
| 		// => 0x010001 below. Also 0x31415352 = "RSA1"
 | ||||
| 		{ 0x31415352, sizeof(pbMyPubKey.Modulus) * 8, 0x010001 }, | ||||
| 		{ 0 }	// Modulus is initialized below
 | ||||
| 	}; | ||||
| 	USHORT dwMyPubKeyLen = sizeof(pbMyPubKey); | ||||
| 	BOOL r; | ||||
| 	BYTE t; | ||||
| 	int i, j; | ||||
| 
 | ||||
| 	// Get a handle to the default PROV_RSA_AES provider (AES so we get SHA-256 support).
 | ||||
| 	// 2 passes in case we need to create a new container.
 | ||||
| 	r = CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_AES, CRYPT_NEWKEYSET | CRYPT_VERIFYCONTEXT); | ||||
| 	if (!r) { | ||||
| 		uprintf("PKI: Could not create the default key container: %s", WinPKIErrorString()); | ||||
| 		goto out; | ||||
| 	} | ||||
| 
 | ||||
| 	// Reverse the modulus bytes from openssl (and also remove the extra unwanted 0x00)
 | ||||
| 	assert(sizeof(rsa_pubkey_modulus) >= sizeof(pbMyPubKey.Modulus)); | ||||
| 	for (i = 0; i < sizeof(pbMyPubKey.Modulus); i++) | ||||
| 		pbMyPubKey.Modulus[i] = rsa_pubkey_modulus[sizeof(rsa_pubkey_modulus) -1 - i]; | ||||
| 
 | ||||
| 	// Import our RSA public key so that the MS API can use it
 | ||||
| 	r = CryptImportKey(hProv, (BYTE*)&pbMyPubKey.BlobHeader, dwMyPubKeyLen, 0, 0, &hPubKey); | ||||
| 	if (!r) { | ||||
| 		uprintf("Could not import public key: %s", WinPKIErrorString()); | ||||
| 		goto out; | ||||
| 	} | ||||
| 
 | ||||
| 	// Create the hash object.
 | ||||
| 	r = CryptCreateHash(hProv, CALG_SHA_256, 0, 0, &hHash); | ||||
| 	if (!r) { | ||||
| 		uprintf("Could not create empty hash: %s", WinPKIErrorString()); | ||||
| 		goto out; | ||||
| 	} | ||||
| 
 | ||||
| 	// Compute the cryptographic hash of the buffer.
 | ||||
| 	r = CryptHashData(hHash, pbBuffer, dwBufferLen, 0); | ||||
| 	if (!r) { | ||||
| 		uprintf("Could not hash data: %s", WinPKIErrorString()); | ||||
| 		goto out; | ||||
| 	} | ||||
| 
 | ||||
| 	// Reverse the signature bytes
 | ||||
| 	for (i = 0, j = dwSigLen - 1; i < j; i++, j--) { | ||||
| 		t = pbSignature[i]; | ||||
| 		pbSignature[i] = pbSignature[j]; | ||||
| 		pbSignature[j] = t; | ||||
| 	} | ||||
| 
 | ||||
| 	// Now that we have all of the public key, hash and signature data in a
 | ||||
| 	// format that Microsoft can handle, we can call CryptVerifySignature().
 | ||||
| 	r = CryptVerifySignature(hHash, pbSignature, dwSigLen, hPubKey, NULL, 0); | ||||
| 	if (!r) | ||||
| 		uprintf("Signature validation failed: %s", WinPKIErrorString()); | ||||
| 
 | ||||
| out: | ||||
| 	if (hHash) | ||||
| 		CryptDestroyHash(hHash); | ||||
| 	if (hProv) | ||||
| 		CryptReleaseContext(hProv, 0); | ||||
| 	return r; | ||||
| } | ||||
|  |  | |||
							
								
								
									
										309
									
								
								src/rufus.c
									
										
									
									
									
								
							
							
						
						
									
										309
									
								
								src/rufus.c
									
										
									
									
									
								
							|  | @ -35,6 +35,7 @@ | |||
| #include <dbt.h> | ||||
| #include <io.h> | ||||
| #include <getopt.h> | ||||
| #include <assert.h> | ||||
| 
 | ||||
| #include "rufus.h" | ||||
| #include "missing.h" | ||||
|  | @ -51,6 +52,7 @@ | |||
| 
 | ||||
| static const char* cmdline_hogger = "rufus.com"; | ||||
| static const char* FileSystemLabel[FS_MAX] = { "FAT", "FAT32", "NTFS", "UDF", "exFAT", "ReFS" }; | ||||
| static const char* flash_type[BADLOCKS_PATTERN_TYPES] = { "SLC", "MLC", "TLC" }; | ||||
| static const char* ep_reg = "Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer"; | ||||
| static const char* vs_reg = "Software\\Microsoft\\VisualStudio"; | ||||
| // Number of steps for each FS for FCC_STRUCTURE_PROGRESS
 | ||||
|  | @ -1165,9 +1167,12 @@ static __inline void MoveCtrlY(HWND hDlg, int nID, int vertical_shift) { | |||
| 
 | ||||
| static void SetPassesTooltip(void) | ||||
| { | ||||
| 	const unsigned char pattern[] = BADBLOCK_PATTERNS; | ||||
| 	CreateTooltip(hNBPasses, lmprintf(MSG_153 + ComboBox_GetCurSel(hNBPasses), | ||||
| 		pattern[0], pattern[1], pattern[2], pattern[3]), -1); | ||||
| 	const unsigned int pattern[BADLOCKS_PATTERN_TYPES][BADBLOCK_PATTERN_COUNT] = | ||||
| 		{ BADBLOCK_PATTERN_SLC, BADCLOCK_PATTERN_MLC, BADBLOCK_PATTERN_TLC }; | ||||
| 	int sel = ComboBox_GetCurSel(hNBPasses); | ||||
| 	int type = (sel < 2) ? 0 : sel - 2; | ||||
| 	CreateTooltip(hNBPasses, lmprintf(MSG_153 + ((sel >= 2) ? 3 : sel), | ||||
| 		pattern[type][0], pattern[type][1], pattern[type][2], pattern[type][3]), -1); | ||||
| } | ||||
| 
 | ||||
| static void ResizeDialogs(int shift) | ||||
|  | @ -1341,14 +1346,13 @@ static void UpdateImage(void) | |||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	if (image_path != NULL) { | ||||
| 		ComboBox_DeleteString(hBootType, index); | ||||
| 		ComboBox_InsertStringU(hBootType, index, short_image_path); | ||||
| 		ComboBox_SetItemData(hBootType, index, BT_IMAGE); | ||||
| 		IGNORE_RETVAL(ComboBox_SetCurSel(hBootType, index)); | ||||
| 		bt = (int)ComboBox_GetItemData(hBootType, ComboBox_GetCurSel(hBootType)); | ||||
| 		SetBootTypeDropdownWidth(); | ||||
| 	} | ||||
| 	ComboBox_DeleteString(hBootType, index); | ||||
| 	ComboBox_InsertStringU(hBootType, index,  | ||||
| 		(image_path == NULL) ? lmprintf(MSG_281, lmprintf(MSG_280)) : short_image_path); | ||||
| 	ComboBox_SetItemData(hBootType, index, BT_IMAGE); | ||||
| 	IGNORE_RETVAL(ComboBox_SetCurSel(hBootType, index)); | ||||
| 	bt = (int)ComboBox_GetItemData(hBootType, ComboBox_GetCurSel(hBootType)); | ||||
| 	SetBootTypeDropdownWidth(); | ||||
| } | ||||
| 
 | ||||
| // The scanning process can be blocking for message processing => use a thread
 | ||||
|  | @ -1358,6 +1362,7 @@ DWORD WINAPI ISOScanThread(LPVOID param) | |||
| 
 | ||||
| 	if (image_path == NULL) | ||||
| 		goto out; | ||||
| 	format_op_in_progress = TRUE; | ||||
| 	PrintInfoDebug(0, MSG_202); | ||||
| 	user_notified = FALSE; | ||||
| 	EnableControls(FALSE); | ||||
|  | @ -1365,15 +1370,16 @@ DWORD WINAPI ISOScanThread(LPVOID param) | |||
| 	img_report.is_iso = (BOOLEAN)ExtractISO(image_path, "", TRUE); | ||||
| 	img_report.is_bootable_img = (BOOLEAN)IsBootableImage(image_path); | ||||
| 
 | ||||
| 	if ((img_report.image_size == 0) || (!img_report.is_iso && !img_report.is_bootable_img)) { | ||||
| 	if (IS_ERROR(FormatStatus) || (img_report.image_size == 0) || (!img_report.is_iso && !img_report.is_bootable_img)) { | ||||
| 		// Failed to scan image
 | ||||
| 		SendMessage(hMainDialog, UM_PROGRESS_EXIT, 0, 0); | ||||
| 		safe_free(image_path); | ||||
| 		EnableControls(TRUE); | ||||
| 		UpdateImage(); | ||||
| 		SetMBRProps(); | ||||
| 		PopulateProperties(); | ||||
| 		PrintInfoDebug(0, MSG_203); | ||||
| 		PrintStatus(0, MSG_203); | ||||
| 		EnableControls(TRUE); | ||||
| 		goto out; | ||||
| 	} | ||||
| 
 | ||||
|  | @ -1435,15 +1441,18 @@ DWORD WINAPI ISOScanThread(LPVOID param) | |||
| 
 | ||||
| out: | ||||
| 	dont_display_image_name = FALSE; | ||||
| 	format_op_in_progress = FALSE; | ||||
| 	PrintInfo(0, MSG_210); | ||||
| 	ExitThread(0); | ||||
| } | ||||
| 
 | ||||
| static BOOL BootCheck(void) | ||||
| // Likewise, boot check will block message processing => use a thread
 | ||||
| static DWORD WINAPI BootCheckThread(LPVOID param) | ||||
| { | ||||
| 	int i, r; | ||||
| 	FILE *fd; | ||||
| 	DWORD len; | ||||
| 	WPARAM ret = -1; | ||||
| 	BOOL in_files_dir = FALSE; | ||||
| 	const char* grub = "grub"; | ||||
| 	const char* core_img = "core.img"; | ||||
|  | @ -1454,34 +1463,42 @@ static BOOL BootCheck(void) | |||
| 
 | ||||
| 	syslinux_ldlinux_len[0] = 0; syslinux_ldlinux_len[1] = 0; | ||||
| 	safe_free(grub2_buf); | ||||
| 
 | ||||
| 	if (ComboBox_GetCurSel(hDeviceList) == CB_ERR) | ||||
| 		goto out; | ||||
| 
 | ||||
| 	if ((zero_drive) || (bt == BT_NON_BOOTABLE)) { | ||||
| 		// Nothing to check
 | ||||
| 		ret = 0; | ||||
| 		goto out; | ||||
| 	} | ||||
| 
 | ||||
| 	if (bt == BT_IMAGE) { | ||||
| 		// We should never be there
 | ||||
| 		if (image_path == NULL) { | ||||
| 			uprintf("Spock gone crazy error in %s:%d", __FILE__, __LINE__); | ||||
| 			MessageBoxExU(hMainDialog, "image_path is NULL. Please report this error to the author of this application", "Logic error", MB_OK|MB_ICONERROR|MB_IS_RTL, selected_langid); | ||||
| 			return FALSE; | ||||
| 		} | ||||
| 		assert(image_path != NULL); | ||||
| 		if (image_path == NULL) | ||||
| 			goto out; | ||||
| 		if ((size_check) && (img_report.projected_size > (uint64_t)SelectedDrive.DiskSize)) { | ||||
| 			// This ISO image is too big for the selected target
 | ||||
| 			MessageBoxExU(hMainDialog, lmprintf(MSG_089), lmprintf(MSG_088), MB_OK|MB_ICONERROR|MB_IS_RTL, selected_langid); | ||||
| 			return FALSE; | ||||
| 			goto out; | ||||
| 		} | ||||
| 		if (IS_DD_BOOTABLE(img_report) && !img_report.is_iso) { | ||||
| 			// Pure DD images are fine at this stage
 | ||||
| 			return TRUE; | ||||
| 			ret = 0; | ||||
| 			goto out; | ||||
| 		} | ||||
| 		if ((display_togo_option) && (ComboBox_GetCurSel(GetDlgItem(hMainDialog, IDC_IMAGE_OPTION)) == 1)) { | ||||
| 			if (fs != FS_NTFS) { | ||||
| 				// Windows To Go only works for NTFS
 | ||||
| 				MessageBoxExU(hMainDialog, lmprintf(MSG_097, "Windows To Go"), lmprintf(MSG_092), MB_OK|MB_ICONERROR|MB_IS_RTL, selected_langid); | ||||
| 				return FALSE; | ||||
| 				goto out; | ||||
| 			} | ||||
| 			if (SelectedDrive.MediaType != FixedMedia) { | ||||
| 				if ((tt == TT_UEFI) && (pt == PARTITION_STYLE_GPT) && (nWindowsBuildNumber < 15000)) { | ||||
| 					// Up to Windows 10 Creators Update, we were screwed, since we need access to 2 partitions at the same time.
 | ||||
| 					// Thankfully, the newer Windows allow mounting multiple partitions on the same REMOVABLE drive.
 | ||||
| 					MessageBoxExU(hMainDialog, lmprintf(MSG_198), lmprintf(MSG_190), MB_OK|MB_ICONERROR|MB_IS_RTL, selected_langid); | ||||
| 					return FALSE; | ||||
| 					goto out; | ||||
| 				} | ||||
| 			} | ||||
| 			// If multiple versions are available, asks the user to select one before we commit to format the drive
 | ||||
|  | @ -1490,7 +1507,7 @@ static BOOL BootCheck(void) | |||
| 				MessageBoxExU(hMainDialog, lmprintf(MSG_073), lmprintf(MSG_291), MB_OK | MB_ICONERROR | MB_IS_RTL, selected_langid); | ||||
| 				// fall through
 | ||||
| 			case -2: | ||||
| 				return FALSE; | ||||
| 				goto out; | ||||
| 			default: | ||||
| 				break; | ||||
| 			} | ||||
|  | @ -1498,13 +1515,13 @@ static BOOL BootCheck(void) | |||
| 			if (!IS_EFI_BOOTABLE(img_report)) { | ||||
| 				// Unsupported ISO
 | ||||
| 				MessageBoxExU(hMainDialog, lmprintf(MSG_091), lmprintf(MSG_090), MB_OK|MB_ICONERROR|MB_IS_RTL, selected_langid); | ||||
| 				return FALSE; | ||||
| 				goto out; | ||||
| 			} | ||||
| 			if (HAS_WIN7_EFI(img_report) && (!WimExtractCheck())) { | ||||
| 				// Your platform cannot extract files from WIM archives => download 7-zip?
 | ||||
| 				if (MessageBoxExU(hMainDialog, lmprintf(MSG_102), lmprintf(MSG_101), MB_YESNO|MB_ICONERROR|MB_IS_RTL, selected_langid) == IDYES) | ||||
| 					ShellExecuteA(hMainDialog, "open", SEVENZIP_URL, NULL, NULL, SW_SHOWNORMAL); | ||||
| 				return FALSE; | ||||
| 				goto out; | ||||
| 			} | ||||
| 		} else if ( ((fs == FS_NTFS) && !HAS_WINDOWS(img_report) && !HAS_GRUB(img_report) &&  | ||||
| 					 (!HAS_SYSLINUX(img_report) || (SL_MAJOR(img_report.sl_version) <= 5))) | ||||
|  | @ -1513,16 +1530,16 @@ static BOOL BootCheck(void) | |||
| 				 || ((IS_FAT(fs)) && (HAS_WINDOWS(img_report) || HAS_INSTALL_WIM(img_report)) && (!allow_dual_uefi_bios)) ) { | ||||
| 			// Incompatible FS and ISO
 | ||||
| 			MessageBoxExU(hMainDialog, lmprintf(MSG_096), lmprintf(MSG_092), MB_OK|MB_ICONERROR|MB_IS_RTL, selected_langid); | ||||
| 			return FALSE; | ||||
| 			goto out; | ||||
| 		} else if ((fs == FS_FAT16) && HAS_KOLIBRIOS(img_report)) { | ||||
| 			// KolibriOS doesn't support FAT16
 | ||||
| 			MessageBoxExU(hMainDialog, lmprintf(MSG_189), lmprintf(MSG_099), MB_OK|MB_ICONERROR|MB_IS_RTL, selected_langid); | ||||
| 			return FALSE; | ||||
| 			goto out; | ||||
| 		} | ||||
| 		if ((IS_FAT(fs)) && (img_report.has_4GB_file)) { | ||||
| 			// This ISO image contains a file larger than 4GB file (FAT32)
 | ||||
| 			MessageBoxExU(hMainDialog, lmprintf(MSG_100), lmprintf(MSG_099), MB_OK|MB_ICONERROR|MB_IS_RTL, selected_langid); | ||||
| 			return FALSE; | ||||
| 			goto out; | ||||
| 		} | ||||
| 
 | ||||
| 		// If the selected target doesn't include include BIOS, skip file downloads for GRUB/Syslinux
 | ||||
|  | @ -1557,15 +1574,13 @@ static BOOL BootCheck(void) | |||
| 				r = MessageBoxExU(hMainDialog, lmprintf(MSG_116, img_report.grub2_version, GRUB2_PACKAGE_VERSION), | ||||
| 					lmprintf(MSG_115), MB_YESNOCANCEL|MB_ICONWARNING|MB_IS_RTL, selected_langid); | ||||
| 				if (r == IDCANCEL) | ||||
| 					return FALSE; | ||||
| 					goto out; | ||||
| 				else if (r == IDYES) { | ||||
| 					static_sprintf(tmp, "%s-%s", grub, img_report.grub2_version); | ||||
| 					IGNORE_RETVAL(_mkdir(tmp)); | ||||
| 					IGNORE_RETVAL(_chdir(tmp)); | ||||
| 					static_sprintf(tmp, "%s/%s-%s/%s", FILES_URL, grub, img_report.grub2_version, core_img); | ||||
| 					PromptOnError = FALSE; | ||||
| 					grub2_len = (long)DownloadFile(tmp, core_img, hMainDialog); | ||||
| 					PromptOnError = TRUE; | ||||
| 					grub2_len = (long)DownloadSignedFile(tmp, core_img, hMainDialog, FALSE); | ||||
| 					if ((grub2_len == 0) && (DownloadStatus == 404)) { | ||||
| 						// Couldn't locate the file on the server => try to download without the version extra
 | ||||
| 						uprintf("Extended version was not found, trying main version..."); | ||||
|  | @ -1574,9 +1589,7 @@ static BOOL BootCheck(void) | |||
| 						for (i = 0; ((tmp2[i] >= '0') && (tmp2[i] <= '9')) || (tmp2[i] == '.'); i++); | ||||
| 						tmp2[i] = 0; | ||||
| 						static_sprintf(tmp, "%s/%s-%s/%s", FILES_URL, grub, tmp2, core_img); | ||||
| 						PromptOnError = FALSE; | ||||
| 						grub2_len = (long)DownloadFile(tmp, core_img, hMainDialog); | ||||
| 						PromptOnError = TRUE; | ||||
| 						grub2_len = (long)DownloadSignedFile(tmp, core_img, hMainDialog, FALSE); | ||||
| 						static_sprintf(tmp, "%s/%s-%s/%s", FILES_URL, grub, img_report.grub2_version, core_img); | ||||
| 					} | ||||
| 					if (grub2_len <= 0) { | ||||
|  | @ -1621,10 +1634,10 @@ static BOOL BootCheck(void) | |||
| 								static_sprintf(tmp, "%s-%s", syslinux, embedded_sl_version_str[0]); | ||||
| 								IGNORE_RETVAL(_mkdir(tmp)); | ||||
| 								static_sprintf(tmp, "%s/%s-%s/%s", FILES_URL, syslinux, embedded_sl_version_str[0], old_c32_name[i]); | ||||
| 								len = DownloadFile(tmp, &tmp[sizeof(FILES_URL)], hMainDialog); | ||||
| 								len = DownloadSignedFile(tmp, &tmp[sizeof(FILES_URL)], hMainDialog, TRUE); | ||||
| 								if (len == 0) { | ||||
| 									uprintf("Could not download file - cancelling"); | ||||
| 									return FALSE; | ||||
| 									goto out; | ||||
| 								} | ||||
| 								use_own_c32[i] = TRUE; | ||||
| 							} | ||||
|  | @ -1657,7 +1670,7 @@ static BOOL BootCheck(void) | |||
| 						embedded_sl_version_str[1], embedded_sl_version_ext[1]), | ||||
| 						lmprintf(MSG_115), MB_YESNO|MB_ICONWARNING|MB_IS_RTL, selected_langid); | ||||
| 					if (r != IDYES) | ||||
| 						return FALSE; | ||||
| 						goto out; | ||||
| 					for (i=0; i<2; i++) { | ||||
| 						static_sprintf(tmp, "%s-%s", syslinux, img_report.sl_version_str); | ||||
| 						IGNORE_RETVAL(_mkdir(tmp)); | ||||
|  | @ -1668,15 +1681,15 @@ static BOOL BootCheck(void) | |||
| 						} | ||||
| 						static_sprintf(tmp, "%s/%s-%s%s/%s.%s", FILES_URL, syslinux, img_report.sl_version_str, | ||||
| 							img_report.sl_version_ext, ldlinux, ldlinux_ext[i]); | ||||
| 						PromptOnError = (*img_report.sl_version_ext == 0); | ||||
| 						syslinux_ldlinux_len[i] = DownloadFile(tmp, &tmp[sizeof(FILES_URL)], hMainDialog); | ||||
| 						PromptOnError = TRUE; | ||||
| 						syslinux_ldlinux_len[i] = DownloadSignedFile(tmp, &tmp[sizeof(FILES_URL)], | ||||
| 							hMainDialog, (*img_report.sl_version_ext == 0)); | ||||
| 						if ((syslinux_ldlinux_len[i] == 0) && (DownloadStatus == 404) && (*img_report.sl_version_ext != 0)) { | ||||
| 							// Couldn't locate the file on the server => try to download without the version extra
 | ||||
| 							uprintf("Extended version was not found, trying main version..."); | ||||
| 							static_sprintf(tmp, "%s/%s-%s/%s.%s", FILES_URL, syslinux, img_report.sl_version_str, | ||||
| 								ldlinux, ldlinux_ext[i]); | ||||
| 							syslinux_ldlinux_len[i] = DownloadFile(tmp, &tmp[sizeof(FILES_URL)], hMainDialog); | ||||
| 							syslinux_ldlinux_len[i] = DownloadSignedFile(tmp, &tmp[sizeof(FILES_URL)], | ||||
| 								hMainDialog, (*img_report.sl_version_ext == 0)); | ||||
| 							if (syslinux_ldlinux_len[i] != 0) { | ||||
| 								// Duplicate the file so that the user won't be prompted to download again
 | ||||
| 								static_sprintf(tmp, "%s-%s\\%s.%s", syslinux, img_report.sl_version_str, ldlinux, ldlinux_ext[i]); | ||||
|  | @ -1691,7 +1704,7 @@ static BOOL BootCheck(void) | |||
| 								uprintf("Could not download the file - will try to use embedded %s version instead", img_report.sl_version_str); | ||||
| 							} else { | ||||
| 								uprintf("Could not download the file - cancelling"); | ||||
| 								return FALSE; | ||||
| 								goto out; | ||||
| 							} | ||||
| 						} | ||||
| 					} | ||||
|  | @ -1714,20 +1727,20 @@ static BOOL BootCheck(void) | |||
| 			r = MessageBoxExU(hMainDialog, lmprintf(MSG_104, "Syslinux v5.0", tmp, "Syslinux v5+", tmp), | ||||
| 				lmprintf(MSG_103, tmp), MB_YESNOCANCEL|MB_ICONWARNING|MB_IS_RTL, selected_langid); | ||||
| 			if (r == IDCANCEL) | ||||
| 				return FALSE; | ||||
| 				goto out; | ||||
| 			if (r == IDYES) { | ||||
| 				static_sprintf(tmp, "%s-%s", syslinux, embedded_sl_version_str[1]); | ||||
| 				IGNORE_RETVAL(_mkdir(tmp)); | ||||
| 				static_sprintf(tmp, "%s/%s-%s/%s.%s", FILES_URL, syslinux, embedded_sl_version_str[1], ldlinux, ldlinux_ext[2]); | ||||
| 				if (DownloadFile(tmp, &tmp[sizeof(FILES_URL)], hMainDialog) == 0) | ||||
| 					return FALSE; | ||||
| 				if (DownloadSignedFile(tmp, &tmp[sizeof(FILES_URL)], hMainDialog, TRUE) == 0) | ||||
| 					goto out; | ||||
| 			} | ||||
| 		} | ||||
| 	} else if (bt == BT_MSDOS) { | ||||
| 		if ((size_check) && (ComboBox_GetItemData(hClusterSize, ComboBox_GetCurSel(hClusterSize)) >= 65536)) { | ||||
| 			// MS-DOS cannot boot from a drive using a 64 kilobytes Cluster size
 | ||||
| 			MessageBoxExU(hMainDialog, lmprintf(MSG_110), lmprintf(MSG_111), MB_OK|MB_ICONERROR|MB_IS_RTL, selected_langid); | ||||
| 			return FALSE; | ||||
| 			goto out; | ||||
| 		} | ||||
| 	} else if (bt == BT_GRUB4DOS) { | ||||
| 		IGNORE_RETVAL(_chdirU(app_dir)); | ||||
|  | @ -1744,13 +1757,13 @@ static BOOL BootCheck(void) | |||
| 			r = MessageBoxExU(hMainDialog, lmprintf(MSG_104, "Grub4DOS 0.4", tmp, "Grub4DOS", tmp), | ||||
| 				lmprintf(MSG_103, tmp), MB_YESNOCANCEL|MB_ICONWARNING|MB_IS_RTL, selected_langid); | ||||
| 			if (r == IDCANCEL) | ||||
| 				return FALSE; | ||||
| 				goto out; | ||||
| 			if (r == IDYES) { | ||||
| 				static_sprintf(tmp, "grub4dos-%s", GRUB4DOS_VERSION); | ||||
| 				IGNORE_RETVAL(_mkdir(tmp)); | ||||
| 				static_sprintf(tmp, "%s/grub4dos-%s/grldr", FILES_URL, GRUB4DOS_VERSION); | ||||
| 				if (DownloadFile(tmp, &tmp[sizeof(FILES_URL)], hMainDialog) == 0) | ||||
| 					return FALSE; | ||||
| 				if (DownloadSignedFile(tmp, &tmp[sizeof(FILES_URL)], hMainDialog, TRUE) == 0) | ||||
| 					goto out; | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
|  | @ -1760,10 +1773,14 @@ uefi_target: | |||
| 		fs = (int)ComboBox_GetItemData(hFileSystem, ComboBox_GetCurSel(hFileSystem)); | ||||
| 		if (fs != FS_NTFS) { | ||||
| 			MessageBoxExU(hMainDialog, lmprintf(MSG_097, "UEFI:NTFS"), lmprintf(MSG_092), MB_OK|MB_ICONERROR|MB_IS_RTL, selected_langid); | ||||
| 			return FALSE; | ||||
| 			goto out; | ||||
| 		} | ||||
| 	} | ||||
| 	return TRUE; | ||||
| 	ret = 0; | ||||
| 
 | ||||
| out: | ||||
| 	PostMessage(hMainDialog, UM_FORMAT_START, ret, 0); | ||||
| 	ExitThread((DWORD)ret); | ||||
| } | ||||
| 
 | ||||
| static __inline const char* IsAlphaOrBeta(void) | ||||
|  | @ -2197,9 +2214,10 @@ static void GetHalfDropwdownWidth(HWND hDlg) | |||
| 		hw = max(hw, GetTextSize(GetDlgItem(hDlg, IDC_TARGET_SYSTEM), lmprintf(msg_id)).cx); | ||||
| 
 | ||||
| 	// Just in case, we also do the number of passes
 | ||||
| 	for (i = 1; i <= 4; i++) | ||||
| 		hw = max(hw, GetTextSize(GetDlgItem(hDlg, IDC_TARGET_SYSTEM), | ||||
| 			lmprintf((i == 1) ? MSG_034 : MSG_035, i)).cx); | ||||
| 	for (i = 1; i <= 5; i++) { | ||||
| 		char* msg = (i == 1) ? lmprintf(MSG_034, 1) : lmprintf(MSG_035, (i == 2) ? 2 : 4, (i == 2) ? "" : lmprintf(MSG_087, flash_type[i - 3])); | ||||
| 		hw = max(hw, GetTextSize(GetDlgItem(hDlg, IDC_TARGET_SYSTEM), msg).cx); | ||||
| 	} | ||||
| 
 | ||||
| 	// Finally, we must ensure that we'll have enough space for the 2 checkbox controls
 | ||||
| 	// that end up with a half dropdown
 | ||||
|  | @ -2529,7 +2547,7 @@ static void InitDialog(HWND hDlg) | |||
| 	DWORD len; | ||||
| 	HDC hDC; | ||||
| 	int i, lfHeight; | ||||
| 	char tmp[128], *token, *buf, *ext; | ||||
| 	char tmp[128], *token, *buf, *ext, *msg; | ||||
| 	static char* resource[2] = { MAKEINTRESOURCEA(IDR_SL_LDLINUX_V4_SYS), MAKEINTRESOURCEA(IDR_SL_LDLINUX_V6_SYS) }; | ||||
| 
 | ||||
| #ifdef RUFUS_TEST | ||||
|  | @ -2635,8 +2653,9 @@ static void InitDialog(HWND hDlg) | |||
| 	SendMessage(hProgress, PBM_SETRANGE, 0, (MAX_PROGRESS<<16) & 0xFFFF0000); | ||||
| 
 | ||||
| 	// Fill up the passes
 | ||||
| 	for (i=0; i<4; i++) { | ||||
| 		IGNORE_RETVAL(ComboBox_AddStringU(hNBPasses, lmprintf((i==0)?MSG_034:MSG_035, i+1))); | ||||
| 	for (i = 1; i <= 5; i++) { | ||||
| 		msg = (i == 1) ? lmprintf(MSG_034, 1) : lmprintf(MSG_035, (i == 2) ? 2 : 4, (i == 2) ? "" : lmprintf(MSG_087, flash_type[i - 3])); | ||||
| 		IGNORE_RETVAL(ComboBox_AddStringU(hNBPasses, msg)); | ||||
| 	} | ||||
| 	IGNORE_RETVAL(ComboBox_SetCurSel(hNBPasses, 0)); | ||||
| 	SetPassesTooltip(); | ||||
|  | @ -2973,7 +2992,7 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA | |||
| 	case WM_COMMAND: | ||||
| #ifdef RUFUS_TEST | ||||
| 		if (LOWORD(wParam) == IDC_TEST) { | ||||
| 			Notification(MSG_ERROR, NULL, lmprintf(MSG_042), lmprintf(MSG_043, lmprintf(MSG_055))); | ||||
| 			DownloadSignedFile(FILES_URL "/gendb.sh", "C:\\Downloads\\gendb.sh", hProgress); | ||||
| 			break; | ||||
| 		} | ||||
| #endif | ||||
|  | @ -3020,6 +3039,7 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA | |||
| 				// User might be trying to cancel during preliminary checks
 | ||||
| 				FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_CANCELLED; | ||||
| 				PrintInfo(0, MSG_201); | ||||
| 				EnableWindow(GetDlgItem(hDlg, IDCANCEL), TRUE); | ||||
| 				return (INT_PTR)TRUE; | ||||
| 			} | ||||
| 			if (ulRegister != 0) | ||||
|  | @ -3217,6 +3237,7 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA | |||
| 				} | ||||
| 			} | ||||
| 			FormatStatus = 0; | ||||
| 			format_op_in_progress = FALSE; | ||||
| 			if (CreateThread(NULL, 0, ISOScanThread, NULL, 0, NULL) == NULL) { | ||||
| 				uprintf("Unable to start ISO scanning thread"); | ||||
| 				FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR(ERROR_CANT_START_THREAD); | ||||
|  | @ -3254,86 +3275,13 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA | |||
| 			SetTaskbarProgressValue(0, MAX_PROGRESS); | ||||
| 			SendMessage(hProgress, PBM_SETPOS, 0, 0); | ||||
| 			selection_default = (int)ComboBox_GetItemData(hBootType, ComboBox_GetCurSel(hBootType)); | ||||
| 			nDeviceIndex = ComboBox_GetCurSel(hDeviceList); | ||||
| 			if (nDeviceIndex != CB_ERR) { | ||||
| 				if (!zero_drive) { | ||||
| 					if ((bt != BT_NON_BOOTABLE) && (!BootCheck())) | ||||
| 						goto aborted_start; | ||||
| 
 | ||||
| 					// Display a warning about UDF formatting times
 | ||||
| 					if (fs == FS_UDF) { | ||||
| 						dur_secs = (uint32_t)(((double)SelectedDrive.DiskSize) / 1073741824.0f / UDF_FORMAT_SPEED); | ||||
| 						if (dur_secs > UDF_FORMAT_WARN) { | ||||
| 							dur_mins = dur_secs / 60; | ||||
| 							dur_secs -= dur_mins * 60; | ||||
| 							MessageBoxExU(hMainDialog, lmprintf(MSG_112, dur_mins, dur_secs), lmprintf(MSG_113), | ||||
| 								MB_OK | MB_ICONASTERISK | MB_IS_RTL, selected_langid); | ||||
| 						} else { | ||||
| 							dur_secs = 0; | ||||
| 							dur_mins = 0; | ||||
| 						} | ||||
| 					} | ||||
| 
 | ||||
| 					if ((bt == BT_IMAGE) && IS_DD_BOOTABLE(img_report)) { | ||||
| 						if (img_report.is_iso) { | ||||
| 							// Ask users how they want to write ISOHybrid images
 | ||||
| 							char* iso_image = lmprintf(MSG_036); | ||||
| 							char* dd_image = lmprintf(MSG_095); | ||||
| 							char* choices[2] = { lmprintf(MSG_276, iso_image), lmprintf(MSG_277, dd_image) }; | ||||
| 							i = SelectionDialog(lmprintf(MSG_274), lmprintf(MSG_275, iso_image, dd_image, iso_image, dd_image), | ||||
| 								choices, 2); | ||||
| 							if (i < 0)	// Cancel
 | ||||
| 								goto aborted_start; | ||||
| 							else if (i == 2) | ||||
| 								write_as_image = TRUE; | ||||
| 						} else { | ||||
| 							write_as_image = TRUE; | ||||
| 						} | ||||
| 					} | ||||
| 				} | ||||
| 
 | ||||
| 				if (!CheckDriveAccess(2000)) | ||||
| 					goto aborted_start; | ||||
| 
 | ||||
| 				GetWindowTextU(hDeviceList, tmp, ARRAYSIZE(tmp)); | ||||
| 				if (MessageBoxExU(hMainDialog, lmprintf(MSG_003, tmp), | ||||
| 					APPLICATION_NAME, MB_OKCANCEL|MB_ICONWARNING|MB_IS_RTL, selected_langid) == IDCANCEL)  | ||||
| 					goto aborted_start; | ||||
| 				if ((SelectedDrive.nPartitions > 1) && (MessageBoxExU(hMainDialog, lmprintf(MSG_093), | ||||
| 					lmprintf(MSG_094), MB_OKCANCEL|MB_ICONWARNING|MB_IS_RTL, selected_langid) == IDCANCEL)) | ||||
| 					goto aborted_start; | ||||
| 				if ((!zero_drive) && (bt != BT_NON_BOOTABLE) && (SelectedDrive.SectorSize != 512) && | ||||
| 					(MessageBoxExU(hMainDialog, lmprintf(MSG_196, SelectedDrive.SectorSize), | ||||
| 						lmprintf(MSG_197), MB_OKCANCEL|MB_ICONWARNING|MB_IS_RTL, selected_langid) == IDCANCEL)) | ||||
| 					goto aborted_start; | ||||
| 
 | ||||
| 				DeviceNum = (DWORD)ComboBox_GetItemData(hDeviceList, nDeviceIndex); | ||||
| 				InitProgress(zero_drive || write_as_image); | ||||
| 				format_thid = CreateThread(NULL, 0, FormatThread, (LPVOID)(uintptr_t)DeviceNum, 0, NULL); | ||||
| 				if (format_thid == NULL) { | ||||
| 					uprintf("Unable to start formatting thread"); | ||||
| 					FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR(ERROR_CANT_START_THREAD); | ||||
| 					PostMessage(hMainDialog, UM_FORMAT_COMPLETED, (WPARAM)FALSE, 0); | ||||
| 				} else { | ||||
| 					uprintf("\r\nFormat operation started"); | ||||
| 					PrintInfo(0, -1); | ||||
| 					timer = 0; | ||||
| 					static_sprintf(szTimer, "00:00:00"); | ||||
| 					SendMessageA(hStatus, SB_SETTEXTA, SBT_OWNERDRAW | SB_SECTION_RIGHT, (LPARAM)szTimer); | ||||
| 					SetTimer(hMainDialog, TID_APP_TIMER, 1000, ClockTimer); | ||||
| 					// Set focus to the Cancel button
 | ||||
| 					SendMessage(hMainDialog, WM_NEXTDLGCTL, (WPARAM)GetDlgItem(hMainDialog, IDCANCEL), TRUE); | ||||
| 				} | ||||
| 			// Create a thread to validate options and download files as needed (so that we can update the UI).
 | ||||
| 			// On exit, this thread sends message UM_FORMAT_START back to this dialog.
 | ||||
| 			if (CreateThread(NULL, 0, BootCheckThread, NULL, 0, NULL) == NULL) { | ||||
| 				uprintf("Unable to start boot check thread"); | ||||
| 				FormatStatus = ERROR_SEVERITY_ERROR | FAC(FACILITY_STORAGE) | APPERR(ERROR_CANT_START_THREAD); | ||||
| 				PostMessage(hMainDialog, UM_FORMAT_COMPLETED, (WPARAM)FALSE, 0); | ||||
| 			} | ||||
| 			if (format_thid != NULL) | ||||
| 				break; | ||||
| 		aborted_start: | ||||
| 			format_op_in_progress = FALSE; | ||||
| 			EnableControls(TRUE); | ||||
| 			zero_drive = FALSE; | ||||
| 			if (queued_hotplug_event) | ||||
| 				SendMessage(hDlg, UM_MEDIA_CHANGE, 0, 0); | ||||
| 			EnableWindow(GetDlgItem(hDlg, IDCANCEL), TRUE); | ||||
| 			break; | ||||
| 		case IDC_LANG: | ||||
| 			// Show the language menu such that it doesn't overlap the button
 | ||||
|  | @ -3610,6 +3558,87 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA | |||
| 		SendMessage(hUpdatesDlg, WM_NEXTDLGCTL, (WPARAM)GetDlgItem(hUpdatesDlg, IDC_CHECK_NOW), TRUE); | ||||
| 		break; | ||||
| 
 | ||||
| 	case UM_FORMAT_START: | ||||
| 		if (wParam != 0) | ||||
| 			goto aborted_start; | ||||
| 
 | ||||
| 		if (!zero_drive) { | ||||
| 			// Display a warning about UDF formatting times
 | ||||
| 			if (fs == FS_UDF) { | ||||
| 				dur_secs = (uint32_t)(((double)SelectedDrive.DiskSize) / 1073741824.0f / UDF_FORMAT_SPEED); | ||||
| 				if (dur_secs > UDF_FORMAT_WARN) { | ||||
| 					dur_mins = dur_secs / 60; | ||||
| 					dur_secs -= dur_mins * 60; | ||||
| 					MessageBoxExU(hMainDialog, lmprintf(MSG_112, dur_mins, dur_secs), lmprintf(MSG_113), | ||||
| 						MB_OK | MB_ICONASTERISK | MB_IS_RTL, selected_langid); | ||||
| 				} else { | ||||
| 					dur_secs = 0; | ||||
| 					dur_mins = 0; | ||||
| 				} | ||||
| 			} | ||||
| 
 | ||||
| 			if ((bt == BT_IMAGE) && IS_DD_BOOTABLE(img_report)) { | ||||
| 				if (img_report.is_iso) { | ||||
| 					// Ask users how they want to write ISOHybrid images
 | ||||
| 					char* iso_image = lmprintf(MSG_036); | ||||
| 					char* dd_image = lmprintf(MSG_095); | ||||
| 					char* choices[2] = { lmprintf(MSG_276, iso_image), lmprintf(MSG_277, dd_image) }; | ||||
| 					i = SelectionDialog(lmprintf(MSG_274), lmprintf(MSG_275, iso_image, dd_image, iso_image, dd_image), | ||||
| 						choices, 2); | ||||
| 					if (i < 0)	// Cancel
 | ||||
| 						goto aborted_start; | ||||
| 					else if (i == 2) | ||||
| 						write_as_image = TRUE; | ||||
| 				} else { | ||||
| 					write_as_image = TRUE; | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		if (!CheckDriveAccess(2000)) | ||||
| 			goto aborted_start; | ||||
| 
 | ||||
| 		GetWindowTextU(hDeviceList, tmp, ARRAYSIZE(tmp)); | ||||
| 		if (MessageBoxExU(hMainDialog, lmprintf(MSG_003, tmp), | ||||
| 			APPLICATION_NAME, MB_OKCANCEL | MB_ICONWARNING | MB_IS_RTL, selected_langid) == IDCANCEL) | ||||
| 			goto aborted_start; | ||||
| 		if ((SelectedDrive.nPartitions > 1) && (MessageBoxExU(hMainDialog, lmprintf(MSG_093), | ||||
| 			lmprintf(MSG_094), MB_OKCANCEL | MB_ICONWARNING | MB_IS_RTL, selected_langid) == IDCANCEL)) | ||||
| 			goto aborted_start; | ||||
| 		if ((!zero_drive) && (bt != BT_NON_BOOTABLE) && (SelectedDrive.SectorSize != 512) && | ||||
| 			(MessageBoxExU(hMainDialog, lmprintf(MSG_196, SelectedDrive.SectorSize), | ||||
| 				lmprintf(MSG_197), MB_OKCANCEL | MB_ICONWARNING | MB_IS_RTL, selected_langid) == IDCANCEL)) | ||||
| 			goto aborted_start; | ||||
| 
 | ||||
| 		nDeviceIndex = ComboBox_GetCurSel(hDeviceList); | ||||
| 		DeviceNum = (DWORD)ComboBox_GetItemData(hDeviceList, nDeviceIndex); | ||||
| 		InitProgress(zero_drive || write_as_image); | ||||
| 		format_thid = CreateThread(NULL, 0, FormatThread, (LPVOID)(uintptr_t)DeviceNum, 0, NULL); | ||||
| 		if (format_thid == NULL) { | ||||
| 			uprintf("Unable to start formatting thread"); | ||||
| 			FormatStatus = ERROR_SEVERITY_ERROR | FAC(FACILITY_STORAGE) | APPERR(ERROR_CANT_START_THREAD); | ||||
| 			PostMessage(hMainDialog, UM_FORMAT_COMPLETED, (WPARAM)FALSE, 0); | ||||
| 		} else { | ||||
| 			uprintf("\r\nFormat operation started"); | ||||
| 			PrintInfo(0, -1); | ||||
| 			timer = 0; | ||||
| 			static_sprintf(szTimer, "00:00:00"); | ||||
| 			SendMessageA(hStatus, SB_SETTEXTA, SBT_OWNERDRAW | SB_SECTION_RIGHT, (LPARAM)szTimer); | ||||
| 			SetTimer(hMainDialog, TID_APP_TIMER, 1000, ClockTimer); | ||||
| 			// Set focus to the Cancel button
 | ||||
| 			SendMessage(hMainDialog, WM_NEXTDLGCTL, (WPARAM)GetDlgItem(hMainDialog, IDCANCEL), TRUE); | ||||
| 		} | ||||
| 		if (format_thid != NULL) | ||||
| 			break; | ||||
| 	aborted_start: | ||||
| 		format_op_in_progress = FALSE; | ||||
| 		EnableControls(TRUE); | ||||
| 		zero_drive = FALSE; | ||||
| 		if (queued_hotplug_event) | ||||
| 			SendMessage(hDlg, UM_MEDIA_CHANGE, 0, 0); | ||||
| 		EnableWindow(GetDlgItem(hDlg, IDCANCEL), TRUE); | ||||
| 		break; | ||||
| 
 | ||||
| 	case UM_FORMAT_COMPLETED: | ||||
| 		format_thid = NULL; | ||||
| 		// Stop the timer
 | ||||
|  |  | |||
							
								
								
									
										16
									
								
								src/rufus.h
									
										
									
									
									
								
							
							
						
						
									
										16
									
								
								src/rufus.h
									
										
									
									
									
								
							|  | @ -67,7 +67,12 @@ | |||
| #define MARQUEE_TIMER_REFRESH       10			// Time between progress bar marquee refreshes, in ms
 | ||||
| #define FS_DEFAULT                  FS_FAT32 | ||||
| #define SINGLE_CLUSTERSIZE_DEFAULT  0x00000100 | ||||
| #define BADBLOCK_PATTERNS           {0xaa, 0x55, 0xff, 0x00} | ||||
| #define BADLOCKS_PATTERN_TYPES      3 | ||||
| #define BADBLOCK_PATTERN_COUNT      4 | ||||
| #define BADBLOCK_PATTERN_SLC        {0x00, 0xff, 0x55, 0xaa} | ||||
| #define BADCLOCK_PATTERN_MLC        {0x00, 0xff, 0x33, 0xcc} | ||||
| #define BADBLOCK_PATTERN_TLC        {0x00, 0xff, 0x1c71c7, 0xe38e38} | ||||
| #define BADBLOCK_BLOCK_SIZE         (128 * 1024) | ||||
| #define LARGE_FAT32_SIZE            (32*1073741824LL)	// Size at which we need to use fat32format
 | ||||
| #define UDF_FORMAT_SPEED            3.1f		// Speed estimate at which we expect UDF drives to be formatted (GB/s)
 | ||||
| #define UDF_FORMAT_WARN             20			// Duration (in seconds) above which we warn about long UDF formatting times
 | ||||
|  | @ -75,6 +80,7 @@ | |||
| #define FAT32_CLUSTER_THRESHOLD     1.011f		// For FAT32, cluster size changes don't occur at power of 2 boundaries but sligthly above
 | ||||
| #define DD_BUFFER_SIZE              65536		// Minimum size of the buffer we use for DD operations
 | ||||
| #define UBUFFER_SIZE                2048 | ||||
| #define RSA_SIGNATURE_SIZE          256 | ||||
| #define CBN_SELCHANGE_INTERNAL      (CBN_SELCHANGE + 256) | ||||
| #define RUFUS_URL                   "https://rufus.ie"
 | ||||
| #define DOWNLOAD_URL                RUFUS_URL "/downloads" | ||||
|  | @ -157,6 +163,7 @@ enum user_message_type { | |||
| 	UM_NO_UPDATE, | ||||
| 	UM_UPDATE_CSM_TOOLTIP, | ||||
| 	UM_RESIZE_BUTTONS, | ||||
| 	UM_FORMAT_START, | ||||
| 	// Start of the WM IDs for the language menu items
 | ||||
| 	UM_LANGUAGE_MENU = WM_APP + 0x100 | ||||
| }; | ||||
|  | @ -394,7 +401,6 @@ extern float fScale; | |||
| extern char szFolderPath[MAX_PATH], app_dir[MAX_PATH], temp_dir[MAX_PATH], system_dir[MAX_PATH], sysnative_dir[MAX_PATH]; | ||||
| extern char* image_path; | ||||
| extern DWORD FormatStatus, DownloadStatus, MainThreadId; | ||||
| extern BOOL PromptOnError; | ||||
| extern unsigned long syslinux_ldlinux_len[2]; | ||||
| extern const int nb_steps[FS_MAX]; | ||||
| extern BOOL use_own_c32[NB_OLD_C32], detect_fakes, iso_op_in_progress, format_op_in_progress, right_to_left_mode; | ||||
|  | @ -470,8 +476,8 @@ extern BOOL ResetDevice(int index); | |||
| extern BOOL GetOpticalMedia(IMG_SAVE* img_save); | ||||
| extern BOOL SetLGP(BOOL bRestore, BOOL* bExistingKey, const char* szPath, const char* szPolicy, DWORD dwValue); | ||||
| extern LONG GetEntryWidth(HWND hDropDown, const char* entry); | ||||
| extern DWORD DownloadFile(const char* url, const char* file, HWND hProgressDialog); | ||||
| extern HANDLE DownloadFileThreaded(const char* url, const char* file, HWND hProgressDialog); | ||||
| extern DWORD DownloadSignedFile(const char* url, const char* file, HWND hProgressDialog, BOOL PromptOnError); | ||||
| extern HANDLE DownloadSignedFileThreaded(const char* url, const char* file, HWND hProgressDialog, BOOL bPromptOnError); | ||||
| extern INT_PTR CALLBACK UpdateCallback(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam); | ||||
| extern BOOL SetUpdateCheck(void); | ||||
| extern BOOL CheckForUpdates(BOOL force); | ||||
|  | @ -498,6 +504,7 @@ extern int IsHDD(DWORD DriveIndex, uint16_t vid, uint16_t pid, const char* strid | |||
| extern char* GetSignatureName(const char* path, const char* country_code); | ||||
| extern uint64_t GetSignatureTimeStamp(const char* path); | ||||
| extern LONG ValidateSignature(HWND hDlg, const char* path); | ||||
| extern BOOL ValidateOpensslSignature(BYTE* pbBuffer, DWORD dwBufferLen, BYTE* pbSignature, DWORD dwSigLen); | ||||
| extern BOOL IsFontAvailable(const char* font_name); | ||||
| extern BOOL WriteFileWithRetry(HANDLE hFile, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite, | ||||
| 	LPDWORD lpNumberOfBytesWritten, DWORD nNumRetries); | ||||
|  | @ -607,3 +614,4 @@ static __inline HMODULE GetLibraryHandle(char* szLibraryName) { | |||
| #define ERROR_CANT_PATCH               0x120A | ||||
| #define ERROR_CANT_ASSIGN_LETTER       0x120B | ||||
| #define ERROR_CANT_MOUNT_VOLUME        0x120C | ||||
| #define ERROR_BAD_SIGNATURE            0x120D | ||||
|  |  | |||
							
								
								
									
										10
									
								
								src/rufus.rc
									
										
									
									
									
								
							
							
						
						
									
										10
									
								
								src/rufus.rc
									
										
									
									
									
								
							|  | @ -33,7 +33,7 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL | |||
| IDD_DIALOG DIALOGEX 12, 12, 232, 326 | ||||
| STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU | ||||
| EXSTYLE WS_EX_ACCEPTFILES | ||||
| CAPTION "Rufus 3.1.1323" | ||||
| CAPTION "Rufus 3.2.1328" | ||||
| FONT 9, "Segoe UI Symbol", 400, 0, 0x0 | ||||
| BEGIN | ||||
|     LTEXT           "Drive Properties",IDS_DRIVE_PROPERTIES_TXT,8,6,53,12,NOT WS_GROUP | ||||
|  | @ -389,8 +389,8 @@ END | |||
| // | ||||
| 
 | ||||
| VS_VERSION_INFO VERSIONINFO | ||||
|  FILEVERSION 3,1,1323,0 | ||||
|  PRODUCTVERSION 3,1,1323,0 | ||||
|  FILEVERSION 3,2,1328,0 | ||||
|  PRODUCTVERSION 3,2,1328,0 | ||||
|  FILEFLAGSMASK 0x3fL | ||||
| #ifdef _DEBUG | ||||
|  FILEFLAGS 0x1L | ||||
|  | @ -407,13 +407,13 @@ BEGIN | |||
|         BEGIN | ||||
|             VALUE "CompanyName", "Akeo Consulting (http://akeo.ie)" | ||||
|             VALUE "FileDescription", "Rufus" | ||||
|             VALUE "FileVersion", "3.1.1323" | ||||
|             VALUE "FileVersion", "3.2.1328" | ||||
|             VALUE "InternalName", "Rufus" | ||||
|             VALUE "LegalCopyright", "© 2011-2018 Pete Batard (GPL v3)" | ||||
|             VALUE "LegalTrademarks", "http://www.gnu.org/copyleft/gpl.html" | ||||
|             VALUE "OriginalFilename", "rufus.exe" | ||||
|             VALUE "ProductName", "Rufus" | ||||
|             VALUE "ProductVersion", "3.1.1323" | ||||
|             VALUE "ProductVersion", "3.2.1328" | ||||
|         END | ||||
|     END | ||||
|     BLOCK "VarFileInfo" | ||||
|  |  | |||
|  | @ -315,6 +315,8 @@ const char* _StrError(DWORD error_code) | |||
| 		return lmprintf(MSG_078); | ||||
| 	case ERROR_NOT_READY: | ||||
| 		return lmprintf(MSG_079); | ||||
| 	case ERROR_BAD_SIGNATURE: | ||||
| 		return lmprintf(MSG_172); | ||||
| 	default: | ||||
| 		SetLastError(error_code); | ||||
| 		return WindowsErrorString(); | ||||
|  |  | |||
							
								
								
									
										27
									
								
								src/stdlg.c
									
										
									
									
									
								
							
							
						
						
									
										27
									
								
								src/stdlg.c
									
										
									
									
									
								
							|  | @ -1558,8 +1558,9 @@ INT_PTR CALLBACK NewVersionCallback(HWND hDlg, UINT message, WPARAM wParam, LPAR | |||
| 	static char* filepath = NULL; | ||||
| 	static int download_status = 0; | ||||
| 	static HFONT hyperlink_font = NULL; | ||||
| 	LONG i; | ||||
| 	static HANDLE hThread = NULL; | ||||
| 	HWND hNotes; | ||||
| 	DWORD exit_code; | ||||
| 	STARTUPINFOA si; | ||||
| 	PROCESS_INFORMATION pi; | ||||
| 	EXT_DECL(dl_ext, NULL, __VA_GROUP__("*.exe"), __VA_GROUP__(lmprintf(MSG_037))); | ||||
|  | @ -1614,8 +1615,16 @@ INT_PTR CALLBACK NewVersionCallback(HWND hDlg, UINT message, WPARAM wParam, LPAR | |||
| 			case 1:		// Abort
 | ||||
| 				FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_CANCELLED; | ||||
| 				download_status = 0; | ||||
| 				hThread = NULL; | ||||
| 				break; | ||||
| 			case 2:		// Launch newer version and close this one
 | ||||
| 				if ((hThread == NULL) || (!GetExitCodeThread(hThread, &exit_code)) || (exit_code == 0)) { | ||||
| 					hThread = NULL; | ||||
| 					EnableWindow(GetDlgItem(hDlg, IDC_DOWNLOAD), FALSE); | ||||
| 					break; | ||||
| 				} | ||||
| 
 | ||||
| 				hThread = NULL; | ||||
| 				Sleep(1000);	// Add a delay on account of antivirus scanners
 | ||||
| 
 | ||||
| 				if (ValidateSignature(hDlg, filepath) != NO_ERROR) { | ||||
|  | @ -1630,7 +1639,7 @@ INT_PTR CALLBACK NewVersionCallback(HWND hDlg, UINT message, WPARAM wParam, LPAR | |||
| 				si.cb = sizeof(si); | ||||
| 				if (!CreateProcessU(filepath, cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) { | ||||
| 					PrintInfo(0, MSG_214); | ||||
| 					uprintf("Failed to launch new application: %s\n", WindowsErrorString()); | ||||
| 					uprintf("Failed to launch new application: %s", WindowsErrorString()); | ||||
| 				} else { | ||||
| 					PrintInfo(0, MSG_213); | ||||
| 					PostMessage(hDlg, WM_COMMAND, (WPARAM)IDCLOSE, 0); | ||||
|  | @ -1639,19 +1648,18 @@ INT_PTR CALLBACK NewVersionCallback(HWND hDlg, UINT message, WPARAM wParam, LPAR | |||
| 				break; | ||||
| 			default:	// Download
 | ||||
| 				if (update.download_url == NULL) { | ||||
| 					uprintf("Could not get download URL\n"); | ||||
| 					uprintf("Could not get download URL"); | ||||
| 					break; | ||||
| 				} | ||||
| 				for (i=(int)strlen(update.download_url); (i>0)&&(update.download_url[i]!='/'); i--); | ||||
| 				dl_ext.filename = &update.download_url[i+1]; | ||||
| 				dl_ext.filename = PathFindFileNameU(update.download_url); | ||||
| 				filepath = FileDialog(TRUE, app_dir, &dl_ext, OFN_NOCHANGEDIR); | ||||
| 				if (filepath == NULL) { | ||||
| 					uprintf("Could not get save path\n"); | ||||
| 					uprintf("Could not get save path"); | ||||
| 					break; | ||||
| 				} | ||||
| 				// Opening the File Dialog will make us lose tabbing focus - set it back
 | ||||
| 				SendMessage(hDlg, WM_NEXTDLGCTL, (WPARAM)GetDlgItem(hDlg, IDC_DOWNLOAD), TRUE); | ||||
| 				DownloadFileThreaded(update.download_url, filepath, hDlg); | ||||
| 				hThread = DownloadSignedFileThreaded(update.download_url, filepath, hDlg, TRUE); | ||||
| 				break; | ||||
| 			} | ||||
| 			return (INT_PTR)TRUE; | ||||
|  | @ -1665,11 +1673,14 @@ INT_PTR CALLBACK NewVersionCallback(HWND hDlg, UINT message, WPARAM wParam, LPAR | |||
| 		return (INT_PTR)TRUE; | ||||
| 	case UM_PROGRESS_EXIT: | ||||
| 		EnableWindow(GetDlgItem(hDlg, IDCANCEL), TRUE); | ||||
| 		if (wParam) { | ||||
| 		if (wParam != 0) { | ||||
| 			SetWindowTextU(GetDlgItem(hDlg, IDC_DOWNLOAD), lmprintf(MSG_039)); | ||||
| 			download_status = 2; | ||||
| 		} else { | ||||
| 			SetWindowTextU(GetDlgItem(hDlg, IDC_DOWNLOAD), lmprintf(MSG_040)); | ||||
| 			// Disable the download button if we found an invalid signature
 | ||||
| 			EnableWindow(GetDlgItem(hDlg, IDC_DOWNLOAD), | ||||
| 				FormatStatus != (ERROR_SEVERITY_ERROR | FAC(FACILITY_STORAGE) | APPERR(ERROR_BAD_SIGNATURE))); | ||||
| 			download_status = 0; | ||||
| 		} | ||||
| 		return (INT_PTR)TRUE; | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue