VeraCrypt
aboutsummaryrefslogtreecommitdiff
path: root/src/Boot
diff options
context:
space:
mode:
Diffstat (limited to 'src/Boot')
-rw-r--r--src/Boot/Windows/Bios.h64
-rw-r--r--src/Boot/Windows/Boot.vcproj492
-rw-r--r--src/Boot/Windows/BootCommon.h164
-rw-r--r--src/Boot/Windows/BootConfig.cpp204
-rw-r--r--src/Boot/Windows/BootConfig.h92
-rw-r--r--src/Boot/Windows/BootConsoleIo.cpp678
-rw-r--r--src/Boot/Windows/BootConsoleIo.h144
-rw-r--r--src/Boot/Windows/BootCrt.asm54
-rw-r--r--src/Boot/Windows/BootDebug.cpp362
-rw-r--r--src/Boot/Windows/BootDebug.h120
-rw-r--r--src/Boot/Windows/BootDefs.h398
-rw-r--r--src/Boot/Windows/BootDiskIo.cpp982
-rw-r--r--src/Boot/Windows/BootDiskIo.h240
-rw-r--r--src/Boot/Windows/BootEncryptedIo.cpp264
-rw-r--r--src/Boot/Windows/BootEncryptedIo.h44
-rw-r--r--src/Boot/Windows/BootMain.cpp2538
-rw-r--r--src/Boot/Windows/BootMain.h68
-rw-r--r--src/Boot/Windows/BootMemory.cpp172
-rw-r--r--src/Boot/Windows/BootMemory.h56
-rw-r--r--src/Boot/Windows/BootSector.asm488
-rw-r--r--src/Boot/Windows/BootStrings.h40
-rw-r--r--src/Boot/Windows/Decompressor.c130
-rw-r--r--src/Boot/Windows/IntFilter.cpp1290
-rw-r--r--src/Boot/Windows/IntFilter.h40
-rw-r--r--src/Boot/Windows/Makefile404
-rw-r--r--src/Boot/Windows/Platform.cpp460
-rw-r--r--src/Boot/Windows/Platform.h232
27 files changed, 5110 insertions, 5110 deletions
diff --git a/src/Boot/Windows/Bios.h b/src/Boot/Windows/Bios.h
index 314b1a62..e6f9ec89 100644
--- a/src/Boot/Windows/Bios.h
+++ b/src/Boot/Windows/Bios.h
@@ -1,32 +1,32 @@
-/*
- Derived from source code of TrueCrypt 7.1a, which is
- Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed
- by the TrueCrypt License 3.0.
-
- Modifications and additions to the original source code (contained in this file)
- and all other portions of this file are Copyright (c) 2013-2016 IDRIX
- and are governed by the Apache License 2.0 the full text of which is
- contained in the file License.txt included in VeraCrypt binary and source
- code distribution packages.
-*/
-
-#ifndef TC_HEADER_Boot_Bios
-#define TC_HEADER_Boot_Bios
-
-#include "Platform.h"
-
-#define TC_LB_SIZE_BIT_SHIFT_DIVISOR 9
-
-#define TC_FIRST_BIOS_DRIVE 0x80
-#define TC_LAST_BIOS_DRIVE 0x8f
-#define TC_INVALID_BIOS_DRIVE (TC_FIRST_BIOS_DRIVE - 1)
-
-enum
-{
- BiosResultSuccess = 0x00,
- BiosResultInvalidFunction = 0x01
-};
-
-typedef byte BiosResult;
-
-#endif // TC_HEADER_Boot_Bios
+/*
+ Derived from source code of TrueCrypt 7.1a, which is
+ Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed
+ by the TrueCrypt License 3.0.
+
+ Modifications and additions to the original source code (contained in this file)
+ and all other portions of this file are Copyright (c) 2013-2016 IDRIX
+ and are governed by the Apache License 2.0 the full text of which is
+ contained in the file License.txt included in VeraCrypt binary and source
+ code distribution packages.
+*/
+
+#ifndef TC_HEADER_Boot_Bios
+#define TC_HEADER_Boot_Bios
+
+#include "Platform.h"
+
+#define TC_LB_SIZE_BIT_SHIFT_DIVISOR 9
+
+#define TC_FIRST_BIOS_DRIVE 0x80
+#define TC_LAST_BIOS_DRIVE 0x8f
+#define TC_INVALID_BIOS_DRIVE (TC_FIRST_BIOS_DRIVE - 1)
+
+enum
+{
+ BiosResultSuccess = 0x00,
+ BiosResultInvalidFunction = 0x01
+};
+
+typedef byte BiosResult;
+
+#endif // TC_HEADER_Boot_Bios
diff --git a/src/Boot/Windows/Boot.vcproj b/src/Boot/Windows/Boot.vcproj
index d0b40f1a..64ad48ec 100644
--- a/src/Boot/Windows/Boot.vcproj
+++ b/src/Boot/Windows/Boot.vcproj
@@ -1,246 +1,246 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
- ProjectType="Visual C++"
- Version="9.00"
- Name="Boot"
- ProjectGUID="{8B7F059F-E4C7-4E11-88F5-EE8B8433072E}"
- RootNamespace="Boot"
- Keyword="MakeFileProj"
- TargetFrameworkVersion="131072"
- >
- <Platforms>
- <Platform
- Name="Win32"
- />
- </Platforms>
- <ToolFiles>
- </ToolFiles>
- <Configurations>
- <Configuration
- Name="Release|Win32"
- OutputDirectory="$(ConfigurationName)"
- IntermediateDirectory="$(ConfigurationName)"
- ConfigurationType="0"
- >
- <Tool
- Name="VCNMakeTool"
- BuildCommandLine="md Release 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1&#x0D;&#x0A;&#x0D;&#x0A;md Release_SHA2 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_PRF=SHA2&#x0D;&#x0A;&#x0D;&#x0A;md Release_AES 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=AES&#x0D;&#x0A;&#x0D;&#x0A;md Release_AES_SHA2 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=AES SINGLE_PRF=SHA2&#x0D;&#x0A;&#x0D;&#x0A;md Release_Serpent 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=SERPENT&#x0D;&#x0A;&#x0D;&#x0A;md Release_Serpent_SHA2 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=SERPENT SINGLE_PRF=SHA2&#x0D;&#x0A;&#x0D;&#x0A;md Release_Twofish 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=TWOFISH&#x0D;&#x0A;&#x0D;&#x0A;md Release_Twofish_SHA2 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=TWOFISH SINGLE_PRF=SHA2&#x0D;&#x0A;&#x0D;&#x0A;md Rescue 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 RESCUE_DISK=1&#x0D;&#x0A;&#x0D;&#x0A;md Rescue_SHA2 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 RESCUE_DISK=1 SINGLE_PRF=SHA2&#x0D;&#x0A;&#x0D;&#x0A;md Rescue_AES 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=AES RESCUE_DISK=1&#x0D;&#x0A;&#x0D;&#x0A;md Rescue_AES_SHA2 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=AES RESCUE_DISK=1 SINGLE_PRF=SHA2&#x0D;&#x0A;&#x0D;&#x0A;md Rescue_Serpent 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=SERPENT RESCUE_DISK=1&#x0D;&#x0A;&#x0D;&#x0A;md Rescue_Serpent_SHA2 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=SERPENT RESCUE_DISK=1 SINGLE_PRF=SHA2&#x0D;&#x0A;&#x0D;&#x0A;md Rescue_Twofish 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=TWOFISH RESCUE_DISK=1&#x0D;&#x0A;&#x0D;&#x0A;md Rescue_Twofish_SHA2 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=TWOFISH RESCUE_DISK=1 SINGLE_PRF=SHA2"
- ReBuildCommandLine="del /q /s Release &gt;NUL:&#x0D;&#x0A;md Release 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1&#x0D;&#x0A;&#x0D;&#x0A;del /q /s Release_SHA2 &gt;NUL:&#x0D;&#x0A;md Release_SHA2 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_PRF=SHA2&#x0D;&#x0A;&#x0D;&#x0A;del /q /s Release_AES &gt;NUL:&#x0D;&#x0A;md Release_AES 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=AES&#x0D;&#x0A;&#x0D;&#x0A;del /q /s Release_AES_SHA2 &gt;NUL:&#x0D;&#x0A;md Release_AES_SHA2 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=AES SINGLE_PRF=SHA2&#x0D;&#x0A;&#x0D;&#x0A;del /q /s Release_Serpent &gt;NUL:&#x0D;&#x0A;md Release_Serpent 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=SERPENT&#x0D;&#x0A;&#x0D;&#x0A;del /q /s Release_Serpent_SHA2 &gt;NUL:&#x0D;&#x0A;md Release_Serpent_SHA2 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=SERPENT SINGLE_PRF=SHA2&#x0D;&#x0A;&#x0D;&#x0A;del /q /s Release_Twofish &gt;NUL:&#x0D;&#x0A;md Release_Twofish 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=TWOFISH&#x0D;&#x0A;&#x0D;&#x0A;del /q /s Release_Twofish_SHA2 &gt;NUL:&#x0D;&#x0A;md Release_Twofish_SHA2 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=TWOFISH SINGLE_PRF=SHA2&#x0D;&#x0A;&#x0D;&#x0A;del /q /s Rescue &gt;NUL:&#x0D;&#x0A;md Rescue 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 RESCUE_DISK=1&#x0D;&#x0A;&#x0D;&#x0A;del /q /s Rescue_SHA2 &gt;NUL:&#x0D;&#x0A;md Rescue_SHA2 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 RESCUE_DISK=1 SINGLE_PRF=SHA2&#x0D;&#x0A;&#x0D;&#x0A;del /q /s Rescue_AES &gt;NUL:&#x0D;&#x0A;md Rescue_AES 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=AES RESCUE_DISK=1&#x0D;&#x0A;&#x0D;&#x0A;del /q /s Rescue_AES_SHA2 &gt;NUL:&#x0D;&#x0A;md Rescue_AES_SHA2 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=AES RESCUE_DISK=1 SINGLE_PRF=SHA2&#x0D;&#x0A;&#x0D;&#x0A;del /q /s Rescue_Serpent &gt;NUL:&#x0D;&#x0A;md Rescue_Serpent 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=SERPENT RESCUE_DISK=1&#x0D;&#x0A;&#x0D;&#x0A;del /q /s Rescue_Serpent_SHA2 &gt;NUL:&#x0D;&#x0A;md Rescue_Serpent_SHA2 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=SERPENT RESCUE_DISK=1 SINGLE_PRF=SHA2&#x0D;&#x0A;&#x0D;&#x0A;del /q /s Rescue_Twofish &gt;NUL:&#x0D;&#x0A;md Rescue_Twofish 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=TWOFISH RESCUE_DISK=1&#x0D;&#x0A;&#x0D;&#x0A;del /q /s Rescue_Twofish_SHA2 &gt;NUL:&#x0D;&#x0A;md Rescue_Twofish_SHA2 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=TWOFISH RESCUE_DISK=1 SINGLE_PRF=SHA2"
- CleanCommandLine="del /q /s Release Release_AES Release_Serpent Release_Twofish Rescue Rescue_AES Rescue_Serpent Rescue_Twofish &gt;NUL:&#x0D;&#x0A;del /q /s Release_SHA2 Release_AES_SHA2 Release_Serpent_SHA2 Release_Twofish_SHA2 Rescue_SHA2 Rescue_AES_SHA2 Rescue_Serpent_SHA2 Rescue_Twofish_SHA2 &gt;NUL:&#x0D;&#x0A;"
- Output="Release\BootLoader.com"
- PreprocessorDefinitions="WIN32;NDEBUG"
- IncludeSearchPath="&quot;$(SolutionDir)&quot;;&quot;$(SolutionDir)\Common&quot;;&quot;$(SolutionDir)\Crypto&quot;;&quot;$(MSVC16_ROOT)\Include&quot;"
- ForcedIncludes=""
- AssemblySearchPath=""
- ForcedUsingAssemblies=""
- CompileAsManaged=""
- />
- </Configuration>
- <Configuration
- Name="Release Loader|Win32"
- OutputDirectory="$(ConfigurationName)"
- IntermediateDirectory="$(ConfigurationName)"
- ConfigurationType="0"
- >
- <Tool
- Name="VCNMakeTool"
- BuildCommandLine="md Release 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1&#x0D;&#x0A;&#x0D;&#x0A;md Release_AES 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=AES&#x0D;&#x0A;&#x0D;&#x0A;md Release_Serpent 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=SERPENT&#x0D;&#x0A;&#x0D;&#x0A;md Release_Twofish 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=TWOFISH"
- ReBuildCommandLine="del /q /s Release &gt;NUL:&#x0D;&#x0A;md Release 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1&#x0D;&#x0A;&#x0D;&#x0A;del /q /s Release_AES &gt;NUL:&#x0D;&#x0A;md Release_AES 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=AES&#x0D;&#x0A;&#x0D;&#x0A;del /q /s Release_Serpent &gt;NUL:&#x0D;&#x0A;md Release_Serpent 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=SERPENT&#x0D;&#x0A;&#x0D;&#x0A;del /q /s Release_Twofish &gt;NUL:&#x0D;&#x0A;md Release_Twofish 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=TWOFISH"
- CleanCommandLine="del /q /s Release Release_AES Release_Serpent Release_Twofish &gt;NUL:"
- Output="Release\BootLoader.com"
- PreprocessorDefinitions="WIN32;NDEBUG"
- IncludeSearchPath="&quot;$(SolutionDir)&quot;;&quot;$(SolutionDir)\Common&quot;;&quot;$(SolutionDir)\Crypto&quot;;&quot;$(MSVC16_ROOT)\Include&quot;"
- ForcedIncludes=""
- AssemblySearchPath=""
- ForcedUsingAssemblies=""
- CompileAsManaged=""
- />
- </Configuration>
- </Configurations>
- <References>
- </References>
- <Files>
- <Filter
- Name="Source Files"
- Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
- UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
- >
- <File
- RelativePath=".\BootConfig.cpp"
- >
- </File>
- <File
- RelativePath=".\BootConsoleIo.cpp"
- >
- </File>
- <File
- RelativePath=".\BootCrt.asm"
- >
- </File>
- <File
- RelativePath=".\BootDebug.cpp"
- >
- </File>
- <File
- RelativePath=".\BootDiskIo.cpp"
- >
- </File>
- <File
- RelativePath=".\BootEncryptedIo.cpp"
- >
- </File>
- <File
- RelativePath=".\BootMain.cpp"
- >
- </File>
- <File
- RelativePath=".\BootMemory.cpp"
- >
- </File>
- <File
- RelativePath=".\BootSector.asm"
- >
- </File>
- <File
- RelativePath=".\Decompressor.c"
- >
- </File>
- <File
- RelativePath=".\IntFilter.cpp"
- >
- </File>
- <File
- RelativePath=".\Platform.cpp"
- >
- </File>
- <Filter
- Name="Common"
- >
- <File
- RelativePath="..\..\Common\Crc.c"
- >
- </File>
- <File
- RelativePath="..\..\Common\Crypto.c"
- >
- </File>
- <File
- RelativePath="..\..\Common\Endian.c"
- >
- </File>
- <File
- RelativePath="..\..\Common\Pkcs5.c"
- >
- </File>
- <File
- RelativePath="..\..\Common\Volumes.c"
- >
- </File>
- <File
- RelativePath="..\..\Common\Xts.c"
- >
- </File>
- </Filter>
- <Filter
- Name="Crypto"
- >
- <File
- RelativePath="..\..\Crypto\Aes_hw_cpu.asm"
- >
- </File>
- <File
- RelativePath="..\..\Crypto\AesSmall.c"
- >
- </File>
- <File
- RelativePath="..\..\Crypto\AesSmall_x86.asm"
- >
- </File>
- <File
- RelativePath="..\..\Crypto\Rmd160.c"
- >
- </File>
- <File
- RelativePath="..\..\Crypto\Serpent.c"
- >
- </File>
- <File
- RelativePath="..\..\Crypto\Sha2Small.c"
- >
- </File>
- <File
- RelativePath="..\..\Crypto\Twofish.c"
- >
- </File>
- </Filter>
- </Filter>
- <Filter
- Name="Header Files"
- Filter="h;hpp;hxx;hm;inl;inc;xsd"
- UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
- >
- <File
- RelativePath=".\Bios.h"
- >
- </File>
- <File
- RelativePath=".\BootCommon.h"
- >
- </File>
- <File
- RelativePath=".\BootConfig.h"
- >
- </File>
- <File
- RelativePath=".\BootConsoleIo.h"
- >
- </File>
- <File
- RelativePath=".\BootDebug.h"
- >
- </File>
- <File
- RelativePath=".\BootDefs.h"
- >
- </File>
- <File
- RelativePath=".\BootDiskIo.h"
- >
- </File>
- <File
- RelativePath=".\BootEncryptedIo.h"
- >
- </File>
- <File
- RelativePath=".\BootMain.h"
- >
- </File>
- <File
- RelativePath=".\BootMemory.h"
- >
- </File>
- <File
- RelativePath=".\BootStrings.h"
- >
- </File>
- <File
- RelativePath=".\IntFilter.h"
- >
- </File>
- <File
- RelativePath=".\Platform.h"
- >
- </File>
- </Filter>
- <Filter
- Name="Build Files"
- >
- <File
- RelativePath=".\Makefile"
- >
- </File>
- </Filter>
- </Files>
- <Globals>
- </Globals>
-</VisualStudioProject>
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9.00"
+ Name="Boot"
+ ProjectGUID="{8B7F059F-E4C7-4E11-88F5-EE8B8433072E}"
+ RootNamespace="Boot"
+ Keyword="MakeFileProj"
+ TargetFrameworkVersion="131072"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="0"
+ >
+ <Tool
+ Name="VCNMakeTool"
+ BuildCommandLine="md Release 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1&#x0D;&#x0A;&#x0D;&#x0A;md Release_SHA2 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_PRF=SHA2&#x0D;&#x0A;&#x0D;&#x0A;md Release_AES 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=AES&#x0D;&#x0A;&#x0D;&#x0A;md Release_AES_SHA2 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=AES SINGLE_PRF=SHA2&#x0D;&#x0A;&#x0D;&#x0A;md Release_Serpent 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=SERPENT&#x0D;&#x0A;&#x0D;&#x0A;md Release_Serpent_SHA2 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=SERPENT SINGLE_PRF=SHA2&#x0D;&#x0A;&#x0D;&#x0A;md Release_Twofish 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=TWOFISH&#x0D;&#x0A;&#x0D;&#x0A;md Release_Twofish_SHA2 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=TWOFISH SINGLE_PRF=SHA2&#x0D;&#x0A;&#x0D;&#x0A;md Rescue 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 RESCUE_DISK=1&#x0D;&#x0A;&#x0D;&#x0A;md Rescue_SHA2 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 RESCUE_DISK=1 SINGLE_PRF=SHA2&#x0D;&#x0A;&#x0D;&#x0A;md Rescue_AES 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=AES RESCUE_DISK=1&#x0D;&#x0A;&#x0D;&#x0A;md Rescue_AES_SHA2 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=AES RESCUE_DISK=1 SINGLE_PRF=SHA2&#x0D;&#x0A;&#x0D;&#x0A;md Rescue_Serpent 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=SERPENT RESCUE_DISK=1&#x0D;&#x0A;&#x0D;&#x0A;md Rescue_Serpent_SHA2 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=SERPENT RESCUE_DISK=1 SINGLE_PRF=SHA2&#x0D;&#x0A;&#x0D;&#x0A;md Rescue_Twofish 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=TWOFISH RESCUE_DISK=1&#x0D;&#x0A;&#x0D;&#x0A;md Rescue_Twofish_SHA2 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=TWOFISH RESCUE_DISK=1 SINGLE_PRF=SHA2"
+ ReBuildCommandLine="del /q /s Release &gt;NUL:&#x0D;&#x0A;md Release 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1&#x0D;&#x0A;&#x0D;&#x0A;del /q /s Release_SHA2 &gt;NUL:&#x0D;&#x0A;md Release_SHA2 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_PRF=SHA2&#x0D;&#x0A;&#x0D;&#x0A;del /q /s Release_AES &gt;NUL:&#x0D;&#x0A;md Release_AES 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=AES&#x0D;&#x0A;&#x0D;&#x0A;del /q /s Release_AES_SHA2 &gt;NUL:&#x0D;&#x0A;md Release_AES_SHA2 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=AES SINGLE_PRF=SHA2&#x0D;&#x0A;&#x0D;&#x0A;del /q /s Release_Serpent &gt;NUL:&#x0D;&#x0A;md Release_Serpent 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=SERPENT&#x0D;&#x0A;&#x0D;&#x0A;del /q /s Release_Serpent_SHA2 &gt;NUL:&#x0D;&#x0A;md Release_Serpent_SHA2 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=SERPENT SINGLE_PRF=SHA2&#x0D;&#x0A;&#x0D;&#x0A;del /q /s Release_Twofish &gt;NUL:&#x0D;&#x0A;md Release_Twofish 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=TWOFISH&#x0D;&#x0A;&#x0D;&#x0A;del /q /s Release_Twofish_SHA2 &gt;NUL:&#x0D;&#x0A;md Release_Twofish_SHA2 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=TWOFISH SINGLE_PRF=SHA2&#x0D;&#x0A;&#x0D;&#x0A;del /q /s Rescue &gt;NUL:&#x0D;&#x0A;md Rescue 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 RESCUE_DISK=1&#x0D;&#x0A;&#x0D;&#x0A;del /q /s Rescue_SHA2 &gt;NUL:&#x0D;&#x0A;md Rescue_SHA2 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 RESCUE_DISK=1 SINGLE_PRF=SHA2&#x0D;&#x0A;&#x0D;&#x0A;del /q /s Rescue_AES &gt;NUL:&#x0D;&#x0A;md Rescue_AES 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=AES RESCUE_DISK=1&#x0D;&#x0A;&#x0D;&#x0A;del /q /s Rescue_AES_SHA2 &gt;NUL:&#x0D;&#x0A;md Rescue_AES_SHA2 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=AES RESCUE_DISK=1 SINGLE_PRF=SHA2&#x0D;&#x0A;&#x0D;&#x0A;del /q /s Rescue_Serpent &gt;NUL:&#x0D;&#x0A;md Rescue_Serpent 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=SERPENT RESCUE_DISK=1&#x0D;&#x0A;&#x0D;&#x0A;del /q /s Rescue_Serpent_SHA2 &gt;NUL:&#x0D;&#x0A;md Rescue_Serpent_SHA2 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=SERPENT RESCUE_DISK=1 SINGLE_PRF=SHA2&#x0D;&#x0A;&#x0D;&#x0A;del /q /s Rescue_Twofish &gt;NUL:&#x0D;&#x0A;md Rescue_Twofish 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=TWOFISH RESCUE_DISK=1&#x0D;&#x0A;&#x0D;&#x0A;del /q /s Rescue_Twofish_SHA2 &gt;NUL:&#x0D;&#x0A;md Rescue_Twofish_SHA2 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=TWOFISH RESCUE_DISK=1 SINGLE_PRF=SHA2"
+ CleanCommandLine="del /q /s Release Release_AES Release_Serpent Release_Twofish Rescue Rescue_AES Rescue_Serpent Rescue_Twofish &gt;NUL:&#x0D;&#x0A;del /q /s Release_SHA2 Release_AES_SHA2 Release_Serpent_SHA2 Release_Twofish_SHA2 Rescue_SHA2 Rescue_AES_SHA2 Rescue_Serpent_SHA2 Rescue_Twofish_SHA2 &gt;NUL:&#x0D;&#x0A;"
+ Output="Release\BootLoader.com"
+ PreprocessorDefinitions="WIN32;NDEBUG"
+ IncludeSearchPath="&quot;$(SolutionDir)&quot;;&quot;$(SolutionDir)\Common&quot;;&quot;$(SolutionDir)\Crypto&quot;;&quot;$(MSVC16_ROOT)\Include&quot;"
+ ForcedIncludes=""
+ AssemblySearchPath=""
+ ForcedUsingAssemblies=""
+ CompileAsManaged=""
+ />
+ </Configuration>
+ <Configuration
+ Name="Release Loader|Win32"
+ OutputDirectory="$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="0"
+ >
+ <Tool
+ Name="VCNMakeTool"
+ BuildCommandLine="md Release 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1&#x0D;&#x0A;&#x0D;&#x0A;md Release_AES 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=AES&#x0D;&#x0A;&#x0D;&#x0A;md Release_Serpent 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=SERPENT&#x0D;&#x0A;&#x0D;&#x0A;md Release_Twofish 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=TWOFISH"
+ ReBuildCommandLine="del /q /s Release &gt;NUL:&#x0D;&#x0A;md Release 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1&#x0D;&#x0A;&#x0D;&#x0A;del /q /s Release_AES &gt;NUL:&#x0D;&#x0A;md Release_AES 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=AES&#x0D;&#x0A;&#x0D;&#x0A;del /q /s Release_Serpent &gt;NUL:&#x0D;&#x0A;md Release_Serpent 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=SERPENT&#x0D;&#x0A;&#x0D;&#x0A;del /q /s Release_Twofish &gt;NUL:&#x0D;&#x0A;md Release_Twofish 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=TWOFISH"
+ CleanCommandLine="del /q /s Release Release_AES Release_Serpent Release_Twofish &gt;NUL:"
+ Output="Release\BootLoader.com"
+ PreprocessorDefinitions="WIN32;NDEBUG"
+ IncludeSearchPath="&quot;$(SolutionDir)&quot;;&quot;$(SolutionDir)\Common&quot;;&quot;$(SolutionDir)\Crypto&quot;;&quot;$(MSVC16_ROOT)\Include&quot;"
+ ForcedIncludes=""
+ AssemblySearchPath=""
+ ForcedUsingAssemblies=""
+ CompileAsManaged=""
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath=".\BootConfig.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\BootConsoleIo.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\BootCrt.asm"
+ >
+ </File>
+ <File
+ RelativePath=".\BootDebug.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\BootDiskIo.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\BootEncryptedIo.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\BootMain.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\BootMemory.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\BootSector.asm"
+ >
+ </File>
+ <File
+ RelativePath=".\Decompressor.c"
+ >
+ </File>
+ <File
+ RelativePath=".\IntFilter.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\Platform.cpp"
+ >
+ </File>
+ <Filter
+ Name="Common"
+ >
+ <File
+ RelativePath="..\..\Common\Crc.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\Common\Crypto.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\Common\Endian.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\Common\Pkcs5.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\Common\Volumes.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\Common\Xts.c"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Crypto"
+ >
+ <File
+ RelativePath="..\..\Crypto\Aes_hw_cpu.asm"
+ >
+ </File>
+ <File
+ RelativePath="..\..\Crypto\AesSmall.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\Crypto\AesSmall_x86.asm"
+ >
+ </File>
+ <File
+ RelativePath="..\..\Crypto\Rmd160.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\Crypto\Serpent.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\Crypto\Sha2Small.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\Crypto\Twofish.c"
+ >
+ </File>
+ </Filter>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ <File
+ RelativePath=".\Bios.h"
+ >
+ </File>
+ <File
+ RelativePath=".\BootCommon.h"
+ >
+ </File>
+ <File
+ RelativePath=".\BootConfig.h"
+ >
+ </File>
+ <File
+ RelativePath=".\BootConsoleIo.h"
+ >
+ </File>
+ <File
+ RelativePath=".\BootDebug.h"
+ >
+ </File>
+ <File
+ RelativePath=".\BootDefs.h"
+ >
+ </File>
+ <File
+ RelativePath=".\BootDiskIo.h"
+ >
+ </File>
+ <File
+ RelativePath=".\BootEncryptedIo.h"
+ >
+ </File>
+ <File
+ RelativePath=".\BootMain.h"
+ >
+ </File>
+ <File
+ RelativePath=".\BootMemory.h"
+ >
+ </File>
+ <File
+ RelativePath=".\BootStrings.h"
+ >
+ </File>
+ <File
+ RelativePath=".\IntFilter.h"
+ >
+ </File>
+ <File
+ RelativePath=".\Platform.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Build Files"
+ >
+ <File
+ RelativePath=".\Makefile"
+ >
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/src/Boot/Windows/BootCommon.h b/src/Boot/Windows/BootCommon.h
index 4d91981b..0d4f710d 100644
--- a/src/Boot/Windows/BootCommon.h
+++ b/src/Boot/Windows/BootCommon.h
@@ -1,82 +1,82 @@
-/*
- Derived from source code of TrueCrypt 7.1a, which is
- Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed
- by the TrueCrypt License 3.0.
-
- Modifications and additions to the original source code (contained in this file)
- and all other portions of this file are Copyright (c) 2013-2016 IDRIX
- and are governed by the Apache License 2.0 the full text of which is
- contained in the file License.txt included in VeraCrypt binary and source
- code distribution packages.
-*/
-
-#ifndef TC_HEADER_Boot_BootCommon
-#define TC_HEADER_Boot_BootCommon
-
-#include "Common/Password.h"
-#include "BootDefs.h"
-
-// The user will be advised to upgrade the rescue disk if upgrading from the following or any previous version
-#define TC_RESCUE_DISK_UPGRADE_NOTICE_MAX_VERSION 0x0117
-
-#define TC_BOOT_LOADER_AREA_SIZE (TC_BOOT_LOADER_AREA_SECTOR_COUNT * TC_SECTOR_SIZE_BIOS)
-
-#define TC_BOOT_VOLUME_HEADER_SECTOR (TC_BOOT_LOADER_AREA_SECTOR_COUNT - 1)
-#define TC_BOOT_VOLUME_HEADER_SECTOR_OFFSET (TC_BOOT_VOLUME_HEADER_SECTOR * TC_SECTOR_SIZE_BIOS)
-
-#define TC_CD_BOOTSECTOR_OFFSET 0xd000
-#define TC_CD_BOOT_LOADER_SECTOR 26
-
-#define TC_ORIG_BOOT_LOADER_BACKUP_SECTOR TC_BOOT_LOADER_AREA_SECTOR_COUNT
-#define TC_ORIG_BOOT_LOADER_BACKUP_SECTOR_OFFSET (TC_ORIG_BOOT_LOADER_BACKUP_SECTOR * TC_SECTOR_SIZE_BIOS)
-
-#define TC_BOOT_LOADER_BACKUP_RESCUE_DISK_SECTOR (TC_ORIG_BOOT_LOADER_BACKUP_SECTOR + TC_BOOT_LOADER_AREA_SECTOR_COUNT)
-#define TC_BOOT_LOADER_BACKUP_RESCUE_DISK_SECTOR_OFFSET (TC_BOOT_LOADER_BACKUP_RESCUE_DISK_SECTOR * TC_SECTOR_SIZE_BIOS)
-
-#define TC_MBR_SECTOR 0
-#define TC_MAX_MBR_BOOT_CODE_SIZE 440
-
-#define TC_MAX_EXTRA_BOOT_PARTITION_SIZE (512UL * 1024UL * 1024UL)
-
-
-#pragma pack (1)
-
-typedef struct
-{
- byte Flags;
-} BootSectorConfiguration;
-
-
-// Modifying this value can introduce incompatibility with previous versions
-#define TC_BOOT_LOADER_ARGS_OFFSET 0x10
-
-typedef struct
-{
- // Modifying this structure can introduce incompatibility with previous versions
- char Signature[8];
- uint16 BootLoaderVersion;
- uint16 CryptoInfoOffset;
- uint16 CryptoInfoLength;
- uint32 HeaderSaltCrc32;
- Password BootPassword;
- uint64 HiddenSystemPartitionStart;
- uint64 DecoySystemPartitionStart;
- uint32 Flags;
- uint32 BootDriveSignature;
-
- uint32 BootArgumentsCrc32;
-
-} BootArguments;
-
-// Modifying these values can introduce incompatibility with previous versions
-#define TC_BOOT_ARGS_FLAG_EXTRA_BOOT_PARTITION 0x1
-
-#pragma pack ()
-
-// Boot arguments signature should not be defined as a static string
-// Modifying these values can introduce incompatibility with previous versions
-#define TC_SET_BOOT_ARGUMENTS_SIGNATURE(SG) do { SG[0] = 'T'; SG[1] = 'R'; SG[2] = 'U'; SG[3] = 'E'; SG[4] = 0x11; SG[5] = 0x23; SG[6] = 0x45; SG[7] = 0x66; } while (FALSE)
-#define TC_IS_BOOT_ARGUMENTS_SIGNATURE(SG) (SG[0] == 'T' && SG[1] == 'R' && SG[2] == 'U' && SG[3] == 'E' && SG[4] == 0x11 && SG[5] == 0x23 && SG[6] == 0x45 && SG[7] == 0x66)
-
-
-#endif // TC_HEADER_Boot_BootCommon
+/*
+ Derived from source code of TrueCrypt 7.1a, which is
+ Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed
+ by the TrueCrypt License 3.0.
+
+ Modifications and additions to the original source code (contained in this file)
+ and all other portions of this file are Copyright (c) 2013-2016 IDRIX
+ and are governed by the Apache License 2.0 the full text of which is
+ contained in the file License.txt included in VeraCrypt binary and source
+ code distribution packages.
+*/
+
+#ifndef TC_HEADER_Boot_BootCommon
+#define TC_HEADER_Boot_BootCommon
+
+#include "Common/Password.h"
+#include "BootDefs.h"
+
+// The user will be advised to upgrade the rescue disk if upgrading from the following or any previous version
+#define TC_RESCUE_DISK_UPGRADE_NOTICE_MAX_VERSION 0x0117
+
+#define TC_BOOT_LOADER_AREA_SIZE (TC_BOOT_LOADER_AREA_SECTOR_COUNT * TC_SECTOR_SIZE_BIOS)
+
+#define TC_BOOT_VOLUME_HEADER_SECTOR (TC_BOOT_LOADER_AREA_SECTOR_COUNT - 1)
+#define TC_BOOT_VOLUME_HEADER_SECTOR_OFFSET (TC_BOOT_VOLUME_HEADER_SECTOR * TC_SECTOR_SIZE_BIOS)
+
+#define TC_CD_BOOTSECTOR_OFFSET 0xd000
+#define TC_CD_BOOT_LOADER_SECTOR 26
+
+#define TC_ORIG_BOOT_LOADER_BACKUP_SECTOR TC_BOOT_LOADER_AREA_SECTOR_COUNT
+#define TC_ORIG_BOOT_LOADER_BACKUP_SECTOR_OFFSET (TC_ORIG_BOOT_LOADER_BACKUP_SECTOR * TC_SECTOR_SIZE_BIOS)
+
+#define TC_BOOT_LOADER_BACKUP_RESCUE_DISK_SECTOR (TC_ORIG_BOOT_LOADER_BACKUP_SECTOR + TC_BOOT_LOADER_AREA_SECTOR_COUNT)
+#define TC_BOOT_LOADER_BACKUP_RESCUE_DISK_SECTOR_OFFSET (TC_BOOT_LOADER_BACKUP_RESCUE_DISK_SECTOR * TC_SECTOR_SIZE_BIOS)
+
+#define TC_MBR_SECTOR 0
+#define TC_MAX_MBR_BOOT_CODE_SIZE 440
+
+#define TC_MAX_EXTRA_BOOT_PARTITION_SIZE (512UL * 1024UL * 1024UL)
+
+
+#pragma pack (1)
+
+typedef struct
+{
+ byte Flags;
+} BootSectorConfiguration;
+
+
+// Modifying this value can introduce incompatibility with previous versions
+#define TC_BOOT_LOADER_ARGS_OFFSET 0x10
+
+typedef struct
+{
+ // Modifying this structure can introduce incompatibility with previous versions
+ char Signature[8];
+ uint16 BootLoaderVersion;
+ uint16 CryptoInfoOffset;
+ uint16 CryptoInfoLength;
+ uint32 HeaderSaltCrc32;
+ Password BootPassword;
+ uint64 HiddenSystemPartitionStart;
+ uint64 DecoySystemPartitionStart;
+ uint32 Flags;
+ uint32 BootDriveSignature;
+
+ uint32 BootArgumentsCrc32;
+
+} BootArguments;
+
+// Modifying these values can introduce incompatibility with previous versions
+#define TC_BOOT_ARGS_FLAG_EXTRA_BOOT_PARTITION 0x1
+
+#pragma pack ()
+
+// Boot arguments signature should not be defined as a static string
+// Modifying these values can introduce incompatibility with previous versions
+#define TC_SET_BOOT_ARGUMENTS_SIGNATURE(SG) do { SG[0] = 'T'; SG[1] = 'R'; SG[2] = 'U'; SG[3] = 'E'; SG[4] = 0x11; SG[5] = 0x23; SG[6] = 0x45; SG[7] = 0x66; } while (FALSE)
+#define TC_IS_BOOT_ARGUMENTS_SIGNATURE(SG) (SG[0] == 'T' && SG[1] == 'R' && SG[2] == 'U' && SG[3] == 'E' && SG[4] == 0x11 && SG[5] == 0x23 && SG[6] == 0x45 && SG[7] == 0x66)
+
+
+#endif // TC_HEADER_Boot_BootCommon
diff --git a/src/Boot/Windows/BootConfig.cpp b/src/Boot/Windows/BootConfig.cpp
index 63ebaf5e..3e41d610 100644
--- a/src/Boot/Windows/BootConfig.cpp
+++ b/src/Boot/Windows/BootConfig.cpp
@@ -1,102 +1,102 @@
-/*
- Derived from source code of TrueCrypt 7.1a, which is
- Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed
- by the TrueCrypt License 3.0.
-
- Modifications and additions to the original source code (contained in this file)
- and all other portions of this file are Copyright (c) 2013-2016 IDRIX
- and are governed by the Apache License 2.0 the full text of which is
- contained in the file License.txt included in VeraCrypt binary and source
- code distribution packages.
-*/
-
-#include "BootConfig.h"
-
-byte BootSectorFlags;
-
-byte BootLoaderDrive;
-byte BootDrive;
-bool BootDriveGeometryValid = false;
-bool PreventNormalSystemBoot = false;
-bool PreventBootMenu = false;
-char CustomUserMessage[TC_BOOT_SECTOR_USER_MESSAGE_MAX_LENGTH + 1];
-uint32 OuterVolumeBackupHeaderCrc;
-
-bool BootStarted = false;
-
-DriveGeometry BootDriveGeometry;
-
-CRYPTO_INFO *BootCryptoInfo;
-Partition EncryptedVirtualPartition;
-
-Partition ActivePartition;
-Partition PartitionFollowingActive;
-bool ExtraBootPartitionPresent = false;
-uint64 PimValueOrHiddenVolumeStartUnitNo; // reuse this variable for stored PIM value to reduce memory usage
-uint64 HiddenVolumeStartSector;
-
-#ifndef TC_WINDOWS_BOOT_RESCUE_DISK_MODE
-
-void ReadBootSectorUserConfiguration ()
-{
- byte userConfig;
-
- AcquireSectorBuffer();
-
- if (ReadWriteMBR (false, BootLoaderDrive, true) != BiosResultSuccess)
- goto ret;
-
- userConfig = SectorBuffer[TC_BOOT_SECTOR_USER_CONFIG_OFFSET];
-
-#ifdef TC_WINDOWS_BOOT_AES
- EnableHwEncryption (!(userConfig & TC_BOOT_USER_CFG_FLAG_DISABLE_HW_ENCRYPTION));
-#endif
-
- PreventBootMenu = (userConfig & TC_BOOT_USER_CFG_FLAG_DISABLE_ESC);
-
- memcpy (CustomUserMessage, SectorBuffer + TC_BOOT_SECTOR_USER_MESSAGE_OFFSET, TC_BOOT_SECTOR_USER_MESSAGE_MAX_LENGTH);
- CustomUserMessage[TC_BOOT_SECTOR_USER_MESSAGE_MAX_LENGTH] = 0;
-
- if (userConfig & TC_BOOT_USER_CFG_FLAG_SILENT_MODE)
- {
- if (CustomUserMessage[0])
- {
- InitVideoMode();
- Print (CustomUserMessage);
- }
-
- DisableScreenOutput();
- }
-
- if (userConfig & TC_BOOT_USER_CFG_FLAG_DISABLE_PIM)
- {
- PimValueOrHiddenVolumeStartUnitNo.LowPart = 0;
- memcpy (&PimValueOrHiddenVolumeStartUnitNo.LowPart, SectorBuffer + TC_BOOT_SECTOR_PIM_VALUE_OFFSET, TC_BOOT_SECTOR_PIM_VALUE_SIZE);
- }
- else
- PimValueOrHiddenVolumeStartUnitNo.LowPart = -1;
-
- OuterVolumeBackupHeaderCrc = *(uint32 *) (SectorBuffer + TC_BOOT_SECTOR_OUTER_VOLUME_BAK_HEADER_CRC_OFFSET);
-
-ret:
- ReleaseSectorBuffer();
-}
-
-
-BiosResult UpdateBootSectorConfiguration (byte drive)
-{
- AcquireSectorBuffer();
-
- BiosResult result = ReadWriteMBR (false, drive);
- if (result != BiosResultSuccess)
- goto ret;
-
- SectorBuffer[TC_BOOT_SECTOR_CONFIG_OFFSET] = BootSectorFlags;
- result = ReadWriteMBR (true, drive);
-
-ret:
- ReleaseSectorBuffer();
- return result;
-}
-
-#endif // !TC_WINDOWS_BOOT_RESCUE_DISK_MODE
+/*
+ Derived from source code of TrueCrypt 7.1a, which is
+ Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed
+ by the TrueCrypt License 3.0.
+
+ Modifications and additions to the original source code (contained in this file)
+ and all other portions of this file are Copyright (c) 2013-2016 IDRIX
+ and are governed by the Apache License 2.0 the full text of which is
+ contained in the file License.txt included in VeraCrypt binary and source
+ code distribution packages.
+*/
+
+#include "BootConfig.h"
+
+byte BootSectorFlags;
+
+byte BootLoaderDrive;
+byte BootDrive;
+bool BootDriveGeometryValid = false;
+bool PreventNormalSystemBoot = false;
+bool PreventBootMenu = false;
+char CustomUserMessage[TC_BOOT_SECTOR_USER_MESSAGE_MAX_LENGTH + 1];
+uint32 OuterVolumeBackupHeaderCrc;
+
+bool BootStarted = false;
+
+DriveGeometry BootDriveGeometry;
+
+CRYPTO_INFO *BootCryptoInfo;
+Partition EncryptedVirtualPartition;
+
+Partition ActivePartition;
+Partition PartitionFollowingActive;
+bool ExtraBootPartitionPresent = false;
+uint64 PimValueOrHiddenVolumeStartUnitNo; // reuse this variable for stored PIM value to reduce memory usage
+uint64 HiddenVolumeStartSector;
+
+#ifndef TC_WINDOWS_BOOT_RESCUE_DISK_MODE
+
+void ReadBootSectorUserConfiguration ()
+{
+ byte userConfig;
+
+ AcquireSectorBuffer();
+
+ if (ReadWriteMBR (false, BootLoaderDrive, true) != BiosResultSuccess)
+ goto ret;
+
+ userConfig = SectorBuffer[TC_BOOT_SECTOR_USER_CONFIG_OFFSET];
+
+#ifdef TC_WINDOWS_BOOT_AES
+ EnableHwEncryption (!(userConfig & TC_BOOT_USER_CFG_FLAG_DISABLE_HW_ENCRYPTION));
+#endif
+
+ PreventBootMenu = (userConfig & TC_BOOT_USER_CFG_FLAG_DISABLE_ESC);
+
+ memcpy (CustomUserMessage, SectorBuffer + TC_BOOT_SECTOR_USER_MESSAGE_OFFSET, TC_BOOT_SECTOR_USER_MESSAGE_MAX_LENGTH);
+ CustomUserMessage[TC_BOOT_SECTOR_USER_MESSAGE_MAX_LENGTH] = 0;
+
+ if (userConfig & TC_BOOT_USER_CFG_FLAG_SILENT_MODE)
+ {
+ if (CustomUserMessage[0])
+ {
+ InitVideoMode();
+ Print (CustomUserMessage);
+ }
+
+ DisableScreenOutput();
+ }
+
+ if (userConfig & TC_BOOT_USER_CFG_FLAG_DISABLE_PIM)
+ {
+ PimValueOrHiddenVolumeStartUnitNo.LowPart = 0;
+ memcpy (&PimValueOrHiddenVolumeStartUnitNo.LowPart, SectorBuffer + TC_BOOT_SECTOR_PIM_VALUE_OFFSET, TC_BOOT_SECTOR_PIM_VALUE_SIZE);
+ }
+ else
+ PimValueOrHiddenVolumeStartUnitNo.LowPart = -1;
+
+ OuterVolumeBackupHeaderCrc = *(uint32 *) (SectorBuffer + TC_BOOT_SECTOR_OUTER_VOLUME_BAK_HEADER_CRC_OFFSET);
+
+ret:
+ ReleaseSectorBuffer();
+}
+
+
+BiosResult UpdateBootSectorConfiguration (byte drive)
+{
+ AcquireSectorBuffer();
+
+ BiosResult result = ReadWriteMBR (false, drive);
+ if (result != BiosResultSuccess)
+ goto ret;
+
+ SectorBuffer[TC_BOOT_SECTOR_CONFIG_OFFSET] = BootSectorFlags;
+ result = ReadWriteMBR (true, drive);
+
+ret:
+ ReleaseSectorBuffer();
+ return result;
+}
+
+#endif // !TC_WINDOWS_BOOT_RESCUE_DISK_MODE
diff --git a/src/Boot/Windows/BootConfig.h b/src/Boot/Windows/BootConfig.h
index 0c5eee74..428d713c 100644
--- a/src/Boot/Windows/BootConfig.h
+++ b/src/Boot/Windows/BootConfig.h
@@ -1,46 +1,46 @@
-/*
- Derived from source code of TrueCrypt 7.1a, which is
- Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed
- by the TrueCrypt License 3.0.
-
- Modifications and additions to the original source code (contained in this file)
- and all other portions of this file are Copyright (c) 2013-2016 IDRIX
- and are governed by the Apache License 2.0 the full text of which is
- contained in the file License.txt included in VeraCrypt binary and source
- code distribution packages.
-*/
-
-#ifndef TC_HEADER_Boot_BootConfig
-#define TC_HEADER_Boot_BootConfig
-
-#include "Crypto.h"
-#include "Platform.h"
-#include "BootDiskIo.h"
-
-extern byte BootSectorFlags;
-
-extern byte BootLoaderDrive;
-extern byte BootDrive;
-extern bool BootDriveGeometryValid;
-extern DriveGeometry BootDriveGeometry;
-extern bool PreventNormalSystemBoot;
-extern bool PreventBootMenu;
-extern char CustomUserMessage[TC_BOOT_SECTOR_USER_MESSAGE_MAX_LENGTH + 1];
-extern uint32 OuterVolumeBackupHeaderCrc;
-
-extern bool BootStarted;
-
-extern CRYPTO_INFO *BootCryptoInfo;
-extern Partition EncryptedVirtualPartition;
-
-extern Partition ActivePartition;
-extern Partition PartitionFollowingActive;
-extern bool ExtraBootPartitionPresent;
-extern uint64 PimValueOrHiddenVolumeStartUnitNo; // reuse this variable for stored PIM value to reduce memory usage
-extern uint64 HiddenVolumeStartSector;
-
-
-void ReadBootSectorUserConfiguration ();
-BiosResult UpdateBootSectorConfiguration (byte drive);
-
-#endif // TC_HEADER_Boot_BootConfig
+/*
+ Derived from source code of TrueCrypt 7.1a, which is
+ Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed
+ by the TrueCrypt License 3.0.
+
+ Modifications and additions to the original source code (contained in this file)
+ and all other portions of this file are Copyright (c) 2013-2016 IDRIX
+ and are governed by the Apache License 2.0 the full text of which is
+ contained in the file License.txt included in VeraCrypt binary and source
+ code distribution packages.
+*/
+
+#ifndef TC_HEADER_Boot_BootConfig
+#define TC_HEADER_Boot_BootConfig
+
+#include "Crypto.h"
+#include "Platform.h"
+#include "BootDiskIo.h"
+
+extern byte BootSectorFlags;
+
+extern byte BootLoaderDrive;
+extern byte BootDrive;
+extern bool BootDriveGeometryValid;
+extern DriveGeometry BootDriveGeometry;
+extern bool PreventNormalSystemBoot;
+extern bool PreventBootMenu;
+extern char CustomUserMessage[TC_BOOT_SECTOR_USER_MESSAGE_MAX_LENGTH + 1];
+extern uint32 OuterVolumeBackupHeaderCrc;
+
+extern bool BootStarted;
+
+extern CRYPTO_INFO *BootCryptoInfo;
+extern Partition EncryptedVirtualPartition;
+
+extern Partition ActivePartition;
+extern Partition PartitionFollowingActive;
+extern bool ExtraBootPartitionPresent;
+extern uint64 PimValueOrHiddenVolumeStartUnitNo; // reuse this variable for stored PIM value to reduce memory usage
+extern uint64 HiddenVolumeStartSector;
+
+
+void ReadBootSectorUserConfiguration ();
+BiosResult UpdateBootSectorConfiguration (byte drive);
+
+#endif // TC_HEADER_Boot_BootConfig
diff --git a/src/Boot/Windows/BootConsoleIo.cpp b/src/Boot/Windows/BootConsoleIo.cpp
index 31b66673..2fee84fc 100644
--- a/src/Boot/Windows/BootConsoleIo.cpp
+++ b/src/Boot/Windows/BootConsoleIo.cpp
@@ -1,339 +1,339 @@
-/*
- Derived from source code of TrueCrypt 7.1a, which is
- Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed
- by the TrueCrypt License 3.0.
-
- Modifications and additions to the original source code (contained in this file)
- and all other portions of this file are Copyright (c) 2013-2016 IDRIX
- and are governed by the Apache License 2.0 the full text of which is
- contained in the file License.txt included in VeraCrypt binary and source
- code distribution packages.
-*/
-
-#include "Platform.h"
-#include "Bios.h"
-#include "BootConsoleIo.h"
-#include "BootDebug.h"
-#include "BootStrings.h"
-
-
-static int ScreenOutputDisabled = 0;
-
-void DisableScreenOutput ()
-{
- ++ScreenOutputDisabled;
-}
-
-
-void EnableScreenOutput ()
-{
- --ScreenOutputDisabled;
-}
-
-
-void PrintChar (char c)
-{
-#ifdef TC_BOOT_TRACING_ENABLED
- WriteDebugPort (c);
-#endif
-
- if (ScreenOutputDisabled)
- return;
-
- __asm
- {
- mov bx, 7
- mov al, c
- mov ah, 0xe
- int 0x10
- }
-}
-
-
-void PrintCharAtCursor (char c)
-{
- if (ScreenOutputDisabled)
- return;
-
- __asm
- {
- mov bx, 7
- mov al, c
- mov cx, 1
- mov ah, 0xa
- int 0x10
- }
-}
-
-
-void Print (const char *str)
-{
- char c;
- while (c = *str++)
- PrintChar (c);
-}
-
-
-void Print (uint32 number)
-{
- char str[12];
- int pos = 0;
- while (number >= 10)
- {
- str[pos++] = (char) (number % 10) + '0';
- number /= 10;
- }
- str[pos] = (char) (number % 10) + '0';
-
- while (pos >= 0)
- PrintChar (str[pos--]);
-}
-
-
-void Print (const uint64 &number)
-{
- if (number.HighPart == 0)
- Print (number.LowPart);
- else
- PrintHex (number);
-}
-
-
-void PrintHex (byte b)
-{
- PrintChar (((b >> 4) >= 0xA ? 'A' - 0xA : '0') + (b >> 4));
- PrintChar (((b & 0xF) >= 0xA ? 'A' - 0xA : '0') + (b & 0xF));
-}
-
-
-void PrintHex (uint16 data)
-{
- PrintHex (byte (data >> 8));
- PrintHex (byte (data));
-}
-
-
-void PrintHex (uint32 data)
-{
- PrintHex (uint16 (data >> 16));
- PrintHex (uint16 (data));
-}
-
-
-void PrintHex (const uint64 &data)
-{
- PrintHex (data.HighPart);
- PrintHex (data.LowPart);
-}
-
-void PrintRepeatedChar (char c, int n)
-{
- while (n-- > 0)
- PrintChar (c);
-}
-
-
-void PrintEndl ()
-{
- Print ("\r\n");
-}
-
-
-void PrintEndl (int cnt)
-{
- while (cnt-- > 0)
- PrintEndl ();
-}
-
-
-void Beep ()
-{
- PrintChar (7);
-}
-
-
-void InitVideoMode ()
-{
- if (ScreenOutputDisabled)
- return;
-
- __asm
- {
- // Text mode 80x25
- mov ax, 3
- int 0x10
-
- // Page 0
- mov ax, 0x500
- int 0x10
- }
-}
-
-
-void ClearScreen ()
-{
- if (ScreenOutputDisabled)
- return;
-
- __asm
- {
- // White text on black
- mov bh, 7
- xor cx, cx
- mov dx, 0x184f
- mov ax, 0x600
- int 0x10
-
- // Cursor at 0,0
- xor bh, bh
- xor dx, dx
- mov ah, 2
- int 0x10
- }
-}
-
-
-void PrintBackspace ()
-{
- PrintChar (TC_BIOS_CHAR_BACKSPACE);
- PrintCharAtCursor (' ');
-}
-
-
-void PrintError (const char *message)
-{
- Print (TC_BOOT_STR_ERROR);
- Print (message);
- PrintEndl();
- Beep();
-}
-
-
-void PrintErrorNoEndl (const char *message)
-{
- Print (TC_BOOT_STR_ERROR);
- Print (message);
- Beep();
-}
-
-
-byte GetShiftFlags ()
-{
- byte flags;
- __asm
- {
- mov ah, 2
- int 0x16
- mov flags, al
- }
-
- return flags;
-}
-
-
-byte GetKeyboardChar ()
-{
- return GetKeyboardChar (nullptr);
-}
-
-
-byte GetKeyboardChar (byte *scanCode)
-{
- // Work around potential BIOS bugs (Windows boot manager polls the keystroke buffer)
- while (!IsKeyboardCharAvailable());
-
- byte asciiCode;
- byte scan;
- __asm
- {
- mov ah, 0
- int 0x16
- mov asciiCode, al
- mov scan, ah
- }
-
- if (scanCode)
- *scanCode = scan;
-
- return asciiCode;
-}
-
-
-bool IsKeyboardCharAvailable ()
-{
- bool available = false;
- __asm
- {
- mov ah, 1
- int 0x16
- jz not_avail
- mov available, true
- not_avail:
- }
-
- return available;
-}
-
-
-bool EscKeyPressed ()
-{
- if (IsKeyboardCharAvailable ())
- {
- byte keyScanCode;
- GetKeyboardChar (&keyScanCode);
- return keyScanCode == TC_BIOS_KEY_ESC;
- }
-
- return false;
-}
-
-
-void ClearBiosKeystrokeBuffer ()
-{
- __asm
- {
- push es
- xor ax, ax
- mov es, ax
- mov di, 0x41e
- mov cx, 32
- cld
- rep stosb
- pop es
- }
-}
-
-
-bool IsPrintable (char c)
-{
- return c >= ' ' && c <= '~';
-}
-
-bool IsDigit (char c)
-{
- return c >= '0' && c <= '9';
-}
-
-
-int GetString (char *buffer, size_t bufferSize)
-{
- byte c;
- byte scanCode;
- size_t pos = 0;
-
- while (pos < bufferSize)
- {
- c = GetKeyboardChar (&scanCode);
-
- if (scanCode == TC_BIOS_KEY_ENTER)
- break;
-
- if (scanCode == TC_BIOS_KEY_ESC)
- return 0;
-
- buffer[pos++] = c;
- PrintChar (IsPrintable (c) ? c : ' ');
- }
-
- return pos;
-}
+/*
+ Derived from source code of TrueCrypt 7.1a, which is
+ Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed
+ by the TrueCrypt License 3.0.
+
+ Modifications and additions to the original source code (contained in this file)
+ and all other portions of this file are Copyright (c) 2013-2016 IDRIX
+ and are governed by the Apache License 2.0 the full text of which is
+ contained in the file License.txt included in VeraCrypt binary and source
+ code distribution packages.
+*/
+
+#include "Platform.h"
+#include "Bios.h"
+#include "BootConsoleIo.h"
+#include "BootDebug.h"
+#include "BootStrings.h"
+
+
+static int ScreenOutputDisabled = 0;
+
+void DisableScreenOutput ()
+{
+ ++ScreenOutputDisabled;
+}
+
+
+void EnableScreenOutput ()
+{
+ --ScreenOutputDisabled;
+}
+
+
+void PrintChar (char c)
+{
+#ifdef TC_BOOT_TRACING_ENABLED
+ WriteDebugPort (c);
+#endif
+
+ if (ScreenOutputDisabled)
+ return;
+
+ __asm
+ {
+ mov bx, 7
+ mov al, c
+ mov ah, 0xe
+ int 0x10
+ }
+}
+
+
+void PrintCharAtCursor (char c)
+{
+ if (ScreenOutputDisabled)
+ return;
+
+ __asm
+ {
+ mov bx, 7
+ mov al, c
+ mov cx, 1
+ mov ah, 0xa
+ int 0x10
+ }
+}
+
+
+void Print (const char *str)
+{
+ char c;
+ while (c = *str++)
+ PrintChar (c);
+}
+
+
+void Print (uint32 number)
+{
+ char str[12];
+ int pos = 0;
+ while (number >= 10)
+ {
+ str[pos++] = (char) (number % 10) + '0';
+ number /= 10;
+ }
+ str[pos] = (char) (number % 10) + '0';
+
+ while (pos >= 0)
+ PrintChar (str[pos--]);
+}
+
+
+void Print (const uint64 &number)
+{
+ if (number.HighPart == 0)
+ Print (number.LowPart);
+ else
+ PrintHex (number);
+}
+
+
+void PrintHex (byte b)
+{
+ PrintChar (((b >> 4) >= 0xA ? 'A' - 0xA : '0') + (b >> 4));
+ PrintChar (((b & 0xF) >= 0xA ? 'A' - 0xA : '0') + (b & 0xF));
+}
+
+
+void PrintHex (uint16 data)
+{
+ PrintHex (byte (data >> 8));
+ PrintHex (byte (data));
+}
+
+
+void PrintHex (uint32 data)
+{
+ PrintHex (uint16 (data >> 16));
+ PrintHex (uint16 (data));
+}
+
+
+void PrintHex (const uint64 &data)
+{
+ PrintHex (data.HighPart);
+ PrintHex (data.LowPart);
+}
+
+void PrintRepeatedChar (char c, int n)
+{
+ while (n-- > 0)
+ PrintChar (c);
+}
+
+
+void PrintEndl ()
+{
+ Print ("\r\n");
+}
+
+
+void PrintEndl (int cnt)
+{
+ while (cnt-- > 0)
+ PrintEndl ();
+}
+
+
+void Beep ()
+{
+ PrintChar (7);
+}
+
+
+void InitVideoMode ()
+{
+ if (ScreenOutputDisabled)
+ return;
+
+ __asm
+ {
+ // Text mode 80x25
+ mov ax, 3
+ int 0x10
+
+ // Page 0
+ mov ax, 0x500
+ int 0x10
+ }
+}
+
+
+void ClearScreen ()
+{
+ if (ScreenOutputDisabled)
+ return;
+
+ __asm
+ {
+ // White text on black
+ mov bh, 7
+ xor cx, cx
+ mov dx, 0x184f
+ mov ax, 0x600
+ int 0x10
+
+ // Cursor at 0,0
+ xor bh, bh
+ xor dx, dx
+ mov ah, 2
+ int 0x10
+ }
+}
+
+
+void PrintBackspace ()
+{
+ PrintChar (TC_BIOS_CHAR_BACKSPACE);
+ PrintCharAtCursor (' ');
+}
+
+
+void PrintError (const char *message)
+{
+ Print (TC_BOOT_STR_ERROR);
+ Print (message);
+ PrintEndl();
+ Beep();
+}
+
+
+void PrintErrorNoEndl (const char *message)
+{
+ Print (TC_BOOT_STR_ERROR);
+ Print (message);
+ Beep();
+}
+
+
+byte GetShiftFlags ()
+{
+ byte flags;
+ __asm
+ {
+ mov ah, 2
+ int 0x16
+ mov flags, al
+ }
+
+ return flags;
+}
+
+
+byte GetKeyboardChar ()
+{
+ return GetKeyboardChar (nullptr);
+}
+
+
+byte GetKeyboardChar (byte *scanCode)
+{
+ // Work around potential BIOS bugs (Windows boot manager polls the keystroke buffer)
+ while (!IsKeyboardCharAvailable());
+
+ byte asciiCode;
+ byte scan;
+ __asm
+ {
+ mov ah, 0
+ int 0x16
+ mov asciiCode, al
+ mov scan, ah
+ }
+
+ if (scanCode)
+ *scanCode = scan;
+
+ return asciiCode;
+}
+
+
+bool IsKeyboardCharAvailable ()
+{
+ bool available = false;
+ __asm
+ {
+ mov ah, 1
+ int 0x16
+ jz not_avail
+ mov available, true
+ not_avail:
+ }
+
+ return available;
+}
+
+
+bool EscKeyPressed ()
+{
+ if (IsKeyboardCharAvailable ())
+ {
+ byte keyScanCode;
+ GetKeyboardChar (&keyScanCode);
+ return keyScanCode == TC_BIOS_KEY_ESC;
+ }
+
+ return false;
+}
+
+
+void ClearBiosKeystrokeBuffer ()
+{
+ __asm
+ {
+ push es
+ xor ax, ax
+ mov es, ax
+ mov di, 0x41e
+ mov cx, 32
+ cld
+ rep stosb
+ pop es
+ }
+}
+
+
+bool IsPrintable (char c)
+{
+ return c >= ' ' && c <= '~';
+}
+
+bool IsDigit (char c)
+{
+ return c >= '0' && c <= '9';
+}
+
+
+int GetString (char *buffer, size_t bufferSize)
+{
+ byte c;
+ byte scanCode;
+ size_t pos = 0;
+
+ while (pos < bufferSize)
+ {
+ c = GetKeyboardChar (&scanCode);
+
+ if (scanCode == TC_BIOS_KEY_ENTER)
+ break;
+
+ if (scanCode == TC_BIOS_KEY_ESC)
+ return 0;
+
+ buffer[pos++] = c;
+ PrintChar (IsPrintable (c) ? c : ' ');
+ }
+
+ return pos;
+}
diff --git a/src/Boot/Windows/BootConsoleIo.h b/src/Boot/Windows/BootConsoleIo.h
index 6af75c05..52a054fe 100644
--- a/src/Boot/Windows/BootConsoleIo.h
+++ b/src/Boot/Windows/BootConsoleIo.h
@@ -1,72 +1,72 @@
-/*
- Derived from source code of TrueCrypt 7.1a, which is
- Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed
- by the TrueCrypt License 3.0.
-
- Modifications and additions to the original source code (contained in this file)
- and all other portions of this file are Copyright (c) 2013-2016 IDRIX
- and are governed by the Apache License 2.0 the full text of which is
- contained in the file License.txt included in VeraCrypt binary and source
- code distribution packages.
-*/
-
-#ifndef TC_HEADER_Boot_BootConsoleIo
-#define TC_HEADER_Boot_BootConsoleIo
-
-#include "Platform.h"
-
-#define TC_DEBUG_PORT 0
-
-#define TC_BIOS_KEY_ESC 1
-#define TC_BIOS_KEY_BACKSPACE 14
-#define TC_BIOS_KEY_ENTER 28
-#define TC_BIOS_KEY_F1 0x3b
-#define TC_BIOS_KEY_F2 0x3c
-#define TC_BIOS_KEY_F3 0x3d
-#define TC_BIOS_KEY_F4 0x3e
-#define TC_BIOS_KEY_F5 0x3f
-#define TC_BIOS_KEY_F6 0x40
-#define TC_BIOS_KEY_F7 0x41
-#define TC_BIOS_KEY_F8 0x42
-#define TC_BIOS_KEY_F9 0x43
-#define TC_BIOS_KEY_F10 0x44
-
-#define TC_BIOS_SHIFTMASK_CAPSLOCK (1 << 6)
-#define TC_BIOS_SHIFTMASK_LSHIFT (1 << 1)
-#define TC_BIOS_SHIFTMASK_RSHIFT (1 << 0)
-
-#define TC_BIOS_CHAR_BACKSPACE 8
-
-#define TC_BIOS_MAX_CHARS_PER_LINE 80
-
-void Beep ();
-void ClearBiosKeystrokeBuffer ();
-void ClearScreen ();
-void DisableScreenOutput ();
-void EnableScreenOutput ();
-bool EscKeyPressed ();
-byte GetKeyboardChar ();
-byte GetKeyboardChar (byte *scanCode);
-byte GetShiftFlags ();
-int GetString (char *buffer, size_t bufferSize);
-void InitVideoMode ();
-bool IsKeyboardCharAvailable ();
-bool IsPrintable (char c);
-bool IsDigit (char c);
-void Print (const char *str);
-void Print (uint32 number);
-void Print (const uint64 &number);
-void PrintBackspace ();
-void PrintChar (char c);
-void PrintCharAtCursor (char c);
-void PrintEndl ();
-void PrintEndl (int cnt);
-void PrintRepeatedChar (char c, int n);
-void PrintError (const char *message);
-void PrintErrorNoEndl (const char *message);
-void PrintHex (byte b);
-void PrintHex (uint16 data);
-void PrintHex (uint32 data);
-void PrintHex (const uint64 &data);
-
-#endif // TC_HEADER_Boot_BootConsoleIo
+/*
+ Derived from source code of TrueCrypt 7.1a, which is
+ Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed
+ by the TrueCrypt License 3.0.
+
+ Modifications and additions to the original source code (contained in this file)
+ and all other portions of this file are Copyright (c) 2013-2016 IDRIX
+ and are governed by the Apache License 2.0 the full text of which is
+ contained in the file License.txt included in VeraCrypt binary and source
+ code distribution packages.
+*/
+
+#ifndef TC_HEADER_Boot_BootConsoleIo
+#define TC_HEADER_Boot_BootConsoleIo
+
+#include "Platform.h"
+
+#define TC_DEBUG_PORT 0
+
+#define TC_BIOS_KEY_ESC 1
+#define TC_BIOS_KEY_BACKSPACE 14
+#define TC_BIOS_KEY_ENTER 28
+#define TC_BIOS_KEY_F1 0x3b
+#define TC_BIOS_KEY_F2 0x3c
+#define TC_BIOS_KEY_F3 0x3d
+#define TC_BIOS_KEY_F4 0x3e
+#define TC_BIOS_KEY_F5 0x3f
+#define TC_BIOS_KEY_F6 0x40
+#define TC_BIOS_KEY_F7 0x41
+#define TC_BIOS_KEY_F8 0x42
+#define TC_BIOS_KEY_F9 0x43
+#define TC_BIOS_KEY_F10 0x44
+
+#define TC_BIOS_SHIFTMASK_CAPSLOCK (1 << 6)
+#define TC_BIOS_SHIFTMASK_LSHIFT (1 << 1)
+#define TC_BIOS_SHIFTMASK_RSHIFT (1 << 0)
+
+#define TC_BIOS_CHAR_BACKSPACE 8
+
+#define TC_BIOS_MAX_CHARS_PER_LINE 80
+
+void Beep ();
+void ClearBiosKeystrokeBuffer ();
+void ClearScreen ();
+void DisableScreenOutput ();
+void EnableScreenOutput ();
+bool EscKeyPressed ();
+byte GetKeyboardChar ();
+byte GetKeyboardChar (byte *scanCode);
+byte GetShiftFlags ();
+int GetString (char *buffer, size_t bufferSize);
+void InitVideoMode ();
+bool IsKeyboardCharAvailable ();
+bool IsPrintable (char c);
+bool IsDigit (char c);
+void Print (const char *str);
+void Print (uint32 number);
+void Print (const uint64 &number);
+void PrintBackspace ();
+void PrintChar (char c);
+void PrintCharAtCursor (char c);
+void PrintEndl ();
+void PrintEndl (int cnt);
+void PrintRepeatedChar (char c, int n);
+void PrintError (const char *message);
+void PrintErrorNoEndl (const char *message);
+void PrintHex (byte b);
+void PrintHex (uint16 data);
+void PrintHex (uint32 data);
+void PrintHex (const uint64 &data);
+
+#endif // TC_HEADER_Boot_BootConsoleIo
diff --git a/src/Boot/Windows/BootCrt.asm b/src/Boot/Windows/BootCrt.asm
index e309fcb0..92ac1563 100644
--- a/src/Boot/Windows/BootCrt.asm
+++ b/src/Boot/Windows/BootCrt.asm
@@ -1,27 +1,27 @@
-;
-; Derived from source code of TrueCrypt 7.1a, which is
-; Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed
-; by the TrueCrypt License 3.0.
-;
-; Modifications and additions to the original source code (contained in this file)
-; and all other portions of this file are Copyright (c) 2013-2016 IDRIX
-; and are governed by the Apache License 2.0 the full text of which is
-; contained in the file License.txt included in VeraCrypt binary and source
-; code distribution packages.
-;
-
-.MODEL tiny, C
-.386
-
-INCLUDE BootDefs.i
-
-EXTERNDEF main:NEAR
-
-_TEXT SEGMENT
-ORG TC_COM_EXECUTABLE_OFFSET
-
-start:
- jmp main
-
-_TEXT ENDS
-END start
+;
+; Derived from source code of TrueCrypt 7.1a, which is
+; Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed
+; by the TrueCrypt License 3.0.
+;
+; Modifications and additions to the original source code (contained in this file)
+; and all other portions of this file are Copyright (c) 2013-2016 IDRIX
+; and are governed by the Apache License 2.0 the full text of which is
+; contained in the file License.txt included in VeraCrypt binary and source
+; code distribution packages.
+;
+
+.MODEL tiny, C
+.386
+
+INCLUDE BootDefs.i
+
+EXTERNDEF main:NEAR
+
+_TEXT SEGMENT
+ORG TC_COM_EXECUTABLE_OFFSET
+
+start:
+ jmp main
+
+_TEXT ENDS
+END start
diff --git a/src/Boot/Windows/BootDebug.cpp b/src/Boot/Windows/BootDebug.cpp
index 0f33ed5a..dd0863a0 100644
--- a/src/Boot/Windows/BootDebug.cpp
+++ b/src/Boot/Windows/BootDebug.cpp
@@ -1,181 +1,181 @@
-/*
- Derived from source code of TrueCrypt 7.1a, which is
- Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed
- by the TrueCrypt License 3.0.
-
- Modifications and additions to the original source code (contained in this file)
- and all other portions of this file are Copyright (c) 2013-2016 IDRIX
- and are governed by the Apache License 2.0 the full text of which is
- contained in the file License.txt included in VeraCrypt binary and source
- code distribution packages.
-*/
-
-#include "Platform.h"
-#include "Bios.h"
-#include "BootConsoleIo.h"
-#include "BootDefs.h"
-#include "BootDiskIo.h"
-#include "BootDebug.h"
-
-
-#ifdef TC_BOOT_TRACING_ENABLED
-
-void InitDebugPort ()
-{
- __asm
- {
- mov dx, TC_DEBUG_PORT
- mov ah, 1
- int 0x17
- mov dx, TC_DEBUG_PORT
- mov ah, 0xe2
- int 0x17
- }
-}
-
-
-void WriteDebugPort (byte dataByte)
-{
- __asm
- {
- mov al, dataByte
- mov dx, TC_DEBUG_PORT
- mov ah, 0
- int 0x17
- }
-}
-
-#endif // TC_BOOT_TRACING_ENABLED
-
-
-#ifdef TC_BOOT_DEBUG_ENABLED
-
-extern "C" void PrintDebug (uint32 debugVal)
-{
- Print (debugVal);
- PrintEndl();
-}
-
-
-void PrintVal (const char *message, const uint32 value, bool newLine, bool hex)
-{
- Print (message);
- Print (": ");
-
- if (hex)
- PrintHex (value);
- else
- Print (value);
-
- if (newLine)
- PrintEndl();
-}
-
-
-void PrintVal (const char *message, const uint64 &value, bool newLine, bool hex)
-{
- Print (message);
- Print (": ");
- PrintHex (value);
- if (newLine)
- PrintEndl();
-}
-
-
-void PrintHexDump (byte *mem, size_t size, uint16 *memSegment)
-{
- const size_t width = 16;
- for (size_t pos = 0; pos < size; )
- {
- for (int pass = 1; pass <= 2; ++pass)
- {
- size_t i;
- for (i = 0; i < width && pos < size; ++i)
- {
- byte dataByte;
- if (memSegment)
- {
- __asm
- {
- push es
- mov si, ss:memSegment
- mov es, ss:[si]
- mov si, ss:mem
- add si, pos
- mov al, es:[si]
- mov dataByte, al
- pop es
- }
- pos++;
- }
- else
- dataByte = mem[pos++];
-
- if (pass == 1)
- {
- PrintHex (dataByte);
- PrintChar (' ');
- }
- else
- PrintChar (IsPrintable (dataByte) ? dataByte : '.');
- }
-
- if (pass == 1)
- {
- pos -= i;
- PrintChar (' ');
- }
- }
-
- PrintEndl ();
- }
-}
-
-
-void PrintHexDump (uint16 memSegment, uint16 memOffset, size_t size)
-{
- PrintHexDump ((byte *) memOffset, size, &memSegment);
-}
-
-#endif // TC_BOOT_DEBUG_ENABLED
-
-
-#ifdef TC_BOOT_STACK_CHECKING_ENABLED
-
-extern "C" char end[];
-
-static void PrintStackInfo ()
-{
- uint16 spReg;
- __asm mov spReg, sp
-
- Print ("Stack: "); Print (TC_BOOT_LOADER_STACK_TOP - spReg);
- Print ("/"); Print (TC_BOOT_LOADER_STACK_TOP - (uint16) end);
-}
-
-
-void CheckStack ()
-{
- uint16 spReg;
- __asm mov spReg, sp
-
- if (*(uint32 *) end != 0x12345678UL || spReg < (uint16) end)
- {
- __asm cli
- __asm mov sp, TC_BOOT_LOADER_STACK_TOP
-
- PrintError ("Stack overflow");
- TC_THROW_FATAL_EXCEPTION;
- }
-}
-
-
-void InitStackChecker ()
-{
- *(uint32 *) end = 0x12345678UL;
-
- PrintStackInfo();
- PrintEndl();
-}
-
-#endif // TC_BOOT_STACK_CHECKING_ENABLED
+/*
+ Derived from source code of TrueCrypt 7.1a, which is
+ Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed
+ by the TrueCrypt License 3.0.
+
+ Modifications and additions to the original source code (contained in this file)
+ and all other portions of this file are Copyright (c) 2013-2016 IDRIX
+ and are governed by the Apache License 2.0 the full text of which is
+ contained in the file License.txt included in VeraCrypt binary and source
+ code distribution packages.
+*/
+
+#include "Platform.h"
+#include "Bios.h"
+#include "BootConsoleIo.h"
+#include "BootDefs.h"
+#include "BootDiskIo.h"
+#include "BootDebug.h"
+
+
+#ifdef TC_BOOT_TRACING_ENABLED
+
+void InitDebugPort ()
+{
+ __asm
+ {
+ mov dx, TC_DEBUG_PORT
+ mov ah, 1
+ int 0x17
+ mov dx, TC_DEBUG_PORT
+ mov ah, 0xe2
+ int 0x17
+ }
+}
+
+
+void WriteDebugPort (byte dataByte)
+{
+ __asm
+ {
+ mov al, dataByte
+ mov dx, TC_DEBUG_PORT
+ mov ah, 0
+ int 0x17
+ }
+}
+
+#endif // TC_BOOT_TRACING_ENABLED
+
+
+#ifdef TC_BOOT_DEBUG_ENABLED
+
+extern "C" void PrintDebug (uint32 debugVal)
+{
+ Print (debugVal);
+ PrintEndl();
+}
+
+
+void PrintVal (const char *message, const uint32 value, bool newLine, bool hex)
+{
+ Print (message);
+ Print (": ");
+
+ if (hex)
+ PrintHex (value);
+ else
+ Print (value);
+
+ if (newLine)
+ PrintEndl();
+}
+
+
+void PrintVal (const char *message, const uint64 &value, bool newLine, bool hex)
+{
+ Print (message);
+ Print (": ");
+ PrintHex (value);
+ if (newLine)
+ PrintEndl();
+}
+
+
+void PrintHexDump (byte *mem, size_t size, uint16 *memSegment)
+{
+ const size_t width = 16;
+ for (size_t pos = 0; pos < size; )
+ {
+ for (int pass = 1; pass <= 2; ++pass)
+ {
+ size_t i;
+ for (i = 0; i < width && pos < size; ++i)
+ {
+ byte dataByte;
+ if (memSegment)
+ {
+ __asm
+ {
+ push es
+ mov si, ss:memSegment
+ mov es, ss:[si]
+ mov si, ss:mem
+ add si, pos
+ mov al, es:[si]
+ mov dataByte, al
+ pop es
+ }
+ pos++;
+ }
+ else
+ dataByte = mem[pos++];
+
+ if (pass == 1)
+ {
+ PrintHex (dataByte);
+ PrintChar (' ');
+ }
+ else
+ PrintChar (IsPrintable (dataByte) ? dataByte : '.');
+ }
+
+ if (pass == 1)
+ {
+ pos -= i;
+ PrintChar (' ');
+ }
+ }
+
+ PrintEndl ();
+ }
+}
+
+
+void PrintHexDump (uint16 memSegment, uint16 memOffset, size_t size)
+{
+ PrintHexDump ((byte *) memOffset, size, &memSegment);
+}
+
+#endif // TC_BOOT_DEBUG_ENABLED
+
+
+#ifdef TC_BOOT_STACK_CHECKING_ENABLED
+
+extern "C" char end[];
+
+static void PrintStackInfo ()
+{
+ uint16 spReg;
+ __asm mov spReg, sp
+
+ Print ("Stack: "); Print (TC_BOOT_LOADER_STACK_TOP - spReg);
+ Print ("/"); Print (TC_BOOT_LOADER_STACK_TOP - (uint16) end);
+}
+
+
+void CheckStack ()
+{
+ uint16 spReg;
+ __asm mov spReg, sp
+
+ if (*(uint32 *) end != 0x12345678UL || spReg < (uint16) end)
+ {
+ __asm cli
+ __asm mov sp, TC_BOOT_LOADER_STACK_TOP
+
+ PrintError ("Stack overflow");
+ TC_THROW_FATAL_EXCEPTION;
+ }
+}
+
+
+void InitStackChecker ()
+{
+ *(uint32 *) end = 0x12345678UL;
+
+ PrintStackInfo();
+ PrintEndl();
+}
+
+#endif // TC_BOOT_STACK_CHECKING_ENABLED
diff --git a/src/Boot/Windows/BootDebug.h b/src/Boot/Windows/BootDebug.h
index 138dcf62..e7ae4134 100644
--- a/src/Boot/Windows/BootDebug.h
+++ b/src/Boot/Windows/BootDebug.h
@@ -1,60 +1,60 @@
-/*
- Derived from source code of TrueCrypt 7.1a, which is
- Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed
- by the TrueCrypt License 3.0.
-
- Modifications and additions to the original source code (contained in this file)
- and all other portions of this file are Copyright (c) 2013-2016 IDRIX
- and are governed by the Apache License 2.0 the full text of which is
- contained in the file License.txt included in VeraCrypt binary and source
- code distribution packages.
-*/
-
-#ifndef TC_HEADER_Boot_BootDebug
-#define TC_HEADER_Boot_BootDebug
-
-#include "Platform.h"
-#include "BootConsoleIo.h"
-
-#if 0
-# define TC_BOOT_DEBUG_ENABLED
-#endif
-
-#if 0 || defined (TC_BOOT_DEBUG_ENABLED)
-# define TC_BOOT_STACK_CHECKING_ENABLED
- extern "C" void CheckStack ();
-#else
-# define CheckStack()
-#endif
-
-#if 0
-# define TC_BOOT_TRACING_ENABLED
-# if 1
-# define TC_TRACE_INT13
-# endif
-# if 0
-# define TC_TRACE_INT15
-# endif
-#endif
-
-#ifdef TC_BOOT_DEBUG_ENABLED
-# define trace_point do { Print(__FILE__); PrintChar (':'); Print (TC_TO_STRING (__LINE__)); PrintEndl(); } while (false)
-# define trace_val(VAL) PrintVal (#VAL, VAL);
-# define trace_hex(VAL) do { Print (#VAL), PrintChar (':'); PrintHex (VAL); PrintEndl(); } while (false)
-# define assert(COND) do { if (!(COND)) { trace_point; __asm jmp $ } } while (false)
-#else
-# define trace_point
-# define trace_val(VAL)
-# define trace_hex(VAL)
-# define assert(COND)
-#endif
-
-void InitDebugPort ();
-void InitStackChecker ();
-void WriteDebugPort (byte dataByte);
-void PrintHexDump (byte *mem, size_t size, uint16 *memSegment = nullptr);
-void PrintHexDump (uint16 memSegment, uint16 memOffset, size_t size);
-void PrintVal (const char *message, const uint32 value, bool newLine = true, bool hex = false);
-void PrintVal (const char *message, const uint64 &value, bool newLine = true, bool hex = false);
-
-#endif // TC_HEADER_Boot_BootDebug
+/*
+ Derived from source code of TrueCrypt 7.1a, which is
+ Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed
+ by the TrueCrypt License 3.0.
+
+ Modifications and additions to the original source code (contained in this file)
+ and all other portions of this file are Copyright (c) 2013-2016 IDRIX
+ and are governed by the Apache License 2.0 the full text of which is
+ contained in the file License.txt included in VeraCrypt binary and source
+ code distribution packages.
+*/
+
+#ifndef TC_HEADER_Boot_BootDebug
+#define TC_HEADER_Boot_BootDebug
+
+#include "Platform.h"
+#include "BootConsoleIo.h"
+
+#if 0
+# define TC_BOOT_DEBUG_ENABLED
+#endif
+
+#if 0 || defined (TC_BOOT_DEBUG_ENABLED)
+# define TC_BOOT_STACK_CHECKING_ENABLED
+ extern "C" void CheckStack ();
+#else
+# define CheckStack()
+#endif
+
+#if 0
+# define TC_BOOT_TRACING_ENABLED
+# if 1
+# define TC_TRACE_INT13
+# endif
+# if 0
+# define TC_TRACE_INT15
+# endif
+#endif
+
+#ifdef TC_BOOT_DEBUG_ENABLED
+# define trace_point do { Print(__FILE__); PrintChar (':'); Print (TC_TO_STRING (__LINE__)); PrintEndl(); } while (false)
+# define trace_val(VAL) PrintVal (#VAL, VAL);
+# define trace_hex(VAL) do { Print (#VAL), PrintChar (':'); PrintHex (VAL); PrintEndl(); } while (false)
+# define assert(COND) do { if (!(COND)) { trace_point; __asm jmp $ } } while (false)
+#else
+# define trace_point
+# define trace_val(VAL)
+# define trace_hex(VAL)
+# define assert(COND)
+#endif
+
+void InitDebugPort ();
+void InitStackChecker ();
+void WriteDebugPort (byte dataByte);
+void PrintHexDump (byte *mem, size_t size, uint16 *memSegment = nullptr);
+void PrintHexDump (uint16 memSegment, uint16 memOffset, size_t size);
+void PrintVal (const char *message, const uint32 value, bool newLine = true, bool hex = false);
+void PrintVal (const char *message, const uint64 &value, bool newLine = true, bool hex = false);
+
+#endif // TC_HEADER_Boot_BootDebug
diff --git a/src/Boot/Windows/BootDefs.h b/src/Boot/Windows/BootDefs.h
index 69c57dbc..1fc923ae 100644
--- a/src/Boot/Windows/BootDefs.h
+++ b/src/Boot/Windows/BootDefs.h
@@ -1,199 +1,199 @@
-/*
- Derived from source code of TrueCrypt 7.1a, which is
- Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed
- by the TrueCrypt License 3.0.
-
- Modifications and additions to the original source code (contained in this file)
- and all other portions of this file are Copyright (c) 2013-2016 IDRIX
- and are governed by the Apache License 2.0 the full text of which is
- contained in the file License.txt included in VeraCrypt binary and source
- code distribution packages.
-*/
-
-#ifndef TC_HEADER_Boot_BootDefs
-#define TC_HEADER_Boot_BootDefs
-
-// Total memory required (CODE + DATA + BSS + STACK + 0x100) in KBytes - determined from linker map.
-#define TC__BOOT_MEMORY_REQUIRED 43
-
-#ifdef TC_WINDOWS_BOOT_SINGLE_CIPHER_MODE
-# undef TC__BOOT_MEMORY_REQUIRED
-
-# ifdef TC_WINDOWS_BOOT_AES
-# ifdef TC_WINDOWS_BOOT_RESCUE_DISK_MODE
-# define TC__BOOT_MEMORY_REQUIRED 31
-# else
-# define TC__BOOT_MEMORY_REQUIRED 29
-# endif
-# elif defined (TC_WINDOWS_BOOT_SERPENT)
-# define TC__BOOT_MEMORY_REQUIRED 33
-# elif defined (TC_WINDOWS_BOOT_TWOFISH)
-# define TC__BOOT_MEMORY_REQUIRED 41
-# endif
-
-#if 0
-# undef TC__BOOT_MEMORY_REQUIRED
-# define TC__BOOT_MEMORY_REQUIRED 60
-#endif
-
-#endif
-
-// Modifying this value can introduce incompatibility with previous versions
-#define TC__BOOT_LOADER_SEGMENT TC_HEX (9000) // Some buggy BIOS routines fail if CS bits 0-10 are not zero
-
-#if TC__BOOT_MEMORY_REQUIRED <= 32
-# define TC__BOOT_LOADER_SEGMENT_LOW (TC__BOOT_LOADER_SEGMENT - 32 * 1024 / 16)
-#else
-# define TC__BOOT_LOADER_SEGMENT_LOW (TC__BOOT_LOADER_SEGMENT - 64 * 1024 / 16)
-#endif
-
-#define TC__COM_EXECUTABLE_OFFSET TC_HEX (100)
-
-#define TC__BOOT_LOADER_LOWMEM_SEGMENT TC_HEX (2000)
-#define TC__BOOT_LOADER_BUFFER_SEGMENT TC_HEX (4000)
-#define TC__BOOT_LOADER_ALT_SEGMENT TC_HEX (6000)
-
-#define TC__BOOT_LOADER_STACK_TOP (TC_BOOT_MEMORY_REQUIRED * TC_UNSIGNED (1024) - 4)
-
-#define TC__LB_SIZE 512
-#define TC__BOOT_LOADER_AREA_SECTOR_COUNT 63
-
-#define TC__BOOT_SECTOR_VERSION_OFFSET 430
-#define TC__BOOT_SECTOR_LOADER_LENGTH_OFFSET 432
-#define TC__BOOT_SECTOR_LOADER_CHECKSUM_OFFSET 434
-#define TC__BOOT_SECTOR_USER_CONFIG_OFFSET 438
-#define TC__BOOT_SECTOR_CONFIG_OFFSET 439 // The last byte that is reserved for the boot loader
-
-#define TC__BOOT_SECTOR_USER_MESSAGE_MAX_LENGTH 24
-#define TC__BOOT_SECTOR_USER_MESSAGE_OFFSET (TC__BOOT_SECTOR_VERSION_OFFSET - TC__BOOT_SECTOR_USER_MESSAGE_MAX_LENGTH)
-
-#define TC__BOOT_SECTOR_OUTER_VOLUME_BAK_HEADER_CRC_SIZE 4
-#define TC__BOOT_SECTOR_OUTER_VOLUME_BAK_HEADER_CRC_OFFSET (TC__BOOT_SECTOR_USER_MESSAGE_OFFSET - TC__BOOT_SECTOR_OUTER_VOLUME_BAK_HEADER_CRC_SIZE)
-
-#define TC__BOOT_SECTOR_PIM_VALUE_SIZE 2
-#define TC__BOOT_SECTOR_PIM_VALUE_OFFSET (TC__BOOT_SECTOR_OUTER_VOLUME_BAK_HEADER_CRC_OFFSET - TC__BOOT_SECTOR_PIM_VALUE_SIZE)
-
-#define TC__BOOT_LOADER_DECOMPRESSOR_START_SECTOR 2
-#define TC__BOOT_LOADER_DECOMPRESSOR_SECTOR_COUNT 4
-#define TC__BOOT_LOADER_DECOMPRESSOR_MEMORY_SIZE 32768
-#define TC__BOOT_LOADER_COMPRESSED_BUFFER_OFFSET (TC_COM_EXECUTABLE_OFFSET + 3072)
-
-#define TC__BOOT_LOADER_START_SECTOR (TC_BOOT_LOADER_DECOMPRESSOR_START_SECTOR + TC_BOOT_LOADER_DECOMPRESSOR_SECTOR_COUNT)
-#define TC__MAX_BOOT_LOADER_SECTOR_COUNT (TC_BOOT_LOADER_AREA_SECTOR_COUNT - TC_BOOT_LOADER_DECOMPRESSOR_SECTOR_COUNT - 2)
-#define TC__MAX_BOOT_LOADER_DECOMPRESSED_SIZE ((TC_BOOT_LOADER_AREA_SECTOR_COUNT - 2) * TC_LB_SIZE)
-
-#define TC__BOOT_LOADER_BACKUP_SECTOR_COUNT 30
-
-#define TC__GZIP_HEADER_SIZE 10
-
-#define TC__BOOT_CFG_FLAG_AREA_SIZE 1 // In bytes
-
-// If you add more flags, revise TC__BOOT_CFG_FLAG_AREA_SIZE
-#define TC__BOOT_CFG_FLAG_BACKUP_LOADER_AVAILABLE TC_HEX (02)
-#define TC__BOOT_CFG_FLAG_WINDOWS_VISTA_OR_LATER TC_HEX (04)
-#define TC__BOOT_CFG_FLAG_RESCUE_DISABLE_HW_ENCRYPTION TC_HEX (10)
-#define TC__BOOT_CFG_FLAG_RESCUE_DISK_ORIG_SYS_LOADER TC_HEX (20)
-#define TC__BOOT_CFG_MASK_HIDDEN_OS_CREATION_PHASE (TC_HEX (40) + TC_HEX (80))
-
-// Modifying the following values can introduce incompatibility with previous versions
-#define TC__BOOT_USER_CFG_FLAG_SILENT_MODE TC_HEX (01)
-#define TC__BOOT_USER_CFG_FLAG_DISABLE_ESC TC_HEX (02)
-#define TC__BOOT_USER_CFG_FLAG_DISABLE_HW_ENCRYPTION TC_HEX (04)
-#define TC__BOOT_USER_CFG_FLAG_DISABLE_PIM TC_HEX (08)
-
-// The following items are treated as a 2-bit value (apply TC_BOOT_CFG_MASK_HIDDEN_OS_CREATION_PHASE to obtain the value)
-#define TC__HIDDEN_OS_CREATION_PHASE_NONE 0
-#define TC__HIDDEN_OS_CREATION_PHASE_CLONING TC_HEX (40) // The boot loader is to copy the content of the system partition to the hidden volume
-#define TC__HIDDEN_OS_CREATION_PHASE_WIPING TC_HEX (80) // The boot loader has successfully copied the content of the system partition to the hidden volume. The original OS is to be wiped now.
-#define TC__HIDDEN_OS_CREATION_PHASE_WIPED (TC_HEX (40) + TC_HEX (80)) // The original OS has been wiped. The user is required to install a new OS (decoy OS) on the system partition now.
-
-
-#ifdef TC_ASM_PREPROCESS
-
-#define TC_HEX(N) 0##N##h
-#define TC_UNSIGNED(N) N
-
-TC_BOOT_MEMORY_REQUIRED = TC__BOOT_MEMORY_REQUIRED
-TC_BOOT_LOADER_SEGMENT = TC__BOOT_LOADER_SEGMENT
-TC_BOOT_LOADER_SEGMENT_LOW = TC__BOOT_LOADER_SEGMENT_LOW
-TC_COM_EXECUTABLE_OFFSET = TC__COM_EXECUTABLE_OFFSET
-TC_BOOT_LOADER_LOWMEM_SEGMENT = TC__BOOT_LOADER_LOWMEM_SEGMENT
-TC_BOOT_LOADER_BUFFER_SEGMENT = TC__BOOT_LOADER_BUFFER_SEGMENT
-TC_BOOT_LOADER_ALT_SEGMENT = TC__BOOT_LOADER_ALT_SEGMENT
-TC_BOOT_LOADER_STACK_TOP = TC__BOOT_LOADER_STACK_TOP
-TC_LB_SIZE = TC__LB_SIZE
-TC_BOOT_LOADER_AREA_SECTOR_COUNT = TC__BOOT_LOADER_AREA_SECTOR_COUNT
-TC_BOOT_SECTOR_LOADER_LENGTH_OFFSET = TC__BOOT_SECTOR_LOADER_LENGTH_OFFSET
-TC_BOOT_SECTOR_LOADER_CHECKSUM_OFFSET = TC__BOOT_SECTOR_LOADER_CHECKSUM_OFFSET
-TC_BOOT_SECTOR_CONFIG_OFFSET = TC__BOOT_SECTOR_CONFIG_OFFSET
-TC_BOOT_SECTOR_USER_CONFIG_OFFSET = TC__BOOT_SECTOR_USER_CONFIG_OFFSET
-TC_BOOT_LOADER_DECOMPRESSOR_START_SECTOR = TC__BOOT_LOADER_DECOMPRESSOR_START_SECTOR
-TC_BOOT_LOADER_DECOMPRESSOR_SECTOR_COUNT = TC__BOOT_LOADER_DECOMPRESSOR_SECTOR_COUNT
-TC_BOOT_LOADER_DECOMPRESSOR_MEMORY_SIZE = TC__BOOT_LOADER_DECOMPRESSOR_MEMORY_SIZE
-TC_BOOT_LOADER_COMPRESSED_BUFFER_OFFSET = TC__BOOT_LOADER_COMPRESSED_BUFFER_OFFSET
-TC_BOOT_LOADER_START_SECTOR = TC__BOOT_LOADER_START_SECTOR
-TC_MAX_BOOT_LOADER_SECTOR_COUNT = TC__MAX_BOOT_LOADER_SECTOR_COUNT
-TC_MAX_BOOT_LOADER_DECOMPRESSED_SIZE = TC__MAX_BOOT_LOADER_DECOMPRESSED_SIZE
-TC_BOOT_LOADER_BACKUP_SECTOR_COUNT = TC__BOOT_LOADER_BACKUP_SECTOR_COUNT
-TC_GZIP_HEADER_SIZE = TC__GZIP_HEADER_SIZE
-TC_BOOT_CFG_FLAG_AREA_SIZE = TC__BOOT_CFG_FLAG_AREA_SIZE
-TC_BOOT_CFG_FLAG_BACKUP_LOADER_AVAILABLE = TC__BOOT_CFG_FLAG_BACKUP_LOADER_AVAILABLE
-TC_BOOT_CFG_FLAG_WINDOWS_VISTA_OR_LATER = TC__BOOT_CFG_FLAG_WINDOWS_VISTA_OR_LATER
-TC_BOOT_CFG_FLAG_RESCUE_DISK_ORIG_SYS_LOADER = TC__BOOT_CFG_FLAG_RESCUE_DISK_ORIG_SYS_LOADER
-TC_BOOT_CFG_MASK_HIDDEN_OS_CREATION_PHASE = TC__BOOT_CFG_MASK_HIDDEN_OS_CREATION_PHASE
-TC_BOOT_USER_CFG_FLAG_SILENT_MODE = TC__BOOT_USER_CFG_FLAG_SILENT_MODE
-TC_HIDDEN_OS_CREATION_PHASE_NONE = TC__HIDDEN_OS_CREATION_PHASE_NONE
-TC_HIDDEN_OS_CREATION_PHASE_CLONING = TC__HIDDEN_OS_CREATION_PHASE_CLONING
-TC_HIDDEN_OS_CREATION_PHASE_WIPING = TC__HIDDEN_OS_CREATION_PHASE_WIPING
-TC_HIDDEN_OS_CREATION_PHASE_WIPED = TC__HIDDEN_OS_CREATION_PHASE_WIPED
-
-#else // TC_ASM_PREPROCESS
-
-#define TC_HEX(N) 0x##N
-#define TC_UNSIGNED(N) N##U
-
-#define TC_BOOT_MEMORY_REQUIRED TC__BOOT_MEMORY_REQUIRED
-#define TC_BOOT_LOADER_SEGMENT TC__BOOT_LOADER_SEGMENT
-#define TC_COM_EXECUTABLE_OFFSET TC__COM_EXECUTABLE_OFFSET
-#define TC_BOOT_LOADER_LOWMEM_SEGMENT TC__BOOT_LOADER_LOWMEM_SEGMENT
-#define TC_BOOT_LOADER_BUFFER_SEGMENT TC__BOOT_LOADER_BUFFER_SEGMENT
-#define TC_BOOT_LOADER_ALT_SEGMENT TC__BOOT_LOADER_ALT_SEGMENT
-#define TC_BOOT_LOADER_STACK_TOP (TC__BOOT_LOADER_STACK_TOP)
-#define TC_BOOT_LOADER_AREA_SECTOR_COUNT TC__BOOT_LOADER_AREA_SECTOR_COUNT
-#define TC_BOOT_SECTOR_USER_MESSAGE_OFFSET TC__BOOT_SECTOR_USER_MESSAGE_OFFSET
-#define TC_BOOT_SECTOR_OUTER_VOLUME_BAK_HEADER_CRC_SIZE TC__BOOT_SECTOR_OUTER_VOLUME_BAK_HEADER_CRC_SIZE
-#define TC_BOOT_SECTOR_OUTER_VOLUME_BAK_HEADER_CRC_OFFSET TC__BOOT_SECTOR_OUTER_VOLUME_BAK_HEADER_CRC_OFFSET
-#define TC_BOOT_SECTOR_PIM_VALUE_SIZE TC__BOOT_SECTOR_PIM_VALUE_SIZE
-#define TC_BOOT_SECTOR_PIM_VALUE_OFFSET TC__BOOT_SECTOR_PIM_VALUE_OFFSET
-#define TC_BOOT_SECTOR_USER_MESSAGE_MAX_LENGTH TC__BOOT_SECTOR_USER_MESSAGE_MAX_LENGTH
-#define TC_BOOT_SECTOR_VERSION_OFFSET TC__BOOT_SECTOR_VERSION_OFFSET
-#define TC_BOOT_SECTOR_LOADER_LENGTH_OFFSET TC__BOOT_SECTOR_LOADER_LENGTH_OFFSET
-#define TC_BOOT_SECTOR_LOADER_CHECKSUM_OFFSET TC__BOOT_SECTOR_LOADER_CHECKSUM_OFFSET
-#define TC_BOOT_LOADER_DECOMPRESSOR_START_SECTOR TC__BOOT_LOADER_DECOMPRESSOR_START_SECTOR
-#define TC_BOOT_LOADER_DECOMPRESSOR_SECTOR_COUNT TC__BOOT_LOADER_DECOMPRESSOR_SECTOR_COUNT
-#define TC_BOOT_SECTOR_CONFIG_OFFSET TC__BOOT_SECTOR_CONFIG_OFFSET
-#define TC_BOOT_SECTOR_USER_CONFIG_OFFSET TC__BOOT_SECTOR_USER_CONFIG_OFFSET
-#define TC_BOOT_LOADER_START_SECTOR TC__BOOT_LOADER_START_SECTOR
-#define TC_LB_SIZE TC__LB_SIZE
-#define TC_MAX_BOOT_LOADER_SECTOR_COUNT TC__MAX_BOOT_LOADER_SECTOR_COUNT
-#define TC_MAX_BOOT_LOADER_DECOMPRESSED_SIZE TC__MAX_BOOT_LOADER_DECOMPRESSED_SIZE
-#define TC_BOOT_LOADER_BACKUP_SECTOR_COUNT TC__BOOT_LOADER_BACKUP_SECTOR_COUNT
-#define TC_GZIP_HEADER_SIZE TC__GZIP_HEADER_SIZE
-#define TC_BOOT_CFG_FLAG_AREA_SIZE TC__BOOT_CFG_FLAG_AREA_SIZE
-#define TC_BOOT_CFG_FLAG_BACKUP_LOADER_AVAILABLE TC__BOOT_CFG_FLAG_BACKUP_LOADER_AVAILABLE
-#define TC_BOOT_CFG_FLAG_WINDOWS_VISTA_OR_LATER TC__BOOT_CFG_FLAG_WINDOWS_VISTA_OR_LATER
-#define TC_BOOT_CFG_FLAG_RESCUE_DISK_ORIG_SYS_LOADER TC__BOOT_CFG_FLAG_RESCUE_DISK_ORIG_SYS_LOADER
-#define TC_BOOT_CFG_FLAG_RESCUE_DISABLE_HW_ENCRYPTION TC__BOOT_CFG_FLAG_RESCUE_DISABLE_HW_ENCRYPTION
-#define TC_BOOT_CFG_MASK_HIDDEN_OS_CREATION_PHASE TC__BOOT_CFG_MASK_HIDDEN_OS_CREATION_PHASE
-#define TC_BOOT_USER_CFG_FLAG_SILENT_MODE TC__BOOT_USER_CFG_FLAG_SILENT_MODE
-#define TC_BOOT_USER_CFG_FLAG_DISABLE_ESC TC__BOOT_USER_CFG_FLAG_DISABLE_ESC
-#define TC_BOOT_USER_CFG_FLAG_DISABLE_HW_ENCRYPTION TC__BOOT_USER_CFG_FLAG_DISABLE_HW_ENCRYPTION
-#define TC_BOOT_USER_CFG_FLAG_DISABLE_PIM TC__BOOT_USER_CFG_FLAG_DISABLE_PIM
-#define TC_HIDDEN_OS_CREATION_PHASE_NONE TC__HIDDEN_OS_CREATION_PHASE_NONE
-#define TC_HIDDEN_OS_CREATION_PHASE_CLONING TC__HIDDEN_OS_CREATION_PHASE_CLONING
-#define TC_HIDDEN_OS_CREATION_PHASE_WIPING TC__HIDDEN_OS_CREATION_PHASE_WIPING
-#define TC_HIDDEN_OS_CREATION_PHASE_WIPED TC__HIDDEN_OS_CREATION_PHASE_WIPED
-
-#endif // TC_ASM_PREPROCESS
-
-#endif // TC_HEADER_Boot_BootDefs
+/*
+ Derived from source code of TrueCrypt 7.1a, which is
+ Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed
+ by the TrueCrypt License 3.0.
+
+ Modifications and additions to the original source code (contained in this file)
+ and all other portions of this file are Copyright (c) 2013-2016 IDRIX
+ and are governed by the Apache License 2.0 the full text of which is
+ contained in the file License.txt included in VeraCrypt binary and source
+ code distribution packages.
+*/
+
+#ifndef TC_HEADER_Boot_BootDefs
+#define TC_HEADER_Boot_BootDefs
+
+// Total memory required (CODE + DATA + BSS + STACK + 0x100) in KBytes - determined from linker map.
+#define TC__BOOT_MEMORY_REQUIRED 43
+
+#ifdef TC_WINDOWS_BOOT_SINGLE_CIPHER_MODE
+# undef TC__BOOT_MEMORY_REQUIRED
+
+# ifdef TC_WINDOWS_BOOT_AES
+# ifdef TC_WINDOWS_BOOT_RESCUE_DISK_MODE
+# define TC__BOOT_MEMORY_REQUIRED 31
+# else
+# define TC__BOOT_MEMORY_REQUIRED 29
+# endif
+# elif defined (TC_WINDOWS_BOOT_SERPENT)
+# define TC__BOOT_MEMORY_REQUIRED 33
+# elif defined (TC_WINDOWS_BOOT_TWOFISH)
+# define TC__BOOT_MEMORY_REQUIRED 41
+# endif
+
+#if 0
+# undef TC__BOOT_MEMORY_REQUIRED
+# define TC__BOOT_MEMORY_REQUIRED 60
+#endif
+
+#endif
+
+// Modifying this value can introduce incompatibility with previous versions
+#define TC__BOOT_LOADER_SEGMENT TC_HEX (9000) // Some buggy BIOS routines fail if CS bits 0-10 are not zero
+
+#if TC__BOOT_MEMORY_REQUIRED <= 32
+# define TC__BOOT_LOADER_SEGMENT_LOW (TC__BOOT_LOADER_SEGMENT - 32 * 1024 / 16)
+#else
+# define TC__BOOT_LOADER_SEGMENT_LOW (TC__BOOT_LOADER_SEGMENT - 64 * 1024 / 16)
+#endif
+
+#define TC__COM_EXECUTABLE_OFFSET TC_HEX (100)
+
+#define TC__BOOT_LOADER_LOWMEM_SEGMENT TC_HEX (2000)
+#define TC__BOOT_LOADER_BUFFER_SEGMENT TC_HEX (4000)
+#define TC__BOOT_LOADER_ALT_SEGMENT TC_HEX (6000)
+
+#define TC__BOOT_LOADER_STACK_TOP (TC_BOOT_MEMORY_REQUIRED * TC_UNSIGNED (1024) - 4)
+
+#define TC__LB_SIZE 512
+#define TC__BOOT_LOADER_AREA_SECTOR_COUNT 63
+
+#define TC__BOOT_SECTOR_VERSION_OFFSET 430
+#define TC__BOOT_SECTOR_LOADER_LENGTH_OFFSET 432
+#define TC__BOOT_SECTOR_LOADER_CHECKSUM_OFFSET 434
+#define TC__BOOT_SECTOR_USER_CONFIG_OFFSET 438
+#define TC__BOOT_SECTOR_CONFIG_OFFSET 439 // The last byte that is reserved for the boot loader
+
+#define TC__BOOT_SECTOR_USER_MESSAGE_MAX_LENGTH 24
+#define TC__BOOT_SECTOR_USER_MESSAGE_OFFSET (TC__BOOT_SECTOR_VERSION_OFFSET - TC__BOOT_SECTOR_USER_MESSAGE_MAX_LENGTH)
+
+#define TC__BOOT_SECTOR_OUTER_VOLUME_BAK_HEADER_CRC_SIZE 4
+#define TC__BOOT_SECTOR_OUTER_VOLUME_BAK_HEADER_CRC_OFFSET (TC__BOOT_SECTOR_USER_MESSAGE_OFFSET - TC__BOOT_SECTOR_OUTER_VOLUME_BAK_HEADER_CRC_SIZE)
+
+#define TC__BOOT_SECTOR_PIM_VALUE_SIZE 2
+#define TC__BOOT_SECTOR_PIM_VALUE_OFFSET (TC__BOOT_SECTOR_OUTER_VOLUME_BAK_HEADER_CRC_OFFSET - TC__BOOT_SECTOR_PIM_VALUE_SIZE)
+
+#define TC__BOOT_LOADER_DECOMPRESSOR_START_SECTOR 2
+#define TC__BOOT_LOADER_DECOMPRESSOR_SECTOR_COUNT 4
+#define TC__BOOT_LOADER_DECOMPRESSOR_MEMORY_SIZE 32768
+#define TC__BOOT_LOADER_COMPRESSED_BUFFER_OFFSET (TC_COM_EXECUTABLE_OFFSET + 3072)
+
+#define TC__BOOT_LOADER_START_SECTOR (TC_BOOT_LOADER_DECOMPRESSOR_START_SECTOR + TC_BOOT_LOADER_DECOMPRESSOR_SECTOR_COUNT)
+#define TC__MAX_BOOT_LOADER_SECTOR_COUNT (TC_BOOT_LOADER_AREA_SECTOR_COUNT - TC_BOOT_LOADER_DECOMPRESSOR_SECTOR_COUNT - 2)
+#define TC__MAX_BOOT_LOADER_DECOMPRESSED_SIZE ((TC_BOOT_LOADER_AREA_SECTOR_COUNT - 2) * TC_LB_SIZE)
+
+#define TC__BOOT_LOADER_BACKUP_SECTOR_COUNT 30
+
+#define TC__GZIP_HEADER_SIZE 10
+
+#define TC__BOOT_CFG_FLAG_AREA_SIZE 1 // In bytes
+
+// If you add more flags, revise TC__BOOT_CFG_FLAG_AREA_SIZE
+#define TC__BOOT_CFG_FLAG_BACKUP_LOADER_AVAILABLE TC_HEX (02)
+#define TC__BOOT_CFG_FLAG_WINDOWS_VISTA_OR_LATER TC_HEX (04)
+#define TC__BOOT_CFG_FLAG_RESCUE_DISABLE_HW_ENCRYPTION TC_HEX (10)
+#define TC__BOOT_CFG_FLAG_RESCUE_DISK_ORIG_SYS_LOADER TC_HEX (20)
+#define TC__BOOT_CFG_MASK_HIDDEN_OS_CREATION_PHASE (TC_HEX (40) + TC_HEX (80))
+
+// Modifying the following values can introduce incompatibility with previous versions
+#define TC__BOOT_USER_CFG_FLAG_SILENT_MODE TC_HEX (01)
+#define TC__BOOT_USER_CFG_FLAG_DISABLE_ESC TC_HEX (02)
+#define TC__BOOT_USER_CFG_FLAG_DISABLE_HW_ENCRYPTION TC_HEX (04)
+#define TC__BOOT_USER_CFG_FLAG_DISABLE_PIM TC_HEX (08)
+
+// The following items are treated as a 2-bit value (apply TC_BOOT_CFG_MASK_HIDDEN_OS_CREATION_PHASE to obtain the value)
+#define TC__HIDDEN_OS_CREATION_PHASE_NONE 0
+#define TC__HIDDEN_OS_CREATION_PHASE_CLONING TC_HEX (40) // The boot loader is to copy the content of the system partition to the hidden volume
+#define TC__HIDDEN_OS_CREATION_PHASE_WIPING TC_HEX (80) // The boot loader has successfully copied the content of the system partition to the hidden volume. The original OS is to be wiped now.
+#define TC__HIDDEN_OS_CREATION_PHASE_WIPED (TC_HEX (40) + TC_HEX (80)) // The original OS has been wiped. The user is required to install a new OS (decoy OS) on the system partition now.
+
+
+#ifdef TC_ASM_PREPROCESS
+
+#define TC_HEX(N) 0##N##h
+#define TC_UNSIGNED(N) N
+
+TC_BOOT_MEMORY_REQUIRED = TC__BOOT_MEMORY_REQUIRED
+TC_BOOT_LOADER_SEGMENT = TC__BOOT_LOADER_SEGMENT
+TC_BOOT_LOADER_SEGMENT_LOW = TC__BOOT_LOADER_SEGMENT_LOW
+TC_COM_EXECUTABLE_OFFSET = TC__COM_EXECUTABLE_OFFSET
+TC_BOOT_LOADER_LOWMEM_SEGMENT = TC__BOOT_LOADER_LOWMEM_SEGMENT
+TC_BOOT_LOADER_BUFFER_SEGMENT = TC__BOOT_LOADER_BUFFER_SEGMENT
+TC_BOOT_LOADER_ALT_SEGMENT = TC__BOOT_LOADER_ALT_SEGMENT
+TC_BOOT_LOADER_STACK_TOP = TC__BOOT_LOADER_STACK_TOP
+TC_LB_SIZE = TC__LB_SIZE
+TC_BOOT_LOADER_AREA_SECTOR_COUNT = TC__BOOT_LOADER_AREA_SECTOR_COUNT
+TC_BOOT_SECTOR_LOADER_LENGTH_OFFSET = TC__BOOT_SECTOR_LOADER_LENGTH_OFFSET
+TC_BOOT_SECTOR_LOADER_CHECKSUM_OFFSET = TC__BOOT_SECTOR_LOADER_CHECKSUM_OFFSET
+TC_BOOT_SECTOR_CONFIG_OFFSET = TC__BOOT_SECTOR_CONFIG_OFFSET
+TC_BOOT_SECTOR_USER_CONFIG_OFFSET = TC__BOOT_SECTOR_USER_CONFIG_OFFSET
+TC_BOOT_LOADER_DECOMPRESSOR_START_SECTOR = TC__BOOT_LOADER_DECOMPRESSOR_START_SECTOR
+TC_BOOT_LOADER_DECOMPRESSOR_SECTOR_COUNT = TC__BOOT_LOADER_DECOMPRESSOR_SECTOR_COUNT
+TC_BOOT_LOADER_DECOMPRESSOR_MEMORY_SIZE = TC__BOOT_LOADER_DECOMPRESSOR_MEMORY_SIZE
+TC_BOOT_LOADER_COMPRESSED_BUFFER_OFFSET = TC__BOOT_LOADER_COMPRESSED_BUFFER_OFFSET
+TC_BOOT_LOADER_START_SECTOR = TC__BOOT_LOADER_START_SECTOR
+TC_MAX_BOOT_LOADER_SECTOR_COUNT = TC__MAX_BOOT_LOADER_SECTOR_COUNT
+TC_MAX_BOOT_LOADER_DECOMPRESSED_SIZE = TC__MAX_BOOT_LOADER_DECOMPRESSED_SIZE
+TC_BOOT_LOADER_BACKUP_SECTOR_COUNT = TC__BOOT_LOADER_BACKUP_SECTOR_COUNT
+TC_GZIP_HEADER_SIZE = TC__GZIP_HEADER_SIZE
+TC_BOOT_CFG_FLAG_AREA_SIZE = TC__BOOT_CFG_FLAG_AREA_SIZE
+TC_BOOT_CFG_FLAG_BACKUP_LOADER_AVAILABLE = TC__BOOT_CFG_FLAG_BACKUP_LOADER_AVAILABLE
+TC_BOOT_CFG_FLAG_WINDOWS_VISTA_OR_LATER = TC__BOOT_CFG_FLAG_WINDOWS_VISTA_OR_LATER
+TC_BOOT_CFG_FLAG_RESCUE_DISK_ORIG_SYS_LOADER = TC__BOOT_CFG_FLAG_RESCUE_DISK_ORIG_SYS_LOADER
+TC_BOOT_CFG_MASK_HIDDEN_OS_CREATION_PHASE = TC__BOOT_CFG_MASK_HIDDEN_OS_CREATION_PHASE
+TC_BOOT_USER_CFG_FLAG_SILENT_MODE = TC__BOOT_USER_CFG_FLAG_SILENT_MODE
+TC_HIDDEN_OS_CREATION_PHASE_NONE = TC__HIDDEN_OS_CREATION_PHASE_NONE
+TC_HIDDEN_OS_CREATION_PHASE_CLONING = TC__HIDDEN_OS_CREATION_PHASE_CLONING
+TC_HIDDEN_OS_CREATION_PHASE_WIPING = TC__HIDDEN_OS_CREATION_PHASE_WIPING
+TC_HIDDEN_OS_CREATION_PHASE_WIPED = TC__HIDDEN_OS_CREATION_PHASE_WIPED
+
+#else // TC_ASM_PREPROCESS
+
+#define TC_HEX(N) 0x##N
+#define TC_UNSIGNED(N) N##U
+
+#define TC_BOOT_MEMORY_REQUIRED TC__BOOT_MEMORY_REQUIRED
+#define TC_BOOT_LOADER_SEGMENT TC__BOOT_LOADER_SEGMENT
+#define TC_COM_EXECUTABLE_OFFSET TC__COM_EXECUTABLE_OFFSET
+#define TC_BOOT_LOADER_LOWMEM_SEGMENT TC__BOOT_LOADER_LOWMEM_SEGMENT
+#define TC_BOOT_LOADER_BUFFER_SEGMENT TC__BOOT_LOADER_BUFFER_SEGMENT
+#define TC_BOOT_LOADER_ALT_SEGMENT TC__BOOT_LOADER_ALT_SEGMENT
+#define TC_BOOT_LOADER_STACK_TOP (TC__BOOT_LOADER_STACK_TOP)
+#define TC_BOOT_LOADER_AREA_SECTOR_COUNT TC__BOOT_LOADER_AREA_SECTOR_COUNT
+#define TC_BOOT_SECTOR_USER_MESSAGE_OFFSET TC__BOOT_SECTOR_USER_MESSAGE_OFFSET
+#define TC_BOOT_SECTOR_OUTER_VOLUME_BAK_HEADER_CRC_SIZE TC__BOOT_SECTOR_OUTER_VOLUME_BAK_HEADER_CRC_SIZE
+#define TC_BOOT_SECTOR_OUTER_VOLUME_BAK_HEADER_CRC_OFFSET TC__BOOT_SECTOR_OUTER_VOLUME_BAK_HEADER_CRC_OFFSET
+#define TC_BOOT_SECTOR_PIM_VALUE_SIZE TC__BOOT_SECTOR_PIM_VALUE_SIZE
+#define TC_BOOT_SECTOR_PIM_VALUE_OFFSET TC__BOOT_SECTOR_PIM_VALUE_OFFSET
+#define TC_BOOT_SECTOR_USER_MESSAGE_MAX_LENGTH TC__BOOT_SECTOR_USER_MESSAGE_MAX_LENGTH
+#define TC_BOOT_SECTOR_VERSION_OFFSET TC__BOOT_SECTOR_VERSION_OFFSET
+#define TC_BOOT_SECTOR_LOADER_LENGTH_OFFSET TC__BOOT_SECTOR_LOADER_LENGTH_OFFSET
+#define TC_BOOT_SECTOR_LOADER_CHECKSUM_OFFSET TC__BOOT_SECTOR_LOADER_CHECKSUM_OFFSET
+#define TC_BOOT_LOADER_DECOMPRESSOR_START_SECTOR TC__BOOT_LOADER_DECOMPRESSOR_START_SECTOR
+#define TC_BOOT_LOADER_DECOMPRESSOR_SECTOR_COUNT TC__BOOT_LOADER_DECOMPRESSOR_SECTOR_COUNT
+#define TC_BOOT_SECTOR_CONFIG_OFFSET TC__BOOT_SECTOR_CONFIG_OFFSET
+#define TC_BOOT_SECTOR_USER_CONFIG_OFFSET TC__BOOT_SECTOR_USER_CONFIG_OFFSET
+#define TC_BOOT_LOADER_START_SECTOR TC__BOOT_LOADER_START_SECTOR
+#define TC_LB_SIZE TC__LB_SIZE
+#define TC_MAX_BOOT_LOADER_SECTOR_COUNT TC__MAX_BOOT_LOADER_SECTOR_COUNT
+#define TC_MAX_BOOT_LOADER_DECOMPRESSED_SIZE TC__MAX_BOOT_LOADER_DECOMPRESSED_SIZE
+#define TC_BOOT_LOADER_BACKUP_SECTOR_COUNT TC__BOOT_LOADER_BACKUP_SECTOR_COUNT
+#define TC_GZIP_HEADER_SIZE TC__GZIP_HEADER_SIZE
+#define TC_BOOT_CFG_FLAG_AREA_SIZE TC__BOOT_CFG_FLAG_AREA_SIZE
+#define TC_BOOT_CFG_FLAG_BACKUP_LOADER_AVAILABLE TC__BOOT_CFG_FLAG_BACKUP_LOADER_AVAILABLE
+#define TC_BOOT_CFG_FLAG_WINDOWS_VISTA_OR_LATER TC__BOOT_CFG_FLAG_WINDOWS_VISTA_OR_LATER
+#define TC_BOOT_CFG_FLAG_RESCUE_DISK_ORIG_SYS_LOADER TC__BOOT_CFG_FLAG_RESCUE_DISK_ORIG_SYS_LOADER
+#define TC_BOOT_CFG_FLAG_RESCUE_DISABLE_HW_ENCRYPTION TC__BOOT_CFG_FLAG_RESCUE_DISABLE_HW_ENCRYPTION
+#define TC_BOOT_CFG_MASK_HIDDEN_OS_CREATION_PHASE TC__BOOT_CFG_MASK_HIDDEN_OS_CREATION_PHASE
+#define TC_BOOT_USER_CFG_FLAG_SILENT_MODE TC__BOOT_USER_CFG_FLAG_SILENT_MODE
+#define TC_BOOT_USER_CFG_FLAG_DISABLE_ESC TC__BOOT_USER_CFG_FLAG_DISABLE_ESC
+#define TC_BOOT_USER_CFG_FLAG_DISABLE_HW_ENCRYPTION TC__BOOT_USER_CFG_FLAG_DISABLE_HW_ENCRYPTION
+#define TC_BOOT_USER_CFG_FLAG_DISABLE_PIM TC__BOOT_USER_CFG_FLAG_DISABLE_PIM
+#define TC_HIDDEN_OS_CREATION_PHASE_NONE TC__HIDDEN_OS_CREATION_PHASE_NONE
+#define TC_HIDDEN_OS_CREATION_PHASE_CLONING TC__HIDDEN_OS_CREATION_PHASE_CLONING
+#define TC_HIDDEN_OS_CREATION_PHASE_WIPING TC__HIDDEN_OS_CREATION_PHASE_WIPING
+#define TC_HIDDEN_OS_CREATION_PHASE_WIPED TC__HIDDEN_OS_CREATION_PHASE_WIPED
+
+#endif // TC_ASM_PREPROCESS
+
+#endif // TC_HEADER_Boot_BootDefs
diff --git a/src/Boot/Windows/BootDiskIo.cpp b/src/Boot/Windows/BootDiskIo.cpp
index 31917a64..15d6f711 100644
--- a/src/Boot/Windows/BootDiskIo.cpp
+++ b/src/Boot/Windows/BootDiskIo.cpp
@@ -1,491 +1,491 @@
-/*
- Derived from source code of TrueCrypt 7.1a, which is
- Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed
- by the TrueCrypt License 3.0.
-
- Modifications and additions to the original source code (contained in this file)
- and all other portions of this file are Copyright (c) 2013-2016 IDRIX
- and are governed by the Apache License 2.0 the full text of which is
- contained in the file License.txt included in VeraCrypt binary and source
- code distribution packages.
-*/
-
-#include "Bios.h"
-#include "BootConsoleIo.h"
-#include "BootConfig.h"
-#include "BootDebug.h"
-#include "BootDefs.h"
-#include "BootDiskIo.h"
-#include "BootStrings.h"
-
-
-byte SectorBuffer[TC_LB_SIZE];
-
-#ifdef TC_BOOT_DEBUG_ENABLED
-static bool SectorBufferInUse = false;
-
-void AcquireSectorBuffer ()
-{
- if (SectorBufferInUse)
- TC_THROW_FATAL_EXCEPTION;
-
- SectorBufferInUse = true;
-}
-
-
-void ReleaseSectorBuffer ()
-{
- SectorBufferInUse = false;
-}
-
-#endif
-
-
-bool IsLbaSupported (byte drive)
-{
- static byte CachedDrive = TC_INVALID_BIOS_DRIVE;
- static bool CachedStatus;
- uint16 result = 0;
-
- if (CachedDrive == drive)
- goto ret;
-
- __asm
- {
- mov bx, 0x55aa
- mov dl, drive
- mov ah, 0x41
- int 0x13
- jc err
- mov result, bx
- err:
- }
-
- CachedDrive = drive;
- CachedStatus = (result == 0xaa55);
-ret:
- return CachedStatus;
-}
-
-
-void PrintDiskError (BiosResult error, bool write, byte drive, const uint64 *sector, const ChsAddress *chs)
-{
- PrintEndl();
- Print (write ? "Write" : "Read"); Print (" error:");
- Print (error);
- Print (" Drive:");
- Print (drive ^ 0x80);
-
- if (sector)
- {
- Print (" Sector:");
- Print (*sector);
- }
-
- if (chs)
- {
- Print (" CHS:");
- Print (*chs);
- }
-
- PrintEndl();
- Beep();
-}
-
-
-void Print (const ChsAddress &chs)
-{
- Print (chs.Cylinder);
- PrintChar ('/');
- Print (chs.Head);
- PrintChar ('/');
- Print (chs.Sector);
-}
-
-
-void PrintSectorCountInMB (const uint64 &sectorCount)
-{
- Print (sectorCount >> (TC_LB_SIZE_BIT_SHIFT_DIVISOR + 2)); Print (" MB ");
-}
-
-
-BiosResult ReadWriteSectors (bool write, uint16 bufferSegment, uint16 bufferOffset, byte drive, const ChsAddress &chs, byte sectorCount, bool silent)
-{
- CheckStack();
-
- byte cylinderLow = (byte) chs.Cylinder;
- byte sector = chs.Sector;
- sector |= byte (chs.Cylinder >> 2) & 0xc0;
- byte function = write ? 0x03 : 0x02;
-
- BiosResult result;
- byte tryCount = TC_MAX_BIOS_DISK_IO_RETRIES;
-
- do
- {
- result = BiosResultSuccess;
-
- __asm
- {
- push es
- mov ax, bufferSegment
- mov es, ax
- mov bx, bufferOffset
- mov dl, drive
- mov ch, cylinderLow
- mov si, chs
- mov dh, [si].Head
- mov cl, sector
- mov al, sectorCount
- mov ah, function
- int 0x13
- jnc ok // If CF=0, ignore AH to prevent issues caused by potential bugs in BIOSes
- mov result, ah
- ok:
- pop es
- }
-
- if (result == BiosResultEccCorrected)
- result = BiosResultSuccess;
-
- // Some BIOSes report I/O errors prematurely in some cases
- } while (result != BiosResultSuccess && --tryCount != 0);
-
- if (!silent && result != BiosResultSuccess)
- PrintDiskError (result, write, drive, nullptr, &chs);
-
- return result;
-}
-
-
-BiosResult ReadWriteSectors (bool write, byte *buffer, byte drive, const ChsAddress &chs, byte sectorCount, bool silent)
-{
- uint16 codeSeg;
- __asm mov codeSeg, cs
- return ReadWriteSectors (write, codeSeg, (uint16) buffer, drive, chs, sectorCount, silent);
-}
-
-
-BiosResult ReadSectors (byte *buffer, byte drive, const ChsAddress &chs, byte sectorCount, bool silent)
-{
- return ReadWriteSectors (false, buffer, drive, chs, sectorCount, silent);
-}
-
-
-BiosResult WriteSectors (byte *buffer, byte drive, const ChsAddress &chs, byte sectorCount, bool silent)
-{
- return ReadWriteSectors (true, buffer, drive, chs, sectorCount, silent);
-}
-
-
-static BiosResult ReadWriteSectors (bool write, BiosLbaPacket &dapPacket, byte drive, const uint64 &sector, uint16 sectorCount, bool silent)
-{
- CheckStack();
-
- if (!IsLbaSupported (drive))
- {
- DriveGeometry geometry;
-
- BiosResult result = GetDriveGeometry (drive, geometry, silent);
- if (result != BiosResultSuccess)
- return result;
-
- ChsAddress chs;
- LbaToChs (geometry, sector, chs);
- return ReadWriteSectors (write, (uint16) (dapPacket.Buffer >> 16), (uint16) dapPacket.Buffer, drive, chs, sectorCount, silent);
- }
-
- dapPacket.Size = sizeof (dapPacket);
- dapPacket.Reserved = 0;
- dapPacket.SectorCount = sectorCount;
- dapPacket.Sector = sector;
-
- byte function = write ? 0x43 : 0x42;
-
- BiosResult result;
- byte tryCount = TC_MAX_BIOS_DISK_IO_RETRIES;
-
- do
- {
- result = BiosResultSuccess;
-
- __asm
- {
- mov bx, 0x55aa
- mov dl, drive
- mov si, [dapPacket]
- mov ah, function
- xor al, al
- int 0x13
- jnc ok // If CF=0, ignore AH to prevent issues caused by potential bugs in BIOSes
- mov result, ah
- ok:
- }
-
- if (result == BiosResultEccCorrected)
- result = BiosResultSuccess;
-
- // Some BIOSes report I/O errors prematurely in some cases
- } while (result != BiosResultSuccess && --tryCount != 0);
-
- if (!silent && result != BiosResultSuccess)
- PrintDiskError (result, write, drive, &sector);
-
- return result;
-}
-
-
-static BiosResult ReadWriteSectors (bool write, byte *buffer, byte drive, const uint64 &sector, uint16 sectorCount, bool silent)
-{
- BiosLbaPacket dapPacket;
- dapPacket.Buffer = (uint32) buffer;
- return ReadWriteSectors (write, dapPacket, drive, sector, sectorCount, silent);
-}
-
-
-BiosResult ReadWriteSectors (bool write, uint16 bufferSegment, uint16 bufferOffset, byte drive, const uint64 &sector, uint16 sectorCount, bool silent)
-{
- BiosLbaPacket dapPacket;
- dapPacket.Buffer = ((uint32) bufferSegment << 16) | bufferOffset;
- return ReadWriteSectors (write, dapPacket, drive, sector, sectorCount, silent);
-}
-
-BiosResult ReadSectors (uint16 bufferSegment, uint16 bufferOffset, byte drive, const uint64 &sector, uint16 sectorCount, bool silent)
-{
- return ReadWriteSectors (false, bufferSegment, bufferOffset, drive, sector, sectorCount, silent);
-}
-
-
-BiosResult ReadSectors (byte *buffer, byte drive, const uint64 &sector, uint16 sectorCount, bool silent)
-{
- BiosResult result;
- uint16 codeSeg;
- __asm mov codeSeg, cs
-
- result = ReadSectors (BootStarted ? codeSeg : TC_BOOT_LOADER_ALT_SEGMENT, (uint16) buffer, drive, sector, sectorCount, silent);
-
- // Alternative segment is used to prevent memory corruption caused by buggy BIOSes
- if (!BootStarted)
- CopyMemory (TC_BOOT_LOADER_ALT_SEGMENT, (uint16) buffer, buffer, sectorCount * TC_LB_SIZE);
-
- return result;
-}
-
-
-BiosResult WriteSectors (byte *buffer, byte drive, const uint64 &sector, uint16 sectorCount, bool silent)
-{
- return ReadWriteSectors (true, buffer, drive, sector, sectorCount, silent);
-}
-
-
-BiosResult GetDriveGeometry (byte drive, DriveGeometry &geometry, bool silent)
-{
- CheckStack();
-
- byte maxCylinderLow, maxHead, maxSector;
- BiosResult result;
- __asm
- {
- push es
- mov dl, drive
- mov ah, 0x08
- int 0x13
-
- mov result, ah
- mov maxCylinderLow, ch
- mov maxSector, cl
- mov maxHead, dh
- pop es
- }
-
- if (result == BiosResultSuccess)
- {
- geometry.Cylinders = (maxCylinderLow | (uint16 (maxSector & 0xc0) << 2)) + 1;
- geometry.Heads = maxHead + 1;
- geometry.Sectors = maxSector & ~0xc0;
- }
- else if (!silent)
- {
- Print ("Drive ");
- Print (drive ^ 0x80);
- Print (" not found: ");
- PrintErrorNoEndl ("");
- Print (result);
- PrintEndl();
- }
-
- return result;
-}
-
-
-void ChsToLba (const DriveGeometry &geometry, const ChsAddress &chs, uint64 &lba)
-{
- lba.HighPart = 0;
- lba.LowPart = (uint32 (chs.Cylinder) * geometry.Heads + chs.Head) * geometry.Sectors + chs.Sector - 1;
-}
-
-
-void LbaToChs (const DriveGeometry &geometry, const uint64 &lba, ChsAddress &chs)
-{
- chs.Sector = (byte) ((lba.LowPart % geometry.Sectors) + 1);
- uint32 ch = lba.LowPart / geometry.Sectors;
- chs.Head = (byte) (ch % geometry.Heads);
- chs.Cylinder = (uint16) (ch / geometry.Heads);
-}
-
-
-void PartitionEntryMBRToPartition (const PartitionEntryMBR &partEntry, Partition &partition)
-{
- partition.Active = partEntry.BootIndicator == 0x80;
- partition.EndSector.HighPart = 0;
- partition.EndSector.LowPart = partEntry.StartLBA + partEntry.SectorCountLBA - 1;
- partition.SectorCount.HighPart = 0;
- partition.SectorCount.LowPart = partEntry.SectorCountLBA;
- partition.StartSector.HighPart = 0;
- partition.StartSector.LowPart = partEntry.StartLBA;
- partition.Type = partEntry.Type;
-}
-
-
-BiosResult ReadWriteMBR (bool write, byte drive, bool silent)
-{
- uint64 mbrSector;
- mbrSector.HighPart = 0;
- mbrSector.LowPart = 0;
-
- if (write)
- return WriteSectors (SectorBuffer, drive, mbrSector, 1, silent);
-
- return ReadSectors (SectorBuffer, drive, mbrSector, 1, silent); // Uses alternative segment
-}
-
-
-BiosResult GetDrivePartitions (byte drive, Partition *partitionArray, size_t partitionArrayCapacity, size_t &partitionCount, bool activeOnly, Partition *findPartitionFollowingThis, bool silent)
-{
- Partition *followingPartition;
- Partition tmpPartition;
-
- if (findPartitionFollowingThis)
- {
- assert (partitionArrayCapacity == 1);
- partitionArrayCapacity = 0xff;
- followingPartition = partitionArray;
- partitionArray = &tmpPartition;
-
- followingPartition->Drive = TC_INVALID_BIOS_DRIVE;
- followingPartition->StartSector.LowPart = 0xFFFFffffUL;
- }
-
- AcquireSectorBuffer();
- BiosResult result = ReadWriteMBR (false, drive, silent);
- ReleaseSectorBuffer();
-
- partitionCount = 0;
-
- MBR *mbr = (MBR *) SectorBuffer;
- if (result != BiosResultSuccess || mbr->Signature != 0xaa55)
- return result;
-
- PartitionEntryMBR mbrPartitions[4];
- memcpy (mbrPartitions, mbr->Partitions, sizeof (mbrPartitions));
- size_t partitionArrayPos = 0, partitionNumber;
-
- for (partitionNumber = 0;
- partitionNumber < array_capacity (mbrPartitions) && partitionArrayPos < partitionArrayCapacity;
- ++partitionNumber)
- {
- const PartitionEntryMBR &partEntry = mbrPartitions[partitionNumber];
-
- if (partEntry.SectorCountLBA > 0)
- {
- Partition &partition = partitionArray[partitionArrayPos];
- PartitionEntryMBRToPartition (partEntry, partition);
-
- if (activeOnly && !partition.Active)
- continue;
-
- partition.Drive = drive;
- partition.Number = partitionArrayPos;
-
- if (partEntry.Type == 0x5 || partEntry.Type == 0xf) // Extended partition
- {
- if (IsLbaSupported (drive))
- {
- // Find all extended partitions
- uint64 firstExtStartLBA = partition.StartSector;
- uint64 extStartLBA = partition.StartSector;
- MBR *extMbr = (MBR *) SectorBuffer;
-
- while (partitionArrayPos < partitionArrayCapacity &&
- (result = ReadSectors ((byte *) extMbr, drive, extStartLBA, 1, silent)) == BiosResultSuccess
- && extMbr->Signature == 0xaa55)
- {
- if (extMbr->Partitions[0].SectorCountLBA > 0)
- {
- Partition &logPart = partitionArray[partitionArrayPos];
- PartitionEntryMBRToPartition (extMbr->Partitions[0], logPart);
- logPart.Drive = drive;
-
- logPart.Number = partitionArrayPos;
- logPart.Primary = false;
-
- logPart.StartSector.LowPart += extStartLBA.LowPart;
- logPart.EndSector.LowPart += extStartLBA.LowPart;
-
- if (findPartitionFollowingThis)
- {
- if (logPart.StartSector.LowPart > findPartitionFollowingThis->EndSector.LowPart
- && logPart.StartSector.LowPart < followingPartition->StartSector.LowPart)
- {
- *followingPartition = logPart;
- }
- }
- else
- ++partitionArrayPos;
- }
-
- // Secondary extended
- if (extMbr->Partitions[1].Type != 0x5 && extMbr->Partitions[1].Type == 0xf
- || extMbr->Partitions[1].SectorCountLBA == 0)
- break;
-
- extStartLBA.LowPart = extMbr->Partitions[1].StartLBA + firstExtStartLBA.LowPart;
- }
- }
- }
- else
- {
- partition.Primary = true;
-
- if (findPartitionFollowingThis)
- {
- if (partition.StartSector.LowPart > findPartitionFollowingThis->EndSector.LowPart
- && partition.StartSector.LowPart < followingPartition->StartSector.LowPart)
- {
- *followingPartition = partition;
- }
- }
- else
- ++partitionArrayPos;
- }
- }
- }
-
- partitionCount = partitionArrayPos;
- return result;
-}
-
-
-bool GetActivePartition (byte drive)
-{
- size_t partCount;
-
- if (GetDrivePartitions (drive, &ActivePartition, 1, partCount, true) != BiosResultSuccess || partCount < 1)
- {
- ActivePartition.Drive = TC_INVALID_BIOS_DRIVE;
- PrintError (TC_BOOT_STR_NO_BOOT_PARTITION);
- return false;
- }
-
- return true;
-}
+/*
+ Derived from source code of TrueCrypt 7.1a, which is
+ Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed
+ by the TrueCrypt License 3.0.
+
+ Modifications and additions to the original source code (contained in this file)
+ and all other portions of this file are Copyright (c) 2013-2016 IDRIX
+ and are governed by the Apache License 2.0 the full text of which is
+ contained in the file License.txt included in VeraCrypt binary and source
+ code distribution packages.
+*/
+
+#include "Bios.h"
+#include "BootConsoleIo.h"
+#include "BootConfig.h"
+#include "BootDebug.h"
+#include "BootDefs.h"
+#include "BootDiskIo.h"
+#include "BootStrings.h"
+
+
+byte SectorBuffer[TC_LB_SIZE];
+
+#ifdef TC_BOOT_DEBUG_ENABLED
+static bool SectorBufferInUse = false;
+
+void AcquireSectorBuffer ()
+{
+ if (SectorBufferInUse)
+ TC_THROW_FATAL_EXCEPTION;
+
+ SectorBufferInUse = true;
+}
+
+
+void ReleaseSectorBuffer ()
+{
+ SectorBufferInUse = false;
+}
+
+#endif
+
+
+bool IsLbaSupported (byte drive)
+{
+ static byte CachedDrive = TC_INVALID_BIOS_DRIVE;
+ static bool CachedStatus;
+ uint16 result = 0;
+
+ if (CachedDrive == drive)
+ goto ret;
+
+ __asm
+ {
+ mov bx, 0x55aa
+ mov dl, drive
+ mov ah, 0x41
+ int 0x13
+ jc err
+ mov result, bx
+ err:
+ }
+
+ CachedDrive = drive;
+ CachedStatus = (result == 0xaa55);
+ret:
+ return CachedStatus;
+}
+
+
+void PrintDiskError (BiosResult error, bool write, byte drive, const uint64 *sector, const ChsAddress *chs)
+{
+ PrintEndl();
+ Print (write ? "Write" : "Read"); Print (" error:");
+ Print (error);
+ Print (" Drive:");
+ Print (drive ^ 0x80);
+
+ if (sector)
+ {
+ Print (" Sector:");
+ Print (*sector);
+ }
+
+ if (chs)
+ {
+ Print (" CHS:");
+ Print (*chs);
+ }
+
+ PrintEndl();
+ Beep();
+}
+
+
+void Print (const ChsAddress &chs)
+{
+ Print (chs.Cylinder);
+ PrintChar ('/');
+ Print (chs.Head);
+ PrintChar ('/');
+ Print (chs.Sector);
+}
+
+
+void PrintSectorCountInMB (const uint64 &sectorCount)
+{
+ Print (sectorCount >> (TC_LB_SIZE_BIT_SHIFT_DIVISOR + 2)); Print (" MB ");
+}
+
+
+BiosResult ReadWriteSectors (bool write, uint16 bufferSegment, uint16 bufferOffset, byte drive, const ChsAddress &chs, byte sectorCount, bool silent)
+{
+ CheckStack();
+
+ byte cylinderLow = (byte) chs.Cylinder;
+ byte sector = chs.Sector;
+ sector |= byte (chs.Cylinder >> 2) & 0xc0;
+ byte function = write ? 0x03 : 0x02;
+
+ BiosResult result;
+ byte tryCount = TC_MAX_BIOS_DISK_IO_RETRIES;
+
+ do
+ {
+ result = BiosResultSuccess;
+
+ __asm
+ {
+ push es
+ mov ax, bufferSegment
+ mov es, ax
+ mov bx, bufferOffset
+ mov dl, drive
+ mov ch, cylinderLow
+ mov si, chs
+ mov dh, [si].Head
+ mov cl, sector
+ mov al, sectorCount
+ mov ah, function
+ int 0x13
+ jnc ok // If CF=0, ignore AH to prevent issues caused by potential bugs in BIOSes
+ mov result, ah
+ ok:
+ pop es
+ }
+
+ if (result == BiosResultEccCorrected)
+ result = BiosResultSuccess;
+
+ // Some BIOSes report I/O errors prematurely in some cases
+ } while (result != BiosResultSuccess && --tryCount != 0);
+
+ if (!silent && result != BiosResultSuccess)
+ PrintDiskError (result, write, drive, nullptr, &chs);
+
+ return result;
+}
+
+
+BiosResult ReadWriteSectors (bool write, byte *buffer, byte drive, const ChsAddress &chs, byte sectorCount, bool silent)
+{
+ uint16 codeSeg;
+ __asm mov codeSeg, cs
+ return ReadWriteSectors (write, codeSeg, (uint16) buffer, drive, chs, sectorCount, silent);
+}
+
+
+BiosResult ReadSectors (byte *buffer, byte drive, const ChsAddress &chs, byte sectorCount, bool silent)
+{
+ return ReadWriteSectors (false, buffer, drive, chs, sectorCount, silent);
+}
+
+
+BiosResult WriteSectors (byte *buffer, byte drive, const ChsAddress &chs, byte sectorCount, bool silent)
+{
+ return ReadWriteSectors (true, buffer, drive, chs, sectorCount, silent);
+}
+
+
+static BiosResult ReadWriteSectors (bool write, BiosLbaPacket &dapPacket, byte drive, const uint64 &sector, uint16 sectorCount, bool silent)
+{
+ CheckStack();
+
+ if (!IsLbaSupported (drive))
+ {
+ DriveGeometry geometry;
+
+ BiosResult result = GetDriveGeometry (drive, geometry, silent);
+ if (result != BiosResultSuccess)
+ return result;
+
+ ChsAddress chs;
+ LbaToChs (geometry, sector, chs);
+ return ReadWriteSectors (write, (uint16) (dapPacket.Buffer >> 16), (uint16) dapPacket.Buffer, drive, chs, sectorCount, silent);
+ }
+
+ dapPacket.Size = sizeof (dapPacket);
+ dapPacket.Reserved = 0;
+ dapPacket.SectorCount = sectorCount;
+ dapPacket.Sector = sector;
+
+ byte function = write ? 0x43 : 0x42;
+
+ BiosResult result;
+ byte tryCount = TC_MAX_BIOS_DISK_IO_RETRIES;
+
+ do
+ {
+ result = BiosResultSuccess;
+
+ __asm
+ {
+ mov bx, 0x55aa
+ mov dl, drive
+ mov si, [dapPacket]
+ mov ah, function
+ xor al, al
+ int 0x13
+ jnc ok // If CF=0, ignore AH to prevent issues caused by potential bugs in BIOSes
+ mov result, ah
+ ok:
+ }
+
+ if (result == BiosResultEccCorrected)
+ result = BiosResultSuccess;
+
+ // Some BIOSes report I/O errors prematurely in some cases
+ } while (result != BiosResultSuccess && --tryCount != 0);
+
+ if (!silent && result != BiosResultSuccess)
+ PrintDiskError (result, write, drive, &sector);
+
+ return result;
+}
+
+
+static BiosResult ReadWriteSectors (bool write, byte *buffer, byte drive, const uint64 &sector, uint16 sectorCount, bool silent)
+{
+ BiosLbaPacket dapPacket;
+ dapPacket.Buffer = (uint32) buffer;
+ return ReadWriteSectors (write, dapPacket, drive, sector, sectorCount, silent);
+}
+
+
+BiosResult ReadWriteSectors (bool write, uint16 bufferSegment, uint16 bufferOffset, byte drive, const uint64 &sector, uint16 sectorCount, bool silent)
+{
+ BiosLbaPacket dapPacket;
+ dapPacket.Buffer = ((uint32) bufferSegment << 16) | bufferOffset;
+ return ReadWriteSectors (write, dapPacket, drive, sector, sectorCount, silent);
+}
+
+BiosResult ReadSectors (uint16 bufferSegment, uint16 bufferOffset, byte drive, const uint64 &sector, uint16 sectorCount, bool silent)
+{
+ return ReadWriteSectors (false, bufferSegment, bufferOffset, drive, sector, sectorCount, silent);
+}
+
+
+BiosResult ReadSectors (byte *buffer, byte drive, const uint64 &sector, uint16 sectorCount, bool silent)
+{
+ BiosResult result;
+ uint16 codeSeg;
+ __asm mov codeSeg, cs
+
+ result = ReadSectors (BootStarted ? codeSeg : TC_BOOT_LOADER_ALT_SEGMENT, (uint16) buffer, drive, sector, sectorCount, silent);
+
+ // Alternative segment is used to prevent memory corruption caused by buggy BIOSes
+ if (!BootStarted)
+ CopyMemory (TC_BOOT_LOADER_ALT_SEGMENT, (uint16) buffer, buffer, sectorCount * TC_LB_SIZE);
+
+ return result;
+}
+
+
+BiosResult WriteSectors (byte *buffer, byte drive, const uint64 &sector, uint16 sectorCount, bool silent)
+{
+ return ReadWriteSectors (true, buffer, drive, sector, sectorCount, silent);
+}
+
+
+BiosResult GetDriveGeometry (byte drive, DriveGeometry &geometry, bool silent)
+{
+ CheckStack();
+
+ byte maxCylinderLow, maxHead, maxSector;
+ BiosResult result;
+ __asm
+ {
+ push es
+ mov dl, drive
+ mov ah, 0x08
+ int 0x13
+
+ mov result, ah
+ mov maxCylinderLow, ch
+ mov maxSector, cl
+ mov maxHead, dh
+ pop es
+ }
+
+ if (result == BiosResultSuccess)
+ {
+ geometry.Cylinders = (maxCylinderLow | (uint16 (maxSector & 0xc0) << 2)) + 1;
+ geometry.Heads = maxHead + 1;
+ geometry.Sectors = maxSector & ~0xc0;
+ }
+ else if (!silent)
+ {
+ Print ("Drive ");
+ Print (drive ^ 0x80);
+ Print (" not found: ");
+ PrintErrorNoEndl ("");
+ Print (result);
+ PrintEndl();
+ }
+
+ return result;
+}
+
+
+void ChsToLba (const DriveGeometry &geometry, const ChsAddress &chs, uint64 &lba)
+{
+ lba.HighPart = 0;
+ lba.LowPart = (uint32 (chs.Cylinder) * geometry.Heads + chs.Head) * geometry.Sectors + chs.Sector - 1;
+}
+
+
+void LbaToChs (const DriveGeometry &geometry, const uint64 &lba, ChsAddress &chs)
+{
+ chs.Sector = (byte) ((lba.LowPart % geometry.Sectors) + 1);
+ uint32 ch = lba.LowPart / geometry.Sectors;
+ chs.Head = (byte) (ch % geometry.Heads);
+ chs.Cylinder = (uint16) (ch / geometry.Heads);
+}
+
+
+void PartitionEntryMBRToPartition (const PartitionEntryMBR &partEntry, Partition &partition)
+{
+ partition.Active = partEntry.BootIndicator == 0x80;
+ partition.EndSector.HighPart = 0;
+ partition.EndSector.LowPart = partEntry.StartLBA + partEntry.SectorCountLBA - 1;
+ partition.SectorCount.HighPart = 0;
+ partition.SectorCount.LowPart = partEntry.SectorCountLBA;
+ partition.StartSector.HighPart = 0;
+ partition.StartSector.LowPart = partEntry.StartLBA;
+ partition.Type = partEntry.Type;
+}
+
+
+BiosResult ReadWriteMBR (bool write, byte drive, bool silent)
+{
+ uint64 mbrSector;
+ mbrSector.HighPart = 0;
+ mbrSector.LowPart = 0;
+
+ if (write)
+ return WriteSectors (SectorBuffer, drive, mbrSector, 1, silent);
+
+ return ReadSectors (SectorBuffer, drive, mbrSector, 1, silent); // Uses alternative segment
+}
+
+
+BiosResult GetDrivePartitions (byte drive, Partition *partitionArray, size_t partitionArrayCapacity, size_t &partitionCount, bool activeOnly, Partition *findPartitionFollowingThis, bool silent)
+{
+ Partition *followingPartition;
+ Partition tmpPartition;
+
+ if (findPartitionFollowingThis)
+ {
+ assert (partitionArrayCapacity == 1);
+ partitionArrayCapacity = 0xff;
+ followingPartition = partitionArray;
+ partitionArray = &tmpPartition;
+
+ followingPartition->Drive = TC_INVALID_BIOS_DRIVE;
+ followingPartition->StartSector.LowPart = 0xFFFFffffUL;
+ }
+
+ AcquireSectorBuffer();
+ BiosResult result = ReadWriteMBR (false, drive, silent);
+ ReleaseSectorBuffer();
+
+ partitionCount = 0;
+
+ MBR *mbr = (MBR *) SectorBuffer;
+ if (result != BiosResultSuccess || mbr->Signature != 0xaa55)
+ return result;
+
+ PartitionEntryMBR mbrPartitions[4];
+ memcpy (mbrPartitions, mbr->Partitions, sizeof (mbrPartitions));
+ size_t partitionArrayPos = 0, partitionNumber;
+
+ for (partitionNumber = 0;
+ partitionNumber < array_capacity (mbrPartitions) && partitionArrayPos < partitionArrayCapacity;
+ ++partitionNumber)
+ {
+ const PartitionEntryMBR &partEntry = mbrPartitions[partitionNumber];
+
+ if (partEntry.SectorCountLBA > 0)
+ {
+ Partition &partition = partitionArray[partitionArrayPos];
+ PartitionEntryMBRToPartition (partEntry, partition);
+
+ if (activeOnly && !partition.Active)
+ continue;
+
+ partition.Drive = drive;
+ partition.Number = partitionArrayPos;
+
+ if (partEntry.Type == 0x5 || partEntry.Type == 0xf) // Extended partition
+ {
+ if (IsLbaSupported (drive))
+ {
+ // Find all extended partitions
+ uint64 firstExtStartLBA = partition.StartSector;
+ uint64 extStartLBA = partition.StartSector;
+ MBR *extMbr = (MBR *) SectorBuffer;
+
+ while (partitionArrayPos < partitionArrayCapacity &&
+ (result = ReadSectors ((byte *) extMbr, drive, extStartLBA, 1, silent)) == BiosResultSuccess
+ && extMbr->Signature == 0xaa55)
+ {
+ if (extMbr->Partitions[0].SectorCountLBA > 0)
+ {
+ Partition &logPart = partitionArray[partitionArrayPos];
+ PartitionEntryMBRToPartition (extMbr->Partitions[0], logPart);
+ logPart.Drive = drive;
+
+ logPart.Number = partitionArrayPos;
+ logPart.Primary = false;
+
+ logPart.StartSector.LowPart += extStartLBA.LowPart;
+ logPart.EndSector.LowPart += extStartLBA.LowPart;
+
+ if (findPartitionFollowingThis)
+ {
+ if (logPart.StartSector.LowPart > findPartitionFollowingThis->EndSector.LowPart
+ && logPart.StartSector.LowPart < followingPartition->StartSector.LowPart)
+ {
+ *followingPartition = logPart;
+ }
+ }
+ else
+ ++partitionArrayPos;
+ }
+
+ // Secondary extended
+ if (extMbr->Partitions[1].Type != 0x5 && extMbr->Partitions[1].Type == 0xf
+ || extMbr->Partitions[1].SectorCountLBA == 0)
+ break;
+
+ extStartLBA.LowPart = extMbr->Partitions[1].StartLBA + firstExtStartLBA.LowPart;
+ }
+ }
+ }
+ else
+ {
+ partition.Primary = true;
+
+ if (findPartitionFollowingThis)
+ {
+ if (partition.StartSector.LowPart > findPartitionFollowingThis->EndSector.LowPart
+ && partition.StartSector.LowPart < followingPartition->StartSector.LowPart)
+ {
+ *followingPartition = partition;
+ }
+ }
+ else
+ ++partitionArrayPos;
+ }
+ }
+ }
+
+ partitionCount = partitionArrayPos;
+ return result;
+}
+
+
+bool GetActivePartition (byte drive)
+{
+ size_t partCount;
+
+ if (GetDrivePartitions (drive, &ActivePartition, 1, partCount, true) != BiosResultSuccess || partCount < 1)
+ {
+ ActivePartition.Drive = TC_INVALID_BIOS_DRIVE;
+ PrintError (TC_BOOT_STR_NO_BOOT_PARTITION);
+ return false;
+ }
+
+ return true;
+}
diff --git a/src/Boot/Windows/BootDiskIo.h b/src/Boot/Windows/BootDiskIo.h
index d1c1ccff..ad9d1437 100644
--- a/src/Boot/Windows/BootDiskIo.h
+++ b/src/Boot/Windows/BootDiskIo.h
@@ -1,120 +1,120 @@
-/*
- Derived from source code of TrueCrypt 7.1a, which is
- Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed
- by the TrueCrypt License 3.0.
-
- Modifications and additions to the original source code (contained in this file)
- and all other portions of this file are Copyright (c) 2013-2016 IDRIX
- and are governed by the Apache License 2.0 the full text of which is
- contained in the file License.txt included in VeraCrypt binary and source
- code distribution packages.
-*/
-
-#ifndef TC_HEADER_Boot_BootDiskIo
-#define TC_HEADER_Boot_BootDiskIo
-
-#include "Bios.h"
-#include "BootDebug.h"
-#include "BootDefs.h"
-
-#define TC_MAX_BIOS_DISK_IO_RETRIES 5
-
-enum
-{
- BiosResultEccCorrected = 0x11
-};
-
-#pragma pack(1)
-
-struct PartitionEntryMBR
-{
- byte BootIndicator;
-
- byte StartHead;
- byte StartCylSector;
- byte StartCylinder;
-
- byte Type;
-
- byte EndHead;
- byte EndSector;
- byte EndCylinder;
-
- uint32 StartLBA;
- uint32 SectorCountLBA;
-};
-
-struct MBR
-{
- byte Code[446];
- PartitionEntryMBR Partitions[4];
- uint16 Signature;
-};
-
-struct BiosLbaPacket
-{
- byte Size;
- byte Reserved;
- uint16 SectorCount;
- uint32 Buffer;
- uint64 Sector;
-};
-
-#pragma pack()
-
-
-struct ChsAddress
-{
- uint16 Cylinder;
- byte Head;
- byte Sector;
-};
-
-struct Partition
-{
- byte Number;
- byte Drive;
- bool Active;
- uint64 EndSector;
- bool Primary;
- uint64 SectorCount;
- uint64 StartSector;
- byte Type;
-};
-
-struct DriveGeometry
-{
- uint16 Cylinders;
- byte Heads;
- byte Sectors;
-};
-
-
-#ifdef TC_BOOT_DEBUG_ENABLED
-void AcquireSectorBuffer ();
-void ReleaseSectorBuffer ();
-#else
-# define AcquireSectorBuffer()
-# define ReleaseSectorBuffer()
-#endif
-
-void ChsToLba (const DriveGeometry &geometry, const ChsAddress &chs, uint64 &lba);
-bool GetActivePartition (byte drive);
-BiosResult GetDriveGeometry (byte drive, DriveGeometry &geometry, bool silent = false);
-BiosResult GetDrivePartitions (byte drive, Partition *partitionArray, size_t partitionArrayCapacity, size_t &partitionCount, bool activeOnly = false, Partition *findPartitionFollowingThis = nullptr, bool silent = false);
-bool IsLbaSupported (byte drive);
-void LbaToChs (const DriveGeometry &geometry, const uint64 &lba, ChsAddress &chs);
-void Print (const ChsAddress &chs);
-void PrintDiskError (BiosResult error, bool write, byte drive, const uint64 *sector, const ChsAddress *chs = nullptr);
-void PrintSectorCountInMB (const uint64 &sectorCount);
-BiosResult ReadWriteMBR (bool write, byte drive, bool silent = false);
-BiosResult ReadSectors (uint16 bufferSegment, uint16 bufferOffset, byte drive, const uint64 &sector, uint16 sectorCount, bool silent = false);
-BiosResult ReadSectors (byte *buffer, byte drive, const uint64 &sector, uint16 sectorCount, bool silent = false);
-BiosResult ReadSectors (byte *buffer, byte drive, const ChsAddress &chs, byte sectorCount, bool silent = false);
-BiosResult ReadWriteSectors (bool write, uint16 bufferSegment, uint16 bufferOffset, byte drive, const uint64 &sector, uint16 sectorCount, bool silent);
-BiosResult WriteSectors (byte *buffer, byte drive, const uint64 &sector, uint16 sectorCount, bool silent = false);
-BiosResult WriteSectors (byte *buffer, byte drive, const ChsAddress &chs, byte sectorCount, bool silent = false);
-
-extern byte SectorBuffer[TC_LB_SIZE];
-
-#endif // TC_HEADER_Boot_BootDiskIo
+/*
+ Derived from source code of TrueCrypt 7.1a, which is
+ Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed
+ by the TrueCrypt License 3.0.
+
+ Modifications and additions to the original source code (contained in this file)
+ and all other portions of this file are Copyright (c) 2013-2016 IDRIX
+ and are governed by the Apache License 2.0 the full text of which is
+ contained in the file License.txt included in VeraCrypt binary and source
+ code distribution packages.
+*/
+
+#ifndef TC_HEADER_Boot_BootDiskIo
+#define TC_HEADER_Boot_BootDiskIo
+
+#include "Bios.h"
+#include "BootDebug.h"
+#include "BootDefs.h"
+
+#define TC_MAX_BIOS_DISK_IO_RETRIES 5
+
+enum
+{
+ BiosResultEccCorrected = 0x11
+};
+
+#pragma pack(1)
+
+struct PartitionEntryMBR
+{
+ byte BootIndicator;
+
+ byte StartHead;
+ byte StartCylSector;
+ byte StartCylinder;
+
+ byte Type;
+
+ byte EndHead;
+ byte EndSector;
+ byte EndCylinder;
+
+ uint32 StartLBA;
+ uint32 SectorCountLBA;
+};
+
+struct MBR
+{
+ byte Code[446];
+ PartitionEntryMBR Partitions[4];
+ uint16 Signature;
+};
+
+struct BiosLbaPacket
+{
+ byte Size;
+ byte Reserved;
+ uint16 SectorCount;
+ uint32 Buffer;
+ uint64 Sector;
+};
+
+#pragma pack()
+
+
+struct ChsAddress
+{
+ uint16 Cylinder;
+ byte Head;
+ byte Sector;
+};
+
+struct Partition
+{
+ byte Number;
+ byte Drive;
+ bool Active;
+ uint64 EndSector;
+ bool Primary;
+ uint64 SectorCount;
+ uint64 StartSector;
+ byte Type;
+};
+
+struct DriveGeometry
+{
+ uint16 Cylinders;
+ byte Heads;
+ byte Sectors;
+};
+
+
+#ifdef TC_BOOT_DEBUG_ENABLED
+void AcquireSectorBuffer ();
+void ReleaseSectorBuffer ();
+#else
+# define AcquireSectorBuffer()
+# define ReleaseSectorBuffer()
+#endif
+
+void ChsToLba (const DriveGeometry &geometry, const ChsAddress &chs, uint64 &lba);
+bool GetActivePartition (byte drive);
+BiosResult GetDriveGeometry (byte drive, DriveGeometry &geometry, bool silent = false);
+BiosResult GetDrivePartitions (byte drive, Partition *partitionArray, size_t partitionArrayCapacity, size_t &partitionCount, bool activeOnly = false, Partition *findPartitionFollowingThis = nullptr, bool silent = false);
+bool IsLbaSupported (byte drive);
+void LbaToChs (const DriveGeometry &geometry, const uint64 &lba, ChsAddress &chs);
+void Print (const ChsAddress &chs);
+void PrintDiskError (BiosResult error, bool write, byte drive, const uint64 *sector, const ChsAddress *chs = nullptr);
+void PrintSectorCountInMB (const uint64 &sectorCount);
+BiosResult ReadWriteMBR (bool write, byte drive, bool silent = false);
+BiosResult ReadSectors (uint16 bufferSegment, uint16 bufferOffset, byte drive, const uint64 &sector, uint16 sectorCount, bool silent = false);
+BiosResult ReadSectors (byte *buffer, byte drive, const uint64 &sector, uint16 sectorCount, bool silent = false);
+BiosResult ReadSectors (byte *buffer, byte drive, const ChsAddress &chs, byte sectorCount, bool silent = false);
+BiosResult ReadWriteSectors (bool write, uint16 bufferSegment, uint16 bufferOffset, byte drive, const uint64 &sector, uint16 sectorCount, bool silent);
+BiosResult WriteSectors (byte *buffer, byte drive, const uint64 &sector, uint16 sectorCount, bool silent = false);
+BiosResult WriteSectors (byte *buffer, byte drive, const ChsAddress &chs, byte sectorCount, bool silent = false);
+
+extern byte SectorBuffer[TC_LB_SIZE];
+
+#endif // TC_HEADER_Boot_BootDiskIo
diff --git a/src/Boot/Windows/BootEncryptedIo.cpp b/src/Boot/Windows/BootEncryptedIo.cpp
index d130534f..63fd0f47 100644
--- a/src/Boot/Windows/BootEncryptedIo.cpp
+++ b/src/Boot/Windows/BootEncryptedIo.cpp
@@ -1,132 +1,132 @@
-/*
- Derived from source code of TrueCrypt 7.1a, which is
- Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed
- by the TrueCrypt License 3.0.
-
- Modifications and additions to the original source code (contained in this file)
- and all other portions of this file are Copyright (c) 2013-2016 IDRIX
- and are governed by the Apache License 2.0 the full text of which is
- contained in the file License.txt included in VeraCrypt binary and source
- code distribution packages.
-*/
-
-#include "Crypto.h"
-#include "Platform.h"
-#include "BootConfig.h"
-#include "BootDebug.h"
-#include "BootDefs.h"
-#include "BootDiskIo.h"
-#include "BootEncryptedIo.h"
-
-
-BiosResult ReadEncryptedSectors (uint16 destSegment, uint16 destOffset, byte drive, uint64 sector, uint16 sectorCount)
-{
- BiosResult result;
- bool decrypt = true;
-
- if (BootCryptoInfo->hiddenVolume)
- {
- if (ReadWritePartiallyCoversEncryptedArea (sector, sectorCount))
- return BiosResultInvalidFunction;
-
- if (sector >= EncryptedVirtualPartition.StartSector && sector <= EncryptedVirtualPartition.EndSector)
- {
- // Remap the request to the hidden volume
- sector -= EncryptedVirtualPartition.StartSector;
- sector += HiddenVolumeStartSector;
- }
- else
- decrypt = false;
- }
-
- result = ReadSectors (destSegment, destOffset, drive, sector, sectorCount);
-
- if (result != BiosResultSuccess || !decrypt)
- return result;
-
- if (BootCryptoInfo->hiddenVolume)
- {
- // Convert sector number to data unit number of the hidden volume
- sector -= HiddenVolumeStartSector;
- sector += PimValueOrHiddenVolumeStartUnitNo;
- }
-
- if (drive == EncryptedVirtualPartition.Drive)
- {
- while (sectorCount-- > 0)
- {
- if (BootCryptoInfo->hiddenVolume
- || (sector >= EncryptedVirtualPartition.StartSector && sector <= EncryptedVirtualPartition.EndSector))
- {
- AcquireSectorBuffer();
- CopyMemory (destSegment, destOffset, SectorBuffer, TC_LB_SIZE);
-
- DecryptDataUnits (SectorBuffer, &sector, 1, BootCryptoInfo);
-
- CopyMemory (SectorBuffer, destSegment, destOffset, TC_LB_SIZE);
- ReleaseSectorBuffer();
- }
-
- ++sector;
- destOffset += TC_LB_SIZE;
- }
- }
-
- return result;
-}
-
-
-BiosResult WriteEncryptedSectors (uint16 sourceSegment, uint16 sourceOffset, byte drive, uint64 sector, uint16 sectorCount)
-{
- BiosResult result = BiosResultSuccess;
- AcquireSectorBuffer();
- uint64 dataUnitNo;
- uint64 writeOffset;
-
- dataUnitNo = sector;
- writeOffset.HighPart = 0;
- writeOffset.LowPart = 0;
-
- if (BootCryptoInfo->hiddenVolume)
- {
- if (ReadWritePartiallyCoversEncryptedArea (sector, sectorCount))
- return BiosResultInvalidFunction;
-
- // Remap the request to the hidden volume
- writeOffset = HiddenVolumeStartSector;
- writeOffset -= EncryptedVirtualPartition.StartSector;
- dataUnitNo -= EncryptedVirtualPartition.StartSector;
- dataUnitNo += PimValueOrHiddenVolumeStartUnitNo;
- }
-
- while (sectorCount-- > 0)
- {
- CopyMemory (sourceSegment, sourceOffset, SectorBuffer, TC_LB_SIZE);
-
- if (drive == EncryptedVirtualPartition.Drive && sector >= EncryptedVirtualPartition.StartSector && sector <= EncryptedVirtualPartition.EndSector)
- {
- EncryptDataUnits (SectorBuffer, &dataUnitNo, 1, BootCryptoInfo);
- }
-
- result = WriteSectors (SectorBuffer, drive, sector + writeOffset, 1);
-
- if (result != BiosResultSuccess)
- break;
-
- ++sector;
- ++dataUnitNo;
- sourceOffset += TC_LB_SIZE;
- }
-
- ReleaseSectorBuffer();
- return result;
-}
-
-
-static bool ReadWritePartiallyCoversEncryptedArea (const uint64 &sector, uint16 sectorCount)
-{
- uint64 readWriteEnd = sector + --sectorCount;
-
- return ((sector < EncryptedVirtualPartition.StartSector && readWriteEnd >= EncryptedVirtualPartition.StartSector)
- || (sector >= EncryptedVirtualPartition.StartSector && readWriteEnd > EncryptedVirtualPartition.EndSector));
-}
+/*
+ Derived from source code of TrueCrypt 7.1a, which is
+ Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed
+ by the TrueCrypt License 3.0.
+
+ Modifications and additions to the original source code (contained in this file)
+ and all other portions of this file are Copyright (c) 2013-2016 IDRIX
+ and are governed by the Apache License 2.0 the full text of which is
+ contained in the file License.txt included in VeraCrypt binary and source
+ code distribution packages.
+*/
+
+#include "Crypto.h"
+#include "Platform.h"
+#include "BootConfig.h"
+#include "BootDebug.h"
+#include "BootDefs.h"
+#include "BootDiskIo.h"
+#include "BootEncryptedIo.h"
+
+
+BiosResult ReadEncryptedSectors (uint16 destSegment, uint16 destOffset, byte drive, uint64 sector, uint16 sectorCount)
+{
+ BiosResult result;
+ bool decrypt = true;
+
+ if (BootCryptoInfo->hiddenVolume)
+ {
+ if (ReadWritePartiallyCoversEncryptedArea (sector, sectorCount))
+ return BiosResultInvalidFunction;
+
+ if (sector >= EncryptedVirtualPartition.StartSector && sector <= EncryptedVirtualPartition.EndSector)
+ {
+ // Remap the request to the hidden volume
+ sector -= EncryptedVirtualPartition.StartSector;
+ sector += HiddenVolumeStartSector;
+ }
+ else
+ decrypt = false;
+ }
+
+ result = ReadSectors (destSegment, destOffset, drive, sector, sectorCount);
+
+ if (result != BiosResultSuccess || !decrypt)
+ return result;
+
+ if (BootCryptoInfo->hiddenVolume)
+ {
+ // Convert sector number to data unit number of the hidden volume
+ sector -= HiddenVolumeStartSector;
+ sector += PimValueOrHiddenVolumeStartUnitNo;
+ }
+
+ if (drive == EncryptedVirtualPartition.Drive)
+ {
+ while (sectorCount-- > 0)
+ {
+ if (BootCryptoInfo->hiddenVolume
+ || (sector >= EncryptedVirtualPartition.StartSector && sector <= EncryptedVirtualPartition.EndSector))
+ {
+ AcquireSectorBuffer();
+ CopyMemory (destSegment, destOffset, SectorBuffer, TC_LB_SIZE);
+
+ DecryptDataUnits (SectorBuffer, &sector, 1, BootCryptoInfo);
+
+ CopyMemory (SectorBuffer, destSegment, destOffset, TC_LB_SIZE);
+ ReleaseSectorBuffer();
+ }
+
+ ++sector;
+ destOffset += TC_LB_SIZE;
+ }
+ }
+
+ return result;
+}
+
+
+BiosResult WriteEncryptedSectors (uint16 sourceSegment, uint16 sourceOffset, byte drive, uint64 sector, uint16 sectorCount)
+{
+ BiosResult result = BiosResultSuccess;
+ AcquireSectorBuffer();
+ uint64 dataUnitNo;
+ uint64 writeOffset;
+
+ dataUnitNo = sector;
+ writeOffset.HighPart = 0;
+ writeOffset.LowPart = 0;
+
+ if (BootCryptoInfo->hiddenVolume)
+ {
+ if (ReadWritePartiallyCoversEncryptedArea (sector, sectorCount))
+ return BiosResultInvalidFunction;
+
+ // Remap the request to the hidden volume
+ writeOffset = HiddenVolumeStartSector;
+ writeOffset -= EncryptedVirtualPartition.StartSector;
+ dataUnitNo -= EncryptedVirtualPartition.StartSector;
+ dataUnitNo += PimValueOrHiddenVolumeStartUnitNo;
+ }
+
+ while (sectorCount-- > 0)
+ {
+ CopyMemory (sourceSegment, sourceOffset, SectorBuffer, TC_LB_SIZE);
+
+ if (drive == EncryptedVirtualPartition.Drive && sector >= EncryptedVirtualPartition.StartSector && sector <= EncryptedVirtualPartition.EndSector)
+ {
+ EncryptDataUnits (SectorBuffer, &dataUnitNo, 1, BootCryptoInfo);
+ }
+
+ result = WriteSectors (SectorBuffer, drive, sector + writeOffset, 1);
+
+ if (result != BiosResultSuccess)
+ break;
+
+ ++sector;
+ ++dataUnitNo;
+ sourceOffset += TC_LB_SIZE;
+ }
+
+ ReleaseSectorBuffer();
+ return result;
+}
+
+
+static bool ReadWritePartiallyCoversEncryptedArea (const uint64 &sector, uint16 sectorCount)
+{
+ uint64 readWriteEnd = sector + --sectorCount;
+
+ return ((sector < EncryptedVirtualPartition.StartSector && readWriteEnd >= EncryptedVirtualPartition.StartSector)
+ || (sector >= EncryptedVirtualPartition.StartSector && readWriteEnd > EncryptedVirtualPartition.EndSector));
+}
diff --git a/src/Boot/Windows/BootEncryptedIo.h b/src/Boot/Windows/BootEncryptedIo.h
index 6cc375fa..d27ec9ea 100644
--- a/src/Boot/Windows/BootEncryptedIo.h
+++ b/src/Boot/Windows/BootEncryptedIo.h
@@ -1,22 +1,22 @@
-/*
- Derived from source code of TrueCrypt 7.1a, which is
- Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed
- by the TrueCrypt License 3.0.
-
- Modifications and additions to the original source code (contained in this file)
- and all other portions of this file are Copyright (c) 2013-2016 IDRIX
- and are governed by the Apache License 2.0 the full text of which is
- contained in the file License.txt included in VeraCrypt binary and source
- code distribution packages.
-*/
-
-#ifndef TC_HEADER_Boot_BootEncryptionIo
-#define TC_HEADER_Boot_BootEncryptionIo
-
-#include "Platform.h"
-
-BiosResult ReadEncryptedSectors (uint16 destSegment, uint16 destOffset, byte drive, uint64 sector, uint16 sectorCount);
-BiosResult WriteEncryptedSectors (uint16 sourceSegment, uint16 sourceOffset, byte drive, uint64 sector, uint16 sectorCount);
-static bool ReadWritePartiallyCoversEncryptedArea (const uint64 &sector, uint16 sectorCount);
-
-#endif // TC_HEADER_Boot_BootEncryptionIo
+/*
+ Derived from source code of TrueCrypt 7.1a, which is
+ Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed
+ by the TrueCrypt License 3.0.
+
+ Modifications and additions to the original source code (contained in this file)
+ and all other portions of this file are Copyright (c) 2013-2016 IDRIX
+ and are governed by the Apache License 2.0 the full text of which is
+ contained in the file License.txt included in VeraCrypt binary and source
+ code distribution packages.
+*/
+
+#ifndef TC_HEADER_Boot_BootEncryptionIo
+#define TC_HEADER_Boot_BootEncryptionIo
+
+#include "Platform.h"
+
+BiosResult ReadEncryptedSectors (uint16 destSegment, uint16 destOffset, byte drive, uint64 sector, uint16 sectorCount);
+BiosResult WriteEncryptedSectors (uint16 sourceSegment, uint16 sourceOffset, byte drive, uint64 sector, uint16 sectorCount);
+static bool ReadWritePartiallyCoversEncryptedArea (const uint64 &sector, uint16 sectorCount);
+
+#endif // TC_HEADER_Boot_BootEncryptionIo
diff --git a/src/Boot/Windows/BootMain.cpp b/src/Boot/Windows/BootMain.cpp
index 275c5762..57697a4f 100644
--- a/src/Boot/Windows/BootMain.cpp
+++ b/src/Boot/Windows/BootMain.cpp
@@ -1,1269 +1,1269 @@
-/*
- Derived from source code of TrueCrypt 7.1a, which is
- Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed
- by the TrueCrypt License 3.0.
-
- Modifications and additions to the original source code (contained in this file)
- and all other portions of this file are Copyright (c) 2013-2016 IDRIX
- and are governed by the Apache License 2.0 the full text of which is
- contained in the file License.txt included in VeraCrypt binary and source
- code distribution packages.
-*/
-
-#include "Crc.h"
-#include "Crypto.h"
-#include "Password.h"
-#include "Volumes.h"
-
-#include "Platform.h"
-#include "Bios.h"
-#include "BootConfig.h"
-#include "BootMain.h"
-#include "BootDefs.h"
-#include "BootCommon.h"
-#include "BootConsoleIo.h"
-#include "BootDebug.h"
-#include "BootDiskIo.h"
-#include "BootEncryptedIo.h"
-#include "BootMemory.h"
-#include "BootStrings.h"
-#include "IntFilter.h"
-
-
-static void InitScreen ()
-{
- ClearScreen();
-
- const char *title =
-#ifndef TC_WINDOWS_BOOT_RESCUE_DISK_MODE
- " VeraCrypt Boot Loader "
-#else
- " VeraCrypt Rescue Disk "
-#endif
- VERSION_STRING "\r\n";
-
- Print (title);
-
- PrintRepeatedChar ('\xDC', TC_BIOS_MAX_CHARS_PER_LINE);
-
-#ifndef TC_WINDOWS_BOOT_RESCUE_DISK_MODE
- if (CustomUserMessage[0])
- {
- PrintEndl();
- Print (CustomUserMessage);
- }
-#endif
-
- PrintEndl (2);
-}
-
-
-static void PrintMainMenu ()
-{
- if (PreventBootMenu)
- return;
-
- Print (" Keyboard Controls:\r\n");
- Print (" [F5] Hide/Show Password and PIM\r\n");
- Print (" [Esc] ");
-
-#ifndef TC_WINDOWS_BOOT_RESCUE_DISK_MODE
-
- Print ((BootSectorFlags & TC_BOOT_CFG_MASK_HIDDEN_OS_CREATION_PHASE) != TC_HIDDEN_OS_CREATION_PHASE_NONE
- ? "Boot Non-Hidden System (Boot Manager)"
- : "Skip Authentication (Boot Manager)");
-
-#else // TC_WINDOWS_BOOT_RESCUE_DISK_MODE
-
- Print ("Skip Authentication (Boot Manager)");
- Print ("\r\n [F8] "); Print ("Repair Options");
-
-#endif // TC_WINDOWS_BOOT_RESCUE_DISK_MODE
-
- PrintEndl (3);
-}
-
-
-static bool IsMenuKey (byte scanCode)
-{
-#ifdef TC_WINDOWS_BOOT_RESCUE_DISK_MODE
- return scanCode == TC_MENU_KEY_REPAIR;
-#else
- return false;
-#endif
-}
-
-
-static bool AskYesNo (const char *message)
-{
- Print (message);
- Print ("? (y/n): ");
- while (true)
- {
- switch (GetKeyboardChar())
- {
- case 'y':
- case 'Y':
- case 'z':
- case 'Z':
- Print ("y\r\n");
- return true;
-
- case 'n':
- case 'N':
- Print ("n\r\n");
- return false;
-
- default:
- Beep();
- }
- }
-}
-
-
-static int AskSelection (const char *options[], size_t optionCount)
-{
- for (int i = 0; i < optionCount; ++i)
- {
- Print ("["); Print (i + 1); Print ("] ");
- Print (options[i]);
- PrintEndl();
- }
- Print ("[Esc] Cancel\r\n\r\n");
-
- Print ("To select, press 1-9: ");
-
- char str;
-
- while (true)
- {
- if (GetString (&str, 1) == 0)
- return 0;
-
- if (str >= '1' && str <= optionCount + '0')
- return str - '0';
-
- Beep();
- PrintBackspace();
- }
-}
-
-
-static byte AskPassword (Password &password, int& pim)
-{
- size_t pos = 0;
- byte scanCode;
- byte asciiCode;
- byte hidePassword = 1;
-
- pim = 0;
-
- Print ("Enter password");
- Print (PreventNormalSystemBoot ? " for hidden system:\r\n" : ": ");
-
- while (true)
- {
- asciiCode = GetKeyboardChar (&scanCode);
-
- switch (scanCode)
- {
- case TC_BIOS_KEY_ENTER:
- password.Length = pos;
- Print ("\r");
- if (!PreventNormalSystemBoot)
- Print ("Enter password: ");
- pos = 0;
- while (pos < MAX_PASSWORD)
- {
- pos++;
- if (pos < MAX_PASSWORD)
- PrintChar ('*');
- else
- PrintCharAtCursor ('*');
- }
-
- ClearBiosKeystrokeBuffer();
- PrintEndl();
-
- break;
-
- case TC_BIOS_KEY_BACKSPACE:
- if (pos > 0)
- {
- if (pos < MAX_PASSWORD)
- PrintBackspace();
- else
- PrintCharAtCursor (' ');
-
- --pos;
- }
- continue;
-
- case TC_BIOS_KEY_F5:
- hidePassword ^= 0x01;
- continue;
-
- default:
- if (scanCode == TC_BIOS_KEY_ESC || IsMenuKey (scanCode))
- {
- burn (password.Text, sizeof (password.Text));
- ClearBiosKeystrokeBuffer();
-
- PrintEndl();
- return scanCode;
- }
- }
-
- if (TC_BIOS_KEY_ENTER == scanCode)
- break;
-
- if (!IsPrintable (asciiCode) || pos == MAX_PASSWORD)
- {
- Beep();
- continue;
- }
-
- password.Text[pos++] = asciiCode;
- if (hidePassword) asciiCode = '*';
- if (pos < MAX_PASSWORD)
- PrintChar (asciiCode);
- else
- PrintCharAtCursor (asciiCode);
- }
-
-#ifndef TC_WINDOWS_BOOT_RESCUE_DISK_MODE
- if (PimValueOrHiddenVolumeStartUnitNo.LowPart != -1)
- {
- pim = (int) PimValueOrHiddenVolumeStartUnitNo.LowPart;
- // reset stored PIM value to allow requesting PIM next time in case the stored value is wrong
- PimValueOrHiddenVolumeStartUnitNo.LowPart = -1;
- return TC_BIOS_KEY_ENTER;
- }
- else
-#endif
- {
- pos = 0;
- Print ("PIM: ");
-
- while (true)
- {
- asciiCode = GetKeyboardChar (&scanCode);
-
- switch (scanCode)
- {
- case TC_BIOS_KEY_ENTER:
- Print ("\rPIM: ");
- pos =0;
- while (pos < MAX_PIM)
- {
- PrintChar ('*');
- pos++;
- }
-
- ClearBiosKeystrokeBuffer();
- PrintEndl();
-
- return TC_BIOS_KEY_ENTER;
-
- case TC_BIOS_KEY_BACKSPACE:
- if (pos > 0)
- {
- if (pos < MAX_PIM)
- PrintBackspace();
- else
- PrintCharAtCursor (' ');
-
- --pos;
- pim /= 10;
- }
- continue;
-
- case TC_BIOS_KEY_F5:
- hidePassword ^= 0x01;
- continue;
-
- default:
- if (scanCode == TC_BIOS_KEY_ESC || IsMenuKey (scanCode))
- {
- burn (password.Text, sizeof (password.Text));
- ClearBiosKeystrokeBuffer();
-
- PrintEndl();
- return scanCode;
- }
- }
-
- if (!IsDigit (asciiCode) || pos == MAX_PIM)
- {
- Beep();
- continue;
- }
-
- pim = 10*pim + (asciiCode - '0');
- pos++;
-
- if (hidePassword) asciiCode = '*';
- if (pos < MAX_PIM)
- PrintChar (asciiCode);
- else
- PrintCharAtCursor (asciiCode);
- }
- }
-}
-
-
-static void ExecuteBootSector (byte drive, byte *sectorBuffer)
-{
- Print ("Booting...\r\n");
- CopyMemory (sectorBuffer, 0x0000, 0x7c00, TC_LB_SIZE);
-
- BootStarted = true;
-
- uint32 addr = 0x7c00;
- __asm
- {
- cli
- mov dl, drive // Boot drive
- mov dh, 0
- xor ax, ax
- mov si, ax
- mov ds, ax
- mov es, ax
- mov ss, ax
- mov sp, 0x7c00
- sti
-
- jmp cs:addr
- }
-}
-
-
-static bool OpenVolume (byte drive, Password &password, int pim, CRYPTO_INFO **cryptoInfo, uint32 *headerSaltCrc32, bool skipNormal, bool skipHidden)
-{
- int volumeType;
- bool hiddenVolume;
- uint64 headerSec;
-
- AcquireSectorBuffer();
-
- for (volumeType = 1; volumeType <= 2; ++volumeType)
- {
- hiddenVolume = (volumeType == 2);
-
- if (hiddenVolume)
- {
- if (skipHidden || PartitionFollowingActive.Drive != drive || PartitionFollowingActive.SectorCount <= ActivePartition.SectorCount)
- continue;
-
- headerSec = PartitionFollowingActive.StartSector + TC_HIDDEN_VOLUME_HEADER_OFFSET / TC_LB_SIZE;
- }
- else
- {
- if (skipNormal)
- continue;
-
- headerSec.HighPart = 0;
- headerSec.LowPart = TC_BOOT_VOLUME_HEADER_SECTOR;
- }
-
- if (ReadSectors (SectorBuffer, drive, headerSec, 1) != BiosResultSuccess)
- continue;
-
- if (ReadVolumeHeader (!hiddenVolume, (char *) SectorBuffer, &password, pim, cryptoInfo, nullptr) == ERR_SUCCESS)
- {
- // Prevent opening a non-system hidden volume
- if (hiddenVolume && !((*cryptoInfo)->HeaderFlags & TC_HEADER_FLAG_ENCRYPTED_SYSTEM))
- {
- crypto_close (*cryptoInfo);
- continue;
- }
-
- if (headerSaltCrc32)
- *headerSaltCrc32 = GetCrc32 (SectorBuffer, PKCS5_SALT_SIZE);
-
- break;
- }
- }
-
- ReleaseSectorBuffer();
- return volumeType != 3;
-}
-
-
-static bool CheckMemoryRequirements ()
-{
- uint16 codeSeg;
- __asm mov codeSeg, cs
- if (codeSeg == TC_BOOT_LOADER_LOWMEM_SEGMENT)
- {
- PrintErrorNoEndl ("BIOS reserved too much memory: ");
-
- uint16 memFree;
- __asm
- {
- push es
- xor ax, ax
- mov es, ax
- mov ax, es:[0x413]
- mov memFree, ax
- pop es
- }
-
- Print (memFree);
- PrintEndl();
- Print (TC_BOOT_STR_UPGRADE_BIOS);
-
- return false;
- }
-
- return true;
-}
-
-
-static bool MountVolume (byte drive, byte &exitKey, bool skipNormal, bool skipHidden)
-{
- BootArguments *bootArguments = (BootArguments *) TC_BOOT_LOADER_ARGS_OFFSET;
- int incorrectPasswordCount = 0, pim = 0;
-
- EraseMemory (bootArguments, sizeof (*bootArguments));
-
- // Open volume header
- while (true)
- {
- exitKey = AskPassword (bootArguments->BootPassword, pim);
-
- if (exitKey != TC_BIOS_KEY_ENTER)
- return false;
-
- Print ("Verifying password...");
-
- if (OpenVolume (BootDrive, bootArguments->BootPassword, pim, &BootCryptoInfo, &bootArguments->HeaderSaltCrc32, skipNormal, skipHidden))
- {
- Print ("OK\r\n");
- break;
- }
- if (GetShiftFlags() & TC_BIOS_SHIFTMASK_CAPSLOCK)
- Print ("Warning: Caps Lock is on.\r\n");
-
- Print ("Incorrect password.\r\n\r\n");
-
- if (++incorrectPasswordCount == 4)
- {
-#ifdef TC_WINDOWS_BOOT_RESCUE_DISK_MODE
- Print ("If you are sure the password is correct, the key data may be damaged.\r\n"
- "If so, use 'Repair Options' > 'Restore key data'.\r\n\r\n");
-#else
- Print ("If you are sure the password is correct, the key data may be damaged. Boot your\r\n"
- "VeraCrypt Rescue Disk and select 'Repair Options' > 'Restore key data'.\r\n\r\n");
-#endif
- }
- }
-
- // Setup boot arguments
- bootArguments->BootLoaderVersion = VERSION_NUM;
- bootArguments->CryptoInfoOffset = (uint16) BootCryptoInfo;
- bootArguments->CryptoInfoLength = sizeof (*BootCryptoInfo);
- bootArguments->Flags = (((uint32)pim) << 16);
-
- if (BootCryptoInfo->hiddenVolume)
- bootArguments->HiddenSystemPartitionStart = PartitionFollowingActive.StartSector << TC_LB_SIZE_BIT_SHIFT_DIVISOR;
-
- if (ExtraBootPartitionPresent)
- bootArguments->Flags |= TC_BOOT_ARGS_FLAG_EXTRA_BOOT_PARTITION;
-
- TC_SET_BOOT_ARGUMENTS_SIGNATURE (bootArguments->Signature);
-
- // Setup virtual encrypted partition
- if (BootCryptoInfo->EncryptedAreaLength.HighPart != 0 || BootCryptoInfo->EncryptedAreaLength.LowPart != 0)
- {
- EncryptedVirtualPartition.Drive = BootDrive;
-
- EncryptedVirtualPartition.StartSector = BootCryptoInfo->EncryptedAreaStart >> TC_LB_SIZE_BIT_SHIFT_DIVISOR;
-
- PimValueOrHiddenVolumeStartUnitNo = EncryptedVirtualPartition.StartSector;
- HiddenVolumeStartSector = PartitionFollowingActive.StartSector;
- HiddenVolumeStartSector += EncryptedVirtualPartition.StartSector;
-
- EncryptedVirtualPartition.SectorCount = BootCryptoInfo->EncryptedAreaLength >> TC_LB_SIZE_BIT_SHIFT_DIVISOR;
-
- EncryptedVirtualPartition.EndSector = EncryptedVirtualPartition.SectorCount - 1;
- EncryptedVirtualPartition.EndSector += EncryptedVirtualPartition.StartSector;
- }
- else
- {
- // Drive not encrypted
- EncryptedVirtualPartition.Drive = TC_INVALID_BIOS_DRIVE;
- }
-
- return true;
-}
-
-
-static bool GetSystemPartitions (byte drive)
-{
- size_t partCount;
-
- if (!GetActivePartition (drive))
- return false;
-
- // Find partition following the active one
- GetDrivePartitions (drive, &PartitionFollowingActive, 1, partCount, false, &ActivePartition);
-
- // If there is an extra boot partition, use the partitions following it.
- // The real boot partition is determined in BootEncryptedDrive().
- if (ActivePartition.SectorCount.HighPart == 0 && ActivePartition.SectorCount.LowPart <= TC_MAX_EXTRA_BOOT_PARTITION_SIZE / TC_LB_SIZE
- && PartitionFollowingActive.Drive != TC_INVALID_BIOS_DRIVE)
- {
- ExtraBootPartitionPresent = true;
-
- ActivePartition = PartitionFollowingActive;
- GetDrivePartitions (drive, &PartitionFollowingActive, 1, partCount, false, &ActivePartition);
- }
-
- return true;
-}
-
-
-static byte BootEncryptedDrive ()
-{
- BootArguments *bootArguments = (BootArguments *) TC_BOOT_LOADER_ARGS_OFFSET;
- byte exitKey;
- BootCryptoInfo = NULL;
-
- if (!GetSystemPartitions (BootDrive))
- goto err;
-
- if (!MountVolume (BootDrive, exitKey, PreventNormalSystemBoot, false))
- return exitKey;
-
- if (!CheckMemoryRequirements ())
- goto err;
-
- if (BootCryptoInfo->hiddenVolume)
- {
- EncryptedVirtualPartition = ActivePartition;
- bootArguments->DecoySystemPartitionStart = ActivePartition.StartSector << TC_LB_SIZE_BIT_SHIFT_DIVISOR;
- }
-
- if (ExtraBootPartitionPresent && !GetActivePartition (BootDrive))
- goto err;
-
- if (ReadWriteMBR (false, ActivePartition.Drive) != BiosResultSuccess)
- goto err;
-
- bootArguments->BootDriveSignature = *(uint32 *) (SectorBuffer + 0x1b8);
-
- if (!InstallInterruptFilters())
- goto err;
-
- bootArguments->BootArgumentsCrc32 = GetCrc32 ((byte *) bootArguments, (byte *) &bootArguments->BootArgumentsCrc32 - (byte *) bootArguments);
-
- while (true)
- {
- // Execute boot sector of the active partition
- if (ReadSectors (SectorBuffer, ActivePartition.Drive, ActivePartition.StartSector, 1) == BiosResultSuccess)
- {
- if (*(uint16 *) (SectorBuffer + 510) != 0xaa55)
- {
- PrintError (TC_BOOT_STR_NO_BOOT_PARTITION);
- GetKeyboardChar();
- }
-
- ExecuteBootSector (ActivePartition.Drive, SectorBuffer);
- }
-
- GetKeyboardChar();
- }
-
-err:
- if (BootCryptoInfo)
- {
- crypto_close (BootCryptoInfo);
- BootCryptoInfo = NULL;
- }
-
- EncryptedVirtualPartition.Drive = TC_INVALID_BIOS_DRIVE;
- EraseMemory ((void *) TC_BOOT_LOADER_ARGS_OFFSET, sizeof (BootArguments));
-
- byte scanCode;
- GetKeyboardChar (&scanCode);
- return scanCode;
-}
-
-
-static void BootMenu ()
-{
- BiosResult result;
- Partition partitions[16];
- Partition bootablePartitions[9];
- size_t partitionCount;
- size_t bootablePartitionCount = 0;
-
- for (byte drive = TC_FIRST_BIOS_DRIVE; drive <= TC_LAST_BIOS_DRIVE; ++drive)
- {
- if (GetDrivePartitions (drive, partitions, array_capacity (partitions), partitionCount, false, nullptr, true) == BiosResultSuccess)
- {
- for (size_t i = 0; i < partitionCount; ++i)
- {
- const Partition &partition = partitions[i];
- result = ReadSectors (SectorBuffer, drive, partition.StartSector, 1);
-
- if (result == BiosResultSuccess && *(uint16 *) (SectorBuffer + TC_LB_SIZE - 2) == 0xaa55)
- {
- // Windows writes boot loader on all NTFS/FAT filesytems it creates and, therefore,
- // NTFS/FAT partitions must have the boot indicator set to be considered bootable.
- if (!partition.Active
- && (*(uint32 *) (SectorBuffer + 3) == 0x5346544e // 'NTFS'
- || *(uint32 *) (SectorBuffer + 3) == 0x41465845 && SectorBuffer[7] == 'T' // 'exFAT'
- || *(uint16 *) (SectorBuffer + 54) == 0x4146 && SectorBuffer[56] == 'T' // 'FAT'
- || *(uint16 *) (SectorBuffer + 82) == 0x4146 && SectorBuffer[84] == 'T'))
- {
- continue;
- }
-
- // Bootable sector found
- if (bootablePartitionCount < array_capacity (bootablePartitions))
- bootablePartitions[bootablePartitionCount++] = partition;
- }
- }
- }
- }
-
- if (bootablePartitionCount < 1)
- {
- PrintError (TC_BOOT_STR_NO_BOOT_PARTITION);
- GetKeyboardChar();
- return;
- }
-
- char partChar;
- while (true)
- {
- InitScreen();
- Print ("Bootable Partitions:\r\n");
- PrintRepeatedChar ('\xC4', 20);
- Print ("\r\n");
-
- for (size_t i = 0; i < bootablePartitionCount; ++i)
- {
- const Partition &partition = bootablePartitions[i];
- Print ("["); Print (i + 1); Print ("] ");
- Print ("Drive: "); Print (partition.Drive - TC_FIRST_BIOS_DRIVE);
- Print (", Partition: "); Print (partition.Number + 1);
- Print (", Size: "); PrintSectorCountInMB (partition.SectorCount); PrintEndl();
- }
-
- if (bootablePartitionCount == 1)
- {
- // There's only one bootable partition so we'll boot it directly instead of showing boot manager
- partChar = '1';
- }
- else
- {
- Print ("[Esc] Cancel\r\n\r\n");
- Print ("Press 1-9 to select partition: ");
-
- if (GetString (&partChar, 1) == 0)
- return;
-
- PrintEndl();
-
- if (partChar < '1' || partChar > '0' + bootablePartitionCount)
- {
- Beep();
- continue;
- }
- }
-
- const Partition &partition = bootablePartitions[partChar - '0' - 1];
-
- if (ReadSectors (SectorBuffer, partition.Drive, partition.StartSector, 1) == BiosResultSuccess)
- {
- ExecuteBootSector (partition.Drive, SectorBuffer);
- }
- }
-}
-
-
-#ifndef TC_WINDOWS_BOOT_RESCUE_DISK_MODE
-
-static bool CopySystemPartitionToHiddenVolume (byte drive, byte &exitKey)
-{
- bool status = false;
-
- uint64 sectorsRemaining;
- uint64 sectorOffset;
- sectorOffset.LowPart = 0;
- sectorOffset.HighPart = 0;
-
- int fragmentSectorCount = 0x7f; // Maximum safe value supported by BIOS
- int statCount = 0;
-
- if (!CheckMemoryRequirements ())
- goto err;
-
- if (!GetSystemPartitions (drive))
- goto err;
-
- if (PartitionFollowingActive.Drive == TC_INVALID_BIOS_DRIVE)
- TC_THROW_FATAL_EXCEPTION;
-
- // Check if BIOS can read the last sector of the hidden system
- AcquireSectorBuffer();
-
- if (ReadSectors (SectorBuffer, PartitionFollowingActive.Drive, PartitionFollowingActive.EndSector - (TC_VOLUME_HEADER_GROUP_SIZE / TC_LB_SIZE - 2), 1) != BiosResultSuccess
- || GetCrc32 (SectorBuffer, sizeof (SectorBuffer)) != OuterVolumeBackupHeaderCrc)
- {
- PrintErrorNoEndl ("Your BIOS does not support large drives");
- Print (IsLbaSupported (PartitionFollowingActive.Drive) ? " due to a bug" : "\r\n- Enable LBA in BIOS");
- PrintEndl();
- Print (TC_BOOT_STR_UPGRADE_BIOS);
-
- ReleaseSectorBuffer();
- goto err;
- }
-
- ReleaseSectorBuffer();
-
- if (!MountVolume (drive, exitKey, true, false))
- return false;
-
- sectorsRemaining = EncryptedVirtualPartition.SectorCount;
-
- if (!(sectorsRemaining == ActivePartition.SectorCount))
- TC_THROW_FATAL_EXCEPTION;
-
- InitScreen();
- Print ("\r\nCopying system to hidden volume. To abort, press Esc.\r\n\r\n");
-
- while (sectorsRemaining.HighPart != 0 || sectorsRemaining.LowPart != 0)
- {
- if (EscKeyPressed())
- {
- Print ("\rIf aborted, copying will have to start from the beginning (if attempted again).\r\n");
- if (AskYesNo ("Abort"))
- break;
- }
-
- if (sectorsRemaining.HighPart == 0 && sectorsRemaining.LowPart < fragmentSectorCount)
- fragmentSectorCount = (int) sectorsRemaining.LowPart;
-
- if (ReadWriteSectors (false, TC_BOOT_LOADER_BUFFER_SEGMENT, 0, drive, ActivePartition.StartSector + sectorOffset, fragmentSectorCount, false) != BiosResultSuccess)
- {
- Print ("To fix bad sectors: 1) Terminate 2) Encrypt and decrypt sys partition 3) Retry\r\n");
- crypto_close (BootCryptoInfo);
- goto err;
- }
-
- AcquireSectorBuffer();
-
- for (int i = 0; i < fragmentSectorCount; ++i)
- {
- CopyMemory (TC_BOOT_LOADER_BUFFER_SEGMENT, i * TC_LB_SIZE, SectorBuffer, TC_LB_SIZE);
-
- uint64 s = PimValueOrHiddenVolumeStartUnitNo + sectorOffset + i;
- EncryptDataUnits (SectorBuffer, &s, 1, BootCryptoInfo);
-
- CopyMemory (SectorBuffer, TC_BOOT_LOADER_BUFFER_SEGMENT, i * TC_LB_SIZE, TC_LB_SIZE);
- }
-
- ReleaseSectorBuffer();
-
- if (ReadWriteSectors (true, TC_BOOT_LOADER_BUFFER_SEGMENT, 0, drive, HiddenVolumeStartSector + sectorOffset, fragmentSectorCount, false) != BiosResultSuccess)
- {
- crypto_close (BootCryptoInfo);
- goto err;
- }
-
- sectorsRemaining = sectorsRemaining - fragmentSectorCount;
- sectorOffset = sectorOffset + fragmentSectorCount;
-
- if (!(statCount++ & 0xf))
- {
- Print ("\rRemaining: ");
- PrintSectorCountInMB (sectorsRemaining);
- }
- }
-
- crypto_close (BootCryptoInfo);
-
- if (sectorsRemaining.HighPart == 0 && sectorsRemaining.LowPart == 0)
- {
- status = true;
- Print ("\rCopying completed.");
- }
-
- PrintEndl (2);
- goto ret;
-
-err:
- exitKey = TC_BIOS_KEY_ESC;
- GetKeyboardChar();
-
-ret:
- EraseMemory ((void *) TC_BOOT_LOADER_ARGS_OFFSET, sizeof (BootArguments));
- return status;
-}
-
-
-#else // TC_WINDOWS_BOOT_RESCUE_DISK_MODE
-
-
-static void DecryptDrive (byte drive)
-{
- byte exitKey;
- if (!MountVolume (drive, exitKey, false, true))
- return;
-
- BootArguments *bootArguments = (BootArguments *) TC_BOOT_LOADER_ARGS_OFFSET;
-
- bool headerUpdateRequired = false;
- uint64 sectorsRemaining = EncryptedVirtualPartition.EndSector + 1 - EncryptedVirtualPartition.StartSector;
- uint64 sector = EncryptedVirtualPartition.EndSector + 1;
-
- int fragmentSectorCount = 0x7f; // Maximum safe value supported by BIOS
- int statCount = 0;
-
- bool skipBadSectors = false;
-
- Print ("\r\nUse only if Windows cannot start. Decryption under Windows is much faster\r\n"
- "(in VeraCrypt, select 'System' > 'Permanently Decrypt').\r\n\r\n");
-
- if (!AskYesNo ("Decrypt now"))
- {
- crypto_close (BootCryptoInfo);
- goto ret;
- }
-
- if (EncryptedVirtualPartition.Drive == TC_INVALID_BIOS_DRIVE)
- {
- // Drive already decrypted
- sectorsRemaining.HighPart = 0;
- sectorsRemaining.LowPart = 0;
- }
- else
- {
- Print ("\r\nTo safely interrupt and defer decryption, press Esc.\r\n"
- "WARNING: You can turn off power only after you press Esc.\r\n\r\n");
- }
-
- while (sectorsRemaining.HighPart != 0 || sectorsRemaining.LowPart != 0)
- {
- if (EscKeyPressed())
- break;
-
- if (sectorsRemaining.HighPart == 0 && sectorsRemaining.LowPart < fragmentSectorCount)
- fragmentSectorCount = (int) sectorsRemaining.LowPart;
-
- sector = sector - fragmentSectorCount;
-
- if (!(statCount++ & 0xf))
- {
- Print ("\rRemaining: ");
- PrintSectorCountInMB (sectorsRemaining);
- }
-
- if (ReadWriteSectors (false, TC_BOOT_LOADER_BUFFER_SEGMENT, 0, drive, sector, fragmentSectorCount, skipBadSectors) == BiosResultSuccess)
- {
- AcquireSectorBuffer();
-
- for (int i = 0; i < fragmentSectorCount; ++i)
- {
- CopyMemory (TC_BOOT_LOADER_BUFFER_SEGMENT, i * TC_LB_SIZE, SectorBuffer, TC_LB_SIZE);
-
- uint64 s = sector + i;
- DecryptDataUnits (SectorBuffer, &s, 1, BootCryptoInfo);
-
- CopyMemory (SectorBuffer, TC_BOOT_LOADER_BUFFER_SEGMENT, i * TC_LB_SIZE, TC_LB_SIZE);
- }
-
- ReleaseSectorBuffer();
-
- if (ReadWriteSectors (true, TC_BOOT_LOADER_BUFFER_SEGMENT, 0, drive, sector, fragmentSectorCount, skipBadSectors) != BiosResultSuccess && !skipBadSectors)
- goto askBadSectorSkip;
- }
- else if (!skipBadSectors)
- goto askBadSectorSkip;
-
- sectorsRemaining = sectorsRemaining - fragmentSectorCount;
- headerUpdateRequired = true;
- continue;
-
-askBadSectorSkip:
- if (!AskYesNo ("Skip all bad sectors"))
- break;
-
- skipBadSectors = true;
- sector = sector + fragmentSectorCount;
- fragmentSectorCount = 1;
- }
-
- crypto_close (BootCryptoInfo);
-
- if (headerUpdateRequired)
- {
- Print ("\rUpdating header...");
-
- AcquireSectorBuffer();
- uint64 headerSector;
- headerSector.HighPart = 0;
- headerSector.LowPart = TC_BOOT_VOLUME_HEADER_SECTOR;
-
- // Update encrypted area size in volume header
-
- CRYPTO_INFO *headerCryptoInfo = crypto_open();
- while (ReadSectors (SectorBuffer, drive, headerSector, 1) != BiosResultSuccess);
-
- if (ReadVolumeHeader (TRUE, (char *) SectorBuffer, &bootArguments->BootPassword, (int) (bootArguments->Flags >> 16), NULL, headerCryptoInfo) == 0)
- {
- DecryptBuffer (SectorBuffer + HEADER_ENCRYPTED_DATA_OFFSET, HEADER_ENCRYPTED_DATA_SIZE, headerCryptoInfo);
-
- uint64 encryptedAreaLength = sectorsRemaining << TC_LB_SIZE_BIT_SHIFT_DIVISOR;
-
- for (int i = 7; i >= 0; --i)
- {
- SectorBuffer[TC_HEADER_OFFSET_ENCRYPTED_AREA_LENGTH + i] = (byte) encryptedAreaLength.LowPart;
- encryptedAreaLength = encryptedAreaLength >> 8;
- }
-
- uint32 headerCrc32 = GetCrc32 (SectorBuffer + TC_HEADER_OFFSET_MAGIC, TC_HEADER_OFFSET_HEADER_CRC - TC_HEADER_OFFSET_MAGIC);
-
- for (i = 3; i >= 0; --i)
- {
- SectorBuffer[TC_HEADER_OFFSET_HEADER_CRC + i] = (byte) headerCrc32;
- headerCrc32 >>= 8;
- }
-
- EncryptBuffer (SectorBuffer + HEADER_ENCRYPTED_DATA_OFFSET, HEADER_ENCRYPTED_DATA_SIZE, headerCryptoInfo);
- }
-
- crypto_close (headerCryptoInfo);
-
- while (WriteSectors (SectorBuffer, drive, headerSector, 1) != BiosResultSuccess);
- ReleaseSectorBuffer();
-
- Print ("Done!\r\n");
- }
-
- if (sectorsRemaining.HighPart == 0 && sectorsRemaining.LowPart == 0)
- Print ("\rDrive decrypted.\r\n");
- else
- Print ("\r\nDecryption deferred.\r\n");
-
- GetKeyboardChar();
-ret:
- EraseMemory (bootArguments, sizeof (*bootArguments));
-}
-
-
-static void RepairMenu ()
-{
- DriveGeometry bootLoaderDriveGeometry;
-
- if (GetDriveGeometry (BootLoaderDrive, bootLoaderDriveGeometry, true) != BiosResultSuccess)
- {
- // Some BIOSes may fail to get the geometry of an emulated floppy drive
- bootLoaderDriveGeometry.Cylinders = 80;
- bootLoaderDriveGeometry.Heads = 2;
- bootLoaderDriveGeometry.Sectors = 18;
- }
-
- while (true)
- {
- InitScreen();
- Print ("Available "); Print ("Repair Options"); Print (":\r\n");
- PrintRepeatedChar ('\xC4', 25);
- PrintEndl();
-
- enum
- {
- RestoreNone = 0,
- DecryptVolume,
- RestoreTrueCryptLoader,
- RestoreVolumeHeader,
- RestoreOriginalSystemLoader
- };
-
- static const char *options[] = { "Permanently decrypt system partition/drive", "Restore VeraCrypt Boot Loader", "Restore key data (volume header)", "Restore original system loader" };
-
- int selection = AskSelection (options,
- (BootSectorFlags & TC_BOOT_CFG_FLAG_RESCUE_DISK_ORIG_SYS_LOADER) ? array_capacity (options) : array_capacity (options) - 1);
-
- PrintEndl();
-
- switch (selection)
- {
- case RestoreNone:
- return;
-
- case DecryptVolume:
- DecryptDrive (BootDrive);
- continue;
-
- case RestoreOriginalSystemLoader:
- if (!AskYesNo ("Is the system partition/drive decrypted"))
- {
- Print ("Please decrypt it first.\r\n");
- GetKeyboardChar();
- continue;
- }
- break;
- }
-
- bool writeConfirmed = false;
- BiosResult result;
-
- uint64 sector;
- sector.HighPart = 0;
- ChsAddress chs;
-
- byte mbrPartTable[TC_LB_SIZE - TC_MAX_MBR_BOOT_CODE_SIZE];
- AcquireSectorBuffer();
-
- for (int i = (selection == RestoreVolumeHeader ? TC_BOOT_VOLUME_HEADER_SECTOR : TC_MBR_SECTOR);
- i < TC_BOOT_LOADER_AREA_SECTOR_COUNT; ++i)
- {
- sector.LowPart = i;
-
- if (selection == RestoreOriginalSystemLoader)
- sector.LowPart += TC_ORIG_BOOT_LOADER_BACKUP_SECTOR;
- else if (selection == RestoreTrueCryptLoader)
- sector.LowPart += TC_BOOT_LOADER_BACKUP_RESCUE_DISK_SECTOR;
-
- // The backup medium may be a floppy-emulated bootable CD. The emulation may fail if LBA addressing is used.
- // Therefore, only CHS addressing can be used.
- LbaToChs (bootLoaderDriveGeometry, sector, chs);
- sector.LowPart = i;
-
- if (i == TC_MBR_SECTOR)
- {
- // Read current partition table
- result = ReadSectors (SectorBuffer, TC_FIRST_BIOS_DRIVE, sector, 1);
- if (result != BiosResultSuccess)
- goto err;
-
- memcpy (mbrPartTable, SectorBuffer + TC_MAX_MBR_BOOT_CODE_SIZE, sizeof (mbrPartTable));
- }
-
- result = ReadSectors (SectorBuffer, BootLoaderDrive, chs, 1);
- if (result != BiosResultSuccess)
- goto err;
-
- if (i == TC_MBR_SECTOR)
- {
- // Preserve current partition table
- memcpy (SectorBuffer + TC_MAX_MBR_BOOT_CODE_SIZE, mbrPartTable, sizeof (mbrPartTable));
- }
-
- // Volume header
- if (i == TC_BOOT_VOLUME_HEADER_SECTOR)
- {
- if (selection == RestoreTrueCryptLoader)
- continue;
-
- if (selection == RestoreVolumeHeader)
- {
- while (true)
- {
- bool validHeaderPresent = false;
- uint32 masterKeyScheduleCrc;
-
- Password password;
- int pim;
- byte exitKey = AskPassword (password, pim);
-
- if (exitKey != TC_BIOS_KEY_ENTER)
- goto abort;
-
- CRYPTO_INFO *cryptoInfo;
-
- CopyMemory (SectorBuffer, TC_BOOT_LOADER_BUFFER_SEGMENT, 0, TC_LB_SIZE);
- ReleaseSectorBuffer();
-
- // Restore volume header only if the current one cannot be used
- if (OpenVolume (TC_FIRST_BIOS_DRIVE, password, pim, &cryptoInfo, nullptr, false, true))
- {
- validHeaderPresent = true;
- masterKeyScheduleCrc = GetCrc32 (cryptoInfo->ks, sizeof (cryptoInfo->ks));
- crypto_close (cryptoInfo);
- }
-
- AcquireSectorBuffer();
- CopyMemory (TC_BOOT_LOADER_BUFFER_SEGMENT, 0, SectorBuffer, TC_LB_SIZE);
-
- if (ReadVolumeHeader (TRUE, (char *) SectorBuffer, &password, pim, &cryptoInfo, nullptr) == 0)
- {
- if (validHeaderPresent)
- {
- if (masterKeyScheduleCrc == GetCrc32 (cryptoInfo->ks, sizeof (cryptoInfo->ks)))
- {
- Print ("Original header preserved.\r\n");
- goto err;
- }
-
- Print ("WARNING: Drive 0 contains a valid header!\r\n");
- }
-
- crypto_close (cryptoInfo);
- break;
- }
-
- Print ("Incorrect password.\r\n\r\n");
- }
- }
- }
-
- if (!writeConfirmed && !AskYesNo ("Modify drive 0"))
- goto abort;
- writeConfirmed = true;
-
- if (WriteSectors (SectorBuffer, TC_FIRST_BIOS_DRIVE, sector, 1) != BiosResultSuccess)
- goto err;
- }
-done:
- switch (selection)
- {
- case RestoreTrueCryptLoader:
- Print ("VeraCrypt Boot Loader");
- break;
-
- case RestoreVolumeHeader:
- Print ("Header");
- break;
-
- case RestoreOriginalSystemLoader:
- Print ("System loader");
- break;
- }
- Print (" restored.\r\n");
-
-err: GetKeyboardChar();
-abort: ReleaseSectorBuffer();
- }
-}
-
-#endif // TC_WINDOWS_BOOT_RESCUE_DISK_MODE
-
-
-#ifndef DEBUG
-extern "C" void _acrtused () { } // Required by linker
-#endif
-
-
-void main ()
-{
- __asm mov BootLoaderDrive, dl
- __asm mov BootSectorFlags, dh
-
-#ifdef TC_BOOT_TRACING_ENABLED
- InitDebugPort();
-#endif
-
-#ifdef TC_BOOT_STACK_CHECKING_ENABLED
- InitStackChecker();
-#endif
-
-#ifndef TC_WINDOWS_BOOT_RESCUE_DISK_MODE
- ReadBootSectorUserConfiguration();
-#elif defined (TC_WINDOWS_BOOT_AES)
- EnableHwEncryption (!(BootSectorFlags & TC_BOOT_CFG_FLAG_RESCUE_DISABLE_HW_ENCRYPTION));
-#endif
-
- InitVideoMode();
- InitScreen();
-
- // Determine boot drive
- BootDrive = BootLoaderDrive;
- if (BootDrive < TC_FIRST_BIOS_DRIVE)
- BootDrive = TC_FIRST_BIOS_DRIVE;
-
- // Query boot drive geometry
- if (GetDriveGeometry (BootDrive, BootDriveGeometry) != BiosResultSuccess)
- {
- BootDrive = TC_FIRST_BIOS_DRIVE;
- if (GetDriveGeometry (BootDrive, BootDriveGeometry) != BiosResultSuccess)
- {
-#ifdef TC_WINDOWS_BOOT_RESCUE_DISK_MODE
- Print ("- Connect system drive to (SATA) port 1\r\n");
-#endif
- GetKeyboardChar();
- }
- else
- BootDriveGeometryValid = true;
- }
- else
- BootDriveGeometryValid = true;
-
-#ifdef TC_WINDOWS_BOOT_RESCUE_DISK_MODE
-
- // Check whether the user is not using the Rescue Disk to create a hidden system
-
- if (ReadWriteMBR (false, BootDrive, true) == BiosResultSuccess
- && *(uint32 *) (SectorBuffer + 6) == 0x61726556
- && *(uint32 *) (SectorBuffer + 10) == 0x70797243
- && (SectorBuffer[TC_BOOT_SECTOR_CONFIG_OFFSET] & TC_BOOT_CFG_MASK_HIDDEN_OS_CREATION_PHASE) != TC_HIDDEN_OS_CREATION_PHASE_NONE)
- {
- PrintError ("It appears you are creating a hidden OS.");
- if (AskYesNo ("Is this correct"))
- {
- Print ("Please remove the Rescue Disk from the drive and restart.");
- while (true);
- }
- }
-
-#endif // TC_WINDOWS_BOOT_RESCUE_DISK_MODE
-
-
- // Main menu
-
- while (true)
- {
- byte exitKey;
- InitScreen();
-
-#ifndef TC_WINDOWS_BOOT_RESCUE_DISK_MODE
-
- // Hidden system setup
- byte hiddenSystemCreationPhase = BootSectorFlags & TC_BOOT_CFG_MASK_HIDDEN_OS_CREATION_PHASE;
-
- if (hiddenSystemCreationPhase != TC_HIDDEN_OS_CREATION_PHASE_NONE)
- {
- PreventNormalSystemBoot = true;
- PrintMainMenu();
-
- if (hiddenSystemCreationPhase == TC_HIDDEN_OS_CREATION_PHASE_CLONING)
- {
- if (CopySystemPartitionToHiddenVolume (BootDrive, exitKey))
- {
- BootSectorFlags = (BootSectorFlags & ~TC_BOOT_CFG_MASK_HIDDEN_OS_CREATION_PHASE) | TC_HIDDEN_OS_CREATION_PHASE_WIPING;
- UpdateBootSectorConfiguration (BootLoaderDrive);
- }
- else if (exitKey == TC_BIOS_KEY_ESC)
- goto bootMenu;
- else
- continue;
- }
- }
- else
- PrintMainMenu();
-
- exitKey = BootEncryptedDrive();
-
-#else // TC_WINDOWS_BOOT_RESCUE_DISK_MODE
-
- PrintMainMenu();
- exitKey = BootEncryptedDrive();
-
- if (exitKey == TC_MENU_KEY_REPAIR)
- {
- RepairMenu();
- continue;
- }
-
-#endif // TC_WINDOWS_BOOT_RESCUE_DISK_MODE
-
-bootMenu:
- if (!PreventBootMenu)
- BootMenu();
- }
-}
+/*
+ Derived from source code of TrueCrypt 7.1a, which is
+ Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed
+ by the TrueCrypt License 3.0.
+
+ Modifications and additions to the original source code (contained in this file)
+ and all other portions of this file are Copyright (c) 2013-2016 IDRIX
+ and are governed by the Apache License 2.0 the full text of which is
+ contained in the file License.txt included in VeraCrypt binary and source
+ code distribution packages.
+*/
+
+#include "Crc.h"
+#include "Crypto.h"
+#include "Password.h"
+#include "Volumes.h"
+
+#include "Platform.h"
+#include "Bios.h"
+#include "BootConfig.h"
+#include "BootMain.h"
+#include "BootDefs.h"
+#include "BootCommon.h"
+#include "BootConsoleIo.h"
+#include "BootDebug.h"
+#include "BootDiskIo.h"
+#include "BootEncryptedIo.h"
+#include "BootMemory.h"
+#include "BootStrings.h"
+#include "IntFilter.h"
+
+
+static void InitScreen ()
+{
+ ClearScreen();
+
+ const char *title =
+#ifndef TC_WINDOWS_BOOT_RESCUE_DISK_MODE
+ " VeraCrypt Boot Loader "
+#else
+ " VeraCrypt Rescue Disk "
+#endif
+ VERSION_STRING "\r\n";
+
+ Print (title);
+
+ PrintRepeatedChar ('\xDC', TC_BIOS_MAX_CHARS_PER_LINE);
+
+#ifndef TC_WINDOWS_BOOT_RESCUE_DISK_MODE
+ if (CustomUserMessage[0])
+ {
+ PrintEndl();
+ Print (CustomUserMessage);
+ }
+#endif
+
+ PrintEndl (2);
+}
+
+
+static void PrintMainMenu ()
+{
+ if (PreventBootMenu)
+ return;
+
+ Print (" Keyboard Controls:\r\n");
+ Print (" [F5] Hide/Show Password and PIM\r\n");
+ Print (" [Esc] ");
+
+#ifndef TC_WINDOWS_BOOT_RESCUE_DISK_MODE
+
+ Print ((BootSectorFlags & TC_BOOT_CFG_MASK_HIDDEN_OS_CREATION_PHASE) != TC_HIDDEN_OS_CREATION_PHASE_NONE
+ ? "Boot Non-Hidden System (Boot Manager)"
+ : "Skip Authentication (Boot Manager)");
+
+#else // TC_WINDOWS_BOOT_RESCUE_DISK_MODE
+
+ Print ("Skip Authentication (Boot Manager)");
+ Print ("\r\n [F8] "); Print ("Repair Options");
+
+#endif // TC_WINDOWS_BOOT_RESCUE_DISK_MODE
+
+ PrintEndl (3);
+}
+
+
+static bool IsMenuKey (byte scanCode)
+{
+#ifdef TC_WINDOWS_BOOT_RESCUE_DISK_MODE
+ return scanCode == TC_MENU_KEY_REPAIR;
+#else
+ return false;
+#endif
+}
+
+
+static bool AskYesNo (const char *message)
+{
+ Print (message);
+ Print ("? (y/n): ");
+ while (true)
+ {
+ switch (GetKeyboardChar())
+ {
+ case 'y':
+ case 'Y':
+ case 'z':
+ case 'Z':
+ Print ("y\r\n");
+ return true;
+
+ case 'n':
+ case 'N':
+ Print ("n\r\n");
+ return false;
+
+ default:
+ Beep();
+ }
+ }
+}
+
+
+static int AskSelection (const char *options[], size_t optionCount)
+{
+ for (int i = 0; i < optionCount; ++i)
+ {
+ Print ("["); Print (i + 1); Print ("] ");
+ Print (options[i]);
+ PrintEndl();
+ }
+ Print ("[Esc] Cancel\r\n\r\n");
+
+ Print ("To select, press 1-9: ");
+
+ char str;
+
+ while (true)
+ {
+ if (GetString (&str, 1) == 0)
+ return 0;
+
+ if (str >= '1' && str <= optionCount + '0')
+ return str - '0';
+
+ Beep();
+ PrintBackspace();
+ }
+}
+
+
+static byte AskPassword (Password &password, int& pim)
+{
+ size_t pos = 0;
+ byte scanCode;
+ byte asciiCode;
+ byte hidePassword = 1;
+
+ pim = 0;
+
+ Print ("Enter password");
+ Print (PreventNormalSystemBoot ? " for hidden system:\r\n" : ": ");
+
+ while (true)
+ {
+ asciiCode = GetKeyboardChar (&scanCode);
+
+ switch (scanCode)
+ {
+ case TC_BIOS_KEY_ENTER:
+ password.Length = pos;
+ Print ("\r");
+ if (!PreventNormalSystemBoot)
+ Print ("Enter password: ");
+ pos = 0;
+ while (pos < MAX_PASSWORD)
+ {
+ pos++;
+ if (pos < MAX_PASSWORD)
+ PrintChar ('*');
+ else
+ PrintCharAtCursor ('*');
+ }
+
+ ClearBiosKeystrokeBuffer();
+ PrintEndl();
+
+ break;
+
+ case TC_BIOS_KEY_BACKSPACE:
+ if (pos > 0)
+ {
+ if (pos < MAX_PASSWORD)
+ PrintBackspace();
+ else
+ PrintCharAtCursor (' ');
+
+ --pos;
+ }
+ continue;
+
+ case TC_BIOS_KEY_F5:
+ hidePassword ^= 0x01;
+ continue;
+
+ default:
+ if (scanCode == TC_BIOS_KEY_ESC || IsMenuKey (scanCode))
+ {
+ burn (password.Text, sizeof (password.Text));
+ ClearBiosKeystrokeBuffer();
+
+ PrintEndl();
+ return scanCode;
+ }
+ }
+
+ if (TC_BIOS_KEY_ENTER == scanCode)
+ break;
+
+ if (!IsPrintable (asciiCode) || pos == MAX_PASSWORD)
+ {
+ Beep();
+ continue;
+ }
+
+ password.Text[pos++] = asciiCode;
+ if (hidePassword) asciiCode = '*';
+ if (pos < MAX_PASSWORD)
+ PrintChar (asciiCode);
+ else
+ PrintCharAtCursor (asciiCode);
+ }
+
+#ifndef TC_WINDOWS_BOOT_RESCUE_DISK_MODE
+ if (PimValueOrHiddenVolumeStartUnitNo.LowPart != -1)
+ {
+ pim = (int) PimValueOrHiddenVolumeStartUnitNo.LowPart;
+ // reset stored PIM value to allow requesting PIM next time in case the stored value is wrong
+ PimValueOrHiddenVolumeStartUnitNo.LowPart = -1;
+ return TC_BIOS_KEY_ENTER;
+ }
+ else
+#endif
+ {
+ pos = 0;
+ Print ("PIM: ");
+
+ while (true)
+ {
+ asciiCode = GetKeyboardChar (&scanCode);
+
+ switch (scanCode)
+ {
+ case TC_BIOS_KEY_ENTER:
+ Print ("\rPIM: ");
+ pos =0;
+ while (pos < MAX_PIM)
+ {
+ PrintChar ('*');
+ pos++;
+ }
+
+ ClearBiosKeystrokeBuffer();
+ PrintEndl();
+
+ return TC_BIOS_KEY_ENTER;
+
+ case TC_BIOS_KEY_BACKSPACE:
+ if (pos > 0)
+ {
+ if (pos < MAX_PIM)
+ PrintBackspace();
+ else
+ PrintCharAtCursor (' ');
+
+ --pos;
+ pim /= 10;
+ }
+ continue;
+
+ case TC_BIOS_KEY_F5:
+ hidePassword ^= 0x01;
+ continue;
+
+ default:
+ if (scanCode == TC_BIOS_KEY_ESC || IsMenuKey (scanCode))
+ {
+ burn (password.Text, sizeof (password.Text));
+ ClearBiosKeystrokeBuffer();
+
+ PrintEndl();
+ return scanCode;
+ }
+ }
+
+ if (!IsDigit (asciiCode) || pos == MAX_PIM)
+ {
+ Beep();
+ continue;
+ }
+
+ pim = 10*pim + (asciiCode - '0');
+ pos++;
+
+ if (hidePassword) asciiCode = '*';
+ if (pos < MAX_PIM)
+ PrintChar (asciiCode);
+ else
+ PrintCharAtCursor (asciiCode);
+ }
+ }
+}
+
+
+static void ExecuteBootSector (byte drive, byte *sectorBuffer)
+{
+ Print ("Booting...\r\n");
+ CopyMemory (sectorBuffer, 0x0000, 0x7c00, TC_LB_SIZE);
+
+ BootStarted = true;
+
+ uint32 addr = 0x7c00;
+ __asm
+ {
+ cli
+ mov dl, drive // Boot drive
+ mov dh, 0
+ xor ax, ax
+ mov si, ax
+ mov ds, ax
+ mov es, ax
+ mov ss, ax
+ mov sp, 0x7c00
+ sti
+
+ jmp cs:addr
+ }
+}
+
+
+static bool OpenVolume (byte drive, Password &password, int pim, CRYPTO_INFO **cryptoInfo, uint32 *headerSaltCrc32, bool skipNormal, bool skipHidden)
+{
+ int volumeType;
+ bool hiddenVolume;
+ uint64 headerSec;
+
+ AcquireSectorBuffer();
+
+ for (volumeType = 1; volumeType <= 2; ++volumeType)
+ {
+ hiddenVolume = (volumeType == 2);
+
+ if (hiddenVolume)
+ {
+ if (skipHidden || PartitionFollowingActive.Drive != drive || PartitionFollowingActive.SectorCount <= ActivePartition.SectorCount)
+ continue;
+
+ headerSec = PartitionFollowingActive.StartSector + TC_HIDDEN_VOLUME_HEADER_OFFSET / TC_LB_SIZE;
+ }
+ else
+ {
+ if (skipNormal)
+ continue;
+
+ headerSec.HighPart = 0;
+ headerSec.LowPart = TC_BOOT_VOLUME_HEADER_SECTOR;
+ }
+
+ if (ReadSectors (SectorBuffer, drive, headerSec, 1) != BiosResultSuccess)
+ continue;
+
+ if (ReadVolumeHeader (!hiddenVolume, (char *) SectorBuffer, &password, pim, cryptoInfo, nullptr) == ERR_SUCCESS)
+ {
+ // Prevent opening a non-system hidden volume
+ if (hiddenVolume && !((*cryptoInfo)->HeaderFlags & TC_HEADER_FLAG_ENCRYPTED_SYSTEM))
+ {
+ crypto_close (*cryptoInfo);
+ continue;
+ }
+
+ if (headerSaltCrc32)
+ *headerSaltCrc32 = GetCrc32 (SectorBuffer, PKCS5_SALT_SIZE);
+
+ break;
+ }
+ }
+
+ ReleaseSectorBuffer();
+ return volumeType != 3;
+}
+
+
+static bool CheckMemoryRequirements ()
+{
+ uint16 codeSeg;
+ __asm mov codeSeg, cs
+ if (codeSeg == TC_BOOT_LOADER_LOWMEM_SEGMENT)
+ {
+ PrintErrorNoEndl ("BIOS reserved too much memory: ");
+
+ uint16 memFree;
+ __asm
+ {
+ push es
+ xor ax, ax
+ mov es, ax
+ mov ax, es:[0x413]
+ mov memFree, ax
+ pop es
+ }
+
+ Print (memFree);
+ PrintEndl();
+ Print (TC_BOOT_STR_UPGRADE_BIOS);
+
+ return false;
+ }
+
+ return true;
+}
+
+
+static bool MountVolume (byte drive, byte &exitKey, bool skipNormal, bool skipHidden)
+{
+ BootArguments *bootArguments = (BootArguments *) TC_BOOT_LOADER_ARGS_OFFSET;
+ int incorrectPasswordCount = 0, pim = 0;
+
+ EraseMemory (bootArguments, sizeof (*bootArguments));
+
+ // Open volume header
+ while (true)
+ {
+ exitKey = AskPassword (bootArguments->BootPassword, pim);
+
+ if (exitKey != TC_BIOS_KEY_ENTER)
+ return false;
+
+ Print ("Verifying password...");
+
+ if (OpenVolume (BootDrive, bootArguments->BootPassword, pim, &BootCryptoInfo, &bootArguments->HeaderSaltCrc32, skipNormal, skipHidden))
+ {
+ Print ("OK\r\n");
+ break;
+ }
+ if (GetShiftFlags() & TC_BIOS_SHIFTMASK_CAPSLOCK)
+ Print ("Warning: Caps Lock is on.\r\n");
+
+ Print ("Incorrect password.\r\n\r\n");
+
+ if (++incorrectPasswordCount == 4)
+ {
+#ifdef TC_WINDOWS_BOOT_RESCUE_DISK_MODE
+ Print ("If you are sure the password is correct, the key data may be damaged.\r\n"
+ "If so, use 'Repair Options' > 'Restore key data'.\r\n\r\n");
+#else
+ Print ("If you are sure the password is correct, the key data may be damaged. Boot your\r\n"
+ "VeraCrypt Rescue Disk and select 'Repair Options' > 'Restore key data'.\r\n\r\n");
+#endif
+ }
+ }
+
+ // Setup boot arguments
+ bootArguments->BootLoaderVersion = VERSION_NUM;
+ bootArguments->CryptoInfoOffset = (uint16) BootCryptoInfo;
+ bootArguments->CryptoInfoLength = sizeof (*BootCryptoInfo);
+ bootArguments->Flags = (((uint32)pim) << 16);
+
+ if (BootCryptoInfo->hiddenVolume)
+ bootArguments->HiddenSystemPartitionStart = PartitionFollowingActive.StartSector << TC_LB_SIZE_BIT_SHIFT_DIVISOR;
+
+ if (ExtraBootPartitionPresent)
+ bootArguments->Flags |= TC_BOOT_ARGS_FLAG_EXTRA_BOOT_PARTITION;
+
+ TC_SET_BOOT_ARGUMENTS_SIGNATURE (bootArguments->Signature);
+
+ // Setup virtual encrypted partition
+ if (BootCryptoInfo->EncryptedAreaLength.HighPart != 0 || BootCryptoInfo->EncryptedAreaLength.LowPart != 0)
+ {
+ EncryptedVirtualPartition.Drive = BootDrive;
+
+ EncryptedVirtualPartition.StartSector = BootCryptoInfo->EncryptedAreaStart >> TC_LB_SIZE_BIT_SHIFT_DIVISOR;
+
+ PimValueOrHiddenVolumeStartUnitNo = EncryptedVirtualPartition.StartSector;
+ HiddenVolumeStartSector = PartitionFollowingActive.StartSector;
+ HiddenVolumeStartSector += EncryptedVirtualPartition.StartSector;
+
+ EncryptedVirtualPartition.SectorCount = BootCryptoInfo->EncryptedAreaLength >> TC_LB_SIZE_BIT_SHIFT_DIVISOR;
+
+ EncryptedVirtualPartition.EndSector = EncryptedVirtualPartition.SectorCount - 1;
+ EncryptedVirtualPartition.EndSector += EncryptedVirtualPartition.StartSector;
+ }
+ else
+ {
+ // Drive not encrypted
+ EncryptedVirtualPartition.Drive = TC_INVALID_BIOS_DRIVE;
+ }
+
+ return true;
+}
+
+
+static bool GetSystemPartitions (byte drive)
+{
+ size_t partCount;
+
+ if (!GetActivePartition (drive))
+ return false;
+
+ // Find partition following the active one
+ GetDrivePartitions (drive, &PartitionFollowingActive, 1, partCount, false, &ActivePartition);
+
+ // If there is an extra boot partition, use the partitions following it.
+ // The real boot partition is determined in BootEncryptedDrive().
+ if (ActivePartition.SectorCount.HighPart == 0 && ActivePartition.SectorCount.LowPart <= TC_MAX_EXTRA_BOOT_PARTITION_SIZE / TC_LB_SIZE
+ && PartitionFollowingActive.Drive != TC_INVALID_BIOS_DRIVE)
+ {
+ ExtraBootPartitionPresent = true;
+
+ ActivePartition = PartitionFollowingActive;
+ GetDrivePartitions (drive, &PartitionFollowingActive, 1, partCount, false, &ActivePartition);
+ }
+
+ return true;
+}
+
+
+static byte BootEncryptedDrive ()
+{
+ BootArguments *bootArguments = (BootArguments *) TC_BOOT_LOADER_ARGS_OFFSET;
+ byte exitKey;
+ BootCryptoInfo = NULL;
+
+ if (!GetSystemPartitions (BootDrive))
+ goto err;
+
+ if (!MountVolume (BootDrive, exitKey, PreventNormalSystemBoot, false))
+ return exitKey;
+
+ if (!CheckMemoryRequirements ())
+ goto err;
+
+ if (BootCryptoInfo->hiddenVolume)
+ {
+ EncryptedVirtualPartition = ActivePartition;
+ bootArguments->DecoySystemPartitionStart = ActivePartition.StartSector << TC_LB_SIZE_BIT_SHIFT_DIVISOR;
+ }
+
+ if (ExtraBootPartitionPresent && !GetActivePartition (BootDrive))
+ goto err;
+
+ if (ReadWriteMBR (false, ActivePartition.Drive) != BiosResultSuccess)
+ goto err;
+
+ bootArguments->BootDriveSignature = *(uint32 *) (SectorBuffer + 0x1b8);
+
+ if (!InstallInterruptFilters())
+ goto err;
+
+ bootArguments->BootArgumentsCrc32 = GetCrc32 ((byte *) bootArguments, (byte *) &bootArguments->BootArgumentsCrc32 - (byte *) bootArguments);
+
+ while (true)
+ {
+ // Execute boot sector of the active partition
+ if (ReadSectors (SectorBuffer, ActivePartition.Drive, ActivePartition.StartSector, 1) == BiosResultSuccess)
+ {
+ if (*(uint16 *) (SectorBuffer + 510) != 0xaa55)
+ {
+ PrintError (TC_BOOT_STR_NO_BOOT_PARTITION);
+ GetKeyboardChar();
+ }
+
+ ExecuteBootSector (ActivePartition.Drive, SectorBuffer);
+ }
+
+ GetKeyboardChar();
+ }
+
+err:
+ if (BootCryptoInfo)
+ {
+ crypto_close (BootCryptoInfo);
+ BootCryptoInfo = NULL;
+ }
+
+ EncryptedVirtualPartition.Drive = TC_INVALID_BIOS_DRIVE;
+ EraseMemory ((void *) TC_BOOT_LOADER_ARGS_OFFSET, sizeof (BootArguments));
+
+ byte scanCode;
+ GetKeyboardChar (&scanCode);
+ return scanCode;
+}
+
+
+static void BootMenu ()
+{
+ BiosResult result;
+ Partition partitions[16];
+ Partition bootablePartitions[9];
+ size_t partitionCount;
+ size_t bootablePartitionCount = 0;
+
+ for (byte drive = TC_FIRST_BIOS_DRIVE; drive <= TC_LAST_BIOS_DRIVE; ++drive)
+ {
+ if (GetDrivePartitions (drive, partitions, array_capacity (partitions), partitionCount, false, nullptr, true) == BiosResultSuccess)
+ {
+ for (size_t i = 0; i < partitionCount; ++i)
+ {
+ const Partition &partition = partitions[i];
+ result = ReadSectors (SectorBuffer, drive, partition.StartSector, 1);
+
+ if (result == BiosResultSuccess && *(uint16 *) (SectorBuffer + TC_LB_SIZE - 2) == 0xaa55)
+ {
+ // Windows writes boot loader on all NTFS/FAT filesytems it creates and, therefore,
+ // NTFS/FAT partitions must have the boot indicator set to be considered bootable.
+ if (!partition.Active
+ && (*(uint32 *) (SectorBuffer + 3) == 0x5346544e // 'NTFS'
+ || *(uint32 *) (SectorBuffer + 3) == 0x41465845 && SectorBuffer[7] == 'T' // 'exFAT'
+ || *(uint16 *) (SectorBuffer + 54) == 0x4146 && SectorBuffer[56] == 'T' // 'FAT'
+ || *(uint16 *) (SectorBuffer + 82) == 0x4146 && SectorBuffer[84] == 'T'))
+ {
+ continue;
+ }
+
+ // Bootable sector found
+ if (bootablePartitionCount < array_capacity (bootablePartitions))
+ bootablePartitions[bootablePartitionCount++] = partition;
+ }
+ }
+ }
+ }
+
+ if (bootablePartitionCount < 1)
+ {
+ PrintError (TC_BOOT_STR_NO_BOOT_PARTITION);
+ GetKeyboardChar();
+ return;
+ }
+
+ char partChar;
+ while (true)
+ {
+ InitScreen();
+ Print ("Bootable Partitions:\r\n");
+ PrintRepeatedChar ('\xC4', 20);
+ Print ("\r\n");
+
+ for (size_t i = 0; i < bootablePartitionCount; ++i)
+ {
+ const Partition &partition = bootablePartitions[i];
+ Print ("["); Print (i + 1); Print ("] ");
+ Print ("Drive: "); Print (partition.Drive - TC_FIRST_BIOS_DRIVE);
+ Print (", Partition: "); Print (partition.Number + 1);
+ Print (", Size: "); PrintSectorCountInMB (partition.SectorCount); PrintEndl();
+ }
+
+ if (bootablePartitionCount == 1)
+ {
+ // There's only one bootable partition so we'll boot it directly instead of showing boot manager
+ partChar = '1';
+ }
+ else
+ {
+ Print ("[Esc] Cancel\r\n\r\n");
+ Print ("Press 1-9 to select partition: ");
+
+ if (GetString (&partChar, 1) == 0)
+ return;
+
+ PrintEndl();
+
+ if (partChar < '1' || partChar > '0' + bootablePartitionCount)
+ {
+ Beep();
+ continue;
+ }
+ }
+
+ const Partition &partition = bootablePartitions[partChar - '0' - 1];
+
+ if (ReadSectors (SectorBuffer, partition.Drive, partition.StartSector, 1) == BiosResultSuccess)
+ {
+ ExecuteBootSector (partition.Drive, SectorBuffer);
+ }
+ }
+}
+
+
+#ifndef TC_WINDOWS_BOOT_RESCUE_DISK_MODE
+
+static bool CopySystemPartitionToHiddenVolume (byte drive, byte &exitKey)
+{
+ bool status = false;
+
+ uint64 sectorsRemaining;
+ uint64 sectorOffset;
+ sectorOffset.LowPart = 0;
+ sectorOffset.HighPart = 0;
+
+ int fragmentSectorCount = 0x7f; // Maximum safe value supported by BIOS
+ int statCount = 0;
+
+ if (!CheckMemoryRequirements ())
+ goto err;
+
+ if (!GetSystemPartitions (drive))
+ goto err;
+
+ if (PartitionFollowingActive.Drive == TC_INVALID_BIOS_DRIVE)
+ TC_THROW_FATAL_EXCEPTION;
+
+ // Check if BIOS can read the last sector of the hidden system
+ AcquireSectorBuffer();
+
+ if (ReadSectors (SectorBuffer, PartitionFollowingActive.Drive, PartitionFollowingActive.EndSector - (TC_VOLUME_HEADER_GROUP_SIZE / TC_LB_SIZE - 2), 1) != BiosResultSuccess
+ || GetCrc32 (SectorBuffer, sizeof (SectorBuffer)) != OuterVolumeBackupHeaderCrc)
+ {
+ PrintErrorNoEndl ("Your BIOS does not support large drives");
+ Print (IsLbaSupported (PartitionFollowingActive.Drive) ? " due to a bug" : "\r\n- Enable LBA in BIOS");
+ PrintEndl();
+ Print (TC_BOOT_STR_UPGRADE_BIOS);
+
+ ReleaseSectorBuffer();
+ goto err;
+ }
+
+ ReleaseSectorBuffer();
+
+ if (!MountVolume (drive, exitKey, true, false))
+ return false;
+
+ sectorsRemaining = EncryptedVirtualPartition.SectorCount;
+
+ if (!(sectorsRemaining == ActivePartition.SectorCount))
+ TC_THROW_FATAL_EXCEPTION;
+
+ InitScreen();
+ Print ("\r\nCopying system to hidden volume. To abort, press Esc.\r\n\r\n");
+
+ while (sectorsRemaining.HighPart != 0 || sectorsRemaining.LowPart != 0)
+ {
+ if (EscKeyPressed())
+ {
+ Print ("\rIf aborted, copying will have to start from the beginning (if attempted again).\r\n");
+ if (AskYesNo ("Abort"))
+ break;
+ }
+
+ if (sectorsRemaining.HighPart == 0 && sectorsRemaining.LowPart < fragmentSectorCount)
+ fragmentSectorCount = (int) sectorsRemaining.LowPart;
+
+ if (ReadWriteSectors (false, TC_BOOT_LOADER_BUFFER_SEGMENT, 0, drive, ActivePartition.StartSector + sectorOffset, fragmentSectorCount, false) != BiosResultSuccess)
+ {
+ Print ("To fix bad sectors: 1) Terminate 2) Encrypt and decrypt sys partition 3) Retry\r\n");
+ crypto_close (BootCryptoInfo);
+ goto err;
+ }
+
+ AcquireSectorBuffer();
+
+ for (int i = 0; i < fragmentSectorCount; ++i)
+ {
+ CopyMemory (TC_BOOT_LOADER_BUFFER_SEGMENT, i * TC_LB_SIZE, SectorBuffer, TC_LB_SIZE);
+
+ uint64 s = PimValueOrHiddenVolumeStartUnitNo + sectorOffset + i;
+ EncryptDataUnits (SectorBuffer, &s, 1, BootCryptoInfo);
+
+ CopyMemory (SectorBuffer, TC_BOOT_LOADER_BUFFER_SEGMENT, i * TC_LB_SIZE, TC_LB_SIZE);
+ }
+
+ ReleaseSectorBuffer();
+
+ if (ReadWriteSectors (true, TC_BOOT_LOADER_BUFFER_SEGMENT, 0, drive, HiddenVolumeStartSector + sectorOffset, fragmentSectorCount, false) != BiosResultSuccess)
+ {
+ crypto_close (BootCryptoInfo);
+ goto err;
+ }
+
+ sectorsRemaining = sectorsRemaining - fragmentSectorCount;
+ sectorOffset = sectorOffset + fragmentSectorCount;
+
+ if (!(statCount++ & 0xf))
+ {
+ Print ("\rRemaining: ");
+ PrintSectorCountInMB (sectorsRemaining);
+ }
+ }
+
+ crypto_close (BootCryptoInfo);
+
+ if (sectorsRemaining.HighPart == 0 && sectorsRemaining.LowPart == 0)
+ {
+ status = true;
+ Print ("\rCopying completed.");
+ }
+
+ PrintEndl (2);
+ goto ret;
+
+err:
+ exitKey = TC_BIOS_KEY_ESC;
+ GetKeyboardChar();
+
+ret:
+ EraseMemory ((void *) TC_BOOT_LOADER_ARGS_OFFSET, sizeof (BootArguments));
+ return status;
+}
+
+
+#else // TC_WINDOWS_BOOT_RESCUE_DISK_MODE
+
+
+static void DecryptDrive (byte drive)
+{
+ byte exitKey;
+ if (!MountVolume (drive, exitKey, false, true))
+ return;
+
+ BootArguments *bootArguments = (BootArguments *) TC_BOOT_LOADER_ARGS_OFFSET;
+
+ bool headerUpdateRequired = false;
+ uint64 sectorsRemaining = EncryptedVirtualPartition.EndSector + 1 - EncryptedVirtualPartition.StartSector;
+ uint64 sector = EncryptedVirtualPartition.EndSector + 1;
+
+ int fragmentSectorCount = 0x7f; // Maximum safe value supported by BIOS
+ int statCount = 0;
+
+ bool skipBadSectors = false;
+
+ Print ("\r\nUse only if Windows cannot start. Decryption under Windows is much faster\r\n"
+ "(in VeraCrypt, select 'System' > 'Permanently Decrypt').\r\n\r\n");
+
+ if (!AskYesNo ("Decrypt now"))
+ {
+ crypto_close (BootCryptoInfo);
+ goto ret;
+ }
+
+ if (EncryptedVirtualPartition.Drive == TC_INVALID_BIOS_DRIVE)
+ {
+ // Drive already decrypted
+ sectorsRemaining.HighPart = 0;
+ sectorsRemaining.LowPart = 0;
+ }
+ else
+ {
+ Print ("\r\nTo safely interrupt and defer decryption, press Esc.\r\n"
+ "WARNING: You can turn off power only after you press Esc.\r\n\r\n");
+ }
+
+ while (sectorsRemaining.HighPart != 0 || sectorsRemaining.LowPart != 0)
+ {
+ if (EscKeyPressed())
+ break;
+
+ if (sectorsRemaining.HighPart == 0 && sectorsRemaining.LowPart < fragmentSectorCount)
+ fragmentSectorCount = (int) sectorsRemaining.LowPart;
+
+ sector = sector - fragmentSectorCount;
+
+ if (!(statCount++ & 0xf))
+ {
+ Print ("\rRemaining: ");
+ PrintSectorCountInMB (sectorsRemaining);
+ }
+
+ if (ReadWriteSectors (false, TC_BOOT_LOADER_BUFFER_SEGMENT, 0, drive, sector, fragmentSectorCount, skipBadSectors) == BiosResultSuccess)
+ {
+ AcquireSectorBuffer();
+
+ for (int i = 0; i < fragmentSectorCount; ++i)
+ {
+ CopyMemory (TC_BOOT_LOADER_BUFFER_SEGMENT, i * TC_LB_SIZE, SectorBuffer, TC_LB_SIZE);
+
+ uint64 s = sector + i;
+ DecryptDataUnits (SectorBuffer, &s, 1, BootCryptoInfo);
+
+ CopyMemory (SectorBuffer, TC_BOOT_LOADER_BUFFER_SEGMENT, i * TC_LB_SIZE, TC_LB_SIZE);
+ }
+
+ ReleaseSectorBuffer();
+
+ if (ReadWriteSectors (true, TC_BOOT_LOADER_BUFFER_SEGMENT, 0, drive, sector, fragmentSectorCount, skipBadSectors) != BiosResultSuccess && !skipBadSectors)
+ goto askBadSectorSkip;
+ }
+ else if (!skipBadSectors)
+ goto askBadSectorSkip;
+
+ sectorsRemaining = sectorsRemaining - fragmentSectorCount;
+ headerUpdateRequired = true;
+ continue;
+
+askBadSectorSkip:
+ if (!AskYesNo ("Skip all bad sectors"))
+ break;
+
+ skipBadSectors = true;
+ sector = sector + fragmentSectorCount;
+ fragmentSectorCount = 1;
+ }
+
+ crypto_close (BootCryptoInfo);
+
+ if (headerUpdateRequired)
+ {
+ Print ("\rUpdating header...");
+
+ AcquireSectorBuffer();
+ uint64 headerSector;
+ headerSector.HighPart = 0;
+ headerSector.LowPart = TC_BOOT_VOLUME_HEADER_SECTOR;
+
+ // Update encrypted area size in volume header
+
+ CRYPTO_INFO *headerCryptoInfo = crypto_open();
+ while (ReadSectors (SectorBuffer, drive, headerSector, 1) != BiosResultSuccess);
+
+ if (ReadVolumeHeader (TRUE, (char *) SectorBuffer, &bootArguments->BootPassword, (int) (bootArguments->Flags >> 16), NULL, headerCryptoInfo) == 0)
+ {
+ DecryptBuffer (SectorBuffer + HEADER_ENCRYPTED_DATA_OFFSET, HEADER_ENCRYPTED_DATA_SIZE, headerCryptoInfo);
+
+ uint64 encryptedAreaLength = sectorsRemaining << TC_LB_SIZE_BIT_SHIFT_DIVISOR;
+
+ for (int i = 7; i >= 0; --i)
+ {
+ SectorBuffer[TC_HEADER_OFFSET_ENCRYPTED_AREA_LENGTH + i] = (byte) encryptedAreaLength.LowPart;
+ encryptedAreaLength = encryptedAreaLength >> 8;
+ }
+
+ uint32 headerCrc32 = GetCrc32 (SectorBuffer + TC_HEADER_OFFSET_MAGIC, TC_HEADER_OFFSET_HEADER_CRC - TC_HEADER_OFFSET_MAGIC);
+
+ for (i = 3; i >= 0; --i)
+ {
+ SectorBuffer[TC_HEADER_OFFSET_HEADER_CRC + i] = (byte) headerCrc32;
+ headerCrc32 >>= 8;
+ }
+
+ EncryptBuffer (SectorBuffer + HEADER_ENCRYPTED_DATA_OFFSET, HEADER_ENCRYPTED_DATA_SIZE, headerCryptoInfo);
+ }
+
+ crypto_close (headerCryptoInfo);
+
+ while (WriteSectors (SectorBuffer, drive, headerSector, 1) != BiosResultSuccess);
+ ReleaseSectorBuffer();
+
+ Print ("Done!\r\n");
+ }
+
+ if (sectorsRemaining.HighPart == 0 && sectorsRemaining.LowPart == 0)
+ Print ("\rDrive decrypted.\r\n");
+ else
+ Print ("\r\nDecryption deferred.\r\n");
+
+ GetKeyboardChar();
+ret:
+ EraseMemory (bootArguments, sizeof (*bootArguments));
+}
+
+
+static void RepairMenu ()
+{
+ DriveGeometry bootLoaderDriveGeometry;
+
+ if (GetDriveGeometry (BootLoaderDrive, bootLoaderDriveGeometry, true) != BiosResultSuccess)
+ {
+ // Some BIOSes may fail to get the geometry of an emulated floppy drive
+ bootLoaderDriveGeometry.Cylinders = 80;
+ bootLoaderDriveGeometry.Heads = 2;
+ bootLoaderDriveGeometry.Sectors = 18;
+ }
+
+ while (true)
+ {
+ InitScreen();
+ Print ("Available "); Print ("Repair Options"); Print (":\r\n");
+ PrintRepeatedChar ('\xC4', 25);
+ PrintEndl();
+
+ enum
+ {
+ RestoreNone = 0,
+ DecryptVolume,
+ RestoreTrueCryptLoader,
+ RestoreVolumeHeader,
+ RestoreOriginalSystemLoader
+ };
+
+ static const char *options[] = { "Permanently decrypt system partition/drive", "Restore VeraCrypt Boot Loader", "Restore key data (volume header)", "Restore original system loader" };
+
+ int selection = AskSelection (options,
+ (BootSectorFlags & TC_BOOT_CFG_FLAG_RESCUE_DISK_ORIG_SYS_LOADER) ? array_capacity (options) : array_capacity (options) - 1);
+
+ PrintEndl();
+
+ switch (selection)
+ {
+ case RestoreNone:
+ return;
+
+ case DecryptVolume:
+ DecryptDrive (BootDrive);
+ continue;
+
+ case RestoreOriginalSystemLoader:
+ if (!AskYesNo ("Is the system partition/drive decrypted"))
+ {
+ Print ("Please decrypt it first.\r\n");
+ GetKeyboardChar();
+ continue;
+ }
+ break;
+ }
+
+ bool writeConfirmed = false;
+ BiosResult result;
+
+ uint64 sector;
+ sector.HighPart = 0;
+ ChsAddress chs;
+
+ byte mbrPartTable[TC_LB_SIZE - TC_MAX_MBR_BOOT_CODE_SIZE];
+ AcquireSectorBuffer();
+
+ for (int i = (selection == RestoreVolumeHeader ? TC_BOOT_VOLUME_HEADER_SECTOR : TC_MBR_SECTOR);
+ i < TC_BOOT_LOADER_AREA_SECTOR_COUNT; ++i)
+ {
+ sector.LowPart = i;
+
+ if (selection == RestoreOriginalSystemLoader)
+ sector.LowPart += TC_ORIG_BOOT_LOADER_BACKUP_SECTOR;
+ else if (selection == RestoreTrueCryptLoader)
+ sector.LowPart += TC_BOOT_LOADER_BACKUP_RESCUE_DISK_SECTOR;
+
+ // The backup medium may be a floppy-emulated bootable CD. The emulation may fail if LBA addressing is used.
+ // Therefore, only CHS addressing can be used.
+ LbaToChs (bootLoaderDriveGeometry, sector, chs);
+ sector.LowPart = i;
+
+ if (i == TC_MBR_SECTOR)
+ {
+ // Read current partition table
+ result = ReadSectors (SectorBuffer, TC_FIRST_BIOS_DRIVE, sector, 1);
+ if (result != BiosResultSuccess)
+ goto err;
+
+ memcpy (mbrPartTable, SectorBuffer + TC_MAX_MBR_BOOT_CODE_SIZE, sizeof (mbrPartTable));
+ }
+
+ result = ReadSectors (SectorBuffer, BootLoaderDrive, chs, 1);
+ if (result != BiosResultSuccess)
+ goto err;
+
+ if (i == TC_MBR_SECTOR)
+ {
+ // Preserve current partition table
+ memcpy (SectorBuffer + TC_MAX_MBR_BOOT_CODE_SIZE, mbrPartTable, sizeof (mbrPartTable));
+ }
+
+ // Volume header
+ if (i == TC_BOOT_VOLUME_HEADER_SECTOR)
+ {
+ if (selection == RestoreTrueCryptLoader)
+ continue;
+
+ if (selection == RestoreVolumeHeader)
+ {
+ while (true)
+ {
+ bool validHeaderPresent = false;
+ uint32 masterKeyScheduleCrc;
+
+ Password password;
+ int pim;
+ byte exitKey = AskPassword (password, pim);
+
+ if (exitKey != TC_BIOS_KEY_ENTER)
+ goto abort;
+
+ CRYPTO_INFO *cryptoInfo;
+
+ CopyMemory (SectorBuffer, TC_BOOT_LOADER_BUFFER_SEGMENT, 0, TC_LB_SIZE);
+ ReleaseSectorBuffer();
+
+ // Restore volume header only if the current one cannot be used
+ if (OpenVolume (TC_FIRST_BIOS_DRIVE, password, pim, &cryptoInfo, nullptr, false, true))
+ {
+ validHeaderPresent = true;
+ masterKeyScheduleCrc = GetCrc32 (cryptoInfo->ks, sizeof (cryptoInfo->ks));
+ crypto_close (cryptoInfo);
+ }
+
+ AcquireSectorBuffer();
+ CopyMemory (TC_BOOT_LOADER_BUFFER_SEGMENT, 0, SectorBuffer, TC_LB_SIZE);
+
+ if (ReadVolumeHeader (TRUE, (char *) SectorBuffer, &password, pim, &cryptoInfo, nullptr) == 0)
+ {
+ if (validHeaderPresent)
+ {
+ if (masterKeyScheduleCrc == GetCrc32 (cryptoInfo->ks, sizeof (cryptoInfo->ks)))
+ {
+ Print ("Original header preserved.\r\n");
+ goto err;
+ }
+
+ Print ("WARNING: Drive 0 contains a valid header!\r\n");
+ }
+
+ crypto_close (cryptoInfo);
+ break;
+ }
+
+ Print ("Incorrect password.\r\n\r\n");
+ }
+ }
+ }
+
+ if (!writeConfirmed && !AskYesNo ("Modify drive 0"))
+ goto abort;
+ writeConfirmed = true;
+
+ if (WriteSectors (SectorBuffer, TC_FIRST_BIOS_DRIVE, sector, 1) != BiosResultSuccess)
+ goto err;
+ }
+done:
+ switch (selection)
+ {
+ case RestoreTrueCryptLoader:
+ Print ("VeraCrypt Boot Loader");
+ break;
+
+ case RestoreVolumeHeader:
+ Print ("Header");
+ break;
+
+ case RestoreOriginalSystemLoader:
+ Print ("System loader");
+ break;
+ }
+ Print (" restored.\r\n");
+
+err: GetKeyboardChar();
+abort: ReleaseSectorBuffer();
+ }
+}
+
+#endif // TC_WINDOWS_BOOT_RESCUE_DISK_MODE
+
+
+#ifndef DEBUG
+extern "C" void _acrtused () { } // Required by linker
+#endif
+
+
+void main ()
+{
+ __asm mov BootLoaderDrive, dl
+ __asm mov BootSectorFlags, dh
+
+#ifdef TC_BOOT_TRACING_ENABLED
+ InitDebugPort();
+#endif
+
+#ifdef TC_BOOT_STACK_CHECKING_ENABLED
+ InitStackChecker();
+#endif
+
+#ifndef TC_WINDOWS_BOOT_RESCUE_DISK_MODE
+ ReadBootSectorUserConfiguration();
+#elif defined (TC_WINDOWS_BOOT_AES)
+ EnableHwEncryption (!(BootSectorFlags & TC_BOOT_CFG_FLAG_RESCUE_DISABLE_HW_ENCRYPTION));
+#endif
+
+ InitVideoMode();
+ InitScreen();
+
+ // Determine boot drive
+ BootDrive = BootLoaderDrive;
+ if (BootDrive < TC_FIRST_BIOS_DRIVE)
+ BootDrive = TC_FIRST_BIOS_DRIVE;
+
+ // Query boot drive geometry
+ if (GetDriveGeometry (BootDrive, BootDriveGeometry) != BiosResultSuccess)
+ {
+ BootDrive = TC_FIRST_BIOS_DRIVE;
+ if (GetDriveGeometry (BootDrive, BootDriveGeometry) != BiosResultSuccess)
+ {
+#ifdef TC_WINDOWS_BOOT_RESCUE_DISK_MODE
+ Print ("- Connect system drive to (SATA) port 1\r\n");
+#endif
+ GetKeyboardChar();
+ }
+ else
+ BootDriveGeometryValid = true;
+ }
+ else
+ BootDriveGeometryValid = true;
+
+#ifdef TC_WINDOWS_BOOT_RESCUE_DISK_MODE
+
+ // Check whether the user is not using the Rescue Disk to create a hidden system
+
+ if (ReadWriteMBR (false, BootDrive, true) == BiosResultSuccess
+ && *(uint32 *) (SectorBuffer + 6) == 0x61726556
+ && *(uint32 *) (SectorBuffer + 10) == 0x70797243
+ && (SectorBuffer[TC_BOOT_SECTOR_CONFIG_OFFSET] & TC_BOOT_CFG_MASK_HIDDEN_OS_CREATION_PHASE) != TC_HIDDEN_OS_CREATION_PHASE_NONE)
+ {
+ PrintError ("It appears you are creating a hidden OS.");
+ if (AskYesNo ("Is this correct"))
+ {
+ Print ("Please remove the Rescue Disk from the drive and restart.");
+ while (true);
+ }
+ }
+
+#endif // TC_WINDOWS_BOOT_RESCUE_DISK_MODE
+
+
+ // Main menu
+
+ while (true)
+ {
+ byte exitKey;
+ InitScreen();
+
+#ifndef TC_WINDOWS_BOOT_RESCUE_DISK_MODE
+
+ // Hidden system setup
+ byte hiddenSystemCreationPhase = BootSectorFlags & TC_BOOT_CFG_MASK_HIDDEN_OS_CREATION_PHASE;
+
+ if (hiddenSystemCreationPhase != TC_HIDDEN_OS_CREATION_PHASE_NONE)
+ {
+ PreventNormalSystemBoot = true;
+ PrintMainMenu();
+
+ if (hiddenSystemCreationPhase == TC_HIDDEN_OS_CREATION_PHASE_CLONING)
+ {
+ if (CopySystemPartitionToHiddenVolume (BootDrive, exitKey))
+ {
+ BootSectorFlags = (BootSectorFlags & ~TC_BOOT_CFG_MASK_HIDDEN_OS_CREATION_PHASE) | TC_HIDDEN_OS_CREATION_PHASE_WIPING;
+ UpdateBootSectorConfiguration (BootLoaderDrive);
+ }
+ else if (exitKey == TC_BIOS_KEY_ESC)
+ goto bootMenu;
+ else
+ continue;
+ }
+ }
+ else
+ PrintMainMenu();
+
+ exitKey = BootEncryptedDrive();
+
+#else // TC_WINDOWS_BOOT_RESCUE_DISK_MODE
+
+ PrintMainMenu();
+ exitKey = BootEncryptedDrive();
+
+ if (exitKey == TC_MENU_KEY_REPAIR)
+ {
+ RepairMenu();
+ continue;
+ }
+
+#endif // TC_WINDOWS_BOOT_RESCUE_DISK_MODE
+
+bootMenu:
+ if (!PreventBootMenu)
+ BootMenu();
+ }
+}
diff --git a/src/Boot/Windows/BootMain.h b/src/Boot/Windows/BootMain.h
index b6e75fa6..0f89179a 100644
--- a/src/Boot/Windows/BootMain.h
+++ b/src/Boot/Windows/BootMain.h
@@ -1,34 +1,34 @@
-/*
- Derived from source code of TrueCrypt 7.1a, which is
- Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed
- by the TrueCrypt License 3.0.
-
- Modifications and additions to the original source code (contained in this file)
- and all other portions of this file are Copyright (c) 2013-2016 IDRIX
- and are governed by the Apache License 2.0 the full text of which is
- contained in the file License.txt included in VeraCrypt binary and source
- code distribution packages.
-*/
-
-#ifndef TC_HEADER_Boot_BootMain
-#define TC_HEADER_Boot_BootMain
-
-#include "TCdefs.h"
-#include "Platform.h"
-
-static byte AskPassword (Password &password, int& pim);
-static int AskSelection (const char *options[], size_t optionCount);
-static bool AskYesNo (const char *message);
-static byte BootEncryptedDrive ();
-static void BootMenu ();
-static void ExecuteBootSector (byte drive, byte *sectorBuffer);
-static void InitScreen ();
-static bool IsMenuKey (byte scanCode);
-static bool MountVolume (byte drive, byte &exitKey);
-static bool OpenVolume (byte drive, Password &password, CRYPTO_INFO **cryptoInfo, uint32 *headerSaltCrc32 = nullptr, bool skipNormal = false, bool skipHidden = false);
-static void PrintMainMenu ();
-static void RepairMenu ();
-
-#define TC_MENU_KEY_REPAIR TC_BIOS_KEY_F8
-
-#endif // TC_HEADER_Boot_BootMain
+/*
+ Derived from source code of TrueCrypt 7.1a, which is
+ Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed
+ by the TrueCrypt License 3.0.
+
+ Modifications and additions to the original source code (contained in this file)
+ and all other portions of this file are Copyright (c) 2013-2016 IDRIX
+ and are governed by the Apache License 2.0 the full text of which is
+ contained in the file License.txt included in VeraCrypt binary and source
+ code distribution packages.
+*/
+
+#ifndef TC_HEADER_Boot_BootMain
+#define TC_HEADER_Boot_BootMain
+
+#include "TCdefs.h"
+#include "Platform.h"
+
+static byte AskPassword (Password &password, int& pim);
+static int AskSelection (const char *options[], size_t optionCount);
+static bool AskYesNo (const char *message);
+static byte BootEncryptedDrive ();
+static void BootMenu ();
+static void ExecuteBootSector (byte drive, byte *sectorBuffer);
+static void InitScreen ();
+static bool IsMenuKey (byte scanCode);
+static bool MountVolume (byte drive, byte &exitKey);
+static bool OpenVolume (byte drive, Password &password, CRYPTO_INFO **cryptoInfo, uint32 *headerSaltCrc32 = nullptr, bool skipNormal = false, bool skipHidden = false);
+static void PrintMainMenu ();
+static void RepairMenu ();
+
+#define TC_MENU_KEY_REPAIR TC_BIOS_KEY_F8
+
+#endif // TC_HEADER_Boot_BootMain
diff --git a/src/Boot/Windows/BootMemory.cpp b/src/Boot/Windows/BootMemory.cpp
index c1dd3833..5729142f 100644
--- a/src/Boot/Windows/BootMemory.cpp
+++ b/src/Boot/Windows/BootMemory.cpp
@@ -1,86 +1,86 @@
-/*
- Derived from source code of TrueCrypt 7.1a, which is
- Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed
- by the TrueCrypt License 3.0.
-
- Modifications and additions to the original source code (contained in this file)
- and all other portions of this file are Copyright (c) 2013-2016 IDRIX
- and are governed by the Apache License 2.0 the full text of which is
- contained in the file License.txt included in VeraCrypt binary and source
- code distribution packages.
-*/
-
-#include "BootDefs.h"
-#include "BootMemory.h"
-
-static uint32 MemoryMapContValue;
-
-static bool GetMemoryMapEntry (BiosMemoryMapEntry &entry)
-{
- static const uint32 function = 0x0000E820UL;
- static const uint32 magic = 0x534D4150UL;
- static const uint32 bufferSize = sizeof (BiosMemoryMapEntry);
-
- bool carry = false;
- uint32 resultMagic;
- uint32 resultSize;
-
- __asm
- {
- push es
-
- lea di, function
- TC_ASM_MOV_EAX_DI
- lea di, MemoryMapContValue
- TC_ASM_MOV_EBX_DI
- lea di, bufferSize
- TC_ASM_MOV_ECX_DI
- lea di, magic
- TC_ASM_MOV_EDX_DI
- lea di, MemoryMapContValue
- TC_ASM_MOV_DI_ECX
-
- // Use alternative segment to prevent memory corruption caused by buggy BIOSes
- push TC_BOOT_LOADER_ALT_SEGMENT
- pop es
- mov di, 0
-
- int 0x15
- jnc no_carry
- mov carry, true
- no_carry:
-
- lea di, resultMagic
- TC_ASM_MOV_DI_EAX
- lea di, MemoryMapContValue
- TC_ASM_MOV_DI_EBX
- lea di, resultSize
- TC_ASM_MOV_DI_ECX
-
- pop es
- }
-
- CopyMemory (TC_BOOT_LOADER_ALT_SEGMENT, 0, &entry, sizeof (entry));
-
- // BIOS may set CF at the end of the list
- if (carry)
- MemoryMapContValue = 0;
-
- return resultMagic == magic && resultSize == bufferSize;
-}
-
-
-bool GetFirstBiosMemoryMapEntry (BiosMemoryMapEntry &entry)
-{
- MemoryMapContValue = 0;
- return GetMemoryMapEntry (entry);
-}
-
-
-bool GetNextBiosMemoryMapEntry (BiosMemoryMapEntry &entry)
-{
- if (MemoryMapContValue == 0)
- return false;
-
- return GetMemoryMapEntry (entry);
-}
+/*
+ Derived from source code of TrueCrypt 7.1a, which is
+ Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed
+ by the TrueCrypt License 3.0.
+
+ Modifications and additions to the original source code (contained in this file)
+ and all other portions of this file are Copyright (c) 2013-2016 IDRIX
+ and are governed by the Apache License 2.0 the full text of which is
+ contained in the file License.txt included in VeraCrypt binary and source
+ code distribution packages.
+*/
+
+#include "BootDefs.h"
+#include "BootMemory.h"
+
+static uint32 MemoryMapContValue;
+
+static bool GetMemoryMapEntry (BiosMemoryMapEntry &entry)
+{
+ static const uint32 function = 0x0000E820UL;
+ static const uint32 magic = 0x534D4150UL;
+ static const uint32 bufferSize = sizeof (BiosMemoryMapEntry);
+
+ bool carry = false;
+ uint32 resultMagic;
+ uint32 resultSize;
+
+ __asm
+ {
+ push es
+
+ lea di, function
+ TC_ASM_MOV_EAX_DI
+ lea di, MemoryMapContValue
+ TC_ASM_MOV_EBX_DI
+ lea di, bufferSize
+ TC_ASM_MOV_ECX_DI
+ lea di, magic
+ TC_ASM_MOV_EDX_DI
+ lea di, MemoryMapContValue
+ TC_ASM_MOV_DI_ECX
+
+ // Use alternative segment to prevent memory corruption caused by buggy BIOSes
+ push TC_BOOT_LOADER_ALT_SEGMENT
+ pop es
+ mov di, 0
+
+ int 0x15
+ jnc no_carry
+ mov carry, true
+ no_carry:
+
+ lea di, resultMagic
+ TC_ASM_MOV_DI_EAX
+ lea di, MemoryMapContValue
+ TC_ASM_MOV_DI_EBX
+ lea di, resultSize
+ TC_ASM_MOV_DI_ECX
+
+ pop es
+ }
+
+ CopyMemory (TC_BOOT_LOADER_ALT_SEGMENT, 0, &entry, sizeof (entry));
+
+ // BIOS may set CF at the end of the list
+ if (carry)
+ MemoryMapContValue = 0;
+
+ return resultMagic == magic && resultSize == bufferSize;
+}
+
+
+bool GetFirstBiosMemoryMapEntry (BiosMemoryMapEntry &entry)
+{
+ MemoryMapContValue = 0;
+ return GetMemoryMapEntry (entry);
+}
+
+
+bool GetNextBiosMemoryMapEntry (BiosMemoryMapEntry &entry)
+{
+ if (MemoryMapContValue == 0)
+ return false;
+
+ return GetMemoryMapEntry (entry);
+}
diff --git a/src/Boot/Windows/BootMemory.h b/src/Boot/Windows/BootMemory.h
index 0ed0470d..d08e88ac 100644
--- a/src/Boot/Windows/BootMemory.h
+++ b/src/Boot/Windows/BootMemory.h
@@ -1,28 +1,28 @@
-/*
- Derived from source code of TrueCrypt 7.1a, which is
- Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed
- by the TrueCrypt License 3.0.
-
- Modifications and additions to the original source code (contained in this file)
- and all other portions of this file are Copyright (c) 2013-2016 IDRIX
- and are governed by the Apache License 2.0 the full text of which is
- contained in the file License.txt included in VeraCrypt binary and source
- code distribution packages.
-*/
-
-#include "Platform.h"
-#include "Bios.h"
-
-#pragma pack(1)
-
-struct BiosMemoryMapEntry
-{
- uint64 BaseAddress;
- uint64 Length;
- uint32 Type;
-};
-
-#pragma pack()
-
-bool GetFirstBiosMemoryMapEntry (BiosMemoryMapEntry &entry);
-bool GetNextBiosMemoryMapEntry (BiosMemoryMapEntry &entry);
+/*
+ Derived from source code of TrueCrypt 7.1a, which is
+ Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed
+ by the TrueCrypt License 3.0.
+
+ Modifications and additions to the original source code (contained in this file)
+ and all other portions of this file are Copyright (c) 2013-2016 IDRIX
+ and are governed by the Apache License 2.0 the full text of which is
+ contained in the file License.txt included in VeraCrypt binary and source
+ code distribution packages.
+*/
+
+#include "Platform.h"
+#include "Bios.h"
+
+#pragma pack(1)
+
+struct BiosMemoryMapEntry
+{
+ uint64 BaseAddress;
+ uint64 Length;
+ uint32 Type;
+};
+
+#pragma pack()
+
+bool GetFirstBiosMemoryMapEntry (BiosMemoryMapEntry &entry);
+bool GetNextBiosMemoryMapEntry (BiosMemoryMapEntry &entry);
diff --git a/src/Boot/Windows/BootSector.asm b/src/Boot/Windows/BootSector.asm
index e0049d29..833ff616 100644
--- a/src/Boot/Windows/BootSector.asm
+++ b/src/Boot/Windows/BootSector.asm
@@ -1,244 +1,244 @@
-;
-; Derived from source code of TrueCrypt 7.1a, which is
-; Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed
-; by the TrueCrypt License 3.0.
-;
-; Modifications and additions to the original source code (contained in this file)
-; and all other portions of this file are Copyright (c) 2013-2016 IDRIX
-; and are governed by the Apache License 2.0 the full text of which is
-; contained in the file License.txt included in VeraCrypt binary and source
-; code distribution packages.
-;
-
-.MODEL tiny
-.386
-_TEXT SEGMENT USE16
-
-INCLUDE BootDefs.i
-
-ORG 7C00h ; Standard boot sector offset
-
-start:
- ; BIOS executes boot sector from 0:7C00 or 7C0:0000 (default CD boot loader address).
- ; Far jump to the next instruction sets IP to the standard offset 7C00.
- db 0EAh ; jmp 0:main
- dw main, 0
-
-loader_name_msg:
- db ' VeraCrypt Boot Loader', 13, 10, 0
-
-main:
- cli
- xor ax, ax
- mov ds, ax
- mov ss, ax
- mov sp, 7C00h
- sti
-
- ; Display boot loader name
- test byte ptr [start + TC_BOOT_SECTOR_USER_CONFIG_OFFSET], TC_BOOT_USER_CFG_FLAG_SILENT_MODE
- jnz skip_loader_name_msg
-
- lea si, loader_name_msg
- call print
-skip_loader_name_msg:
-
- ; Determine boot loader segment
- mov ax, TC_BOOT_LOADER_SEGMENT
-
- ; Check available memory
- cmp word ptr [ds:413h], TC_BOOT_LOADER_SEGMENT / 1024 * 16 + TC_BOOT_MEMORY_REQUIRED
- jge memory_ok
-
- mov ax, TC_BOOT_LOADER_SEGMENT_LOW
-
- cmp word ptr [ds:413h], TC_BOOT_LOADER_SEGMENT_LOW / 1024 * 16 + TC_BOOT_MEMORY_REQUIRED
- jge memory_ok
-
- ; Insufficient memory
- mov ax, TC_BOOT_LOADER_LOWMEM_SEGMENT
-
-memory_ok:
- mov es, ax
-
- ; Clear BSS section
- xor al, al
- mov di, TC_COM_EXECUTABLE_OFFSET
- mov cx, TC_BOOT_MEMORY_REQUIRED * 1024 - TC_COM_EXECUTABLE_OFFSET - 1
- cld
- rep stosb
-
- mov ax, es
- sub ax, TC_BOOT_LOADER_DECOMPRESSOR_MEMORY_SIZE / 16 ; Decompressor segment
- mov es, ax
-
- ; Load decompressor
- mov cl, TC_BOOT_LOADER_DECOMPRESSOR_START_SECTOR
-retry_backup:
- mov al, TC_BOOT_LOADER_DECOMPRESSOR_SECTOR_COUNT
- mov bx, TC_COM_EXECUTABLE_OFFSET
- call read_sectors
-
- ; Decompressor checksum
- xor ebx, ebx
- mov si, TC_COM_EXECUTABLE_OFFSET
- mov cx, TC_BOOT_LOADER_DECOMPRESSOR_SECTOR_COUNT * TC_LB_SIZE
- call checksum
- push ebx
-
- ; Load compressed boot loader
- mov bx, TC_BOOT_LOADER_COMPRESSED_BUFFER_OFFSET
- mov cl, TC_BOOT_LOADER_START_SECTOR
- mov al, TC_MAX_BOOT_LOADER_SECTOR_COUNT
-
- test backup_loader_used, 1
- jz non_backup
- mov al, TC_BOOT_LOADER_BACKUP_SECTOR_COUNT - TC_BOOT_LOADER_DECOMPRESSOR_SECTOR_COUNT
- mov cl, TC_BOOT_LOADER_START_SECTOR + TC_BOOT_LOADER_BACKUP_SECTOR_COUNT
-
-non_backup:
- call read_sectors
-
- ; Boot loader checksum
- pop ebx
- mov si, TC_BOOT_LOADER_COMPRESSED_BUFFER_OFFSET
- mov cx, word ptr [start + TC_BOOT_SECTOR_LOADER_LENGTH_OFFSET]
- call checksum
-
- ; Verify checksum
- cmp ebx, dword ptr [start + TC_BOOT_SECTOR_LOADER_CHECKSUM_OFFSET]
- je checksum_ok
-
- ; Checksum incorrect - try using backup if available
- test backup_loader_used, 1
- jnz loader_damaged
-
- mov backup_loader_used, 1
- mov cl, TC_BOOT_LOADER_DECOMPRESSOR_START_SECTOR + TC_BOOT_LOADER_BACKUP_SECTOR_COUNT
-
- test TC_BOOT_CFG_FLAG_BACKUP_LOADER_AVAILABLE, byte ptr [start + TC_BOOT_SECTOR_CONFIG_OFFSET]
- jnz retry_backup
-
-loader_damaged:
- lea si, loader_damaged_msg
- call print
- lea si, loader_name_msg
- call print
- jmp $
-checksum_ok:
-
- ; Set up decompressor segment
- mov ax, es
- mov ds, ax
- cli
- mov ss, ax
- mov sp, TC_BOOT_LOADER_DECOMPRESSOR_MEMORY_SIZE
- sti
-
- push dx
-
- ; Decompress boot loader
- mov cx, word ptr [start + TC_BOOT_SECTOR_LOADER_LENGTH_OFFSET]
- sub cx, TC_GZIP_HEADER_SIZE
- push cx ; Compressed data size
- push TC_BOOT_LOADER_COMPRESSED_BUFFER_OFFSET + TC_GZIP_HEADER_SIZE ; Compressed data
- push TC_MAX_BOOT_LOADER_DECOMPRESSED_SIZE ; Output buffer size
- push TC_BOOT_LOADER_DECOMPRESSOR_MEMORY_SIZE + TC_COM_EXECUTABLE_OFFSET ; Output buffer
-
- push cs
- push decompressor_ret
- push es
- push TC_COM_EXECUTABLE_OFFSET
- retf
-decompressor_ret:
-
- add sp, 8
- pop dx
-
- ; Restore boot sector segment
- push cs
- pop ds
-
- ; Check decompression result
- test ax, ax
- jz decompression_ok
-
- lea si, loader_damaged_msg
- call print
- jmp $
-decompression_ok:
-
- ; DH = boot sector flags
- mov dh, byte ptr [start + TC_BOOT_SECTOR_CONFIG_OFFSET]
-
- ; Set up boot loader segment
- mov ax, es
- add ax, TC_BOOT_LOADER_DECOMPRESSOR_MEMORY_SIZE / 16
- mov es, ax
- mov ds, ax
- cli
- mov ss, ax
- mov sp, TC_BOOT_LOADER_STACK_TOP
- sti
-
- ; Execute boot loader
- push es
- push TC_COM_EXECUTABLE_OFFSET
- retf
-
- ; Print string
-print:
- xor bx, bx
- mov ah, 0eh
- cld
-
-@@: lodsb
- test al, al
- jz print_end
-
- int 10h
- jmp @B
-
-print_end:
- ret
-
- ; Read sectors of the first cylinder
-read_sectors:
- mov ch, 0 ; Cylinder
- mov dh, 0 ; Head
- ; DL = drive number passed from BIOS
- mov ah, 2
- int 13h
- jnc read_ok
-
- lea si, disk_error_msg
- call print
-read_ok:
- ret
-
- ; Calculate checksum
-checksum:
- push ds
- push es
- pop ds
- xor eax, eax
- cld
-
-@@: lodsb
- add ebx, eax
- rol ebx, 1
- loop @B
-
- pop ds
- ret
-
-backup_loader_used db 0
-
-disk_error_msg db 'Disk error', 13, 10, 7, 0
-loader_damaged_msg db 7, 'Loader damaged! Repair with Rescue Disk', 0
-
-ORG 7C00h + 510
- dw 0AA55h ; Boot sector signature
-
-_TEXT ENDS
-END start
+;
+; Derived from source code of TrueCrypt 7.1a, which is
+; Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed
+; by the TrueCrypt License 3.0.
+;
+; Modifications and additions to the original source code (contained in this file)
+; and all other portions of this file are Copyright (c) 2013-2016 IDRIX
+; and are governed by the Apache License 2.0 the full text of which is
+; contained in the file License.txt included in VeraCrypt binary and source
+; code distribution packages.
+;
+
+.MODEL tiny
+.386
+_TEXT SEGMENT USE16
+
+INCLUDE BootDefs.i
+
+ORG 7C00h ; Standard boot sector offset
+
+start:
+ ; BIOS executes boot sector from 0:7C00 or 7C0:0000 (default CD boot loader address).
+ ; Far jump to the next instruction sets IP to the standard offset 7C00.
+ db 0EAh ; jmp 0:main
+ dw main, 0
+
+loader_name_msg:
+ db ' VeraCrypt Boot Loader', 13, 10, 0
+
+main:
+ cli
+ xor ax, ax
+ mov ds, ax
+ mov ss, ax
+ mov sp, 7C00h
+ sti
+
+ ; Display boot loader name
+ test byte ptr [start + TC_BOOT_SECTOR_USER_CONFIG_OFFSET], TC_BOOT_USER_CFG_FLAG_SILENT_MODE
+ jnz skip_loader_name_msg
+
+ lea si, loader_name_msg
+ call print
+skip_loader_name_msg:
+
+ ; Determine boot loader segment
+ mov ax, TC_BOOT_LOADER_SEGMENT
+
+ ; Check available memory
+ cmp word ptr [ds:413h], TC_BOOT_LOADER_SEGMENT / 1024 * 16 + TC_BOOT_MEMORY_REQUIRED
+ jge memory_ok
+
+ mov ax, TC_BOOT_LOADER_SEGMENT_LOW
+
+ cmp word ptr [ds:413h], TC_BOOT_LOADER_SEGMENT_LOW / 1024 * 16 + TC_BOOT_MEMORY_REQUIRED
+ jge memory_ok
+
+ ; Insufficient memory
+ mov ax, TC_BOOT_LOADER_LOWMEM_SEGMENT
+
+memory_ok:
+ mov es, ax
+
+ ; Clear BSS section
+ xor al, al
+ mov di, TC_COM_EXECUTABLE_OFFSET
+ mov cx, TC_BOOT_MEMORY_REQUIRED * 1024 - TC_COM_EXECUTABLE_OFFSET - 1
+ cld
+ rep stosb
+
+ mov ax, es
+ sub ax, TC_BOOT_LOADER_DECOMPRESSOR_MEMORY_SIZE / 16 ; Decompressor segment
+ mov es, ax
+
+ ; Load decompressor
+ mov cl, TC_BOOT_LOADER_DECOMPRESSOR_START_SECTOR
+retry_backup:
+ mov al, TC_BOOT_LOADER_DECOMPRESSOR_SECTOR_COUNT
+ mov bx, TC_COM_EXECUTABLE_OFFSET
+ call read_sectors
+
+ ; Decompressor checksum
+ xor ebx, ebx
+ mov si, TC_COM_EXECUTABLE_OFFSET
+ mov cx, TC_BOOT_LOADER_DECOMPRESSOR_SECTOR_COUNT * TC_LB_SIZE
+ call checksum
+ push ebx
+
+ ; Load compressed boot loader
+ mov bx, TC_BOOT_LOADER_COMPRESSED_BUFFER_OFFSET
+ mov cl, TC_BOOT_LOADER_START_SECTOR
+ mov al, TC_MAX_BOOT_LOADER_SECTOR_COUNT
+
+ test backup_loader_used, 1
+ jz non_backup
+ mov al, TC_BOOT_LOADER_BACKUP_SECTOR_COUNT - TC_BOOT_LOADER_DECOMPRESSOR_SECTOR_COUNT
+ mov cl, TC_BOOT_LOADER_START_SECTOR + TC_BOOT_LOADER_BACKUP_SECTOR_COUNT
+
+non_backup:
+ call read_sectors
+
+ ; Boot loader checksum
+ pop ebx
+ mov si, TC_BOOT_LOADER_COMPRESSED_BUFFER_OFFSET
+ mov cx, word ptr [start + TC_BOOT_SECTOR_LOADER_LENGTH_OFFSET]
+ call checksum
+
+ ; Verify checksum
+ cmp ebx, dword ptr [start + TC_BOOT_SECTOR_LOADER_CHECKSUM_OFFSET]
+ je checksum_ok
+
+ ; Checksum incorrect - try using backup if available
+ test backup_loader_used, 1
+ jnz loader_damaged
+
+ mov backup_loader_used, 1
+ mov cl, TC_BOOT_LOADER_DECOMPRESSOR_START_SECTOR + TC_BOOT_LOADER_BACKUP_SECTOR_COUNT
+
+ test TC_BOOT_CFG_FLAG_BACKUP_LOADER_AVAILABLE, byte ptr [start + TC_BOOT_SECTOR_CONFIG_OFFSET]
+ jnz retry_backup
+
+loader_damaged:
+ lea si, loader_damaged_msg
+ call print
+ lea si, loader_name_msg
+ call print
+ jmp $
+checksum_ok:
+
+ ; Set up decompressor segment
+ mov ax, es
+ mov ds, ax
+ cli
+ mov ss, ax
+ mov sp, TC_BOOT_LOADER_DECOMPRESSOR_MEMORY_SIZE
+ sti
+
+ push dx
+
+ ; Decompress boot loader
+ mov cx, word ptr [start + TC_BOOT_SECTOR_LOADER_LENGTH_OFFSET]
+ sub cx, TC_GZIP_HEADER_SIZE
+ push cx ; Compressed data size
+ push TC_BOOT_LOADER_COMPRESSED_BUFFER_OFFSET + TC_GZIP_HEADER_SIZE ; Compressed data
+ push TC_MAX_BOOT_LOADER_DECOMPRESSED_SIZE ; Output buffer size
+ push TC_BOOT_LOADER_DECOMPRESSOR_MEMORY_SIZE + TC_COM_EXECUTABLE_OFFSET ; Output buffer
+
+ push cs
+ push decompressor_ret
+ push es
+ push TC_COM_EXECUTABLE_OFFSET
+ retf
+decompressor_ret:
+
+ add sp, 8
+ pop dx
+
+ ; Restore boot sector segment
+ push cs
+ pop ds
+
+ ; Check decompression result
+ test ax, ax
+ jz decompression_ok
+
+ lea si, loader_damaged_msg
+ call print
+ jmp $
+decompression_ok:
+
+ ; DH = boot sector flags
+ mov dh, byte ptr [start + TC_BOOT_SECTOR_CONFIG_OFFSET]
+
+ ; Set up boot loader segment
+ mov ax, es
+ add ax, TC_BOOT_LOADER_DECOMPRESSOR_MEMORY_SIZE / 16
+ mov es, ax
+ mov ds, ax
+ cli
+ mov ss, ax
+ mov sp, TC_BOOT_LOADER_STACK_TOP
+ sti
+
+ ; Execute boot loader
+ push es
+ push TC_COM_EXECUTABLE_OFFSET
+ retf
+
+ ; Print string
+print:
+ xor bx, bx
+ mov ah, 0eh
+ cld
+
+@@: lodsb
+ test al, al
+ jz print_end
+
+ int 10h
+ jmp @B
+
+print_end:
+ ret
+
+ ; Read sectors of the first cylinder
+read_sectors:
+ mov ch, 0 ; Cylinder
+ mov dh, 0 ; Head
+ ; DL = drive number passed from BIOS
+ mov ah, 2
+ int 13h
+ jnc read_ok
+
+ lea si, disk_error_msg
+ call print
+read_ok:
+ ret
+
+ ; Calculate checksum
+checksum:
+ push ds
+ push es
+ pop ds
+ xor eax, eax
+ cld
+
+@@: lodsb
+ add ebx, eax
+ rol ebx, 1
+ loop @B
+
+ pop ds
+ ret
+
+backup_loader_used db 0
+
+disk_error_msg db 'Disk error', 13, 10, 7, 0
+loader_damaged_msg db 7, 'Loader damaged! Repair with Rescue Disk', 0
+
+ORG 7C00h + 510
+ dw 0AA55h ; Boot sector signature
+
+_TEXT ENDS
+END start
diff --git a/src/Boot/Windows/BootStrings.h b/src/Boot/Windows/BootStrings.h
index dcf197a1..6c5d7847 100644
--- a/src/Boot/Windows/BootStrings.h
+++ b/src/Boot/Windows/BootStrings.h
@@ -1,20 +1,20 @@
-/*
- Derived from source code of TrueCrypt 7.1a, which is
- Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed
- by the TrueCrypt License 3.0.
-
- Modifications and additions to the original source code (contained in this file)
- and all other portions of this file are Copyright (c) 2013-2016 IDRIX
- and are governed by the Apache License 2.0 the full text of which is
- contained in the file License.txt included in VeraCrypt binary and source
- code distribution packages.
-*/
-
-#ifndef TC_HEADER_Boot_BootStrings
-#define TC_HEADER_Boot_BootStrings
-
-#define TC_BOOT_STR_ERROR "Error: "
-#define TC_BOOT_STR_NO_BOOT_PARTITION "No bootable partition found"
-#define TC_BOOT_STR_UPGRADE_BIOS "- Upgrade BIOS\r\n- Use a different motherboard model/brand\r\n"
-
-#endif // TC_HEADER_Boot_BootStrings
+/*
+ Derived from source code of TrueCrypt 7.1a, which is
+ Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed
+ by the TrueCrypt License 3.0.
+
+ Modifications and additions to the original source code (contained in this file)
+ and all other portions of this file are Copyright (c) 2013-2016 IDRIX
+ and are governed by the Apache License 2.0 the full text of which is
+ contained in the file License.txt included in VeraCrypt binary and source
+ code distribution packages.
+*/
+
+#ifndef TC_HEADER_Boot_BootStrings
+#define TC_HEADER_Boot_BootStrings
+
+#define TC_BOOT_STR_ERROR "Error: "
+#define TC_BOOT_STR_NO_BOOT_PARTITION "No bootable partition found"
+#define TC_BOOT_STR_UPGRADE_BIOS "- Upgrade BIOS\r\n- Use a different motherboard model/brand\r\n"
+
+#endif // TC_HEADER_Boot_BootStrings
diff --git a/src/Boot/Windows/Decompressor.c b/src/Boot/Windows/Decompressor.c
index 475a501d..3bed8c67 100644
--- a/src/Boot/Windows/Decompressor.c
+++ b/src/Boot/Windows/Decompressor.c
@@ -83,7 +83,7 @@ local int stored(struct state *s)
s->bitbuf = 0;
s->bitcnt = 0;
- if (s->incnt + 4 > s->inlen)
+ if (s->incnt + 4 > s->inlen)
return 2; /* not enough input */
/* get length and check against its one's complement */
@@ -93,7 +93,7 @@ local int stored(struct state *s)
s->in[s->incnt++] != ((~len >> 8) & 0xff))
return -2; /* didn't match complement! */
- if (s->incnt + len > s->inlen)
+ if (s->incnt + len > s->inlen)
return 2; /* not enough input */
/* copy len bytes from in to out */
@@ -379,21 +379,21 @@ local int dynamic(struct state *s)
lengths[index++] = symbol;
else { /* repeat instruction */
len = 0; /* assume repeating zeros */
- switch(symbol)
- {
- case 16: { /* repeat last length 3..6 times */
- if (index == 0) return -5; /* no last length! */
- len = lengths[index - 1]; /* last length */
- symbol = 3 + bits(s, 2);
- break;
- }
- case 17: /* repeat zero 3..10 times */
- symbol = 3 + bits(s, 3);
- break;
- default: /* == 18, repeat zero 11..138 times */
- symbol = 11 + bits(s, 7);
- break;
- }
+ switch(symbol)
+ {
+ case 16: { /* repeat last length 3..6 times */
+ if (index == 0) return -5; /* no last length! */
+ len = lengths[index - 1]; /* last length */
+ symbol = 3 + bits(s, 2);
+ break;
+ }
+ case 17: /* repeat zero 3..10 times */
+ symbol = 3 + bits(s, 3);
+ break;
+ default: /* == 18, repeat zero 11..138 times */
+ symbol = 11 + bits(s, 7);
+ break;
+ }
if ((index + symbol > nlen + ndist))
return -6; /* too many lengths! */
while (symbol--) /* repeat last or zero symbol times */
@@ -401,8 +401,8 @@ local int dynamic(struct state *s)
}
}
- /* check for end-of-block code -- there better be one! */
- if (lengths[256] == 0)
+ /* check for end-of-block code -- there better be one! */
+ if (lengths[256] == 0)
return -9;
/* build huffman table for literal/length codes */
@@ -423,50 +423,50 @@ local int dynamic(struct state *s)
void _acrtused () { }
// Decompress deflated data
-int far main (
- unsigned char *dest, /* pointer to destination pointer */
- unsigned int destlen, /* amount of output space */
- unsigned char *source, /* pointer to source data pointer */
- unsigned int sourcelen)
-{
- struct state s; /* input/output state */
- int last, type; /* block information */
- int err; /* return value */
-
- /* initialize output state */
- s.out = dest;
- s.outlen = destlen; /* ignored if dest is NIL */
- s.outcnt = 0;
-
- /* initialize input state */
- s.in = source;
- s.inlen = sourcelen;
- s.incnt = 0;
- s.bitbuf = 0;
- s.bitcnt = 0;
-
- /* process blocks until last block or error */
- do {
- last = bits(&s, 1); /* one if last block */
- type = bits(&s, 2); /* block type 0..3 */
- switch(type)
- {
- case 0:
- err = stored(&s);
- break;
- case 1:
- err = fixed(&s);
- break;
- case 2:
- err = dynamic(&s);
- break;
- default:
- err = -1; /* type == 3, invalid */
- break;
- }
-
- if (err != 0) break; /* return with error */
- } while (!last);
-
- return err;
+int far main (
+ unsigned char *dest, /* pointer to destination pointer */
+ unsigned int destlen, /* amount of output space */
+ unsigned char *source, /* pointer to source data pointer */
+ unsigned int sourcelen)
+{
+ struct state s; /* input/output state */
+ int last, type; /* block information */
+ int err; /* return value */
+
+ /* initialize output state */
+ s.out = dest;
+ s.outlen = destlen; /* ignored if dest is NIL */
+ s.outcnt = 0;
+
+ /* initialize input state */
+ s.in = source;
+ s.inlen = sourcelen;
+ s.incnt = 0;
+ s.bitbuf = 0;
+ s.bitcnt = 0;
+
+ /* process blocks until last block or error */
+ do {
+ last = bits(&s, 1); /* one if last block */
+ type = bits(&s, 2); /* block type 0..3 */
+ switch(type)
+ {
+ case 0:
+ err = stored(&s);
+ break;
+ case 1:
+ err = fixed(&s);
+ break;
+ case 2:
+ err = dynamic(&s);
+ break;
+ default:
+ err = -1; /* type == 3, invalid */
+ break;
+ }
+
+ if (err != 0) break; /* return with error */
+ } while (!last);
+
+ return err;
}
diff --git a/src/Boot/Windows/IntFilter.cpp b/src/Boot/Windows/IntFilter.cpp
index 0671c4d0..4a39fd14 100644
--- a/src/Boot/Windows/IntFilter.cpp
+++ b/src/Boot/Windows/IntFilter.cpp
@@ -1,645 +1,645 @@
-/*
- Derived from source code of TrueCrypt 7.1a, which is
- Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed
- by the TrueCrypt License 3.0.
-
- Modifications and additions to the original source code (contained in this file)
- and all other portions of this file are Copyright (c) 2013-2016 IDRIX
- and are governed by the Apache License 2.0 the full text of which is
- contained in the file License.txt included in VeraCrypt binary and source
- code distribution packages.
-*/
-
-#include "Platform.h"
-#include "BootMemory.h"
-#include "BootConfig.h"
-#include "BootConsoleIo.h"
-#include "BootDebug.h"
-#include "BootDefs.h"
-#include "BootDiskIo.h"
-#include "BootEncryptedIo.h"
-#include "BootStrings.h"
-#include "IntFilter.h"
-
-static uint32 OriginalInt13Handler;
-static uint32 OriginalInt15Handler;
-
-static Registers IntRegisters;
-
-
-bool Int13Filter ()
-{
- CheckStack();
-
- Registers regs;
- memcpy (&regs, &IntRegisters, sizeof (regs));
- __asm sti
-
- static int ReEntryCount = -1;
- ++ReEntryCount;
-
- byte function = (byte) (regs.AX >> 8);
-
-#ifdef TC_TRACE_INT13
- DisableScreenOutput();
-
- PrintHex (function);
-
- Print (" EN:"); Print (ReEntryCount);
- Print (" SS:"); PrintHex (regs.SS);
-
- uint16 spdbg;
- __asm mov spdbg, sp
- PrintChar (' ');
- PrintHex (spdbg);
- PrintChar ('<'); PrintHex (TC_BOOT_LOADER_STACK_TOP);
-
-#endif
-
- bool passOriginalRequest = true;
-
- switch (function)
- {
- case 0x2: // Read sectors
- case 0x3: // Write sectors
- {
- byte drive = (byte) regs.DX;
-
- ChsAddress chs;
- chs.Cylinder = ((regs.CX << 2) & 0x300) | (regs.CX >> 8);
- chs.Head = regs.DX >> 8;
- chs.Sector = regs.CX & 0x3f;
-
- byte sectorCount = (byte) regs.AX;
-
-#ifdef TC_TRACE_INT13
- PrintVal (": Drive", drive - TC_FIRST_BIOS_DRIVE, false);
- Print (" Chs: "); Print (chs);
-#endif
-
- uint64 sector;
- if (drive == BootDrive)
- {
- if (!BootDriveGeometryValid)
- TC_THROW_FATAL_EXCEPTION;
-
- ChsToLba (BootDriveGeometry, chs, sector);
-#ifdef TC_TRACE_INT13
- PrintVal (" Sec", sector.LowPart, false);
-#endif
- }
-
-#ifdef TC_TRACE_INT13
- PrintVal (" Count", sectorCount, false);
- Print (" Buf: "); PrintHex (regs.ES); PrintChar (':'); PrintHex (regs.BX);
- PrintEndl();
-#endif
-
- if (ReEntryCount == 0 && drive == EncryptedVirtualPartition.Drive)
- {
- BiosResult result;
-
- if (function == 0x3)
- result = WriteEncryptedSectors (regs.ES, regs.BX, drive, sector, sectorCount);
- else
- result = ReadEncryptedSectors (regs.ES, regs.BX, drive, sector, sectorCount);
-
- __asm cli
-
- memcpy (&IntRegisters, &regs, sizeof (regs));
- IntRegisters.AX = (uint16) result << 8;
-
- if (result == BiosResultSuccess)
- {
- IntRegisters.AX |= sectorCount;
- IntRegisters.Flags &= ~TC_X86_CARRY_FLAG;
- }
- else
- IntRegisters.Flags |= TC_X86_CARRY_FLAG;
-
- passOriginalRequest = false;
- }
- }
- break;
-
- case 0x42: // Read sectors LBA
- case 0x43: // Write sectors LBA
- {
- byte drive = (byte) regs.DX;
-
- BiosLbaPacket lba;
- CopyMemory (regs.DS, regs.SI, (byte *) &lba, sizeof (lba));
-
-#ifdef TC_TRACE_INT13
- PrintVal (": Drive", drive - TC_FIRST_BIOS_DRIVE, false);
- PrintVal (" Sec", lba.Sector.LowPart, false);
- PrintVal (" Count", lba.SectorCount, false);
- PrintVal (" Buf", lba.Buffer, false, true);
- PrintEndl();
-#endif
-
- if (ReEntryCount == 0 && drive == EncryptedVirtualPartition.Drive)
- {
- BiosResult result;
-
- uint16 segment = (uint16) (lba.Buffer >> 16);
- uint16 offset = (uint16) lba.Buffer;
-
- if (function == 0x43)
- result = WriteEncryptedSectors (segment, offset, drive, lba.Sector, lba.SectorCount);
- else
- result = ReadEncryptedSectors (segment, offset, drive, lba.Sector, lba.SectorCount);
-
- __asm cli
-
- memcpy (&IntRegisters, &regs, sizeof (regs));
- IntRegisters.AX = (IntRegisters.AX & 0xff) | ((uint16) result << 8);
-
- if (result == BiosResultSuccess)
- IntRegisters.Flags &= ~TC_X86_CARRY_FLAG;
- else
- IntRegisters.Flags |= TC_X86_CARRY_FLAG;
-
- passOriginalRequest = false;
- }
- }
- break;
-
- default:
-#ifdef TC_TRACE_INT13
- PrintEndl();
-#endif
- break;
- }
-
-#ifdef TC_TRACE_INT13
- EnableScreenOutput();
-#endif
- --ReEntryCount;
-
- return passOriginalRequest;
-}
-
-
-#define TC_MAX_MEMORY_MAP_SIZE 80
-
-BiosMemoryMapEntry BiosMemoryMap[TC_MAX_MEMORY_MAP_SIZE];
-static size_t BiosMemoryMapSize;
-
-
-static void CreateBootLoaderMemoryMapEntry (BiosMemoryMapEntry *newMapEntry, uint32 bootLoaderStart)
-{
- newMapEntry->Type = 0x2;
- newMapEntry->BaseAddress.HighPart = 0;
- newMapEntry->BaseAddress.LowPart = bootLoaderStart;
- newMapEntry->Length.HighPart = 0;
- newMapEntry->Length.LowPart = TC_BOOT_MEMORY_REQUIRED * 1024UL;
-}
-
-
-static bool CreateNewBiosMemoryMap ()
-{
- // Create a new BIOS memory map presenting the memory area of the loader as reserved
-
- BiosMemoryMapSize = 0;
- BiosMemoryMapEntry entry;
- BiosMemoryMapEntry *newMapEntry = BiosMemoryMap;
-
- const BiosMemoryMapEntry *mapEnd = BiosMemoryMap + TC_MAX_MEMORY_MAP_SIZE;
-
- uint64 bootLoaderStart;
- bootLoaderStart.HighPart = 0;
-
- uint16 codeSeg;
- __asm mov codeSeg, cs
- bootLoaderStart.LowPart = GetLinearAddress (codeSeg, 0);
-
- uint64 bootLoaderEnd;
- bootLoaderEnd.HighPart = 0;
- bootLoaderEnd.LowPart = bootLoaderStart.LowPart + TC_BOOT_MEMORY_REQUIRED * 1024UL;
-
- bool loaderEntryInserted = false;
-
- if (GetFirstBiosMemoryMapEntry (entry))
- {
- do
- {
- uint64 entryEnd = entry.BaseAddress + entry.Length;
-
- if (entry.Type == 0x1 && RegionsIntersect (bootLoaderStart, TC_BOOT_MEMORY_REQUIRED * 1024UL, entry.BaseAddress, entryEnd - 1))
- {
- // Free map entry covers the boot loader area
-
- if (entry.BaseAddress < bootLoaderStart)
- {
- // Create free entry below the boot loader area
- if (newMapEntry >= mapEnd)
- goto mapOverflow;
-
- *newMapEntry = entry;
- newMapEntry->Length = bootLoaderStart - entry.BaseAddress;
- ++newMapEntry;
- }
-
- if (!loaderEntryInserted)
- {
- // Create reserved entry for the boot loader if it has not been done yet
- if (newMapEntry >= mapEnd)
- goto mapOverflow;
-
- CreateBootLoaderMemoryMapEntry (newMapEntry, bootLoaderStart.LowPart);
- ++newMapEntry;
- loaderEntryInserted = true;
- }
-
- if (bootLoaderEnd < entryEnd)
- {
- // Create free entry above the boot loader area
- if (newMapEntry >= mapEnd)
- goto mapOverflow;
-
- newMapEntry->Type = 0x1;
- newMapEntry->BaseAddress = bootLoaderEnd;
- newMapEntry->Length = entryEnd - bootLoaderEnd;
- ++newMapEntry;
- }
- }
- else
- {
- if (newMapEntry >= mapEnd)
- goto mapOverflow;
-
- if (!loaderEntryInserted && entry.BaseAddress > bootLoaderStart)
- {
- // Create reserved entry for the boot loader if it has not been done yet
- CreateBootLoaderMemoryMapEntry (newMapEntry, bootLoaderStart.LowPart);
- ++newMapEntry;
- loaderEntryInserted = true;
- }
-
- // Copy map entry
- *newMapEntry++ = entry;
- }
-
- } while (GetNextBiosMemoryMapEntry (entry));
- }
-
- BiosMemoryMapSize = newMapEntry - BiosMemoryMap;
- return true;
-
-mapOverflow:
- size_t overSize = 0;
- while (GetNextBiosMemoryMapEntry (entry))
- {
- ++overSize;
- }
-
- PrintErrorNoEndl ("MMP:");
- Print (overSize);
- PrintEndl();
-
- return false;
-}
-
-
-bool Int15Filter ()
-{
- CheckStack();
-
-#ifdef TC_TRACE_INT15
- DisableScreenOutput();
-
- Print ("15-");
- PrintHex (IntRegisters.AX);
-
- Print (" SS:"); PrintHex (IntRegisters.SS);
-
- uint16 spdbg;
- __asm mov spdbg, sp
- PrintChar (' ');
- PrintHex (spdbg);
- PrintChar ('<'); PrintHex (TC_BOOT_LOADER_STACK_TOP);
-
- Print (" EAX:"); PrintHex (IntRegisters.EAX);
- Print (" EBX:"); PrintHex (IntRegisters.EBX);
- Print (" ECX:"); PrintHex (IntRegisters.ECX);
- Print (" EDX:"); PrintHex (IntRegisters.EDX);
- Print (" DI:"); PrintHex (IntRegisters.DI);
- PrintEndl();
-
-#endif
-
- if (IntRegisters.EBX >= BiosMemoryMapSize)
- {
- IntRegisters.Flags |= TC_X86_CARRY_FLAG;
- IntRegisters.EBX = 0;
- IntRegisters.AX = -1;
- }
- else
- {
- CopyMemory ((byte *) &BiosMemoryMap[IntRegisters.EBX], IntRegisters.ES, IntRegisters.DI, sizeof (BiosMemoryMap[0]));
-
- IntRegisters.Flags &= ~TC_X86_CARRY_FLAG;
- IntRegisters.EAX = 0x534D4150UL;
-
- ++IntRegisters.EBX;
- if (IntRegisters.EBX >= BiosMemoryMapSize)
- IntRegisters.EBX = 0;
-
- IntRegisters.ECX = sizeof (BiosMemoryMap[0]);
- }
-
- if (IntRegisters.EBX == 0 && !(BootSectorFlags & TC_BOOT_CFG_FLAG_WINDOWS_VISTA_OR_LATER))
- {
- // Uninstall filter when the modified map has been issued three times to prevent
- // problems with hardware drivers on some notebooks running Windows XP.
-
- static int CompleteMapIssueCount = 0;
- if (++CompleteMapIssueCount >= 3)
- {
- __asm
- {
- cli
- push es
-
- lea si, OriginalInt15Handler
- xor ax, ax
- mov es, ax
- mov di, 0x15 * 4
-
- mov ax, [si]
- mov es:[di], ax
- mov ax, [si + 2]
- mov es:[di + 2], ax
-
- pop es
- sti
- }
- }
- }
-
-#ifdef TC_TRACE_INT15
- BiosMemoryMapEntry entry;
- CopyMemory (IntRegisters.ES, IntRegisters.DI, (byte *) &entry, sizeof (entry));
- PrintHex (entry.Type); PrintChar (' ');
- PrintHex (entry.BaseAddress); PrintChar (' ');
- PrintHex (entry.Length); PrintChar (' ');
- PrintHex (entry.BaseAddress + entry.Length); PrintEndl();
-
- Print ("EAX:"); PrintHex (IntRegisters.EAX);
- Print (" EBX:"); PrintHex (IntRegisters.EBX);
- Print (" ECX:"); PrintHex (IntRegisters.ECX);
- Print (" EDX:"); PrintHex (IntRegisters.EDX);
- Print (" DI:"); PrintHex (IntRegisters.DI);
- Print (" FL:"); PrintHex (IntRegisters.Flags);
- PrintEndl (2);
-#endif
-
-#ifdef TC_TRACE_INT15
- EnableScreenOutput();
-#endif
- return false;
-}
-
-
-void IntFilterEntry ()
-{
- // No automatic variables should be used in this scope as SS may change
- static uint16 OrigStackPointer;
- static uint16 OrigStackSegment;
-
- __asm
- {
- pushf
- pushad
-
- cli
- mov cs:IntRegisters.DI, di
-
- lea di, cs:IntRegisters.EAX
- TC_ASM_EMIT4 (66,2E,89,05) // mov [cs:di], eax
- lea di, cs:IntRegisters.EBX
- TC_ASM_EMIT4 (66,2E,89,1D) // mov [cs:di], ebx
- lea di, cs:IntRegisters.ECX
- TC_ASM_EMIT4 (66,2E,89,0D) // mov [cs:di], ecx
- lea di, cs:IntRegisters.EDX
- TC_ASM_EMIT4 (66,2E,89,15) // mov [cs:di], edx
-
- mov ax, [bp + 8]
- mov cs:IntRegisters.Flags, ax
-
- mov cs:IntRegisters.SI, si
- mov si, [bp + 2] // Int number
-
- mov cs:IntRegisters.DS, ds
- mov cs:IntRegisters.ES, es
- mov cs:IntRegisters.SS, ss
-
- // Compiler assumes SS == DS - use our stack if this condition is not met
- mov ax, ss
- mov bx, cs
- cmp ax, bx
- jz stack_ok
-
- mov cs:OrigStackPointer, sp
- mov cs:OrigStackSegment, ss
- mov ax, cs
- mov ss, ax
- mov sp, TC_BOOT_LOADER_STACK_TOP
-
- stack_ok:
- // DS = CS
- push ds
- push es
- mov ax, cs
- mov ds, ax
- mov es, ax
-
- push si // Int number
-
- // Filter request
- cmp si, 0x15
- je filter15
- cmp si, 0x13
- jne $
-
- call Int13Filter
- jmp s0
-
- filter15:
- call Int15Filter
-
- s0:
- pop si // Int number
- pop es
- pop ds
-
- // Restore original SS:SP if our stack is empty
- cli
- mov bx, TC_BOOT_LOADER_STACK_TOP
- cmp bx, sp
- jnz stack_in_use
-
- mov ss, cs:OrigStackSegment
- mov sp, cs:OrigStackPointer
- stack_in_use:
-
- test ax, ax // passOriginalRequest
- jnz pass_request
-
- // Return results of filtered request
- popad
- popf
- mov ax, cs:IntRegisters.Flags
- mov [bp + 8], ax
- leave
-
- lea di, cs:IntRegisters.EAX
- TC_ASM_EMIT4 (66,2E,8B,05) // mov eax, [cs:di]
- lea di, cs:IntRegisters.EBX
- TC_ASM_EMIT4 (66,2E,8B,1D) // mov ebx, [cs:di]
- lea di, cs:IntRegisters.ECX
- TC_ASM_EMIT4 (66,2E,8B,0D) // mov ecx, [cs:di]
- lea di, cs:IntRegisters.EDX
- TC_ASM_EMIT4 (66,2E,8B,15) // mov edx, [cs:di]
-
- mov di, cs:IntRegisters.DI
- mov si, cs:IntRegisters.SI
- mov es, cs:IntRegisters.ES
- mov ds, cs:IntRegisters.DS
-
- sti
- add sp, 2
- iret
-
- // Pass original request
- pass_request:
- sti
- cmp si, 0x15
- je pass15
- cmp si, 0x13
- jne $
-
- popad
- popf
- leave
- add sp, 2
- jmp cs:OriginalInt13Handler
-
- pass15:
- popad
- popf
- leave
- add sp, 2
- jmp cs:OriginalInt15Handler
- }
-}
-
-
-void Int13FilterEntry ()
-{
- __asm
- {
- leave
- push 0x13
- jmp IntFilterEntry
- }
-}
-
-
-static void Int15FilterEntry ()
-{
- __asm
- {
- pushf
- cmp ax, 0xe820 // Get system memory map
- je filter
-
- popf
- leave
- jmp cs:OriginalInt15Handler
-
- filter:
- leave
- push 0x15
- jmp IntFilterEntry
- }
-}
-
-
-bool InstallInterruptFilters ()
-{
-
-#ifndef TC_WINDOWS_BOOT_RESCUE_DISK_MODE
-
- // If the filters have already been installed, it usually indicates stack corruption
- // and a consequent reentry of this routine without a system reset.
-
- uint32 currentInt13Handler;
- CopyMemory (0, 0x13 * 4, &currentInt13Handler, sizeof (currentInt13Handler));
-
- if (currentInt13Handler == (uint32) Int13FilterEntry)
- {
- PrintError ("Memory corrupted");
- Print (TC_BOOT_STR_UPGRADE_BIOS);
-
- GetKeyboardChar();
- return true;
- }
-
-#endif
-
- if (!CreateNewBiosMemoryMap())
- return false;
-
- __asm
- {
- cli
- push es
-
- // Save original INT 13 handler
- xor ax, ax
- mov es, ax
-
- mov si, 0x13 * 4
- lea di, OriginalInt13Handler
-
- mov ax, es:[si]
- mov [di], ax
- mov ax, es:[si + 2]
- mov [di + 2], ax
-
- // Install INT 13 filter
- lea ax, Int13FilterEntry
- mov es:[si], ax
- mov es:[si + 2], cs
-
- // Save original INT 15 handler
- mov si, 0x15 * 4
- lea di, OriginalInt15Handler
-
- mov ax, es:[si]
- mov [di], ax
- mov ax, es:[si + 2]
- mov [di + 2], ax
-
- // Install INT 15 filter
- lea ax, Int15FilterEntry
- mov es:[si], ax
- mov es:[si + 2], cs
-
- // If the BIOS does not support system memory map (INT15 0xe820),
- // set amount of available memory to CS:0000 - 0:0000
- cmp BiosMemoryMapSize, 1
- jg mem_map_ok
- mov ax, cs
- shr ax, 10 - 4 // CS * 16 / 1024
- mov es:[0x413], ax // = KBytes available
- mem_map_ok:
-
- pop es
- sti
- }
-
- return true;
-}
+/*
+ Derived from source code of TrueCrypt 7.1a, which is
+ Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed
+ by the TrueCrypt License 3.0.
+
+ Modifications and additions to the original source code (contained in this file)
+ and all other portions of this file are Copyright (c) 2013-2016 IDRIX
+ and are governed by the Apache License 2.0 the full text of which is
+ contained in the file License.txt included in VeraCrypt binary and source
+ code distribution packages.
+*/
+
+#include "Platform.h"
+#include "BootMemory.h"
+#include "BootConfig.h"
+#include "BootConsoleIo.h"
+#include "BootDebug.h"
+#include "BootDefs.h"
+#include "BootDiskIo.h"
+#include "BootEncryptedIo.h"
+#include "BootStrings.h"
+#include "IntFilter.h"
+
+static uint32 OriginalInt13Handler;
+static uint32 OriginalInt15Handler;
+
+static Registers IntRegisters;
+
+
+bool Int13Filter ()
+{
+ CheckStack();
+
+ Registers regs;
+ memcpy (&regs, &IntRegisters, sizeof (regs));
+ __asm sti
+
+ static int ReEntryCount = -1;
+ ++ReEntryCount;
+
+ byte function = (byte) (regs.AX >> 8);
+
+#ifdef TC_TRACE_INT13
+ DisableScreenOutput();
+
+ PrintHex (function);
+
+ Print (" EN:"); Print (ReEntryCount);
+ Print (" SS:"); PrintHex (regs.SS);
+
+ uint16 spdbg;
+ __asm mov spdbg, sp
+ PrintChar (' ');
+ PrintHex (spdbg);
+ PrintChar ('<'); PrintHex (TC_BOOT_LOADER_STACK_TOP);
+
+#endif
+
+ bool passOriginalRequest = true;
+
+ switch (function)
+ {
+ case 0x2: // Read sectors
+ case 0x3: // Write sectors
+ {
+ byte drive = (byte) regs.DX;
+
+ ChsAddress chs;
+ chs.Cylinder = ((regs.CX << 2) & 0x300) | (regs.CX >> 8);
+ chs.Head = regs.DX >> 8;
+ chs.Sector = regs.CX & 0x3f;
+
+ byte sectorCount = (byte) regs.AX;
+
+#ifdef TC_TRACE_INT13
+ PrintVal (": Drive", drive - TC_FIRST_BIOS_DRIVE, false);
+ Print (" Chs: "); Print (chs);
+#endif
+
+ uint64 sector;
+ if (drive == BootDrive)
+ {
+ if (!BootDriveGeometryValid)
+ TC_THROW_FATAL_EXCEPTION;
+
+ ChsToLba (BootDriveGeometry, chs, sector);
+#ifdef TC_TRACE_INT13
+ PrintVal (" Sec", sector.LowPart, false);
+#endif
+ }
+
+#ifdef TC_TRACE_INT13
+ PrintVal (" Count", sectorCount, false);
+ Print (" Buf: "); PrintHex (regs.ES); PrintChar (':'); PrintHex (regs.BX);
+ PrintEndl();
+#endif
+
+ if (ReEntryCount == 0 && drive == EncryptedVirtualPartition.Drive)
+ {
+ BiosResult result;
+
+ if (function == 0x3)
+ result = WriteEncryptedSectors (regs.ES, regs.BX, drive, sector, sectorCount);
+ else
+ result = ReadEncryptedSectors (regs.ES, regs.BX, drive, sector, sectorCount);
+
+ __asm cli
+
+ memcpy (&IntRegisters, &regs, sizeof (regs));
+ IntRegisters.AX = (uint16) result << 8;
+
+ if (result == BiosResultSuccess)
+ {
+ IntRegisters.AX |= sectorCount;
+ IntRegisters.Flags &= ~TC_X86_CARRY_FLAG;
+ }
+ else
+ IntRegisters.Flags |= TC_X86_CARRY_FLAG;
+
+ passOriginalRequest = false;
+ }
+ }
+ break;
+
+ case 0x42: // Read sectors LBA
+ case 0x43: // Write sectors LBA
+ {
+ byte drive = (byte) regs.DX;
+
+ BiosLbaPacket lba;
+ CopyMemory (regs.DS, regs.SI, (byte *) &lba, sizeof (lba));
+
+#ifdef TC_TRACE_INT13
+ PrintVal (": Drive", drive - TC_FIRST_BIOS_DRIVE, false);
+ PrintVal (" Sec", lba.Sector.LowPart, false);
+ PrintVal (" Count", lba.SectorCount, false);
+ PrintVal (" Buf", lba.Buffer, false, true);
+ PrintEndl();
+#endif
+
+ if (ReEntryCount == 0 && drive == EncryptedVirtualPartition.Drive)
+ {
+ BiosResult result;
+
+ uint16 segment = (uint16) (lba.Buffer >> 16);
+ uint16 offset = (uint16) lba.Buffer;
+
+ if (function == 0x43)
+ result = WriteEncryptedSectors (segment, offset, drive, lba.Sector, lba.SectorCount);
+ else
+ result = ReadEncryptedSectors (segment, offset, drive, lba.Sector, lba.SectorCount);
+
+ __asm cli
+
+ memcpy (&IntRegisters, &regs, sizeof (regs));
+ IntRegisters.AX = (IntRegisters.AX & 0xff) | ((uint16) result << 8);
+
+ if (result == BiosResultSuccess)
+ IntRegisters.Flags &= ~TC_X86_CARRY_FLAG;
+ else
+ IntRegisters.Flags |= TC_X86_CARRY_FLAG;
+
+ passOriginalRequest = false;
+ }
+ }
+ break;
+
+ default:
+#ifdef TC_TRACE_INT13
+ PrintEndl();
+#endif
+ break;
+ }
+
+#ifdef TC_TRACE_INT13
+ EnableScreenOutput();
+#endif
+ --ReEntryCount;
+
+ return passOriginalRequest;
+}
+
+
+#define TC_MAX_MEMORY_MAP_SIZE 80
+
+BiosMemoryMapEntry BiosMemoryMap[TC_MAX_MEMORY_MAP_SIZE];
+static size_t BiosMemoryMapSize;
+
+
+static void CreateBootLoaderMemoryMapEntry (BiosMemoryMapEntry *newMapEntry, uint32 bootLoaderStart)
+{
+ newMapEntry->Type = 0x2;
+ newMapEntry->BaseAddress.HighPart = 0;
+ newMapEntry->BaseAddress.LowPart = bootLoaderStart;
+ newMapEntry->Length.HighPart = 0;
+ newMapEntry->Length.LowPart = TC_BOOT_MEMORY_REQUIRED * 1024UL;
+}
+
+
+static bool CreateNewBiosMemoryMap ()
+{
+ // Create a new BIOS memory map presenting the memory area of the loader as reserved
+
+ BiosMemoryMapSize = 0;
+ BiosMemoryMapEntry entry;
+ BiosMemoryMapEntry *newMapEntry = BiosMemoryMap;
+
+ const BiosMemoryMapEntry *mapEnd = BiosMemoryMap + TC_MAX_MEMORY_MAP_SIZE;
+
+ uint64 bootLoaderStart;
+ bootLoaderStart.HighPart = 0;
+
+ uint16 codeSeg;
+ __asm mov codeSeg, cs
+ bootLoaderStart.LowPart = GetLinearAddress (codeSeg, 0);
+
+ uint64 bootLoaderEnd;
+ bootLoaderEnd.HighPart = 0;
+ bootLoaderEnd.LowPart = bootLoaderStart.LowPart + TC_BOOT_MEMORY_REQUIRED * 1024UL;
+
+ bool loaderEntryInserted = false;
+
+ if (GetFirstBiosMemoryMapEntry (entry))
+ {
+ do
+ {
+ uint64 entryEnd = entry.BaseAddress + entry.Length;
+
+ if (entry.Type == 0x1 && RegionsIntersect (bootLoaderStart, TC_BOOT_MEMORY_REQUIRED * 1024UL, entry.BaseAddress, entryEnd - 1))
+ {
+ // Free map entry covers the boot loader area
+
+ if (entry.BaseAddress < bootLoaderStart)
+ {
+ // Create free entry below the boot loader area
+ if (newMapEntry >= mapEnd)
+ goto mapOverflow;
+
+ *newMapEntry = entry;
+ newMapEntry->Length = bootLoaderStart - entry.BaseAddress;
+ ++newMapEntry;
+ }
+
+ if (!loaderEntryInserted)
+ {
+ // Create reserved entry for the boot loader if it has not been done yet
+ if (newMapEntry >= mapEnd)
+ goto mapOverflow;
+
+ CreateBootLoaderMemoryMapEntry (newMapEntry, bootLoaderStart.LowPart);
+ ++newMapEntry;
+ loaderEntryInserted = true;
+ }
+
+ if (bootLoaderEnd < entryEnd)
+ {
+ // Create free entry above the boot loader area
+ if (newMapEntry >= mapEnd)
+ goto mapOverflow;
+
+ newMapEntry->Type = 0x1;
+ newMapEntry->BaseAddress = bootLoaderEnd;
+ newMapEntry->Length = entryEnd - bootLoaderEnd;
+ ++newMapEntry;
+ }
+ }
+ else
+ {
+ if (newMapEntry >= mapEnd)
+ goto mapOverflow;
+
+ if (!loaderEntryInserted && entry.BaseAddress > bootLoaderStart)
+ {
+ // Create reserved entry for the boot loader if it has not been done yet
+ CreateBootLoaderMemoryMapEntry (newMapEntry, bootLoaderStart.LowPart);
+ ++newMapEntry;
+ loaderEntryInserted = true;
+ }
+
+ // Copy map entry
+ *newMapEntry++ = entry;
+ }
+
+ } while (GetNextBiosMemoryMapEntry (entry));
+ }
+
+ BiosMemoryMapSize = newMapEntry - BiosMemoryMap;
+ return true;
+
+mapOverflow:
+ size_t overSize = 0;
+ while (GetNextBiosMemoryMapEntry (entry))
+ {
+ ++overSize;
+ }
+
+ PrintErrorNoEndl ("MMP:");
+ Print (overSize);
+ PrintEndl();
+
+ return false;
+}
+
+
+bool Int15Filter ()
+{
+ CheckStack();
+
+#ifdef TC_TRACE_INT15
+ DisableScreenOutput();
+
+ Print ("15-");
+ PrintHex (IntRegisters.AX);
+
+ Print (" SS:"); PrintHex (IntRegisters.SS);
+
+ uint16 spdbg;
+ __asm mov spdbg, sp
+ PrintChar (' ');
+ PrintHex (spdbg);
+ PrintChar ('<'); PrintHex (TC_BOOT_LOADER_STACK_TOP);
+
+ Print (" EAX:"); PrintHex (IntRegisters.EAX);
+ Print (" EBX:"); PrintHex (IntRegisters.EBX);
+ Print (" ECX:"); PrintHex (IntRegisters.ECX);
+ Print (" EDX:"); PrintHex (IntRegisters.EDX);
+ Print (" DI:"); PrintHex (IntRegisters.DI);
+ PrintEndl();
+
+#endif
+
+ if (IntRegisters.EBX >= BiosMemoryMapSize)
+ {
+ IntRegisters.Flags |= TC_X86_CARRY_FLAG;
+ IntRegisters.EBX = 0;
+ IntRegisters.AX = -1;
+ }
+ else
+ {
+ CopyMemory ((byte *) &BiosMemoryMap[IntRegisters.EBX], IntRegisters.ES, IntRegisters.DI, sizeof (BiosMemoryMap[0]));
+
+ IntRegisters.Flags &= ~TC_X86_CARRY_FLAG;
+ IntRegisters.EAX = 0x534D4150UL;
+
+ ++IntRegisters.EBX;
+ if (IntRegisters.EBX >= BiosMemoryMapSize)
+ IntRegisters.EBX = 0;
+
+ IntRegisters.ECX = sizeof (BiosMemoryMap[0]);
+ }
+
+ if (IntRegisters.EBX == 0 && !(BootSectorFlags & TC_BOOT_CFG_FLAG_WINDOWS_VISTA_OR_LATER))
+ {
+ // Uninstall filter when the modified map has been issued three times to prevent
+ // problems with hardware drivers on some notebooks running Windows XP.
+
+ static int CompleteMapIssueCount = 0;
+ if (++CompleteMapIssueCount >= 3)
+ {
+ __asm
+ {
+ cli
+ push es
+
+ lea si, OriginalInt15Handler
+ xor ax, ax
+ mov es, ax
+ mov di, 0x15 * 4
+
+ mov ax, [si]
+ mov es:[di], ax
+ mov ax, [si + 2]
+ mov es:[di + 2], ax
+
+ pop es
+ sti
+ }
+ }
+ }
+
+#ifdef TC_TRACE_INT15
+ BiosMemoryMapEntry entry;
+ CopyMemory (IntRegisters.ES, IntRegisters.DI, (byte *) &entry, sizeof (entry));
+ PrintHex (entry.Type); PrintChar (' ');
+ PrintHex (entry.BaseAddress); PrintChar (' ');
+ PrintHex (entry.Length); PrintChar (' ');
+ PrintHex (entry.BaseAddress + entry.Length); PrintEndl();
+
+ Print ("EAX:"); PrintHex (IntRegisters.EAX);
+ Print (" EBX:"); PrintHex (IntRegisters.EBX);
+ Print (" ECX:"); PrintHex (IntRegisters.ECX);
+ Print (" EDX:"); PrintHex (IntRegisters.EDX);
+ Print (" DI:"); PrintHex (IntRegisters.DI);
+ Print (" FL:"); PrintHex (IntRegisters.Flags);
+ PrintEndl (2);
+#endif
+
+#ifdef TC_TRACE_INT15
+ EnableScreenOutput();
+#endif
+ return false;
+}
+
+
+void IntFilterEntry ()
+{
+ // No automatic variables should be used in this scope as SS may change
+ static uint16 OrigStackPointer;
+ static uint16 OrigStackSegment;
+
+ __asm
+ {
+ pushf
+ pushad
+
+ cli
+ mov cs:IntRegisters.DI, di
+
+ lea di, cs:IntRegisters.EAX
+ TC_ASM_EMIT4 (66,2E,89,05) // mov [cs:di], eax
+ lea di, cs:IntRegisters.EBX
+ TC_ASM_EMIT4 (66,2E,89,1D) // mov [cs:di], ebx
+ lea di, cs:IntRegisters.ECX
+ TC_ASM_EMIT4 (66,2E,89,0D) // mov [cs:di], ecx
+ lea di, cs:IntRegisters.EDX
+ TC_ASM_EMIT4 (66,2E,89,15) // mov [cs:di], edx
+
+ mov ax, [bp + 8]
+ mov cs:IntRegisters.Flags, ax
+
+ mov cs:IntRegisters.SI, si
+ mov si, [bp + 2] // Int number
+
+ mov cs:IntRegisters.DS, ds
+ mov cs:IntRegisters.ES, es
+ mov cs:IntRegisters.SS, ss
+
+ // Compiler assumes SS == DS - use our stack if this condition is not met
+ mov ax, ss
+ mov bx, cs
+ cmp ax, bx
+ jz stack_ok
+
+ mov cs:OrigStackPointer, sp
+ mov cs:OrigStackSegment, ss
+ mov ax, cs
+ mov ss, ax
+ mov sp, TC_BOOT_LOADER_STACK_TOP
+
+ stack_ok:
+ // DS = CS
+ push ds
+ push es
+ mov ax, cs
+ mov ds, ax
+ mov es, ax
+
+ push si // Int number
+
+ // Filter request
+ cmp si, 0x15
+ je filter15
+ cmp si, 0x13
+ jne $
+
+ call Int13Filter
+ jmp s0
+
+ filter15:
+ call Int15Filter
+
+ s0:
+ pop si // Int number
+ pop es
+ pop ds
+
+ // Restore original SS:SP if our stack is empty
+ cli
+ mov bx, TC_BOOT_LOADER_STACK_TOP
+ cmp bx, sp
+ jnz stack_in_use
+
+ mov ss, cs:OrigStackSegment
+ mov sp, cs:OrigStackPointer
+ stack_in_use:
+
+ test ax, ax // passOriginalRequest
+ jnz pass_request
+
+ // Return results of filtered request
+ popad
+ popf
+ mov ax, cs:IntRegisters.Flags
+ mov [bp + 8], ax
+ leave
+
+ lea di, cs:IntRegisters.EAX
+ TC_ASM_EMIT4 (66,2E,8B,05) // mov eax, [cs:di]
+ lea di, cs:IntRegisters.EBX
+ TC_ASM_EMIT4 (66,2E,8B,1D) // mov ebx, [cs:di]
+ lea di, cs:IntRegisters.ECX
+ TC_ASM_EMIT4 (66,2E,8B,0D) // mov ecx, [cs:di]
+ lea di, cs:IntRegisters.EDX
+ TC_ASM_EMIT4 (66,2E,8B,15) // mov edx, [cs:di]
+
+ mov di, cs:IntRegisters.DI
+ mov si, cs:IntRegisters.SI
+ mov es, cs:IntRegisters.ES
+ mov ds, cs:IntRegisters.DS
+
+ sti
+ add sp, 2
+ iret
+
+ // Pass original request
+ pass_request:
+ sti
+ cmp si, 0x15
+ je pass15
+ cmp si, 0x13
+ jne $
+
+ popad
+ popf
+ leave
+ add sp, 2
+ jmp cs:OriginalInt13Handler
+
+ pass15:
+ popad
+ popf
+ leave
+ add sp, 2
+ jmp cs:OriginalInt15Handler
+ }
+}
+
+
+void Int13FilterEntry ()
+{
+ __asm
+ {
+ leave
+ push 0x13
+ jmp IntFilterEntry
+ }
+}
+
+
+static void Int15FilterEntry ()
+{
+ __asm
+ {
+ pushf
+ cmp ax, 0xe820 // Get system memory map
+ je filter
+
+ popf
+ leave
+ jmp cs:OriginalInt15Handler
+
+ filter:
+ leave
+ push 0x15
+ jmp IntFilterEntry
+ }
+}
+
+
+bool InstallInterruptFilters ()
+{
+
+#ifndef TC_WINDOWS_BOOT_RESCUE_DISK_MODE
+
+ // If the filters have already been installed, it usually indicates stack corruption
+ // and a consequent reentry of this routine without a system reset.
+
+ uint32 currentInt13Handler;
+ CopyMemory (0, 0x13 * 4, &currentInt13Handler, sizeof (currentInt13Handler));
+
+ if (currentInt13Handler == (uint32) Int13FilterEntry)
+ {
+ PrintError ("Memory corrupted");
+ Print (TC_BOOT_STR_UPGRADE_BIOS);
+
+ GetKeyboardChar();
+ return true;
+ }
+
+#endif
+
+ if (!CreateNewBiosMemoryMap())
+ return false;
+
+ __asm
+ {
+ cli
+ push es
+
+ // Save original INT 13 handler
+ xor ax, ax
+ mov es, ax
+
+ mov si, 0x13 * 4
+ lea di, OriginalInt13Handler
+
+ mov ax, es:[si]
+ mov [di], ax
+ mov ax, es:[si + 2]
+ mov [di + 2], ax
+
+ // Install INT 13 filter
+ lea ax, Int13FilterEntry
+ mov es:[si], ax
+ mov es:[si + 2], cs
+
+ // Save original INT 15 handler
+ mov si, 0x15 * 4
+ lea di, OriginalInt15Handler
+
+ mov ax, es:[si]
+ mov [di], ax
+ mov ax, es:[si + 2]
+ mov [di + 2], ax
+
+ // Install INT 15 filter
+ lea ax, Int15FilterEntry
+ mov es:[si], ax
+ mov es:[si + 2], cs
+
+ // If the BIOS does not support system memory map (INT15 0xe820),
+ // set amount of available memory to CS:0000 - 0:0000
+ cmp BiosMemoryMapSize, 1
+ jg mem_map_ok
+ mov ax, cs
+ shr ax, 10 - 4 // CS * 16 / 1024
+ mov es:[0x413], ax // = KBytes available
+ mem_map_ok:
+
+ pop es
+ sti
+ }
+
+ return true;
+}
diff --git a/src/Boot/Windows/IntFilter.h b/src/Boot/Windows/IntFilter.h
index af354802..3f3a486a 100644
--- a/src/Boot/Windows/IntFilter.h
+++ b/src/Boot/Windows/IntFilter.h
@@ -1,20 +1,20 @@
-/*
- Derived from source code of TrueCrypt 7.1a, which is
- Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed
- by the TrueCrypt License 3.0.
-
- Modifications and additions to the original source code (contained in this file)
- and all other portions of this file are Copyright (c) 2013-2016 IDRIX
- and are governed by the Apache License 2.0 the full text of which is
- contained in the file License.txt included in VeraCrypt binary and source
- code distribution packages.
-*/
-
-#ifndef TC_HEADER_Boot_IntFilter
-#define TC_HEADER_Boot_IntFilter
-
-#include "Platform.h"
-
-bool InstallInterruptFilters ();
-
-#endif TC_HEADER_Boot_IntFilter
+/*
+ Derived from source code of TrueCrypt 7.1a, which is
+ Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed
+ by the TrueCrypt License 3.0.
+
+ Modifications and additions to the original source code (contained in this file)
+ and all other portions of this file are Copyright (c) 2013-2016 IDRIX
+ and are governed by the Apache License 2.0 the full text of which is
+ contained in the file License.txt included in VeraCrypt binary and source
+ code distribution packages.
+*/
+
+#ifndef TC_HEADER_Boot_IntFilter
+#define TC_HEADER_Boot_IntFilter
+
+#include "Platform.h"
+
+bool InstallInterruptFilters ();
+
+#endif TC_HEADER_Boot_IntFilter
diff --git a/src/Boot/Windows/Makefile b/src/Boot/Windows/Makefile
index f9851051..8377520b 100644
--- a/src/Boot/Windows/Makefile
+++ b/src/Boot/Windows/Makefile
@@ -1,202 +1,202 @@
-#
-# Derived from source code of TrueCrypt 7.1a, which is
-# Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed
-# by the TrueCrypt License 3.0.
-#
-# Modifications and additions to the original source code (contained in this file)
-# and all other portions of this file are Copyright (c) 2013-2016 IDRIX
-# and are governed by the Apache License 2.0 the full text of which is
-# contained in the file License.txt included in VeraCrypt binary and source
-# code distribution packages.
-
-PROJ = BootLoader
-.SILENT:
-
-!ifndef MSVC16_ROOT
-!error Environment variable MSVC16_ROOT must point to the installation directory of MS Visual C++ 1.5
-!endif
-
-ENVPATH = $(PATH)
-
-CC = $(MSVC16_ROOT)\bin\cl.exe
-LD = $(MSVC16_ROOT)\bin\link.exe
-
-AFLAGS = /nologo /omf
-
-CFLAGS = /nologo /W3 /Fc /I "$(MSVC16_ROOT)\Include" /I"..\..\.." /I"..\..\..\Common" /I"..\..\..\Crypto"
-CFLAGS = $(CFLAGS) /D __int8=char /D __int16=int /D __int32=long /D BOOL=char /D FALSE=0 /D TRUE=1
-CFLAGS = $(CFLAGS) /D LITTLE_ENDIAN=1234 /D BYTE_ORDER=1234 /D TC_WINDOWS_BOOT /D TC_MINIMIZE_CODE_SIZE /D TC_NO_COMPILER_INT64
-CFLAGS = $(CFLAGS) /D malloc=malloc_NA
-
-LFLAGS = /NOLOGO /ONERROR:NOEXE /NOI /BATCH
-
-OBJDIR = Release
-
-!ifdef RESCUE_DISK
-OBJDIR = Rescue
-CFLAGS = $(CFLAGS) /D TC_WINDOWS_BOOT_RESCUE_DISK_MODE
-!endif
-
-!ifdef SINGLE_CIPHER
-OBJDIR = $(OBJDIR)_$(SINGLE_CIPHER)
-CFLAGS = $(CFLAGS) /D TC_WINDOWS_BOOT_SINGLE_CIPHER_MODE /D TC_WINDOWS_BOOT_$(SINGLE_CIPHER)
-!endif
-
-!ifdef SINGLE_PRF
-OBJDIR = $(OBJDIR)_$(SINGLE_PRF)
-CFLAGS = $(CFLAGS) /D TC_WINDOWS_BOOT_$(SINGLE_PRF)
-!else
-CFLAGS = $(CFLAGS) /D TC_WINDOWS_BOOT_RIPEMD160
-!endif
-
-OUTDIR = $(OBJDIR)
-TARGETEXT = com
-TARGETS = $(OUTDIR)\BootDefs.i $(OUTDIR)\BootSector.bin $(OUTDIR)\Decompressor.com
-CFLAGS = $(CFLAGS) /AT /Zl /f- /G3 /Oe /Os /Ob1 /OV0 /Gs /Gf /Gy /D NDEBUG
-LFLAGS = $(LFLAGS) /NOD /NOE /TINY
-OBJS = $(OUTDIR)\BootCrt.obj
-LIBS = slibce
-
-!if 1
-SRCDIR = ..
-!else
-SRCDIR = $(MAKEDIR)
-!endif
-
-TARGETS = $(TARGETS) $(OUTDIR)\$(PROJ).$(TARGETEXT)
-
-OBJS = $(OBJS) $(OUTDIR)\BootConfig.obj
-OBJS = $(OBJS) $(OUTDIR)\BootConsoleIo.obj
-OBJS = $(OBJS) $(OUTDIR)\BootDebug.obj
-OBJS = $(OBJS) $(OUTDIR)\BootDiskIo.obj
-OBJS = $(OBJS) $(OUTDIR)\BootEncryptedIo.obj
-OBJS = $(OBJS) $(OUTDIR)\BootMain.obj
-OBJS = $(OBJS) $(OUTDIR)\BootMemory.obj
-OBJS = $(OBJS) $(OUTDIR)\IntFilter.obj
-OBJS = $(OBJS) $(OUTDIR)\Platform.obj
-
-OBJS = $(OBJS) $(OUTDIR)\Crc.obj
-OBJS = $(OBJS) $(OUTDIR)\Crypto.obj
-OBJS = $(OBJS) $(OUTDIR)\Endian.obj
-OBJS = $(OBJS) $(OUTDIR)\Pkcs5.obj
-OBJS = $(OBJS) $(OUTDIR)\Volumes.obj
-OBJS = $(OBJS) $(OUTDIR)\Xts.obj
-
-!if "$(SINGLE_PRF)" == "SHA2"
-OBJS = $(OBJS) $(OUTDIR)\Sha2Small.obj
-!else
-OBJS = $(OBJS) $(OUTDIR)\Rmd160.obj
-!endif
-
-!if !DEFINED (SINGLE_CIPHER)
-OBJS = $(OBJS) $(OUTDIR)\AesSmall.obj
-!else if "$(SINGLE_CIPHER)" == "AES"
-OBJS = $(OBJS) $(OUTDIR)\Aes_hw_cpu.obj
-OBJS = $(OBJS) $(OUTDIR)\AesSmall_x86.obj
-OBJS = $(OBJS) $(OUTDIR)\Aestab.obj
-!endif
-
-!if !DEFINED (SINGLE_CIPHER) || "$(SINGLE_CIPHER)" == "SERPENT"
-OBJS = $(OBJS) $(OUTDIR)\Serpent.obj
-!endif
-
-!if !DEFINED (SINGLE_CIPHER) || "$(SINGLE_CIPHER)" == "TWOFISH"
-OBJS = $(OBJS) $(OUTDIR)\Twofish.obj
-!endif
-
-
-all: env $(TARGETS)
-
-env:
- set INCLUDE=.
- set LIB=.
- set LIBPATH=.
-
-clean:
- -del /q /s $(OBJDIR) >NUL:
-
-
-.asm{$(OUTDIR)}.obj:
- cd $(OBJDIR)
- $(AS) $(AFLAGS) /c "$(SRCDIR)\$<"
- cd ..
-
-{..\..\Crypto}.asm{$(OUTDIR)}.obj:
- cd $(OBJDIR)
- echo $(<F)
- nasm.exe -Xvc -f obj -Ox -o "$(<B).obj" -l "$(<B).lst" "$(SRCDIR)\$<"
- cd ..
-
-{..\..\Crypto}.c{$(OUTDIR)}.obj:
- cd $(OBJDIR)
- set PATH=.
- $(CC) $(CFLAGS) /c "$(SRCDIR)\$<"
- set PATH=$(ENVPATH)
- cd ..
-
-{..\..\Common}.c{$(OUTDIR)}.obj:
- cd $(OBJDIR)
- set PATH=.
- $(CC) $(CFLAGS) /c "$(SRCDIR)\$<"
- set PATH=$(ENVPATH)
- cd ..
-
-.c{$(OUTDIR)}.obj:
- cd $(OBJDIR)
- set PATH=.
- $(CC) $(CFLAGS) /c "$(SRCDIR)\$<"
- set PATH=$(ENVPATH)
- cd ..
-
-.cpp{$(OUTDIR)}.obj:
- cd $(OBJDIR)
- set PATH=.
- $(CC) $(CFLAGS) /c "$(SRCDIR)\$<"
- set PATH=$(ENVPATH)
- cd ..
-
-$(OUTDIR)\BootDefs.i: BootDefs.h
- cd $(OBJDIR)
- set PATH=.
- $(CC) $(CFLAGS) /D TC_ASM_PREPROCESS /P /EP "$(SRCDIR)\BootDefs.h"
- set PATH=$(ENVPATH)
- cd ..
-
-$(OUTDIR)\BootSector.bin: $(OUTDIR)\BootSector.obj
- cd $(OBJDIR)
- $(LD) $(LFLAGS) BootSector.obj,BootSector.bin,,,, >NUL:
- -dd.exe conv=notrunc bs=512 if=BootSector.bin of=$(PROJ).flp 2>NUL:
- cd ..
-
-$(OUTDIR)\Decompressor.com: $(OUTDIR)\BootCrt.obj $(OUTDIR)\Decompressor.obj
- cd $(OBJDIR)
- $(LD) $(LFLAGS) BootCrt.obj Decompressor.obj,Decompressor.com,Decompressor.map,$(MSVC16_ROOT)\lib\+slibce,,
- -dd.exe conv=notrunc,sync bs=512 seek=1 if=Decompressor.com of=$(PROJ).flp 2>NUL:
- cd ..
-
-$(OUTDIR)\$(PROJ).$(TARGETEXT): $(OBJS)
- @echo Linking...
- cd $(OBJDIR)
-
- echo >NUL: @<<$(PROJ).crf2
-
-$(PROJ).$(TARGETEXT)
-$(PROJ).map
-$(MSVC16_ROOT)\lib\+
-$(LIBS)
-;
-<<
- del $(PROJ).crf >NUL: 2>NUL:
- for %F in ($(**F)) do @echo %F + >>$(PROJ).crf
- type $(PROJ).crf2 >>$(PROJ).crf
-
- $(LD) $(LFLAGS) @$(PROJ).crf
- del $(PROJ).crf $(PROJ).crf2
-
-# Compress the Rescue Disk botloader for Cascades and Serpent since it is too big (size > 31232 bytes)
-!if DEFINED(RESCUE_DISK) && (!DEFINED (SINGLE_CIPHER) || ("$(SINGLE_CIPHER)" == "SERPENT"))
- upx $(PROJ).$(TARGETEXT)
-!endif
- gzip.exe -c -n --best $(PROJ).$(TARGETEXT) >$(PROJ).$(TARGETEXT).gz
- -dd.exe conv=notrunc,sync bs=512 seek=5 if=$(PROJ).$(TARGETEXT).gz of=$(PROJ).flp 2>NUL:
- cd ..
+#
+# Derived from source code of TrueCrypt 7.1a, which is
+# Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed
+# by the TrueCrypt License 3.0.
+#
+# Modifications and additions to the original source code (contained in this file)
+# and all other portions of this file are Copyright (c) 2013-2016 IDRIX
+# and are governed by the Apache License 2.0 the full text of which is
+# contained in the file License.txt included in VeraCrypt binary and source
+# code distribution packages.
+
+PROJ = BootLoader
+.SILENT:
+
+!ifndef MSVC16_ROOT
+!error Environment variable MSVC16_ROOT must point to the installation directory of MS Visual C++ 1.5
+!endif
+
+ENVPATH = $(PATH)
+
+CC = $(MSVC16_ROOT)\bin\cl.exe
+LD = $(MSVC16_ROOT)\bin\link.exe
+
+AFLAGS = /nologo /omf
+
+CFLAGS = /nologo /W3 /Fc /I "$(MSVC16_ROOT)\Include" /I"..\..\.." /I"..\..\..\Common" /I"..\..\..\Crypto"
+CFLAGS = $(CFLAGS) /D __int8=char /D __int16=int /D __int32=long /D BOOL=char /D FALSE=0 /D TRUE=1
+CFLAGS = $(CFLAGS) /D LITTLE_ENDIAN=1234 /D BYTE_ORDER=1234 /D TC_WINDOWS_BOOT /D TC_MINIMIZE_CODE_SIZE /D TC_NO_COMPILER_INT64
+CFLAGS = $(CFLAGS) /D malloc=malloc_NA
+
+LFLAGS = /NOLOGO /ONERROR:NOEXE /NOI /BATCH
+
+OBJDIR = Release
+
+!ifdef RESCUE_DISK
+OBJDIR = Rescue
+CFLAGS = $(CFLAGS) /D TC_WINDOWS_BOOT_RESCUE_DISK_MODE
+!endif
+
+!ifdef SINGLE_CIPHER
+OBJDIR = $(OBJDIR)_$(SINGLE_CIPHER)
+CFLAGS = $(CFLAGS) /D TC_WINDOWS_BOOT_SINGLE_CIPHER_MODE /D TC_WINDOWS_BOOT_$(SINGLE_CIPHER)
+!endif
+
+!ifdef SINGLE_PRF
+OBJDIR = $(OBJDIR)_$(SINGLE_PRF)
+CFLAGS = $(CFLAGS) /D TC_WINDOWS_BOOT_$(SINGLE_PRF)
+!else
+CFLAGS = $(CFLAGS) /D TC_WINDOWS_BOOT_RIPEMD160
+!endif
+
+OUTDIR = $(OBJDIR)
+TARGETEXT = com
+TARGETS = $(OUTDIR)\BootDefs.i $(OUTDIR)\BootSector.bin $(OUTDIR)\Decompressor.com
+CFLAGS = $(CFLAGS) /AT /Zl /f- /G3 /Oe /Os /Ob1 /OV0 /Gs /Gf /Gy /D NDEBUG
+LFLAGS = $(LFLAGS) /NOD /NOE /TINY
+OBJS = $(OUTDIR)\BootCrt.obj
+LIBS = slibce
+
+!if 1
+SRCDIR = ..
+!else
+SRCDIR = $(MAKEDIR)
+!endif
+
+TARGETS = $(TARGETS) $(OUTDIR)\$(PROJ).$(TARGETEXT)
+
+OBJS = $(OBJS) $(OUTDIR)\BootConfig.obj
+OBJS = $(OBJS) $(OUTDIR)\BootConsoleIo.obj
+OBJS = $(OBJS) $(OUTDIR)\BootDebug.obj
+OBJS = $(OBJS) $(OUTDIR)\BootDiskIo.obj
+OBJS = $(OBJS) $(OUTDIR)\BootEncryptedIo.obj
+OBJS = $(OBJS) $(OUTDIR)\BootMain.obj
+OBJS = $(OBJS) $(OUTDIR)\BootMemory.obj
+OBJS = $(OBJS) $(OUTDIR)\IntFilter.obj
+OBJS = $(OBJS) $(OUTDIR)\Platform.obj
+
+OBJS = $(OBJS) $(OUTDIR)\Crc.obj
+OBJS = $(OBJS) $(OUTDIR)\Crypto.obj
+OBJS = $(OBJS) $(OUTDIR)\Endian.obj
+OBJS = $(OBJS) $(OUTDIR)\Pkcs5.obj
+OBJS = $(OBJS) $(OUTDIR)\Volumes.obj
+OBJS = $(OBJS) $(OUTDIR)\Xts.obj
+
+!if "$(SINGLE_PRF)" == "SHA2"
+OBJS = $(OBJS) $(OUTDIR)\Sha2Small.obj
+!else
+OBJS = $(OBJS) $(OUTDIR)\Rmd160.obj
+!endif
+
+!if !DEFINED (SINGLE_CIPHER)
+OBJS = $(OBJS) $(OUTDIR)\AesSmall.obj
+!else if "$(SINGLE_CIPHER)" == "AES"
+OBJS = $(OBJS) $(OUTDIR)\Aes_hw_cpu.obj
+OBJS = $(OBJS) $(OUTDIR)\AesSmall_x86.obj
+OBJS = $(OBJS) $(OUTDIR)\Aestab.obj
+!endif
+
+!if !DEFINED (SINGLE_CIPHER) || "$(SINGLE_CIPHER)" == "SERPENT"
+OBJS = $(OBJS) $(OUTDIR)\Serpent.obj
+!endif
+
+!if !DEFINED (SINGLE_CIPHER) || "$(SINGLE_CIPHER)" == "TWOFISH"
+OBJS = $(OBJS) $(OUTDIR)\Twofish.obj
+!endif
+
+
+all: env $(TARGETS)
+
+env:
+ set INCLUDE=.
+ set LIB=.
+ set LIBPATH=.
+
+clean:
+ -del /q /s $(OBJDIR) >NUL:
+
+
+.asm{$(OUTDIR)}.obj:
+ cd $(OBJDIR)
+ $(AS) $(AFLAGS) /c "$(SRCDIR)\$<"
+ cd ..
+
+{..\..\Crypto}.asm{$(OUTDIR)}.obj:
+ cd $(OBJDIR)
+ echo $(<F)
+ nasm.exe -Xvc -f obj -Ox -o "$(<B).obj" -l "$(<B).lst" "$(SRCDIR)\$<"
+ cd ..
+
+{..\..\Crypto}.c{$(OUTDIR)}.obj:
+ cd $(OBJDIR)
+ set PATH=.
+ $(CC) $(CFLAGS) /c "$(SRCDIR)\$<"
+ set PATH=$(ENVPATH)
+ cd ..
+
+{..\..\Common}.c{$(OUTDIR)}.obj:
+ cd $(OBJDIR)
+ set PATH=.
+ $(CC) $(CFLAGS) /c "$(SRCDIR)\$<"
+ set PATH=$(ENVPATH)
+ cd ..
+
+.c{$(OUTDIR)}.obj:
+ cd $(OBJDIR)
+ set PATH=.
+ $(CC) $(CFLAGS) /c "$(SRCDIR)\$<"
+ set PATH=$(ENVPATH)
+ cd ..
+
+.cpp{$(OUTDIR)}.obj:
+ cd $(OBJDIR)
+ set PATH=.
+ $(CC) $(CFLAGS) /c "$(SRCDIR)\$<"
+ set PATH=$(ENVPATH)
+ cd ..
+
+$(OUTDIR)\BootDefs.i: BootDefs.h
+ cd $(OBJDIR)
+ set PATH=.
+ $(CC) $(CFLAGS) /D TC_ASM_PREPROCESS /P /EP "$(SRCDIR)\BootDefs.h"
+ set PATH=$(ENVPATH)
+ cd ..
+
+$(OUTDIR)\BootSector.bin: $(OUTDIR)\BootSector.obj
+ cd $(OBJDIR)
+ $(LD) $(LFLAGS) BootSector.obj,BootSector.bin,,,, >NUL:
+ -dd.exe conv=notrunc bs=512 if=BootSector.bin of=$(PROJ).flp 2>NUL:
+ cd ..
+
+$(OUTDIR)\Decompressor.com: $(OUTDIR)\BootCrt.obj $(OUTDIR)\Decompressor.obj
+ cd $(OBJDIR)
+ $(LD) $(LFLAGS) BootCrt.obj Decompressor.obj,Decompressor.com,Decompressor.map,$(MSVC16_ROOT)\lib\+slibce,,
+ -dd.exe conv=notrunc,sync bs=512 seek=1 if=Decompressor.com of=$(PROJ).flp 2>NUL:
+ cd ..
+
+$(OUTDIR)\$(PROJ).$(TARGETEXT): $(OBJS)
+ @echo Linking...
+ cd $(OBJDIR)
+
+ echo >NUL: @<<$(PROJ).crf2
+
+$(PROJ).$(TARGETEXT)
+$(PROJ).map
+$(MSVC16_ROOT)\lib\+
+$(LIBS)
+;
+<<
+ del $(PROJ).crf >NUL: 2>NUL:
+ for %F in ($(**F)) do @echo %F + >>$(PROJ).crf
+ type $(PROJ).crf2 >>$(PROJ).crf
+
+ $(LD) $(LFLAGS) @$(PROJ).crf
+ del $(PROJ).crf $(PROJ).crf2
+
+# Compress the Rescue Disk botloader for Cascades and Serpent since it is too big (size > 31232 bytes)
+!if DEFINED(RESCUE_DISK) && (!DEFINED (SINGLE_CIPHER) || ("$(SINGLE_CIPHER)" == "SERPENT"))
+ upx $(PROJ).$(TARGETEXT)
+!endif
+ gzip.exe -c -n --best $(PROJ).$(TARGETEXT) >$(PROJ).$(TARGETEXT).gz
+ -dd.exe conv=notrunc,sync bs=512 seek=5 if=$(PROJ).$(TARGETEXT).gz of=$(PROJ).flp 2>NUL:
+ cd ..
diff --git a/src/Boot/Windows/Platform.cpp b/src/Boot/Windows/Platform.cpp
index d9819cfa..0a45bba6 100644
--- a/src/Boot/Windows/Platform.cpp
+++ b/src/Boot/Windows/Platform.cpp
@@ -1,230 +1,230 @@
-/*
- Derived from source code of TrueCrypt 7.1a, which is
- Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed
- by the TrueCrypt License 3.0.
-
- Modifications and additions to the original source code (contained in this file)
- and all other portions of this file are Copyright (c) 2013-2016 IDRIX
- and are governed by the Apache License 2.0 the full text of which is
- contained in the file License.txt included in VeraCrypt binary and source
- code distribution packages.
-*/
-
-#include "Platform.h"
-#include "BootConsoleIo.h"
-
-
-uint64 operator+ (const uint64 &a, const uint64 &b)
-{
- int carry = 0;
- uint64 r;
-
- r.LowPart = a.LowPart + b.LowPart;
- __asm
- {
- jnc nocarry
- mov carry, 1
- nocarry:
- }
-
- r.HighPart = a.HighPart + b.HighPart + carry;
-
- return r;
-}
-
-uint64 operator+ (const uint64 &a, uint32 b)
-{
- uint64 b64;
- b64.HighPart = 0;
- b64.LowPart = b;
- return a + b64;
-}
-
-uint64 &operator+= (uint64 &a, const uint64 &b)
-{
- return a = a + b;
-}
-
-uint64 operator- (const uint64 &a, const uint64 &b)
-{
- int carry = 0;
- uint64 r;
-
- r.LowPart = a.LowPart - b.LowPart;
- __asm
- {
- jnc nocarry
- mov carry, 1
- nocarry:
- }
-
- r.HighPart = a.HighPart - b.HighPart - carry;
-
- return r;
-}
-
-uint64 operator- (const uint64 &a, uint32 b)
-{
- uint64 b64;
- b64.HighPart = 0;
- b64.LowPart = b;
- return a - b64;
-}
-
-uint64 &operator-= (uint64 &a, const uint64 &b)
-{
- return a = a - b;
-}
-
-uint64 operator>> (const uint64 &a, int shiftCount)
-{
- uint64 r = a;
-
- while (shiftCount--)
- {
- r.LowPart >>= 1;
-
- if ((byte) r.HighPart & 1)
- r.LowPart |= 0x80000000UL;
-
- r.HighPart >>= 1;
- }
-
- return r;
-}
-
-uint64 operator<< (const uint64 &a, int shiftCount)
-{
- uint64 r = a;
-
- while (shiftCount--)
- r += r;
-
- return r;
-}
-
-uint64 &operator++ (uint64 &a)
-{
- uint64 b;
- b.HighPart = 0;
- b.LowPart = 1;
-
- return a += b;
-}
-
-bool operator== (const uint64 &a, const uint64 &b)
-{
- return a.HighPart == b.HighPart && a.LowPart == b.LowPart;
-}
-
-bool operator> (const uint64 &a, const uint64 &b)
-{
- return (a.HighPart > b.HighPart) || (a.HighPart == b.HighPart && a.LowPart > b.LowPart);
-}
-
-bool operator< (const uint64 &a, const uint64 &b)
-{
- return (a.HighPart < b.HighPart) || (a.HighPart == b.HighPart && a.LowPart < b.LowPart);
-}
-
-bool operator>= (const uint64 &a, const uint64 &b)
-{
- return a > b || a == b;
-}
-
-bool operator<= (const uint64 &a, const uint64 &b)
-{
- return a < b || a == b;
-}
-
-bool TestInt64 ()
-{
- uint64 a, b, c;
- a.HighPart = 0x00112233UL;
- a.LowPart = 0xabcd1234UL;
-
- b.HighPart = 0x00ffeeddUL;
- b.LowPart = 0xffffFFFFUL;
-
- a += b;
- a -= b;
-
- ++a;
-
- b = b + (uint32) 1UL;
-
- c = (a - ((a + b) >> 32) - (uint32) 1UL);
- if (c.HighPart != 0x112233UL || c.LowPart != 0xAABC0123UL)
- return false;
-
- c = c << 9;
- return c.HighPart == 0x22446755UL && c.LowPart == 0x78024600UL;
-}
-
-
-void CopyMemory (void *source, uint16 destSegment, uint16 destOffset, uint16 blockSize)
-{
- __asm
- {
- push es
- mov si, ss:source
- mov es, ss:destSegment
- mov di, ss:destOffset
- mov cx, ss:blockSize
- cld
- rep movsb
- pop es
- }
-}
-
-
-void CopyMemory (uint16 sourceSegment, uint16 sourceOffset, void *destination, uint16 blockSize)
-{
- __asm
- {
- push ds
- push es
- mov ax, ds
- mov es, ax
- mov di, ss:destination
- mov si, ss:sourceOffset
- mov cx, ss:blockSize
- mov ds, ss:sourceSegment
- cld
- rep movsb
- pop es
- pop ds
- }
-}
-
-
-void EraseMemory (void *memory, int size)
-{
- memset (memory, 0, size);
-}
-
-
-uint32 GetLinearAddress (uint16 segment, uint16 offset)
-{
- return (uint32 (segment) << 4) + offset;
-}
-
-
-bool RegionsIntersect (const uint64 &start1, uint32 length1, const uint64 &start2, const uint64 &end2)
-{
- uint64 end1 = start1 + length1 - 1UL;
- uint64 intersectEnd = (end1 <= end2) ? end1 : end2;
-
- uint64 intersectStart = (start1 >= start2) ? start1 : start2;
- if (intersectStart > intersectEnd)
- return false;
-
- return (intersectEnd + 1UL - intersectStart).LowPart != 0;
-}
-
-
-void ThrowFatalException (int line)
-{
- PrintChar ('#'); Print (line);
- while (1);
-}
+/*
+ Derived from source code of TrueCrypt 7.1a, which is
+ Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed
+ by the TrueCrypt License 3.0.
+
+ Modifications and additions to the original source code (contained in this file)
+ and all other portions of this file are Copyright (c) 2013-2016 IDRIX
+ and are governed by the Apache License 2.0 the full text of which is
+ contained in the file License.txt included in VeraCrypt binary and source
+ code distribution packages.
+*/
+
+#include "Platform.h"
+#include "BootConsoleIo.h"
+
+
+uint64 operator+ (const uint64 &a, const uint64 &b)
+{
+ int carry = 0;
+ uint64 r;
+
+ r.LowPart = a.LowPart + b.LowPart;
+ __asm
+ {
+ jnc nocarry
+ mov carry, 1
+ nocarry:
+ }
+
+ r.HighPart = a.HighPart + b.HighPart + carry;
+
+ return r;
+}
+
+uint64 operator+ (const uint64 &a, uint32 b)
+{
+ uint64 b64;
+ b64.HighPart = 0;
+ b64.LowPart = b;
+ return a + b64;
+}
+
+uint64 &operator+= (uint64 &a, const uint64 &b)
+{
+ return a = a + b;
+}
+
+uint64 operator- (const uint64 &a, const uint64 &b)
+{
+ int carry = 0;
+ uint64 r;
+
+ r.LowPart = a.LowPart - b.LowPart;
+ __asm
+ {
+ jnc nocarry
+ mov carry, 1
+ nocarry:
+ }
+
+ r.HighPart = a.HighPart - b.HighPart - carry;
+
+ return r;
+}
+
+uint64 operator- (const uint64 &a, uint32 b)
+{
+ uint64 b64;
+ b64.HighPart = 0;
+ b64.LowPart = b;
+ return a - b64;
+}
+
+uint64 &operator-= (uint64 &a, const uint64 &b)
+{
+ return a = a - b;
+}
+
+uint64 operator>> (const uint64 &a, int shiftCount)
+{
+ uint64 r = a;
+
+ while (shiftCount--)
+ {
+ r.LowPart >>= 1;
+
+ if ((byte) r.HighPart & 1)
+ r.LowPart |= 0x80000000UL;
+
+ r.HighPart >>= 1;
+ }
+
+ return r;
+}
+
+uint64 operator<< (const uint64 &a, int shiftCount)
+{
+ uint64 r = a;
+
+ while (shiftCount--)
+ r += r;
+
+ return r;
+}
+
+uint64 &operator++ (uint64 &a)
+{
+ uint64 b;
+ b.HighPart = 0;
+ b.LowPart = 1;
+
+ return a += b;
+}
+
+bool operator== (const uint64 &a, const uint64 &b)
+{
+ return a.HighPart == b.HighPart && a.LowPart == b.LowPart;
+}
+
+bool operator> (const uint64 &a, const uint64 &b)
+{
+ return (a.HighPart > b.HighPart) || (a.HighPart == b.HighPart && a.LowPart > b.LowPart);
+}
+
+bool operator< (const uint64 &a, const uint64 &b)
+{
+ return (a.HighPart < b.HighPart) || (a.HighPart == b.HighPart && a.LowPart < b.LowPart);
+}
+
+bool operator>= (const uint64 &a, const uint64 &b)
+{
+ return a > b || a == b;
+}
+
+bool operator<= (const uint64 &a, const uint64 &b)
+{
+ return a < b || a == b;
+}
+
+bool TestInt64 ()
+{
+ uint64 a, b, c;
+ a.HighPart = 0x00112233UL;
+ a.LowPart = 0xabcd1234UL;
+
+ b.HighPart = 0x00ffeeddUL;
+ b.LowPart = 0xffffFFFFUL;
+
+ a += b;
+ a -= b;
+
+ ++a;
+
+ b = b + (uint32) 1UL;
+
+ c = (a - ((a + b) >> 32) - (uint32) 1UL);
+ if (c.HighPart != 0x112233UL || c.LowPart != 0xAABC0123UL)
+ return false;
+
+ c = c << 9;
+ return c.HighPart == 0x22446755UL && c.LowPart == 0x78024600UL;
+}
+
+
+void CopyMemory (void *source, uint16 destSegment, uint16 destOffset, uint16 blockSize)
+{
+ __asm
+ {
+ push es
+ mov si, ss:source
+ mov es, ss:destSegment
+ mov di, ss:destOffset
+ mov cx, ss:blockSize
+ cld
+ rep movsb
+ pop es
+ }
+}
+
+
+void CopyMemory (uint16 sourceSegment, uint16 sourceOffset, void *destination, uint16 blockSize)
+{
+ __asm
+ {
+ push ds
+ push es
+ mov ax, ds
+ mov es, ax
+ mov di, ss:destination
+ mov si, ss:sourceOffset
+ mov cx, ss:blockSize
+ mov ds, ss:sourceSegment
+ cld
+ rep movsb
+ pop es
+ pop ds
+ }
+}
+
+
+void EraseMemory (void *memory, int size)
+{
+ memset (memory, 0, size);
+}
+
+
+uint32 GetLinearAddress (uint16 segment, uint16 offset)
+{
+ return (uint32 (segment) << 4) + offset;
+}
+
+
+bool RegionsIntersect (const uint64 &start1, uint32 length1, const uint64 &start2, const uint64 &end2)
+{
+ uint64 end1 = start1 + length1 - 1UL;
+ uint64 intersectEnd = (end1 <= end2) ? end1 : end2;
+
+ uint64 intersectStart = (start1 >= start2) ? start1 : start2;
+ if (intersectStart > intersectEnd)
+ return false;
+
+ return (intersectEnd + 1UL - intersectStart).LowPart != 0;
+}
+
+
+void ThrowFatalException (int line)
+{
+ PrintChar ('#'); Print (line);
+ while (1);
+}
diff --git a/src/Boot/Windows/Platform.h b/src/Boot/Windows/Platform.h
index 2fa532ce..a8e83bec 100644
--- a/src/Boot/Windows/Platform.h
+++ b/src/Boot/Windows/Platform.h
@@ -1,116 +1,116 @@
-/*
- Derived from source code of TrueCrypt 7.1a, which is
- Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed
- by the TrueCrypt License 3.0.
-
- Modifications and additions to the original source code (contained in this file)
- and all other portions of this file are Copyright (c) 2013-2016 IDRIX
- and are governed by the Apache License 2.0 the full text of which is
- contained in the file License.txt included in VeraCrypt binary and source
- code distribution packages.
-*/
-
-#ifndef TC_HEADER_Boot_Platform
-#define TC_HEADER_Boot_Platform
-
-#pragma warning (disable: 4018 4102 4704 4769)
-
-#include "TCdefs.h"
-#include <memory.h>
-
-typedef char bool;
-#define false 0
-#define true 1
-
-#define nullptr 0
-#define NULL 0
-
-typedef UINT64_STRUCT uint64;
-
-#define array_capacity(arr) (sizeof (arr) / sizeof ((arr)[0]))
-
-#define TC_TO_STRING2(n) #n
-#define TC_TO_STRING(n) TC_TO_STRING2(n)
-
-
-#define TC_X86_CARRY_FLAG 0x1
-
-#define TC_ASM_EMIT(A,B) __asm _emit 0x##A __asm _emit 0x##B
-#define TC_ASM_EMIT3(A,B,C) __asm _emit 0x##A __asm _emit 0x##B __asm _emit 0x##C
-#define TC_ASM_EMIT4(A,B,C,D) __asm _emit 0x##A __asm _emit 0x##B __asm _emit 0x##C __asm _emit 0x##D
-
-#define TC_ASM_MOV_EAX_DI TC_ASM_EMIT3 (66, 8B, 05)
-#define TC_ASM_MOV_EBX_DI TC_ASM_EMIT3 (66, 8B, 1D)
-#define TC_ASM_MOV_ECX_DI TC_ASM_EMIT3 (66, 8B, 0D)
-#define TC_ASM_MOV_EDX_DI TC_ASM_EMIT3 (66, 8B, 15)
-
-#define TC_ASM_MOV_DI_EAX TC_ASM_EMIT3 (66, 89, 05)
-#define TC_ASM_MOV_DI_EBX TC_ASM_EMIT3 (66, 89, 1D)
-#define TC_ASM_MOV_DI_ECX TC_ASM_EMIT3 (66, 89, 0D)
-#define TC_ASM_MOV_DI_EDX TC_ASM_EMIT3 (66, 89, 15)
-
-
-#pragma pack(1)
-
-struct Registers
-{
- uint16 Flags;
-
- union
- {
- uint32 EAX;
- struct { uint16 AX; uint16 EAXH; };
- };
-
- union
- {
- uint32 EBX;
- struct { uint16 BX; uint16 EBXH; };
- };
-
- union
- {
- uint32 ECX;
- struct { uint16 CX; uint16 ECXH; };
- };
-
- union
- {
- uint32 EDX;
- struct { uint16 DX; uint16 EDXH; };
- };
-
- uint16 DI;
- uint16 SI;
- uint16 DS;
- uint16 ES;
- uint16 SS;
-};
-
-#pragma pack()
-
-
-uint64 operator+ (const uint64 &a, const uint64 &b);
-uint64 operator+ (const uint64 &a, uint32 b);
-uint64 &operator+= (uint64 &a, const uint64 &b);
-uint64 operator- (const uint64 &a, const uint64 &b);
-uint64 operator- (const uint64 &a, uint32 b);
-uint64 &operator-= (uint64 &a, const uint64 &b);
-uint64 operator>> (const uint64 &a, int shiftCount);
-uint64 operator<< (const uint64 &a, int shiftCount);
-uint64 &operator++ (uint64 &a);
-bool operator== (const uint64 &a, const uint64 &b);
-bool operator> (const uint64 &a, const uint64 &b);
-bool operator< (const uint64 &a, const uint64 &b);
-bool operator>= (const uint64 &a, const uint64 &b);
-bool operator<= (const uint64 &a, const uint64 &b);
-
-void CopyMemory (void *source, uint16 destSegment, uint16 destOffset, uint16 blockSize);
-void CopyMemory (uint16 sourceSegment, uint16 sourceOffset, void *destination, uint16 blockSize);
-extern "C" void EraseMemory (void *memory, int size);
-uint32 GetLinearAddress (uint16 segment, uint16 offset);
-bool RegionsIntersect (const uint64 &start1, uint32 length1, const uint64 &start2, const uint64 &end2);
-bool TestInt64 ();
-extern "C" void ThrowFatalException (int line);
-
-#endif // TC_HEADER_Boot_Platform
+/*
+ Derived from source code of TrueCrypt 7.1a, which is
+ Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed
+ by the TrueCrypt License 3.0.
+
+ Modifications and additions to the original source code (contained in this file)
+ and all other portions of this file are Copyright (c) 2013-2016 IDRIX
+ and are governed by the Apache License 2.0 the full text of which is
+ contained in the file License.txt included in VeraCrypt binary and source
+ code distribution packages.
+*/
+
+#ifndef TC_HEADER_Boot_Platform
+#define TC_HEADER_Boot_Platform
+
+#pragma warning (disable: 4018 4102 4704 4769)
+
+#include "TCdefs.h"
+#include <memory.h>
+
+typedef char bool;
+#define false 0
+#define true 1
+
+#define nullptr 0
+#define NULL 0
+
+typedef UINT64_STRUCT uint64;
+
+#define array_capacity(arr) (sizeof (arr) / sizeof ((arr)[0]))
+
+#define TC_TO_STRING2(n) #n
+#define TC_TO_STRING(n) TC_TO_STRING2(n)
+
+
+#define TC_X86_CARRY_FLAG 0x1
+
+#define TC_ASM_EMIT(A,B) __asm _emit 0x##A __asm _emit 0x##B
+#define TC_ASM_EMIT3(A,B,C) __asm _emit 0x##A __asm _emit 0x##B __asm _emit 0x##C
+#define TC_ASM_EMIT4(A,B,C,D) __asm _emit 0x##A __asm _emit 0x##B __asm _emit 0x##C __asm _emit 0x##D
+
+#define TC_ASM_MOV_EAX_DI TC_ASM_EMIT3 (66, 8B, 05)
+#define TC_ASM_MOV_EBX_DI TC_ASM_EMIT3 (66, 8B, 1D)
+#define TC_ASM_MOV_ECX_DI TC_ASM_EMIT3 (66, 8B, 0D)
+#define TC_ASM_MOV_EDX_DI TC_ASM_EMIT3 (66, 8B, 15)
+
+#define TC_ASM_MOV_DI_EAX TC_ASM_EMIT3 (66, 89, 05)
+#define TC_ASM_MOV_DI_EBX TC_ASM_EMIT3 (66, 89, 1D)
+#define TC_ASM_MOV_DI_ECX TC_ASM_EMIT3 (66, 89, 0D)
+#define TC_ASM_MOV_DI_EDX TC_ASM_EMIT3 (66, 89, 15)
+
+
+#pragma pack(1)
+
+struct Registers
+{
+ uint16 Flags;
+
+ union
+ {
+ uint32 EAX;
+ struct { uint16 AX; uint16 EAXH; };
+ };
+
+ union
+ {
+ uint32 EBX;
+ struct { uint16 BX; uint16 EBXH; };
+ };
+
+ union
+ {
+ uint32 ECX;
+ struct { uint16 CX; uint16 ECXH; };
+ };
+
+ union
+ {
+ uint32 EDX;
+ struct { uint16 DX; uint16 EDXH; };
+ };
+
+ uint16 DI;
+ uint16 SI;
+ uint16 DS;
+ uint16 ES;
+ uint16 SS;
+};
+
+#pragma pack()
+
+
+uint64 operator+ (const uint64 &a, const uint64 &b);
+uint64 operator+ (const uint64 &a, uint32 b);
+uint64 &operator+= (uint64 &a, const uint64 &b);
+uint64 operator- (const uint64 &a, const uint64 &b);
+uint64 operator- (const uint64 &a, uint32 b);
+uint64 &operator-= (uint64 &a, const uint64 &b);
+uint64 operator>> (const uint64 &a, int shiftCount);
+uint64 operator<< (const uint64 &a, int shiftCount);
+uint64 &operator++ (uint64 &a);
+bool operator== (const uint64 &a, const uint64 &b);
+bool operator> (const uint64 &a, const uint64 &b);
+bool operator< (const uint64 &a, const uint64 &b);
+bool operator>= (const uint64 &a, const uint64 &b);
+bool operator<= (const uint64 &a, const uint64 &b);
+
+void CopyMemory (void *source, uint16 destSegment, uint16 destOffset, uint16 blockSize);
+void CopyMemory (uint16 sourceSegment, uint16 sourceOffset, void *destination, uint16 blockSize);
+extern "C" void EraseMemory (void *memory, int size);
+uint32 GetLinearAddress (uint16 segment, uint16 offset);
+bool RegionsIntersect (const uint64 &start1, uint32 length1, const uint64 &start2, const uint64 &end2);
+bool TestInt64 ();
+extern "C" void ThrowFatalException (int line);
+
+#endif // TC_HEADER_Boot_Platform