diff --git a/res/localization/rufus.loc b/res/localization/rufus.loc
index 26a626ac..3bb0699d 100644
--- a/res/localization/rufus.loc
+++ b/res/localization/rufus.loc
@@ -517,6 +517,7 @@ t MSG_267 "Applying Windows image: %0.1f%% completed"
t MSG_268 "Applying Windows image..."
t MSG_269 "Preserve timestamps"
t MSG_270 "USB debug"
+t MSG_271 "Computing image checksum: %0.1f%% completed"
################################################################################
############################# TRANSLATOR END COPY ##############################
diff --git a/src/.msvc/rufus.vcxproj b/src/.msvc/rufus.vcxproj
index 9dcc30bf..abfac84a 100644
--- a/src/.msvc/rufus.vcxproj
+++ b/src/.msvc/rufus.vcxproj
@@ -189,6 +189,7 @@
+
diff --git a/src/.msvc/rufus.vcxproj.filters b/src/.msvc/rufus.vcxproj.filters
index f36a263d..b7a5d182 100644
--- a/src/.msvc/rufus.vcxproj.filters
+++ b/src/.msvc/rufus.vcxproj.filters
@@ -69,6 +69,9 @@
Source Files
+
+ Source Files
+
diff --git a/src/.msvc/rufus_sources b/src/.msvc/rufus_sources
index 67ad702f..68dd6d5e 100644
--- a/src/.msvc/rufus_sources
+++ b/src/.msvc/rufus_sources
@@ -31,20 +31,21 @@ TARGETLIBS=$(SDK_LIB_PATH)\kernel32.lib \
# http://jpassing.com/2008/02/01/how-to-use-manifests-with-buildexe/
SXS_APPLICATION_MANIFEST=..\rufus.manifest
-SOURCES=rufus.c \
- format.c \
- stdio.c \
- stdfn.c \
- stdlg.c \
- icon.c \
- parser.c \
- localization.c \
- net.c \
- iso.c \
+SOURCES=badblocks.c \
+ checksum.c \
dos.c \
dos_locale.c \
- badblocks.c \
drive.c \
+ format.c \
+ icon.c \
+ iso.c \
+ stdfn.c \
+ stdio.c \
+ stdlg.c \
+ localization.c \
+ net.c \
+ parser.c \
+ rufus.c \
smart.c \
syslinux.c \
usb.c \
diff --git a/src/Makefile.am b/src/Makefile.am
index 1ac4b773..d0c90327 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -10,7 +10,8 @@ AM_V_WINDRES = $(AM_V_WINDRES_$(V))
%_rc.o: %.rc ../res/localization/embedded.loc
$(AM_V_WINDRES) $(AM_RCFLAGS) -i $< -o $@
-rufus_SOURCES = drive.c icon.c parser.c localization.c iso.c net.c dos.c dos_locale.c badblocks.c syslinux.c usb.c vhd.c format.c smart.c stdio.c stdfn.c stdlg.c rufus.c
+rufus_SOURCES = badblocks.c checksum.c dos.c dos_locale.c drive.c format.c icon.c iso.c localization.c net.c smart.c \
+ stdfn.c stdio.c stdlg.c rufus.c parser.c syslinux.c usb.c vhd.c
rufus_CFLAGS = -I./ms-sys/inc -I./syslinux/libfat -I./syslinux/libinstaller -I./libcdio $(AM_CFLAGS)
rufus_LDFLAGS = $(AM_LDFLAGS) -mwindows
rufus_LDADD = rufus_rc.o bled/libbled.a ms-sys/libmssys.a syslinux/libfat/libfat.a syslinux/libinstaller/libinstaller.a \
diff --git a/src/Makefile.in b/src/Makefile.in
index f51c63e3..e52be8fd 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -87,15 +87,16 @@ mkinstalldirs = $(install_sh) -d
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
PROGRAMS = $(noinst_PROGRAMS)
-am_rufus_OBJECTS = rufus-drive.$(OBJEXT) rufus-icon.$(OBJEXT) \
- rufus-parser.$(OBJEXT) rufus-localization.$(OBJEXT) \
- rufus-iso.$(OBJEXT) rufus-net.$(OBJEXT) rufus-dos.$(OBJEXT) \
- rufus-dos_locale.$(OBJEXT) rufus-badblocks.$(OBJEXT) \
+am_rufus_OBJECTS = rufus-badblocks.$(OBJEXT) rufus-checksum.$(OBJEXT) \
+ rufus-dos.$(OBJEXT) rufus-dos_locale.$(OBJEXT) \
+ rufus-drive.$(OBJEXT) rufus-format.$(OBJEXT) \
+ rufus-icon.$(OBJEXT) rufus-iso.$(OBJEXT) \
+ rufus-localization.$(OBJEXT) rufus-net.$(OBJEXT) \
+ rufus-smart.$(OBJEXT) rufus-stdfn.$(OBJEXT) \
+ rufus-stdio.$(OBJEXT) rufus-stdlg.$(OBJEXT) \
+ rufus-rufus.$(OBJEXT) rufus-parser.$(OBJEXT) \
rufus-syslinux.$(OBJEXT) rufus-usb.$(OBJEXT) \
- rufus-vhd.$(OBJEXT) rufus-format.$(OBJEXT) \
- rufus-smart.$(OBJEXT) rufus-stdio.$(OBJEXT) \
- rufus-stdfn.$(OBJEXT) rufus-stdlg.$(OBJEXT) \
- rufus-rufus.$(OBJEXT)
+ rufus-vhd.$(OBJEXT)
rufus_OBJECTS = $(am_rufus_OBJECTS)
rufus_DEPENDENCIES = rufus_rc.o bled/libbled.a ms-sys/libmssys.a \
syslinux/libfat/libfat.a syslinux/libinstaller/libinstaller.a \
@@ -269,7 +270,9 @@ AM_V_WINDRES_0 = @echo " RC $@";$(WINDRES)
AM_V_WINDRES_1 = $(WINDRES)
AM_V_WINDRES_ = $(AM_V_WINDRES_$(AM_DEFAULT_VERBOSITY))
AM_V_WINDRES = $(AM_V_WINDRES_$(V))
-rufus_SOURCES = drive.c icon.c parser.c localization.c iso.c net.c dos.c dos_locale.c badblocks.c syslinux.c usb.c vhd.c format.c smart.c stdio.c stdfn.c stdlg.c rufus.c
+rufus_SOURCES = badblocks.c checksum.c dos.c dos_locale.c drive.c format.c icon.c iso.c localization.c net.c smart.c \
+ stdfn.c stdio.c stdlg.c rufus.c parser.c syslinux.c usb.c vhd.c
+
rufus_CFLAGS = -I./ms-sys/inc -I./syslinux/libfat -I./syslinux/libinstaller -I./libcdio $(AM_CFLAGS)
rufus_LDFLAGS = $(AM_LDFLAGS) -mwindows
rufus_LDADD = rufus_rc.o bled/libbled.a ms-sys/libmssys.a syslinux/libfat/libfat.a syslinux/libinstaller/libinstaller.a \
@@ -329,41 +332,17 @@ distclean-compile:
.c.obj:
$(AM_V_CC)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
-rufus-drive.o: drive.c
- $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rufus_CFLAGS) $(CFLAGS) -c -o rufus-drive.o `test -f 'drive.c' || echo '$(srcdir)/'`drive.c
+rufus-badblocks.o: badblocks.c
+ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rufus_CFLAGS) $(CFLAGS) -c -o rufus-badblocks.o `test -f 'badblocks.c' || echo '$(srcdir)/'`badblocks.c
-rufus-drive.obj: drive.c
- $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rufus_CFLAGS) $(CFLAGS) -c -o rufus-drive.obj `if test -f 'drive.c'; then $(CYGPATH_W) 'drive.c'; else $(CYGPATH_W) '$(srcdir)/drive.c'; fi`
+rufus-badblocks.obj: badblocks.c
+ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rufus_CFLAGS) $(CFLAGS) -c -o rufus-badblocks.obj `if test -f 'badblocks.c'; then $(CYGPATH_W) 'badblocks.c'; else $(CYGPATH_W) '$(srcdir)/badblocks.c'; fi`
-rufus-icon.o: icon.c
- $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rufus_CFLAGS) $(CFLAGS) -c -o rufus-icon.o `test -f 'icon.c' || echo '$(srcdir)/'`icon.c
+rufus-checksum.o: checksum.c
+ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rufus_CFLAGS) $(CFLAGS) -c -o rufus-checksum.o `test -f 'checksum.c' || echo '$(srcdir)/'`checksum.c
-rufus-icon.obj: icon.c
- $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rufus_CFLAGS) $(CFLAGS) -c -o rufus-icon.obj `if test -f 'icon.c'; then $(CYGPATH_W) 'icon.c'; else $(CYGPATH_W) '$(srcdir)/icon.c'; fi`
-
-rufus-parser.o: parser.c
- $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rufus_CFLAGS) $(CFLAGS) -c -o rufus-parser.o `test -f 'parser.c' || echo '$(srcdir)/'`parser.c
-
-rufus-parser.obj: parser.c
- $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rufus_CFLAGS) $(CFLAGS) -c -o rufus-parser.obj `if test -f 'parser.c'; then $(CYGPATH_W) 'parser.c'; else $(CYGPATH_W) '$(srcdir)/parser.c'; fi`
-
-rufus-localization.o: localization.c
- $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rufus_CFLAGS) $(CFLAGS) -c -o rufus-localization.o `test -f 'localization.c' || echo '$(srcdir)/'`localization.c
-
-rufus-localization.obj: localization.c
- $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rufus_CFLAGS) $(CFLAGS) -c -o rufus-localization.obj `if test -f 'localization.c'; then $(CYGPATH_W) 'localization.c'; else $(CYGPATH_W) '$(srcdir)/localization.c'; fi`
-
-rufus-iso.o: iso.c
- $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rufus_CFLAGS) $(CFLAGS) -c -o rufus-iso.o `test -f 'iso.c' || echo '$(srcdir)/'`iso.c
-
-rufus-iso.obj: iso.c
- $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rufus_CFLAGS) $(CFLAGS) -c -o rufus-iso.obj `if test -f 'iso.c'; then $(CYGPATH_W) 'iso.c'; else $(CYGPATH_W) '$(srcdir)/iso.c'; fi`
-
-rufus-net.o: net.c
- $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rufus_CFLAGS) $(CFLAGS) -c -o rufus-net.o `test -f 'net.c' || echo '$(srcdir)/'`net.c
-
-rufus-net.obj: net.c
- $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rufus_CFLAGS) $(CFLAGS) -c -o rufus-net.obj `if test -f 'net.c'; then $(CYGPATH_W) 'net.c'; else $(CYGPATH_W) '$(srcdir)/net.c'; fi`
+rufus-checksum.obj: checksum.c
+ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rufus_CFLAGS) $(CFLAGS) -c -o rufus-checksum.obj `if test -f 'checksum.c'; then $(CYGPATH_W) 'checksum.c'; else $(CYGPATH_W) '$(srcdir)/checksum.c'; fi`
rufus-dos.o: dos.c
$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rufus_CFLAGS) $(CFLAGS) -c -o rufus-dos.o `test -f 'dos.c' || echo '$(srcdir)/'`dos.c
@@ -377,11 +356,77 @@ rufus-dos_locale.o: dos_locale.c
rufus-dos_locale.obj: dos_locale.c
$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rufus_CFLAGS) $(CFLAGS) -c -o rufus-dos_locale.obj `if test -f 'dos_locale.c'; then $(CYGPATH_W) 'dos_locale.c'; else $(CYGPATH_W) '$(srcdir)/dos_locale.c'; fi`
-rufus-badblocks.o: badblocks.c
- $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rufus_CFLAGS) $(CFLAGS) -c -o rufus-badblocks.o `test -f 'badblocks.c' || echo '$(srcdir)/'`badblocks.c
+rufus-drive.o: drive.c
+ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rufus_CFLAGS) $(CFLAGS) -c -o rufus-drive.o `test -f 'drive.c' || echo '$(srcdir)/'`drive.c
-rufus-badblocks.obj: badblocks.c
- $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rufus_CFLAGS) $(CFLAGS) -c -o rufus-badblocks.obj `if test -f 'badblocks.c'; then $(CYGPATH_W) 'badblocks.c'; else $(CYGPATH_W) '$(srcdir)/badblocks.c'; fi`
+rufus-drive.obj: drive.c
+ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rufus_CFLAGS) $(CFLAGS) -c -o rufus-drive.obj `if test -f 'drive.c'; then $(CYGPATH_W) 'drive.c'; else $(CYGPATH_W) '$(srcdir)/drive.c'; fi`
+
+rufus-format.o: format.c
+ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rufus_CFLAGS) $(CFLAGS) -c -o rufus-format.o `test -f 'format.c' || echo '$(srcdir)/'`format.c
+
+rufus-format.obj: format.c
+ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rufus_CFLAGS) $(CFLAGS) -c -o rufus-format.obj `if test -f 'format.c'; then $(CYGPATH_W) 'format.c'; else $(CYGPATH_W) '$(srcdir)/format.c'; fi`
+
+rufus-icon.o: icon.c
+ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rufus_CFLAGS) $(CFLAGS) -c -o rufus-icon.o `test -f 'icon.c' || echo '$(srcdir)/'`icon.c
+
+rufus-icon.obj: icon.c
+ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rufus_CFLAGS) $(CFLAGS) -c -o rufus-icon.obj `if test -f 'icon.c'; then $(CYGPATH_W) 'icon.c'; else $(CYGPATH_W) '$(srcdir)/icon.c'; fi`
+
+rufus-iso.o: iso.c
+ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rufus_CFLAGS) $(CFLAGS) -c -o rufus-iso.o `test -f 'iso.c' || echo '$(srcdir)/'`iso.c
+
+rufus-iso.obj: iso.c
+ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rufus_CFLAGS) $(CFLAGS) -c -o rufus-iso.obj `if test -f 'iso.c'; then $(CYGPATH_W) 'iso.c'; else $(CYGPATH_W) '$(srcdir)/iso.c'; fi`
+
+rufus-localization.o: localization.c
+ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rufus_CFLAGS) $(CFLAGS) -c -o rufus-localization.o `test -f 'localization.c' || echo '$(srcdir)/'`localization.c
+
+rufus-localization.obj: localization.c
+ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rufus_CFLAGS) $(CFLAGS) -c -o rufus-localization.obj `if test -f 'localization.c'; then $(CYGPATH_W) 'localization.c'; else $(CYGPATH_W) '$(srcdir)/localization.c'; fi`
+
+rufus-net.o: net.c
+ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rufus_CFLAGS) $(CFLAGS) -c -o rufus-net.o `test -f 'net.c' || echo '$(srcdir)/'`net.c
+
+rufus-net.obj: net.c
+ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rufus_CFLAGS) $(CFLAGS) -c -o rufus-net.obj `if test -f 'net.c'; then $(CYGPATH_W) 'net.c'; else $(CYGPATH_W) '$(srcdir)/net.c'; fi`
+
+rufus-smart.o: smart.c
+ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rufus_CFLAGS) $(CFLAGS) -c -o rufus-smart.o `test -f 'smart.c' || echo '$(srcdir)/'`smart.c
+
+rufus-smart.obj: smart.c
+ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rufus_CFLAGS) $(CFLAGS) -c -o rufus-smart.obj `if test -f 'smart.c'; then $(CYGPATH_W) 'smart.c'; else $(CYGPATH_W) '$(srcdir)/smart.c'; fi`
+
+rufus-stdfn.o: stdfn.c
+ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rufus_CFLAGS) $(CFLAGS) -c -o rufus-stdfn.o `test -f 'stdfn.c' || echo '$(srcdir)/'`stdfn.c
+
+rufus-stdfn.obj: stdfn.c
+ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rufus_CFLAGS) $(CFLAGS) -c -o rufus-stdfn.obj `if test -f 'stdfn.c'; then $(CYGPATH_W) 'stdfn.c'; else $(CYGPATH_W) '$(srcdir)/stdfn.c'; fi`
+
+rufus-stdio.o: stdio.c
+ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rufus_CFLAGS) $(CFLAGS) -c -o rufus-stdio.o `test -f 'stdio.c' || echo '$(srcdir)/'`stdio.c
+
+rufus-stdio.obj: stdio.c
+ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rufus_CFLAGS) $(CFLAGS) -c -o rufus-stdio.obj `if test -f 'stdio.c'; then $(CYGPATH_W) 'stdio.c'; else $(CYGPATH_W) '$(srcdir)/stdio.c'; fi`
+
+rufus-stdlg.o: stdlg.c
+ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rufus_CFLAGS) $(CFLAGS) -c -o rufus-stdlg.o `test -f 'stdlg.c' || echo '$(srcdir)/'`stdlg.c
+
+rufus-stdlg.obj: stdlg.c
+ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rufus_CFLAGS) $(CFLAGS) -c -o rufus-stdlg.obj `if test -f 'stdlg.c'; then $(CYGPATH_W) 'stdlg.c'; else $(CYGPATH_W) '$(srcdir)/stdlg.c'; fi`
+
+rufus-rufus.o: rufus.c
+ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rufus_CFLAGS) $(CFLAGS) -c -o rufus-rufus.o `test -f 'rufus.c' || echo '$(srcdir)/'`rufus.c
+
+rufus-rufus.obj: rufus.c
+ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rufus_CFLAGS) $(CFLAGS) -c -o rufus-rufus.obj `if test -f 'rufus.c'; then $(CYGPATH_W) 'rufus.c'; else $(CYGPATH_W) '$(srcdir)/rufus.c'; fi`
+
+rufus-parser.o: parser.c
+ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rufus_CFLAGS) $(CFLAGS) -c -o rufus-parser.o `test -f 'parser.c' || echo '$(srcdir)/'`parser.c
+
+rufus-parser.obj: parser.c
+ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rufus_CFLAGS) $(CFLAGS) -c -o rufus-parser.obj `if test -f 'parser.c'; then $(CYGPATH_W) 'parser.c'; else $(CYGPATH_W) '$(srcdir)/parser.c'; fi`
rufus-syslinux.o: syslinux.c
$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rufus_CFLAGS) $(CFLAGS) -c -o rufus-syslinux.o `test -f 'syslinux.c' || echo '$(srcdir)/'`syslinux.c
@@ -401,42 +446,6 @@ rufus-vhd.o: vhd.c
rufus-vhd.obj: vhd.c
$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rufus_CFLAGS) $(CFLAGS) -c -o rufus-vhd.obj `if test -f 'vhd.c'; then $(CYGPATH_W) 'vhd.c'; else $(CYGPATH_W) '$(srcdir)/vhd.c'; fi`
-rufus-format.o: format.c
- $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rufus_CFLAGS) $(CFLAGS) -c -o rufus-format.o `test -f 'format.c' || echo '$(srcdir)/'`format.c
-
-rufus-format.obj: format.c
- $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rufus_CFLAGS) $(CFLAGS) -c -o rufus-format.obj `if test -f 'format.c'; then $(CYGPATH_W) 'format.c'; else $(CYGPATH_W) '$(srcdir)/format.c'; fi`
-
-rufus-smart.o: smart.c
- $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rufus_CFLAGS) $(CFLAGS) -c -o rufus-smart.o `test -f 'smart.c' || echo '$(srcdir)/'`smart.c
-
-rufus-smart.obj: smart.c
- $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rufus_CFLAGS) $(CFLAGS) -c -o rufus-smart.obj `if test -f 'smart.c'; then $(CYGPATH_W) 'smart.c'; else $(CYGPATH_W) '$(srcdir)/smart.c'; fi`
-
-rufus-stdio.o: stdio.c
- $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rufus_CFLAGS) $(CFLAGS) -c -o rufus-stdio.o `test -f 'stdio.c' || echo '$(srcdir)/'`stdio.c
-
-rufus-stdio.obj: stdio.c
- $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rufus_CFLAGS) $(CFLAGS) -c -o rufus-stdio.obj `if test -f 'stdio.c'; then $(CYGPATH_W) 'stdio.c'; else $(CYGPATH_W) '$(srcdir)/stdio.c'; fi`
-
-rufus-stdfn.o: stdfn.c
- $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rufus_CFLAGS) $(CFLAGS) -c -o rufus-stdfn.o `test -f 'stdfn.c' || echo '$(srcdir)/'`stdfn.c
-
-rufus-stdfn.obj: stdfn.c
- $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rufus_CFLAGS) $(CFLAGS) -c -o rufus-stdfn.obj `if test -f 'stdfn.c'; then $(CYGPATH_W) 'stdfn.c'; else $(CYGPATH_W) '$(srcdir)/stdfn.c'; fi`
-
-rufus-stdlg.o: stdlg.c
- $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rufus_CFLAGS) $(CFLAGS) -c -o rufus-stdlg.o `test -f 'stdlg.c' || echo '$(srcdir)/'`stdlg.c
-
-rufus-stdlg.obj: stdlg.c
- $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rufus_CFLAGS) $(CFLAGS) -c -o rufus-stdlg.obj `if test -f 'stdlg.c'; then $(CYGPATH_W) 'stdlg.c'; else $(CYGPATH_W) '$(srcdir)/stdlg.c'; fi`
-
-rufus-rufus.o: rufus.c
- $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rufus_CFLAGS) $(CFLAGS) -c -o rufus-rufus.o `test -f 'rufus.c' || echo '$(srcdir)/'`rufus.c
-
-rufus-rufus.obj: rufus.c
- $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rufus_CFLAGS) $(CFLAGS) -c -o rufus-rufus.obj `if test -f 'rufus.c'; then $(CYGPATH_W) 'rufus.c'; else $(CYGPATH_W) '$(srcdir)/rufus.c'; fi`
-
# This directory's subdirectories are mostly independent; you can cd
# into them and run 'make' without going through this Makefile.
# To change the values of 'make' variables: instead of editing Makefiles,
diff --git a/src/checksum.c b/src/checksum.c
new file mode 100644
index 00000000..79209110
--- /dev/null
+++ b/src/checksum.c
@@ -0,0 +1,600 @@
+/*
+ * Rufus: The Reliable USB Formatting Utility
+ * Message-Digest algorithms (sha1sum, md5sum)
+ * Copyright © 1998-2001 Free Software Foundation, Inc.
+ * Copyright © 2004 g10 Code GmbH
+ * Copyright © 2015 Pete Batard
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+/* SHA-1 code taken from GnuPG */
+/* MD5 code taken from Asterisk */
+#include
+#include
+#include
+#include
+#include
+#include "msapi_utf8.h"
+#include "rufus.h"
+#include "resource.h"
+
+#undef BIG_ENDIAN_HOST
+
+/* Rotate a 32 bit integer by n bytes */
+#if defined(__GNUC__) && defined(__i386__)
+static inline uint32_t
+rol(uint32_t x, int n)
+{
+ __asm__("roll %%cl,%0"
+ :"=r" (x)
+ :"0" (x),"c" (n));
+ return x;
+}
+#else
+#define rol(x,n) ( ((x) << (n)) | ((x) >> (32-(n))) )
+#endif
+
+#ifndef BIG_ENDIAN_HOST
+#define byte_reverse(buf, nlongs) /* nothing */
+#else
+static void byte_reverse(unsigned char *buf, unsigned nlongs)
+{
+ uint32_t t;
+ do {
+ t = (uint32_t)((unsigned)buf[3] << 8 | buf[2]) << 16 |
+ ((unsigned)buf[1] << 8 | buf[0]);
+ *(uint32_t *)buf = t;
+ buf += 4;
+ } while (--nlongs);
+}
+#endif
+
+typedef struct {
+ uint32_t h0, h1, h2, h3, h4;
+ uint32_t nblocks;
+ unsigned char buf[64];
+ int count;
+} SHA1_CONTEXT;
+
+typedef struct {
+ uint32_t h0, h1, h2, h3;
+ uint32_t bits[2];
+ unsigned char buf[64];
+} MD5_CONTEXT;
+
+void sha1_init(SHA1_CONTEXT *ctx)
+{
+ memset(ctx, 0, sizeof(*ctx));
+ ctx->h0 = 0x67452301;
+ ctx->h1 = 0xefcdab89;
+ ctx->h2 = 0x98badcfe;
+ ctx->h3 = 0x10325476;
+ ctx->h4 = 0xc3d2e1f0;
+ ctx->nblocks = 0;
+ ctx->count = 0;
+}
+
+void md5_init(MD5_CONTEXT *ctx)
+{
+ memset(ctx, 0, sizeof(*ctx));
+ ctx->h0 = 0x67452301;
+ ctx->h1 = 0xefcdab89;
+ ctx->h2 = 0x98badcfe;
+ ctx->h3 = 0x10325476;
+ ctx->bits[0] = 0;
+ ctx->bits[1] = 0;
+}
+
+/* Transform the message X which consists of 16 32-bit-words (SHA-1) */
+static void sha1_transform(SHA1_CONTEXT *ctx, const unsigned char *data)
+{
+ uint32_t a, b, c, d, e, tm;
+ uint32_t x[16];
+
+ /* get values from the chaining vars */
+ a = ctx->h0;
+ b = ctx->h1;
+ c = ctx->h2;
+ d = ctx->h3;
+ e = ctx->h4;
+
+#ifdef BIG_ENDIAN_HOST
+ memcpy(x, data, sizeof(x));
+#else
+ {
+ int i;
+ unsigned char *p2;
+ for (i = 0, p2 = (unsigned char*)x; i < 16; i++, p2 += 4) {
+ p2[3] = *data++;
+ p2[2] = *data++;
+ p2[1] = *data++;
+ p2[0] = *data++;
+ }
+ }
+#endif
+
+#define K1 0x5A827999L
+#define K2 0x6ED9EBA1L
+#define K3 0x8F1BBCDCL
+#define K4 0xCA62C1D6L
+#define F1(x,y,z) ( z ^ ( x & ( y ^ z ) ) )
+#define F2(x,y,z) ( x ^ y ^ z )
+#define F3(x,y,z) ( ( x & y ) | ( z & ( x | y ) ) )
+#define F4(x,y,z) ( x ^ y ^ z )
+
+#define M(i) ( tm = x[i&0x0f] ^ x[(i-14)&0x0f] ^ x[(i-8)&0x0f] ^ x[(i-3)&0x0f], (x[i&0x0f] = rol(tm,1)) )
+
+#define SHA1STEP(a,b,c,d,e,f,k,m) do { e += rol( a, 5 ) + f( b, c, d ) + k + m; \
+ b = rol( b, 30 ); } while(0)
+ SHA1STEP(a, b, c, d, e, F1, K1, x[0]);
+ SHA1STEP(e, a, b, c, d, F1, K1, x[1]);
+ SHA1STEP(d, e, a, b, c, F1, K1, x[2]);
+ SHA1STEP(c, d, e, a, b, F1, K1, x[3]);
+ SHA1STEP(b, c, d, e, a, F1, K1, x[4]);
+ SHA1STEP(a, b, c, d, e, F1, K1, x[5]);
+ SHA1STEP(e, a, b, c, d, F1, K1, x[6]);
+ SHA1STEP(d, e, a, b, c, F1, K1, x[7]);
+ SHA1STEP(c, d, e, a, b, F1, K1, x[8]);
+ SHA1STEP(b, c, d, e, a, F1, K1, x[9]);
+ SHA1STEP(a, b, c, d, e, F1, K1, x[10]);
+ SHA1STEP(e, a, b, c, d, F1, K1, x[11]);
+ SHA1STEP(d, e, a, b, c, F1, K1, x[12]);
+ SHA1STEP(c, d, e, a, b, F1, K1, x[13]);
+ SHA1STEP(b, c, d, e, a, F1, K1, x[14]);
+ SHA1STEP(a, b, c, d, e, F1, K1, x[15]);
+ SHA1STEP(e, a, b, c, d, F1, K1, M(16));
+ SHA1STEP(d, e, a, b, c, F1, K1, M(17));
+ SHA1STEP(c, d, e, a, b, F1, K1, M(18));
+ SHA1STEP(b, c, d, e, a, F1, K1, M(19));
+ SHA1STEP(a, b, c, d, e, F2, K2, M(20));
+ SHA1STEP(e, a, b, c, d, F2, K2, M(21));
+ SHA1STEP(d, e, a, b, c, F2, K2, M(22));
+ SHA1STEP(c, d, e, a, b, F2, K2, M(23));
+ SHA1STEP(b, c, d, e, a, F2, K2, M(24));
+ SHA1STEP(a, b, c, d, e, F2, K2, M(25));
+ SHA1STEP(e, a, b, c, d, F2, K2, M(26));
+ SHA1STEP(d, e, a, b, c, F2, K2, M(27));
+ SHA1STEP(c, d, e, a, b, F2, K2, M(28));
+ SHA1STEP(b, c, d, e, a, F2, K2, M(29));
+ SHA1STEP(a, b, c, d, e, F2, K2, M(30));
+ SHA1STEP(e, a, b, c, d, F2, K2, M(31));
+ SHA1STEP(d, e, a, b, c, F2, K2, M(32));
+ SHA1STEP(c, d, e, a, b, F2, K2, M(33));
+ SHA1STEP(b, c, d, e, a, F2, K2, M(34));
+ SHA1STEP(a, b, c, d, e, F2, K2, M(35));
+ SHA1STEP(e, a, b, c, d, F2, K2, M(36));
+ SHA1STEP(d, e, a, b, c, F2, K2, M(37));
+ SHA1STEP(c, d, e, a, b, F2, K2, M(38));
+ SHA1STEP(b, c, d, e, a, F2, K2, M(39));
+ SHA1STEP(a, b, c, d, e, F3, K3, M(40));
+ SHA1STEP(e, a, b, c, d, F3, K3, M(41));
+ SHA1STEP(d, e, a, b, c, F3, K3, M(42));
+ SHA1STEP(c, d, e, a, b, F3, K3, M(43));
+ SHA1STEP(b, c, d, e, a, F3, K3, M(44));
+ SHA1STEP(a, b, c, d, e, F3, K3, M(45));
+ SHA1STEP(e, a, b, c, d, F3, K3, M(46));
+ SHA1STEP(d, e, a, b, c, F3, K3, M(47));
+ SHA1STEP(c, d, e, a, b, F3, K3, M(48));
+ SHA1STEP(b, c, d, e, a, F3, K3, M(49));
+ SHA1STEP(a, b, c, d, e, F3, K3, M(50));
+ SHA1STEP(e, a, b, c, d, F3, K3, M(51));
+ SHA1STEP(d, e, a, b, c, F3, K3, M(52));
+ SHA1STEP(c, d, e, a, b, F3, K3, M(53));
+ SHA1STEP(b, c, d, e, a, F3, K3, M(54));
+ SHA1STEP(a, b, c, d, e, F3, K3, M(55));
+ SHA1STEP(e, a, b, c, d, F3, K3, M(56));
+ SHA1STEP(d, e, a, b, c, F3, K3, M(57));
+ SHA1STEP(c, d, e, a, b, F3, K3, M(58));
+ SHA1STEP(b, c, d, e, a, F3, K3, M(59));
+ SHA1STEP(a, b, c, d, e, F4, K4, M(60));
+ SHA1STEP(e, a, b, c, d, F4, K4, M(61));
+ SHA1STEP(d, e, a, b, c, F4, K4, M(62));
+ SHA1STEP(c, d, e, a, b, F4, K4, M(63));
+ SHA1STEP(b, c, d, e, a, F4, K4, M(64));
+ SHA1STEP(a, b, c, d, e, F4, K4, M(65));
+ SHA1STEP(e, a, b, c, d, F4, K4, M(66));
+ SHA1STEP(d, e, a, b, c, F4, K4, M(67));
+ SHA1STEP(c, d, e, a, b, F4, K4, M(68));
+ SHA1STEP(b, c, d, e, a, F4, K4, M(69));
+ SHA1STEP(a, b, c, d, e, F4, K4, M(70));
+ SHA1STEP(e, a, b, c, d, F4, K4, M(71));
+ SHA1STEP(d, e, a, b, c, F4, K4, M(72));
+ SHA1STEP(c, d, e, a, b, F4, K4, M(73));
+ SHA1STEP(b, c, d, e, a, F4, K4, M(74));
+ SHA1STEP(a, b, c, d, e, F4, K4, M(75));
+ SHA1STEP(e, a, b, c, d, F4, K4, M(76));
+ SHA1STEP(d, e, a, b, c, F4, K4, M(77));
+ SHA1STEP(c, d, e, a, b, F4, K4, M(78));
+ SHA1STEP(b, c, d, e, a, F4, K4, M(79));
+
+#undef F1
+#undef F2
+#undef F3
+#undef F4
+
+ /* Update chaining vars */
+ ctx->h0 += a;
+ ctx->h1 += b;
+ ctx->h2 += c;
+ ctx->h3 += d;
+ ctx->h4 += e;
+}
+
+/* Transform the message X which consists of 16 32-bit-words (MD5) */
+static void md5_transform(MD5_CONTEXT *ctx, const unsigned char *data)
+{
+ uint32_t a, b, c, d;
+ uint32_t x[16];
+
+ a = ctx->h0;
+ b = ctx->h1;
+ c = ctx->h2;
+ d = ctx->h3;
+
+#ifndef BIG_ENDIAN_HOST
+ memcpy(x, data, sizeof(x));
+#else
+ {
+ int i;
+ unsigned char *p;
+ for (i = 0, p = (unsigned char*)x; i < 16; i++, p += 4) {
+ p[3] = *data++;
+ p[2] = *data++;
+ p[1] = *data++;
+ p[0] = *data++;
+ }
+ }
+#endif
+
+#define F1(x, y, z) (z ^ (x & (y ^ z)))
+#define F2(x, y, z) F1(z, x, y)
+#define F3(x, y, z) (x ^ y ^ z)
+#define F4(x, y, z) (y ^ (x | ~z))
+
+#define MD5STEP(f, w, x, y, z, data, s) do { \
+ ( w += f(x, y, z) + data, w = w<>(32-s), w += x ); } while(0)
+
+ MD5STEP(F1, a, b, c, d, x[0] + 0xd76aa478, 7);
+ MD5STEP(F1, d, a, b, c, x[1] + 0xe8c7b756, 12);
+ MD5STEP(F1, c, d, a, b, x[2] + 0x242070db, 17);
+ MD5STEP(F1, b, c, d, a, x[3] + 0xc1bdceee, 22);
+ MD5STEP(F1, a, b, c, d, x[4] + 0xf57c0faf, 7);
+ MD5STEP(F1, d, a, b, c, x[5] + 0x4787c62a, 12);
+ MD5STEP(F1, c, d, a, b, x[6] + 0xa8304613, 17);
+ MD5STEP(F1, b, c, d, a, x[7] + 0xfd469501, 22);
+ MD5STEP(F1, a, b, c, d, x[8] + 0x698098d8, 7);
+ MD5STEP(F1, d, a, b, c, x[9] + 0x8b44f7af, 12);
+ MD5STEP(F1, c, d, a, b, x[10] + 0xffff5bb1, 17);
+ MD5STEP(F1, b, c, d, a, x[11] + 0x895cd7be, 22);
+ MD5STEP(F1, a, b, c, d, x[12] + 0x6b901122, 7);
+ MD5STEP(F1, d, a, b, c, x[13] + 0xfd987193, 12);
+ MD5STEP(F1, c, d, a, b, x[14] + 0xa679438e, 17);
+ MD5STEP(F1, b, c, d, a, x[15] + 0x49b40821, 22);
+
+ MD5STEP(F2, a, b, c, d, x[1] + 0xf61e2562, 5);
+ MD5STEP(F2, d, a, b, c, x[6] + 0xc040b340, 9);
+ MD5STEP(F2, c, d, a, b, x[11] + 0x265e5a51, 14);
+ MD5STEP(F2, b, c, d, a, x[0] + 0xe9b6c7aa, 20);
+ MD5STEP(F2, a, b, c, d, x[5] + 0xd62f105d, 5);
+ MD5STEP(F2, d, a, b, c, x[10] + 0x02441453, 9);
+ MD5STEP(F2, c, d, a, b, x[15] + 0xd8a1e681, 14);
+ MD5STEP(F2, b, c, d, a, x[4] + 0xe7d3fbc8, 20);
+ MD5STEP(F2, a, b, c, d, x[9] + 0x21e1cde6, 5);
+ MD5STEP(F2, d, a, b, c, x[14] + 0xc33707d6, 9);
+ MD5STEP(F2, c, d, a, b, x[3] + 0xf4d50d87, 14);
+ MD5STEP(F2, b, c, d, a, x[8] + 0x455a14ed, 20);
+ MD5STEP(F2, a, b, c, d, x[13] + 0xa9e3e905, 5);
+ MD5STEP(F2, d, a, b, c, x[2] + 0xfcefa3f8, 9);
+ MD5STEP(F2, c, d, a, b, x[7] + 0x676f02d9, 14);
+ MD5STEP(F2, b, c, d, a, x[12] + 0x8d2a4c8a, 20);
+
+ MD5STEP(F3, a, b, c, d, x[5] + 0xfffa3942, 4);
+ MD5STEP(F3, d, a, b, c, x[8] + 0x8771f681, 11);
+ MD5STEP(F3, c, d, a, b, x[11] + 0x6d9d6122, 16);
+ MD5STEP(F3, b, c, d, a, x[14] + 0xfde5380c, 23);
+ MD5STEP(F3, a, b, c, d, x[1] + 0xa4beea44, 4);
+ MD5STEP(F3, d, a, b, c, x[4] + 0x4bdecfa9, 11);
+ MD5STEP(F3, c, d, a, b, x[7] + 0xf6bb4b60, 16);
+ MD5STEP(F3, b, c, d, a, x[10] + 0xbebfbc70, 23);
+ MD5STEP(F3, a, b, c, d, x[13] + 0x289b7ec6, 4);
+ MD5STEP(F3, d, a, b, c, x[0] + 0xeaa127fa, 11);
+ MD5STEP(F3, c, d, a, b, x[3] + 0xd4ef3085, 16);
+ MD5STEP(F3, b, c, d, a, x[6] + 0x04881d05, 23);
+ MD5STEP(F3, a, b, c, d, x[9] + 0xd9d4d039, 4);
+ MD5STEP(F3, d, a, b, c, x[12] + 0xe6db99e5, 11);
+ MD5STEP(F3, c, d, a, b, x[15] + 0x1fa27cf8, 16);
+ MD5STEP(F3, b, c, d, a, x[2] + 0xc4ac5665, 23);
+
+ MD5STEP(F4, a, b, c, d, x[0] + 0xf4292244, 6);
+ MD5STEP(F4, d, a, b, c, x[7] + 0x432aff97, 10);
+ MD5STEP(F4, c, d, a, b, x[14] + 0xab9423a7, 15);
+ MD5STEP(F4, b, c, d, a, x[5] + 0xfc93a039, 21);
+ MD5STEP(F4, a, b, c, d, x[12] + 0x655b59c3, 6);
+ MD5STEP(F4, d, a, b, c, x[3] + 0x8f0ccc92, 10);
+ MD5STEP(F4, c, d, a, b, x[10] + 0xffeff47d, 15);
+ MD5STEP(F4, b, c, d, a, x[1] + 0x85845dd1, 21);
+ MD5STEP(F4, a, b, c, d, x[8] + 0x6fa87e4f, 6);
+ MD5STEP(F4, d, a, b, c, x[15] + 0xfe2ce6e0, 10);
+ MD5STEP(F4, c, d, a, b, x[6] + 0xa3014314, 15);
+ MD5STEP(F4, b, c, d, a, x[13] + 0x4e0811a1, 21);
+ MD5STEP(F4, a, b, c, d, x[4] + 0xf7537e82, 6);
+ MD5STEP(F4, d, a, b, c, x[11] + 0xbd3af235, 10);
+ MD5STEP(F4, c, d, a, b, x[2] + 0x2ad7d2bb, 15);
+ MD5STEP(F4, b, c, d, a, x[9] + 0xeb86d391, 21);
+
+#undef F1
+#undef F2
+#undef F3
+#undef F4
+
+ /* Update chaining vars */
+ ctx->h0 += a;
+ ctx->h1 += b;
+ ctx->h2 += c;
+ ctx->h3 += d;
+}
+
+/* Update the message digest with the contents of the buffer (SHA-1) */
+static void sha1_write(SHA1_CONTEXT *ctx, const unsigned char *buf, size_t len)
+{
+ if (ctx->count == 64) { /* flush the buffer */
+ sha1_transform(ctx, ctx->buf);
+ ctx->count = 0;
+ ctx->nblocks++;
+ }
+ if (!buf)
+ return;
+ if (ctx->count) {
+ for (; len && ctx->count < 64; len--)
+ ctx->buf[ctx->count++] = *buf++;
+ sha1_write(ctx, NULL, 0);
+ if (!len)
+ return;
+ }
+
+ while (len >= 64) {
+ sha1_transform(ctx, buf);
+ ctx->count = 0;
+ ctx->nblocks++;
+ len -= 64;
+ buf += 64;
+ }
+ for (; len && ctx->count < 64; len--)
+ ctx->buf[ctx->count++] = *buf++;
+}
+
+/* Update the message digest with the contents of the buffer (MD5) */
+void md5_write(MD5_CONTEXT *ctx, const unsigned char *buf, size_t len)
+{
+ uint32_t t;
+
+ /* Update bitcount */
+ t = ctx->bits[0];
+ if ((ctx->bits[0] = t + ((uint32_t)len << 3)) < t)
+ ctx->bits[1]++; /* carry from low to high */
+ ctx->bits[1] += len >> 29;
+
+ t = (t >> 3) & 0x3f; /* bytes already in shsInfo->data */
+
+ /* Handle any leading odd-sized chunks */
+ if (t) {
+ unsigned char *p = ctx->buf + t;
+
+ t = 64 - t;
+ if (len < t) {
+ memcpy(p, buf, len);
+ return;
+ }
+ memcpy(p, buf, t);
+ byte_reverse(ctx->buf, 16);
+ md5_transform(ctx, ctx->buf);
+ buf += t;
+ len -= t;
+ }
+
+ /* Process data in 64-byte chunks */
+ while (len >= 64) {
+ memcpy(ctx->buf, buf, 64);
+ byte_reverse(ctx->buf, 16);
+ md5_transform(ctx, ctx->buf);
+ buf += 64;
+ len -= 64;
+ }
+
+ /* Handle any remaining bytes of data. */
+ memcpy(ctx->buf, buf, len);
+}
+
+/* The routine final terminates the computation and returns the digest (SHA-1) */
+static void sha1_final(SHA1_CONTEXT *ctx)
+{
+ uint32_t t, msb, lsb;
+ unsigned char *p;
+
+ sha1_write(ctx, NULL, 0); /* flush */;
+
+ t = ctx->nblocks;
+ /* multiply by 64 to make a byte count */
+ lsb = t << 6;
+ msb = t >> 26;
+ /* add the count */
+ t = lsb;
+ if ((lsb += ctx->count) < t)
+ msb++;
+ /* multiply by 8 to make a bit count */
+ t = lsb;
+ lsb <<= 3;
+ msb <<= 3;
+ msb |= t >> 29;
+
+ if (ctx->count < 56) { /* enough room */
+ ctx->buf[ctx->count++] = 0x80; /* pad */
+ while (ctx->count < 56)
+ ctx->buf[ctx->count++] = 0; /* pad */
+ } else { /* need one extra block */
+ ctx->buf[ctx->count++] = 0x80; /* pad character */
+ while (ctx->count < 64)
+ ctx->buf[ctx->count++] = 0;
+ sha1_write(ctx, NULL, 0); /* flush */;
+ memset(ctx->buf, 0, 56); /* fill next block with zeroes */
+ }
+ /* append the 64 bit count */
+ ctx->buf[56] = msb >> 24;
+ ctx->buf[57] = msb >> 16;
+ ctx->buf[58] = msb >> 8;
+ ctx->buf[59] = msb;
+ ctx->buf[60] = lsb >> 24;
+ ctx->buf[61] = lsb >> 16;
+ ctx->buf[62] = lsb >> 8;
+ ctx->buf[63] = lsb;
+ sha1_transform(ctx, ctx->buf);
+
+ p = ctx->buf;
+#ifdef BIG_ENDIAN_HOST
+#define X(a) do { *(uint32_t*)p = ctx->h##a ; p += 4; } while(0)
+#else /* little endian */
+#define X(a) do { *p++ = ctx->h##a >> 24; *p++ = ctx->h##a >> 16; \
+ *p++ = ctx->h##a >> 8; *p++ = ctx->h##a; } while(0)
+#endif
+ X(0);
+ X(1);
+ X(2);
+ X(3);
+ X(4);
+#undef X
+}
+
+/* The routine final terminates the computation and returns the digest (MD5) */
+static void md5_final(MD5_CONTEXT *ctx)
+{
+ unsigned count;
+ unsigned char *p;
+
+ /* Compute number of bytes mod 64 */
+ count = (ctx->bits[0] >> 3) & 0x3F;
+
+ /* Set the first char of padding to 0x80.
+ * This is safe since there is always at least one byte free
+ */
+ p = ctx->buf + count;
+ *p++ = 0x80;
+
+ /* Bytes of padding needed to make 64 bytes */
+ count = 64 - 1 - count;
+
+ /* Pad out to 56 mod 64 */
+ if (count < 8) {
+ /* Two lots of padding: Pad the first block to 64 bytes */
+ memset(p, 0, count);
+ byte_reverse(ctx->buf, 16);
+ md5_transform(ctx, ctx->buf);
+
+ /* Now fill the next block with 56 bytes */
+ memset(ctx->buf, 0, 56);
+ } else {
+ /* Pad block to 56 bytes */
+ memset(p, 0, count - 8);
+ }
+ byte_reverse(ctx->buf, 14);
+
+ /* append the 64 bit count */
+ ctx->buf[56] = ctx->bits[0];
+ ctx->buf[57] = ctx->bits[0] >> 8;
+ ctx->buf[58] = ctx->bits[0] >> 16;
+ ctx->buf[59] = ctx->bits[0] >> 24;
+ ctx->buf[60] = ctx->bits[1];
+ ctx->buf[61] = ctx->bits[1] >> 8;
+ ctx->buf[62] = ctx->bits[1] >> 16;
+ ctx->buf[63] = ctx->bits[1] >> 24;
+
+ md5_transform(ctx, ctx->buf);
+
+ p = ctx->buf;
+#ifndef BIG_ENDIAN_HOST
+#define X(a) do { *(uint32_t*)p = ctx->h##a ; p += 4; } while(0)
+#else /* big endian */
+#define X(a) do { *p++ = ctx->h##a >> 24; *p++ = ctx->h##a >> 16; \
+ *p++ = ctx->h##a >> 8; *p++ = ctx->h##a; } while(0)
+#endif
+ X(0);
+ X(1);
+ X(2);
+ X(3);
+#undef X
+}
+
+DWORD WINAPI SumThread(void* param)
+{
+ HANDLE h = INVALID_HANDLE_VALUE;
+ DWORD rSize = 0, LastRefresh = 0;
+ uint64_t rb;
+ char buffer[4096];
+ char str[41];
+ SHA1_CONTEXT sha1_ctx;
+ MD5_CONTEXT md5_ctx;
+ int i, r = -1;
+ float format_percent = 0.0f;
+
+ if (image_path == NULL)
+ goto out;
+
+ uprintf("\r\nComputing checksum for '%s'...", image_path);
+ h = CreateFileU(image_path, GENERIC_READ, FILE_SHARE_READ, NULL,
+ OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL);
+ if (h == INVALID_HANDLE_VALUE) {
+ uprintf("Could not open file: %s", WindowsErrorString());
+ FormatStatus = ERROR_SEVERITY_ERROR | FAC(FACILITY_STORAGE) | ERROR_OPEN_FAILED;
+ goto out;
+ }
+
+ sha1_init(&sha1_ctx);
+ md5_init(&md5_ctx);
+
+ for (rb = 0; ; rb += rSize) {
+ if (GetTickCount() > LastRefresh + 25) {
+ LastRefresh = GetTickCount();
+ format_percent = (100.0f*rb) / (1.0f*iso_report.projected_size);
+ PrintInfo(0, MSG_271, format_percent);
+ SendMessage(hProgress, PBM_SETPOS, (WPARAM)((format_percent/100.0f)*MAX_PROGRESS), 0);
+ SetTaskbarProgressValue(rb, iso_report.projected_size);
+ }
+ CHECK_FOR_USER_CANCEL;
+ if (!ReadFile(h, buffer, sizeof(buffer), &rSize, NULL)) {
+ FormatStatus = ERROR_SEVERITY_ERROR | FAC(FACILITY_STORAGE) | ERROR_READ_FAULT;
+ uprintf(" Read error: %s", WindowsErrorString());
+ goto out;
+ }
+ if (rSize == 0)
+ break;
+ sha1_write(&sha1_ctx, buffer, (size_t)rSize);
+ md5_write(&md5_ctx, buffer, (size_t)rSize);
+ }
+
+ sha1_final(&sha1_ctx);
+ md5_final(&md5_ctx);
+
+ for (i = 0; i < 16; i++)
+ safe_sprintf(&str[2 * i], sizeof(str) - 2 * i, "%02x", md5_ctx.buf[i]);
+ uprintf(" MD5:\t%s", str);
+ for (i = 0; i < 20; i++)
+ safe_sprintf(&str[2*i], sizeof(str) - 2*i, "%02x", sha1_ctx.buf[i]);
+ uprintf(" SHA1:\t%s", str);
+ r = 0;
+
+out:
+ safe_closehandle(h);
+ PostMessage(hMainDialog, UM_FORMAT_COMPLETED, (WPARAM)FALSE, 0);
+ ExitThread(r);
+}
diff --git a/src/format.c b/src/format.c
index e37ec8ef..a5550338 100644
--- a/src/format.c
+++ b/src/format.c
@@ -1481,7 +1481,6 @@ void update_progress(const uint64_t processed_bytes)
* Unlock the volume.
* Close the volume handle.
*/
-#define CHECK_FOR_USER_CANCEL if (IS_ERROR(FormatStatus)) goto out
DWORD WINAPI FormatThread(void* param)
{
int i, r, pt, bt, fs, dt;
@@ -1972,7 +1971,7 @@ out:
free(guid_volume);
}
}
- PostMessage(hMainDialog, UM_FORMAT_COMPLETED, 0, 0);
+ PostMessage(hMainDialog, UM_FORMAT_COMPLETED, (WPARAM)TRUE, 0);
ExitThread(0);
}
@@ -2074,6 +2073,6 @@ out:
safe_free(buffer);
safe_closehandle(hDestImage);
safe_unlockclose(hPhysicalDrive);
- PostMessage(hMainDialog, UM_FORMAT_COMPLETED, 0, 0);
+ PostMessage(hMainDialog, UM_FORMAT_COMPLETED, (WPARAM)TRUE, 0);
ExitThread(0);
}
diff --git a/src/rufus.c b/src/rufus.c
index b0442317..8d7f6038 100644
--- a/src/rufus.c
+++ b/src/rufus.c
@@ -135,7 +135,7 @@ HWND hLogDlg = NULL, hProgress = NULL, hInfo, hDiskID;
BOOL use_own_c32[NB_OLD_C32] = {FALSE, FALSE}, detect_fakes = TRUE, mbr_selected_by_user = FALSE;
BOOL iso_op_in_progress = FALSE, format_op_in_progress = FALSE, right_to_left_mode = FALSE;
BOOL enable_HDDs = FALSE, advanced_mode = TRUE, force_update = FALSE, use_fake_units = TRUE;
-BOOL allow_dual_uefi_bios = FALSE, enable_vmdk = FALSE, togo_mode = TRUE;
+BOOL allow_dual_uefi_bios = FALSE, enable_vmdk = FALSE, togo_mode = TRUE, no_confirmation_on_cancel = FALSE;
int dialog_showing = 0, lang_button_id = 0;
uint16_t rufus_version[3], embedded_sl_version[2];
char embedded_sl_version_str[2][12] = { "?.??", "?.??" };
@@ -2091,8 +2091,8 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA
PF_INIT(SHChangeNotifyDeregister, Shell32);
EnableWindow(GetDlgItem(hDlg, IDCANCEL), FALSE);
if (format_thid != NULL) {
- if (MessageBoxU(hMainDialog, lmprintf(MSG_105), lmprintf(MSG_049),
- MB_YESNO|MB_ICONWARNING|MB_IS_RTL) == IDYES) {
+ if ((no_confirmation_on_cancel) || (MessageBoxU(hMainDialog, lmprintf(MSG_105), lmprintf(MSG_049),
+ MB_YESNO|MB_ICONWARNING|MB_IS_RTL) == IDYES)) {
// Operation may have completed in the meantime
if (format_thid != NULL) {
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_CANCELLED;
@@ -2107,6 +2107,7 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA
} else {
EnableWindow(GetDlgItem(hDlg, IDCANCEL), TRUE);
}
+ no_confirmation_on_cancel = FALSE;
return (INT_PTR)TRUE;
}
if ((pfSHChangeNotifyDeregister != NULL) && (ulRegister != 0))
@@ -2330,6 +2331,7 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA
}
FormatStatus = 0;
format_op_in_progress = TRUE;
+ no_confirmation_on_cancel = FALSE;
// Reset all progress bars
SendMessage(hProgress, PBM_SETSTATE, (WPARAM)PBST_NORMAL, 0);
SetTaskbarProgressState(TASKBAR_NORMAL);
@@ -2378,13 +2380,12 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA
// Disable all controls except cancel
EnableControls(FALSE);
DeviceNum = (DWORD)ComboBox_GetItemData(hDeviceList, nDeviceIndex);
- FormatStatus = 0;
InitProgress(FALSE);
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, 0, 0);
+ PostMessage(hMainDialog, UM_FORMAT_COMPLETED, (WPARAM)FALSE, 0);
}
uprintf("\r\nFormat operation started");
PrintInfo(0, -1);
@@ -2478,8 +2479,10 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA
SendMessage(FindWindowA(MAKEINTRESOURCEA(32770), lmprintf(MSG_049)), WM_COMMAND, IDYES, 0);
EnableWindow(GetDlgItem(hMainDialog, IDCANCEL), TRUE);
EnableControls(TRUE);
- uprintf("\r\n");
- GetUSBDevices(DeviceNum);
+ if (wParam) {
+ uprintf("\r\n");
+ GetUSBDevices(DeviceNum);
+ }
if (!IS_ERROR(FormatStatus)) {
// This is the only way to achieve instantaneous progress transition to 100%
SendMessage(hProgress, PBM_SETRANGE, 0, ((MAX_PROGRESS+1)<<16) & 0xFFFF0000);
@@ -2919,6 +2922,37 @@ relaunch:
GetUSBDevices(0);
continue;
}
+ // Alt-M => Compute Message Digests (MD5, SHA-1) on the current image
+ if ((msg.message == WM_SYSKEYDOWN) && (msg.wParam == 'M')) {
+ if ((format_thid != NULL) || (image_path == NULL))
+ continue;
+ FormatStatus = 0;
+ format_op_in_progress = TRUE;
+ no_confirmation_on_cancel = TRUE;
+ // Reset all progress bars
+ SendMessage(hProgress, PBM_SETSTATE, (WPARAM)PBST_NORMAL, 0);
+ SetTaskbarProgressState(TASKBAR_NORMAL);
+ SetTaskbarProgressValue(0, MAX_PROGRESS);
+ SendMessage(hProgress, PBM_SETPOS, 0, 0);
+ // Disable all controls except cancel
+ EnableControls(FALSE);
+ InitProgress(FALSE);
+ format_thid = CreateThread(NULL, 0, SumThread, NULL, 0, NULL);
+ if (format_thid != NULL) {
+ PrintInfo(0, -1);
+ timer = 0;
+ safe_sprintf(szTimer, sizeof(szTimer), "00:00:00");
+ SendMessageA(GetDlgItem(hMainDialog, IDC_STATUS), SB_SETTEXTA,
+ SBT_OWNERDRAW | 1, (LPARAM)szTimer);
+ SetTimer(hMainDialog, TID_APP_TIMER, 1000, ClockTimer);
+ } else {
+ uprintf("Unable to start checksum thread");
+ FormatStatus = ERROR_SEVERITY_ERROR | FAC(FACILITY_STORAGE) | APPERR(ERROR_CANT_START_THREAD);
+ PostMessage(hMainDialog, UM_FORMAT_COMPLETED, (WPARAM)FALSE, 0);
+ format_op_in_progress = FALSE;
+ }
+ continue;
+ }
// Alt N => Enable NTFS compression
if ((msg.message == WM_SYSKEYDOWN) && (msg.wParam == 'N')) {
enable_ntfs_compression = !enable_ntfs_compression;
@@ -2992,7 +3026,7 @@ relaunch:
uprintf("Unable to start VHD save thread");
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR(ERROR_CANT_START_THREAD);
safe_free(vhd_save.path);
- PostMessage(hMainDialog, UM_FORMAT_COMPLETED, 0, 0);
+ PostMessage(hMainDialog, UM_FORMAT_COMPLETED, (WPARAM)FALSE, 0);
format_op_in_progress = FALSE;
}
} else {
@@ -3004,7 +3038,7 @@ relaunch:
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_FILE_TOO_LARGE;
}
safe_free(vhd_save.path);
- PostMessage(hMainDialog, UM_FORMAT_COMPLETED, 0, 0);
+ PostMessage(hMainDialog, UM_FORMAT_COMPLETED, (WPARAM)FALSE, 0);
format_op_in_progress = FALSE;
}
}
diff --git a/src/rufus.h b/src/rufus.h
index afcea481..03470392 100644
--- a/src/rufus.h
+++ b/src/rufus.h
@@ -83,6 +83,7 @@
#define IsChecked(CheckBox_ID) (IsDlgButtonChecked(hMainDialog, CheckBox_ID) == BST_CHECKED)
#define MB_IS_RTL (right_to_left_mode?MB_RTLREADING:0)
#define IDD_OFFSET ((right_to_left_mode?100:0) + ((nWindowsVersion <= WINDOWS_XP)?50:0))
+#define CHECK_FOR_USER_CANCEL if (IS_ERROR(FormatStatus)) goto out
#define safe_free(p) do {free((void*)p); p = NULL;} while(0)
#define safe_min(a, b) min((size_t)(a), (size_t)(b))
@@ -252,7 +253,6 @@ typedef struct {
char reactos_path[128]; /* path to the ISO's freeldr.sys or setupldr.sys */
char install_wim_path[64]; /* path to install.wim or install.swm */
uint64_t projected_size;
- uint64_t src_size;
uint8_t winpe;
uint8_t has_efi;
BOOLEAN has_4GB_file;
@@ -441,6 +441,7 @@ extern void LostTranslatorCheck(void);
DWORD WINAPI FormatThread(void* param);
DWORD WINAPI SaveImageThread(void* param);
+DWORD WINAPI SumThread(void* param);
static __inline BOOL UnlockDrive(HANDLE hDrive) {
DWORD size;
diff --git a/src/rufus.rc b/src/rufus.rc
index fad822a0..e13ad17e 100644
--- a/src/rufus.rc
+++ b/src/rufus.rc
@@ -32,7 +32,7 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
IDD_DIALOG DIALOGEX 12, 12, 242, 376
STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU
-CAPTION "Rufus 2.3.684"
+CAPTION "Rufus 2.3.685"
FONT 8, "Segoe UI", 400, 0, 0x1
BEGIN
LTEXT "Device",IDS_DEVICE_TXT,9,6,200,8
@@ -157,7 +157,7 @@ END
IDD_DIALOG_XP DIALOGEX 12, 12, 242, 376
STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU
-CAPTION "Rufus 2.3.684"
+CAPTION "Rufus 2.3.685"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
LTEXT "Device",IDS_DEVICE_TXT,9,6,200,8
@@ -283,7 +283,7 @@ END
IDD_DIALOG_RTL DIALOGEX 12, 12, 242, 376
STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU
EXSTYLE WS_EX_RTLREADING | WS_EX_APPWINDOW | WS_EX_LAYOUTRTL
-CAPTION "Rufus 2.3.684"
+CAPTION "Rufus 2.3.685"
FONT 8, "Segoe UI", 400, 0, 0x1
BEGIN
LTEXT "Device",IDS_DEVICE_TXT,9,6,200,8
@@ -415,7 +415,7 @@ END
IDD_DIALOG_RTL_XP DIALOGEX 12, 12, 242, 376
STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU
EXSTYLE WS_EX_RTLREADING | WS_EX_APPWINDOW | WS_EX_LAYOUTRTL
-CAPTION "Rufus 2.3.684"
+CAPTION "Rufus 2.3.685"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
LTEXT "Device",IDS_DEVICE_TXT,9,6,200,8
@@ -671,8 +671,8 @@ END
//
VS_VERSION_INFO VERSIONINFO
- FILEVERSION 2,3,684,0
- PRODUCTVERSION 2,3,684,0
+ FILEVERSION 2,3,685,0
+ PRODUCTVERSION 2,3,685,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@@ -689,13 +689,13 @@ BEGIN
BEGIN
VALUE "CompanyName", "Akeo Consulting (http://akeo.ie)"
VALUE "FileDescription", "Rufus"
- VALUE "FileVersion", "2.3.684"
+ VALUE "FileVersion", "2.3.685"
VALUE "InternalName", "Rufus"
VALUE "LegalCopyright", "© 2011-2015 Pete Batard (GPL v3)"
VALUE "LegalTrademarks", "http://www.gnu.org/copyleft/gpl.html"
VALUE "OriginalFilename", "rufus.exe"
VALUE "ProductName", "Rufus"
- VALUE "ProductVersion", "2.3.684"
+ VALUE "ProductVersion", "2.3.685"
END
END
BLOCK "VarFileInfo"