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