VeraCrypt
aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Boot/EFI/DcsBoot.efibin24088 -> 24088 bytes
-rw-r--r--src/Boot/EFI/DcsBoot32.efibin20472 -> 20472 bytes
-rw-r--r--src/Boot/EFI/DcsCfg.efibin953400 -> 953528 bytes
-rw-r--r--src/Boot/EFI/DcsCfg32.efibin816024 -> 816152 bytes
-rw-r--r--src/Boot/EFI/DcsInfo.efibin37144 -> 37144 bytes
-rw-r--r--src/Boot/EFI/DcsInfo32.efibin33880 -> 33880 bytes
-rw-r--r--src/Boot/EFI/DcsInt.efibin911864 -> 912184 bytes
-rw-r--r--src/Boot/EFI/DcsInt32.efibin794936 -> 795160 bytes
-rw-r--r--src/Boot/EFI/DcsRe.efibin28472 -> 28472 bytes
-rw-r--r--src/Boot/EFI/DcsRe32.efibin24056 -> 24056 bytes
-rw-r--r--src/Boot/EFI/LegacySpeaker.efibin9816 -> 9816 bytes
-rw-r--r--src/Boot/EFI/LegacySpeaker32.efibin9560 -> 9560 bytes
-rw-r--r--src/Boot/Windows/BootSector.asm2
-rw-r--r--src/Build/CMakeLists.txt58
-rw-r--r--src/Build/Resources/MacOSX/Info.plist.legacy.xml2
-rw-r--r--src/Build/Resources/MacOSX/Info.plist.xml2
-rwxr-xr-xsrc/Build/build_cmake_deb.sh40
-rw-r--r--src/Build/build_cmake_opensuse.sh14
-rw-r--r--src/Build/build_cmake_rpm_gtk2.sh10
-rw-r--r--src/Build/build_cmake_rpm_gtk3.sh10
-rwxr-xr-xsrc/Build/build_veracrypt_freebsd.sh6
-rwxr-xr-xsrc/Build/build_veracrypt_linux.sh6
-rwxr-xr-xsrc/Build/build_veracrypt_linux_no_sse2.sh6
-rwxr-xr-xsrc/Build/build_veracrypt_macosx.sh2
-rw-r--r--src/Common/BaseCom.cpp4
-rw-r--r--src/Common/BootEncryption.cpp23
-rw-r--r--src/Common/Cmdline.c4
-rw-r--r--src/Common/Crypto.c11
-rw-r--r--src/Common/Dlgcode.c851
-rw-r--r--src/Common/Dlgcode.h91
-rw-r--r--src/Common/EncryptionThreadPool.c132
-rw-r--r--src/Common/EncryptionThreadPool.h4
-rw-r--r--src/Common/Fat.c41
-rw-r--r--src/Common/Format.c264
-rw-r--r--src/Common/Format.h2
-rw-r--r--src/Common/Language.c1
-rw-r--r--src/Common/Language.xml14
-rw-r--r--src/Common/SecurityToken.cpp20
-rw-r--r--src/Common/SecurityToken.h8
-rw-r--r--src/Common/Tcdefs.h23
-rw-r--r--src/Common/Zip.vcxproj24
-rw-r--r--src/Common/Zip.vcxproj.filters74
-rw-r--r--src/Common/libzip/LICENSE2
-rw-r--r--src/Common/libzip/NEWS.md50
-rw-r--r--src/Common/libzip/compat.h25
-rw-r--r--src/Common/libzip/config.h2
-rw-r--r--src/Common/libzip/mkstemp.c153
-rw-r--r--src/Common/libzip/zip.h306
-rw-r--r--src/Common/libzip/zip_add.c2
-rw-r--r--src/Common/libzip/zip_add_dir.c2
-rw-r--r--src/Common/libzip/zip_add_entry.c2
-rw-r--r--src/Common/libzip/zip_algorithm_deflate.c21
-rw-r--r--src/Common/libzip/zip_buffer.c2
-rw-r--r--src/Common/libzip/zip_close.c122
-rw-r--r--src/Common/libzip/zip_delete.c2
-rw-r--r--src/Common/libzip/zip_dir_add.c2
-rw-r--r--src/Common/libzip/zip_dirent.c125
-rw-r--r--src/Common/libzip/zip_discard.c2
-rw-r--r--src/Common/libzip/zip_entry.c2
-rw-r--r--src/Common/libzip/zip_err_str.c72
-rw-r--r--src/Common/libzip/zip_error.c2
-rw-r--r--src/Common/libzip/zip_error_clear.c2
-rw-r--r--src/Common/libzip/zip_error_get.c2
-rw-r--r--src/Common/libzip/zip_error_get_sys_type.c2
-rw-r--r--src/Common/libzip/zip_error_strerror.c3
-rw-r--r--src/Common/libzip/zip_error_to_str.c4
-rw-r--r--src/Common/libzip/zip_extra_field.c2
-rw-r--r--src/Common/libzip/zip_extra_field_api.c2
-rw-r--r--src/Common/libzip/zip_fclose.c2
-rw-r--r--src/Common/libzip/zip_fdopen.c2
-rw-r--r--src/Common/libzip/zip_file_add.c2
-rw-r--r--src/Common/libzip/zip_file_error_clear.c2
-rw-r--r--src/Common/libzip/zip_file_error_get.c2
-rw-r--r--src/Common/libzip/zip_file_get_comment.c2
-rw-r--r--src/Common/libzip/zip_file_get_external_attributes.c2
-rw-r--r--src/Common/libzip/zip_file_get_offset.c5
-rw-r--r--src/Common/libzip/zip_file_rename.c2
-rw-r--r--src/Common/libzip/zip_file_replace.c2
-rw-r--r--src/Common/libzip/zip_file_set_comment.c2
-rw-r--r--src/Common/libzip/zip_file_set_external_attributes.c2
-rw-r--r--src/Common/libzip/zip_file_set_mtime.c36
-rw-r--r--src/Common/libzip/zip_file_strerror.c2
-rw-r--r--src/Common/libzip/zip_filerange_crc.c2
-rw-r--r--src/Common/libzip/zip_fopen.c2
-rw-r--r--src/Common/libzip/zip_fopen_encrypted.c2
-rw-r--r--src/Common/libzip/zip_fopen_index.c5
-rw-r--r--src/Common/libzip/zip_fopen_index_encrypted.c2
-rw-r--r--src/Common/libzip/zip_fread.c2
-rw-r--r--src/Common/libzip/zip_get_archive_comment.c2
-rw-r--r--src/Common/libzip/zip_get_archive_flag.c2
-rw-r--r--src/Common/libzip/zip_get_encryption_implementation.c15
-rw-r--r--src/Common/libzip/zip_get_file_comment.c2
-rw-r--r--src/Common/libzip/zip_get_name.c2
-rw-r--r--src/Common/libzip/zip_get_num_entries.c2
-rw-r--r--src/Common/libzip/zip_get_num_files.c2
-rw-r--r--src/Common/libzip/zip_hash.c2
-rw-r--r--src/Common/libzip/zip_io_util.c2
-rw-r--r--src/Common/libzip/zip_memdup.c2
-rw-r--r--src/Common/libzip/zip_name_locate.c2
-rw-r--r--src/Common/libzip/zip_new.c2
-rw-r--r--src/Common/libzip/zip_open.c39
-rw-r--r--src/Common/libzip/zip_pkware.c112
-rw-r--r--src/Common/libzip/zip_progress.c172
-rw-r--r--src/Common/libzip/zip_rename.c4
-rw-r--r--src/Common/libzip/zip_replace.c2
-rw-r--r--src/Common/libzip/zip_set_archive_comment.c2
-rw-r--r--src/Common/libzip/zip_set_archive_flag.c2
-rw-r--r--src/Common/libzip/zip_set_default_password.c2
-rw-r--r--src/Common/libzip/zip_set_file_comment.c4
-rw-r--r--src/Common/libzip/zip_set_file_compression.c2
-rw-r--r--src/Common/libzip/zip_set_name.c2
-rw-r--r--src/Common/libzip/zip_source_accept_empty.c (renamed from src/Common/libzip/zip_source_get_compression_flags.c)33
-rw-r--r--src/Common/libzip/zip_source_begin_write.c2
-rw-r--r--src/Common/libzip/zip_source_begin_write_cloning.c2
-rw-r--r--src/Common/libzip/zip_source_buffer.c59
-rw-r--r--src/Common/libzip/zip_source_call.c2
-rw-r--r--src/Common/libzip/zip_source_close.c2
-rw-r--r--src/Common/libzip/zip_source_commit_write.c2
-rw-r--r--src/Common/libzip/zip_source_compress.c40
-rw-r--r--src/Common/libzip/zip_source_crc.c6
-rw-r--r--src/Common/libzip/zip_source_deflate.c415
-rw-r--r--src/Common/libzip/zip_source_error.c2
-rw-r--r--src/Common/libzip/zip_source_file.h90
-rw-r--r--src/Common/libzip/zip_source_file_common.c378
-rw-r--r--src/Common/libzip/zip_source_file_stdio.c208
-rw-r--r--src/Common/libzip/zip_source_file_stdio.h (renamed from src/Common/libzip/zip_source_file.c)38
-rw-r--r--src/Common/libzip/zip_source_file_win32.c230
-rw-r--r--src/Common/libzip/zip_source_file_win32.h74
-rw-r--r--src/Common/libzip/zip_source_file_win32_named.c268
-rw-r--r--src/Common/libzip/zip_source_file_win32_utf16.c117
-rw-r--r--src/Common/libzip/zip_source_file_win32_utf8.c (renamed from src/Common/libzip/zip_source_win32utf8.c)37
-rw-r--r--src/Common/libzip/zip_source_filep.c658
-rw-r--r--src/Common/libzip/zip_source_free.c2
-rw-r--r--src/Common/libzip/zip_source_function.c2
-rw-r--r--src/Common/libzip/zip_source_get_file_attributes.c104
-rw-r--r--src/Common/libzip/zip_source_is_deleted.c2
-rw-r--r--src/Common/libzip/zip_source_layered.c2
-rw-r--r--src/Common/libzip/zip_source_open.c2
-rw-r--r--src/Common/libzip/zip_source_pkware_decode.c (renamed from src/Common/libzip/zip_source_pkware.c)137
-rw-r--r--src/Common/libzip/zip_source_pkware_encode.c249
-rw-r--r--src/Common/libzip/zip_source_read.c2
-rw-r--r--src/Common/libzip/zip_source_remove.c2
-rw-r--r--src/Common/libzip/zip_source_rollback_write.c2
-rw-r--r--src/Common/libzip/zip_source_seek.c2
-rw-r--r--src/Common/libzip/zip_source_seek_write.c2
-rw-r--r--src/Common/libzip/zip_source_stat.c2
-rw-r--r--src/Common/libzip/zip_source_supports.c2
-rw-r--r--src/Common/libzip/zip_source_tell.c2
-rw-r--r--src/Common/libzip/zip_source_tell_write.c2
-rw-r--r--src/Common/libzip/zip_source_win32a.c125
-rw-r--r--src/Common/libzip/zip_source_win32handle.c597
-rw-r--r--src/Common/libzip/zip_source_win32w.c149
-rw-r--r--src/Common/libzip/zip_source_window.c27
-rw-r--r--src/Common/libzip/zip_source_write.c2
-rw-r--r--src/Common/libzip/zip_source_zip.c3
-rw-r--r--src/Common/libzip/zip_source_zip_new.c40
-rw-r--r--src/Common/libzip/zip_stat.c2
-rw-r--r--src/Common/libzip/zip_stat_index.c11
-rw-r--r--src/Common/libzip/zip_stat_init.c2
-rw-r--r--src/Common/libzip/zip_strerror.c2
-rw-r--r--src/Common/libzip/zip_string.c6
-rw-r--r--src/Common/libzip/zip_unchange.c2
-rw-r--r--src/Common/libzip/zip_unchange_all.c4
-rw-r--r--src/Common/libzip/zip_unchange_archive.c2
-rw-r--r--src/Common/libzip/zip_unchange_data.c2
-rw-r--r--src/Common/libzip/zip_utf-8.c2
-rw-r--r--src/Common/libzip/zipint.h72
-rw-r--r--src/Common/libzip/zipwin32.h85
-rw-r--r--src/Core/Core.h4
-rw-r--r--src/Core/CoreBase.cpp6
-rw-r--r--src/Core/RandomNumberGenerator.cpp33
-rw-r--r--src/Core/RandomNumberGenerator.h2
-rw-r--r--src/Core/Unix/CoreService.cpp32
-rw-r--r--src/Core/Unix/CoreService.h12
-rw-r--r--src/Core/Unix/CoreUnix.cpp2
-rw-r--r--src/Core/Unix/FreeBSD/CoreFreeBSD.cpp4
-rw-r--r--src/Core/Unix/Linux/CoreLinux.cpp4
-rw-r--r--src/Core/Unix/MacOSX/CoreMacOSX.cpp4
-rw-r--r--src/Core/Unix/Solaris/CoreSolaris.cpp4
-rw-r--r--src/Core/VolumeCreator.h69
-rw-r--r--src/Crypto/Aes_hw_cpu.h2
-rw-r--r--src/Crypto/Aeskey.c13
-rw-r--r--src/Crypto/Camellia.c2
-rw-r--r--src/Crypto/Camellia.h2
-rw-r--r--src/Crypto/Sha2.c4
-rw-r--r--src/Crypto/Sha2.h2
-rw-r--r--src/Crypto/Streebog.c113
-rw-r--r--src/Crypto/Twofish.c8
-rw-r--r--src/Crypto/Twofish.h4
-rw-r--r--src/Crypto/Whirlpool.c1
-rw-r--r--src/Crypto/cpu.c22
-rw-r--r--src/Crypto/jitterentropy-base-user.h2
-rw-r--r--src/Driver/DriveFilter.c5
-rw-r--r--src/Driver/Driver.rc4
-rw-r--r--src/Driver/Fuse/FuseService.cpp2
-rw-r--r--src/Driver/Fuse/FuseService.h2
-rw-r--r--src/Driver/Ntdriver.c145
-rw-r--r--src/Driver/Ntdriver.h4
-rw-r--r--src/Driver/Ntvol.c4
-rw-r--r--src/ExpandVolume/ExpandVolume.c46
-rw-r--r--src/ExpandVolume/ExpandVolume.rc8
-rw-r--r--src/ExpandVolume/InitDataArea.c32
-rw-r--r--src/ExpandVolume/WinMain.cpp93
-rw-r--r--src/Format/Format.rc12
-rw-r--r--src/Format/FormatCom.cpp43
-rw-r--r--src/Format/FormatCom.h1
-rw-r--r--src/Format/FormatCom.idl4
-rw-r--r--src/Format/InPlace.c58
-rw-r--r--src/Format/Tcformat.c225
-rw-r--r--src/Format/VeraCrypt_Wizard.bmpbin190998 -> 193446 bytes
-rw-r--r--src/Main/CommandLineInterface.cpp6
-rw-r--r--src/Main/CommandLineInterface.h2
-rw-r--r--src/Main/Forms/AboutDialog.cpp6
-rw-r--r--src/Main/Forms/MainFrame.cpp16
-rw-r--r--src/Main/Forms/MainFrame.h36
-rw-r--r--src/Main/Forms/PreferencesDialog.cpp2
-rw-r--r--src/Main/Forms/PreferencesDialog.h2
-rw-r--r--src/Main/Forms/ProgressWizardPage.h2
-rw-r--r--src/Main/Forms/VolumeCreationProgressWizardPage.h2
-rw-r--r--src/Main/Forms/VolumeCreationWizard.cpp179
-rw-r--r--src/Main/Forms/VolumeCreationWizard.h6
-rw-r--r--src/Main/Forms/VolumeFormatOptionsWizardPage.cpp22
-rw-r--r--src/Main/Forms/VolumeFormatOptionsWizardPage.h2
-rw-r--r--src/Main/Forms/VolumeSizeWizardPage.cpp2
-rwxr-xr-xsrc/Main/GraphicUserInterface.cpp10
-rw-r--r--src/Main/GraphicUserInterface.h4
-rwxr-xr-xsrc/Main/Main.make4
-rw-r--r--src/Main/TextUserInterface.cpp41
-rw-r--r--src/Main/TextUserInterface.h6
-rw-r--r--src/Main/UserPreferences.cpp4
-rw-r--r--src/Main/Xml.h4
-rw-r--r--src/Makefile4
-rw-r--r--src/Mount/MainCom.cpp20
-rw-r--r--src/Mount/MainCom.idl16
-rw-r--r--src/Mount/Mount.c370
-rw-r--r--src/Mount/Mount.rc61
-rw-r--r--src/Mount/Mount.vcxproj.user3
-rw-r--r--src/Mount/Resource.h6
-rw-r--r--src/Platform/Buffer.cpp2
-rw-r--r--src/Platform/File.h6
-rw-r--r--src/Platform/Memory.cpp6
-rw-r--r--src/Platform/Memory.h2
-rw-r--r--src/Platform/SharedPtr.h17
-rw-r--r--src/Platform/StringConverter.cpp2
-rw-r--r--src/Platform/Unix/Process.cpp2
-rw-r--r--src/Readme.txt6
-rw-r--r--src/Release/Setup Files/veracrypt-x64.catbin10607 -> 10637 bytes
-rw-r--r--src/Release/Setup Files/veracrypt-x64.sysbin831320 -> 831616 bytes
-rw-r--r--src/Release/Setup Files/veracrypt.Inf4
-rw-r--r--src/Release/Setup Files/veracrypt.catbin10765 -> 10570 bytes
-rw-r--r--src/Release/Setup Files/veracrypt.sysbin768560 -> 798080 bytes
-rw-r--r--src/Setup/ComSetup.cpp12
-rwxr-xr-xsrc/Setup/MacOSX/veracrypt.pkgproj4
-rwxr-xr-xsrc/Setup/MacOSX/veracrypt_Legacy.pkgproj4
-rw-r--r--src/Setup/Portable.rc8
-rw-r--r--src/Setup/Setup.c9
-rw-r--r--src/Setup/Setup.rc8
-rw-r--r--src/Setup/Wizard.c26
-rw-r--r--src/Setup/Wizard.h1
-rw-r--r--src/Signing/DigiCert_Assured_ID_Code_Signing_CA.cerbin0 -> 1703 bytes
-rw-r--r--src/Signing/DigiCert_Assured_ID_MS_Cross_Cert.crt30
-rw-r--r--src/Signing/DigiCert_High_Assurance_Code_Signing_CA.cerbin1734 -> 0 bytes
-rw-r--r--src/Signing/DigiCert_High_Assurance_MS_Cross_Cert.crt30
-rw-r--r--src/Signing/GlobalSign_R3Cross.cer30
-rw-r--r--src/Signing/sign-sha256.bat62
-rw-r--r--src/Signing/sign.bat17
-rw-r--r--src/Signing/sign_test.bat6
-rw-r--r--src/Signing/sign_test_debug.bat6
-rw-r--r--src/Volume/Cipher.cpp16
-rw-r--r--src/Volume/EncryptionThreadPool.cpp4
-rw-r--r--src/Volume/EncryptionThreadPool.h2
-rw-r--r--src/Volume/Keyfile.cpp2
272 files changed, 6056 insertions, 3583 deletions
diff --git a/src/Boot/EFI/DcsBoot.efi b/src/Boot/EFI/DcsBoot.efi
index 185c6a0..0fcd48e 100644
--- a/src/Boot/EFI/DcsBoot.efi
+++ b/src/Boot/EFI/DcsBoot.efi
Binary files differ
diff --git a/src/Boot/EFI/DcsBoot32.efi b/src/Boot/EFI/DcsBoot32.efi
index 0e95330..48db0ca 100644
--- a/src/Boot/EFI/DcsBoot32.efi
+++ b/src/Boot/EFI/DcsBoot32.efi
Binary files differ
diff --git a/src/Boot/EFI/DcsCfg.efi b/src/Boot/EFI/DcsCfg.efi
index 32e2051..03c9761 100644
--- a/src/Boot/EFI/DcsCfg.efi
+++ b/src/Boot/EFI/DcsCfg.efi
Binary files differ
diff --git a/src/Boot/EFI/DcsCfg32.efi b/src/Boot/EFI/DcsCfg32.efi
index ace6379..22cc0d5 100644
--- a/src/Boot/EFI/DcsCfg32.efi
+++ b/src/Boot/EFI/DcsCfg32.efi
Binary files differ
diff --git a/src/Boot/EFI/DcsInfo.efi b/src/Boot/EFI/DcsInfo.efi
index 73ee873..6be1cb8 100644
--- a/src/Boot/EFI/DcsInfo.efi
+++ b/src/Boot/EFI/DcsInfo.efi
Binary files differ
diff --git a/src/Boot/EFI/DcsInfo32.efi b/src/Boot/EFI/DcsInfo32.efi
index f0ca687..006adfb 100644
--- a/src/Boot/EFI/DcsInfo32.efi
+++ b/src/Boot/EFI/DcsInfo32.efi
Binary files differ
diff --git a/src/Boot/EFI/DcsInt.efi b/src/Boot/EFI/DcsInt.efi
index 8ba5c28..a0c2975 100644
--- a/src/Boot/EFI/DcsInt.efi
+++ b/src/Boot/EFI/DcsInt.efi
Binary files differ
diff --git a/src/Boot/EFI/DcsInt32.efi b/src/Boot/EFI/DcsInt32.efi
index 85fa724..991885f 100644
--- a/src/Boot/EFI/DcsInt32.efi
+++ b/src/Boot/EFI/DcsInt32.efi
Binary files differ
diff --git a/src/Boot/EFI/DcsRe.efi b/src/Boot/EFI/DcsRe.efi
index 8e9ae8c..070cc97 100644
--- a/src/Boot/EFI/DcsRe.efi
+++ b/src/Boot/EFI/DcsRe.efi
Binary files differ
diff --git a/src/Boot/EFI/DcsRe32.efi b/src/Boot/EFI/DcsRe32.efi
index 081c19d..c4f2013 100644
--- a/src/Boot/EFI/DcsRe32.efi
+++ b/src/Boot/EFI/DcsRe32.efi
Binary files differ
diff --git a/src/Boot/EFI/LegacySpeaker.efi b/src/Boot/EFI/LegacySpeaker.efi
index 7c9f2d8..a1d14eb 100644
--- a/src/Boot/EFI/LegacySpeaker.efi
+++ b/src/Boot/EFI/LegacySpeaker.efi
Binary files differ
diff --git a/src/Boot/EFI/LegacySpeaker32.efi b/src/Boot/EFI/LegacySpeaker32.efi
index 8c4c8ca..1ec5ba6 100644
--- a/src/Boot/EFI/LegacySpeaker32.efi
+++ b/src/Boot/EFI/LegacySpeaker32.efi
Binary files differ
diff --git a/src/Boot/Windows/BootSector.asm b/src/Boot/Windows/BootSector.asm
index 351b2c6..0d2bbdc 100644
--- a/src/Boot/Windows/BootSector.asm
+++ b/src/Boot/Windows/BootSector.asm
@@ -139,7 +139,7 @@ checksum_ok:
push dx
; Decompress boot loader
- mov cx, word ptr [start + TC_BOOT_SECTOR_LOADER_LENGTH_OFFSET]
+ mov cx, word ptr cs:[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
diff --git a/src/Build/CMakeLists.txt b/src/Build/CMakeLists.txt
index 4724339..cf7e95c 100644
--- a/src/Build/CMakeLists.txt
+++ b/src/Build/CMakeLists.txt
@@ -11,8 +11,8 @@ elseif ( NOT DEFINED NOGUI )
endif()
# - Set version of the package
-set( FULL_VERSION "1.24-Hotfix2" )
-set( VERSION "1.24.8" )
+set( FULL_VERSION "1.24-Update7" )
+set( VERSION "1.24.23" )
set( RELEASE "1" )
# - Set PROJECT_NAME and CONFLICT_PACKAGE values
@@ -242,19 +242,29 @@ if ( ( PLATFORM STREQUAL "Debian" ) OR ( PLATFORM STREQUAL "Ubuntu" ) )
set( CPACK_DEBIAN_PACKAGE_RELEASE ${CPACK_PACKAGE_RELEASE} )
set( CPACK_DEBIAN_PACKAGE_ARCHITECTURE ${ARCHITECTURE} ) # mandatory
- # Link against gtk3 version of wxWidgets if >= Debian 10 or >= Ubuntu 18.04
- # Otherwise, link against gtk2 version of wxWidgets
- if ( ( ( PLATFORM STREQUAL "Debian" ) AND ( PLATFORM_VERSION VERSION_GREATER_EQUAL "10" ) )
- OR ( ( PLATFORM STREQUAL "Ubuntu" ) AND ( PLATFORM_VERSION VERSION_GREATER_EQUAL "18.04" ) ) )
-
- set( CPACK_DEBIAN_PACKAGE_DEPENDS "libwxgtk3.0-gtk3-0v5, libfuse2, dmsetup, sudo" )
-
+ if (NOGUI)
+ # Link against statically built wxWidgets so that we don't depend on any GTK library
+ set( CPACK_DEBIAN_PACKAGE_DEPENDS "libfuse2, dmsetup, sudo" )
else ()
-
- set( CPACK_DEBIAN_PACKAGE_DEPENDS "libwxgtk3.0-0v5, libfuse2, dmsetup, sudo" )
-
+ # Link against gtk3 version of wxWidgets if >= Debian 10 or >= Ubuntu 18.04
+ # Otherwise, link against gtk2 version of wxWidgets
+ if ( ( ( PLATFORM STREQUAL "Debian" ) AND ( PLATFORM_VERSION VERSION_GREATER_EQUAL "10" ) )
+ OR ( ( PLATFORM STREQUAL "Ubuntu" ) AND ( PLATFORM_VERSION VERSION_GREATER_EQUAL "18.04" ) ) )
+
+ set( CPACK_DEBIAN_PACKAGE_DEPENDS "libwxgtk3.0-gtk3-0v5, libfuse2, dmsetup, sudo" )
+
+ else ()
+ # Link against statically built wxWidgets on Ubuntu 14.04 and older, and Debian 8 and older
+ if ( ( ( PLATFORM STREQUAL "Debian" ) AND ( PLATFORM_VERSION VERSION_LESS_EQUAL "8" ) )
+ OR ( ( PLATFORM STREQUAL "Ubuntu" ) AND ( PLATFORM_VERSION VERSION_LESS_EQUAL "14.04" ) ) )
+ set( CPACK_DEBIAN_PACKAGE_DEPENDS "libgtk2.0-0, libfuse2, dmsetup, sudo" )
+ else ()
+ set( CPACK_DEBIAN_PACKAGE_DEPENDS "libwxgtk3.0-0v5, libfuse2, dmsetup, sudo" )
+ endif ()
+
+ endif()
endif()
-
+
set( CPACK_DEBIAN_PACKAGE_MAINTAINER ${CONTACT} ) # mandatory
set( CPACK_DEBIAN_PACKAGE_DESCRIPTION ${CPACK_PACKAGE_DESCRIPTION_SUMMARY} ) # mandatory
set( CPACK_DEBIAN_ARCHIVE_TYPE "gnutar") # mandatory
@@ -284,19 +294,23 @@ elseif ( ( PLATFORM STREQUAL "CentOS" ) OR ( PLATFORM STREQUAL "openSUSE" ) )
set( CPACK_RPM_PACKAGE_VENDOR ${CPACK_PACKAGE_VENDOR} ) # mandatory
set( CPACK_RPM_PACKAGE_AUTOREQ "no" ) # disable automatic shared libraries dependency detection (most of the time buggy)
- if ( PLATFORM STREQUAL "CentOS" )
+ if (NOGUI)
+ set( CPACK_RPM_PACKAGE_REQUIRES "fuse, device-mapper, sudo" )
+ else ()
+ if ( PLATFORM STREQUAL "CentOS" )
+
+ if ( DEFINED WITHGTK3 AND WITHGTK3 )
+ set( CPACK_RPM_PACKAGE_REQUIRES "fuse, device-mapper, gtk3, sudo" )
+ else ()
+ set( CPACK_RPM_PACKAGE_REQUIRES "fuse, device-mapper, gtk2, sudo" )
+ endif()
+
+ elseif ( PLATFORM STREQUAL "openSUSE" )
- if ( DEFINED WITHGTK3 AND WITHGTK3 )
- set( CPACK_RPM_PACKAGE_REQUIRES "fuse, device-mapper, gtk3, sudo" )
- else ()
set( CPACK_RPM_PACKAGE_REQUIRES "fuse, device-mapper, gtk2, sudo" )
endif()
-
- elseif ( PLATFORM STREQUAL "openSUSE" )
-
- set( CPACK_RPM_PACKAGE_REQUIRES "fuse, device-mapper, gtk2, sudo" )
endif()
-
+
set( CPACK_RPM_PRE_UNINSTALL_SCRIPT_FILE ${RPM_PRERM}) # optional
# Prevents CPack from generating file conflicts
diff --git a/src/Build/Resources/MacOSX/Info.plist.legacy.xml b/src/Build/Resources/MacOSX/Info.plist.legacy.xml
index 7ecb3c2..099bf03 100644
--- a/src/Build/Resources/MacOSX/Info.plist.legacy.xml
+++ b/src/Build/Resources/MacOSX/Info.plist.legacy.xml
@@ -74,7 +74,7 @@
<string>TRUE</string>
<key>CFBundleVersion</key>
- <string>1.24.8</string>
+ <string>1.24.23</string>
<key>CFBundleShortVersionString</key>
<string>_VERSION_</string>
diff --git a/src/Build/Resources/MacOSX/Info.plist.xml b/src/Build/Resources/MacOSX/Info.plist.xml
index 4df84a0..3362911 100644
--- a/src/Build/Resources/MacOSX/Info.plist.xml
+++ b/src/Build/Resources/MacOSX/Info.plist.xml
@@ -74,7 +74,7 @@
<string>TRUE</string>
<key>CFBundleVersion</key>
- <string>1.24.8</string>
+ <string>1.24.23</string>
<key>CFBundleShortVersionString</key>
<string>_VERSION_</string>
diff --git a/src/Build/build_cmake_deb.sh b/src/Build/build_cmake_deb.sh
index 3be23dd..f54d67b 100755
--- a/src/Build/build_cmake_deb.sh
+++ b/src/Build/build_cmake_deb.sh
@@ -1,4 +1,10 @@
#!/bin/sh
+#
+# Copyright (c) 2013-2020 IDRIX
+# 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.
+#
# Errors should cause script to exit
set -e
@@ -12,22 +18,48 @@ export SOURCEPATH=$(readlink -f "$SCRIPTPATH/..")
# Directory where the VeraCrypt has been checked out
export PARENTDIR=$(readlink -f "$SCRIPTPATH/../../..")
+# The sources of wxWidgets 3.0.5 must be extracted to the parent directory
+export WX_ROOT=$PARENTDIR/wxWidgets-3.0.5
+echo "Using wxWidgets sources in $WX_ROOT"
+
cd $SOURCEPATH
+if [ "$#" = "1" ] && [ "$1" = "WXSTATIC" ]
+then
+echo "Building GUI version of VeraCrypt for DEB using wxWidgets static libraries"
+
+# This will be the temporary wxWidgets directory
+export WX_BUILD_DIR=$PARENTDIR/wxBuildGUI
+
+# To build wxWidgets without GUI
+make WXSTATIC=1 wxbuild || exit 1
+make WXSTATIC=1 clean || exit 1
+make WXSTATIC=1 || exit 1
+make WXSTATIC=1 install DESTDIR="$PARENTDIR/VeraCrypt_Setup/GUI" || exit 1
+
+else
+
echo "Building GUI version of VeraCrypt for DEB using system wxWidgets"
make clean || exit 1
make || exit 1
make install DESTDIR="$PARENTDIR/VeraCrypt_Setup/GUI" || exit 1
-echo "Building console version of VeraCrypt for DEB using system wxWidgets"
+fi
+
+echo "Building console version of VeraCrypt for DEB using wxWidgets static libraries"
# This is to avoid " Error: Unable to initialize GTK+, is DISPLAY set properly?"
# when building over SSH without X11 Forwarding
# export DISPLAY=:0.0
-make NOGUI=1 clean || exit 1
-make NOGUI=1 || exit 1
-make NOGUI=1 install DESTDIR="$PARENTDIR/VeraCrypt_Setup/Console" || exit 1
+# This will be the temporary wxWidgets directory
+export WX_BUILD_DIR=$PARENTDIR/wxBuildConsole
+
+# To build wxWidgets without GUI
+make WXSTATIC=1 NOGUI=1 wxbuild || exit 1
+make WXSTATIC=1 NOGUI=1 clean || exit 1
+make WXSTATIC=1 NOGUI=1 || exit 1
+make WXSTATIC=1 NOGUI=1 install DESTDIR="$PARENTDIR/VeraCrypt_Setup/Console" || exit 1
echo "Creating VeraCrypt DEB packages"
diff --git a/src/Build/build_cmake_opensuse.sh b/src/Build/build_cmake_opensuse.sh
index 340440a..d1a6fd0 100644
--- a/src/Build/build_cmake_opensuse.sh
+++ b/src/Build/build_cmake_opensuse.sh
@@ -1,4 +1,10 @@
#!/bin/sh
+#
+# Copyright (c) 2013-2020 IDRIX
+# 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.
+#
# Errors should cause script to exit
set -e
@@ -12,8 +18,8 @@ export SOURCEPATH=$(readlink -f "$SCRIPTPATH/..")
# Directory where the VeraCrypt has been checked out
export PARENTDIR=$(readlink -f "$SCRIPTPATH/../../..")
-# The sources of wxWidgets 3.0.4 must be extracted to the parent directory
-export WX_ROOT=$PARENTDIR/wxWidgets-3.0.4
+# The sources of wxWidgets 3.0.5 must be extracted to the parent directory
+export WX_ROOT=$PARENTDIR/wxWidgets-3.0.5
echo "Using wxWidgets sources in $WX_ROOT"
cd $SOURCEPATH
@@ -65,7 +71,7 @@ mkdir -p $PARENTDIR/VeraCrypt_Packaging/GUI
mkdir -p $PARENTDIR/VeraCrypt_Packaging/Console
# wxWidgets was built using GTK-2
-cmake -H$SCRIPTPATH -B$PARENTDIR/VeraCrypt_Packaging/GUI -DVERACRYPT_BUILD_DIR="$PARENTDIR/VeraCrypt_Setup/GUI" -DWITHGTK3=TRUE -DNOGUI=FALSE || exit 1
+cmake -H$SCRIPTPATH -B$PARENTDIR/VeraCrypt_Packaging/GUI -DVERACRYPT_BUILD_DIR="$PARENTDIR/VeraCrypt_Setup/GUI" -DWITHGTK3=FALSE -DNOGUI=FALSE || exit 1
cpack --config $PARENTDIR/VeraCrypt_Packaging/GUI/CPackConfig.cmake || exit 1
-cmake -H$SCRIPTPATH -B$PARENTDIR/VeraCrypt_Packaging/Console -DVERACRYPT_BUILD_DIR="$PARENTDIR/VeraCrypt_Setup/Console" -DWITHGTK3=TRUE -DNOGUI=TRUE || exit 1
+cmake -H$SCRIPTPATH -B$PARENTDIR/VeraCrypt_Packaging/Console -DVERACRYPT_BUILD_DIR="$PARENTDIR/VeraCrypt_Setup/Console" -DWITHGTK3=FALSE -DNOGUI=TRUE || exit 1
cpack --config $PARENTDIR/VeraCrypt_Packaging/Console/CPackConfig.cmake|| exit 1
diff --git a/src/Build/build_cmake_rpm_gtk2.sh b/src/Build/build_cmake_rpm_gtk2.sh
index 38c66a9..e7c953f 100644
--- a/src/Build/build_cmake_rpm_gtk2.sh
+++ b/src/Build/build_cmake_rpm_gtk2.sh
@@ -1,4 +1,10 @@
#!/bin/sh
+#
+# Copyright (c) 2013-2020 IDRIX
+# 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.
+#
# Errors should cause script to exit
set -e
@@ -12,8 +18,8 @@ export SOURCEPATH=$(readlink -f "$SCRIPTPATH/..")
# Directory where the VeraCrypt has been checked out
export PARENTDIR=$(readlink -f "$SCRIPTPATH/../../..")
-# The sources of wxWidgets 3.0.4 must be extracted to the parent directory
-export WX_ROOT=$PARENTDIR/wxWidgets-3.0.4
+# The sources of wxWidgets 3.0.5 must be extracted to the parent directory
+export WX_ROOT=$PARENTDIR/wxWidgets-3.0.5
echo "Using wxWidgets sources in $WX_ROOT"
cd $SOURCEPATH
diff --git a/src/Build/build_cmake_rpm_gtk3.sh b/src/Build/build_cmake_rpm_gtk3.sh
index 97091ce..8b47b3d 100644
--- a/src/Build/build_cmake_rpm_gtk3.sh
+++ b/src/Build/build_cmake_rpm_gtk3.sh
@@ -1,4 +1,10 @@
#!/bin/sh
+#
+# Copyright (c) 2013-2020 IDRIX
+# 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.
+#
# Errors should cause script to exit
set -e
@@ -12,8 +18,8 @@ export SOURCEPATH=$(readlink -f "$SCRIPTPATH/..")
# Directory where the VeraCrypt has been checked out
export PARENTDIR=$(readlink -f "$SCRIPTPATH/../../..")
-# The sources of wxWidgets 3.0.4 must be extracted to the parent directory
-export WX_ROOT=$PARENTDIR/wxWidgets-3.0.4
+# The sources of wxWidgets 3.0.5 must be extracted to the parent directory
+export WX_ROOT=$PARENTDIR/wxWidgets-3.0.5
echo "Using wxWidgets sources in $WX_ROOT"
cd $SOURCEPATH
diff --git a/src/Build/build_veracrypt_freebsd.sh b/src/Build/build_veracrypt_freebsd.sh
index 6dc594c..359c797 100755
--- a/src/Build/build_veracrypt_freebsd.sh
+++ b/src/Build/build_veracrypt_freebsd.sh
@@ -1,6 +1,6 @@
#!/bin/sh
#
-# Copyright (c) 2013-2016 IDRIX
+# Copyright (c) 2013-2020 IDRIX
# 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.
@@ -21,8 +21,8 @@ if [ "$(id -u)" != "0" ]; then
exit 1
fi
-# the sources of wxWidgets 3.0.3 must be extracted to the parent directory
-export WX_ROOT=$PARENTDIR/wxWidgets-3.0.4
+# the sources of wxWidgets 3.0.5 must be extracted to the parent directory
+export WX_ROOT=$PARENTDIR/wxWidgets-3.0.5
echo "Using wxWidgets sources in $WX_ROOT"
cd $SOURCEPATH
diff --git a/src/Build/build_veracrypt_linux.sh b/src/Build/build_veracrypt_linux.sh
index 013103b..08ef99a 100755
--- a/src/Build/build_veracrypt_linux.sh
+++ b/src/Build/build_veracrypt_linux.sh
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2013-2017 IDRIX
+# Copyright (c) 2013-2020 IDRIX
# 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.
@@ -20,8 +20,8 @@ if [ "$(id -u)" != "0" ]; then
exit 1
fi
-# the sources of wxWidgets 3.0.3 must be extracted to the parent directory
-export WX_ROOT=$PARENTDIR/wxWidgets-3.0.4
+# the sources of wxWidgets 3.0.5 must be extracted to the parent directory
+export WX_ROOT=$PARENTDIR/wxWidgets-3.0.5
echo "Using wxWidgets sources in $WX_ROOT"
cd $SOURCEPATH
diff --git a/src/Build/build_veracrypt_linux_no_sse2.sh b/src/Build/build_veracrypt_linux_no_sse2.sh
index 2f78418..e7629ef 100755
--- a/src/Build/build_veracrypt_linux_no_sse2.sh
+++ b/src/Build/build_veracrypt_linux_no_sse2.sh
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2013-2017 IDRIX
+# Copyright (c) 2013-2020 IDRIX
# 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.
@@ -20,8 +20,8 @@ if [ "$(id -u)" != "0" ]; then
exit 1
fi
-# the sources of wxWidgets 3.0.3 must be extracted to the parent directory
-export WX_ROOT=$PARENTDIR/wxWidgets-3.0.4
+# the sources of wxWidgets 3.0.5 must be extracted to the parent directory
+export WX_ROOT=$PARENTDIR/wxWidgets-3.0.5
echo "Using wxWidgets sources in $WX_ROOT"
cd $SOURCEPATH
diff --git a/src/Build/build_veracrypt_macosx.sh b/src/Build/build_veracrypt_macosx.sh
index 70a94c4..6b3707e 100755
--- a/src/Build/build_veracrypt_macosx.sh
+++ b/src/Build/build_veracrypt_macosx.sh
@@ -22,7 +22,7 @@ export WX_BUILD_DIR=$PARENTDIR/wxBuild-3.1.2
# define the SDK version to use and OSX minimum target. We target 10.9 by default
export VC_OSX_TARGET=10.9
export VC_OSX_SDK=10.14
-echo "Using MacOSX SDK $VC_OSX_SDK"
+echo "Using MacOSX SDK $VC_OSX_SDK with target set to $VC_OSX_TARGET"
cd $SOURCEPATH
diff --git a/src/Common/BaseCom.cpp b/src/Common/BaseCom.cpp
index 7a74e29..32859b1 100644
--- a/src/Common/BaseCom.cpp
+++ b/src/Common/BaseCom.cpp
@@ -130,7 +130,7 @@ DWORD BaseCom::ReadWriteFile (BOOL write, BOOL device, BSTR filePath, BSTR *buff
{
try
{
- auto_ptr <File> file (device ? new Device (filePath, !write) : new File (filePath, !write));
+ unique_ptr <File> file (device ? new Device (filePath, !write) : new File (filePath, !write));
file->CheckOpened (SRC_POS);
file->SeekAt (offset);
@@ -194,7 +194,7 @@ DWORD BaseCom::DeviceIoControl (BOOL readOnly, BOOL device, BSTR filePath, DWORD
{
try
{
- auto_ptr <File> file (device ? new Device (filePath, readOnly == TRUE) : new File (filePath, readOnly == TRUE));
+ unique_ptr <File> file (device ? new Device (filePath, readOnly == TRUE) : new File (filePath, readOnly == TRUE));
file->CheckOpened (SRC_POS);
if (!file->IoCtl (dwIoControlCode, (BYTE *) input, !(BYTE *) input ? 0 : ((DWORD *) ((BYTE *) input))[-1],
(BYTE *) *output, !(BYTE *) *output ? 0 : ((DWORD *) ((BYTE *) *output))[-1]))
diff --git a/src/Common/BootEncryption.cpp b/src/Common/BootEncryption.cpp
index e956695..d89c4df 100644
--- a/src/Common/BootEncryption.cpp
+++ b/src/Common/BootEncryption.cpp
@@ -3498,7 +3498,7 @@ namespace VeraCrypt
EfiBootInst.SaveFile(L"\\EFI\\VeraCrypt\\DcsInfo.dcs", DcsInfoImg, sizeDcsInfo);
if (!preserveUserConfig)
EfiBootInst.DelFile(L"\\EFI\\VeraCrypt\\PlatformInfo");
- EfiBootInst.SetStartExec(L"VeraCrypt BootLoader (DcsBoot)", L"\\EFI\\VeraCrypt\\DcsBoot.efi");
+ EfiBootInst.SetStartExec(L"VeraCrypt BootLoader (DcsBoot)", L"\\EFI\\VeraCrypt\\DcsBoot.efi", SetBootEntry, ForceFirstBootEntry, SetBootNext);
if (EfiBootInst.FileExists (szStdEfiBootloader))
{
@@ -5169,16 +5169,19 @@ namespace VeraCrypt
#endif
#ifndef SETUP
void BootEncryption::CheckRequirements ()
- {
- if (nCurrentOS == WIN_2000)
- throw ErrorException ("SYS_ENCRYPTION_UNSUPPORTED_ON_CURRENT_OS", SRC_POS);
-
+ {
if (CurrentOSMajor == 6 && CurrentOSMinor == 0 && CurrentOSServicePack < 1)
throw ErrorException ("SYS_ENCRYPTION_UNSUPPORTED_ON_VISTA_SP0", SRC_POS);
if (IsNonInstallMode())
throw ErrorException ("FEATURE_REQUIRES_INSTALLATION", SRC_POS);
+ /* check if the system drive is already encrypted by BitLocker */
+ wchar_t windowsDrive = (wchar_t) towupper (GetWindowsDirectory()[0]);
+ BitLockerEncryptionStatus bitLockerStatus = GetBitLockerEncryptionStatus (windowsDrive);
+ if (bitLockerStatus == BL_Status_Protected)
+ throw ErrorException ("SYSENC_BITLOCKER_CONFLICT", SRC_POS);
+
SystemDriveConfiguration config = GetSystemDriveConfiguration ();
if (SystemDriveIsDynamic())
@@ -5670,6 +5673,16 @@ namespace VeraCrypt
if (!rescueIsoImagePath.empty())
CreateRescueIsoImage (true, rescueIsoImagePath);
+
+ // check if Fast Startup is enabled and if yes then offer to disable it
+ BOOL bHibernateEnabled = FALSE, bHiberbootEnabled = FALSE;
+ if (GetHibernateStatus (bHibernateEnabled, bHiberbootEnabled) && bHiberbootEnabled)
+ {
+ if (AskWarnYesNo ("CONFIRM_DISABLE_FAST_STARTUP", ParentWindow) == IDYES)
+ {
+ WriteLocalMachineRegistryDwordValue (L"SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Power", L"HiberbootEnabled", 0);
+ }
+ }
}
bool BootEncryption::IsPagingFileActive (BOOL checkNonWindowsPartitionsOnly)
diff --git a/src/Common/Cmdline.c b/src/Common/Cmdline.c
index d205673..f0dcf7c 100644
--- a/src/Common/Cmdline.c
+++ b/src/Common/Cmdline.c
@@ -70,9 +70,9 @@ BOOL CALLBACK CommandHelpDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM
StringCchCatW(tmp, 8192, tmp2);
}
}
-
+#if defined(TCMOUNT) && !defined(VCEXPANDER)
StringCchCatW (tmp, 8192, L"\nExamples:\n\nMount a volume as X:\tveracrypt.exe /q /v volume.hc /l X\nDismount a volume X:\tveracrypt.exe /q /d X");
-
+#endif
SetWindowTextW (GetDlgItem (hwndDlg, IDC_COMMANDHELP_TEXT), tmp);
TCfree(tmp);
diff --git a/src/Common/Crypto.c b/src/Common/Crypto.c
index 89ce250..550de2b 100644
--- a/src/Common/Crypto.c
+++ b/src/Common/Crypto.c
@@ -252,7 +252,7 @@ void EncipherBlocks (int cipher, void *dataPtr, void *ks, size_t blockCount)
#endif
}
#endif
-#if CRYPTOPP_BOOL_X64
+#if CRYPTOPP_BOOL_X64 && !defined(CRYPTOPP_DISABLE_ASM)
else if (cipher == TWOFISH) {
twofish_encrypt_blocks(ks, data, data, (uint32) blockCount);
}
@@ -369,7 +369,7 @@ void DecipherBlocks (int cipher, void *dataPtr, void *ks, size_t blockCount)
#endif
}
#endif
-#if CRYPTOPP_BOOL_X64
+#if CRYPTOPP_BOOL_X64 && !defined(CRYPTOPP_DISABLE_ASM)
else if (cipher == TWOFISH) {
twofish_decrypt_blocks(ks, data, data, (uint32) blockCount);
}
@@ -464,7 +464,7 @@ BOOL CipherSupportsIntraDataUnitParallelization (int cipher)
|| (cipher == SERPENT && HasSSE2())
|| (cipher == KUZNYECHIK && HasSSE2())
#endif
-#if CRYPTOPP_BOOL_X64
+#if CRYPTOPP_BOOL_X64 && !defined(CRYPTOPP_DISABLE_ASM)
|| (cipher == TWOFISH)
|| (cipher == CAMELLIA)
#endif
@@ -1243,7 +1243,10 @@ BOOL IsCpuRngEnabled ()
BOOL IsRamEncryptionSupported ()
{
#ifdef _WIN64
- return TRUE;
+ if (t1ha_selfcheck__t1ha2() == 0)
+ return TRUE;
+ else
+ return FALSE;
#else
return FALSE;
#endif
diff --git a/src/Common/Dlgcode.c b/src/Common/Dlgcode.c
index 5a83786..28eb380 100644
--- a/src/Common/Dlgcode.c
+++ b/src/Common/Dlgcode.c
@@ -179,7 +179,7 @@ BOOL bInPlaceEncNonSysPending = FALSE; // TRUE if the non-system in-place encry
BOOL PimEnable = FALSE;
BOOL KeyFilesEnable = FALSE;
KeyFile *FirstKeyFile = NULL;
-KeyFilesDlgParam defaultKeyFilesParam;
+KeyFilesDlgParam defaultKeyFilesParam = {0};
BOOL IgnoreWmDeviceChange = FALSE;
BOOL DeviceChangeBroadcastDisabled = FALSE;
@@ -190,6 +190,7 @@ BOOL MultipleMountOperationInProgress = FALSE;
volatile BOOL NeedPeriodicDeviceListUpdate = FALSE;
BOOL DisablePeriodicDeviceListUpdate = FALSE;
+BOOL EnableMemoryProtection = FALSE;
BOOL WaitDialogDisplaying = FALSE;
@@ -380,14 +381,24 @@ static WTHELPERGETPROVSIGNERFROMCHAIN WTHelperGetProvSignerFromChainFn = NULL;
static WTHELPERGETPROVCERTFROMCHAIN WTHelperGetProvCertFromChainFn = NULL;
static unsigned char gpbSha1CodeSignCertFingerprint[64] = {
- 0x64, 0x4C, 0x59, 0x15, 0xC5, 0xD4, 0x31, 0x2A, 0x73, 0x12, 0xC4, 0xA6,
- 0xF2, 0x2C, 0xE8, 0x7E, 0xA8, 0x05, 0x53, 0xB5, 0x99, 0x9A, 0xF5, 0xD1,
- 0xBE, 0x57, 0x56, 0x3D, 0x2F, 0xCA, 0x0B, 0x2F, 0xEF, 0x57, 0xFB, 0xA0,
- 0x03, 0xEF, 0x66, 0x4D, 0xBF, 0xEE, 0x25, 0xBC, 0x22, 0xDD, 0x5C, 0x15,
- 0x47, 0xD6, 0x6F, 0x57, 0x94, 0xBB, 0x65, 0xBC, 0x5C, 0xAA, 0xE8, 0x80,
- 0xFB, 0xD0, 0xEF, 0x00
+ 0x97, 0xE3, 0x36, 0xE0, 0x45, 0x21, 0xE9, 0x8A, 0xA7, 0xEA, 0xE8, 0x68,
+ 0x4A, 0x56, 0x02, 0xB2, 0xE7, 0x63, 0x59, 0x3A, 0x37, 0x03, 0x64, 0xC3,
+ 0x7D, 0xBF, 0xF8, 0x19, 0xDB, 0x39, 0x57, 0x41, 0x55, 0x00, 0x9C, 0xBE,
+ 0xFE, 0xA3, 0xBC, 0x0F, 0xE3, 0xD8, 0x34, 0x2D, 0x2F, 0xB4, 0x80, 0xBE,
+ 0xDD, 0xEA, 0xA7, 0xDB, 0xAD, 0x53, 0x07, 0x71, 0x1A, 0x12, 0x42, 0xB4,
+ 0xE9, 0x65, 0xA5, 0x61
};
+static unsigned char gpbSha256CodeSignCertFingerprint[64] = {
+ 0x88, 0x60, 0xC4, 0x26, 0x6D, 0x42, 0x59, 0x1B, 0xDF, 0x89, 0x0F, 0x1A,
+ 0x2F, 0x70, 0x8D, 0xBB, 0xC0, 0xF0, 0x03, 0x1F, 0x37, 0x11, 0xF9, 0x24,
+ 0x78, 0xDF, 0xD3, 0x60, 0xFB, 0xF3, 0xDC, 0xCA, 0x0D, 0x95, 0x06, 0x6A,
+ 0x5E, 0xAD, 0x5C, 0xA3, 0x3E, 0x75, 0x55, 0x96, 0x7B, 0xD1, 0x0D, 0xC1,
+ 0x00, 0xFE, 0xA0, 0x95, 0x13, 0x23, 0x20, 0x63, 0x26, 0x57, 0xFA, 0x6C,
+ 0xE4, 0x27, 0xF8, 0x36
+};
+
+
typedef HRESULT (WINAPI *SHGETKNOWNFOLDERPATH) (
_In_ REFKNOWNFOLDERID rfid,
_In_ DWORD dwFlags,
@@ -486,6 +497,10 @@ void FinalizeGlobalLocks ()
void cleanup ()
{
burn (&CmdTokenPin, sizeof (CmdTokenPin));
+#ifndef SETUP
+ KeyFileRemoveAll (&FirstKeyFile);
+ KeyFileRemoveAll (&defaultKeyFilesParam.FirstKeyFile);
+#endif
/* Cleanup the GDI fonts */
if (hFixedFont != NULL)
@@ -1204,6 +1219,44 @@ void EnableCloseButton (HWND hwndDlg)
EnableMenuItem (GetSystemMenu (hwndDlg, FALSE), SC_CLOSE, MF_BYCOMMAND | MF_ENABLED);
}
+void HandlePasswordEditWmChar (HWND hwnd, WPARAM wParam)
+{
+ DWORD dwStartPos = 0, dwEndPos = 0;
+ short vk = VkKeyScanW ((WCHAR) wParam);
+ BYTE vkCode = LOBYTE (vk);
+ BYTE vkState = HIBYTE (vk);
+ bool ctrlPressed = (vkState & 2) && !(vkState & 4);
+ int dwMaxPassLen = (int) SendMessage (hwnd, EM_GETLIMITTEXT, 0, 0);
+
+ // check if there is a selected text
+ SendMessage (hwnd, EM_GETSEL, (WPARAM) &dwStartPos, (LPARAM) &dwEndPos);
+
+ if ((dwStartPos == dwEndPos)
+ && (vkCode != VK_DELETE) && (vkCode != VK_BACK)
+ && !ctrlPressed
+ && (GetWindowTextLength (hwnd) == dwMaxPassLen))
+ {
+ EDITBALLOONTIP ebt;
+ DWORD dwTextSize = (DWORD) wcslen (GetString ("PASSWORD_MAXLENGTH_REACHED")) + 16;
+ WCHAR* szErrorText = (WCHAR*) malloc (dwTextSize * sizeof (WCHAR));
+
+ StringCchPrintf (szErrorText, dwTextSize, GetString ("PASSWORD_MAXLENGTH_REACHED"), dwMaxPassLen);
+
+ ebt.cbStruct = sizeof( EDITBALLOONTIP );
+ ebt.pszText = szErrorText;
+ ebt.pszTitle = lpszTitle;
+ ebt.ttiIcon = TTI_ERROR_LARGE; // tooltip warning icon
+
+ SendMessage(hwnd, EM_SHOWBALLOONTIP, 0, (LPARAM)&ebt);
+
+ MessageBeep (0xFFFFFFFF);
+
+ free (szErrorText);
+ }
+ else
+ SendMessage(hwnd, EM_HIDEBALLOONTIP, 0, 0);
+}
+
// Protects an input field from having its content updated by a Paste action (call ToBootPwdField() to use this).
static LRESULT CALLBACK BootPwdFieldProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
@@ -1213,6 +1266,9 @@ static LRESULT CALLBACK BootPwdFieldProc (HWND hwnd, UINT message, WPARAM wParam
{
case WM_PASTE:
return 1;
+ case WM_CHAR:
+ HandlePasswordEditWmChar (hwnd, wParam);
+ break;
}
return CallWindowProcW (wp, hwnd, message, wParam, lParam);
@@ -1273,9 +1329,13 @@ static LRESULT CALLBACK NormalPwdFieldProc (HWND hwnd, UINT message, WPARAM wPar
if (curLen == dwMaxPassLen)
{
EDITBALLOONTIP ebt;
+ DWORD dwTextSize = (DWORD) wcslen (GetString ("PASSWORD_MAXLENGTH_REACHED")) + 16;
+ WCHAR* szErrorText = (WCHAR*) malloc (dwTextSize * sizeof (WCHAR));
+
+ StringCchPrintf (szErrorText, dwTextSize, GetString ("PASSWORD_MAXLENGTH_REACHED"), dwMaxPassLen);
ebt.cbStruct = sizeof( EDITBALLOONTIP );
- ebt.pszText = GetString ("PASSWORD_MAXLENGTH_REACHED");
+ ebt.pszText = szErrorText;
ebt.pszTitle = lpszTitle;
ebt.ttiIcon = TTI_ERROR_LARGE; // tooltip warning icon
@@ -1283,20 +1343,28 @@ static LRESULT CALLBACK NormalPwdFieldProc (HWND hwnd, UINT message, WPARAM wPar
MessageBeep (0xFFFFFFFF);
+ free (szErrorText);
+
bBlock = true;
}
else if ((txtlen + curLen) > dwMaxPassLen)
{
EDITBALLOONTIP ebt;
+ DWORD dwTextSize = (DWORD) wcslen (GetString ("PASSWORD_PASTED_TRUNCATED")) + 16;
+ WCHAR* szErrorText = (WCHAR*) malloc (dwTextSize * sizeof (WCHAR));
+
+ StringCchPrintf (szErrorText, dwTextSize, GetString ("PASSWORD_PASTED_TRUNCATED"), dwMaxPassLen);
ebt.cbStruct = sizeof( EDITBALLOONTIP );
- ebt.pszText = GetString ("PASSWORD_PASTED_TRUNCATED");
+ ebt.pszText = szErrorText;
ebt.pszTitle = lpszTitle;
ebt.ttiIcon = TTI_WARNING_LARGE; // tooltip warning icon
SendMessage(hwnd, EM_SHOWBALLOONTIP, 0, (LPARAM)&ebt);
MessageBeep (0xFFFFFFFF);
+
+ free (szErrorText);
}
else
SendMessage(hwnd, EM_HIDEBALLOONTIP, 0, 0);
@@ -1311,36 +1379,7 @@ static LRESULT CALLBACK NormalPwdFieldProc (HWND hwnd, UINT message, WPARAM wPar
}
break;
case WM_CHAR:
- {
- DWORD dwStartPos = 0, dwEndPos = 0;
- short vk = VkKeyScanW ((WCHAR) wParam);
- BYTE vkCode = LOBYTE (vk);
- BYTE vkState = HIBYTE (vk);
- bool ctrlPressed = (vkState & 2) && !(vkState & 4);
- int dwMaxPassLen = bUseLegacyMaxPasswordLength? MAX_LEGACY_PASSWORD : MAX_PASSWORD;
-
- // check if there is a selected text
- SendMessage (hwnd, EM_GETSEL, (WPARAM) &dwStartPos, (LPARAM) &dwEndPos);
-
- if ((dwStartPos == dwEndPos)
- && (vkCode != VK_DELETE) && (vkCode != VK_BACK)
- && !ctrlPressed
- && (GetWindowTextLength (hwnd) == dwMaxPassLen))
- {
- EDITBALLOONTIP ebt;
-
- ebt.cbStruct = sizeof( EDITBALLOONTIP );
- ebt.pszText = GetString ("PASSWORD_MAXLENGTH_REACHED");
- ebt.pszTitle = lpszTitle;
- ebt.ttiIcon = TTI_ERROR_LARGE; // tooltip warning icon
-
- SendMessage(hwnd, EM_SHOWBALLOONTIP, 0, (LPARAM)&ebt);
-
- MessageBeep (0xFFFFFFFF);
- }
- else
- SendMessage(hwnd, EM_HIDEBALLOONTIP, 0, 0);
- }
+ HandlePasswordEditWmChar (hwnd, wParam);
break;
}
@@ -1482,7 +1521,7 @@ BOOL CALLBACK AboutDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam
L"Based on TrueCrypt 7.1a, freely available at http://www.truecrypt.org/ .\r\n\r\n"
L"Portions of this software:\r\n"
- L"Copyright \xA9 2013-2019 IDRIX. All rights reserved.\r\n"
+ L"Copyright \xA9 2013-2020 IDRIX. All rights reserved.\r\n"
L"Copyright \xA9 2003-2012 TrueCrypt Developers Association. All Rights Reserved.\r\n"
L"Copyright \xA9 1998-2000 Paul Le Roux. All Rights Reserved.\r\n"
L"Copyright \xA9 1998-2008 Brian Gladman. All Rights Reserved.\r\n"
@@ -1491,10 +1530,10 @@ BOOL CALLBACK AboutDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam
L"Copyright \xA9 1999-2017 Dieter Baron and Thomas Klausner.\r\n"
L"Copyright \xA9 2013, Alexey Degtyarev. All rights reserved.\r\n"
L"Copyright \xA9 1999-2016 Jack Lloyd. All rights reserved.\r\n"
- L"Copyright \xA9 2013-2018 Stephan Mueller <smueller@chronox.de>\r\n\r\n"
+ L"Copyright \xA9 2013-2019 Stephan Mueller <smueller@chronox.de>\r\n\r\n"
L"This software as a whole:\r\n"
- L"Copyright \xA9 2013-2019 IDRIX. All rights reserved.\r\n\r\n"
+ L"Copyright \xA9 2013-2020 IDRIX. All rights reserved.\r\n\r\n"
L"An IDRIX Release");
@@ -2630,6 +2669,16 @@ uint32 ReadDriverConfigurationFlags ()
return configMap;
}
+uint32 ReadServiceConfigurationFlags ()
+{
+ DWORD configMap;
+
+ if (!ReadLocalMachineRegistryDword (L"SYSTEM\\CurrentControlSet\\Services\\" TC_SYSTEM_FAVORITES_SERVICE_NAME, TC_SYSTEM_FAVORITES_SERVICE_NAME L"Config", &configMap))
+ configMap = 0;
+
+ return configMap;
+}
+
uint32 ReadEncryptionThreadPoolFreeCpuCountLimit ()
{
@@ -2919,9 +2968,6 @@ void InitApp (HINSTANCE hInstance, wchar_t *lpszCommandLine)
char langId[6];
InitCommonControlsPtr InitCommonControlsFn = NULL;
wchar_t modPath[MAX_PATH];
-
- /* Protect this process memory from being accessed by non-admin users */
- EnableProcessProtection ();
GetModuleFileNameW (NULL, modPath, ARRAYSIZE (modPath));
@@ -3668,11 +3714,15 @@ struct _TEXT_EDIT_DIALOG_PARAM {
std::string& Text;
const WCHAR* Title;
- _TEXT_EDIT_DIALOG_PARAM(BOOL _readOnly, const WCHAR* title, std::string& _text) : Title(title), Text(_text), ReadOnly(_readOnly) {}
+ _TEXT_EDIT_DIALOG_PARAM (const _TEXT_EDIT_DIALOG_PARAM& other) : ReadOnly (other.ReadOnly), Text (other.Text), Title (other.Title) {}
+ _TEXT_EDIT_DIALOG_PARAM(BOOL _readOnly, const WCHAR* title, std::string& _text) : ReadOnly(_readOnly), Text(_text), Title(title) {}
_TEXT_EDIT_DIALOG_PARAM& operator=( const _TEXT_EDIT_DIALOG_PARAM& other) {
- ReadOnly = other.ReadOnly;
- Text = other.Text;
- Title = other.Title;
+ if (this != &other)
+ {
+ ReadOnly = other.ReadOnly;
+ Text = other.Text;
+ Title = other.Title;
+ }
return *this;
}
};
@@ -5531,11 +5581,11 @@ static void DisplayBenchmarkResults (HWND hwndDlg)
SendMessageW (hList, LVM_SETITEMW, 0, (LPARAM)&LvItem);
break;
case BENCHMARK_TYPE_PRF:
- swprintf_s (item1, sizeof(item1) / sizeof(item1[0]), L"%d ms", benchmarkTable[i].meanBytesPerSec);
+ swprintf_s (item1, sizeof(item1) / sizeof(item1[0]), L"%d ms", (int) benchmarkTable[i].meanBytesPerSec);
LvItem.iSubItem = 1;
LvItem.pszText = item1;
SendMessageW (hList, LVM_SETITEMW, 0, (LPARAM)&LvItem);
- swprintf_s (item1, sizeof(item1) / sizeof(item1[0]), L"%d", benchmarkTable[i].decSpeed);
+ swprintf_s (item1, sizeof(item1) / sizeof(item1[0]), L"%d", (int) benchmarkTable[i].decSpeed);
LvItem.iSubItem = 2;
LvItem.pszText = item1;
SendMessageW (hList, LVM_SETITEMW, 0, (LPARAM)&LvItem);
@@ -5572,13 +5622,11 @@ static BOOL PerformBenchmark(HWND hBenchDlg, HWND hwndDlg)
BYTE *lpTestBuffer = NULL;
PCRYPTO_INFO ci = NULL;
UINT64_STRUCT startDataUnitNo;
- SYSTEM_INFO sysInfo = {0};
-
- GetSystemInfo (&sysInfo);
+ size_t cpuCount = GetCpuCount(NULL);
startDataUnitNo.Value = 0;
/* set priority to critical only when there are 2 or more CPUs on the system */
- if (sysInfo.dwNumberOfProcessors > 1 && (benchmarkType != BENCHMARK_TYPE_ENCRYPTION))
+ if (cpuCount > 1 && (benchmarkType != BENCHMARK_TYPE_ENCRYPTION))
SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL);
ci = crypto_open ();
@@ -5785,6 +5833,10 @@ static BOOL PerformBenchmark(HWND hBenchDlg, HWND hwndDlg)
if (EAInitMode (ci, ci->k2))
{
int i;
+#ifdef _WIN64
+ if (IsRamEncryptionEnabled ())
+ VcProtectKeys (ci, VcGetEncryptionID (ci));
+#endif
for (i = 0; i < 10; i++)
{
@@ -5806,6 +5858,11 @@ static BOOL PerformBenchmark(HWND hBenchDlg, HWND hwndDlg)
if (!EAInitMode (ci, ci->k2))
goto counter_error;
+#ifdef _WIN64
+ if (IsRamEncryptionEnabled ())
+ VcProtectKeys (ci, VcGetEncryptionID (ci));
+#endif
+
if (QueryPerformanceCounter (&performanceCountStart) == 0)
goto counter_error;
@@ -5997,7 +6054,7 @@ BOOL CALLBACK BenchmarkDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lP
uint32 driverConfig = ReadDriverConfigurationFlags();
- int isAesHwSupported = is_aes_hw_cpu_supported();
+ int isAesHwSupported = HasAESNI();
SetDlgItemTextW (hwndDlg, IDC_HW_AES, (wstring (L" ") + (GetString (isAesHwSupported ? ((driverConfig & TC_DRIVER_CONFIG_DISABLE_HARDWARE_ENCRYPTION) ? "UISTR_DISABLED" : "UISTR_YES") : "NOT_APPLICABLE_OR_NOT_AVAILABLE"))).c_str());
@@ -6008,13 +6065,12 @@ BOOL CALLBACK BenchmarkDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lP
Warning ("DISABLED_HW_AES_AFFECTS_PERFORMANCE", hwndDlg);
}
- SYSTEM_INFO sysInfo;
- GetSystemInfo (&sysInfo);
+ size_t cpuCount = GetCpuCount (NULL);
size_t nbrThreads = GetEncryptionThreadCount();
wchar_t nbrThreadsStr [300];
- if (sysInfo.dwNumberOfProcessors < 2)
+ if (cpuCount < 2)
{
StringCbCopyW (nbrThreadsStr, sizeof(nbrThreadsStr), GetString ("NOT_APPLICABLE_OR_NOT_AVAILABLE"));
}
@@ -6031,8 +6087,8 @@ BOOL CALLBACK BenchmarkDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lP
ToHyperlink (hwndDlg, IDC_PARALLELIZATION_LABEL_LINK);
- if (nbrThreads < min (sysInfo.dwNumberOfProcessors, GetMaxEncryptionThreadCount())
- && sysInfo.dwNumberOfProcessors > 1)
+ if (nbrThreads < min (cpuCount, GetMaxEncryptionThreadCount())
+ && cpuCount > 1)
{
Warning ("LIMITED_THREAD_COUNT_AFFECTS_PERFORMANCE", hwndDlg);
}
@@ -7392,6 +7448,15 @@ BOOL CheckFileExtension (wchar_t *fileName)
return FALSE;
}
+BOOL IsTrueCryptFileExtension (wchar_t *fileName)
+{
+ wchar_t *ext = wcsrchr (fileName, L'.');
+ if (ext && !_wcsicmp (ext, L".tc"))
+ return TRUE;
+ else
+ return FALSE;
+}
+
void CorrectFileName (wchar_t* fileName)
{
/* replace '/' by '\' */
@@ -7523,7 +7588,10 @@ int GetLastAvailableDrive ()
BOOL IsDriveAvailable (int driveNo)
{
- return (GetUsedLogicalDrives() & (1 << driveNo)) == 0;
+ if (driveNo >= 0 && driveNo < 26)
+ return (GetUsedLogicalDrives() & (1 << driveNo)) == 0;
+ else
+ return FALSE;
}
@@ -10042,12 +10110,6 @@ wchar_t GetSystemDriveLetter (void)
void TaskBarIconDisplayBalloonTooltip (HWND hwnd, wchar_t *headline, wchar_t *text, BOOL warning)
{
- if (nCurrentOS == WIN_2000)
- {
- MessageBoxW (MainDlg, text, headline, warning ? MB_ICONWARNING : MB_ICONINFORMATION);
- return;
- }
-
NOTIFYICONDATAW tnid;
ZeroMemory (&tnid, sizeof (tnid));
@@ -11620,6 +11682,17 @@ BOOL CALLBACK SecurityTokenPasswordDlgProc (HWND hwndDlg, UINT msg, WPARAM wPara
SetForegroundWindow (hwndDlg);
SetFocus (GetDlgItem (hwndDlg, IDC_TOKEN_PASSWORD));
+
+ if (!bSecureDesktopOngoing)
+ {
+ PasswordEditDropTarget* pTarget = new PasswordEditDropTarget ();
+ if (pTarget->Register (hwndDlg))
+ {
+ SetWindowLongPtr (hwndDlg, DWLP_USER, (LONG_PTR) pTarget);
+ }
+ else
+ delete pTarget;
+ }
}
return 0;
@@ -11655,6 +11728,19 @@ BOOL CALLBACK SecurityTokenPasswordDlgProc (HWND hwndDlg, UINT msg, WPARAM wPara
EndDialog (hwndDlg, lw);
}
return 1;
+
+ case WM_NCDESTROY:
+ {
+ /* unregister drap-n-drop support */
+ PasswordEditDropTarget* pTarget = (PasswordEditDropTarget*) GetWindowLongPtr (hwndDlg, DWLP_USER);
+ if (pTarget)
+ {
+ SetWindowLongPtr (hwndDlg, DWLP_USER, (LONG_PTR) 0);
+ pTarget->Revoke ();
+ pTarget->Release();
+ }
+ }
+ return 0;
}
return 0;
@@ -12090,7 +12176,7 @@ BOOL InitSecurityTokenLibrary (HWND hwndDlg)
try
{
- SecurityToken::InitLibrary (SecurityTokenLibraryPath, auto_ptr <GetPinFunctor> (new PinRequestHandler(MainDlg)), auto_ptr <SendExceptionFunctor> (new WarningHandler(MainDlg)));
+ SecurityToken::InitLibrary (SecurityTokenLibraryPath, unique_ptr <GetPinFunctor> (new PinRequestHandler(MainDlg)), unique_ptr <SendExceptionFunctor> (new WarningHandler(MainDlg)));
}
catch (Exception &e)
{
@@ -13050,7 +13136,7 @@ BOOL IsApplicationInstalled (const wchar_t *appName, BOOL b32bitApp)
}
wchar_t regName[1024];
- DWORD regNameSize = sizeof (regName);
+ DWORD regNameSize = ARRAYSIZE (regName);
DWORD index = 0;
while (RegEnumKeyEx (unistallKey, index++, regName, &regNameSize, NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
{
@@ -13165,11 +13251,21 @@ BOOL GetPassword (HWND hwndDlg, UINT ctrlID, char* passValue, int bufSize, BOOL
passValue [0] = 0;
if (bShowError)
{
- SetFocus (GetDlgItem(hwndDlg, ctrlID));
if (GetLastError () == ERROR_INSUFFICIENT_BUFFER)
- Error ((bufSize == (MAX_LEGACY_PASSWORD + 1))? "LEGACY_PASSWORD_UTF8_TOO_LONG": "PASSWORD_UTF8_TOO_LONG", hwndDlg);
+ {
+ DWORD dwTextSize = (DWORD) wcslen (GetString ("PASSWORD_UTF8_TOO_LONG")) + 16;
+ WCHAR* szErrorText = (WCHAR*) malloc (dwTextSize * sizeof (WCHAR));
+
+ // bufSize is equal to maximum password length plus one
+ StringCchPrintf (szErrorText, dwTextSize, GetString ("PASSWORD_UTF8_TOO_LONG"), (bufSize - 1));
+
+ ErrorDirect (szErrorText, hwndDlg);
+
+ free (szErrorText);
+ }
else
Error ("PASSWORD_UTF8_INVALID", hwndDlg);
+ SetFocus (GetDlgItem(hwndDlg, ctrlID));
}
}
@@ -13835,7 +13931,7 @@ BOOL VerifyModuleSignature (const wchar_t* path)
WVTData.dwProvFlags = WTD_REVOCATION_CHECK_NONE | WTD_CACHE_ONLY_URL_RETRIEVAL;
hResult = WinVerifyTrustFn(0, &gActionID, &WVTData);
- if (SUCCEEDED (hResult))
+ if (0 == hResult)
{
PCRYPT_PROVIDER_DATA pProviderData = WTHelperProvDataFromStateDataFn (WVTData.hWVTStateData);
if (pProviderData)
@@ -13849,7 +13945,9 @@ BOOL VerifyModuleSignature (const wchar_t* path)
BYTE hashVal[64];
sha512 (hashVal, pProviderCert->pCert->pbCertEncoded, pProviderCert->pCert->cbCertEncoded);
- if (0 == memcmp (hashVal, gpbSha1CodeSignCertFingerprint, 64))
+ if ( (0 == memcmp (hashVal, gpbSha1CodeSignCertFingerprint, 64))
+ || (0 == memcmp (hashVal, gpbSha256CodeSignCertFingerprint, 64))
+ )
{
bResult = TRUE;
}
@@ -14236,11 +14334,35 @@ cleanup:
return retval;
}
+// This function checks if the process is running with elevated privileges or not
+BOOL IsElevated()
+{
+ DWORD dwSize = 0;
+ HANDLE hToken = NULL;
+ TOKEN_ELEVATION tokenInformation;
+ BOOL bReturn = FALSE;
+
+ if(OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken))
+ {
+ if(GetTokenInformation(hToken, TokenElevation, &tokenInformation, sizeof(TOKEN_ELEVATION), &dwSize))
+ {
+ if (tokenInformation.TokenIsElevated)
+ bReturn = TRUE;
+ }
+
+ CloseHandle(hToken);
+ }
+ return bReturn;
+}
+
// This function always loads a URL in a non-privileged mode
// If current process has admin privileges, we execute the command "rundll32 url.dll,FileProtocolHandler URL" as non-elevated
+// Use this security mechanism only starting from Windows Vista and only if we can get the window of the Shell's desktop since
+// we rely on the Shell to be already running in a non-privileges mode. If the Shell is not running or if it has been modified,
+// then we can't protect the user in such non standard environment
void SafeOpenURL (LPCWSTR szUrl)
{
- if (IsAdmin ())
+ if (IsOSAtLeast (WIN_VISTA) && IsAdmin () && IsElevated() && GetShellWindow())
{
WCHAR szRunDllPath[TC_MAX_PATH];
WCHAR szUrlDllPath[TC_MAX_PATH];
@@ -14332,3 +14454,582 @@ void GetAppRandomSeed (unsigned char* pbRandSeed, size_t cbRandSeed)
burn (&tctx, sizeof(tctx));
}
#endif
+
+/*
+ * GetBitLockerEncryptionStatus: retuns the BitLocker encryption status of a given drive.
+ */
+
+typedef enum BitLockerProtectionState
+{
+ BL_State_FullyDecrypted = 0,
+ BL_State_FullyEncrypted = 1,
+ BL_State_EncryptionInProgress = 2,
+ BL_State_DecryptionInProgress = 3,
+ BL_State_EncryptionSuspended = 4,
+ BL_State_DecryptionSuspended = 5,
+ BL_State_FullyEncryptedWipeInProgress = 6,
+ BL_State_FullyEncryptedWipeSuspended = 7
+} BitLockerProtectionState;
+
+typedef HRESULT (WINAPI *SHCreateItemFromParsingNameFn)(
+ PCWSTR pszPath,
+ IBindCtx* pbc,
+ REFIID riid,
+ void** ppv
+);
+
+typedef HRESULT (WINAPI *PSGetPropertyKeyFromNameFn)(
+ _In_ PCWSTR pszName,
+ _Out_ PROPERTYKEY* ppropkey);
+
+
+/*
+ Code derived from https://stackoverflow.com/questions/23841973/how-to-tell-if-drive-is-bitlocker-encrypted-without-admin-privilege/47192128#47192128
+*/
+BitLockerEncryptionStatus GetBitLockerEncryptionStatus(WCHAR driveLetter)
+{
+ HRESULT hr;
+ BitLockerEncryptionStatus blStatus = BL_Status_Unknown;
+ wchar_t szDllPath[MAX_PATH] = { 0 };
+ HMODULE hShell32 = NULL;
+
+ CoInitialize(NULL);
+
+ if (GetSystemDirectory(szDllPath, MAX_PATH))
+ StringCchCatW(szDllPath, MAX_PATH, L"\\Shell32.dll");
+ else
+ StringCchCopyW(szDllPath, MAX_PATH, L"C:\\Windows\\System32\\Shell32.dll");
+
+ hShell32 = LoadLibrary(szDllPath);
+ if (hShell32)
+ {
+ SHCreateItemFromParsingNameFn SHCreateItemFromParsingNamePtr = (SHCreateItemFromParsingNameFn)GetProcAddress(hShell32, "SHCreateItemFromParsingName");
+ if (SHCreateItemFromParsingNamePtr)
+ {
+ HMODULE hPropsys = NULL;
+
+ if (GetSystemDirectory(szDllPath, MAX_PATH))
+ StringCchCatW(szDllPath, MAX_PATH, L"\\Propsys.dll");
+ else
+ StringCchCopyW(szDllPath, MAX_PATH, L"C:\\Windows\\System32\\Propsys.dll");
+
+ hPropsys = LoadLibrary(szDllPath);
+ if (hPropsys)
+ {
+ PSGetPropertyKeyFromNameFn PSGetPropertyKeyFromNamePtr = (PSGetPropertyKeyFromNameFn)GetProcAddress(hPropsys, "PSGetPropertyKeyFromName");
+ if (PSGetPropertyKeyFromNamePtr)
+ {
+ WCHAR parsingName[3] = {driveLetter, L':', 0};
+ IShellItem2* drive = NULL;
+ hr = SHCreateItemFromParsingNamePtr(parsingName, NULL, IID_PPV_ARGS(&drive));
+ if (SUCCEEDED(hr)) {
+ PROPERTYKEY pKey;
+ hr = PSGetPropertyKeyFromNamePtr(L"System.Volume.BitLockerProtection", &pKey);
+ if (SUCCEEDED(hr)) {
+ PROPVARIANT prop;
+ PropVariantInit(&prop);
+ hr = drive->GetProperty(pKey, &prop);
+ if (SUCCEEDED(hr)) {
+ int status = prop.intVal;
+ if (status == BL_State_FullyEncrypted || status == BL_State_DecryptionInProgress || status == BL_State_DecryptionSuspended)
+ blStatus = BL_Status_Protected;
+ else
+ blStatus = BL_Status_Unprotected;
+ }
+ }
+ }
+ if (drive)
+ drive->Release();
+ }
+
+ FreeLibrary(hPropsys);
+ }
+ }
+ else
+ {
+ blStatus = BL_Status_Unprotected; // before Vista, there was no Bitlocker
+ }
+
+ FreeLibrary(hShell32);
+ }
+
+ CoUninitialize();
+ return blStatus;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+
+static CLIPFORMAT g_supportedFormats[] = { CF_UNICODETEXT, CF_TEXT, CF_OEMTEXT};
+
+//*************************************************************
+// GenericDropTarget
+//*************************************************************
+GenericDropTarget::GenericDropTarget(CLIPFORMAT* pFormats, size_t count)
+ : m_DropTargetWnd(NULL),
+ m_dwRefCount(1),
+ m_KeyState(0L),
+ m_Data(NULL)
+{
+ m_DropPoint.x = 0;
+ m_DropPoint.y = 0;
+
+ if (pFormats && count)
+ {
+ for (size_t i = 0; i < count; i++)
+ {
+ m_SupportedFormat.push_back (pFormats[i]);
+ }
+ }
+}
+
+GenericDropTarget::~GenericDropTarget()
+{
+}
+
+HRESULT GenericDropTarget::QueryInterface(REFIID iid, void **ppvObject)
+{
+ if(ppvObject == NULL)
+ return E_FAIL;
+
+ if (iid == IID_IUnknown)
+ {
+ AddRef();
+ (*ppvObject) = this;
+ return S_OK;
+ }
+ // compare guids fast and dirty
+ if (IsEqualGUID (iid, IID_IDropTarget))
+ {
+ AddRef();
+ (*ppvObject) = this;
+ return S_OK;
+ }
+
+ return E_FAIL;
+}
+
+ULONG GenericDropTarget::AddRef(void)
+{
+ return (ULONG) InterlockedIncrement (&m_dwRefCount);
+}
+
+ULONG GenericDropTarget::Release(void)
+{
+ if (InterlockedDecrement (&m_dwRefCount) == 0)
+ {
+ delete this;
+ return 0;
+ }
+ else
+ return (ULONG) m_dwRefCount;
+}
+
+//*************************************************************
+// Register
+// Called by whom implements us so we can serve
+//*************************************************************
+BOOL GenericDropTarget::Register(HWND hWnd)
+{
+ if(NULL == hWnd)
+ return E_FAIL;
+
+ OleInitialize(NULL);
+
+ // required: these MUST be strong locked
+ CoLockObjectExternal(this, TRUE, 0);
+
+ // this is ok, we have it
+ DWORD hRes = ::RegisterDragDrop(hWnd, this);
+ if(SUCCEEDED(hRes))
+ {
+ // keep
+ m_DropTargetWnd = hWnd;
+ return TRUE;
+ }
+
+ // unlock
+ CoLockObjectExternal(this, FALSE, 0);
+
+ // bye bye COM
+ OleUninitialize();
+
+ // wont accept data now
+ return FALSE;
+}
+
+//*************************************************************
+// Revoke
+// Unregister us as a target
+//*************************************************************
+void GenericDropTarget::Revoke()
+{
+ if(NULL == m_DropTargetWnd)
+ return;
+
+ RevokeDragDrop(m_DropTargetWnd);
+
+ m_DropTargetWnd = NULL;
+
+ // unlock
+ CoLockObjectExternal(this, FALSE, 0);
+
+ // bye bye COM
+ OleUninitialize();
+}
+
+//*************************************************************
+// DragEnter
+//*************************************************************
+HRESULT GenericDropTarget::DragEnter(struct IDataObject *pDataObject, unsigned long grfKeyState, struct _POINTL pMouse, unsigned long * pDropEffect)
+{
+ if(pDataObject == NULL)
+ return E_FAIL; // must have data
+
+ // keep point
+ m_DropPoint.x = pMouse.x;
+ m_DropPoint.y = pMouse.y;
+
+ // keep key
+ m_KeyState = grfKeyState;
+
+ // call top
+ *pDropEffect = GotEnter();
+
+ return S_OK;
+}
+
+//*************************************************************
+// DragOver
+// Coming over!
+//*************************************************************
+HRESULT GenericDropTarget::DragOver(unsigned long grfKeyState, struct _POINTL pMouse, unsigned long *pEffect)
+{
+ // keep point
+ m_DropPoint.x = pMouse.x;
+ m_DropPoint.y = pMouse.y;
+
+ // keep key
+ m_KeyState = grfKeyState;
+
+ // call top
+ *pEffect = GotDrag();
+
+ return S_OK;
+}
+
+//*************************************************************
+// DragLeave
+// Free! At last!
+//*************************************************************
+HRESULT GenericDropTarget::DragLeave(void)
+{
+ GotLeave();
+
+ return S_OK;
+}
+
+//*************************************************************
+// Drop
+//*************************************************************
+HRESULT GenericDropTarget::Drop(struct IDataObject *pDataObject, unsigned long grfKeyState, struct _POINTL pMouse, unsigned long *pdwEffect)
+{
+ if(NULL == pDataObject)
+ return E_FAIL;
+
+ // do final effect
+ *pdwEffect = DROPEFFECT_COPY;
+
+ // Check the data
+ FORMATETC iFormat;
+ ZeroMemory(&iFormat, sizeof(FORMATETC));
+
+ STGMEDIUM iMedium;
+ ZeroMemory(&iMedium, sizeof(STGMEDIUM));
+
+ HRESULT hRes;
+ size_t i;
+ bool bFound = false;
+
+ for (i = 0; i < m_SupportedFormat.size(); i++)
+ {
+ // data
+ iFormat.cfFormat = m_SupportedFormat[i];
+ iFormat.dwAspect = DVASPECT_CONTENT;
+ iFormat.lindex = -1; // give me all baby
+ iFormat.tymed = TYMED_HGLOBAL; // want mem
+
+ hRes = pDataObject->GetData(&iFormat, &iMedium);
+ if(SUCCEEDED(hRes))
+ {
+ bFound = true;
+ break;
+ }
+ }
+
+ if (!bFound)
+ return hRes;
+
+ // we have the data, get it
+ BYTE *iMem = (BYTE *)::GlobalLock(iMedium.hGlobal);
+
+ // pass over
+ m_Data = iMem;
+
+ // keep point
+ m_DropPoint.x = pMouse.x;
+ m_DropPoint.y = pMouse.y;
+
+ // keep key
+ m_KeyState = grfKeyState;
+
+ // notify parent of drop
+ GotDrop(m_SupportedFormat[i]);
+
+ ::GlobalUnlock(iMedium.hGlobal);
+
+ // free data
+ if(iMedium.pUnkForRelease != NULL)
+ iMedium.pUnkForRelease->Release();
+
+ return S_OK;
+}
+
+//*************************************************************
+// Stub implementation
+// Real stuff would be done in parent
+//*************************************************************
+void GenericDropTarget::GotDrop(CLIPFORMAT format)
+{
+}
+
+DWORD GenericDropTarget::GotDrag(void)
+{
+ return DROPEFFECT_LINK;
+}
+
+void GenericDropTarget::GotLeave(void)
+{
+}
+
+DWORD GenericDropTarget::GotEnter(void)
+{
+ return DROPEFFECT_LINK;
+}
+
+// ************************************************************
+// PasswordEditDropTarget
+// Constructor
+// ************************************************************
+PasswordEditDropTarget::PasswordEditDropTarget() : GenericDropTarget (g_supportedFormats, ARRAYSIZE (g_supportedFormats))
+{
+
+}
+
+// ************************************************************
+// GotDrag
+
+// ************************************************************
+DWORD PasswordEditDropTarget::GotDrag(void)
+{
+ return GotEnter();
+}
+
+// ************************************************************
+// GotLeave
+// ************************************************************
+void PasswordEditDropTarget::GotLeave(void)
+{
+}
+
+// ************************************************************
+// GotEnter
+// ************************************************************
+DWORD PasswordEditDropTarget::GotEnter(void)
+{
+ TCHAR szClassName[64];
+ DWORD dwStyles;
+ int maxLen;
+ HWND hChild = WindowFromPoint (m_DropPoint);
+ // check that we are on password edit control (we use maximum length to correctly identify password fields since they don't always have ES_PASSWORD style (if the the user checked show password)
+ if (hChild && GetClassName (hChild, szClassName, ARRAYSIZE (szClassName)) && (0 == _tcsicmp (szClassName, _T("EDIT")))
+ && (dwStyles = GetWindowLong (hChild, GWL_STYLE)) && !(dwStyles & ES_NUMBER)
+ && (maxLen = (int) SendMessage (hChild, EM_GETLIMITTEXT, 0, 0)) && (maxLen == MAX_PASSWORD || maxLen == MAX_LEGACY_PASSWORD)
+ )
+ {
+ return DROPEFFECT_COPY;
+ }
+
+ return DROPEFFECT_LINK;
+}
+
+// ************************************************************
+// GotDrop
+// Called if we have a drop text drop here.
+//
+// ************************************************************
+void PasswordEditDropTarget::GotDrop(CLIPFORMAT format)
+{
+ // value contains the material itself
+ if(m_Data)
+ {
+ TCHAR szClassName[64];
+ DWORD dwStyles;
+ int maxLen;
+ HWND hChild = WindowFromPoint (m_DropPoint);
+ if (hChild && GetClassName (hChild, szClassName, ARRAYSIZE (szClassName)) && (0 == _tcsicmp (szClassName, _T("EDIT")))
+ && (dwStyles = GetWindowLong (hChild, GWL_STYLE)) && !(dwStyles & ES_NUMBER)
+ && (maxLen = (int) SendMessage (hChild, EM_GETLIMITTEXT, 0, 0)) && (maxLen == MAX_PASSWORD || maxLen == MAX_LEGACY_PASSWORD)
+ )
+ {
+ WCHAR* wszText;
+ int wlen;
+ bool bFree = false;
+ // get the text
+ if (format == CF_UNICODETEXT)
+ {
+ wszText = (WCHAR *)m_Data;
+ }
+ else
+ {
+ char *iText = (char *)m_Data;
+ wlen = MultiByteToWideChar ((format == CF_OEMTEXT)? CP_OEMCP : CP_ACP, 0, iText, -1, NULL, 0);
+ wszText = new WCHAR[wlen];
+ if (wszText)
+ {
+ wlen = MultiByteToWideChar (CP_ACP, 0, iText, -1, wszText, wlen);
+ bFree = true;
+ }
+ }
+
+ WCHAR* pchData = wszText;
+ int txtlen = 0;
+ bool bTruncated = false;
+
+ // remove any appended \r or \n
+ while (*pchData)
+ {
+ if (*pchData == '\r' || *pchData == '\n')
+ break;
+ else
+ {
+ txtlen++;
+ pchData++;
+ }
+ }
+
+ if (txtlen)
+ {
+ if (txtlen > maxLen)
+ {
+ bTruncated = true;
+ txtlen = maxLen;
+ }
+
+ SetFocus (hChild);
+
+ wszText[txtlen] = 0;
+ SetWindowText(hChild , wszText);
+
+ if (bTruncated)
+ {
+ EDITBALLOONTIP ebt;
+ DWORD dwTextSize = (DWORD) wcslen (GetString ("PASSWORD_PASTED_TRUNCATED")) + 16;
+ WCHAR* szErrorText = (WCHAR*) malloc (dwTextSize * sizeof (WCHAR));
+
+ StringCchPrintf (szErrorText, dwTextSize, GetString ("PASSWORD_PASTED_TRUNCATED"), maxLen);
+
+ ebt.cbStruct = sizeof( EDITBALLOONTIP );
+ ebt.pszText = szErrorText;
+ ebt.pszTitle = lpszTitle;
+ ebt.ttiIcon = TTI_WARNING_LARGE; // tooltip warning icon
+
+ SendMessage(hChild, EM_SHOWBALLOONTIP, 0, (LPARAM)&ebt);
+
+ MessageBeep (0xFFFFFFFF);
+
+ free (szErrorText);
+ }
+ }
+
+ if (bFree)
+ {
+ burn (wszText, wlen * sizeof (WCHAR));
+ delete [] wszText;
+ }
+ }
+ }
+}
+
+
+/*
+ * Query the status of Hibernate and Fast Startup
+ */
+
+typedef BOOLEAN (WINAPI *GetPwrCapabilitiesFn)(
+ PSYSTEM_POWER_CAPABILITIES lpspc
+);
+
+BOOL GetHibernateStatus (BOOL& bHibernateEnabled, BOOL& bHiberbootEnabled)
+{
+ wchar_t szPowrProfPath[MAX_PATH] = {0};
+ HMODULE hPowrProf = NULL;
+ BOOL bResult = FALSE;
+
+ bHibernateEnabled = bHiberbootEnabled = FALSE;
+
+ if (GetSystemDirectory(szPowrProfPath, MAX_PATH))
+ StringCchCatW (szPowrProfPath, MAX_PATH, L"\\PowrProf.dll");
+ else
+ StringCchCopyW (szPowrProfPath, MAX_PATH, L"C:\\Windows\\System32\\PowrProf.dll");
+
+ hPowrProf = LoadLibrary (szPowrProfPath);
+ if (hPowrProf)
+ {
+ GetPwrCapabilitiesFn GetPwrCapabilitiesPtr = (GetPwrCapabilitiesFn) GetProcAddress (hPowrProf, "GetPwrCapabilities");
+ if ( GetPwrCapabilitiesPtr)
+ {
+ SYSTEM_POWER_CAPABILITIES spc;
+ BOOLEAN bRet = GetPwrCapabilitiesPtr (&spc);
+ if (bRet)
+ {
+ DWORD dwHibernateEnabled = 0;
+ DWORD dwHiberbootEnabled = 0;
+
+ if (spc.SystemS4)
+ {
+ dwHibernateEnabled = 1;
+ if(!ReadLocalMachineRegistryDword (L"SYSTEM\\CurrentControlSet\\Control\\Power", L"HibernateEnabled", &dwHibernateEnabled))
+ {
+ // starting from Windows 10 1809 (Build 17763), HibernateEnabledDefault is used when HibernateEnabled is absent
+ if (IsOSVersionAtLeast (WIN_10, 0) && CurrentOSBuildNumber >= 17763)
+ ReadLocalMachineRegistryDword (L"SYSTEM\\CurrentControlSet\\Control\\Power", L"HibernateEnabledDefault", &dwHibernateEnabled);
+ }
+ }
+
+ // check if Fast Startup / Hybrid Boot is enabled
+ if (IsOSVersionAtLeast (WIN_8, 0) && spc.spare2[0])
+ {
+ dwHiberbootEnabled = 1;
+ ReadLocalMachineRegistryDword (L"SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Power", L"HiberbootEnabled", &dwHiberbootEnabled);
+ }
+
+ if (dwHibernateEnabled)
+ bHibernateEnabled = TRUE;
+ else
+ bHibernateEnabled = FALSE;
+
+ if (dwHiberbootEnabled)
+ bHiberbootEnabled = TRUE;
+ else
+ bHiberbootEnabled = FALSE;
+
+ bResult = TRUE;
+ }
+ }
+
+ FreeLibrary (hPowrProf);
+ }
+
+ return bResult;
+}
+
diff --git a/src/Common/Dlgcode.h b/src/Common/Dlgcode.h
index 5da717f..e4b2198 100644
--- a/src/Common/Dlgcode.h
+++ b/src/Common/Dlgcode.h
@@ -167,6 +167,7 @@ extern BOOL MultipleMountOperationInProgress;
extern volatile BOOL NeedPeriodicDeviceListUpdate;
extern BOOL DisablePeriodicDeviceListUpdate;
+extern BOOL EnableMemoryProtection;
#ifndef SETUP
extern BOOL bLanguageSetInSetup;
@@ -241,6 +242,13 @@ typedef struct
} OpenVolumeContext;
+typedef enum BitLockerEncryptionStatus
+{
+ BL_Status_Unknown = 0,
+ BL_Status_Unprotected,
+ BL_Status_Protected
+} BitLockerEncryptionStatus;
+
#define DEFAULT_VOL_CREATION_WIZARD_MODE WIZARD_MODE_FILE_CONTAINER
@@ -311,6 +319,7 @@ BOOL InstanceHasAppSetupMutex (void);
void CloseAppSetupMutex (void);
BOOL IsTrueCryptInstallerRunning (void);
uint32 ReadDriverConfigurationFlags ();
+uint32 ReadServiceConfigurationFlags ();
uint32 ReadEncryptionThreadPoolFreeCpuCountLimit ();
BOOL LoadSysEncSettings ();
int LoadNonSysInPlaceEncSettings (WipeAlgorithmId *wipeAlgorithm);
@@ -351,6 +360,7 @@ BOOL CloseVolumeExplorerWindows (HWND hwnd, int driveNo);
BOOL UpdateDriveCustomLabel (int driveNo, wchar_t* effectiveLabel, BOOL bSetValue);
BOOL CheckCapsLock (HWND hwnd, BOOL quiet);
BOOL CheckFileExtension (wchar_t *fileName);
+BOOL IsTrueCryptFileExtension (wchar_t *fileName);
void CorrectFileName (wchar_t* fileName);
void CorrectURL (wchar_t* fileName);
void IncreaseWrongPwdRetryCount (int count);
@@ -546,6 +556,7 @@ BOOL GetSetupconfigLocation (wchar_t* path, DWORD cchSize);
BOOL BufferHasPattern (const unsigned char* buffer, size_t bufferLen, const void* pattern, size_t patternLen);
BOOL EnableProcessProtection();
void SafeOpenURL (LPCWSTR szUrl);
+BitLockerEncryptionStatus GetBitLockerEncryptionStatus(WCHAR driveLetter);
#ifdef _WIN64
void GetAppRandomSeed (unsigned char* pbRandSeed, size_t cbRandSeed);
#endif
@@ -599,6 +610,30 @@ struct HostDevice
~HostDevice () {}
+ HostDevice& operator= (const HostDevice& device)
+ {
+ if (this != &device)
+ {
+ Bootable = device.Bootable;
+ ContainsSystem = device.ContainsSystem;
+ DynamicVolume = device.DynamicVolume;
+ Floppy = device.Floppy;
+ IsPartition = device.IsPartition;
+ IsVirtualPartition = device.IsVirtualPartition;
+ HasUnencryptedFilesystem = device.HasUnencryptedFilesystem;
+ MountPoint = device.MountPoint;
+ Name = device.Name;
+ Path = device.Path;
+ Removable = device.Removable;
+ Size = device.Size;
+ SystemNumber = device.SystemNumber;
+ HasVolumeIDs = device.HasVolumeIDs;
+ Partitions = device.Partitions;
+ memcpy (VolumeIDs, device.VolumeIDs, sizeof (VolumeIDs));
+ }
+ return *this;
+ }
+
bool Bootable;
bool ContainsSystem;
bool DynamicVolume;
@@ -657,6 +692,62 @@ typedef void (CALLBACK* WaitThreadProc)(void* pArg, HWND hWaitDlg);
void BringToForeground(HWND hWnd);
void ShowWaitDialog(HWND hwnd, BOOL bUseHwndAsParent, WaitThreadProc callback, void* pArg);
+// classes used to implement support for password drag-n-drop from KeePass Password Safe
+// Implementation based the following source code with many modifications to fix isses and add features
+// URL: https://www.codeguru.com/cpp/misc/misc/draganddrop/article.php/c349/Drag-And-Drop-between-Window-Controls.htm
+
+interface GenericDropTarget : public IDropTarget
+{
+public:
+ GenericDropTarget(CLIPFORMAT* pFormats, size_t count);
+ ~GenericDropTarget();
+
+ // basic IUnknown stuff
+ HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void ** ppvObject);
+ ULONG STDMETHODCALLTYPE AddRef(void);
+ ULONG STDMETHODCALLTYPE Release(void);
+
+ HRESULT STDMETHODCALLTYPE DragEnter(struct IDataObject *,unsigned long,struct _POINTL,unsigned long *);
+ HRESULT STDMETHODCALLTYPE DragOver(unsigned long,struct _POINTL,unsigned long *);
+ HRESULT STDMETHODCALLTYPE DragLeave(void);
+ HRESULT STDMETHODCALLTYPE Drop(struct IDataObject *,unsigned long,struct _POINTL,unsigned long *);
+
+ // called by parents
+ BOOL Register(HWND hWnd);
+ void Revoke();
+
+ // call parent we have goodies
+ virtual void GotDrop(CLIPFORMAT format);
+ virtual DWORD GotDrag(void);
+ virtual void GotLeave(void);
+ virtual DWORD GotEnter(void);
+public:
+ BYTE *m_Data;
+
+ POINT m_DropPoint;
+
+ DWORD m_KeyState;
+
+protected:
+ HWND m_DropTargetWnd;
+ std::vector<CLIPFORMAT> m_SupportedFormat;
+ volatile LONG m_dwRefCount;
+};
+
+class PasswordEditDropTarget : public GenericDropTarget
+{
+public:
+ PasswordEditDropTarget();
+
+ // called by child we have drop
+ void GotDrop(CLIPFORMAT format);
+ DWORD GotDrag(void);
+ void GotLeave(void);
+ DWORD GotEnter(void);
+};
+
+BOOL GetHibernateStatus (BOOL& bHibernateEnabled, BOOL& bHiberbootEnabled);
+
#endif // __cplusplus
#endif // TC_HEADER_DLGCODE
diff --git a/src/Common/EncryptionThreadPool.c b/src/Common/EncryptionThreadPool.c
index 461f284..1005279 100644
--- a/src/Common/EncryptionThreadPool.c
+++ b/src/Common/EncryptionThreadPool.c
@@ -16,9 +16,16 @@
#include "Driver/Ntdriver.h"
#endif
-#define TC_ENC_THREAD_POOL_MAX_THREAD_COUNT 64
+//Increasing the maximum number of threads
+#define TC_ENC_THREAD_POOL_MAX_THREAD_COUNT 256 //64
#define TC_ENC_THREAD_POOL_QUEUE_SIZE (TC_ENC_THREAD_POOL_MAX_THREAD_COUNT * 2)
+#define TC_ENC_THREAD_POOL_LEGACY_MAX_THREAD_COUNT 64
+#define TC_ENC_THREAD_POOL_LEGACY_QUEUE_SIZE (TC_ENC_THREAD_POOL_LEGACY_MAX_THREAD_COUNT * 2)
+
+static volatile size_t ThreadPoolCount = TC_ENC_THREAD_POOL_LEGACY_MAX_THREAD_COUNT;
+static volatile int ThreadQueueSize = TC_ENC_THREAD_POOL_LEGACY_QUEUE_SIZE;
+
#ifdef DEVICE_DRIVER
#define TC_THREAD_HANDLE PKTHREAD
@@ -43,6 +50,18 @@
#define TC_ACQUIRE_MUTEX(MUTEX) WaitForSingleObject (*(MUTEX), INFINITE)
#define TC_RELEASE_MUTEX(MUTEX) ReleaseMutex (*(MUTEX))
+typedef BOOL (WINAPI *SetThreadGroupAffinityFn)(
+ HANDLE hThread,
+ const GROUP_AFFINITY *GroupAffinity,
+ PGROUP_AFFINITY PreviousGroupAffinity
+);
+
+typedef WORD (WINAPI* GetActiveProcessorGroupCountFn)();
+
+typedef DWORD (WINAPI *GetActiveProcessorCountFn)(
+ WORD GroupNumber
+);
+
#endif // !DEVICE_DRIVER
@@ -99,6 +118,7 @@ static volatile BOOL StopPending = FALSE;
static uint32 ThreadCount;
static TC_THREAD_HANDLE ThreadHandles[TC_ENC_THREAD_POOL_MAX_THREAD_COUNT];
+static WORD ThreadProcessorGroups[TC_ENC_THREAD_POOL_MAX_THREAD_COUNT];
static EncryptionThreadPoolWorkItem WorkItemQueue[TC_ENC_THREAD_POOL_QUEUE_SIZE];
@@ -164,6 +184,23 @@ static void SetWorkItemState (EncryptionThreadPoolWorkItem *workItem, WorkItemSt
static TC_THREAD_PROC EncryptionThreadProc (void *threadArg)
{
EncryptionThreadPoolWorkItem *workItem;
+ if (threadArg)
+ {
+#ifdef DEVICE_DRIVER
+ SetThreadCpuGroupAffinity ((USHORT) *(WORD*)(threadArg));
+#else
+ SetThreadGroupAffinityFn SetThreadGroupAffinityPtr = (SetThreadGroupAffinityFn) GetProcAddress (GetModuleHandle (L"kernel32.dll"), "SetThreadGroupAffinity");
+ if (SetThreadGroupAffinityPtr && threadArg)
+ {
+ GROUP_AFFINITY groupAffinity = {0};
+ groupAffinity.Mask = ~0ULL;
+ groupAffinity.Group = *(WORD*)(threadArg);
+ SetThreadGroupAffinityPtr(GetCurrentThread(), &groupAffinity, NULL);
+ }
+
+#endif
+ }
+
while (!StopPending)
{
@@ -171,7 +208,7 @@ static TC_THREAD_PROC EncryptionThreadProc (void *threadArg)
workItem = &WorkItemQueue[DequeuePosition++];
- if (DequeuePosition >= TC_ENC_THREAD_POOL_QUEUE_SIZE)
+ if (DequeuePosition >= ThreadQueueSize)
DequeuePosition = 0;
while (!StopPending && GetWorkItemState (workItem) != WorkItemReady)
@@ -260,23 +297,55 @@ static TC_THREAD_PROC EncryptionThreadProc (void *threadArg)
#endif
}
+#ifndef DEVICE_DRIVER
+
+size_t GetCpuCount (WORD* pGroupCount)
+{
+ size_t cpuCount = 0;
+ SYSTEM_INFO sysInfo;
+ GetActiveProcessorGroupCountFn GetActiveProcessorGroupCountPtr = (GetActiveProcessorGroupCountFn) GetProcAddress (GetModuleHandle (L"Kernel32.dll"), "GetActiveProcessorGroupCount");
+ GetActiveProcessorCountFn GetActiveProcessorCountPtr = (GetActiveProcessorCountFn) GetProcAddress (GetModuleHandle (L"Kernel32.dll"), "GetActiveProcessorCount");
+ if (GetActiveProcessorGroupCountPtr && GetActiveProcessorCountPtr)
+ {
+ WORD j, groupCount = GetActiveProcessorGroupCountPtr();
+ size_t totalProcessors = 0;
+ for (j = 0; j < groupCount; ++j)
+ {
+ totalProcessors += (size_t) GetActiveProcessorCountPtr(j);
+ }
+ cpuCount = totalProcessors;
+ if (pGroupCount)
+ *pGroupCount = groupCount;
+ }
+ else
+ {
+ GetSystemInfo(&sysInfo);
+ cpuCount = (size_t) sysInfo.dwNumberOfProcessors;
+ if (pGroupCount)
+ *pGroupCount = 1;
+ }
+
+ return cpuCount;
+}
+
+#endif
+
BOOL EncryptionThreadPoolStart (size_t encryptionFreeCpuCount)
{
- size_t cpuCount, i;
+ size_t cpuCount = 0, i = 0;
+ WORD groupCount = 1;
+
+ cpuCount = GetCpuCount(&groupCount);
if (ThreadPoolRunning)
return TRUE;
-#ifdef DEVICE_DRIVER
- cpuCount = GetCpuCount();
-#else
+ if (groupCount > 1)
{
- SYSTEM_INFO sysInfo;
- GetSystemInfo (&sysInfo);
- cpuCount = sysInfo.dwNumberOfProcessors;
+ ThreadPoolCount = TC_ENC_THREAD_POOL_MAX_THREAD_COUNT;
+ ThreadQueueSize = TC_ENC_THREAD_POOL_QUEUE_SIZE;
}
-#endif
if (cpuCount > encryptionFreeCpuCount)
cpuCount -= encryptionFreeCpuCount;
@@ -284,8 +353,8 @@ BOOL EncryptionThreadPoolStart (size_t encryptionFreeCpuCount)
if (cpuCount < 2)
return TRUE;
- if (cpuCount > TC_ENC_THREAD_POOL_MAX_THREAD_COUNT)
- cpuCount = TC_ENC_THREAD_POOL_MAX_THREAD_COUNT;
+ if (cpuCount > ThreadPoolCount)
+ cpuCount = ThreadPoolCount;
StopPending = FALSE;
DequeuePosition = 0;
@@ -337,11 +406,40 @@ BOOL EncryptionThreadPoolStart (size_t encryptionFreeCpuCount)
for (ThreadCount = 0; ThreadCount < cpuCount; ++ThreadCount)
{
+ WORD* pThreadArg = NULL;
+ if (groupCount > 1)
+ {
+#ifdef DEVICE_DRIVER
+ ThreadProcessorGroups[ThreadCount] = GetCpuGroup ((size_t) ThreadCount);
+#else
+ GetActiveProcessorCountFn GetActiveProcessorCountPtr = (GetActiveProcessorCountFn) GetProcAddress (GetModuleHandle (L"Kernel32.dll"), "GetActiveProcessorCount");
+ // Determine which processor group to bind the thread to.
+ if (GetActiveProcessorCountPtr)
+ {
+ WORD j;
+ uint32 totalProcessors = 0U;
+ for (j = 0U; j < groupCount; j++)
+ {
+ totalProcessors += (uint32) GetActiveProcessorCountPtr(j);
+ if (totalProcessors >= ThreadCount)
+ {
+ ThreadProcessorGroups[ThreadCount] = j;
+ break;
+ }
+ }
+ }
+ else
+ ThreadProcessorGroups[ThreadCount] = 0;
+#endif
+ pThreadArg = &ThreadProcessorGroups[ThreadCount];
+ }
+
#ifdef DEVICE_DRIVER
- if (!NT_SUCCESS (TCStartThread (EncryptionThreadProc, NULL, &ThreadHandles[ThreadCount])))
+ if (!NT_SUCCESS(TCStartThread(EncryptionThreadProc, (void*) pThreadArg, &ThreadHandles[ThreadCount])))
#else
- if (!(ThreadHandles[ThreadCount] = (HANDLE) _beginthreadex (NULL, 0, EncryptionThreadProc, NULL, 0, NULL)))
+ if (!(ThreadHandles[ThreadCount] = (HANDLE)_beginthreadex(NULL, 0, EncryptionThreadProc, (void*) pThreadArg, 0, NULL)))
#endif
+
{
EncryptionThreadPoolStop();
return FALSE;
@@ -402,7 +500,7 @@ void EncryptionThreadPoolBeginKeyDerivation (TC_EVENT *completionEvent, TC_EVENT
TC_ACQUIRE_MUTEX (&EnqueueMutex);
workItem = &WorkItemQueue[EnqueuePosition++];
- if (EnqueuePosition >= TC_ENC_THREAD_POOL_QUEUE_SIZE)
+ if (EnqueuePosition >= ThreadQueueSize)
EnqueuePosition = 0;
while (GetWorkItemState (workItem) != WorkItemFree)
@@ -501,7 +599,7 @@ void EncryptionThreadPoolDoWork (EncryptionThreadPoolWorkType type, byte *data,
while (fragmentCount-- > 0)
{
workItem = &WorkItemQueue[EnqueuePosition++];
- if (EnqueuePosition >= TC_ENC_THREAD_POOL_QUEUE_SIZE)
+ if (EnqueuePosition >= ThreadQueueSize)
EnqueuePosition = 0;
while (GetWorkItemState (workItem) != WorkItemFree)
@@ -543,7 +641,7 @@ size_t GetEncryptionThreadCount ()
size_t GetMaxEncryptionThreadCount ()
{
- return TC_ENC_THREAD_POOL_MAX_THREAD_COUNT;
+ return ThreadPoolCount;
}
diff --git a/src/Common/EncryptionThreadPool.h b/src/Common/EncryptionThreadPool.h
index 6a28062..161fb7c 100644
--- a/src/Common/EncryptionThreadPool.h
+++ b/src/Common/EncryptionThreadPool.h
@@ -27,6 +27,10 @@ typedef enum
DeriveKeyWork
} EncryptionThreadPoolWorkType;
+#ifndef DEVICE_DRIVER
+size_t GetCpuCount (WORD* pGroupCount);
+#endif
+
void EncryptionThreadPoolBeginKeyDerivation (TC_EVENT *completionEvent, TC_EVENT *noOutstandingWorkItemEvent, LONG *completionFlag, LONG *outstandingWorkItemCount, int pkcs5Prf, char *password, int passwordLength, char *salt, int iterationCount, char *derivedKey);
void EncryptionThreadPoolDoWork (EncryptionThreadPoolWorkType type, byte *data, const UINT64_STRUCT *startUnitNo, uint32 unitCount, PCRYPTO_INFO cryptoInfo);
BOOL EncryptionThreadPoolStart (size_t encryptionFreeCpuCount);
diff --git a/src/Common/Fat.c b/src/Common/Fat.c
index b47e531..cd2c124 100644
--- a/src/Common/Fat.c
+++ b/src/Common/Fat.c
@@ -394,6 +394,8 @@ FormatFat (void* hwndDlgPtr, unsigned __int64 startSector, fatparams * ft, void
if(!quickFormat)
{
+ CRYPTO_INFO tmpCI;
+
if (!FlushFormatWriteBuffer (dev, write_buf, &write_buf_cnt, &nSecNo, cryptoInfo))
goto fail;
@@ -402,26 +404,49 @@ FormatFat (void* hwndDlgPtr, unsigned __int64 startSector, fatparams * ft, void
deniability of hidden volumes (and also reduces the amount of predictable plaintext
within the volume). */
+ VirtualLock (&tmpCI, sizeof (tmpCI));
+ memcpy (&tmpCI, cryptoInfo, sizeof (CRYPTO_INFO));
+ cryptoInfo = &tmpCI;
+
// Temporary master key
if (!RandgetBytes (hwndDlg, temporaryKey, EAGetKeySize (cryptoInfo->ea), FALSE))
+ {
+ burn (&tmpCI, sizeof (tmpCI));
+ VirtualUnlock (&tmpCI, sizeof (tmpCI));
goto fail;
+ }
// Temporary secondary key (XTS mode)
if (!RandgetBytes (hwndDlg, cryptoInfo->k2, sizeof cryptoInfo->k2, FALSE))
+ {
+ burn (&tmpCI, sizeof (tmpCI));
+ VirtualUnlock (&tmpCI, sizeof (tmpCI));
goto fail;
+ }
retVal = EAInit (cryptoInfo->ea, temporaryKey, cryptoInfo->ks);
if (retVal != ERR_SUCCESS)
{
+ TCfree (write_buf);
burn (temporaryKey, sizeof(temporaryKey));
+ burn (&tmpCI, sizeof (tmpCI));
+ VirtualUnlock (&tmpCI, sizeof (tmpCI));
return retVal;
}
if (!EAInitMode (cryptoInfo, cryptoInfo->k2))
{
+ TCfree (write_buf);
burn (temporaryKey, sizeof(temporaryKey));
+ burn (&tmpCI, sizeof (tmpCI));
+ VirtualUnlock (&tmpCI, sizeof (tmpCI));
return ERR_MODE_INIT_FAILED;
}
+#ifdef _WIN64
+ if (IsRamEncryptionEnabled ())
+ VcProtectKeys (cryptoInfo, VcGetEncryptionID (cryptoInfo));
+#endif
+
x = ft->num_sectors - ft->reserved - ft->size_root_dir / ft->sector_size - ft->fat_length * 2;
while (x--)
{
@@ -430,12 +455,24 @@ FormatFat (void* hwndDlgPtr, unsigned __int64 startSector, fatparams * ft, void
goto fail;
}
UpdateProgressBar (nSecNo * ft->sector_size);
+
+ if (!FlushFormatWriteBuffer (dev, write_buf, &write_buf_cnt, &nSecNo, cryptoInfo))
+ {
+ burn (&tmpCI, sizeof (tmpCI));
+ VirtualUnlock (&tmpCI, sizeof (tmpCI));
+ goto fail;
+ }
+
+ burn (&tmpCI, sizeof (tmpCI));
+ VirtualUnlock (&tmpCI, sizeof (tmpCI));
}
else
+ {
UpdateProgressBar ((uint64) ft->num_sectors * ft->sector_size);
- if (!FlushFormatWriteBuffer (dev, write_buf, &write_buf_cnt, &nSecNo, cryptoInfo))
- goto fail;
+ if (!FlushFormatWriteBuffer (dev, write_buf, &write_buf_cnt, &nSecNo, cryptoInfo))
+ goto fail;
+ }
TCfree (write_buf);
burn (temporaryKey, sizeof(temporaryKey));
diff --git a/src/Common/Format.c b/src/Common/Format.c
index 82c4df5..f691c78 100644
--- a/src/Common/Format.c
+++ b/src/Common/Format.c
@@ -100,6 +100,10 @@ int TCFormatVolume (volatile FORMAT_VOL_PARAMETERS *volParams)
LARGE_INTEGER offset;
BOOL bFailedRequiredDASD = FALSE;
HWND hwndDlg = volParams->hwndDlg;
+#ifdef _WIN64
+ CRYPTO_INFO tmpCI;
+ PCRYPTO_INFO cryptoInfoBackup = NULL;
+#endif
FormatSectorSize = volParams->sectorSize;
@@ -369,8 +373,13 @@ begin_format:
if (!volParams->hiddenVol && !bInstantRetryOtherFilesys)
{
LARGE_INTEGER volumeSize;
+ BOOL speedupFileCreation = FALSE;
volumeSize.QuadPart = dataAreaSize + TC_VOLUME_HEADER_GROUP_SIZE;
+ // speedup for file creation only makes sens when using quick format
+ if (volParams->quickFormat && volParams->fastCreateFile)
+ speedupFileCreation = TRUE;
+
if (volParams->sparseFileSwitch && volParams->quickFormat)
{
// Create as sparse file container
@@ -384,12 +393,28 @@ begin_format:
// Preallocate the file
if (!SetFilePointerEx (dev, volumeSize, NULL, FILE_BEGIN)
- || !SetEndOfFile (dev)
- || SetFilePointer (dev, 0, NULL, FILE_BEGIN) != 0)
+ || !SetEndOfFile (dev))
{
nStatus = ERR_OS_ERROR;
goto error;
}
+
+ if (speedupFileCreation)
+ {
+ // accelerate file creation by telling Windows not to fill all file content with zeros
+ // this has security issues since it will put existing disk content into file container
+ // We use this mechanism only when switch /fastCreateFile specific and when quick format
+ // also specified and which is documented to have security issues.
+ // we don't check returned status because failure is not issue for us
+ SetFileValidData (dev, volumeSize.QuadPart);
+ }
+
+ if (SetFilePointer (dev, 0, NULL, FILE_BEGIN) != 0)
+ {
+ nStatus = ERR_OS_ERROR;
+ goto error;
+ }
+
}
}
@@ -553,6 +578,17 @@ begin_format:
goto error;
}
+#ifdef _WIN64
+ if (IsRamEncryptionEnabled ())
+ {
+ VirtualLock (&tmpCI, sizeof (tmpCI));
+ memcpy (&tmpCI, cryptoInfo, sizeof (CRYPTO_INFO));
+ VcUnprotectKeys (&tmpCI, VcGetEncryptionID (cryptoInfo));
+ cryptoInfoBackup = cryptoInfo;
+ cryptoInfo = &tmpCI;
+ }
+#endif
+
nStatus = CreateVolumeHeaderInMemory (hwndDlg, FALSE,
header,
volParams->ea,
@@ -571,6 +607,15 @@ begin_format:
FormatSectorSize,
FALSE);
+#ifdef _WIN64
+ if (IsRamEncryptionEnabled ())
+ {
+ cryptoInfo = cryptoInfoBackup;
+ burn (&tmpCI, sizeof (CRYPTO_INFO));
+ VirtualUnlock (&tmpCI, sizeof (tmpCI));
+ }
+#endif
+
if (!WriteEffectiveVolumeHeader (volParams->bDevice, dev, header))
{
nStatus = ERR_OS_ERROR;
@@ -582,8 +627,28 @@ begin_format:
{
BOOL bUpdateBackup = FALSE;
+#ifdef _WIN64
+ if (IsRamEncryptionEnabled ())
+ {
+ VirtualLock (&tmpCI, sizeof (tmpCI));
+ memcpy (&tmpCI, cryptoInfo, sizeof (CRYPTO_INFO));
+ VcUnprotectKeys (&tmpCI, VcGetEncryptionID (cryptoInfo));
+ cryptoInfoBackup = cryptoInfo;
+ cryptoInfo = &tmpCI;
+ }
+#endif
+
nStatus = WriteRandomDataToReservedHeaderAreas (hwndDlg, dev, cryptoInfo, dataAreaSize, FALSE, FALSE);
+#ifdef _WIN64
+ if (IsRamEncryptionEnabled ())
+ {
+ cryptoInfo = cryptoInfoBackup;
+ burn (&tmpCI, sizeof (CRYPTO_INFO));
+ VirtualUnlock (&tmpCI, sizeof (tmpCI));
+ }
+#endif
+
if (nStatus != ERR_SUCCESS)
goto error;
@@ -697,13 +762,13 @@ error:
}
mountOptions.ReadOnly = FALSE;
- mountOptions.Removable = FALSE;
+ mountOptions.Removable = TRUE; /* mount as removal media to allow formatting without admin rights */
mountOptions.ProtectHiddenVolume = FALSE;
mountOptions.PreserveTimestamp = bPreserveTimestamp;
mountOptions.PartitionInInactiveSysEncScope = FALSE;
mountOptions.UseBackupHeader = FALSE;
- if (MountVolume (volParams->hwndDlg, driveNo, volParams->volumePath, volParams->password, volParams->pkcs5, volParams->pim, FALSE, FALSE, FALSE, TRUE, &mountOptions, FALSE, TRUE) < 1)
+ if (MountVolume (volParams->hwndDlg, driveNo, volParams->volumePath, volParams->password, volParams->pkcs5, volParams->pim, FALSE, FALSE, FALSE, TRUE, &mountOptions, Silent, TRUE) < 1)
{
if (!Silent)
{
@@ -714,10 +779,15 @@ error:
goto fv_end;
}
- if (!Silent && !IsAdmin () && IsUacSupported ())
- retCode = UacFormatFs (volParams->hwndDlg, driveNo, volParams->clusterSize, fsType);
- else
- retCode = FormatFs (driveNo, volParams->clusterSize, fsType);
+ retCode = ExternalFormatFs (driveNo, volParams->clusterSize, fsType);
+ if (retCode != TRUE)
+ {
+ /* fallback to using FormatEx function from fmifs.dll */
+ if (!Silent && !IsAdmin () && IsUacSupported ())
+ retCode = UacFormatFs (volParams->hwndDlg, driveNo, volParams->clusterSize, fsType);
+ else
+ retCode = FormatFs (driveNo, volParams->clusterSize, fsType);
+ }
if (retCode != TRUE)
{
@@ -773,6 +843,10 @@ int FormatNoFs (HWND hwndDlg, unsigned __int64 startSector, __int64 num_sectors,
LARGE_INTEGER startOffset;
LARGE_INTEGER newOffset;
+#ifdef _WIN64
+ CRYPTO_INFO tmpCI;
+#endif
+
// Seek to start sector
startOffset.QuadPart = startSector * FormatSectorSize;
if (!SetFilePointerEx ((HANDLE) dev, startOffset, &newOffset, FILE_BEGIN)
@@ -790,6 +864,16 @@ int FormatNoFs (HWND hwndDlg, unsigned __int64 startSector, __int64 num_sectors,
memset (sector, 0, sizeof (sector));
+#ifdef _WIN64
+ if (IsRamEncryptionEnabled ())
+ {
+ VirtualLock (&tmpCI, sizeof (tmpCI));
+ memcpy (&tmpCI, cryptoInfo, sizeof (CRYPTO_INFO));
+ VcUnprotectKeys (&tmpCI, VcGetEncryptionID (cryptoInfo));
+ cryptoInfo = &tmpCI;
+ }
+#endif
+
// Remember the original secondary key (XTS mode) before generating a temporary one
memcpy (originalK2, cryptoInfo->k2, sizeof (cryptoInfo->k2));
@@ -819,6 +903,11 @@ int FormatNoFs (HWND hwndDlg, unsigned __int64 startSector, __int64 num_sectors,
goto fail;
}
+#ifdef _WIN64
+ if (IsRamEncryptionEnabled ())
+ VcProtectKeys (cryptoInfo, VcGetEncryptionID (cryptoInfo));
+#endif
+
while (num_sectors--)
{
if (WriteSector (dev, sector, write_buf, &write_buf_cnt, &nSecNo,
@@ -852,6 +941,13 @@ int FormatNoFs (HWND hwndDlg, unsigned __int64 startSector, __int64 num_sectors,
VirtualUnlock (temporaryKey, sizeof (temporaryKey));
VirtualUnlock (originalK2, sizeof (originalK2));
TCfree (write_buf);
+#ifdef _WIN64
+ if (IsRamEncryptionEnabled ())
+ {
+ burn (&tmpCI, sizeof (CRYPTO_INFO));
+ VirtualUnlock (&tmpCI, sizeof (tmpCI));
+ }
+#endif
return 0;
@@ -863,6 +959,13 @@ fail:
VirtualUnlock (temporaryKey, sizeof (temporaryKey));
VirtualUnlock (originalK2, sizeof (originalK2));
TCfree (write_buf);
+#ifdef _WIN64
+ if (IsRamEncryptionEnabled ())
+ {
+ burn (&tmpCI, sizeof (CRYPTO_INFO));
+ VirtualUnlock (&tmpCI, sizeof (tmpCI));
+ }
+#endif
SetLastError (err);
return (retVal ? retVal : ERR_OS_ERROR);
@@ -996,6 +1099,151 @@ BOOL FormatNtfs (int driveNo, int clusterSize)
return FormatFs (driveNo, clusterSize, FILESYS_NTFS);
}
+/* call Windows format.com program to perform formatting */
+BOOL ExternalFormatFs (int driveNo, int clusterSize, int fsType)
+{
+ wchar_t exePath[MAX_PATH] = {0};
+ HANDLE hChildStd_IN_Rd = NULL;
+ HANDLE hChildStd_IN_Wr = NULL;
+ HANDLE hChildStd_OUT_Rd = NULL;
+ HANDLE hChildStd_OUT_Wr = NULL;
+ WCHAR szFsFormat[16];
+ TCHAR szCmdline[2 * MAX_PATH];
+ STARTUPINFO siStartInfo;
+ PROCESS_INFORMATION piProcInfo;
+ BOOL bSuccess = FALSE;
+ SECURITY_ATTRIBUTES saAttr;
+
+ switch (fsType)
+ {
+ case FILESYS_NTFS:
+ StringCchCopyW (szFsFormat, ARRAYSIZE (szFsFormat),L"NTFS");
+ break;
+ case FILESYS_EXFAT:
+ StringCchCopyW (szFsFormat, ARRAYSIZE (szFsFormat),L"exFAT");
+ break;
+ case FILESYS_REFS:
+ StringCchCopyW (szFsFormat, ARRAYSIZE (szFsFormat),L"ReFS");
+ break;
+ default:
+ return FALSE;
+ }
+
+ /* Set the bInheritHandle flag so pipe handles are inherited. */
+ saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
+ saAttr.bInheritHandle = TRUE;
+ saAttr.lpSecurityDescriptor = NULL;
+
+ /* Create a pipe for the child process's STDOUT. */
+ if ( !CreatePipe(&hChildStd_OUT_Rd, &hChildStd_OUT_Wr, &saAttr, 0) )
+ return FALSE;
+
+ /* Ensure the read handle to the pipe for STDOUT is not inherited. */
+ /* Create a pipe for the child process's STDIN. */
+ if ( !SetHandleInformation(hChildStd_OUT_Rd, HANDLE_FLAG_INHERIT, 0)
+ || !CreatePipe(&hChildStd_IN_Rd, &hChildStd_IN_Wr, &saAttr, 0))
+ {
+ CloseHandle (hChildStd_OUT_Rd);
+ CloseHandle (hChildStd_OUT_Wr);
+ return FALSE;
+ }
+
+ /* Ensure the write handle to the pipe for STDIN is not inherited. */
+ if ( !SetHandleInformation(hChildStd_IN_Wr, HANDLE_FLAG_INHERIT, 0))
+ {
+ CloseHandle (hChildStd_OUT_Rd);
+ CloseHandle (hChildStd_OUT_Wr);
+ CloseHandle (hChildStd_IN_Rd);
+ CloseHandle (hChildStd_IN_Wr);
+ return FALSE;
+ }
+
+ if (GetSystemDirectory (exePath, MAX_PATH))
+ {
+ StringCchCatW(exePath, ARRAYSIZE(exePath), L"\\format.com");
+ }
+ else
+ StringCchCopyW(exePath, ARRAYSIZE(exePath), L"C:\\Windows\\System32\\format.com");
+
+ StringCbPrintf (szCmdline, sizeof(szCmdline), L"%s %c: /FS:%s /Q /X /V:\"\"", exePath, (WCHAR) driveNo + L'A', szFsFormat);
+
+ if (clusterSize)
+ {
+ WCHAR szSize[8];
+ uint32 unitSize = (uint32) clusterSize * FormatSectorSize;
+ if (unitSize <= 8192)
+ StringCbPrintf (szSize, sizeof (szSize), L"%d", unitSize);
+ else if (unitSize < BYTES_PER_MB)
+ {
+ StringCbPrintf (szSize, sizeof (szSize), L"%dK", unitSize / BYTES_PER_KB);
+ }
+ else
+ StringCbPrintf (szSize, sizeof (szSize), L"%dM", unitSize / BYTES_PER_MB);
+
+ StringCbCat (szCmdline, sizeof (szCmdline), L" /A:");
+ StringCbCat (szCmdline, sizeof (szCmdline), szSize);
+ }
+
+
+ ZeroMemory( &piProcInfo, sizeof(PROCESS_INFORMATION) );
+
+ /* Set up members of the STARTUPINFO structure.
+ This structure specifies the STDIN and STDOUT handles for redirection.
+ */
+ ZeroMemory( &siStartInfo, sizeof(STARTUPINFO) );
+ siStartInfo.cb = sizeof(STARTUPINFO);
+ siStartInfo.hStdError = hChildStd_OUT_Wr;
+ siStartInfo.hStdOutput = hChildStd_OUT_Wr;
+ siStartInfo.hStdInput = hChildStd_IN_Rd;
+ siStartInfo.wShowWindow = SW_HIDE;
+ siStartInfo.dwFlags |= STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
+
+ /* Create the child process. */
+ bSuccess = CreateProcess(NULL,
+ szCmdline, // command line
+ NULL, // process security attributes
+ NULL, // primary thread security attributes
+ TRUE, // handles are inherited
+ 0, // creation flags
+ NULL, // use parent's environment
+ NULL, // use parent's current directory
+ &siStartInfo, // STARTUPINFO pointer
+ &piProcInfo); // receives PROCESS_INFORMATION
+
+ if (bSuccess)
+ {
+ /* Unblock the format process by simulating hit on ENTER key */
+ DWORD dwExitCode, dwWritten;
+ LPCSTR newLine = "\n";
+
+ WriteFile(hChildStd_IN_Wr, (LPCVOID) newLine, 1, &dwWritten, NULL);
+
+ /* wait for the format process to finish */
+ WaitForSingleObject (piProcInfo.hProcess, INFINITE);
+
+ /* check if it was successfull */
+ if (GetExitCodeProcess (piProcInfo.hProcess, &dwExitCode))
+ {
+ if (dwExitCode == 0)
+ bSuccess = TRUE;
+ else
+ bSuccess = FALSE;
+ }
+ else
+ bSuccess = FALSE;
+
+ CloseHandle (piProcInfo.hThread);
+ CloseHandle (piProcInfo.hProcess);
+ }
+
+ CloseHandle(hChildStd_OUT_Wr);
+ CloseHandle(hChildStd_OUT_Rd);
+ CloseHandle(hChildStd_IN_Rd);
+ CloseHandle(hChildStd_IN_Wr);
+
+ return bSuccess;
+}
+
BOOL WriteSector (void *dev, char *sector,
char *write_buf, int *write_buf_cnt,
__int64 *nSecNo, PCRYPTO_INFO cryptoInfo)
diff --git a/src/Common/Format.h b/src/Common/Format.h
index 961ece7..139607e 100644
--- a/src/Common/Format.h
+++ b/src/Common/Format.h
@@ -38,6 +38,7 @@ typedef struct
unsigned int clusterSize;
BOOL sparseFileSwitch;
BOOL quickFormat;
+ BOOL fastCreateFile;
DWORD sectorSize;
int *realClusterSize;
Password *password;
@@ -75,6 +76,7 @@ extern int FormatWriteBufferSize;
int TCFormatVolume (volatile FORMAT_VOL_PARAMETERS *volParams);
BOOL FormatNtfs (int driveNo, int clusterSize);
BOOL FormatFs (int driveNo, int clusterSize, int fsType);
+BOOL ExternalFormatFs (int driveNo, int clusterSize, int fsType);
uint64 GetVolumeDataAreaSize (BOOL hiddenVolume, uint64 volumeSize);
int FormatNoFs (HWND hwndDlg, unsigned __int64 startSector, __int64 num_sectors, void *dev, PCRYPTO_INFO cryptoInfo, BOOL quickFormat);
BOOL WriteSector ( void *dev , char *sector , char *write_buf , int *write_buf_cnt , __int64 *nSecNo , PCRYPTO_INFO cryptoInfo );
diff --git a/src/Common/Language.c b/src/Common/Language.c
index 6dbd8b6..ffccd44 100644
--- a/src/Common/Language.c
+++ b/src/Common/Language.c
@@ -209,6 +209,7 @@ static BOOL LoadLanguageData (int resourceid, BOOL bForceSetPreferredLanguage, B
LocalizationActive = FALSE;
ActiveLangPackVersion[0] = 0;
ClearDictionaryPool ();
+ LanguageResource = NULL;
if ((resourceid == 0) && (PreferredLangId[0] != 0))
StringCbCopyA (langId, sizeof(langId), PreferredLangId);
diff --git a/src/Common/Language.xml b/src/Common/Language.xml
index 18dbaf1..3144c3a 100644
--- a/src/Common/Language.xml
+++ b/src/Common/Language.xml
@@ -1378,7 +1378,7 @@
<entry lang="en" key="IDC_BOOT_LOADER_CACHE_PIM">Include &amp;PIM when caching pre-boot authentication password</entry>
<entry lang="en" key="IDC_PREF_CACHE_PIM">Include PIM when caching a password</entry>
<entry lang="en" key="IDC_SHOW_DISCONNECTED_NETWORK_DRIVES">Make disconnected network drives available for mounting</entry>
- <entry lang="en" key="PASSWORD_UTF8_TOO_LONG">The entered password is too long: its UTF-8 representation exceeds 128 bytes.</entry>
+ <entry lang="en" key="PASSWORD_UTF8_TOO_LONG">The entered password is too long: its UTF-8 representation exceeds %d bytes.</entry>
<entry lang="en" key="PASSWORD_UTF8_INVALID">The entered password contains Unicode characters that couldn't be converted to UTF-8 representation.</entry>
<entry lang="en" key="INIT_DLL">Error: Failed to load a system library.</entry>
<entry lang="en" key="ERR_EXFAT_INVALID_VOLUME_SIZE">The volume file size specified in the command line is incompatible with selected exFAT filesystem.</entry>
@@ -1421,8 +1421,8 @@
<entry lang="en" key="IDC_BLOCK_SYSENC_TRIM">Block TRIM command on system partition/drive</entry>
<entry lang="en" key="WINDOWS_EFI_BOOT_LOADER_MISSING">ERROR: Windows EFI system loader could not be located on the disk. Operation will be aborted.</entry>
<entry lang="en" key="SYSENC_EFI_UNSUPPORTED_SECUREBOOT">It is currently not possible to encrypt a system if SecureBoot is enabled and if VeraCrypt custom keys are not loaded into the machine firmware. SecureBoot needs to be disabled in the BIOS configuration in order to allow system encryption to proceed.</entry>
- <entry lang="en" key="PASSWORD_PASTED_TRUNCATED">Pasted text truncated because the password maximum length is 128 characters</entry>
- <entry lang="en" key="PASSWORD_MAXLENGTH_REACHED">Password already reached its maximum length of 128 characters.\nNo additional character is allowed.</entry>
+ <entry lang="en" key="PASSWORD_PASTED_TRUNCATED">Pasted text truncated because the password maximum length is %d characters</entry>
+ <entry lang="en" key="PASSWORD_MAXLENGTH_REACHED">Password already reached its maximum length of %d characters.\nNo additional character is allowed.</entry>
<entry lang="en" key="IDC_SELECT_LANGUAGE_LABEL">Select the language to use during the installation:</entry>
<entry lang="en" key="VOLUME_TOO_LARGE_FOR_HOST">ERROR: The size of the file container is larger than the available free space on disk.</entry>
<entry lang="en" key="IDC_ALLOW_WINDOWS_DEFRAG">Allow Windows Disk Defragmenter to defragment non-system partition/drive</entry>
@@ -1438,6 +1438,14 @@
<entry lang="en" key="IDT_BENCHMARK">Benchmark:</entry>
<entry lang="en" key="IDC_DISABLE_MOUNT_MANAGER">Only create virtual device without mounting on selected drive letter</entry>
<entry lang="en" key="LEGACY_PASSWORD_UTF8_TOO_LONG">The entered password is too long: its UTF-8 representation exceeds 64 bytes.</entry>
+ <entry lang="en" key="HIDDEN_CREDS_SAME_AS_OUTER">The Hidden volume can't have the same password, PIM and keyfiles as the Outer volume</entry>
+ <entry lang="en" key="SYSENC_BITLOCKER_CONFLICT">VeraCrypt does not support encrypting a system drive that is already encrypted by BitLocker.</entry>
+ <entry lang="en" key="IDC_UPDATE_BOOTLOADER_ON_SHUTDOWN">Automatically fix boot configuration issues that may prevent Windows from starting</entry>
+ <entry lang="en" key="IDC_FORCE_NEXT_BOOT_VERACRYPT">Force machine to boot on VeraCrypt in the next startup</entry>
+ <entry lang="en" key="IDC_FORCE_VERACRYPT_BOOT_ENTRY">Force the presence of VeraCrypt entry in the EFI firmware boot menu</entry>
+ <entry lang="en" key="IDC_FORCE_VERACRYPT_FIRST_BOOT_ENTRY">Force VeraCrypt entry to be the first in the EFI firmware boot menu</entry>
+ <entry lang="en" key="RAM_ENCRYPTION_DISABLE_HIBERNATE">WARNING: RAM encryption is not compatible with Windows Hibernate and Windows Fast Startup features. VeraCrypt needs to disable them before activating RAM encryption.\n\nContinue?</entry>
+ <entry lang="en" key="CONFIRM_DISABLE_FAST_STARTUP">WARNING: Windows Fast Startup is enabled and it is known to cause issues when working with VeraCrypt volumes. It is advised to disable it for better security and usability.\n\nDo you want to disable Windows Fast Startup?</entry>
</localization>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="VeraCrypt">
diff --git a/src/Common/SecurityToken.cpp b/src/Common/SecurityToken.cpp
index 841ca72..8401a0e 100644
--- a/src/Common/SecurityToken.cpp
+++ b/src/Common/SecurityToken.cpp
@@ -26,12 +26,12 @@
# include <dlfcn.h>
#endif
-#include "SecurityToken.h"
-
-#ifndef burn
-# define burn Memory::Erase
+#ifdef TC_WINDOWS
+#define move_ptr std::move
#endif
+#include "SecurityToken.h"
+
using namespace std;
namespace VeraCrypt
@@ -513,9 +513,9 @@ namespace VeraCrypt
}
#ifdef TC_WINDOWS
- void SecurityToken::InitLibrary (const wstring &pkcs11LibraryPath, auto_ptr <GetPinFunctor> pinCallback, auto_ptr <SendExceptionFunctor> warningCallback)
+ void SecurityToken::InitLibrary (const wstring &pkcs11LibraryPath, unique_ptr <GetPinFunctor> pinCallback, unique_ptr <SendExceptionFunctor> warningCallback)
#else
- void SecurityToken::InitLibrary (const string &pkcs11LibraryPath, auto_ptr <GetPinFunctor> pinCallback, auto_ptr <SendExceptionFunctor> warningCallback)
+ void SecurityToken::InitLibrary (const string &pkcs11LibraryPath, unique_ptr <GetPinFunctor> pinCallback, unique_ptr <SendExceptionFunctor> warningCallback)
#endif
{
if (Initialized)
@@ -548,8 +548,8 @@ namespace VeraCrypt
if (status != CKR_OK)
throw Pkcs11Exception (status);
- PinCallback = pinCallback;
- WarningCallback = warningCallback;
+ PinCallback = move_ptr(pinCallback);
+ WarningCallback = move_ptr(warningCallback);
Initialized = true;
}
@@ -728,8 +728,8 @@ namespace VeraCrypt
}
#endif // TC_HEADER_Common_Exception
- auto_ptr <GetPinFunctor> SecurityToken::PinCallback;
- auto_ptr <SendExceptionFunctor> SecurityToken::WarningCallback;
+ unique_ptr <GetPinFunctor> SecurityToken::PinCallback;
+ unique_ptr <SendExceptionFunctor> SecurityToken::WarningCallback;
bool SecurityToken::Initialized;
CK_FUNCTION_LIST_PTR SecurityToken::Pkcs11Functions;
diff --git a/src/Common/SecurityToken.h b/src/Common/SecurityToken.h
index 1112f11..6b22889 100644
--- a/src/Common/SecurityToken.h
+++ b/src/Common/SecurityToken.h
@@ -191,9 +191,9 @@ namespace VeraCrypt
static list <SecurityTokenInfo> GetAvailableTokens ();
static SecurityTokenInfo GetTokenInfo (CK_SLOT_ID slotId);
#ifdef TC_WINDOWS
- static void InitLibrary (const wstring &pkcs11LibraryPath, auto_ptr <GetPinFunctor> pinCallback, auto_ptr <SendExceptionFunctor> warningCallback);
+ static void InitLibrary (const wstring &pkcs11LibraryPath, unique_ptr <GetPinFunctor> pinCallback, unique_ptr <SendExceptionFunctor> warningCallback);
#else
- static void InitLibrary (const string &pkcs11LibraryPath, auto_ptr <GetPinFunctor> pinCallback, auto_ptr <SendExceptionFunctor> warningCallback);
+ static void InitLibrary (const string &pkcs11LibraryPath, unique_ptr <GetPinFunctor> pinCallback, unique_ptr <SendExceptionFunctor> warningCallback);
#endif
static bool IsInitialized () { return Initialized; }
static bool IsKeyfilePathValid (const wstring &securityTokenKeyfilePath);
@@ -211,7 +211,7 @@ namespace VeraCrypt
static void CheckLibraryStatus ();
static bool Initialized;
- static auto_ptr <GetPinFunctor> PinCallback;
+ static unique_ptr <GetPinFunctor> PinCallback;
static CK_FUNCTION_LIST_PTR Pkcs11Functions;
#ifdef TC_WINDOWS
static HMODULE Pkcs11LibraryHandle;
@@ -219,7 +219,7 @@ namespace VeraCrypt
static void *Pkcs11LibraryHandle;
#endif
static map <CK_SLOT_ID, Pkcs11Session> Sessions;
- static auto_ptr <SendExceptionFunctor> WarningCallback;
+ static unique_ptr <SendExceptionFunctor> WarningCallback;
};
}
diff --git a/src/Common/Tcdefs.h b/src/Common/Tcdefs.h
index 79180c1..2ce5f9f 100644
--- a/src/Common/Tcdefs.h
+++ b/src/Common/Tcdefs.h
@@ -55,7 +55,7 @@ extern unsigned short _rotl16(unsigned short value, unsigned char shift);
#define TC_APP_NAME "VeraCrypt"
// Version displayed to user
-#define VERSION_STRING "1.24-Hotfix2"
+#define VERSION_STRING "1.24-Update7"
#ifdef VC_EFI_CUSTOM_MODE
#define VERSION_STRING_SUFFIX "-CustomEFI"
@@ -67,9 +67,9 @@ extern unsigned short _rotl16(unsigned short value, unsigned char shift);
#define VERSION_NUM 0x0124
// Release date
-#define TC_STR_RELEASE_DATE L"November 4, 2019"
-#define TC_RELEASE_DATE_YEAR 2019
-#define TC_RELEASE_DATE_MONTH 11
+#define TC_STR_RELEASE_DATE L"August 7, 2020"
+#define TC_RELEASE_DATE_YEAR 2020
+#define TC_RELEASE_DATE_MONTH 8
#define BYTES_PER_KB 1024LL
#define BYTES_PER_MB 1048576LL
@@ -263,6 +263,10 @@ extern ULONG AllocTag;
typedef int BOOL;
#endif
+#ifndef WORD
+typedef USHORT WORD;
+#endif
+
#ifndef BOOLEAN
typedef unsigned char BOOLEAN;
#endif
@@ -295,6 +299,17 @@ typedef NTSTATUS (NTAPI *ExGetFirmwareEnvironmentVariableFn) (
typedef BOOLEAN (NTAPI *KeAreAllApcsDisabledFn) ();
+typedef void (NTAPI *KeSetSystemGroupAffinityThreadFn)(
+ PGROUP_AFFINITY Affinity,
+ PGROUP_AFFINITY PreviousAffinity
+);
+
+typedef USHORT (NTAPI *KeQueryActiveGroupCountFn)();
+
+typedef ULONG (NTAPI *KeQueryActiveProcessorCountExFn)(
+ USHORT GroupNumber
+);
+
extern NTSTATUS NTAPI KeSaveExtendedProcessorState (
__in ULONG64 Mask,
PXSTATE_SAVE XStateSave
diff --git a/src/Common/Zip.vcxproj b/src/Common/Zip.vcxproj
index 746f771..ec907d9 100644
--- a/src/Common/Zip.vcxproj
+++ b/src/Common/Zip.vcxproj
@@ -19,7 +19,6 @@
</ProjectConfiguration>
</ItemGroup>
<ItemGroup>
- <ClCompile Include="libzip\mkstemp.c" />
<ClCompile Include="libzip\zip_add.c" />
<ClCompile Include="libzip\zip_add_dir.c" />
<ClCompile Include="libzip\zip_add_entry.c" />
@@ -72,6 +71,7 @@
<ClCompile Include="libzip\zip_name_locate.c" />
<ClCompile Include="libzip\zip_new.c" />
<ClCompile Include="libzip\zip_open.c" />
+ <ClCompile Include="libzip\zip_pkware.c" />
<ClCompile Include="libzip\zip_progress.c" />
<ClCompile Include="libzip\zip_rename.c" />
<ClCompile Include="libzip\zip_replace.c" />
@@ -81,6 +81,7 @@
<ClCompile Include="libzip\zip_set_file_comment.c" />
<ClCompile Include="libzip\zip_set_file_compression.c" />
<ClCompile Include="libzip\zip_set_name.c" />
+ <ClCompile Include="libzip\zip_source_accept_empty.c" />
<ClCompile Include="libzip\zip_source_begin_write.c" />
<ClCompile Include="libzip\zip_source_begin_write_cloning.c" />
<ClCompile Include="libzip\zip_source_buffer.c" />
@@ -89,16 +90,21 @@
<ClCompile Include="libzip\zip_source_commit_write.c" />
<ClCompile Include="libzip\zip_source_compress.c" />
<ClCompile Include="libzip\zip_source_crc.c" />
- <ClCompile Include="libzip\zip_source_deflate.c" />
<ClCompile Include="libzip\zip_source_error.c" />
- <ClCompile Include="libzip\zip_source_filep.c" />
+ <ClCompile Include="libzip\zip_source_file_common.c" />
+ <ClCompile Include="libzip\zip_source_file_stdio.c" />
+ <ClCompile Include="libzip\zip_source_file_win32.c" />
+ <ClCompile Include="libzip\zip_source_file_win32_named.c" />
+ <ClCompile Include="libzip\zip_source_file_win32_utf16.c" />
+ <ClCompile Include="libzip\zip_source_file_win32_utf8.c" />
<ClCompile Include="libzip\zip_source_free.c" />
<ClCompile Include="libzip\zip_source_function.c" />
- <ClCompile Include="libzip\zip_source_get_compression_flags.c" />
+ <ClCompile Include="libzip\zip_source_get_file_attributes.c" />
<ClCompile Include="libzip\zip_source_is_deleted.c" />
<ClCompile Include="libzip\zip_source_layered.c" />
<ClCompile Include="libzip\zip_source_open.c" />
- <ClCompile Include="libzip\zip_source_pkware.c" />
+ <ClCompile Include="libzip\zip_source_pkware_decode.c" />
+ <ClCompile Include="libzip\zip_source_pkware_encode.c" />
<ClCompile Include="libzip\zip_source_read.c" />
<ClCompile Include="libzip\zip_source_remove.c" />
<ClCompile Include="libzip\zip_source_rollback_write.c" />
@@ -108,10 +114,6 @@
<ClCompile Include="libzip\zip_source_supports.c" />
<ClCompile Include="libzip\zip_source_tell.c" />
<ClCompile Include="libzip\zip_source_tell_write.c" />
- <ClCompile Include="libzip\zip_source_win32a.c" />
- <ClCompile Include="libzip\zip_source_win32handle.c" />
- <ClCompile Include="libzip\zip_source_win32utf8.c" />
- <ClCompile Include="libzip\zip_source_win32w.c" />
<ClCompile Include="libzip\zip_source_window.c" />
<ClCompile Include="libzip\zip_source_write.c" />
<ClCompile Include="libzip\zip_source_zip.c" />
@@ -144,7 +146,9 @@
<ClInclude Include="libzip\zip.h" />
<ClInclude Include="libzip\zipconf.h" />
<ClInclude Include="libzip\zipint.h" />
- <ClInclude Include="libzip\zipwin32.h" />
+ <ClInclude Include="libzip\zip_source_file.h" />
+ <ClInclude Include="libzip\zip_source_file_stdio.h" />
+ <ClInclude Include="libzip\zip_source_file_win32.h" />
<ClInclude Include="zlib\crc32.h" />
<ClInclude Include="zlib\deflate.h" />
<ClInclude Include="zlib\inffast.h" />
diff --git a/src/Common/Zip.vcxproj.filters b/src/Common/Zip.vcxproj.filters
index fa83631..88c8ff6 100644
--- a/src/Common/Zip.vcxproj.filters
+++ b/src/Common/Zip.vcxproj.filters
@@ -9,9 +9,6 @@
</Filter>
</ItemGroup>
<ItemGroup>
- <ClCompile Include="libzip\mkstemp.c">
- <Filter>libzip</Filter>
- </ClCompile>
<ClCompile Include="libzip\zip_add.c">
<Filter>libzip</Filter>
</ClCompile>
@@ -57,9 +54,6 @@
<ClCompile Include="libzip\zip_error_strerror.c">
<Filter>libzip</Filter>
</ClCompile>
- <ClCompile Include="libzip\zip_err_str.c">
- <Filter>libzip</Filter>
- </ClCompile>
<ClCompile Include="libzip\zip_extra_field.c">
<Filter>libzip</Filter>
</ClCompile>
@@ -207,15 +201,9 @@
<ClCompile Include="libzip\zip_source_crc.c">
<Filter>libzip</Filter>
</ClCompile>
- <ClCompile Include="libzip\zip_source_deflate.c">
- <Filter>libzip</Filter>
- </ClCompile>
<ClCompile Include="libzip\zip_source_error.c">
<Filter>libzip</Filter>
</ClCompile>
- <ClCompile Include="libzip\zip_source_filep.c">
- <Filter>libzip</Filter>
- </ClCompile>
<ClCompile Include="libzip\zip_source_free.c">
<Filter>libzip</Filter>
</ClCompile>
@@ -231,9 +219,6 @@
<ClCompile Include="libzip\zip_source_open.c">
<Filter>libzip</Filter>
</ClCompile>
- <ClCompile Include="libzip\zip_source_pkware.c">
- <Filter>libzip</Filter>
- </ClCompile>
<ClCompile Include="libzip\zip_source_read.c">
<Filter>libzip</Filter>
</ClCompile>
@@ -261,18 +246,6 @@
<ClCompile Include="libzip\zip_source_tell_write.c">
<Filter>libzip</Filter>
</ClCompile>
- <ClCompile Include="libzip\zip_source_win32a.c">
- <Filter>libzip</Filter>
- </ClCompile>
- <ClCompile Include="libzip\zip_source_win32handle.c">
- <Filter>libzip</Filter>
- </ClCompile>
- <ClCompile Include="libzip\zip_source_win32utf8.c">
- <Filter>libzip</Filter>
- </ClCompile>
- <ClCompile Include="libzip\zip_source_win32w.c">
- <Filter>libzip</Filter>
- </ClCompile>
<ClCompile Include="libzip\zip_source_window.c">
<Filter>libzip</Filter>
</ClCompile>
@@ -357,7 +330,40 @@
<ClCompile Include="libzip\zip_algorithm_deflate.c">
<Filter>libzip</Filter>
</ClCompile>
- <ClCompile Include="libzip\zip_source_get_compression_flags.c">
+ <ClCompile Include="libzip\zip_source_accept_empty.c">
+ <Filter>libzip</Filter>
+ </ClCompile>
+ <ClCompile Include="libzip\zip_source_get_file_attributes.c">
+ <Filter>libzip</Filter>
+ </ClCompile>
+ <ClCompile Include="libzip\zip_source_pkware_decode.c">
+ <Filter>libzip</Filter>
+ </ClCompile>
+ <ClCompile Include="libzip\zip_source_pkware_encode.c">
+ <Filter>libzip</Filter>
+ </ClCompile>
+ <ClCompile Include="libzip\zip_pkware.c">
+ <Filter>libzip</Filter>
+ </ClCompile>
+ <ClCompile Include="libzip\zip_source_file_common.c">
+ <Filter>libzip</Filter>
+ </ClCompile>
+ <ClCompile Include="libzip\zip_source_file_stdio.c">
+ <Filter>libzip</Filter>
+ </ClCompile>
+ <ClCompile Include="libzip\zip_source_file_win32_named.c">
+ <Filter>libzip</Filter>
+ </ClCompile>
+ <ClCompile Include="libzip\zip_source_file_win32_utf8.c">
+ <Filter>libzip</Filter>
+ </ClCompile>
+ <ClCompile Include="libzip\zip_source_file_win32_utf16.c">
+ <Filter>libzip</Filter>
+ </ClCompile>
+ <ClCompile Include="libzip\zip_source_file_win32.c">
+ <Filter>libzip</Filter>
+ </ClCompile>
+ <ClCompile Include="libzip\zip_err_str.c">
<Filter>libzip</Filter>
</ClCompile>
</ItemGroup>
@@ -380,9 +386,6 @@
<ClInclude Include="libzip\zipint.h">
<Filter>libzip</Filter>
</ClInclude>
- <ClInclude Include="libzip\zipwin32.h">
- <Filter>libzip</Filter>
- </ClInclude>
<ClInclude Include="zlib\crc32.h">
<Filter>zlib</Filter>
</ClInclude>
@@ -413,5 +416,14 @@
<ClInclude Include="zlib\zutil.h">
<Filter>zlib</Filter>
</ClInclude>
+ <ClInclude Include="libzip\zip_source_file.h">
+ <Filter>libzip</Filter>
+ </ClInclude>
+ <ClInclude Include="libzip\zip_source_file_stdio.h">
+ <Filter>libzip</Filter>
+ </ClInclude>
+ <ClInclude Include="libzip\zip_source_file_win32.h">
+ <Filter>libzip</Filter>
+ </ClInclude>
</ItemGroup>
</Project> \ No newline at end of file
diff --git a/src/Common/libzip/LICENSE b/src/Common/libzip/LICENSE
index e93454e..573d5d9 100644
--- a/src/Common/libzip/LICENSE
+++ b/src/Common/libzip/LICENSE
@@ -1,4 +1,4 @@
-Copyright (C) 1999-2017 Dieter Baron and Thomas Klausner
+Copyright (C) 1999-2020 Dieter Baron and Thomas Klausner
The authors can be contacted at <libzip@nih.at>
diff --git a/src/Common/libzip/NEWS.md b/src/Common/libzip/NEWS.md
index 9d8d2a3..d48b59a 100644
--- a/src/Common/libzip/NEWS.md
+++ b/src/Common/libzip/NEWS.md
@@ -1,5 +1,52 @@
+1.7.3 [2020-07-15]
+==================
+
+* Support cmake < 3.17 again.
+* Fix pkgconfig file (regression in 1.7.2).
+
+1.7.2 [2020-07-11]
+==================
+
+* Fixes for the CMake `find_project()` files.
+* libzip moved to the CMake `libzip::` `NAMESPACE`.
+* CMake usage best practice cleanups.
+
+1.7.1 [2020-06-13]
+==================
+
+* Restore `LIBZIP_VERSION_{MAJOR,MINOR,MICRO}` symbols.
+* Fixes warnings reported by PVS-Studio.
+* Add `LIBZIP_DO_INSTALL` build setting to make it easier to use
+ libzip as subproject.
+
+1.7.0 [2020-06-05]
+==================
+
+* Add support for encrypting using traditional PKWare encryption.
+* Add `zip_compression_method_supported()`.
+* Add `zip_encryption_method_supported()`.
+* Add the `ZIP_SOURCE_GET_FILE_ATTRIBUTES` source command.
+* Refactor stdio file backend.
+* Add CMake find_project() support.
+
+1.6.1 [2020-02-03]
+==================
+
+* Bugfix for double-free in `zipcmp(1)` during cleanup.
+
+1.6.0 [2020-01-24]
+==================
+
+* Avoid using `umask()` since it's not thread-safe.
+* Set close-on-exec flag when opening files.
+* Do not accept empty files as valid zip archives any longer.
+* Add support for XZ compressed files (using liblzma).
+* Add support for cancelling while closing zip archives.
+* Add support for setting the time in the on-disk format.
+
1.5.2 [2019-03-12]
==================
+
* Fix bug in AES encryption affecting certain file sizes
* Keep file permissions when modifying zip archives
* Support systems with small stack size.
@@ -37,6 +84,7 @@
1.3.2 [2017-11-20]
==================
+
* Fix bug introduced in last: zip_t was erroneously freed if zip_close() failed.
1.3.1 [2017-11-19]
@@ -181,7 +229,7 @@
0.9 [2008-07-25]
==================
-* on Windows, explictly set dllimport/dllexport
+* on Windows, explicitly set dllimport/dllexport
* remove erroneous references to GPL
* add support for torrentzip
* new functions: zip_get_archive_flag, zip_set_archive_flag
diff --git a/src/Common/libzip/compat.h b/src/Common/libzip/compat.h
index f2e4c6c..fb2c56e 100644
--- a/src/Common/libzip/compat.h
+++ b/src/Common/libzip/compat.h
@@ -3,7 +3,7 @@
/*
compat.h -- compatibility defines.
- Copyright (C) 1999-2018 Dieter Baron and Thomas Klausner
+ Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
@@ -36,9 +36,7 @@
#include "zipconf.h"
-#ifdef HAVE_CONFIG_H
#include "config.h"
-#endif
/* to have *_MAX definitions for all types when compiling with g++ */
#define __STDC_LIMIT_MACROS
@@ -81,6 +79,11 @@ typedef char bool;
#define EOVERFLOW EFBIG
#endif
+/* not supported on at least Windows */
+#ifndef O_CLOEXEC
+#define O_CLOEXEC 0
+#endif
+
#ifdef _WIN32
#if defined(HAVE__CHMOD)
#define chmod _chmod
@@ -98,10 +101,6 @@ typedef char bool;
#if !defined(HAVE_FILENO) && defined(HAVE__FILENO)
#define fileno _fileno
#endif
-/* Windows' open() doesn't understand Unix permissions */
-#if defined(HAVE__OPEN)
-#define open(a, b, c) _open((a), (b))
-#endif
#if defined(HAVE__SNPRINTF)
#define snprintf _snprintf
#endif
@@ -120,9 +119,6 @@ typedef char bool;
#if !defined(HAVE_STRTOULL) && defined(HAVE__STRTOUI64)
#define strtoull _strtoui64
#endif
-#if defined(HAVE__UMASK)
-#define umask _umask
-#endif
#if defined(HAVE__UNLINK)
#define unlink _unlink
#endif
@@ -136,11 +132,6 @@ typedef char bool;
#define ftello(s) ((long)ftell((s)))
#endif
-#ifndef HAVE_MKSTEMP
-int _zip_mkstemp(char *);
-#define mkstemp _zip_mkstemp
-#endif
-
#if !defined(HAVE_STRCASECMP)
#if defined(HAVE__STRICMP)
#define strcasecmp _stricmp
@@ -203,4 +194,8 @@ int _zip_mkstemp(char *);
#define S_ISDIR(mode) (((mode)&S_IFMT) == S_IFDIR)
#endif
+#ifndef S_ISREG
+#define S_ISREG(mode) (((mode)&S_IFMT) == S_IFREG)
+#endif
+
#endif /* compat.h */
diff --git a/src/Common/libzip/config.h b/src/Common/libzip/config.h
index 4de10df..1edd29b 100644
--- a/src/Common/libzip/config.h
+++ b/src/Common/libzip/config.h
@@ -76,7 +76,7 @@
#define HAVE_SHARED
/* END DEFINES */
#define PACKAGE "libzip"
-#define VERSION "1.5.2"
+#define VERSION "1.7.3"
#ifndef HAVE_SSIZE_T_LIBZIP
# if SIZE_T_LIBZIP == INT_LIBZIP
diff --git a/src/Common/libzip/mkstemp.c b/src/Common/libzip/mkstemp.c
deleted file mode 100644
index 01a531f..0000000
--- a/src/Common/libzip/mkstemp.c
+++ /dev/null
@@ -1,153 +0,0 @@
-/* Adapted from NetBSB libc by Dieter Baron */
-
-/* NetBSD: gettemp.c,v 1.13 2003/12/05 00:57:36 uebayasi Exp */
-
-/*
- * Copyright (c) 1987, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <sys/stat.h>
-#include <sys/types.h>
-
-#include <assert.h>
-#include <ctype.h>
-#include <errno.h>
-#include <fcntl.h>
-#ifdef _WIN32
-#include <io.h>
-#include <process.h>
-#else
-#include <unistd.h>
-#endif
-#include <stdio.h>
-#include <stdlib.h>
-
-#ifndef O_BINARY
-#define O_BINARY 0
-#endif
-
-
-int
-_zip_mkstemp(char *path) {
-#ifdef _WIN32
- int ret;
- ret = _creat(_mktemp(path), _S_IREAD | _S_IWRITE);
- if (ret == -1) {
- return 0;
- }
- else {
- return ret;
- }
-#else
- int fd;
- char *start, *trv;
- struct stat sbuf;
- pid_t pid;
-
- /* To guarantee multiple calls generate unique names even if
- the file is not created. 676 different possibilities with 7
- or more X's, 26 with 6 or less. */
- static char xtra[2] = "aa";
- int xcnt = 0;
-
- pid = getpid();
-
- /* Move to end of path and count trailing X's. */
- for (trv = path; *trv; ++trv)
- if (*trv == 'X')
- xcnt++;
- else
- xcnt = 0;
-
- /* Use at least one from xtra. Use 2 if more than 6 X's. */
- if (*(trv - 1) == 'X')
- *--trv = xtra[0];
- if (xcnt > 6 && *(trv - 1) == 'X')
- *--trv = xtra[1];
-
- /* Set remaining X's to pid digits with 0's to the left. */
- while (*--trv == 'X') {
- *trv = (pid % 10) + '0';
- pid /= 10;
- }
-
- /* update xtra for next call. */
- if (xtra[0] != 'z')
- xtra[0]++;
- else {
- xtra[0] = 'a';
- if (xtra[1] != 'z')
- xtra[1]++;
- else
- xtra[1] = 'a';
- }
-
- /*
- * check the target directory; if you have six X's and it
- * doesn't exist this runs for a *very* long time.
- */
- for (start = trv + 1;; --trv) {
- if (trv <= path)
- break;
- if (*trv == '/') {
- *trv = '\0';
- if (stat(path, &sbuf))
- return (0);
- if (!S_ISDIR(sbuf.st_mode)) {
- errno = ENOTDIR;
- return (0);
- }
- *trv = '/';
- break;
- }
- }
-
- for (;;) {
- if ((fd = open(path, O_CREAT | O_EXCL | O_RDWR | O_BINARY, 0600)) >= 0)
- return (fd);
- if (errno != EEXIST)
- return (0);
-
- /* tricky little algorithm for backward compatibility */
- for (trv = start;;) {
- if (!*trv)
- return (0);
- if (*trv == 'z')
- *trv++ = 'a';
- else {
- if (isdigit((unsigned char)*trv))
- *trv = 'a';
- else
- ++*trv;
- break;
- }
- }
- }
- /*NOTREACHED*/
-#endif
-}
diff --git a/src/Common/libzip/zip.h b/src/Common/libzip/zip.h
index b7cd60c..ba0b6ba 100644
--- a/src/Common/libzip/zip.h
+++ b/src/Common/libzip/zip.h
@@ -3,7 +3,7 @@
/*
zip.h -- exported declarations.
- Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner
+ Copyright (C) 1999-2020 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
@@ -58,6 +58,9 @@ extern "C" {
#endif
#endif
+#define _Nullable
+#define _Nonnull
+
#include <stdio.h>
#include <sys/types.h>
#include <time.h>
@@ -134,6 +137,7 @@ extern "C" {
#define ZIP_ER_INUSE 29 /* N Resource still in use */
#define ZIP_ER_TELL 30 /* S Tell error */
#define ZIP_ER_COMPRESSED_DATA 31 /* N Compressed data invalid */
+#define ZIP_ER_CANCELLED 32 /* N Operation cancelled */
/* type of system error value */
@@ -160,8 +164,9 @@ extern "C" {
/* 13 - Reserved by PKWARE */
#define ZIP_CM_LZMA 14 /* LZMA (EFS) */
/* 15-17 - Reserved by PKWARE */
-#define ZIP_CM_TERSE 18 /* compressed using IBM TERSE (new) */
-#define ZIP_CM_LZ77 19 /* IBM LZ77 z Architecture (PFS) */
+#define ZIP_CM_TERSE 18 /* compressed using IBM TERSE (new) */
+#define ZIP_CM_LZ77 19 /* IBM LZ77 z Architecture (PFS) */
+#define ZIP_CM_LZMA2 33
#define ZIP_CM_XZ 95 /* XZ compressed data */
#define ZIP_CM_JPEG 96 /* Compressed Jpeg data */
#define ZIP_CM_WAVPACK 97 /* WavPack compressed data */
@@ -212,30 +217,32 @@ extern "C" {
enum zip_source_cmd {
- ZIP_SOURCE_OPEN, /* prepare for reading */
- ZIP_SOURCE_READ, /* read data */
- ZIP_SOURCE_CLOSE, /* reading is done */
- ZIP_SOURCE_STAT, /* get meta information */
- ZIP_SOURCE_ERROR, /* get error information */
- ZIP_SOURCE_FREE, /* cleanup and free resources */
- ZIP_SOURCE_SEEK, /* set position for reading */
- ZIP_SOURCE_TELL, /* get read position */
- ZIP_SOURCE_BEGIN_WRITE, /* prepare for writing */
- ZIP_SOURCE_COMMIT_WRITE, /* writing is done */
- ZIP_SOURCE_ROLLBACK_WRITE, /* discard written changes */
- ZIP_SOURCE_WRITE, /* write data */
- ZIP_SOURCE_SEEK_WRITE, /* set position for writing */
- ZIP_SOURCE_TELL_WRITE, /* get write position */
- ZIP_SOURCE_SUPPORTS, /* check whether source supports command */
- ZIP_SOURCE_REMOVE, /* remove file */
- ZIP_SOURCE_GET_COMPRESSION_FLAGS, /* get compression flags, internal only */
- ZIP_SOURCE_BEGIN_WRITE_CLONING /* like ZIP_SOURCE_BEGIN_WRITE, but keep part of original file */
+ ZIP_SOURCE_OPEN, /* prepare for reading */
+ ZIP_SOURCE_READ, /* read data */
+ ZIP_SOURCE_CLOSE, /* reading is done */
+ ZIP_SOURCE_STAT, /* get meta information */
+ ZIP_SOURCE_ERROR, /* get error information */
+ ZIP_SOURCE_FREE, /* cleanup and free resources */
+ ZIP_SOURCE_SEEK, /* set position for reading */
+ ZIP_SOURCE_TELL, /* get read position */
+ ZIP_SOURCE_BEGIN_WRITE, /* prepare for writing */
+ ZIP_SOURCE_COMMIT_WRITE, /* writing is done */
+ ZIP_SOURCE_ROLLBACK_WRITE, /* discard written changes */
+ ZIP_SOURCE_WRITE, /* write data */
+ ZIP_SOURCE_SEEK_WRITE, /* set position for writing */
+ ZIP_SOURCE_TELL_WRITE, /* get write position */
+ ZIP_SOURCE_SUPPORTS, /* check whether source supports command */
+ ZIP_SOURCE_REMOVE, /* remove file */
+ ZIP_SOURCE_RESERVED_1, /* previously used internally */
+ ZIP_SOURCE_BEGIN_WRITE_CLONING, /* like ZIP_SOURCE_BEGIN_WRITE, but keep part of original file */
+ ZIP_SOURCE_ACCEPT_EMPTY, /* whether empty files are valid archives */
+ ZIP_SOURCE_GET_FILE_ATTRIBUTES /* get additional file attributes */
};
typedef enum zip_source_cmd zip_source_cmd_t;
#define ZIP_SOURCE_MAKE_COMMAND_BITMASK(cmd) (((zip_int64_t)1) << (cmd))
-// clang-format off
+/* clang-format off */
#define ZIP_SOURCE_SUPPORTS_READABLE (ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_OPEN) \
| ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_READ) \
@@ -258,7 +265,7 @@ typedef enum zip_source_cmd zip_source_cmd_t;
| ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_TELL_WRITE) \
| ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_REMOVE))
-// clang-format on
+/* clang-format on */
/* for use by sources */
struct zip_source_args_seek {
@@ -273,9 +280,9 @@ typedef struct zip_source_args_seek zip_source_args_seek_t;
/* error information */
/* use zip_error_*() to access */
struct zip_error {
- int zip_err; /* libzip error code (ZIP_ER_*) */
- int sys_err; /* copy of errno (E*) or zlib error code */
- char *str; /* string representation or NULL */
+ int zip_err; /* libzip error code (ZIP_ER_*) */
+ int sys_err; /* copy of errno (E*) or zlib error code */
+ char *_Nullable str; /* string representation or NULL */
};
#define ZIP_STAT_NAME 0x0001u
@@ -290,7 +297,7 @@ struct zip_error {
struct zip_stat {
zip_uint64_t valid; /* which fields have valid values */
- const char * name; /* name of the file */
+ const char *_Nullable name; /* name of the file */
zip_uint64_t index; /* index within archive */
zip_uint64_t size; /* size of file (uncompressed) */
zip_uint64_t comp_size; /* size of file (compressed) */
@@ -302,10 +309,27 @@ struct zip_stat {
};
struct zip_buffer_fragment {
- zip_uint8_t * data;
+ zip_uint8_t *_Nonnull data;
zip_uint64_t length;
};
+struct zip_file_attributes {
+ zip_uint64_t valid; /* which fields have valid values */
+ zip_uint8_t version; /* version of this struct, currently 1 */
+ zip_uint8_t host_system; /* host system on which file was created */
+ zip_uint8_t ascii; /* flag whether file is ASCII text */
+ zip_uint8_t version_needed; /* minimum version needed to extract file */
+ zip_uint32_t external_file_attributes; /* external file attributes (host-system specific) */
+ zip_uint16_t general_purpose_bit_flags; /* general purpose big flags, only some bits are honored */
+ zip_uint16_t general_purpose_bit_mask; /* which bits in general_purpose_bit_flags are valid */
+};
+
+#define ZIP_FILE_ATTRIBUTES_HOST_SYSTEM 0x0001u
+#define ZIP_FILE_ATTRIBUTES_ASCII 0x0002u
+#define ZIP_FILE_ATTRIBUTES_VERSION_NEEDED 0x0004u
+#define ZIP_FILE_ATTRIBUTES_EXTERNAL_FILE_ATTRIBUTES 0x0008u
+#define ZIP_FILE_ATTRIBUTES_GENERAL_PURPOSE_BIT_FLAGS 0x0010u
+
struct zip;
struct zip_file;
struct zip_source;
@@ -313,118 +337,124 @@ struct zip_source;
typedef struct zip zip_t;
typedef struct zip_error zip_error_t;
typedef struct zip_file zip_file_t;
+typedef struct zip_file_attributes zip_file_attributes_t;
typedef struct zip_source zip_source_t;
typedef struct zip_stat zip_stat_t;
typedef struct zip_buffer_fragment zip_buffer_fragment_t;
typedef zip_uint32_t zip_flags_t;
-typedef zip_int64_t (*zip_source_callback)(void *, void *, zip_uint64_t, zip_source_cmd_t);
-typedef void (*zip_progress_callback)(zip_t *, double, void *);
+typedef zip_int64_t (*zip_source_callback)(void *_Nullable, void *_Nullable, zip_uint64_t, zip_source_cmd_t);
+typedef void (*zip_progress_callback)(zip_t *_Nonnull, double, void *_Nullable);
+typedef int (*zip_cancel_callback)(zip_t *_Nonnull, void *_Nullable);
#ifndef ZIP_DISABLE_DEPRECATED
typedef void (*zip_progress_callback_t)(double);
-ZIP_EXTERN void zip_register_progress_callback(zip_t *, zip_progress_callback_t); /* use zip_register_progress_callback_with_state */
-
-ZIP_EXTERN zip_int64_t zip_add(zip_t *, const char *, zip_source_t *); /* use zip_file_add */
-ZIP_EXTERN zip_int64_t zip_add_dir(zip_t *, const char *); /* use zip_dir_add */
-ZIP_EXTERN const char * zip_get_file_comment(zip_t *, zip_uint64_t, int *, int); /* use zip_file_get_comment */
-ZIP_EXTERN int zip_get_num_files(zip_t *); /* use zip_get_num_entries instead */
-ZIP_EXTERN int zip_rename(zip_t *, zip_uint64_t, const char *); /* use zip_file_rename */
-ZIP_EXTERN int zip_replace(zip_t *, zip_uint64_t, zip_source_t *); /* use zip_file_replace */
-ZIP_EXTERN int zip_set_file_comment(zip_t *, zip_uint64_t, const char *, int); /* use zip_file_set_comment */
-ZIP_EXTERN int zip_error_get_sys_type(int); /* use zip_error_system_type */
-ZIP_EXTERN void zip_error_get(zip_t *, int *, int *); /* use zip_get_error, zip_error_code_zip / zip_error_code_system */
-ZIP_EXTERN int zip_error_to_str(char *, zip_uint64_t, int, int); /* use zip_error_init_with_code / zip_error_strerror */
-ZIP_EXTERN void zip_file_error_get(zip_file_t *, int *, int *); /* use zip_file_get_error, zip_error_code_zip / zip_error_code_system */
+ZIP_EXTERN void zip_register_progress_callback(zip_t *_Nonnull, zip_progress_callback_t _Nullable); /* use zip_register_progress_callback_with_state */
+
+ZIP_EXTERN zip_int64_t zip_add(zip_t *_Nonnull, const char *_Nonnull, zip_source_t *_Nonnull); /* use zip_file_add */
+ZIP_EXTERN zip_int64_t zip_add_dir(zip_t *_Nonnull, const char *_Nonnull); /* use zip_dir_add */
+ZIP_EXTERN const char *_Nullable zip_get_file_comment(zip_t *_Nonnull, zip_uint64_t, int *_Nullable, int); /* use zip_file_get_comment */
+ZIP_EXTERN int zip_get_num_files(zip_t *_Nonnull); /* use zip_get_num_entries instead */
+ZIP_EXTERN int zip_rename(zip_t *_Nonnull, zip_uint64_t, const char *_Nonnull); /* use zip_file_rename */
+ZIP_EXTERN int zip_replace(zip_t *_Nonnull, zip_uint64_t, zip_source_t *_Nonnull); /* use zip_file_replace */
+ZIP_EXTERN int zip_set_file_comment(zip_t *_Nonnull, zip_uint64_t, const char *_Nullable, int); /* use zip_file_set_comment */
+ZIP_EXTERN int zip_error_get_sys_type(int); /* use zip_error_system_type */
+ZIP_EXTERN void zip_error_get(zip_t *_Nonnull, int *_Nullable, int *_Nullable); /* use zip_get_error, zip_error_code_zip / zip_error_code_system */
+ZIP_EXTERN int zip_error_to_str(char *_Nonnull, zip_uint64_t, int, int); /* use zip_error_init_with_code / zip_error_strerror */
+ZIP_EXTERN void zip_file_error_get(zip_file_t *_Nonnull, int *_Nullable, int *_Nullable); /* use zip_file_get_error, zip_error_code_zip / zip_error_code_system */
#endif
-ZIP_EXTERN int zip_close(zip_t *);
-ZIP_EXTERN int zip_delete(zip_t *, zip_uint64_t);
-ZIP_EXTERN zip_int64_t zip_dir_add(zip_t *, const char *, zip_flags_t);
-ZIP_EXTERN void zip_discard(zip_t *);
-
-ZIP_EXTERN zip_error_t * zip_get_error(zip_t *);
-ZIP_EXTERN void zip_error_clear(zip_t *);
-ZIP_EXTERN int zip_error_code_zip(const zip_error_t *);
-ZIP_EXTERN int zip_error_code_system(const zip_error_t *);
-ZIP_EXTERN void zip_error_fini(zip_error_t *);
-ZIP_EXTERN void zip_error_init(zip_error_t *);
-ZIP_EXTERN void zip_error_init_with_code(zip_error_t *, int);
-ZIP_EXTERN void zip_error_set(zip_error_t *, int, int);
-ZIP_EXTERN const char * zip_error_strerror(zip_error_t *);
-ZIP_EXTERN int zip_error_system_type(const zip_error_t *);
-ZIP_EXTERN zip_int64_t zip_error_to_data(const zip_error_t *, void *, zip_uint64_t);
-
-ZIP_EXTERN int zip_fclose(zip_file_t *);
-ZIP_EXTERN zip_t * zip_fdopen(int, int, int *);
-ZIP_EXTERN zip_int64_t zip_file_add(zip_t *, const char *, zip_source_t *, zip_flags_t);
-ZIP_EXTERN void zip_file_error_clear(zip_file_t *);
-ZIP_EXTERN int zip_file_extra_field_delete(zip_t *, zip_uint64_t, zip_uint16_t, zip_flags_t);
-ZIP_EXTERN int zip_file_extra_field_delete_by_id(zip_t *, zip_uint64_t, zip_uint16_t, zip_uint16_t, zip_flags_t);
-ZIP_EXTERN int zip_file_extra_field_set(zip_t *, zip_uint64_t, zip_uint16_t, zip_uint16_t, const zip_uint8_t *, zip_uint16_t, zip_flags_t);
-ZIP_EXTERN zip_int16_t zip_file_extra_fields_count(zip_t *, zip_uint64_t, zip_flags_t);
-ZIP_EXTERN zip_int16_t zip_file_extra_fields_count_by_id(zip_t *, zip_uint64_t, zip_uint16_t, zip_flags_t);
-ZIP_EXTERN const zip_uint8_t * zip_file_extra_field_get(zip_t *, zip_uint64_t, zip_uint16_t, zip_uint16_t *, zip_uint16_t *, zip_flags_t);
-ZIP_EXTERN const zip_uint8_t * zip_file_extra_field_get_by_id(zip_t *, zip_uint64_t, zip_uint16_t, zip_uint16_t, zip_uint16_t *, zip_flags_t);
-ZIP_EXTERN const char * zip_file_get_comment(zip_t *, zip_uint64_t, zip_uint32_t *, zip_flags_t);
-ZIP_EXTERN zip_error_t * zip_file_get_error(zip_file_t *);
-ZIP_EXTERN int zip_file_get_external_attributes(zip_t *, zip_uint64_t, zip_flags_t, zip_uint8_t *, zip_uint32_t *);
-ZIP_EXTERN int zip_file_rename(zip_t *, zip_uint64_t, const char *, zip_flags_t);
-ZIP_EXTERN int zip_file_replace(zip_t *, zip_uint64_t, zip_source_t *, zip_flags_t);
-ZIP_EXTERN int zip_file_set_comment(zip_t *, zip_uint64_t, const char *, zip_uint16_t, zip_flags_t);
-ZIP_EXTERN int zip_file_set_encryption(zip_t *, zip_uint64_t, zip_uint16_t, const char *);
-ZIP_EXTERN int zip_file_set_external_attributes(zip_t *, zip_uint64_t, zip_flags_t, zip_uint8_t, zip_uint32_t);
-ZIP_EXTERN int zip_file_set_mtime(zip_t *, zip_uint64_t, time_t, zip_flags_t);
-ZIP_EXTERN const char * zip_file_strerror(zip_file_t *);
-ZIP_EXTERN zip_file_t * zip_fopen(zip_t *, const char *, zip_flags_t);
-ZIP_EXTERN zip_file_t * zip_fopen_encrypted(zip_t *, const char *, zip_flags_t, const char *);
-ZIP_EXTERN zip_file_t * zip_fopen_index(zip_t *, zip_uint64_t, zip_flags_t);
-ZIP_EXTERN zip_file_t * zip_fopen_index_encrypted(zip_t *, zip_uint64_t, zip_flags_t, const char *);
-ZIP_EXTERN zip_int64_t zip_fread(zip_file_t *, void *, zip_uint64_t);
-ZIP_EXTERN zip_int8_t zip_fseek(zip_file_t *, zip_int64_t, int);
-ZIP_EXTERN zip_int64_t zip_ftell(zip_file_t *);
-ZIP_EXTERN const char * zip_get_archive_comment(zip_t *, int *, zip_flags_t);
-ZIP_EXTERN int zip_get_archive_flag(zip_t *, zip_flags_t, zip_flags_t);
-ZIP_EXTERN const char * zip_get_name(zip_t *, zip_uint64_t, zip_flags_t);
-ZIP_EXTERN zip_int64_t zip_get_num_entries(zip_t *, zip_flags_t);
-ZIP_EXTERN const char * zip_libzip_version(void);
-ZIP_EXTERN zip_int64_t zip_name_locate(zip_t *, const char *, zip_flags_t);
-ZIP_EXTERN zip_t * zip_open(const char *, int, int *);
-ZIP_EXTERN zip_t * zip_open_from_source(zip_source_t *, int, zip_error_t *);
-ZIP_EXTERN int zip_register_progress_callback_with_state(zip_t *, double, zip_progress_callback, void (*)(void *), void *);
-ZIP_EXTERN int zip_set_archive_comment(zip_t *, const char *, zip_uint16_t);
-ZIP_EXTERN int zip_set_archive_flag(zip_t *, zip_flags_t, int);
-ZIP_EXTERN int zip_set_default_password(zip_t *, const char *);
-ZIP_EXTERN int zip_set_file_compression(zip_t *, zip_uint64_t, zip_int32_t, zip_uint32_t);
-ZIP_EXTERN int zip_source_begin_write(zip_source_t *);
-ZIP_EXTERN int zip_source_begin_write_cloning(zip_source_t *, zip_uint64_t);
-ZIP_EXTERN zip_source_t * zip_source_buffer(zip_t *, const void *, zip_uint64_t, int);
-ZIP_EXTERN zip_source_t * zip_source_buffer_create(const void *, zip_uint64_t, int, zip_error_t *);
-ZIP_EXTERN zip_source_t * zip_source_buffer_fragment(zip_t *, const zip_buffer_fragment_t *, zip_uint64_t, int);
-ZIP_EXTERN zip_source_t * zip_source_buffer_fragment_create(const zip_buffer_fragment_t *, zip_uint64_t, int, zip_error_t *);
-ZIP_EXTERN int zip_source_close(zip_source_t *);
-ZIP_EXTERN int zip_source_commit_write(zip_source_t *);
-ZIP_EXTERN zip_error_t * zip_source_error(zip_source_t *);
-ZIP_EXTERN zip_source_t * zip_source_file(zip_t *, const char *, zip_uint64_t, zip_int64_t);
-ZIP_EXTERN zip_source_t * zip_source_file_create(const char *, zip_uint64_t, zip_int64_t, zip_error_t *);
-ZIP_EXTERN zip_source_t * zip_source_filep(zip_t *, FILE *, zip_uint64_t, zip_int64_t);
-ZIP_EXTERN zip_source_t * zip_source_filep_create(FILE *, zip_uint64_t, zip_int64_t, zip_error_t *);
-ZIP_EXTERN void zip_source_free(zip_source_t *);
-ZIP_EXTERN zip_source_t * zip_source_function(zip_t *, zip_source_callback , void *);
-ZIP_EXTERN zip_source_t * zip_source_function_create(zip_source_callback , void *, zip_error_t *);
-ZIP_EXTERN int zip_source_is_deleted(zip_source_t *);
-ZIP_EXTERN void zip_source_keep(zip_source_t *);
+ZIP_EXTERN int zip_close(zip_t *_Nonnull);
+ZIP_EXTERN int zip_delete(zip_t *_Nonnull, zip_uint64_t);
+ZIP_EXTERN zip_int64_t zip_dir_add(zip_t *_Nonnull, const char *_Nonnull, zip_flags_t);
+ZIP_EXTERN void zip_discard(zip_t *_Nonnull);
+
+ZIP_EXTERN zip_error_t *_Nonnull zip_get_error(zip_t *_Nonnull);
+ZIP_EXTERN void zip_error_clear(zip_t *_Nonnull);
+ZIP_EXTERN int zip_error_code_zip(const zip_error_t *_Nonnull);
+ZIP_EXTERN int zip_error_code_system(const zip_error_t *_Nonnull);
+ZIP_EXTERN void zip_error_fini(zip_error_t *_Nonnull);
+ZIP_EXTERN void zip_error_init(zip_error_t *_Nonnull);
+ZIP_EXTERN void zip_error_init_with_code(zip_error_t *_Nonnull, int);
+ZIP_EXTERN void zip_error_set(zip_error_t *_Nullable, int, int);
+ZIP_EXTERN const char *_Nonnull zip_error_strerror(zip_error_t *_Nonnull);
+ZIP_EXTERN int zip_error_system_type(const zip_error_t *_Nonnull);
+ZIP_EXTERN zip_int64_t zip_error_to_data(const zip_error_t *_Nonnull, void *_Nonnull, zip_uint64_t);
+
+ZIP_EXTERN int zip_fclose(zip_file_t *_Nonnull);
+ZIP_EXTERN zip_t *_Nullable zip_fdopen(int, int, int *_Nullable);
+ZIP_EXTERN zip_int64_t zip_file_add(zip_t *_Nonnull, const char *_Nonnull, zip_source_t *_Nonnull, zip_flags_t);
+ZIP_EXTERN void zip_file_attributes_init(zip_file_attributes_t *_Nonnull);
+ZIP_EXTERN void zip_file_error_clear(zip_file_t *_Nonnull);
+ZIP_EXTERN int zip_file_extra_field_delete(zip_t *_Nonnull, zip_uint64_t, zip_uint16_t, zip_flags_t);
+ZIP_EXTERN int zip_file_extra_field_delete_by_id(zip_t *_Nonnull, zip_uint64_t, zip_uint16_t, zip_uint16_t, zip_flags_t);
+ZIP_EXTERN int zip_file_extra_field_set(zip_t *_Nonnull, zip_uint64_t, zip_uint16_t, zip_uint16_t, const zip_uint8_t *_Nullable, zip_uint16_t, zip_flags_t);
+ZIP_EXTERN zip_int16_t zip_file_extra_fields_count(zip_t *_Nonnull, zip_uint64_t, zip_flags_t);
+ZIP_EXTERN zip_int16_t zip_file_extra_fields_count_by_id(zip_t *_Nonnull, zip_uint64_t, zip_uint16_t, zip_flags_t);
+ZIP_EXTERN const zip_uint8_t *_Nullable zip_file_extra_field_get(zip_t *_Nonnull, zip_uint64_t, zip_uint16_t, zip_uint16_t *_Nullable, zip_uint16_t *_Nullable, zip_flags_t);
+ZIP_EXTERN const zip_uint8_t *_Nullable zip_file_extra_field_get_by_id(zip_t *_Nonnull, zip_uint64_t, zip_uint16_t, zip_uint16_t, zip_uint16_t *_Nullable, zip_flags_t);
+ZIP_EXTERN const char *_Nullable zip_file_get_comment(zip_t *_Nonnull, zip_uint64_t, zip_uint32_t *_Nullable, zip_flags_t);
+ZIP_EXTERN zip_error_t *_Nonnull zip_file_get_error(zip_file_t *_Nonnull);
+ZIP_EXTERN int zip_file_get_external_attributes(zip_t *_Nonnull, zip_uint64_t, zip_flags_t, zip_uint8_t *_Nullable, zip_uint32_t *_Nullable);
+ZIP_EXTERN int zip_file_rename(zip_t *_Nonnull, zip_uint64_t, const char *_Nonnull, zip_flags_t);
+ZIP_EXTERN int zip_file_replace(zip_t *_Nonnull, zip_uint64_t, zip_source_t *_Nonnull, zip_flags_t);
+ZIP_EXTERN int zip_file_set_comment(zip_t *_Nonnull, zip_uint64_t, const char *_Nullable, zip_uint16_t, zip_flags_t);
+ZIP_EXTERN int zip_file_set_dostime(zip_t *_Nonnull, zip_uint64_t, zip_uint16_t, zip_uint16_t, zip_flags_t);
+ZIP_EXTERN int zip_file_set_encryption(zip_t *_Nonnull, zip_uint64_t, zip_uint16_t, const char *_Nullable);
+ZIP_EXTERN int zip_file_set_external_attributes(zip_t *_Nonnull, zip_uint64_t, zip_flags_t, zip_uint8_t, zip_uint32_t);
+ZIP_EXTERN int zip_file_set_mtime(zip_t *_Nonnull, zip_uint64_t, time_t, zip_flags_t);
+ZIP_EXTERN const char *_Nonnull zip_file_strerror(zip_file_t *_Nonnull);
+ZIP_EXTERN zip_file_t *_Nullable zip_fopen(zip_t *_Nonnull, const char *_Nonnull, zip_flags_t);
+ZIP_EXTERN zip_file_t *_Nullable zip_fopen_encrypted(zip_t *_Nonnull, const char *_Nonnull, zip_flags_t, const char *_Nullable);
+ZIP_EXTERN zip_file_t *_Nullable zip_fopen_index(zip_t *_Nonnull, zip_uint64_t, zip_flags_t);
+ZIP_EXTERN zip_file_t *_Nullable zip_fopen_index_encrypted(zip_t *_Nonnull, zip_uint64_t, zip_flags_t, const char *_Nullable);
+ZIP_EXTERN zip_int64_t zip_fread(zip_file_t *_Nonnull, void *_Nonnull, zip_uint64_t);
+ZIP_EXTERN zip_int8_t zip_fseek(zip_file_t *_Nonnull, zip_int64_t, int);
+ZIP_EXTERN zip_int64_t zip_ftell(zip_file_t *_Nonnull);
+ZIP_EXTERN const char *_Nullable zip_get_archive_comment(zip_t *_Nonnull, int *_Nullable, zip_flags_t);
+ZIP_EXTERN int zip_get_archive_flag(zip_t *_Nonnull, zip_flags_t, zip_flags_t);
+ZIP_EXTERN const char *_Nullable zip_get_name(zip_t *_Nonnull, zip_uint64_t, zip_flags_t);
+ZIP_EXTERN zip_int64_t zip_get_num_entries(zip_t *_Nonnull, zip_flags_t);
+ZIP_EXTERN const char *_Nonnull zip_libzip_version(void);
+ZIP_EXTERN zip_int64_t zip_name_locate(zip_t *_Nonnull, const char *_Nonnull, zip_flags_t);
+ZIP_EXTERN zip_t *_Nullable zip_open(const char *_Nonnull, int, int *_Nullable);
+ZIP_EXTERN zip_t *_Nullable zip_open_from_source(zip_source_t *_Nonnull, int, zip_error_t *_Nullable);
+ZIP_EXTERN int zip_register_progress_callback_with_state(zip_t *_Nonnull, double, zip_progress_callback _Nullable, void (*_Nullable)(void *_Nullable), void *_Nullable);
+ZIP_EXTERN int zip_register_cancel_callback_with_state(zip_t *_Nonnull, zip_cancel_callback _Nullable, void (*_Nullable)(void *_Nullable), void *_Nullable);
+ZIP_EXTERN int zip_set_archive_comment(zip_t *_Nonnull, const char *_Nullable, zip_uint16_t);
+ZIP_EXTERN int zip_set_archive_flag(zip_t *_Nonnull, zip_flags_t, int);
+ZIP_EXTERN int zip_set_default_password(zip_t *_Nonnull, const char *_Nullable);
+ZIP_EXTERN int zip_set_file_compression(zip_t *_Nonnull, zip_uint64_t, zip_int32_t, zip_uint32_t);
+ZIP_EXTERN int zip_source_begin_write(zip_source_t *_Nonnull);
+ZIP_EXTERN int zip_source_begin_write_cloning(zip_source_t *_Nonnull, zip_uint64_t);
+ZIP_EXTERN zip_source_t *_Nullable zip_source_buffer(zip_t *_Nonnull, const void *_Nullable, zip_uint64_t, int);
+ZIP_EXTERN zip_source_t *_Nullable zip_source_buffer_create(const void *_Nullable, zip_uint64_t, int, zip_error_t *_Nullable);
+ZIP_EXTERN zip_source_t *_Nullable zip_source_buffer_fragment(zip_t *_Nonnull, const zip_buffer_fragment_t *_Nonnull, zip_uint64_t, int);
+ZIP_EXTERN zip_source_t *_Nullable zip_source_buffer_fragment_create(const zip_buffer_fragment_t *_Nullable, zip_uint64_t, int, zip_error_t *_Nullable);
+ZIP_EXTERN int zip_source_close(zip_source_t *_Nonnull);
+ZIP_EXTERN int zip_source_commit_write(zip_source_t *_Nonnull);
+ZIP_EXTERN zip_error_t *_Nonnull zip_source_error(zip_source_t *_Nonnull);
+ZIP_EXTERN zip_source_t *_Nullable zip_source_file(zip_t *_Nonnull, const char *_Nonnull, zip_uint64_t, zip_int64_t);
+ZIP_EXTERN zip_source_t *_Nullable zip_source_file_create(const char *_Nonnull, zip_uint64_t, zip_int64_t, zip_error_t *_Nullable);
+ZIP_EXTERN zip_source_t *_Nullable zip_source_filep(zip_t *_Nonnull, FILE *_Nonnull, zip_uint64_t, zip_int64_t);
+ZIP_EXTERN zip_source_t *_Nullable zip_source_filep_create(FILE *_Nonnull, zip_uint64_t, zip_int64_t, zip_error_t *_Nullable);
+ZIP_EXTERN void zip_source_free(zip_source_t *_Nullable);
+ZIP_EXTERN zip_source_t *_Nullable zip_source_function(zip_t *_Nonnull, zip_source_callback _Nonnull, void *_Nullable);
+ZIP_EXTERN zip_source_t *_Nullable zip_source_function_create(zip_source_callback _Nonnull, void *_Nullable, zip_error_t *_Nullable);
+ZIP_EXTERN int zip_source_get_file_attributes(zip_source_t *_Nonnull, zip_file_attributes_t *_Nonnull);
+ZIP_EXTERN int zip_source_is_deleted(zip_source_t *_Nonnull);
+ZIP_EXTERN void zip_source_keep(zip_source_t *_Nonnull);
ZIP_EXTERN zip_int64_t zip_source_make_command_bitmap(zip_source_cmd_t, ...);
-ZIP_EXTERN int zip_source_open(zip_source_t *);
-ZIP_EXTERN zip_int64_t zip_source_read(zip_source_t *, void *, zip_uint64_t);
-ZIP_EXTERN void zip_source_rollback_write(zip_source_t *);
-ZIP_EXTERN int zip_source_seek(zip_source_t *, zip_int64_t, int);
-ZIP_EXTERN zip_int64_t zip_source_seek_compute_offset(zip_uint64_t, zip_uint64_t, void *, zip_uint64_t, zip_error_t *);
-ZIP_EXTERN int zip_source_seek_write(zip_source_t *, zip_int64_t, int);
-ZIP_EXTERN int zip_source_stat(zip_source_t *, zip_stat_t *);
-ZIP_EXTERN zip_int64_t zip_source_tell(zip_source_t *);
-ZIP_EXTERN zip_int64_t zip_source_tell_write(zip_source_t *);
+ZIP_EXTERN int zip_source_open(zip_source_t *_Nonnull);
+ZIP_EXTERN zip_int64_t zip_source_read(zip_source_t *_Nonnull, void *_Nonnull, zip_uint64_t);
+ZIP_EXTERN void zip_source_rollback_write(zip_source_t *_Nonnull);
+ZIP_EXTERN int zip_source_seek(zip_source_t *_Nonnull, zip_int64_t, int);
+ZIP_EXTERN zip_int64_t zip_source_seek_compute_offset(zip_uint64_t, zip_uint64_t, void *_Nonnull, zip_uint64_t, zip_error_t *_Nullable);
+ZIP_EXTERN int zip_source_seek_write(zip_source_t *_Nonnull, zip_int64_t, int);
+ZIP_EXTERN int zip_source_stat(zip_source_t *_Nonnull, zip_stat_t *_Nonnull);
+ZIP_EXTERN zip_int64_t zip_source_tell(zip_source_t *_Nonnull);
+ZIP_EXTERN zip_int64_t zip_source_tell_write(zip_source_t *_Nonnull);
#ifdef _WIN32
ZIP_EXTERN zip_source_t *zip_source_win32a(zip_t *, const char *, zip_uint64_t, zip_int64_t);
ZIP_EXTERN zip_source_t *zip_source_win32a_create(const char *, zip_uint64_t, zip_int64_t, zip_error_t *);
@@ -433,15 +463,17 @@ ZIP_EXTERN zip_source_t *zip_source_win32handle_create(void *, zip_uint64_t, zip
ZIP_EXTERN zip_source_t *zip_source_win32w(zip_t *, const wchar_t *, zip_uint64_t, zip_int64_t);
ZIP_EXTERN zip_source_t *zip_source_win32w_create(const wchar_t *, zip_uint64_t, zip_int64_t, zip_error_t *);
#endif
-ZIP_EXTERN zip_int64_t zip_source_write(zip_source_t *, const void *, zip_uint64_t);
-ZIP_EXTERN zip_source_t * zip_source_zip(zip_t *, zip_t *, zip_uint64_t, zip_flags_t, zip_uint64_t, zip_int64_t);
-ZIP_EXTERN int zip_stat(zip_t *, const char *, zip_flags_t, zip_stat_t *);
-ZIP_EXTERN int zip_stat_index(zip_t *, zip_uint64_t, zip_flags_t, zip_stat_t *);
-ZIP_EXTERN void zip_stat_init( zip_stat_t *);
-ZIP_EXTERN const char * zip_strerror(zip_t *);
-ZIP_EXTERN int zip_unchange(zip_t *, zip_uint64_t);
-ZIP_EXTERN int zip_unchange_all(zip_t *);
-ZIP_EXTERN int zip_unchange_archive(zip_t *);
+ZIP_EXTERN zip_int64_t zip_source_write(zip_source_t *_Nonnull, const void *_Nullable, zip_uint64_t);
+ZIP_EXTERN zip_source_t *_Nullable zip_source_zip(zip_t *_Nonnull, zip_t *_Nonnull, zip_uint64_t, zip_flags_t, zip_uint64_t, zip_int64_t);
+ZIP_EXTERN int zip_stat(zip_t *_Nonnull, const char *_Nonnull, zip_flags_t, zip_stat_t *_Nonnull);
+ZIP_EXTERN int zip_stat_index(zip_t *_Nonnull, zip_uint64_t, zip_flags_t, zip_stat_t *_Nonnull);
+ZIP_EXTERN void zip_stat_init(zip_stat_t *_Nonnull);
+ZIP_EXTERN const char *_Nonnull zip_strerror(zip_t *_Nonnull);
+ZIP_EXTERN int zip_unchange(zip_t *_Nonnull, zip_uint64_t);
+ZIP_EXTERN int zip_unchange_all(zip_t *_Nonnull);
+ZIP_EXTERN int zip_unchange_archive(zip_t *_Nonnull);
+ZIP_EXTERN int zip_compression_method_supported(zip_int32_t method, int compress);
+ZIP_EXTERN int zip_encryption_method_supported(zip_uint16_t method, int encode);
#ifdef __cplusplus
}
diff --git a/src/Common/libzip/zip_add.c b/src/Common/libzip/zip_add.c
index f09c9ff..1954235 100644
--- a/src/Common/libzip/zip_add.c
+++ b/src/Common/libzip/zip_add.c
@@ -1,6 +1,6 @@
/*
zip_add.c -- add file via callback function
- Copyright (C) 1999-2018 Dieter Baron and Thomas Klausner
+ Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
diff --git a/src/Common/libzip/zip_add_dir.c b/src/Common/libzip/zip_add_dir.c
index 6beb929..88fcf53 100644
--- a/src/Common/libzip/zip_add_dir.c
+++ b/src/Common/libzip/zip_add_dir.c
@@ -1,6 +1,6 @@
/*
zip_add_dir.c -- add directory
- Copyright (C) 1999-2018 Dieter Baron and Thomas Klausner
+ Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
diff --git a/src/Common/libzip/zip_add_entry.c b/src/Common/libzip/zip_add_entry.c
index 45def7a..f52e0b5 100644
--- a/src/Common/libzip/zip_add_entry.c
+++ b/src/Common/libzip/zip_add_entry.c
@@ -1,6 +1,6 @@
/*
zip_add_entry.c -- create and init struct zip_entry
- Copyright (C) 1999-2018 Dieter Baron and Thomas Klausner
+ Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
diff --git a/src/Common/libzip/zip_algorithm_deflate.c b/src/Common/libzip/zip_algorithm_deflate.c
index ba5ad43..d28a1ac 100644
--- a/src/Common/libzip/zip_algorithm_deflate.c
+++ b/src/Common/libzip/zip_algorithm_deflate.c
@@ -1,6 +1,6 @@
/*
zip_algorithm_deflate.c -- deflate (de)compression routines
- Copyright (C) 2017-2018 Dieter Baron and Thomas Klausner
+ Copyright (C) 2017-2019 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
@@ -51,6 +51,7 @@ allocate(bool compress, int compression_flags, zip_error_t *error) {
struct ctx *ctx;
if ((ctx = (struct ctx *)malloc(sizeof(*ctx))) == NULL) {
+ zip_error_set(error, ZIP_ET_SYS, errno);
return NULL;
}
@@ -90,8 +91,8 @@ deallocate(void *ud) {
}
-static int
-compression_flags(void *ud) {
+static zip_uint16_t
+general_purpose_bit_flags(void *ud) {
struct ctx *ctx = (struct ctx *)ud;
if (!ctx->compress) {
@@ -99,10 +100,10 @@ compression_flags(void *ud) {
}
if (ctx->compression_flags < 3) {
- return 2;
+ return 2 << 1;
}
else if (ctx->compression_flags > 7) {
- return 1;
+ return 1 << 1;
}
return 0;
}
@@ -219,12 +220,13 @@ process(void *ud, zip_uint8_t *data, zip_uint64_t *length) {
}
}
-// clang-format off
+/* clang-format off */
zip_compression_algorithm_t zip_algorithm_deflate_compress = {
compress_allocate,
deallocate,
- compression_flags,
+ general_purpose_bit_flags,
+ 20,
start,
end,
input,
@@ -236,7 +238,8 @@ zip_compression_algorithm_t zip_algorithm_deflate_compress = {
zip_compression_algorithm_t zip_algorithm_deflate_decompress = {
decompress_allocate,
deallocate,
- compression_flags,
+ general_purpose_bit_flags,
+ 20,
start,
end,
input,
@@ -244,4 +247,4 @@ zip_compression_algorithm_t zip_algorithm_deflate_decompress = {
process
};
-// clang-format on
+/* clang-format on */
diff --git a/src/Common/libzip/zip_buffer.c b/src/Common/libzip/zip_buffer.c
index 37977f0..8c24b27 100644
--- a/src/Common/libzip/zip_buffer.c
+++ b/src/Common/libzip/zip_buffer.c
@@ -1,6 +1,6 @@
/*
zip_buffer.c -- bounds checked access to memory buffer
- Copyright (C) 2014-2018 Dieter Baron and Thomas Klausner
+ Copyright (C) 2014-2019 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
diff --git a/src/Common/libzip/zip_close.c b/src/Common/libzip/zip_close.c
index 2657226..816fcef 100644
--- a/src/Common/libzip/zip_close.c
+++ b/src/Common/libzip/zip_close.c
@@ -1,6 +1,6 @@
/*
zip_close.c -- close zip archive and update changes
- Copyright (C) 1999-2018 Dieter Baron and Thomas Klausner
+ Copyright (C) 1999-2020 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
@@ -36,25 +36,17 @@
#include <stdio.h>
#include <stdlib.h>
-#include <string.h>
-#ifdef HAVE_STRINGS_H
-#include <strings.h>
-#endif
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#include <sys/stat.h>
-#include <sys/types.h>
#ifdef _WIN32
#include <fcntl.h>
#include <io.h>
#endif
-static int add_data(zip_t *, zip_source_t *, zip_dirent_t *);
+static int add_data(zip_t *, zip_source_t *, zip_dirent_t *, zip_uint32_t);
static int copy_data(zip_t *, zip_uint64_t);
static int copy_source(zip_t *, zip_source_t *, zip_int64_t);
static int write_cdir(zip_t *, const zip_filelist_t *, zip_uint64_t);
+static int write_data_descriptor(zip_t *za, const zip_dirent_t *dirent, int is_zip64);
ZIP_EXTERN int
zip_close(zip_t *za) {
@@ -73,8 +65,10 @@ zip_close(zip_t *za) {
if (survivors == 0) {
if ((za->open_flags & ZIP_TRUNCATE) || changed) {
if (zip_source_remove(za->src) < 0) {
- _zip_error_set_from_source(&za->error, za->src);
- return -1;
+ if (!((zip_error_code_zip(zip_source_error(za->src)) == ZIP_ER_REMOVE) && (zip_error_code_system(zip_source_error(za->src)) == ENOENT))) {
+ _zip_error_set_from_source(&za->error, za->src);
+ return -1;
+ }
}
}
zip_discard(za);
@@ -158,14 +152,23 @@ zip_close(zip_t *za) {
}
}
- _zip_progress_start(za->progress);
+ if (_zip_progress_start(za->progress) != 0) {
+ zip_error_set(&za->error, ZIP_ER_CANCELLED, 0);
+ zip_source_rollback_write(za->src);
+ free(filelist);
+ return -1;
+ }
error = 0;
for (j = 0; j < survivors; j++) {
int new_data;
zip_entry_t *entry;
zip_dirent_t *de;
- _zip_progress_subrange(za->progress, (double)j / (double)survivors, (double)(j + 1) / (double)survivors);
+ if (_zip_progress_subrange(za->progress, (double)j / (double)survivors, (double)(j + 1) / (double)survivors) != 0) {
+ zip_error_set(&za->error, ZIP_ER_CANCELLED, 0);
+ error = 1;
+ break;
+ }
i = filelist[j].idx;
entry = za->entry + i;
@@ -193,6 +196,7 @@ zip_close(zip_t *za) {
}
if ((off = zip_source_tell_write(za->src)) < 0) {
+ _zip_error_set_from_source(&za->error, za->src);
error = 1;
break;
}
@@ -210,7 +214,7 @@ zip_close(zip_t *za) {
}
/* add_data writes dirent */
- if (add_data(za, zs ? zs : entry->source, de) < 0) {
+ if (add_data(za, zs ? zs : entry->source, de, entry->changes ? entry->changes->changed : 0) < 0) {
error = 1;
if (zs)
zip_source_free(zs);
@@ -222,8 +226,11 @@ zip_close(zip_t *za) {
else {
zip_uint64_t offset;
- /* when copying data, all sizes are known -> no data descriptor needed */
- de->bitflags &= (zip_uint16_t)~ZIP_GPBF_DATA_DESCRIPTOR;
+ if (de->encryption_method != ZIP_EM_TRAD_PKWARE) {
+ /* when copying data, all sizes are known -> no data descriptor needed */
+ /* except for PKWare encryption, where removing the data descriptor breaks password validation */
+ de->bitflags &= (zip_uint16_t)~ZIP_GPBF_DATA_DESCRIPTOR;
+ }
if (_zip_dirent_write(za, de, ZIP_FL_LOCAL) < 0) {
error = 1;
break;
@@ -234,13 +241,20 @@ zip_close(zip_t *za) {
}
if (zip_source_seek(za->src, (zip_int64_t)offset, SEEK_SET) < 0) {
_zip_error_set_from_source(&za->error, za->src);
- error = 1;
+ error = 1;
break;
}
if (copy_data(za, de->comp_size) < 0) {
- error = 1;
+ error = 1;
break;
}
+
+ if (de->bitflags & ZIP_GPBF_DATA_DESCRIPTOR) {
+ if (write_data_descriptor(za, de, _zip_dirent_needs_zip64(de, 0)) < 0) {
+ error = 1;
+ break;
+ }
+ }
}
}
@@ -256,10 +270,9 @@ zip_close(zip_t *za) {
_zip_error_set_from_source(&za->error, za->src);
error = 1;
}
+ _zip_progress_end(za->progress);
}
- _zip_progress_end(za->progress);
-
if (error) {
zip_source_rollback_write(za->src);
return -1;
@@ -272,14 +285,14 @@ zip_close(zip_t *za) {
static int
-add_data(zip_t *za, zip_source_t *src, zip_dirent_t *de) {
+add_data(zip_t *za, zip_source_t *src, zip_dirent_t *de, zip_uint32_t changed) {
zip_int64_t offstart, offdata, offend, data_length;
- struct zip_stat st;
+ zip_stat_t st;
+ zip_file_attributes_t attributes;
zip_source_t *src_final, *src_tmp;
int ret;
int is_zip64;
zip_flags_t flags;
- zip_int8_t compression_flags;
bool needs_recompress, needs_decompress, needs_crc, needs_compress, needs_reencrypt, needs_decrypt, needs_encrypt;
if (zip_source_stat(src, &st) < 0) {
@@ -443,6 +456,9 @@ add_data(zip_t *za, zip_source_t *src, zip_dirent_t *de) {
zip_source_free(src_final);
return -1;
}
+ if (de->encryption_method == ZIP_EM_TRAD_PKWARE) {
+ de->bitflags |= ZIP_GPBF_DATA_DESCRIPTOR;
+ }
zip_source_free(src_final);
src_final = src_tmp;
@@ -461,7 +477,7 @@ add_data(zip_t *za, zip_source_t *src, zip_dirent_t *de) {
ret = -1;
}
- if ((compression_flags = zip_source_get_compression_flags(src_final)) < 0) {
+ if (zip_source_get_file_attributes(src_final, &attributes) != 0) {
_zip_error_set_from_source(&za->error, src_final);
ret = -1;
}
@@ -497,8 +513,7 @@ add_data(zip_t *za, zip_source_t *src, zip_dirent_t *de) {
de->crc = st.crc;
de->uncomp_size = st.size;
de->comp_size = (zip_uint64_t)(offend - offdata);
- de->bitflags = (zip_uint16_t)((de->bitflags & (zip_uint16_t)~6) | ((zip_uint8_t)compression_flags << 1));
- _zip_dirent_set_version_needed(de, (flags & ZIP_FL_FORCE_ZIP64) != 0);
+ _zip_dirent_apply_attributes(de, &attributes, (flags & ZIP_FL_FORCE_ZIP64) != 0, changed);
if ((ret = _zip_dirent_write(za, de, flags)) < 0)
return -1;
@@ -514,6 +529,12 @@ add_data(zip_t *za, zip_source_t *src, zip_dirent_t *de) {
return -1;
}
+ if (de->bitflags & ZIP_GPBF_DATA_DESCRIPTOR) {
+ if (write_data_descriptor(za, de, is_zip64) < 0) {
+ return -1;
+ }
+ }
+
return 0;
}
@@ -543,7 +564,10 @@ copy_data(zip_t *za, zip_uint64_t len) {
len -= n;
- _zip_progress_update(za->progress, (total - (double)len) / total);
+ if (_zip_progress_update(za->progress, (total - (double)len) / total) != 0) {
+ zip_error_set(&za->error, ZIP_ER_CANCELLED, 0);
+ return -1;
+ }
}
byte_array_fini(buf);
@@ -576,7 +600,11 @@ copy_source(zip_t *za, zip_source_t *src, zip_int64_t data_length) {
}
if (n == BUFSIZE && za->progress && data_length > 0) {
current += n;
- _zip_progress_update(za->progress, (double)current / (double)data_length);
+ if (_zip_progress_update(za->progress, (double)current / (double)data_length) != 0) {
+ zip_error_set(&za->error, ZIP_ER_CANCELLED, 0);
+ ret = -1;
+ break;
+ }
}
}
@@ -639,3 +667,37 @@ _zip_changed(const zip_t *za, zip_uint64_t *survivorsp) {
return changed;
}
+
+static int
+write_data_descriptor(zip_t *za, const zip_dirent_t *de, int is_zip64) {
+ zip_buffer_t *buffer = _zip_buffer_new(NULL, MAX_DATA_DESCRIPTOR_LENGTH);
+ int ret = 0;
+
+ if (buffer == NULL) {
+ zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
+ return -1;
+ }
+
+ _zip_buffer_put(buffer, DATADES_MAGIC, 4);
+ _zip_buffer_put_32(buffer, de->crc);
+ if (is_zip64) {
+ _zip_buffer_put_64(buffer, de->comp_size);
+ _zip_buffer_put_64(buffer, de->uncomp_size);
+ }
+ else {
+ _zip_buffer_put_32(buffer, (zip_uint32_t)de->comp_size);
+ _zip_buffer_put_32(buffer, (zip_uint32_t)de->uncomp_size);
+ }
+
+ if (!_zip_buffer_ok(buffer)) {
+ zip_error_set(&za->error, ZIP_ER_INTERNAL, 0);
+ ret = -1;
+ }
+ else {
+ ret = _zip_write(za, _zip_buffer_data(buffer), _zip_buffer_offset(buffer));
+ }
+
+ _zip_buffer_free(buffer);
+
+ return ret;
+}
diff --git a/src/Common/libzip/zip_delete.c b/src/Common/libzip/zip_delete.c
index 458a1b8..97701a0 100644
--- a/src/Common/libzip/zip_delete.c
+++ b/src/Common/libzip/zip_delete.c
@@ -1,6 +1,6 @@
/*
zip_delete.c -- delete file from zip archive
- Copyright (C) 1999-2018 Dieter Baron and Thomas Klausner
+ Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
diff --git a/src/Common/libzip/zip_dir_add.c b/src/Common/libzip/zip_dir_add.c
index 46c76cf..c40b1cb 100644
--- a/src/Common/libzip/zip_dir_add.c
+++ b/src/Common/libzip/zip_dir_add.c
@@ -1,6 +1,6 @@
/*
zip_dir_add.c -- add directory
- Copyright (C) 1999-2018 Dieter Baron and Thomas Klausner
+ Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
diff --git a/src/Common/libzip/zip_dirent.c b/src/Common/libzip/zip_dirent.c
index 4dcb339..1691071 100644
--- a/src/Common/libzip/zip_dirent.c
+++ b/src/Common/libzip/zip_dirent.c
@@ -1,6 +1,6 @@
/*
zip_dirent.c -- read directory entry (local or central), clean dirent
- Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner
+ Copyright (C) 1999-2020 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
@@ -35,13 +35,11 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <sys/stat.h>
#include <sys/types.h>
#include <time.h>
#include "zipint.h"
-static time_t _zip_d2u_time(zip_uint16_t, zip_uint16_t);
static zip_string_t *_zip_dirent_process_ef_utf_8(const zip_dirent_t *de, zip_uint16_t id, zip_string_t *str);
static zip_extra_field_t *_zip_ef_utf8(zip_uint16_t, zip_string_t *, zip_error_t *);
static bool _zip_dirent_process_winzip_aes(zip_dirent_t *de, zip_error_t *error);
@@ -523,29 +521,54 @@ _zip_dirent_read(zip_dirent_t *zde, zip_source_t *src, zip_buffer_t *buffer, boo
return -1;
}
- if (zde->uncomp_size == ZIP_UINT32_MAX)
+ if (zde->uncomp_size == ZIP_UINT32_MAX) {
zde->uncomp_size = _zip_buffer_get_64(ef_buffer);
+ }
else if (local) {
/* From appnote.txt: This entry in the Local header MUST
include BOTH original and compressed file size fields. */
(void)_zip_buffer_skip(ef_buffer, 8); /* error is caught by _zip_buffer_eof() call */
}
- if (zde->comp_size == ZIP_UINT32_MAX)
+ if (zde->comp_size == ZIP_UINT32_MAX) {
zde->comp_size = _zip_buffer_get_64(ef_buffer);
+ }
if (!local) {
- if (zde->offset == ZIP_UINT32_MAX)
+ if (zde->offset == ZIP_UINT32_MAX) {
zde->offset = _zip_buffer_get_64(ef_buffer);
- if (zde->disk_number == ZIP_UINT16_MAX)
+ }
+ if (zde->disk_number == ZIP_UINT16_MAX) {
zde->disk_number = _zip_buffer_get_32(ef_buffer);
+ }
}
if (!_zip_buffer_eof(ef_buffer)) {
- zip_error_set(error, ZIP_ER_INCONS, 0);
- _zip_buffer_free(ef_buffer);
- if (!from_buffer) {
- _zip_buffer_free(buffer);
+ /* accept additional fields if values match */
+ bool ok = true;
+ switch (got_len) {
+ case 28:
+ _zip_buffer_set_offset(ef_buffer, 24);
+ if (zde->disk_number != _zip_buffer_get_32(ef_buffer)) {
+ ok = false;
+ }
+ /* fallthrough */
+ case 24:
+ _zip_buffer_set_offset(ef_buffer, 0);
+ if ((zde->uncomp_size != _zip_buffer_get_64(ef_buffer)) || (zde->comp_size != _zip_buffer_get_64(ef_buffer)) || (zde->offset != _zip_buffer_get_64(ef_buffer))) {
+ ok = false;
+ }
+ break;
+
+ default:
+ ok = false;
+ }
+ if (!ok) {
+ zip_error_set(error, ZIP_ER_INCONS, 0);
+ _zip_buffer_free(ef_buffer);
+ if (!from_buffer) {
+ _zip_buffer_free(buffer);
+ }
+ return -1;
}
- return -1;
}
_zip_buffer_free(ef_buffer);
}
@@ -573,7 +596,7 @@ _zip_dirent_read(zip_dirent_t *zde, zip_source_t *src, zip_buffer_t *buffer, boo
zde->extra_fields = _zip_ef_remove_internal(zde->extra_fields);
- return (zip_int64_t)(size + variable_size);
+ return (zip_int64_t)size + (zip_int64_t)variable_size;
}
@@ -868,9 +891,9 @@ _zip_dirent_write(zip_t *za, zip_dirent_t *de, zip_flags_t flags) {
_zip_buffer_put(buffer, (flags & ZIP_FL_LOCAL) ? LOCAL_MAGIC : CENTRAL_MAGIC, 4);
if ((flags & ZIP_FL_LOCAL) == 0) {
- _zip_buffer_put_16(buffer, (zip_uint16_t)(is_really_zip64 ? 45 : de->version_madeby));
+ _zip_buffer_put_16(buffer, de->version_madeby);
}
- _zip_buffer_put_16(buffer, (zip_uint16_t)(is_really_zip64 ? 45 : de->version_needed));
+ _zip_buffer_put_16(buffer, ZIP_MAX(is_really_zip64 ? 45 : 0, de->version_needed));
_zip_buffer_put_16(buffer, de->bitflags);
if (is_winzip_aes) {
_zip_buffer_put_16(buffer, ZIP_CM_WINZIP_AES);
@@ -978,7 +1001,7 @@ _zip_dirent_write(zip_t *za, zip_dirent_t *de, zip_flags_t flags) {
}
-static time_t
+time_t
_zip_d2u_time(zip_uint16_t dtime, zip_uint16_t ddate) {
struct tm tm;
@@ -1066,57 +1089,75 @@ _zip_get_dirent(zip_t *za, zip_uint64_t idx, zip_flags_t flags, zip_error_t *err
void
_zip_u2d_time(time_t intime, zip_uint16_t *dtime, zip_uint16_t *ddate) {
- struct tm *tm;
+ struct tm *tpm;
- tm = localtime(&intime);
- if (tm == NULL) {
- /* if localtime() fails, return an arbitrary date (1980-01-01 00:00:00) */
+#ifdef HAVE_LOCALTIME_R
+ struct tm tm;
+ tpm = localtime_r(&intime, &tm);
+#else
+ tpm = localtime(&intime);
+#endif
+ if (tpm == NULL) {
+ /* if localtime() fails, return an arbitrary date (1980-01-01 00:00:00) */
*ddate = (1 << 5) + 1;
*dtime = 0;
return;
}
- if (tm->tm_year < 80) {
- tm->tm_year = 80;
+ if (tpm->tm_year < 80) {
+ tpm->tm_year = 80;
}
- *ddate = (zip_uint16_t)(((tm->tm_year + 1900 - 1980) << 9) + ((tm->tm_mon + 1) << 5) + tm->tm_mday);
- *dtime = (zip_uint16_t)(((tm->tm_hour) << 11) + ((tm->tm_min) << 5) + ((tm->tm_sec) >> 1));
+ *ddate = (zip_uint16_t)(((tpm->tm_year + 1900 - 1980) << 9) + ((tpm->tm_mon + 1) << 5) + tpm->tm_mday);
+ *dtime = (zip_uint16_t)(((tpm->tm_hour) << 11) + ((tpm->tm_min) << 5) + ((tpm->tm_sec) >> 1));
return;
}
void
-_zip_dirent_set_version_needed(zip_dirent_t *de, bool force_zip64) {
+_zip_dirent_apply_attributes(zip_dirent_t *de, zip_file_attributes_t *attributes, bool force_zip64, zip_uint32_t changed) {
zip_uint16_t length;
+ if (attributes->valid & ZIP_FILE_ATTRIBUTES_GENERAL_PURPOSE_BIT_FLAGS) {
+ zip_uint16_t mask = attributes->general_purpose_bit_mask & ZIP_FILE_ATTRIBUTES_GENERAL_PURPOSE_BIT_FLAGS_ALLOWED_MASK;
+ de->bitflags = (de->bitflags & ~mask) | (attributes->general_purpose_bit_flags & mask);
+ }
+ if (attributes->valid & ZIP_FILE_ATTRIBUTES_ASCII) {
+ de->int_attrib = (de->int_attrib & ~0x1) | (attributes->ascii ? 1 : 0);
+ }
+ /* manually set attributes are preferred over attributes provided by source */
+ if ((changed & ZIP_DIRENT_ATTRIBUTES) == 0 && (attributes->valid & ZIP_FILE_ATTRIBUTES_EXTERNAL_FILE_ATTRIBUTES)) {
+ de->ext_attrib = attributes->external_file_attributes;
+ }
+
if (de->comp_method == ZIP_CM_LZMA) {
de->version_needed = 63;
- return;
}
-
- if (de->comp_method == ZIP_CM_BZIP2) {
+ else if (de->encryption_method == ZIP_EM_AES_128 || de->encryption_method == ZIP_EM_AES_192 || de->encryption_method == ZIP_EM_AES_256) {
+ de->version_needed = 51;
+ }
+ else if (de->comp_method == ZIP_CM_BZIP2) {
de->version_needed = 46;
- return;
}
-
- if (force_zip64 || _zip_dirent_needs_zip64(de, 0)) {
+ else if (force_zip64 || _zip_dirent_needs_zip64(de, 0)) {
de->version_needed = 45;
- return;
}
-
- if (de->comp_method == ZIP_CM_DEFLATE || de->encryption_method == ZIP_EM_TRAD_PKWARE) {
+ else if (de->comp_method == ZIP_CM_DEFLATE || de->encryption_method == ZIP_EM_TRAD_PKWARE) {
+ de->version_needed = 20;
+ }
+ else if ((length = _zip_string_length(de->filename)) > 0 && de->filename->raw[length - 1] == '/') {
de->version_needed = 20;
- return;
+ }
+ else {
+ de->version_needed = 10;
}
- /* directory */
- if ((length = _zip_string_length(de->filename)) > 0) {
- if (de->filename->raw[length - 1] == '/') {
- de->version_needed = 20;
- return;
- }
+ if (attributes->valid & ZIP_FILE_ATTRIBUTES_VERSION_NEEDED) {
+ de->version_needed = ZIP_MAX(de->version_needed, attributes->version_needed);
}
- de->version_needed = 10;
+ de->version_madeby = 63 | (de->version_madeby & 0xff00);
+ if ((changed & ZIP_DIRENT_ATTRIBUTES) == 0 && (attributes->valid & ZIP_FILE_ATTRIBUTES_HOST_SYSTEM)) {
+ de->version_madeby = (de->version_madeby & 0xff) | (zip_uint16_t)(attributes->host_system << 8);
+ }
}
diff --git a/src/Common/libzip/zip_discard.c b/src/Common/libzip/zip_discard.c
index 94972cf..12f0636 100644
--- a/src/Common/libzip/zip_discard.c
+++ b/src/Common/libzip/zip_discard.c
@@ -1,6 +1,6 @@
/*
zip_discard.c -- discard and free struct zip
- Copyright (C) 1999-2018 Dieter Baron and Thomas Klausner
+ Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
diff --git a/src/Common/libzip/zip_entry.c b/src/Common/libzip/zip_entry.c
index 55f6458..52ecaef 100644
--- a/src/Common/libzip/zip_entry.c
+++ b/src/Common/libzip/zip_entry.c
@@ -1,6 +1,6 @@
/*
zip_entry.c -- struct zip_entry helper functions
- Copyright (C) 1999-2018 Dieter Baron and Thomas Klausner
+ Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
diff --git a/src/Common/libzip/zip_err_str.c b/src/Common/libzip/zip_err_str.c
index 3d9ee54..e0a04a9 100644
--- a/src/Common/libzip/zip_err_str.c
+++ b/src/Common/libzip/zip_err_str.c
@@ -5,16 +5,80 @@
#include "zipint.h"
-const char *const _zip_err_str[] = {
- "No error", "Multi-disk zip archives not supported", "Renaming temporary file failed", "Closing zip archive failed", "Seek error", "Read error", "Write error", "CRC error", "Containing zip archive was closed", "No such file", "File already exists", "Can't open file", "Failure to create temporary file", "Zlib error", "Malloc failure", "Entry has been changed", "Compression method not supported", "Premature end of file", "Invalid argument", "Not a zip archive", "Internal error", "Zip archive inconsistent", "Can't remove file", "Entry has been deleted", "Encryption method not supported", "Read-only archive", "No password provided", "Wrong password provided", "Operation not supported", "Resource still in use", "Tell error", "Compressed data invalid",
+const char * const _zip_err_str[] = {
+ "No error",
+ "Multi-disk zip archives not supported",
+ "Renaming temporary file failed",
+ "Closing zip archive failed",
+ "Seek error",
+ "Read error",
+ "Write error",
+ "CRC error",
+ "Containing zip archive was closed",
+ "No such file",
+ "File already exists",
+ "Can't open file",
+ "Failure to create temporary file",
+ "Zlib error",
+ "Malloc failure",
+ "Entry has been changed",
+ "Compression method not supported",
+ "Premature end of file",
+ "Invalid argument",
+ "Not a zip archive",
+ "Internal error",
+ "Zip archive inconsistent",
+ "Can't remove file",
+ "Entry has been deleted",
+ "Encryption method not supported",
+ "Read-only archive",
+ "No password provided",
+ "Wrong password provided",
+ "Operation not supported",
+ "Resource still in use",
+ "Tell error",
+ "Compressed data invalid",
+ "Operation cancelled",
};
-const int _zip_nerr_str = sizeof(_zip_err_str) / sizeof(_zip_err_str[0]);
+const int _zip_nerr_str = sizeof(_zip_err_str)/sizeof(_zip_err_str[0]);
#define N ZIP_ET_NONE
#define S ZIP_ET_SYS
#define Z ZIP_ET_ZLIB
const int _zip_err_type[] = {
- N, N, S, S, S, S, S, N, N, N, N, S, S, Z, N, N, N, N, N, N, N, N, S, N, N, N, N, N, N, N, S, N,
+ N,
+ N,
+ S,
+ S,
+ S,
+ S,
+ S,
+ N,
+ N,
+ N,
+ N,
+ S,
+ S,
+ Z,
+ N,
+ N,
+ N,
+ N,
+ N,
+ N,
+ N,
+ N,
+ S,
+ N,
+ N,
+ N,
+ N,
+ N,
+ N,
+ N,
+ S,
+ N,
+ N,
};
diff --git a/src/Common/libzip/zip_error.c b/src/Common/libzip/zip_error.c
index e05ae50..a0f74f0 100644
--- a/src/Common/libzip/zip_error.c
+++ b/src/Common/libzip/zip_error.c
@@ -1,6 +1,6 @@
/*
zip_error.c -- zip_error_t helper functions
- Copyright (C) 1999-2018 Dieter Baron and Thomas Klausner
+ Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
diff --git a/src/Common/libzip/zip_error_clear.c b/src/Common/libzip/zip_error_clear.c
index 6b3a8da..eec1568 100644
--- a/src/Common/libzip/zip_error_clear.c
+++ b/src/Common/libzip/zip_error_clear.c
@@ -1,6 +1,6 @@
/*
zip_error_clear.c -- clear zip error
- Copyright (C) 1999-2018 Dieter Baron and Thomas Klausner
+ Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
diff --git a/src/Common/libzip/zip_error_get.c b/src/Common/libzip/zip_error_get.c
index 12341d1..9588b4c 100644
--- a/src/Common/libzip/zip_error_get.c
+++ b/src/Common/libzip/zip_error_get.c
@@ -1,6 +1,6 @@
/*
zip_error_get.c -- get zip error
- Copyright (C) 1999-2018 Dieter Baron and Thomas Klausner
+ Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
diff --git a/src/Common/libzip/zip_error_get_sys_type.c b/src/Common/libzip/zip_error_get_sys_type.c
index 80bfc0c..3dfe5c2 100644
--- a/src/Common/libzip/zip_error_get_sys_type.c
+++ b/src/Common/libzip/zip_error_get_sys_type.c
@@ -1,6 +1,6 @@
/*
zip_error_get_sys_type.c -- return type of system error code
- Copyright (C) 1999-2018 Dieter Baron and Thomas Klausner
+ Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
diff --git a/src/Common/libzip/zip_error_strerror.c b/src/Common/libzip/zip_error_strerror.c
index 0f650b5..93b24ea 100644
--- a/src/Common/libzip/zip_error_strerror.c
+++ b/src/Common/libzip/zip_error_strerror.c
@@ -1,6 +1,6 @@
/*
zip_error_sterror.c -- get string representation of struct zip_error
- Copyright (C) 1999-2018 Dieter Baron and Thomas Klausner
+ Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
@@ -35,6 +35,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <zlib.h>
#include "zipint.h"
diff --git a/src/Common/libzip/zip_error_to_str.c b/src/Common/libzip/zip_error_to_str.c
index bf51569..34a3331 100644
--- a/src/Common/libzip/zip_error_to_str.c
+++ b/src/Common/libzip/zip_error_to_str.c
@@ -1,6 +1,6 @@
/*
zip_error_to_str.c -- get string representation of zip error code
- Copyright (C) 1999-2018 Dieter Baron and Thomas Klausner
+ Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
@@ -33,8 +33,8 @@
#include <stdio.h>
-#include <stdlib.h>
#include <string.h>
+#include <zlib.h>
#define _ZIP_COMPILING_DEPRECATED
#include "zipint.h"
diff --git a/src/Common/libzip/zip_extra_field.c b/src/Common/libzip/zip_extra_field.c
index a17e491..7114a25 100644
--- a/src/Common/libzip/zip_extra_field.c
+++ b/src/Common/libzip/zip_extra_field.c
@@ -1,6 +1,6 @@
/*
zip_extra_field.c -- manipulate extra fields
- Copyright (C) 2012-2018 Dieter Baron and Thomas Klausner
+ Copyright (C) 2012-2019 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
diff --git a/src/Common/libzip/zip_extra_field_api.c b/src/Common/libzip/zip_extra_field_api.c
index 31808de..605f95d 100644
--- a/src/Common/libzip/zip_extra_field_api.c
+++ b/src/Common/libzip/zip_extra_field_api.c
@@ -1,6 +1,6 @@
/*
zip_extra_field_api.c -- public extra fields API functions
- Copyright (C) 2012-2018 Dieter Baron and Thomas Klausner
+ Copyright (C) 2012-2019 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
diff --git a/src/Common/libzip/zip_fclose.c b/src/Common/libzip/zip_fclose.c
index 1c69a96..6eb9dc9 100644
--- a/src/Common/libzip/zip_fclose.c
+++ b/src/Common/libzip/zip_fclose.c
@@ -1,6 +1,6 @@
/*
zip_fclose.c -- close file in zip archive
- Copyright (C) 1999-2018 Dieter Baron and Thomas Klausner
+ Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
diff --git a/src/Common/libzip/zip_fdopen.c b/src/Common/libzip/zip_fdopen.c
index 3270935..5a732cd 100644
--- a/src/Common/libzip/zip_fdopen.c
+++ b/src/Common/libzip/zip_fdopen.c
@@ -1,6 +1,6 @@
/*
zip_fdopen.c -- open read-only archive from file descriptor
- Copyright (C) 2009-2018 Dieter Baron and Thomas Klausner
+ Copyright (C) 2009-2019 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
diff --git a/src/Common/libzip/zip_file_add.c b/src/Common/libzip/zip_file_add.c
index c2c13d6..c019d8d 100644
--- a/src/Common/libzip/zip_file_add.c
+++ b/src/Common/libzip/zip_file_add.c
@@ -1,6 +1,6 @@
/*
zip_file_add.c -- add file via callback function
- Copyright (C) 1999-2018 Dieter Baron and Thomas Klausner
+ Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
diff --git a/src/Common/libzip/zip_file_error_clear.c b/src/Common/libzip/zip_file_error_clear.c
index 2e7dcea..47e5da6 100644
--- a/src/Common/libzip/zip_file_error_clear.c
+++ b/src/Common/libzip/zip_file_error_clear.c
@@ -1,6 +1,6 @@
/*
zip_file_error_clear.c -- clear zip file error
- Copyright (C) 1999-2018 Dieter Baron and Thomas Klausner
+ Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
diff --git a/src/Common/libzip/zip_file_error_get.c b/src/Common/libzip/zip_file_error_get.c
index 1d13807..1ed68df 100644
--- a/src/Common/libzip/zip_file_error_get.c
+++ b/src/Common/libzip/zip_file_error_get.c
@@ -1,6 +1,6 @@
/*
zip_file_error_get.c -- get zip file error
- Copyright (C) 1999-2018 Dieter Baron and Thomas Klausner
+ Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
diff --git a/src/Common/libzip/zip_file_get_comment.c b/src/Common/libzip/zip_file_get_comment.c
index ad944aa..8f68141 100644
--- a/src/Common/libzip/zip_file_get_comment.c
+++ b/src/Common/libzip/zip_file_get_comment.c
@@ -1,6 +1,6 @@
/*
zip_file_get_comment.c -- get file comment
- Copyright (C) 2006-2018 Dieter Baron and Thomas Klausner
+ Copyright (C) 2006-2019 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
diff --git a/src/Common/libzip/zip_file_get_external_attributes.c b/src/Common/libzip/zip_file_get_external_attributes.c
index e2e5535..ebc2058 100644
--- a/src/Common/libzip/zip_file_get_external_attributes.c
+++ b/src/Common/libzip/zip_file_get_external_attributes.c
@@ -1,6 +1,6 @@
/*
zip_file_get_external_attributes.c -- get opsys/external attributes
- Copyright (C) 2013-2018 Dieter Baron and Thomas Klausner
+ Copyright (C) 2013-2019 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
diff --git a/src/Common/libzip/zip_file_get_offset.c b/src/Common/libzip/zip_file_get_offset.c
index 858a78a..2cf4480 100644
--- a/src/Common/libzip/zip_file_get_offset.c
+++ b/src/Common/libzip/zip_file_get_offset.c
@@ -1,6 +1,6 @@
/*
zip_file_get_offset.c -- get offset of file data in archive.
- Copyright (C) 1999-2018 Dieter Baron and Thomas Klausner
+ Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
@@ -33,10 +33,7 @@
#include <stdio.h>
-#include <stdlib.h>
#include <string.h>
-#include <sys/stat.h>
-#include <sys/types.h>
#include "zipint.h"
diff --git a/src/Common/libzip/zip_file_rename.c b/src/Common/libzip/zip_file_rename.c
index cc42dfc..7ca428c 100644
--- a/src/Common/libzip/zip_file_rename.c
+++ b/src/Common/libzip/zip_file_rename.c
@@ -1,6 +1,6 @@
/*
zip_file_rename.c -- rename file in zip archive
- Copyright (C) 1999-2018 Dieter Baron and Thomas Klausner
+ Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
diff --git a/src/Common/libzip/zip_file_replace.c b/src/Common/libzip/zip_file_replace.c
index 70b379a..87401f4 100644
--- a/src/Common/libzip/zip_file_replace.c
+++ b/src/Common/libzip/zip_file_replace.c
@@ -1,6 +1,6 @@
/*
zip_file_replace.c -- replace file via callback function
- Copyright (C) 1999-2018 Dieter Baron and Thomas Klausner
+ Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
diff --git a/src/Common/libzip/zip_file_set_comment.c b/src/Common/libzip/zip_file_set_comment.c
index ae6b602..c309db8 100644
--- a/src/Common/libzip/zip_file_set_comment.c
+++ b/src/Common/libzip/zip_file_set_comment.c
@@ -1,6 +1,6 @@
/*
zip_file_set_comment.c -- set comment for file in archive
- Copyright (C) 2006-2018 Dieter Baron and Thomas Klausner
+ Copyright (C) 2006-2019 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
diff --git a/src/Common/libzip/zip_file_set_external_attributes.c b/src/Common/libzip/zip_file_set_external_attributes.c
index c412f27..bb2ea61 100644
--- a/src/Common/libzip/zip_file_set_external_attributes.c
+++ b/src/Common/libzip/zip_file_set_external_attributes.c
@@ -1,6 +1,6 @@
/*
zip_file_set_external_attributes.c -- set external attributes for entry
- Copyright (C) 2013-2018 Dieter Baron and Thomas Klausner
+ Copyright (C) 2013-2019 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
diff --git a/src/Common/libzip/zip_file_set_mtime.c b/src/Common/libzip/zip_file_set_mtime.c
index f8d6c20..838548e 100644
--- a/src/Common/libzip/zip_file_set_mtime.c
+++ b/src/Common/libzip/zip_file_set_mtime.c
@@ -1,6 +1,6 @@
/*
zip_file_set_mtime.c -- set modification time of entry.
- Copyright (C) 2014-2018 Dieter Baron and Thomas Klausner
+ Copyright (C) 2014-2020 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
@@ -34,9 +34,15 @@
#include "zipint.h"
ZIP_EXTERN int
+zip_file_set_dostime(zip_t *za, zip_uint64_t idx, zip_uint16_t dtime, zip_uint16_t ddate, zip_flags_t flags) {
+ time_t mtime;
+ mtime = _zip_d2u_time(dtime, ddate);
+ return zip_file_set_mtime(za, idx, mtime, flags);
+}
+
+ZIP_EXTERN int
zip_file_set_mtime(zip_t *za, zip_uint64_t idx, time_t mtime, zip_flags_t flags) {
zip_entry_t *e;
- int changed;
if (_zip_get_dirent(za, idx, 0, NULL) == NULL)
return -1;
@@ -48,27 +54,15 @@ zip_file_set_mtime(zip_t *za, zip_uint64_t idx, time_t mtime, zip_flags_t flags)
e = za->entry + idx;
- changed = e->orig == NULL || mtime != e->orig->last_mod;
-
- if (changed) {
- if (e->changes == NULL) {
- if ((e->changes = _zip_dirent_clone(e->orig)) == NULL) {
- zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
- return -1;
- }
- }
- e->changes->last_mod = mtime;
- e->changes->changed |= ZIP_DIRENT_LAST_MOD;
- }
- else {
- if (e->changes) {
- e->changes->changed &= ~ZIP_DIRENT_LAST_MOD;
- if (e->changes->changed == 0) {
- _zip_dirent_free(e->changes);
- e->changes = NULL;
- }
+ if (e->changes == NULL) {
+ if ((e->changes = _zip_dirent_clone(e->orig)) == NULL) {
+ zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
+ return -1;
}
}
+ e->changes->last_mod = mtime;
+ e->changes->changed |= ZIP_DIRENT_LAST_MOD;
+
return 0;
}
diff --git a/src/Common/libzip/zip_file_strerror.c b/src/Common/libzip/zip_file_strerror.c
index 189c556..1fa7fff 100644
--- a/src/Common/libzip/zip_file_strerror.c
+++ b/src/Common/libzip/zip_file_strerror.c
@@ -1,6 +1,6 @@
/*
zip_file_sterror.c -- get string representation of zip file error
- Copyright (C) 1999-2018 Dieter Baron and Thomas Klausner
+ Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
diff --git a/src/Common/libzip/zip_filerange_crc.c b/src/Common/libzip/zip_filerange_crc.c
index 33bf5d8..b887363 100644
--- a/src/Common/libzip/zip_filerange_crc.c
+++ b/src/Common/libzip/zip_filerange_crc.c
@@ -1,6 +1,6 @@
/*
zip_filerange_crc.c -- compute CRC32 for a range of a file
- Copyright (C) 2008-2018 Dieter Baron and Thomas Klausner
+ Copyright (C) 2008-2019 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
diff --git a/src/Common/libzip/zip_fopen.c b/src/Common/libzip/zip_fopen.c
index 4ef76ba..4f1a051 100644
--- a/src/Common/libzip/zip_fopen.c
+++ b/src/Common/libzip/zip_fopen.c
@@ -1,6 +1,6 @@
/*
zip_fopen.c -- open file in zip archive for reading
- Copyright (C) 1999-2018 Dieter Baron and Thomas Klausner
+ Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
diff --git a/src/Common/libzip/zip_fopen_encrypted.c b/src/Common/libzip/zip_fopen_encrypted.c
index 47cd377..9e9b13e 100644
--- a/src/Common/libzip/zip_fopen_encrypted.c
+++ b/src/Common/libzip/zip_fopen_encrypted.c
@@ -1,6 +1,6 @@
/*
zip_fopen_encrypted.c -- open file for reading with password
- Copyright (C) 1999-2018 Dieter Baron and Thomas Klausner
+ Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
diff --git a/src/Common/libzip/zip_fopen_index.c b/src/Common/libzip/zip_fopen_index.c
index 5f0dc2a..e5205b7 100644
--- a/src/Common/libzip/zip_fopen_index.c
+++ b/src/Common/libzip/zip_fopen_index.c
@@ -1,6 +1,6 @@
/*
zip_fopen_index.c -- open file in zip archive for reading by index
- Copyright (C) 1999-2018 Dieter Baron and Thomas Klausner
+ Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
@@ -32,9 +32,6 @@
*/
-#include <stdio.h>
-#include <stdlib.h>
-
#include "zipint.h"
diff --git a/src/Common/libzip/zip_fopen_index_encrypted.c b/src/Common/libzip/zip_fopen_index_encrypted.c
index 4d4aee3..6712c32 100644
--- a/src/Common/libzip/zip_fopen_index_encrypted.c
+++ b/src/Common/libzip/zip_fopen_index_encrypted.c
@@ -1,6 +1,6 @@
/*
zip_fopen_index_encrypted.c -- open file for reading by index w/ password
- Copyright (C) 1999-2018 Dieter Baron and Thomas Klausner
+ Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
diff --git a/src/Common/libzip/zip_fread.c b/src/Common/libzip/zip_fread.c
index 3020a16..646d712 100644
--- a/src/Common/libzip/zip_fread.c
+++ b/src/Common/libzip/zip_fread.c
@@ -1,6 +1,6 @@
/*
zip_fread.c -- read from file
- Copyright (C) 1999-2018 Dieter Baron and Thomas Klausner
+ Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
diff --git a/src/Common/libzip/zip_get_archive_comment.c b/src/Common/libzip/zip_get_archive_comment.c
index c51148d..953c6f4 100644
--- a/src/Common/libzip/zip_get_archive_comment.c
+++ b/src/Common/libzip/zip_get_archive_comment.c
@@ -1,6 +1,6 @@
/*
zip_get_archive_comment.c -- get archive comment
- Copyright (C) 2006-2018 Dieter Baron and Thomas Klausner
+ Copyright (C) 2006-2019 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
diff --git a/src/Common/libzip/zip_get_archive_flag.c b/src/Common/libzip/zip_get_archive_flag.c
index 1aaca72..fa4dd50 100644
--- a/src/Common/libzip/zip_get_archive_flag.c
+++ b/src/Common/libzip/zip_get_archive_flag.c
@@ -1,6 +1,6 @@
/*
zip_get_archive_flag.c -- get archive global flag
- Copyright (C) 2008-2018 Dieter Baron and Thomas Klausner
+ Copyright (C) 2008-2019 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
diff --git a/src/Common/libzip/zip_get_encryption_implementation.c b/src/Common/libzip/zip_get_encryption_implementation.c
index 07e4316..3909e6f 100644
--- a/src/Common/libzip/zip_get_encryption_implementation.c
+++ b/src/Common/libzip/zip_get_encryption_implementation.c
@@ -1,6 +1,6 @@
/*
zip_get_encryption_implementation.c -- get encryption implementation
- Copyright (C) 2009-2018 Dieter Baron and Thomas Klausner
+ Copyright (C) 2009-2019 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
@@ -39,10 +39,7 @@ zip_encryption_implementation
_zip_get_encryption_implementation(zip_uint16_t em, int operation) {
switch (em) {
case ZIP_EM_TRAD_PKWARE:
- if (operation == ZIP_CODEC_ENCODE) {
- return NULL;
- }
- return zip_source_pkware;
+ return operation == ZIP_CODEC_DECODE ? zip_source_pkware_decode : zip_source_pkware_encode;
#if defined(HAVE_CRYPTO)
case ZIP_EM_AES_128:
@@ -55,3 +52,11 @@ _zip_get_encryption_implementation(zip_uint16_t em, int operation) {
return NULL;
}
}
+
+ZIP_EXTERN int
+zip_encryption_method_supported(zip_uint16_t method, int encode) {
+ if (method == ZIP_EM_NONE) {
+ return 1;
+ }
+ return _zip_get_encryption_implementation(method, encode ? ZIP_CODEC_ENCODE : ZIP_CODEC_DECODE) != NULL;
+}
diff --git a/src/Common/libzip/zip_get_file_comment.c b/src/Common/libzip/zip_get_file_comment.c
index 6e85a58..f800686 100644
--- a/src/Common/libzip/zip_get_file_comment.c
+++ b/src/Common/libzip/zip_get_file_comment.c
@@ -1,6 +1,6 @@
/*
zip_get_file_comment.c -- get file comment
- Copyright (C) 2006-2018 Dieter Baron and Thomas Klausner
+ Copyright (C) 2006-2019 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
diff --git a/src/Common/libzip/zip_get_name.c b/src/Common/libzip/zip_get_name.c
index 2ac005a..4344209 100644
--- a/src/Common/libzip/zip_get_name.c
+++ b/src/Common/libzip/zip_get_name.c
@@ -1,6 +1,6 @@
/*
zip_get_name.c -- get filename for a file in zip file
- Copyright (C) 1999-2018 Dieter Baron and Thomas Klausner
+ Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
diff --git a/src/Common/libzip/zip_get_num_entries.c b/src/Common/libzip/zip_get_num_entries.c
index 99dfc7a..410d26e 100644
--- a/src/Common/libzip/zip_get_num_entries.c
+++ b/src/Common/libzip/zip_get_num_entries.c
@@ -1,6 +1,6 @@
/*
zip_get_num_entries.c -- get number of entries in archive
- Copyright (C) 1999-2018 Dieter Baron and Thomas Klausner
+ Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
diff --git a/src/Common/libzip/zip_get_num_files.c b/src/Common/libzip/zip_get_num_files.c
index b6e910e..4895eaa 100644
--- a/src/Common/libzip/zip_get_num_files.c
+++ b/src/Common/libzip/zip_get_num_files.c
@@ -1,6 +1,6 @@
/*
zip_get_num_files.c -- get number of files in archive
- Copyright (C) 1999-2018 Dieter Baron and Thomas Klausner
+ Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
diff --git a/src/Common/libzip/zip_hash.c b/src/Common/libzip/zip_hash.c
index 7288453..3206dbf 100644
--- a/src/Common/libzip/zip_hash.c
+++ b/src/Common/libzip/zip_hash.c
@@ -1,6 +1,6 @@
/*
zip_hash.c -- hash table string -> uint64
- Copyright (C) 2015-2018 Dieter Baron and Thomas Klausner
+ Copyright (C) 2015-2019 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
diff --git a/src/Common/libzip/zip_io_util.c b/src/Common/libzip/zip_io_util.c
index 53f4437..dd07cbb 100644
--- a/src/Common/libzip/zip_io_util.c
+++ b/src/Common/libzip/zip_io_util.c
@@ -1,6 +1,6 @@
/*
zip_io_util.c -- I/O helper functions
- Copyright (C) 1999-2018 Dieter Baron and Thomas Klausner
+ Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
diff --git a/src/Common/libzip/zip_memdup.c b/src/Common/libzip/zip_memdup.c
index d604408..05fcb7b 100644
--- a/src/Common/libzip/zip_memdup.c
+++ b/src/Common/libzip/zip_memdup.c
@@ -1,6 +1,6 @@
/*
zip_memdup.c -- internal zip function, "strdup" with len
- Copyright (C) 1999-2018 Dieter Baron and Thomas Klausner
+ Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
diff --git a/src/Common/libzip/zip_name_locate.c b/src/Common/libzip/zip_name_locate.c
index 37b1ffe..f7318ec 100644
--- a/src/Common/libzip/zip_name_locate.c
+++ b/src/Common/libzip/zip_name_locate.c
@@ -1,6 +1,6 @@
/*
zip_name_locate.c -- get index by name
- Copyright (C) 1999-2018 Dieter Baron and Thomas Klausner
+ Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
diff --git a/src/Common/libzip/zip_new.c b/src/Common/libzip/zip_new.c
index 1cd614d..4f58ecc 100644
--- a/src/Common/libzip/zip_new.c
+++ b/src/Common/libzip/zip_new.c
@@ -1,6 +1,6 @@
/*
zip_new.c -- create and init struct zip
- Copyright (C) 1999-2018 Dieter Baron and Thomas Klausner
+ Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
diff --git a/src/Common/libzip/zip_open.c b/src/Common/libzip/zip_open.c
index 593bfde..019cd98 100644
--- a/src/Common/libzip/zip_open.c
+++ b/src/Common/libzip/zip_open.c
@@ -1,6 +1,6 @@
/*
zip_open.c -- open zip archive by name
- Copyright (C) 1999-2018 Dieter Baron and Thomas Klausner
+ Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
@@ -32,20 +32,13 @@
*/
-#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <sys/stat.h>
#include "zipint.h"
-typedef enum {
- EXISTS_ERROR = -1,
- EXISTS_NOT = 0,
- EXISTS_EMPTY,
- EXISTS_NONEMPTY,
-} exists_t;
+typedef enum { EXISTS_ERROR = -1, EXISTS_NOT = 0, EXISTS_OK } exists_t;
static zip_t *_zip_allocate_new(zip_source_t *src, unsigned int flags, zip_error_t *error);
static zip_int64_t _zip_checkcons(zip_t *za, zip_cdir_t *cdir, zip_error_t *error);
static zip_cdir_t *_zip_find_central_dir(zip_t *za, zip_uint64_t len);
@@ -174,19 +167,16 @@ _zip_open(zip_source_t *src, unsigned int flags, zip_error_t *error) {
}
len = st.size;
- /* treat empty files as empty archives */
- if (len == 0) {
- if ((za = _zip_allocate_new(src, flags, error)) == NULL) {
- return NULL;
- }
-
- return za;
- }
if ((za = _zip_allocate_new(src, flags, error)) == NULL) {
return NULL;
}
+ /* treat empty files as empty archives */
+ if (len == 0 && zip_source_accept_empty(src)) {
+ return za;
+ }
+
if ((cdir = _zip_find_central_dir(za, len)) == NULL) {
_zip_error_copy(error, &za->error);
/* keep src so discard does not get rid of it */
@@ -540,7 +530,7 @@ _zip_file_exists(zip_source_t *src, zip_error_t *error) {
return EXISTS_ERROR;
}
- return (st.valid & ZIP_STAT_SIZE) && st.size == 0 ? EXISTS_EMPTY : EXISTS_NONEMPTY;
+ return EXISTS_OK;
}
@@ -725,16 +715,19 @@ _zip_read_eocd64(zip_source_t *src, zip_buffer_t *buffer, zip_uint64_t buf_offse
eocd_disk = _zip_buffer_get_16(buffer);
eocd_offset = _zip_buffer_get_64(buffer);
- if (eocd_offset > ZIP_INT64_MAX || eocd_offset + EOCD64LEN < eocd_offset) {
+ /* valid seek value for start of EOCD */
+ if (eocd_offset > ZIP_INT64_MAX) {
zip_error_set(error, ZIP_ER_SEEK, EFBIG);
return NULL;
}
+ /* does EOCD fit before EOCD locator? */
if (eocd_offset + EOCD64LEN > eocdloc_offset + buf_offset) {
zip_error_set(error, ZIP_ER_INCONS, 0);
return NULL;
}
+ /* make sure current position of buffer is beginning of EOCD */
if (eocd_offset >= buf_offset && eocd_offset + EOCD64LEN <= buf_offset + _zip_buffer_size(buffer)) {
_zip_buffer_set_offset(buffer, eocd_offset - buf_offset);
free_buffer = false;
@@ -758,8 +751,10 @@ _zip_read_eocd64(zip_source_t *src, zip_buffer_t *buffer, zip_uint64_t buf_offse
return NULL;
}
+ /* size of EOCD */
size = _zip_buffer_get_64(buffer);
+ /* is there a hole between EOCD and EOCD locator, or do they overlap? */
if ((flags & ZIP_CHECKCONS) && size + eocd_offset + 12 != buf_offset + eocdloc_offset) {
zip_error_set(error, ZIP_ER_INCONS, 0);
if (free_buffer) {
@@ -811,6 +806,7 @@ _zip_read_eocd64(zip_source_t *src, zip_buffer_t *buffer, zip_uint64_t buf_offse
size = _zip_buffer_get_64(buffer);
offset = _zip_buffer_get_64(buffer);
+ /* did we read past the end of the buffer? */
if (!_zip_buffer_ok(buffer)) {
zip_error_set(error, ZIP_ER_INTERNAL, 0);
if (free_buffer) {
@@ -837,6 +833,11 @@ _zip_read_eocd64(zip_source_t *src, zip_buffer_t *buffer, zip_uint64_t buf_offse
return NULL;
}
+ if (nentry > size / CDENTRYSIZE) {
+ zip_error_set(error, ZIP_ER_INCONS, 0);
+ return NULL;
+ }
+
if ((cd = _zip_cdir_new(nentry, error)) == NULL)
return NULL;
diff --git a/src/Common/libzip/zip_pkware.c b/src/Common/libzip/zip_pkware.c
new file mode 100644
index 0000000..eb12b1e
--- /dev/null
+++ b/src/Common/libzip/zip_pkware.c
@@ -0,0 +1,112 @@
+/*
+ zip_pkware.c -- Traditional PKWARE de/encryption backend routines
+ Copyright (C) 2009-2020 Dieter Baron and Thomas Klausner
+
+ This file is part of libzip, a library to manipulate ZIP archives.
+ The authors can be contacted at <libzip@nih.at>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+ 3. The names of the authors may not be used to endorse or promote
+ products derived from this software without specific prior
+ written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
+ OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+
+#include <stdlib.h>
+#include <zlib.h>
+
+#include "zipint.h"
+
+#define PKWARE_KEY0 305419896
+#define PKWARE_KEY1 591751049
+#define PKWARE_KEY2 878082192
+
+
+static void
+update_keys(zip_pkware_keys_t *keys, zip_uint8_t b) {
+ keys->key[0] = (zip_uint32_t)crc32(keys->key[0] ^ 0xffffffffUL, &b, 1) ^ 0xffffffffUL;
+ keys->key[1] = (keys->key[1] + (keys->key[0] & 0xff)) * 134775813 + 1;
+ b = (zip_uint8_t)(keys->key[1] >> 24);
+ keys->key[2] = (zip_uint32_t)crc32(keys->key[2] ^ 0xffffffffUL, &b, 1) ^ 0xffffffffUL;
+}
+
+
+static zip_uint8_t
+crypt_byte(zip_pkware_keys_t *keys) {
+ zip_uint16_t tmp;
+ tmp = (zip_uint16_t)(keys->key[2] | 2);
+ tmp = (zip_uint16_t)(((zip_uint32_t)tmp * (tmp ^ 1)) >> 8);
+ return (zip_uint8_t)tmp;
+}
+
+
+void
+_zip_pkware_keys_reset(zip_pkware_keys_t *keys) {
+ keys->key[0] = PKWARE_KEY0;
+ keys->key[1] = PKWARE_KEY1;
+ keys->key[2] = PKWARE_KEY2;
+}
+
+
+void
+_zip_pkware_encrypt(zip_pkware_keys_t *keys, zip_uint8_t *out, const zip_uint8_t *in, zip_uint64_t len) {
+ zip_uint64_t i;
+ zip_uint8_t b;
+ zip_uint8_t tmp;
+
+ for (i = 0; i < len; i++) {
+ b = in[i];
+
+ if (out != NULL) {
+ tmp = crypt_byte(keys);
+ update_keys(keys, b);
+ b ^= tmp;
+ out[i] = b;
+ }
+ else {
+ /* during initialization, we're only interested in key updates */
+ update_keys(keys, b);
+ }
+ }
+}
+
+
+void
+_zip_pkware_decrypt(zip_pkware_keys_t *keys, zip_uint8_t *out, const zip_uint8_t *in, zip_uint64_t len) {
+ zip_uint64_t i;
+ zip_uint8_t b;
+ zip_uint8_t tmp;
+
+ for (i = 0; i < len; i++) {
+ b = in[i];
+
+ /* during initialization, we're only interested in key updates */
+ if (out != NULL) {
+ tmp = crypt_byte(keys);
+ b ^= tmp;
+ out[i] = b;
+ }
+
+ update_keys(keys, b);
+ }
+}
diff --git a/src/Common/libzip/zip_progress.c b/src/Common/libzip/zip_progress.c
index 9b11694..ddb47c7 100644
--- a/src/Common/libzip/zip_progress.c
+++ b/src/Common/libzip/zip_progress.c
@@ -1,6 +1,6 @@
/*
zip_progress.c -- progress reporting
- Copyright (C) 2017-2018 Dieter Baron and Thomas Klausner
+ Copyright (C) 2017-2020 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
@@ -40,10 +40,14 @@
struct zip_progress {
zip_t *za;
- zip_progress_callback callback;
- void (*ud_free)(void *);
- void *ud;
+ zip_progress_callback callback_progress;
+ void (*ud_progress_free)(void *);
+ void *ud_progress;
+
+ zip_cancel_callback callback_cancel;
+ void (*ud_cancel_free)(void *);
+ void *ud_cancel;
double precision;
@@ -54,6 +58,11 @@ struct zip_progress {
double end; /* end of sub-progress section */
};
+static void _zip_progress_free_cancel_callback(zip_progress_t *progress);
+static void _zip_progress_free_progress_callback(zip_progress_t *progress);
+static zip_progress_t *_zip_progress_new(zip_t *za);
+static void _zip_progress_set_cancel_callback(zip_progress_t *progress, zip_cancel_callback callback, void (*ud_free)(void *), void *ud);
+static void _zip_progress_set_progress_callback(zip_progress_t *progress, double precision, zip_progress_callback callback, void (*ud_free)(void *), void *ud);
void
_zip_progress_end(zip_progress_t *progress) {
@@ -67,16 +76,15 @@ _zip_progress_free(zip_progress_t *progress) {
return;
}
- if (progress->ud_free) {
- progress->ud_free(progress->ud);
- }
+ _zip_progress_free_progress_callback(progress);
+ _zip_progress_free_cancel_callback(progress);
free(progress);
}
-zip_progress_t *
-_zip_progress_new(zip_t *za, double precision, zip_progress_callback callback, void (*ud_free)(void *), void *ud) {
+static zip_progress_t *
+_zip_progress_new(zip_t *za) {
zip_progress_t *progress = (zip_progress_t *)malloc(sizeof(*progress));
if (progress == NULL) {
@@ -85,67 +93,169 @@ _zip_progress_new(zip_t *za, double precision, zip_progress_callback callback, v
}
progress->za = za;
- progress->callback = callback;
- progress->ud_free = ud_free;
- progress->ud = ud;
- progress->precision = precision;
+
+ progress->callback_progress = NULL;
+ progress->ud_progress_free = NULL;
+ progress->ud_progress = NULL;
+ progress->precision = 0.0;
+
+ progress->callback_cancel = NULL;
+ progress->ud_cancel_free = NULL;
+ progress->ud_cancel = NULL;
return progress;
}
+static void
+_zip_progress_free_progress_callback(zip_progress_t *progress) {
+ if (progress->ud_progress_free) {
+ progress->ud_progress_free(progress->ud_progress);
+ }
+
+ progress->callback_progress = NULL;
+ progress->ud_progress = NULL;
+ progress->ud_progress_free = NULL;
+}
+
+static void
+_zip_progress_free_cancel_callback(zip_progress_t *progress) {
+ if (progress->ud_cancel_free) {
+ progress->ud_cancel_free(progress->ud_cancel);
+ }
+
+ progress->callback_cancel = NULL;
+ progress->ud_cancel = NULL;
+ progress->ud_cancel_free = NULL;
+}
+
+static void
+_zip_progress_set_progress_callback(zip_progress_t *progress, double precision, zip_progress_callback callback, void (*ud_free)(void *), void *ud) {
+ _zip_progress_free_progress_callback(progress);
+
+ progress->callback_progress = callback;
+ progress->ud_progress_free = ud_free;
+ progress->ud_progress = ud;
+ progress->precision = precision;
+}
void
+_zip_progress_set_cancel_callback(zip_progress_t *progress, zip_cancel_callback callback, void (*ud_free)(void *), void *ud) {
+ _zip_progress_free_cancel_callback(progress);
+
+ progress->callback_cancel = callback;
+ progress->ud_cancel_free = ud_free;
+ progress->ud_cancel = ud;
+}
+
+int
_zip_progress_start(zip_progress_t *progress) {
if (progress == NULL) {
- return;
+ return 0;
+ }
+
+ if (progress->callback_progress != NULL) {
+ progress->last_update = 0.0;
+ progress->callback_progress(progress->za, 0.0, progress->ud_progress);
+ }
+
+ if (progress->callback_cancel != NULL) {
+ if (progress->callback_cancel(progress->za, progress->ud_cancel)) {
+ return -1;
+ }
}
- progress->last_update = 0.0;
- progress->callback(progress->za, 0.0, progress->ud);
+ return 0;
}
-void
+int
_zip_progress_subrange(zip_progress_t *progress, double start, double end) {
if (progress == NULL) {
- return;
+ return 0;
}
progress->start = start;
progress->end = end;
- _zip_progress_update(progress, 0.0);
+ return _zip_progress_update(progress, 0.0);
}
-void
+int
_zip_progress_update(zip_progress_t *progress, double sub_current) {
double current;
if (progress == NULL) {
- return;
+ return 0;
}
- current = ZIP_MIN(ZIP_MAX(sub_current, 0.0), 1.0) * (progress->end - progress->start) + progress->start;
+ if (progress->callback_progress != NULL) {
+ current = ZIP_MIN(ZIP_MAX(sub_current, 0.0), 1.0) * (progress->end - progress->start) + progress->start;
+
+ if (current - progress->last_update > progress->precision) {
+ progress->callback_progress(progress->za, current, progress->ud_progress);
+ progress->last_update = current;
+ }
+ }
- if (current - progress->last_update > progress->precision) {
- progress->callback(progress->za, current, progress->ud);
- progress->last_update = current;
+ if (progress->callback_cancel != NULL) {
+ if (progress->callback_cancel(progress->za, progress->ud_cancel)) {
+ return -1;
+ }
}
+
+ return 0;
}
ZIP_EXTERN int
zip_register_progress_callback_with_state(zip_t *za, double precision, zip_progress_callback callback, void (*ud_free)(void *), void *ud) {
- zip_progress_t *progress = NULL;
-
if (callback != NULL) {
- if ((progress = _zip_progress_new(za, precision, callback, ud_free, ud)) == NULL) {
- return -1;
+ if (za->progress == NULL) {
+ if ((za->progress = _zip_progress_new(za)) == NULL) {
+ return -1;
+ }
+ }
+
+ _zip_progress_set_progress_callback(za->progress, precision, callback, ud_free, ud);
+ }
+ else {
+ if (za->progress != NULL) {
+ if (za->progress->callback_cancel == NULL) {
+ _zip_progress_free(za->progress);
+ za->progress = NULL;
+ }
+ else {
+ _zip_progress_free_progress_callback(za->progress);
+ }
}
}
- _zip_progress_free(za->progress);
- za->progress = progress;
+ return 0;
+}
+
+
+ZIP_EXTERN int
+zip_register_cancel_callback_with_state(zip_t *za, zip_cancel_callback callback, void (*ud_free)(void *), void *ud) {
+ if (callback != NULL) {
+ if (za->progress == NULL) {
+ if ((za->progress = _zip_progress_new(za)) == NULL) {
+ return -1;
+ }
+ }
+
+ _zip_progress_set_cancel_callback(za->progress, callback, ud_free, ud);
+ }
+ else {
+ if (za->progress != NULL) {
+ if (za->progress->callback_progress == NULL) {
+ _zip_progress_free(za->progress);
+ za->progress = NULL;
+ }
+ else {
+ _zip_progress_free_cancel_callback(za->progress);
+ }
+ }
+ }
return 0;
}
diff --git a/src/Common/libzip/zip_rename.c b/src/Common/libzip/zip_rename.c
index 4fdf636..75b456d 100644
--- a/src/Common/libzip/zip_rename.c
+++ b/src/Common/libzip/zip_rename.c
@@ -1,6 +1,6 @@
/*
zip_rename.c -- rename file in zip archive
- Copyright (C) 1999-2018 Dieter Baron and Thomas Klausner
+ Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
@@ -32,8 +32,6 @@
*/
-#include <string.h>
-
#define _ZIP_COMPILING_DEPRECATED
#include "zipint.h"
diff --git a/src/Common/libzip/zip_replace.c b/src/Common/libzip/zip_replace.c
index 2e982af..30a2eb1 100644
--- a/src/Common/libzip/zip_replace.c
+++ b/src/Common/libzip/zip_replace.c
@@ -1,6 +1,6 @@
/*
zip_replace.c -- replace file via callback function
- Copyright (C) 1999-2018 Dieter Baron and Thomas Klausner
+ Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
diff --git a/src/Common/libzip/zip_set_archive_comment.c b/src/Common/libzip/zip_set_archive_comment.c
index 166a2c0..3f050b3 100644
--- a/src/Common/libzip/zip_set_archive_comment.c
+++ b/src/Common/libzip/zip_set_archive_comment.c
@@ -1,6 +1,6 @@
/*
zip_set_archive_comment.c -- set archive comment
- Copyright (C) 2006-2018 Dieter Baron and Thomas Klausner
+ Copyright (C) 2006-2019 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
diff --git a/src/Common/libzip/zip_set_archive_flag.c b/src/Common/libzip/zip_set_archive_flag.c
index facf614..e0d5502 100644
--- a/src/Common/libzip/zip_set_archive_flag.c
+++ b/src/Common/libzip/zip_set_archive_flag.c
@@ -1,6 +1,6 @@
/*
zip_get_archive_flag.c -- set archive global flag
- Copyright (C) 2008-2018 Dieter Baron and Thomas Klausner
+ Copyright (C) 2008-2019 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
diff --git a/src/Common/libzip/zip_set_default_password.c b/src/Common/libzip/zip_set_default_password.c
index 8081657..41c7c51 100644
--- a/src/Common/libzip/zip_set_default_password.c
+++ b/src/Common/libzip/zip_set_default_password.c
@@ -1,6 +1,6 @@
/*
zip_set_default_password.c -- set default password for decryption
- Copyright (C) 2009-2018 Dieter Baron and Thomas Klausner
+ Copyright (C) 2009-2019 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
diff --git a/src/Common/libzip/zip_set_file_comment.c b/src/Common/libzip/zip_set_file_comment.c
index e4e0331..4277893 100644
--- a/src/Common/libzip/zip_set_file_comment.c
+++ b/src/Common/libzip/zip_set_file_comment.c
@@ -1,6 +1,6 @@
/*
zip_set_file_comment.c -- set comment for file in archive
- Copyright (C) 2006-2018 Dieter Baron and Thomas Klausner
+ Copyright (C) 2006-2019 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
@@ -32,8 +32,6 @@
*/
-#include <stdlib.h>
-
#define _ZIP_COMPILING_DEPRECATED
#include "zipint.h"
diff --git a/src/Common/libzip/zip_set_file_compression.c b/src/Common/libzip/zip_set_file_compression.c
index 054dd1f..927fbb7 100644
--- a/src/Common/libzip/zip_set_file_compression.c
+++ b/src/Common/libzip/zip_set_file_compression.c
@@ -1,6 +1,6 @@
/*
zip_set_file_compression.c -- set compression for file in archive
- Copyright (C) 2012-2018 Dieter Baron and Thomas Klausner
+ Copyright (C) 2012-2019 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
diff --git a/src/Common/libzip/zip_set_name.c b/src/Common/libzip/zip_set_name.c
index aa1dd8e..43c772e 100644
--- a/src/Common/libzip/zip_set_name.c
+++ b/src/Common/libzip/zip_set_name.c
@@ -1,6 +1,6 @@
/*
zip_set_name.c -- rename helper function
- Copyright (C) 1999-2018 Dieter Baron and Thomas Klausner
+ Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
diff --git a/src/Common/libzip/zip_source_get_compression_flags.c b/src/Common/libzip/zip_source_accept_empty.c
index a9442aa..e6d5151 100644
--- a/src/Common/libzip/zip_source_get_compression_flags.c
+++ b/src/Common/libzip/zip_source_accept_empty.c
@@ -1,6 +1,6 @@
/*
- zip_source_get_compression_flags.c -- get compression flags for entry
- Copyright (C) 2017-2018 Dieter Baron and Thomas Klausner
+ zip_source_accept_empty.c -- if empty source is a valid archive
+ Copyright (C) 2019 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
@@ -34,24 +34,19 @@
#include "zipint.h"
-#define ZIP_COMPRESSION_BITFLAG_MAX 3
-
-zip_int8_t
-zip_source_get_compression_flags(zip_source_t *src) {
- while (src) {
- if ((src->supports & ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_GET_COMPRESSION_FLAGS))) {
- zip_int64_t ret = _zip_source_call(src, NULL, 0, ZIP_SOURCE_GET_COMPRESSION_FLAGS);
- if (ret < 0) {
- return -1;
- }
- if (ret > ZIP_COMPRESSION_BITFLAG_MAX) {
- zip_error_set(&src->error, ZIP_ER_INTERNAL, 0);
- return -1;
- }
- return (zip_int8_t)ret;
+
+bool
+zip_source_accept_empty(zip_source_t *src) {
+ int ret;
+
+ if ((zip_source_supports(src) & ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_ACCEPT_EMPTY)) == 0) {
+ if (ZIP_SOURCE_IS_LAYERED(src)) {
+ return zip_source_accept_empty(src->src);
}
- src = src->src;
+ return true;
}
- return 0;
+ ret = (int)_zip_source_call(src, NULL, 0, ZIP_SOURCE_ACCEPT_EMPTY);
+
+ return ret != 0;
}
diff --git a/src/Common/libzip/zip_source_begin_write.c b/src/Common/libzip/zip_source_begin_write.c
index a8b90b5..432c2c1 100644
--- a/src/Common/libzip/zip_source_begin_write.c
+++ b/src/Common/libzip/zip_source_begin_write.c
@@ -1,6 +1,6 @@
/*
zip_source_begin_write.c -- start a new file for writing
- Copyright (C) 2014-2018 Dieter Baron and Thomas Klausner
+ Copyright (C) 2014-2019 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
diff --git a/src/Common/libzip/zip_source_begin_write_cloning.c b/src/Common/libzip/zip_source_begin_write_cloning.c
index b38de04..41b4c73 100644
--- a/src/Common/libzip/zip_source_begin_write_cloning.c
+++ b/src/Common/libzip/zip_source_begin_write_cloning.c
@@ -1,6 +1,6 @@
/*
zip_source_begin_write_cloning.c -- clone part of file for writing
- Copyright (C) 2017-2018 Dieter Baron and Thomas Klausner
+ Copyright (C) 2017-2019 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
diff --git a/src/Common/libzip/zip_source_buffer.c b/src/Common/libzip/zip_source_buffer.c
index 119bc02..519d2c3 100644
--- a/src/Common/libzip/zip_source_buffer.c
+++ b/src/Common/libzip/zip_source_buffer.c
@@ -1,6 +1,6 @@
/*
zip_source_buffer.c -- create zip data source from buffer
- Copyright (C) 1999-2018 Dieter Baron and Thomas Klausner
+ Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
@@ -61,6 +61,7 @@ typedef struct buffer buffer_t;
struct read_data {
zip_error_t error;
time_t mtime;
+ zip_file_attributes_t attributes;
buffer_t *in;
buffer_t *out;
};
@@ -79,29 +80,42 @@ static zip_int64_t buffer_write(buffer_t *buffer, const zip_uint8_t *data, zip_u
static zip_int64_t read_data(void *, void *, zip_uint64_t, zip_source_cmd_t);
+zip_source_t *zip_source_buffer_with_attributes_create(const void *data, zip_uint64_t len, int freep, zip_file_attributes_t *attributes, zip_error_t *error);
+zip_source_t *zip_source_buffer_fragment_with_attributes_create(const zip_buffer_fragment_t *fragments, zip_uint64_t nfragments, int freep, zip_file_attributes_t *attributes, zip_error_t *error);
+
ZIP_EXTERN zip_source_t *
zip_source_buffer(zip_t *za, const void *data, zip_uint64_t len, int freep) {
if (za == NULL)
return NULL;
- return zip_source_buffer_create(data, len, freep, &za->error);
+ return zip_source_buffer_with_attributes_create(data, len, freep, NULL, &za->error);
}
ZIP_EXTERN zip_source_t *
zip_source_buffer_create(const void *data, zip_uint64_t len, int freep, zip_error_t *error) {
+ return zip_source_buffer_with_attributes_create(data, len, freep, NULL, error);
+}
+
+
+zip_source_t *
+zip_source_buffer_with_attributes_create(const void *data, zip_uint64_t len, int freep, zip_file_attributes_t *attributes, zip_error_t *error) {
zip_buffer_fragment_t fragment;
- if (data == NULL && len > 0) {
- zip_error_set(error, ZIP_ER_INVAL, 0);
- return NULL;
+ if (data == NULL) {
+ if (len > 0) {
+ zip_error_set(error, ZIP_ER_INVAL, 0);
+ return NULL;
+ }
+
+ return zip_source_buffer_fragment_with_attributes_create(NULL, 0, freep, attributes, error);
}
fragment.data = (zip_uint8_t *)data;
fragment.length = len;
- return zip_source_buffer_fragment_create(&fragment, 1, freep, error);
+ return zip_source_buffer_fragment_with_attributes_create(&fragment, 1, freep, attributes, error);
}
@@ -111,12 +125,17 @@ zip_source_buffer_fragment(zip_t *za, const zip_buffer_fragment_t *fragments, zi
return NULL;
}
- return zip_source_buffer_fragment_create(fragments, nfragments, freep, &za->error);
+ return zip_source_buffer_fragment_with_attributes_create(fragments, nfragments, freep, NULL, &za->error);
}
ZIP_EXTERN zip_source_t *
zip_source_buffer_fragment_create(const zip_buffer_fragment_t *fragments, zip_uint64_t nfragments, int freep, zip_error_t *error) {
+ return zip_source_buffer_fragment_with_attributes_create(fragments, nfragments, freep, NULL, error);
+}
+
+zip_source_t *
+zip_source_buffer_fragment_with_attributes_create(const zip_buffer_fragment_t *fragments, zip_uint64_t nfragments, int freep, zip_file_attributes_t *attributes, zip_error_t *error) {
struct read_data *ctx;
zip_source_t *zs;
buffer_t *buffer;
@@ -139,6 +158,12 @@ zip_source_buffer_fragment_create(const zip_buffer_fragment_t *fragments, zip_ui
ctx->in = buffer;
ctx->out = NULL;
ctx->mtime = time(NULL);
+ if (attributes) {
+ memcpy(&ctx->attributes, attributes, sizeof(ctx->attributes));
+ }
+ else {
+ zip_file_attributes_init(&ctx->attributes);
+ }
zip_error_init(&ctx->error);
if ((zs = zip_source_function_create(read_data, ctx, error)) == NULL) {
@@ -151,6 +176,11 @@ zip_source_buffer_fragment_create(const zip_buffer_fragment_t *fragments, zip_ui
}
+zip_source_t *
+zip_source_buffer_with_attributes(zip_t *za, const void *data, zip_uint64_t len, int freep, zip_file_attributes_t *attributes) {
+ return zip_source_buffer_with_attributes_create(data, len, freep, attributes, &za->error);
+}
+
static zip_int64_t
read_data(void *state, void *data, zip_uint64_t len, zip_source_cmd_t cmd) {
struct read_data *ctx = (struct read_data *)state;
@@ -190,6 +220,17 @@ read_data(void *state, void *data, zip_uint64_t len, zip_source_cmd_t cmd) {
free(ctx);
return 0;
+ case ZIP_SOURCE_GET_FILE_ATTRIBUTES: {
+ if (len < sizeof(ctx->attributes)) {
+ zip_error_set(&ctx->error, ZIP_ER_INVAL, 0);
+ return -1;
+ }
+
+ memcpy(data, &ctx->attributes, sizeof(ctx->attributes));
+
+ return sizeof(ctx->attributes);
+ }
+
case ZIP_SOURCE_OPEN:
ctx->in->offset = 0;
ctx->in->current_fragment = 0;
@@ -246,7 +287,7 @@ read_data(void *state, void *data, zip_uint64_t len, zip_source_cmd_t cmd) {
}
case ZIP_SOURCE_SUPPORTS:
- return zip_source_make_command_bitmap(ZIP_SOURCE_OPEN, ZIP_SOURCE_READ, ZIP_SOURCE_CLOSE, ZIP_SOURCE_STAT, ZIP_SOURCE_ERROR, ZIP_SOURCE_FREE, ZIP_SOURCE_SEEK, ZIP_SOURCE_TELL, ZIP_SOURCE_BEGIN_WRITE, ZIP_SOURCE_BEGIN_WRITE_CLONING, ZIP_SOURCE_COMMIT_WRITE, ZIP_SOURCE_REMOVE, ZIP_SOURCE_ROLLBACK_WRITE, ZIP_SOURCE_SEEK_WRITE, ZIP_SOURCE_TELL_WRITE, ZIP_SOURCE_WRITE, -1);
+ return zip_source_make_command_bitmap(ZIP_SOURCE_GET_FILE_ATTRIBUTES, ZIP_SOURCE_OPEN, ZIP_SOURCE_READ, ZIP_SOURCE_CLOSE, ZIP_SOURCE_STAT, ZIP_SOURCE_ERROR, ZIP_SOURCE_FREE, ZIP_SOURCE_SEEK, ZIP_SOURCE_TELL, ZIP_SOURCE_BEGIN_WRITE, ZIP_SOURCE_BEGIN_WRITE_CLONING, ZIP_SOURCE_COMMIT_WRITE, ZIP_SOURCE_REMOVE, ZIP_SOURCE_ROLLBACK_WRITE, ZIP_SOURCE_SEEK_WRITE, ZIP_SOURCE_TELL_WRITE, ZIP_SOURCE_WRITE, -1);
case ZIP_SOURCE_TELL:
if (ctx->in->offset > ZIP_INT64_MAX) {
@@ -457,7 +498,7 @@ buffer_new(const zip_buffer_fragment_t *fragments, zip_uint64_t nfragments, int
}
buffer->nfragments = j;
buffer->first_owned_fragment = free_data ? 0 : buffer->nfragments;
- buffer->fragment_offsets[nfragments] = offset;
+ buffer->fragment_offsets[buffer->nfragments] = offset;
buffer->size = offset;
}
diff --git a/src/Common/libzip/zip_source_call.c b/src/Common/libzip/zip_source_call.c
index 3f374fc..e7c2954 100644
--- a/src/Common/libzip/zip_source_call.c
+++ b/src/Common/libzip/zip_source_call.c
@@ -1,6 +1,6 @@
/*
zip_source_call.c -- invoke callback command on zip_source
- Copyright (C) 2009-2018 Dieter Baron and Thomas Klausner
+ Copyright (C) 2009-2019 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
diff --git a/src/Common/libzip/zip_source_close.c b/src/Common/libzip/zip_source_close.c
index 7916550..ab7898c 100644
--- a/src/Common/libzip/zip_source_close.c
+++ b/src/Common/libzip/zip_source_close.c
@@ -1,6 +1,6 @@
/*
zip_source_close.c -- close zip_source (stop reading)
- Copyright (C) 2009-2018 Dieter Baron and Thomas Klausner
+ Copyright (C) 2009-2019 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
diff --git a/src/Common/libzip/zip_source_commit_write.c b/src/Common/libzip/zip_source_commit_write.c
index 67881f0..d1254bf 100644
--- a/src/Common/libzip/zip_source_commit_write.c
+++ b/src/Common/libzip/zip_source_commit_write.c
@@ -1,6 +1,6 @@
/*
zip_source_commit_write.c -- commit changes to file
- Copyright (C) 2014-2018 Dieter Baron and Thomas Klausner
+ Copyright (C) 2014-2019 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
diff --git a/src/Common/libzip/zip_source_compress.c b/src/Common/libzip/zip_source_compress.c
index d2ae220..e49929f 100644
--- a/src/Common/libzip/zip_source_compress.c
+++ b/src/Common/libzip/zip_source_compress.c
@@ -1,6 +1,6 @@
/*
zip_source_compress.c -- (de)compression routines
- Copyright (C) 2017-2018 Dieter Baron and Thomas Klausner
+ Copyright (C) 2017-2019 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
@@ -31,7 +31,6 @@
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include <limits.h>
#include <stdlib.h>
#include <string.h>
@@ -67,6 +66,16 @@ static struct implementation implementations[] = {
#if defined(HAVE_LIBBZ2)
{ZIP_CM_BZIP2, &zip_algorithm_bzip2_compress, &zip_algorithm_bzip2_decompress},
#endif
+#if defined(HAVE_LIBLZMA)
+ /* Disabled - because 7z isn't able to unpack ZIP+LZMA ZIP+LZMA2
+ archives made this way - and vice versa.
+
+ {ZIP_CM_LZMA, &zip_algorithm_xz_compress, &zip_algorithm_xz_decompress},
+ {ZIP_CM_LZMA2, &zip_algorithm_xz_compress, &zip_algorithm_xz_decompress},
+ */
+ {ZIP_CM_XZ, &zip_algorithm_xz_compress, &zip_algorithm_xz_decompress},
+#endif
+
};
static size_t implementations_size = sizeof(implementations) / sizeof(implementations[0]);
@@ -96,10 +105,10 @@ get_algorithm(zip_int32_t method, bool compress) {
return NULL;
}
-bool
-zip_compression_method_supported(zip_int32_t method, bool compress) {
+ZIP_EXTERN int
+zip_compression_method_supported(zip_int32_t method, int compress) {
if (method == ZIP_CM_STORE) {
- return true;
+ return 1;
}
return get_algorithm(method, compress) != NULL;
}
@@ -347,9 +356,6 @@ compress_callback(zip_source_t *src, void *ud, void *data, zip_uint64_t len, zip
}
return 0;
- case ZIP_SOURCE_GET_COMPRESSION_FLAGS:
- return ctx->is_stored ? 0 : ctx->algorithm->compression_flags(ctx->ud);
-
case ZIP_SOURCE_ERROR:
return zip_error_to_data(&ctx->error, data, len);
@@ -357,8 +363,24 @@ compress_callback(zip_source_t *src, void *ud, void *data, zip_uint64_t len, zip
context_free(ctx);
return 0;
+ case ZIP_SOURCE_GET_FILE_ATTRIBUTES: {
+ zip_file_attributes_t *attributes = (zip_file_attributes_t *)data;
+
+ if (len < sizeof(*attributes)) {
+ zip_error_set(&ctx->error, ZIP_ER_INVAL, 0);
+ return -1;
+ }
+
+ attributes->valid |= ZIP_FILE_ATTRIBUTES_VERSION_NEEDED | ZIP_FILE_ATTRIBUTES_GENERAL_PURPOSE_BIT_FLAGS;
+ attributes->version_needed = ctx->algorithm->version_needed;
+ attributes->general_purpose_bit_mask = ZIP_FILE_ATTRIBUTES_GENERAL_PURPOSE_BIT_FLAGS_ALLOWED_MASK;
+ attributes->general_purpose_bit_flags = (ctx->is_stored ? 0 : ctx->algorithm->general_purpose_bit_flags(ctx->ud));
+
+ return sizeof(*attributes);
+ }
+
case ZIP_SOURCE_SUPPORTS:
- return ZIP_SOURCE_SUPPORTS_READABLE | zip_source_make_command_bitmap(ZIP_SOURCE_GET_COMPRESSION_FLAGS, -1);
+ return ZIP_SOURCE_SUPPORTS_READABLE | zip_source_make_command_bitmap(ZIP_SOURCE_GET_FILE_ATTRIBUTES, -1);
default:
zip_error_set(&ctx->error, ZIP_ER_INTERNAL, 0);
diff --git a/src/Common/libzip/zip_source_crc.c b/src/Common/libzip/zip_source_crc.c
index e16f929..4f3f223 100644
--- a/src/Common/libzip/zip_source_crc.c
+++ b/src/Common/libzip/zip_source_crc.c
@@ -1,6 +1,6 @@
/*
zip_source_crc.c -- pass-through source that calculates CRC32 and size
- Copyright (C) 2009-2018 Dieter Baron and Thomas Klausner
+ Copyright (C) 2009-2019 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
@@ -34,7 +34,7 @@
#include <limits.h>
#include <stdlib.h>
-#include <string.h>
+#include <zlib.h>
#include "zipint.h"
@@ -167,7 +167,7 @@ crc_read(zip_source_t *src, void *_ctx, void *data, zip_uint64_t len, zip_source
return -1;
}
- return mask & ~zip_source_make_command_bitmap(ZIP_SOURCE_BEGIN_WRITE, ZIP_SOURCE_COMMIT_WRITE, ZIP_SOURCE_ROLLBACK_WRITE, ZIP_SOURCE_SEEK_WRITE, ZIP_SOURCE_TELL_WRITE, ZIP_SOURCE_REMOVE, ZIP_SOURCE_GET_COMPRESSION_FLAGS, -1);
+ return mask & ~zip_source_make_command_bitmap(ZIP_SOURCE_BEGIN_WRITE, ZIP_SOURCE_COMMIT_WRITE, ZIP_SOURCE_ROLLBACK_WRITE, ZIP_SOURCE_SEEK_WRITE, ZIP_SOURCE_TELL_WRITE, ZIP_SOURCE_REMOVE, ZIP_SOURCE_GET_FILE_ATTRIBUTES, -1);
}
case ZIP_SOURCE_SEEK: {
diff --git a/src/Common/libzip/zip_source_deflate.c b/src/Common/libzip/zip_source_deflate.c
deleted file mode 100644
index 2574ad0..0000000
--- a/src/Common/libzip/zip_source_deflate.c
+++ /dev/null
@@ -1,415 +0,0 @@
-/*
- zip_source_deflate.c -- deflate (de)compressoin routines
- Copyright (C) 2009-2015 Dieter Baron and Thomas Klausner
-
- This file is part of libzip, a library to manipulate ZIP archives.
- The authors can be contacted at <libzip@nih.at>
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
- 1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in
- the documentation and/or other materials provided with the
- distribution.
- 3. The names of the authors may not be used to endorse or promote
- products derived from this software without specific prior
- written permission.
-
- THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
- OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
- DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
- IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#include <stdlib.h>
-#include <string.h>
-#include <limits.h>
-
-#include "zipint.h"
-
-struct deflate {
- zip_error_t error;
-
- bool eof;
- bool can_store;
- bool is_stored;
- int mem_level;
- zip_uint64_t size;
- zip_uint8_t buffer[BUFSIZE];
- z_stream zstr;
-};
-
-static zip_int64_t compress_read(zip_source_t *, struct deflate *, void *, zip_uint64_t);
-static zip_int64_t decompress_read(zip_source_t *, struct deflate *, void *, zip_uint64_t);
-static zip_int64_t deflate_compress(zip_source_t *, void *, void *, zip_uint64_t, zip_source_cmd_t);
-static zip_int64_t deflate_decompress(zip_source_t *, void *, void *, zip_uint64_t, zip_source_cmd_t);
-static void deflate_free(struct deflate *);
-
-
-zip_source_t *
-zip_source_deflate(zip_t *za, zip_source_t *src, zip_int32_t cm, int flags)
-{
- struct deflate *ctx;
- zip_source_t *s2;
-
- if (src == NULL || (cm != ZIP_CM_DEFLATE && !ZIP_CM_IS_DEFAULT(cm))) {
- zip_error_set(&za->error, ZIP_ER_INVAL, 0);
- return NULL;
- }
-
- if ((ctx=(struct deflate *)malloc(sizeof(*ctx))) == NULL) {
- zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
- return NULL;
- }
-
- zip_error_init(&ctx->error);
- ctx->eof = false;
- ctx->is_stored = false;
- ctx->can_store = ZIP_CM_IS_DEFAULT(cm);
- if (flags & ZIP_CODEC_ENCODE) {
- ctx->mem_level = MAX_MEM_LEVEL;
- }
-
- if ((s2=zip_source_layered(za, src,
- ((flags & ZIP_CODEC_ENCODE)
- ? deflate_compress : deflate_decompress),
- ctx)) == NULL) {
- deflate_free(ctx);
- return NULL;
- }
-
- return s2;
-}
-
-
-static zip_int64_t
-compress_read(zip_source_t *src, struct deflate *ctx, void *data, zip_uint64_t len)
-{
- int end, ret;
- zip_int64_t n;
- zip_uint64_t out_offset;
- uInt out_len;
-
- if (zip_error_code_zip(&ctx->error) != ZIP_ER_OK)
- return -1;
-
- if (len == 0 || ctx->is_stored) {
- return 0;
- }
-
- out_offset = 0;
- out_len = (uInt)ZIP_MIN(UINT_MAX, len);
- ctx->zstr.next_out = (Bytef *)data;
- ctx->zstr.avail_out = out_len;
-
- end = 0;
- while (!end) {
- ret = deflate(&ctx->zstr, ctx->eof ? Z_FINISH : 0);
-
- switch (ret) {
- case Z_STREAM_END:
- if (ctx->can_store && ctx->zstr.total_in <= ctx->zstr.total_out) {
- ctx->is_stored = true;
- ctx->size = ctx->zstr.total_in;
- memcpy(data, ctx->buffer, ctx->size);
- return (zip_int64_t)ctx->size;
- }
- /* fallthrough */
- case Z_OK:
- /* all ok */
-
- if (ctx->zstr.avail_out == 0) {
- out_offset += out_len;
- if (out_offset < len) {
- out_len = (uInt)ZIP_MIN(UINT_MAX, len-out_offset);
- ctx->zstr.next_out = (Bytef *)data+out_offset;
- ctx->zstr.avail_out = out_len;
- }
- else {
- ctx->can_store = false;
- end = 1;
- }
- }
- else if (ctx->eof && ctx->zstr.avail_in == 0)
- end = 1;
- break;
-
- case Z_BUF_ERROR:
- if (ctx->zstr.avail_in == 0) {
- if (ctx->eof) {
- end = 1;
- break;
- }
-
- if ((n=zip_source_read(src, ctx->buffer, sizeof(ctx->buffer))) < 0) {
- _zip_error_set_from_source(&ctx->error, src);
- end = 1;
- break;
- }
- else if (n == 0) {
- ctx->eof = true;
- /* TODO: check against stat of src? */
- ctx->size = ctx->zstr.total_in;
- }
- else {
- if (ctx->zstr.total_in > 0) {
- /* we overwrote a previously filled ctx->buffer */
- ctx->can_store = false;
- }
- ctx->zstr.next_in = (Bytef *)ctx->buffer;
- ctx->zstr.avail_in = (uInt)n;
- }
- continue;
- }
- /* fallthrough */
- case Z_NEED_DICT:
- case Z_DATA_ERROR:
- case Z_STREAM_ERROR:
- case Z_MEM_ERROR:
- zip_error_set(&ctx->error, ZIP_ER_ZLIB, ret);
-
- end = 1;
- break;
- }
- }
-
- if (ctx->zstr.avail_out < len) {
- ctx->can_store = false;
- return (zip_int64_t)(len - ctx->zstr.avail_out);
- }
-
- return (zip_error_code_zip(&ctx->error) == ZIP_ER_OK) ? 0 : -1;
-}
-
-
-static zip_int64_t
-decompress_read(zip_source_t *src, struct deflate *ctx, void *data, zip_uint64_t len)
-{
- int end, ret;
- zip_int64_t n;
- zip_uint64_t out_offset;
- uInt out_len;
-
- if (zip_error_code_zip(&ctx->error) != ZIP_ER_OK)
- return -1;
-
- if (len == 0)
- return 0;
-
- out_offset = 0;
- out_len = (uInt)ZIP_MIN(UINT_MAX, len);
- ctx->zstr.next_out = (Bytef *)data;
- ctx->zstr.avail_out = out_len;
-
- end = 0;
- while (!end) {
- ret = inflate(&ctx->zstr, Z_SYNC_FLUSH);
-
- switch (ret) {
- case Z_OK:
- if (ctx->zstr.avail_out == 0) {
- out_offset += out_len;
- if (out_offset < len) {
- out_len = (uInt)ZIP_MIN(UINT_MAX, len-out_offset);
- ctx->zstr.next_out = (Bytef *)data+out_offset;
- ctx->zstr.avail_out = out_len;
- }
- else {
- end = 1;
- }
- }
- break;
-
- case Z_STREAM_END:
- ctx->eof = 1;
- end = 1;
- break;
-
- case Z_BUF_ERROR:
- if (ctx->zstr.avail_in == 0) {
- if (ctx->eof) {
- end = 1;
- break;
- }
-
- if ((n=zip_source_read(src, ctx->buffer, sizeof(ctx->buffer))) < 0) {
- _zip_error_set_from_source(&ctx->error, src);
- end = 1;
- break;
- }
- else if (n == 0) {
- ctx->eof = 1;
- }
- else {
- ctx->zstr.next_in = (Bytef *)ctx->buffer;
- ctx->zstr.avail_in = (uInt)n;
- }
- continue;
- }
- /* fallthrough */
- case Z_NEED_DICT:
- case Z_DATA_ERROR:
- case Z_STREAM_ERROR:
- case Z_MEM_ERROR:
- zip_error_set(&ctx->error, ZIP_ER_ZLIB, ret);
- end = 1;
- break;
- }
- }
-
- if (ctx->zstr.avail_out < len)
- return (zip_int64_t)(len - ctx->zstr.avail_out);
-
- return (zip_error_code_zip(&ctx->error) == ZIP_ER_OK) ? 0 : -1;
-}
-
-
-static zip_int64_t
-deflate_compress(zip_source_t *src, void *ud, void *data, zip_uint64_t len, zip_source_cmd_t cmd)
-{
- struct deflate *ctx;
- int ret;
-
- ctx = (struct deflate *)ud;
-
- switch (cmd) {
- case ZIP_SOURCE_OPEN:
- ctx->zstr.zalloc = Z_NULL;
- ctx->zstr.zfree = Z_NULL;
- ctx->zstr.opaque = NULL;
- ctx->zstr.avail_in = 0;
- ctx->zstr.next_in = NULL;
- ctx->zstr.avail_out = 0;
- ctx->zstr.next_out = NULL;
-
- /* negative value to tell zlib not to write a header */
- if ((ret=deflateInit2(&ctx->zstr, Z_BEST_COMPRESSION, Z_DEFLATED, -MAX_WBITS, ctx->mem_level, Z_DEFAULT_STRATEGY)) != Z_OK) {
- zip_error_set(&ctx->error, ZIP_ER_ZLIB, ret);
- return -1;
- }
-
- return 0;
-
- case ZIP_SOURCE_READ:
- return compress_read(src, ctx, data, len);
-
- case ZIP_SOURCE_CLOSE:
- deflateEnd(&ctx->zstr);
- return 0;
-
- case ZIP_SOURCE_STAT:
- {
- zip_stat_t *st;
-
- st = (zip_stat_t *)data;
-
- st->comp_method = ctx->is_stored ? ZIP_CM_STORE : ZIP_CM_DEFLATE;
- st->valid |= ZIP_STAT_COMP_METHOD;
- if (ctx->eof) {
- st->comp_size = ctx->size;
- st->valid |= ZIP_STAT_COMP_SIZE;
- }
- else
- st->valid &= ~ZIP_STAT_COMP_SIZE;
- }
- return 0;
-
- case ZIP_SOURCE_ERROR:
- return zip_error_to_data(&ctx->error, data, len);
-
- case ZIP_SOURCE_FREE:
- deflate_free(ctx);
- return 0;
-
- case ZIP_SOURCE_SUPPORTS:
- return ZIP_SOURCE_SUPPORTS_READABLE;
-
- default:
- zip_error_set(&ctx->error, ZIP_ER_INTERNAL, 0);
- return -1;
- }
-}
-
-
-static zip_int64_t
-deflate_decompress(zip_source_t *src, void *ud, void *data,
- zip_uint64_t len, zip_source_cmd_t cmd)
-{
- struct deflate *ctx;
- zip_int64_t n;
- int ret;
-
- ctx = (struct deflate *)ud;
-
- switch (cmd) {
- case ZIP_SOURCE_OPEN:
- if ((n=zip_source_read(src, ctx->buffer, sizeof(ctx->buffer))) < 0) {
- _zip_error_set_from_source(&ctx->error, src);
- return -1;
- }
-
- ctx->zstr.zalloc = Z_NULL;
- ctx->zstr.zfree = Z_NULL;
- ctx->zstr.opaque = NULL;
- ctx->zstr.next_in = (Bytef *)ctx->buffer;
- ctx->zstr.avail_in = (uInt)n;
-
- /* negative value to tell zlib that there is no header */
- if ((ret=inflateInit2(&ctx->zstr, -MAX_WBITS)) != Z_OK) {
- zip_error_set(&ctx->error, ZIP_ER_ZLIB, ret);
- return -1;
- }
- return 0;
-
- case ZIP_SOURCE_READ:
- return decompress_read(src, ctx, data, len);
-
- case ZIP_SOURCE_CLOSE:
- inflateEnd(&ctx->zstr);
- return 0;
-
- case ZIP_SOURCE_STAT:
- {
- zip_stat_t *st;
-
- st = (zip_stat_t *)data;
-
- st->comp_method = ZIP_CM_STORE;
- if (st->comp_size > 0 && st->size > 0)
- st->comp_size = st->size;
-
- return 0;
- }
-
- case ZIP_SOURCE_ERROR:
- return zip_error_to_data(&ctx->error, data, len);
-
- case ZIP_SOURCE_FREE:
- free(ctx);
- return 0;
-
- case ZIP_SOURCE_SUPPORTS:
- return zip_source_make_command_bitmap(ZIP_SOURCE_OPEN, ZIP_SOURCE_READ, ZIP_SOURCE_CLOSE, ZIP_SOURCE_STAT, ZIP_SOURCE_ERROR, ZIP_SOURCE_FREE, -1);
-
- default:
- zip_error_set(&ctx->error, ZIP_ER_OPNOTSUPP, 0);
- return -1;
- }
-}
-
-
-static void
-deflate_free(struct deflate *ctx)
-{
- free(ctx);
-}
diff --git a/src/Common/libzip/zip_source_error.c b/src/Common/libzip/zip_source_error.c
index 1e0e0d4..2257f71 100644
--- a/src/Common/libzip/zip_source_error.c
+++ b/src/Common/libzip/zip_source_error.c
@@ -1,6 +1,6 @@
/*
zip_source_error.c -- get last error from zip_source
- Copyright (C) 2009-2018 Dieter Baron and Thomas Klausner
+ Copyright (C) 2009-2019 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
diff --git a/src/Common/libzip/zip_source_file.h b/src/Common/libzip/zip_source_file.h
new file mode 100644
index 0000000..43a4645
--- /dev/null
+++ b/src/Common/libzip/zip_source_file.h
@@ -0,0 +1,90 @@
+/*
+ zip_source_file.h -- header for common file operations
+ Copyright (C) 2020 Dieter Baron and Thomas Klausner
+
+ This file is part of libzip, a library to manipulate ZIP archives.
+ The authors can be contacted at <libzip@nih.at>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+ 3. The names of the authors may not be used to endorse or promote
+ products derived from this software without specific prior
+ written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
+ OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+struct zip_source_file_stat {
+ zip_uint64_t size; /* must be valid for regular files */
+ time_t mtime; /* must always be valid, is initialized to current time */
+ bool exists; /* must always be vaild */
+ bool regular_file; /* must always be valid */
+};
+
+typedef struct zip_source_file_context zip_source_file_context_t;
+typedef struct zip_source_file_operations zip_source_file_operations_t;
+typedef struct zip_source_file_stat zip_source_file_stat_t;
+
+struct zip_source_file_context {
+ zip_error_t error; /* last error information */
+ zip_int64_t supports;
+
+ /* reading */
+ char *fname; /* name of file to read from */
+ void *f; /* file to read from */
+ zip_stat_t st; /* stat information passed in */
+ zip_file_attributes_t attributes; /* additional file attributes */
+ zip_error_t stat_error; /* error returned for stat */
+ zip_uint64_t start; /* start offset of data to read */
+ zip_uint64_t len; /* length of the file, 0 for up to EOF */
+ zip_uint64_t offset; /* current offset relative to start (0 is beginning of part we read) */
+
+ /* writing */
+ char *tmpname;
+ void *fout;
+
+ zip_source_file_operations_t *ops;
+ void *ops_userdata;
+};
+
+
+/* The following methods must be implemented to support each feature:
+ - close, read, seek, and stat must always be implemented.
+ - To support specifying the file by name, open, and strdup must be implemented.
+ - For write support, the file must be specified by name and close, commit_write, create_temp_output, remove, rollback_write, and tell must be implemented.
+ - create_temp_output_cloning is always optional. */
+
+struct zip_source_file_operations {
+ void (*close)(zip_source_file_context_t *ctx);
+ zip_int64_t (*commit_write)(zip_source_file_context_t *ctx);
+ zip_int64_t (*create_temp_output)(zip_source_file_context_t *ctx);
+ zip_int64_t (*create_temp_output_cloning)(zip_source_file_context_t *ctx, zip_uint64_t len);
+ bool (*open)(zip_source_file_context_t *ctx);
+ zip_int64_t (*read)(zip_source_file_context_t *ctx, void *buf, zip_uint64_t len);
+ zip_int64_t (*remove)(zip_source_file_context_t *ctx);
+ void (*rollback_write)(zip_source_file_context_t *ctx);
+ bool (*seek)(zip_source_file_context_t *ctx, void *f, zip_int64_t offset, int whence);
+ bool (*stat)(zip_source_file_context_t *ctx, zip_source_file_stat_t *st);
+ char *(*string_duplicate)(zip_source_file_context_t *ctx, const char *);
+ zip_int64_t (*tell)(zip_source_file_context_t *ctx, void *f);
+ zip_int64_t (*write)(zip_source_file_context_t *ctx, const void *data, zip_uint64_t len);
+};
+
+zip_source_t *zip_source_file_common_new(const char *fname, void *file, zip_uint64_t start, zip_int64_t len, const zip_stat_t *st, zip_source_file_operations_t *ops, void *ops_userdata, zip_error_t *error);
diff --git a/src/Common/libzip/zip_source_file_common.c b/src/Common/libzip/zip_source_file_common.c
new file mode 100644
index 0000000..74e2100
--- /dev/null
+++ b/src/Common/libzip/zip_source_file_common.c
@@ -0,0 +1,378 @@
+/*
+ zip_source_file_common.c -- create data source from file
+ Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner
+
+ This file is part of libzip, a library to manipulate ZIP archives.
+ The authors can be contacted at <libzip@nih.at>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+ 3. The names of the authors may not be used to endorse or promote
+ products derived from this software without specific prior
+ written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
+ OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "zipint.h"
+
+#include "zip_source_file.h"
+
+static zip_int64_t read_file(void *state, void *data, zip_uint64_t len, zip_source_cmd_t cmd);
+
+static void
+zip_source_file_stat_init(zip_source_file_stat_t *st) {
+ st->size = 0;
+ st->mtime = time(NULL);
+ st->exists = false;
+ st->regular_file = false;
+}
+
+zip_source_t *
+zip_source_file_common_new(const char *fname, void *file, zip_uint64_t start, zip_int64_t len, const zip_stat_t *st, zip_source_file_operations_t *ops, void *ops_userdata, zip_error_t *error) {
+ zip_source_file_context_t *ctx;
+ zip_source_t *zs;
+ zip_source_file_stat_t sb;
+
+ if (ops == NULL) {
+ zip_error_set(error, ZIP_ER_INVAL, 0);
+ return NULL;
+ }
+
+ if (ops->close == NULL || ops->read == NULL || ops->seek == NULL || ops->stat == NULL) {
+ zip_error_set(error, ZIP_ER_INTERNAL, 0);
+ return NULL;
+ }
+
+ if (ops->write != NULL && (ops->commit_write == NULL || ops->create_temp_output == NULL || ops->remove == NULL || ops->rollback_write == NULL || ops->tell == NULL)) {
+ zip_error_set(error, ZIP_ER_INTERNAL, 0);
+ return NULL;
+ }
+
+ if (fname != NULL) {
+ if (ops->open == NULL || ops->string_duplicate == NULL) {
+ zip_error_set(error, ZIP_ER_INTERNAL, 0);
+ return NULL;
+ }
+ }
+ else if (file == NULL) {
+ zip_error_set(error, ZIP_ER_INVAL, 0);
+ return NULL;
+ }
+
+ if (len < 0) {
+ len = 0;
+ }
+
+ if (start > ZIP_INT64_MAX || start + (zip_uint64_t)len < start) {
+ zip_error_set(error, ZIP_ER_INVAL, 0);
+ return NULL;
+ }
+
+ if ((ctx = (zip_source_file_context_t *)malloc(sizeof(zip_source_file_context_t))) == NULL) {
+ zip_error_set(error, ZIP_ER_MEMORY, 0);
+ return NULL;
+ }
+
+ ctx->ops = ops;
+ ctx->ops_userdata = ops_userdata;
+ ctx->fname = NULL;
+ if (fname) {
+ if ((ctx->fname = ops->string_duplicate(ctx, fname)) == NULL) {
+ zip_error_set(error, ZIP_ER_MEMORY, 0);
+ free(ctx);
+ return NULL;
+ }
+ }
+ ctx->f = file;
+ ctx->start = start;
+ ctx->len = (zip_uint64_t)len;
+ if (st) {
+ memcpy(&ctx->st, st, sizeof(ctx->st));
+ ctx->st.name = NULL;
+ ctx->st.valid &= ~ZIP_STAT_NAME;
+ }
+ else {
+ zip_stat_init(&ctx->st);
+ }
+
+ if (ctx->len > 0) {
+ ctx->st.size = ctx->len;
+ ctx->st.valid |= ZIP_STAT_SIZE;
+ }
+
+ zip_error_init(&ctx->stat_error);
+
+ ctx->tmpname = NULL;
+ ctx->fout = NULL;
+
+ zip_error_init(&ctx->error);
+ zip_file_attributes_init(&ctx->attributes);
+
+ ctx->supports = ZIP_SOURCE_SUPPORTS_READABLE | zip_source_make_command_bitmap(ZIP_SOURCE_SUPPORTS, ZIP_SOURCE_TELL, -1);
+
+ zip_source_file_stat_init(&sb);
+ if (!ops->stat(ctx, &sb)) {
+ _zip_error_copy(error, &ctx->error);
+ free(ctx->fname);
+ free(ctx);
+ return NULL;
+ }
+
+ if (!sb.exists) {
+ if (ctx->fname && ctx->start == 0 && ctx->len == 0 && ops->write != NULL) {
+ ctx->supports = ZIP_SOURCE_SUPPORTS_WRITABLE;
+ /* zip_open_from_source checks for this to detect non-existing files */
+ zip_error_set(&ctx->stat_error, ZIP_ER_READ, ENOENT);
+ }
+ else {
+ zip_error_set(&ctx->stat_error, ZIP_ER_READ, ENOENT);
+ free(ctx->fname);
+ free(ctx);
+ return NULL;
+ }
+ }
+ else {
+ if ((ctx->st.valid & ZIP_STAT_MTIME) == 0) {
+ ctx->st.mtime = sb.mtime;
+ ctx->st.valid |= ZIP_STAT_MTIME;
+ }
+ if (sb.regular_file) {
+ ctx->supports = ZIP_SOURCE_SUPPORTS_SEEKABLE;
+
+ if (ctx->start + ctx->len > sb.size) {
+ zip_error_set(error, ZIP_ER_INVAL, 0);
+ free(ctx->fname);
+ free(ctx);
+ return NULL;
+ }
+
+ if (ctx->len == 0) {
+ ctx->len = sb.size - ctx->start;
+ ctx->st.size = ctx->len;
+ ctx->st.valid |= ZIP_STAT_SIZE;
+
+ /* when using a partial file, don't allow writing */
+ if (ctx->fname && start == 0 && ops->write != NULL) {
+ ctx->supports = ZIP_SOURCE_SUPPORTS_WRITABLE;
+ }
+ }
+ }
+
+ ctx->supports |= ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_GET_FILE_ATTRIBUTES);
+ }
+
+ ctx->supports |= ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_ACCEPT_EMPTY);
+ if (ops->create_temp_output_cloning != NULL) {
+ if (ctx->supports & ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_BEGIN_WRITE)) {
+ ctx->supports |= ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_BEGIN_WRITE_CLONING);
+ }
+ }
+
+ if ((zs = zip_source_function_create(read_file, ctx, error)) == NULL) {
+ free(ctx->fname);
+ free(ctx);
+ return NULL;
+ }
+
+ return zs;
+}
+
+
+static zip_int64_t
+read_file(void *state, void *data, zip_uint64_t len, zip_source_cmd_t cmd) {
+ zip_source_file_context_t *ctx;
+ char *buf;
+
+ ctx = (zip_source_file_context_t *)state;
+ buf = (char *)data;
+
+ switch (cmd) {
+ case ZIP_SOURCE_ACCEPT_EMPTY:
+ return 0;
+
+ case ZIP_SOURCE_BEGIN_WRITE:
+ /* write support should not be set if fname is NULL */
+ if (ctx->fname == NULL) {
+ zip_error_set(&ctx->error, ZIP_ER_INTERNAL, 0);
+ return -1;
+ }
+ return ctx->ops->create_temp_output(ctx);
+
+ case ZIP_SOURCE_BEGIN_WRITE_CLONING:
+ /* write support should not be set if fname is NULL */
+ if (ctx->fname == NULL) {
+ zip_error_set(&ctx->error, ZIP_ER_INTERNAL, 0);
+ return -1;
+ }
+ return ctx->ops->create_temp_output_cloning(ctx, len);
+
+ case ZIP_SOURCE_CLOSE:
+ if (ctx->fname) {
+ ctx->ops->close(ctx);
+ ctx->f = NULL;
+ }
+ return 0;
+
+ case ZIP_SOURCE_COMMIT_WRITE: {
+ zip_int64_t ret = ctx->ops->commit_write(ctx);
+ ctx->fout = NULL;
+ if (ret == 0) {
+ free(ctx->tmpname);
+ ctx->tmpname = NULL;
+ }
+ return ret;
+ }
+
+ case ZIP_SOURCE_ERROR:
+ return zip_error_to_data(&ctx->error, data, len);
+
+ case ZIP_SOURCE_FREE:
+ free(ctx->fname);
+ free(ctx->tmpname);
+ if (ctx->f) {
+ ctx->ops->close(ctx);
+ }
+ free(ctx);
+ return 0;
+
+ case ZIP_SOURCE_GET_FILE_ATTRIBUTES:
+ if (len < sizeof(ctx->attributes)) {
+ zip_error_set(&ctx->error, ZIP_ER_INVAL, 0);
+ return -1;
+ }
+ memcpy(data, &ctx->attributes, sizeof(ctx->attributes));
+ return sizeof(ctx->attributes);
+
+ case ZIP_SOURCE_OPEN:
+ if (ctx->fname) {
+ if (ctx->ops->open(ctx) == false) {
+ return -1;
+ }
+ }
+
+ if (ctx->start > 0) { // TODO: rewind on re-open
+ if (ctx->ops->seek(ctx, ctx->f, (zip_int64_t)ctx->start, SEEK_SET) == false) {
+ /* TODO: skip by reading */
+ return -1;
+ }
+ }
+ ctx->offset = 0;
+ return 0;
+
+ case ZIP_SOURCE_READ: {
+ zip_int64_t i;
+ zip_uint64_t n;
+
+ if (ctx->len > 0) {
+ n = ZIP_MIN(ctx->len - ctx->offset, len);
+ }
+ else {
+ n = len;
+ }
+
+ if ((i = ctx->ops->read(ctx, buf, n)) < 0) {
+ zip_error_set(&ctx->error, ZIP_ER_READ, errno);
+ return -1;
+ }
+ ctx->offset += (zip_uint64_t)i;
+
+ return i;
+ }
+
+ case ZIP_SOURCE_REMOVE:
+ return ctx->ops->remove(ctx);
+
+ case ZIP_SOURCE_ROLLBACK_WRITE:
+ ctx->ops->rollback_write(ctx);
+ ctx->fout = NULL;
+ free(ctx->tmpname);
+ ctx->tmpname = NULL;
+ return 0;
+
+ case ZIP_SOURCE_SEEK: {
+ zip_int64_t new_offset = zip_source_seek_compute_offset(ctx->offset, ctx->len, data, len, &ctx->error);
+
+ if (new_offset < 0) {
+ return -1;
+ }
+
+ /* The actual offset inside the file must be representable as zip_int64_t. */
+ if (new_offset > ZIP_INT64_MAX - (zip_int64_t)ctx->start) {
+ zip_error_set(&ctx->error, ZIP_ER_SEEK, EOVERFLOW);
+ return -1;
+ }
+
+ ctx->offset = (zip_uint64_t)new_offset;
+
+ if (ctx->ops->seek(ctx, ctx->f, (zip_int64_t)(ctx->offset + ctx->start), SEEK_SET) == false) {
+ return -1;
+ }
+ return 0;
+ }
+
+ case ZIP_SOURCE_SEEK_WRITE: {
+ zip_source_args_seek_t *args;
+
+ args = ZIP_SOURCE_GET_ARGS(zip_source_args_seek_t, data, len, &ctx->error);
+ if (args == NULL) {
+ return -1;
+ }
+
+ if (ctx->ops->seek(ctx, ctx->fout, args->offset, args->whence) == false) {
+ return -1;
+ }
+ return 0;
+ }
+
+ case ZIP_SOURCE_STAT: {
+ if (len < sizeof(ctx->st))
+ return -1;
+
+ if (zip_error_code_zip(&ctx->stat_error) != 0) {
+ zip_error_set(&ctx->error, zip_error_code_zip(&ctx->stat_error), zip_error_code_system(&ctx->stat_error));
+ return -1;
+ }
+
+ memcpy(data, &ctx->st, sizeof(ctx->st));
+ return sizeof(ctx->st);
+ }
+
+ case ZIP_SOURCE_SUPPORTS:
+ return ctx->supports;
+
+ case ZIP_SOURCE_TELL:
+ return (zip_int64_t)ctx->offset;
+
+ case ZIP_SOURCE_TELL_WRITE:
+ return ctx->ops->tell(ctx, ctx->fout);
+
+ case ZIP_SOURCE_WRITE:
+ return ctx->ops->write(ctx, data, len);
+
+ default:
+ zip_error_set(&ctx->error, ZIP_ER_OPNOTSUPP, 0);
+ return -1;
+ }
+}
diff --git a/src/Common/libzip/zip_source_file_stdio.c b/src/Common/libzip/zip_source_file_stdio.c
new file mode 100644
index 0000000..4a22f78
--- /dev/null
+++ b/src/Common/libzip/zip_source_file_stdio.c
@@ -0,0 +1,208 @@
+/*
+ zip_source_file_stdio.c -- read-only stdio file source implementation
+ Copyright (C) 2020 Dieter Baron and Thomas Klausner
+
+ This file is part of libzip, a library to manipulate ZIP archives.
+ The authors can be contacted at <libzip@nih.at>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+ 3. The names of the authors may not be used to endorse or promote
+ products derived from this software without specific prior
+ written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
+ OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "zipint.h"
+
+#include "zip_source_file.h"
+#include "zip_source_file_stdio.h"
+
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+
+#ifdef _WIN32
+#ifndef S_IWUSR
+#define S_IWUSR _S_IWRITE
+#endif
+#endif
+
+/* clang-format off */
+static zip_source_file_operations_t ops_stdio_read = {
+ _zip_stdio_op_close,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ _zip_stdio_op_read,
+ NULL,
+ NULL,
+ _zip_stdio_op_seek,
+ _zip_stdio_op_stat,
+ NULL,
+ _zip_stdio_op_tell,
+ NULL
+};
+/* clang-format on */
+
+
+ZIP_EXTERN zip_source_t *
+zip_source_filep(zip_t *za, FILE *file, zip_uint64_t start, zip_int64_t len) {
+ if (za == NULL) {
+ return NULL;
+ }
+
+ return zip_source_filep_create(file, start, len, &za->error);
+}
+
+
+ZIP_EXTERN zip_source_t *
+zip_source_filep_create(FILE *file, zip_uint64_t start, zip_int64_t length, zip_error_t *error) {
+ if (file == NULL || length < -1) {
+ zip_error_set(error, ZIP_ER_INVAL, 0);
+ return NULL;
+ }
+
+ return zip_source_file_common_new(NULL, file, start, length, NULL, &ops_stdio_read, NULL, error);
+}
+
+
+void
+_zip_stdio_op_close(zip_source_file_context_t *ctx) {
+ fclose((FILE *)ctx->f);
+}
+
+
+zip_int64_t
+_zip_stdio_op_read(zip_source_file_context_t *ctx, void *buf, zip_uint64_t len) {
+ size_t i;
+ if (len > SIZE_MAX) {
+ len = SIZE_MAX;
+ }
+
+ if ((i = fread(buf, 1, (size_t)len, ctx->f)) == 0) {
+ if (ferror((FILE *)ctx->f)) {
+ zip_error_set(&ctx->error, ZIP_ER_READ, errno);
+ return -1;
+ }
+ }
+
+ return (zip_int64_t)i;
+}
+
+
+bool
+_zip_stdio_op_seek(zip_source_file_context_t *ctx, void *f, zip_int64_t offset, int whence) {
+#if ZIP_FSEEK_MAX > ZIP_INT64_MAX
+ if (offset > ZIP_FSEEK_MAX || offset < ZIP_FSEEK_MIN) {
+ zip_error_set(&ctx->error, ZIP_ER_SEEK, EOVERFLOW);
+ return false;
+ }
+#endif
+
+ if (fseeko((FILE *)f, (off_t)offset, whence) < 0) {
+ zip_error_set(&ctx->error, ZIP_ER_SEEK, errno);
+ return false;
+ }
+ return true;
+}
+
+
+bool
+_zip_stdio_op_stat(zip_source_file_context_t *ctx, zip_source_file_stat_t *st) {
+ struct stat sb;
+
+ int ret;
+
+ if (ctx->fname) {
+ ret = stat(ctx->fname, &sb);
+ }
+ else {
+ ret = fstat(fileno((FILE *)ctx->f), &sb);
+ }
+
+ if (ret < 0) {
+ if (errno == ENOENT) {
+ st->exists = false;
+ return true;
+ }
+ zip_error_set(&ctx->error, ZIP_ER_READ, errno);
+ return false;
+ }
+
+ st->size = (zip_uint64_t)sb.st_size;
+ st->mtime = sb.st_mtime;
+
+ st->regular_file = S_ISREG(sb.st_mode);
+ st->exists = true;
+
+ /* We're using UNIX file API, even on Windows; thus, we supply external file attributes with Unix values. */
+ /* TODO: This could be improved on Windows by providing Windows-specific file attributes */
+ ctx->attributes.valid = ZIP_FILE_ATTRIBUTES_HOST_SYSTEM | ZIP_FILE_ATTRIBUTES_EXTERNAL_FILE_ATTRIBUTES;
+ ctx->attributes.host_system = ZIP_OPSYS_UNIX;
+ ctx->attributes.external_file_attributes = (((zip_uint32_t)sb.st_mode) << 16) | ((sb.st_mode & S_IWUSR) ? 0 : 1);
+
+ return true;
+}
+
+
+zip_int64_t
+_zip_stdio_op_tell(zip_source_file_context_t *ctx, void *f) {
+ off_t offset = ftello((FILE *)f);
+
+ if (offset < 0) {
+ zip_error_set(&ctx->error, ZIP_ER_SEEK, errno);
+ }
+
+ return offset;
+}
+
+
+/*
+ * fopen replacement that sets the close-on-exec flag
+ * some implementations support an fopen 'e' flag for that,
+ * but e.g. macOS doesn't.
+ */
+FILE *
+_zip_fopen_close_on_exec(const char *name, bool writeable) {
+ int fd;
+ int flags;
+ FILE *fp;
+
+ flags = O_CLOEXEC;
+ if (writeable) {
+ flags |= O_RDWR;
+ }
+ else {
+ flags |= O_RDONLY;
+ }
+
+ /* mode argument needed on Windows */
+ if ((fd = open(name, flags, 0666)) < 0) {
+ return NULL;
+ }
+ if ((fp = fdopen(fd, writeable ? "r+b" : "rb")) == NULL) {
+ return NULL;
+ }
+ return fp;
+}
diff --git a/src/Common/libzip/zip_source_file.c b/src/Common/libzip/zip_source_file_stdio.h
index 8714785..1bf698c 100644
--- a/src/Common/libzip/zip_source_file.c
+++ b/src/Common/libzip/zip_source_file_stdio.h
@@ -1,6 +1,9 @@
+#ifndef _HAD_ZIP_SOURCE_FILE_STDIO_H
+#define _HAD_ZIP_SOURCE_FILE_STDIO_H
+
/*
- zip_source_file.c -- create data source from file
- Copyright (C) 1999-2018 Dieter Baron and Thomas Klausner
+ zip_source_file_stdio.h -- common header for stdio file implementation
+ Copyright (C) 2020 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
@@ -31,31 +34,14 @@
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-
#include <stdio.h>
-#include "zipint.h"
-
-#ifdef _WIN32
-#error This file is incompatible with Windows, use zip_source_win32utf8.c instead.
-#error Something probably went wrong with configure/cmake.
-#endif
-
-ZIP_EXTERN zip_source_t *
-zip_source_file(zip_t *za, const char *fname, zip_uint64_t start, zip_int64_t len) {
- if (za == NULL)
- return NULL;
-
- return zip_source_file_create(fname, start, len, &za->error);
-}
-
+void _zip_stdio_op_close(zip_source_file_context_t *ctx);
+zip_int64_t _zip_stdio_op_read(zip_source_file_context_t *ctx, void *buf, zip_uint64_t len);
+bool _zip_stdio_op_seek(zip_source_file_context_t *ctx, void *f, zip_int64_t offset, int whence);
+bool _zip_stdio_op_stat(zip_source_file_context_t *ctx, zip_source_file_stat_t *st);
+zip_int64_t _zip_stdio_op_tell(zip_source_file_context_t *ctx, void *f);
-ZIP_EXTERN zip_source_t *
-zip_source_file_create(const char *fname, zip_uint64_t start, zip_int64_t length, zip_error_t *error) {
- if (fname == NULL || length < -1) {
- zip_error_set(error, ZIP_ER_INVAL, 0);
- return NULL;
- }
+FILE *_zip_fopen_close_on_exec(const char *name, bool writeable);
- return _zip_source_file_or_p(fname, NULL, start, length, NULL, error);
-}
+#endif /* _HAD_ZIP_SOURCE_FILE_STDIO_H */
diff --git a/src/Common/libzip/zip_source_file_win32.c b/src/Common/libzip/zip_source_file_win32.c
new file mode 100644
index 0000000..2fe838f
--- /dev/null
+++ b/src/Common/libzip/zip_source_file_win32.c
@@ -0,0 +1,230 @@
+/*
+ zip_source_file_win32.c -- read-only Windows file source implementation
+ Copyright (C) 1999-2020 Dieter Baron and Thomas Klausner
+
+ This file is part of libzip, a library to manipulate ZIP archives.
+ The authors can be contacted at <libzip@nih.at>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+ 3. The names of the authors may not be used to endorse or promote
+ products derived from this software without specific prior
+ written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
+ OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "zip_source_file_win32.h"
+
+static bool _zip_win32_op_stat(zip_source_file_context_t *ctx, zip_source_file_stat_t *st);
+
+static bool _zip_stat_win32(zip_source_file_context_t *ctx, zip_source_file_stat_t *st, HANDLE h);
+
+static zip_source_file_operations_t ops_win32_read = {
+ _zip_win32_op_close,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ _zip_win32_op_read,
+ NULL,
+ NULL,
+ _zip_win32_op_seek,
+ _zip_win32_op_stat,
+ NULL,
+ _zip_win32_op_tell,
+ NULL
+};
+
+
+ZIP_EXTERN zip_source_t *
+zip_source_win32handle(zip_t *za, HANDLE h, zip_uint64_t start, zip_int64_t len) {
+ if (za == NULL) {
+ return NULL;
+ }
+
+ return zip_source_win32handle_create(h, start, len, &za->error);
+}
+
+
+ZIP_EXTERN zip_source_t *
+zip_source_win32handle_create(HANDLE h, zip_uint64_t start, zip_int64_t length, zip_error_t *error) {
+ if (h == INVALID_HANDLE_VALUE || length < -1) {
+ zip_error_set(error, ZIP_ER_INVAL, 0);
+ return NULL;
+ }
+
+ return zip_source_file_common_new(NULL, h, start, length, NULL, &ops_win32_read, NULL, error);
+}
+
+
+void
+_zip_win32_op_close(zip_source_file_context_t *ctx) {
+ CloseHandle((HANDLE)ctx->f);
+}
+
+
+zip_int64_t
+_zip_win32_op_read(zip_source_file_context_t *ctx, void *buf, zip_uint64_t len) {
+ DWORD i;
+
+ /* TODO: cap len to "DWORD_MAX" */
+ if (!ReadFile((HANDLE)ctx->f, buf, (DWORD)len, &i, NULL)) {
+ zip_error_set(&ctx->error, ZIP_ER_READ, _zip_win32_error_to_errno(GetLastError()));
+ return -1;
+ }
+
+ return (zip_int64_t)i;
+}
+
+
+bool
+_zip_win32_op_seek(zip_source_file_context_t *ctx, void *f, zip_int64_t offset, int whence) {
+ LARGE_INTEGER li;
+ DWORD method;
+
+ switch (whence) {
+ case SEEK_SET:
+ method = FILE_BEGIN;
+ break;
+ case SEEK_END:
+ method = FILE_END;
+ break;
+ case SEEK_CUR:
+ method = FILE_CURRENT;
+ break;
+ default:
+ zip_error_set(&ctx->error, ZIP_ER_SEEK, EINVAL);
+ return -1;
+ }
+
+ li.QuadPart = (LONGLONG)offset;
+ if (!SetFilePointerEx((HANDLE)f, li, NULL, method)) {
+ zip_error_set(&ctx->error, ZIP_ER_SEEK, _zip_win32_error_to_errno(GetLastError()));
+ return false;
+ }
+
+ return true;
+}
+
+
+static bool
+_zip_win32_op_stat(zip_source_file_context_t *ctx, zip_source_file_stat_t *st) {
+ return _zip_stat_win32(ctx, st, (HANDLE)ctx->f);
+}
+
+
+zip_int64_t
+_zip_win32_op_tell(zip_source_file_context_t *ctx, void *f) {
+ LARGE_INTEGER zero;
+ LARGE_INTEGER new_offset;
+
+ zero.QuadPart = 0;
+ if (!SetFilePointerEx((HANDLE)f, zero, &new_offset, FILE_CURRENT)) {
+ zip_error_set(&ctx->error, ZIP_ER_SEEK, _zip_win32_error_to_errno(GetLastError()));
+ return -1;
+ }
+
+ return (zip_int64_t)new_offset.QuadPart;
+}
+
+
+int
+_zip_win32_error_to_errno(DWORD win32err) {
+ /* Note: This list isn't exhaustive, but should cover common cases. */
+ switch (win32err) {
+ case ERROR_INVALID_PARAMETER:
+ return EINVAL;
+ case ERROR_FILE_NOT_FOUND:
+ return ENOENT;
+ case ERROR_INVALID_HANDLE:
+ return EBADF;
+ case ERROR_ACCESS_DENIED:
+ return EACCES;
+ case ERROR_FILE_EXISTS:
+ return EEXIST;
+ case ERROR_TOO_MANY_OPEN_FILES:
+ return EMFILE;
+ case ERROR_DISK_FULL:
+ return ENOSPC;
+ default:
+ return 10000 + win32err;
+ }
+}
+
+
+static bool
+_zip_stat_win32(zip_source_file_context_t *ctx, zip_source_file_stat_t *st, HANDLE h) {
+ FILETIME mtimeft;
+ time_t mtime;
+ LARGE_INTEGER size;
+
+ if (!GetFileTime(h, NULL, NULL, &mtimeft)) {
+ zip_error_set(&ctx->error, ZIP_ER_READ, _zip_win32_error_to_errno(GetLastError()));
+ return false;
+ }
+ if (_zip_filetime_to_time_t(mtimeft, &mtime) < 0) {
+ zip_error_set(&ctx->error, ZIP_ER_READ, ERANGE);
+ return false;
+ }
+
+ st->exists = true;
+ st->mtime = mtime;
+
+ if (GetFileType(h) == FILE_TYPE_DISK) {
+ st->regular_file = 1;
+
+ if (!GetFileSizeEx(h, &size)) {
+ zip_error_set(&ctx->error, ZIP_ER_READ, _zip_win32_error_to_errno(GetLastError()));
+ return false;
+ }
+
+ st->size = (zip_uint64_t)size.QuadPart;
+ }
+
+ /* TODO: fill in ctx->attributes */
+
+ return true;
+}
+
+
+bool
+_zip_filetime_to_time_t(FILETIME ft, time_t *t) {
+ /*
+ Inspired by http://stackoverflow.com/questions/6161776/convert-windows-filetime-to-second-in-unix-linux
+ */
+ const zip_int64_t WINDOWS_TICK = 10000000LL;
+ const zip_int64_t SEC_TO_UNIX_EPOCH = 11644473600LL;
+ ULARGE_INTEGER li;
+ zip_int64_t secs;
+ time_t temp;
+
+ li.LowPart = ft.dwLowDateTime;
+ li.HighPart = ft.dwHighDateTime;
+ secs = (li.QuadPart / WINDOWS_TICK - SEC_TO_UNIX_EPOCH);
+
+ temp = (time_t)secs;
+ if (secs != (zip_int64_t)temp) {
+ return false;
+ }
+
+ *t = temp;
+ return true;
+}
diff --git a/src/Common/libzip/zip_source_file_win32.h b/src/Common/libzip/zip_source_file_win32.h
new file mode 100644
index 0000000..5092e63
--- /dev/null
+++ b/src/Common/libzip/zip_source_file_win32.h
@@ -0,0 +1,74 @@
+#ifndef _HAD_ZIP_SOURCE_FILE_WIN32_H
+#define _HAD_ZIP_SOURCE_FILE_WIN32_H
+
+/*
+ zip_source_file_win32.h -- common header for Windows file implementation
+ Copyright (C) 2020 Dieter Baron and Thomas Klausner
+
+ This file is part of libzip, a library to manipulate ZIP archives.
+ The authors can be contacted at <libzip@nih.at>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+ 3. The names of the authors may not be used to endorse or promote
+ products derived from this software without specific prior
+ written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
+ OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/* 0x0501 => Windows XP; needs to be at least this value because of GetFileSizeEx */
+#if !defined(MS_UWP) && !defined(_WIN32_WINNT)
+#define _WIN32_WINNT 0x0501
+#endif
+
+#include <windows.h>
+
+#include <aclapi.h>
+
+#include "zipint.h"
+
+#include "zip_source_file.h"
+
+struct zip_win32_file_operations {
+ char *(*allocate_tempname)(const char *name, size_t extra_chars, size_t *lengthp);
+ HANDLE (__stdcall *create_file)(const void *name, DWORD access, DWORD share_mode, PSECURITY_ATTRIBUTES security_attributes, DWORD creation_disposition, DWORD file_attributes, HANDLE template_file);
+ BOOL (__stdcall *delete_file)(const void *name);
+ DWORD (__stdcall *get_file_attributes)(const void *name);
+ BOOL (__stdcall *get_file_attributes_ex)(const void *name, GET_FILEEX_INFO_LEVELS info_level, void *information);
+ void (*make_tempname)(char *buf, size_t len, const char *name, zip_uint32_t i);
+ BOOL (__stdcall *move_file)(const void *from, const void *to, DWORD flags);
+ BOOL (__stdcall *set_file_attributes)(const void *name, DWORD attributes);
+ char *(*string_duplicate)(const char *string);
+};
+
+typedef struct zip_win32_file_operations zip_win32_file_operations_t;
+
+extern zip_source_file_operations_t _zip_source_file_win32_named_ops;
+
+void _zip_win32_op_close(zip_source_file_context_t *ctx);
+zip_int64_t _zip_win32_op_read(zip_source_file_context_t *ctx, void *buf, zip_uint64_t len);
+bool _zip_win32_op_seek(zip_source_file_context_t *ctx, void *f, zip_int64_t offset, int whence);
+zip_int64_t _zip_win32_op_tell(zip_source_file_context_t *ctx, void *f);
+
+bool _zip_filetime_to_time_t(FILETIME ft, time_t *t);
+int _zip_win32_error_to_errno(DWORD win32err);
+
+#endif /* _HAD_ZIP_SOURCE_FILE_WIN32_H */
diff --git a/src/Common/libzip/zip_source_file_win32_named.c b/src/Common/libzip/zip_source_file_win32_named.c
new file mode 100644
index 0000000..63791f8
--- /dev/null
+++ b/src/Common/libzip/zip_source_file_win32_named.c
@@ -0,0 +1,268 @@
+/*
+ zip_source_file_win32_named.c -- source for Windows file opened by name
+ Copyright (C) 1999-2020 Dieter Baron and Thomas Klausner
+
+ This file is part of libzip, a library to manipulate ZIP archives.
+ The authors can be contacted at <libzip@nih.at>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+ 3. The names of the authors may not be used to endorse or promote
+ products derived from this software without specific prior
+ written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
+ OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "zip_source_file_win32.h"
+
+static zip_int64_t _zip_win32_named_op_commit_write(zip_source_file_context_t *ctx);
+static zip_int64_t _zip_win32_named_op_create_temp_output(zip_source_file_context_t *ctx);
+static bool _zip_win32_named_op_open(zip_source_file_context_t *ctx);
+static zip_int64_t _zip_win32_named_op_remove(zip_source_file_context_t *ctx);
+static void _zip_win32_named_op_rollback_write(zip_source_file_context_t *ctx);
+static bool _zip_win32_named_op_stat(zip_source_file_context_t *ctx, zip_source_file_stat_t *st);
+static char *_zip_win32_named_op_string_duplicate(zip_source_file_context_t *ctx, const char *string);
+static zip_int64_t _zip_win32_named_op_write(zip_source_file_context_t *ctx, const void *data, zip_uint64_t len);
+
+static HANDLE win32_named_open(zip_source_file_context_t *ctx, const char *name, bool temporary, PSECURITY_ATTRIBUTES security_attributes);
+
+/* clang-format off */
+zip_source_file_operations_t _zip_source_file_win32_named_ops = {
+ _zip_win32_op_close,
+ _zip_win32_named_op_commit_write,
+ _zip_win32_named_op_create_temp_output,
+ NULL,
+ _zip_win32_named_op_open,
+ _zip_win32_op_read,
+ _zip_win32_named_op_remove,
+ _zip_win32_named_op_rollback_write,
+ _zip_win32_op_seek,
+ _zip_win32_named_op_stat,
+ _zip_win32_named_op_string_duplicate,
+ _zip_win32_op_tell,
+ _zip_win32_named_op_write
+};
+/* clang-format on */
+
+static zip_int64_t
+_zip_win32_named_op_commit_write(zip_source_file_context_t *ctx) {
+ zip_win32_file_operations_t *file_ops = (zip_win32_file_operations_t *)ctx->ops_userdata;
+ DWORD attributes;
+
+ if (!CloseHandle((HANDLE)ctx->fout)) {
+ zip_error_set(&ctx->error, ZIP_ER_WRITE, _zip_win32_error_to_errno(GetLastError()));
+ return -1;
+ }
+
+ attributes = file_ops->get_file_attributes(ctx->tmpname);
+ if (attributes == INVALID_FILE_ATTRIBUTES) {
+ zip_error_set(&ctx->error, ZIP_ER_RENAME, _zip_win32_error_to_errno(GetLastError()));
+ return -1;
+ }
+
+ if (attributes & FILE_ATTRIBUTE_TEMPORARY) {
+ if (!file_ops->set_file_attributes(ctx->tmpname, attributes & ~FILE_ATTRIBUTE_TEMPORARY)) {
+ zip_error_set(&ctx->error, ZIP_ER_RENAME, _zip_win32_error_to_errno(GetLastError()));
+ return -1;
+ }
+ }
+
+ if (!file_ops->move_file(ctx->tmpname, ctx->fname, MOVEFILE_REPLACE_EXISTING)) {
+ zip_error_set(&ctx->error, ZIP_ER_RENAME, _zip_win32_error_to_errno(GetLastError()));
+ return -1;
+ }
+
+ return 0;
+}
+
+static zip_int64_t
+_zip_win32_named_op_create_temp_output(zip_source_file_context_t *ctx) {
+ zip_win32_file_operations_t *file_ops = (zip_win32_file_operations_t *)ctx->ops_userdata;
+
+ zip_uint32_t value, i;
+ HANDLE th = INVALID_HANDLE_VALUE;
+ void *temp = NULL;
+ PSECURITY_DESCRIPTOR psd = NULL;
+ PSECURITY_ATTRIBUTES psa = NULL;
+ SECURITY_ATTRIBUTES sa;
+ SECURITY_INFORMATION si;
+ DWORD success;
+ PACL dacl = NULL;
+ char *tempname = NULL;
+ size_t tempname_size = 0;
+
+ if ((HANDLE)ctx->f != INVALID_HANDLE_VALUE && GetFileType((HANDLE)ctx->f) == FILE_TYPE_DISK) {
+ si = DACL_SECURITY_INFORMATION | UNPROTECTED_DACL_SECURITY_INFORMATION;
+ success = GetSecurityInfo((HANDLE)ctx->f, SE_FILE_OBJECT, si, NULL, NULL, &dacl, NULL, &psd);
+ if (success == ERROR_SUCCESS) {
+ sa.nLength = sizeof(SECURITY_ATTRIBUTES);
+ sa.bInheritHandle = FALSE;
+ sa.lpSecurityDescriptor = psd;
+ psa = &sa;
+ }
+ }
+
+ #ifndef MS_UWP
+ value = GetTickCount();
+#else
+ value = (zip_uint32_t)(GetTickCount64() & 0xffffffff);
+#endif
+
+ if ((tempname = file_ops->allocate_tempname(ctx->fname, 10, &tempname_size)) == NULL) {
+ zip_error_set(&ctx->error, ZIP_ER_MEMORY, 0);
+ return -1;
+ }
+
+ for (i = 0; i < 1024 && th == INVALID_HANDLE_VALUE; i++) {
+ file_ops->make_tempname(tempname, tempname_size, ctx->fname, value + i);
+
+ th = win32_named_open(ctx, tempname, true, psa);
+ if (th == INVALID_HANDLE_VALUE && GetLastError() != ERROR_FILE_EXISTS)
+ break;
+ }
+
+ if (th == INVALID_HANDLE_VALUE) {
+ free(tempname);
+ LocalFree(psd);
+ zip_error_set(&ctx->error, ZIP_ER_TMPOPEN, _zip_win32_error_to_errno(GetLastError()));
+ return -1;
+ }
+
+ LocalFree(psd);
+ ctx->fout = th;
+ ctx->tmpname = tempname;
+
+ return 0;
+}
+
+
+static bool
+_zip_win32_named_op_open(zip_source_file_context_t *ctx) {
+ HANDLE h = win32_named_open(ctx, ctx->fname, false, NULL);
+
+ if (h == INVALID_HANDLE_VALUE) {
+ return false;
+ }
+
+ ctx->f = h;
+ return true;
+}
+
+
+static zip_int64_t
+_zip_win32_named_op_remove(zip_source_file_context_t *ctx) {
+ zip_win32_file_operations_t *file_ops = (zip_win32_file_operations_t *)ctx->ops_userdata;
+
+ if (!file_ops->delete_file(ctx->fname)) {
+ zip_error_set(&ctx->error, ZIP_ER_REMOVE, _zip_win32_error_to_errno(GetLastError()));
+ return -1;
+ }
+
+ return 0;
+}
+
+
+static void
+_zip_win32_named_op_rollback_write(zip_source_file_context_t *ctx) {
+ zip_win32_file_operations_t *file_ops = (zip_win32_file_operations_t *)ctx->ops_userdata;
+
+ if (ctx->fout) {
+ CloseHandle((HANDLE)ctx->fout);
+ }
+ file_ops->delete_file(ctx->tmpname);
+}
+
+
+static bool
+_zip_win32_named_op_stat(zip_source_file_context_t *ctx, zip_source_file_stat_t *st) {
+ zip_win32_file_operations_t *file_ops = (zip_win32_file_operations_t *)ctx->ops_userdata;
+
+ WIN32_FILE_ATTRIBUTE_DATA file_attributes;
+
+ if (!file_ops->get_file_attributes_ex(ctx->fname, GetFileExInfoStandard, &file_attributes)) {
+ DWORD error = GetLastError();
+ if (error == ERROR_FILE_NOT_FOUND) {
+ st->exists = false;
+ return true;
+ }
+ zip_error_set(&ctx->error, ZIP_ER_READ, _zip_win32_error_to_errno(error));
+ return false;
+ }
+
+ st->exists = true;
+ st->regular_file = true; /* TODO: Is this always right? How to determine without a HANDLE? */
+ if (!_zip_filetime_to_time_t(file_attributes.ftLastWriteTime, &st->mtime)) {
+ zip_error_set(&ctx->error, ZIP_ER_READ, ERANGE);
+ return false;
+ }
+ st->size = ((zip_uint64_t)file_attributes.nFileSizeHigh << 32) | file_attributes.nFileSizeLow;
+
+ /* TODO: fill in ctx->attributes */
+
+ return true;
+}
+
+
+static char *
+_zip_win32_named_op_string_duplicate(zip_source_file_context_t *ctx, const char *string) {
+ zip_win32_file_operations_t *file_ops = (zip_win32_file_operations_t *)ctx->ops_userdata;
+
+ return file_ops->string_duplicate(string);
+}
+
+
+static zip_int64_t
+_zip_win32_named_op_write(zip_source_file_context_t *ctx, const void *data, zip_uint64_t len) {
+ DWORD ret;
+ if (!WriteFile((HANDLE)ctx->fout, data, (DWORD)len, &ret, NULL) || ret != len) {
+ zip_error_set(&ctx->error, ZIP_ER_WRITE, _zip_win32_error_to_errno(GetLastError()));
+ return -1;
+ }
+
+ return (zip_int64_t)ret;
+}
+
+
+static HANDLE
+win32_named_open(zip_source_file_context_t *ctx, const char *name, bool temporary, PSECURITY_ATTRIBUTES security_attributes) {
+ zip_win32_file_operations_t *file_ops = (zip_win32_file_operations_t *)ctx->ops_userdata;
+
+ DWORD access = GENERIC_READ;
+ DWORD share_mode = FILE_SHARE_READ | FILE_SHARE_WRITE;
+ DWORD creation_disposition = OPEN_EXISTING;
+ DWORD file_attributes = FILE_ATTRIBUTE_NORMAL;
+ HANDLE h;
+
+ if (temporary) {
+ access = GENERIC_READ | GENERIC_WRITE;
+ share_mode = FILE_SHARE_READ;
+ creation_disposition = CREATE_NEW;
+ file_attributes = FILE_ATTRIBUTE_NORMAL | FILE_ATTRIBUTE_TEMPORARY;
+ }
+
+ h = file_ops->create_file(name, access, share_mode, security_attributes, creation_disposition, file_attributes, NULL);
+
+ if (h == INVALID_HANDLE_VALUE) {
+ zip_error_set(&ctx->error, ZIP_ER_OPEN, _zip_win32_error_to_errno(GetLastError()));
+ }
+
+ return h;
+}
diff --git a/src/Common/libzip/zip_source_file_win32_utf16.c b/src/Common/libzip/zip_source_file_win32_utf16.c
new file mode 100644
index 0000000..8378648
--- /dev/null
+++ b/src/Common/libzip/zip_source_file_win32_utf16.c
@@ -0,0 +1,117 @@
+/*
+ zip_source_file_win32_utf16.c -- source for Windows file opened by UTF-16 name
+ Copyright (C) 1999-2020 Dieter Baron and Thomas Klausner
+
+ This file is part of libzip, a library to manipulate ZIP archives.
+ The authors can be contacted at <libzip@nih.at>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+ 3. The names of the authors may not be used to endorse or promote
+ products derived from this software without specific prior
+ written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
+ OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "zip_source_file_win32.h"
+
+#define RtlGenRandom SystemFunction036
+BOOLEAN NTAPI RtlGenRandom(PVOID RandomBuffer, ULONG RandomBufferLength);
+
+bool zip_secure_random(zip_uint8_t *buffer, zip_uint16_t length)
+{
+ return RtlGenRandom (buffer, (ULONG) length);
+}
+
+
+static char *utf16_allocate_tempname(const char *name, size_t extra_chars, size_t *lengthp);
+static HANDLE __stdcall utf16_create_file(const char *name, DWORD access, DWORD share_mode, PSECURITY_ATTRIBUTES security_attributes, DWORD creation_disposition, DWORD file_attributes, HANDLE template_file);
+static void utf16_make_tempname(char *buf, size_t len, const char *name, zip_uint32_t i);
+static char *utf16_strdup(const char *string);
+
+zip_win32_file_operations_t ops_utf16 = {
+ utf16_allocate_tempname,
+ utf16_create_file,
+ DeleteFileW,
+ GetFileAttributesW,
+ GetFileAttributesExW,
+ utf16_make_tempname,
+ MoveFileExW,
+ SetFileAttributesW,
+ utf16_strdup
+};
+
+ZIP_EXTERN zip_source_t *
+zip_source_win32w(zip_t *za, const wchar_t *fname, zip_uint64_t start, zip_int64_t len) {
+ if (za == NULL)
+ return NULL;
+
+ return zip_source_win32w_create(fname, start, len, &za->error);
+}
+
+
+ZIP_EXTERN zip_source_t *
+zip_source_win32w_create(const wchar_t *fname, zip_uint64_t start, zip_int64_t length, zip_error_t *error) {
+ if (fname == NULL || length < -1) {
+ zip_error_set(error, ZIP_ER_INVAL, 0);
+ return NULL;
+ }
+
+
+ return zip_source_file_common_new((const char *)fname, NULL, start, length, NULL, &_zip_source_file_win32_named_ops, &ops_utf16, error);
+}
+
+
+static char *
+utf16_allocate_tempname(const char *name, size_t extra_chars, size_t *lengthp) {
+ *lengthp = wcslen((const wchar_t *)name) + extra_chars;
+ return (char *)malloc(*lengthp * sizeof(wchar_t));
+}
+
+
+static HANDLE __stdcall
+utf16_create_file(const char *name, DWORD access, DWORD share_mode, PSECURITY_ATTRIBUTES security_attributes, DWORD creation_disposition, DWORD file_attributes, HANDLE template_file) {
+#ifdef MS_UWP
+ CREATEFILE2_EXTENDED_PARAMETERS extParams = {0};
+ extParams.dwFileAttributes = file_attributes;
+ extParams.dwFileFlags = FILE_FLAG_RANDOM_ACCESS;
+ extParams.dwSecurityQosFlags = SECURITY_ANONYMOUS;
+ extParams.dwSize = sizeof(extParams);
+ extParams.hTemplateFile = template_file;
+ extParams.lpSecurityAttributes = security_attributes;
+
+ return CreateFile2((const wchar_t *)name, access, share_mode, creation_disposition, &extParams);
+#else
+ return CreateFileW((const wchar_t *)name, access, share_mode, security_attributes, creation_disposition, file_attributes, template_file);
+#endif
+}
+
+
+static void
+utf16_make_tempname(char *buf, size_t len, const char *name, zip_uint32_t i) {
+ _snwprintf((wchar_t *)buf, len, L"%s.%08x", (const wchar_t *)name, i);
+}
+
+
+static char *
+utf16_strdup(const char *string) {
+ return (char *)_wcsdup((const wchar_t *)string);
+}
diff --git a/src/Common/libzip/zip_source_win32utf8.c b/src/Common/libzip/zip_source_file_win32_utf8.c
index 103b498..4f258bc 100644
--- a/src/Common/libzip/zip_source_win32utf8.c
+++ b/src/Common/libzip/zip_source_file_win32_utf8.c
@@ -1,6 +1,6 @@
/*
- zip_source_win32utf8.c -- create data source from Windows file (UTF-8)
- Copyright (C) 1999-2018 Dieter Baron and Thomas Klausner
+ zip_source_file_win32_ansi.c -- source for Windows file opened by UTF-8 name
+ Copyright (C) 1999-2020 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
@@ -31,23 +31,14 @@
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-/* 0x0501 => Windows XP; needs to be at least this value because of GetFileSizeEx */
-#if !defined(MS_UWP) && !defined(_WIN32_WINNT)
-#define _WIN32_WINNT 0x0501
-#endif
-#include <windows.h>
-
-#include <stdlib.h>
-
-#include "zipint.h"
-#include "zipwin32.h"
-
+#include "zip_source_file_win32.h"
ZIP_EXTERN zip_source_t *
zip_source_file(zip_t *za, const char *fname, zip_uint64_t start, zip_int64_t len) {
- if (za == NULL)
- return NULL;
-
+ if (za == NULL) {
+ return NULL;
+ }
+
return zip_source_file_create(fname, start, len, &za->error);
}
@@ -59,24 +50,24 @@ zip_source_file_create(const char *fname, zip_uint64_t start, zip_int64_t length
zip_source_t *source;
if (fname == NULL || length < -1) {
- zip_error_set(error, ZIP_ER_INVAL, 0);
- return NULL;
+ zip_error_set(error, ZIP_ER_INVAL, 0);
+ return NULL;
}
/* Convert fname from UTF-8 to Windows-friendly UTF-16. */
size = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, fname, -1, NULL, 0);
if (size == 0) {
- zip_error_set(error, ZIP_ER_INVAL, 0);
- return NULL;
+ zip_error_set(error, ZIP_ER_INVAL, 0);
+ return NULL;
}
if ((wfname = (wchar_t *)malloc(sizeof(wchar_t) * size)) == NULL) {
- zip_error_set(error, ZIP_ER_MEMORY, 0);
- return NULL;
+ zip_error_set(error, ZIP_ER_MEMORY, 0);
+ return NULL;
}
MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, fname, -1, wfname, size);
source = zip_source_win32w_create(wfname, start, length, error);
-
+
free(wfname);
return source;
}
diff --git a/src/Common/libzip/zip_source_filep.c b/src/Common/libzip/zip_source_filep.c
deleted file mode 100644
index cb3d151..0000000
--- a/src/Common/libzip/zip_source_filep.c
+++ /dev/null
@@ -1,658 +0,0 @@
-/*
- zip_source_filep.c -- create data source from FILE *
- Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner
-
- This file is part of libzip, a library to manipulate ZIP archives.
- The authors can be contacted at <libzip@nih.at>
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
- 1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in
- the documentation and/or other materials provided with the
- distribution.
- 3. The names of the authors may not be used to endorse or promote
- products derived from this software without specific prior
- written permission.
-
- THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
- OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
- DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
- IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-
-#include "zipint.h"
-
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-
-#ifdef HAVE_CLONEFILE
-#include <sys/attr.h>
-#include <sys/clonefile.h>
-#define CAN_CLONE
-#endif
-#ifdef HAVE_FICLONERANGE
-#include <linux/fs.h>
-#include <sys/ioctl.h>
-#define CAN_CLONE
-#endif
-
-#ifdef _WIN32
-/* WIN32 needs <fcntl.h> for _O_BINARY */
-#include <fcntl.h>
-#endif
-
-/* Windows sys/types.h does not provide these */
-#ifndef S_ISREG
-#define S_ISREG(m) (((m)&S_IFMT) == S_IFREG)
-#endif
-#if defined(S_IXUSR) && defined(S_IRWXG) && defined(S_IRWXO)
-#define _SAFE_MASK (S_IXUSR | S_IRWXG | S_IRWXO)
-#elif defined(_S_IWRITE)
-#define _SAFE_MASK (_S_IWRITE)
-#else
-#error do not know safe values for umask, please report this
-#endif
-
-#ifdef _MSC_VER
-/* MSVC doesn't have mode_t */
-typedef int mode_t;
-#endif
-
-struct read_file {
- zip_error_t error; /* last error information */
- zip_int64_t supports;
-
- /* reading */
- char *fname; /* name of file to read from */
- FILE *f; /* file to read from */
- struct zip_stat st; /* stat information passed in */
- zip_error_t stat_error; /* error returned for stat */
- zip_uint64_t start; /* start offset of data to read */
- zip_uint64_t end; /* end offset of data to read relative to start, 0 for up to EOF */
- zip_uint64_t current; /* current offset relative to start (0 is beginning of part we read) */
-
- /* writing */
- char *tmpname;
- FILE *fout;
-};
-
-static zip_int64_t read_file(void *state, void *data, zip_uint64_t len, zip_source_cmd_t cmd);
-static int create_temp_output(struct read_file *ctx);
-#ifdef CAN_CLONE
-static zip_int64_t create_temp_output_cloning(struct read_file *ctx, zip_uint64_t offset);
-#endif
-static int _zip_fseek_u(FILE *f, zip_uint64_t offset, int whence, zip_error_t *error);
-static int _zip_fseek(FILE *f, zip_int64_t offset, int whence, zip_error_t *error);
-
-
-ZIP_EXTERN zip_source_t *
-zip_source_filep(zip_t *za, FILE *file, zip_uint64_t start, zip_int64_t len) {
- if (za == NULL)
- return NULL;
-
- return zip_source_filep_create(file, start, len, &za->error);
-}
-
-
-ZIP_EXTERN zip_source_t *
-zip_source_filep_create(FILE *file, zip_uint64_t start, zip_int64_t length, zip_error_t *error) {
- if (file == NULL || length < -1) {
- zip_error_set(error, ZIP_ER_INVAL, 0);
- return NULL;
- }
-
- return _zip_source_file_or_p(NULL, file, start, length, NULL, error);
-}
-
-
-zip_source_t *
-_zip_source_file_or_p(const char *fname, FILE *file, zip_uint64_t start, zip_int64_t len, const zip_stat_t *st, zip_error_t *error) {
- struct read_file *ctx;
- zip_source_t *zs;
- struct stat sb;
- bool stat_valid;
-
- if (file == NULL && fname == NULL) {
- zip_error_set(error, ZIP_ER_INVAL, 0);
- return NULL;
- }
-
- if (len < 0) {
- len = 0;
- }
-
- if (start > ZIP_INT64_MAX || start + (zip_uint64_t)len < start) {
- zip_error_set(error, ZIP_ER_INVAL, 0);
- return NULL;
- }
-
- if ((ctx = (struct read_file *)malloc(sizeof(struct read_file))) == NULL) {
- zip_error_set(error, ZIP_ER_MEMORY, 0);
- return NULL;
- }
-
- ctx->fname = NULL;
- if (fname) {
- if ((ctx->fname = strdup(fname)) == NULL) {
- zip_error_set(error, ZIP_ER_MEMORY, 0);
- free(ctx);
- return NULL;
- }
- }
- ctx->f = file;
- ctx->start = start;
- ctx->end = (zip_uint64_t)len;
- if (st) {
- memcpy(&ctx->st, st, sizeof(ctx->st));
- ctx->st.name = NULL;
- ctx->st.valid &= ~ZIP_STAT_NAME;
- }
- else {
- zip_stat_init(&ctx->st);
- }
-
- if (ctx->end > 0) {
- ctx->st.size = ctx->end;
- ctx->st.valid |= ZIP_STAT_SIZE;
- }
-
- zip_error_init(&ctx->stat_error);
-
- ctx->tmpname = NULL;
- ctx->fout = NULL;
-
- zip_error_init(&ctx->error);
-
- ctx->supports = ZIP_SOURCE_SUPPORTS_READABLE | zip_source_make_command_bitmap(ZIP_SOURCE_SUPPORTS, ZIP_SOURCE_TELL, -1);
-
- if (ctx->fname) {
- stat_valid = stat(ctx->fname, &sb) >= 0;
-
- if (!stat_valid) {
- if (ctx->start == 0 && ctx->end == 0) {
- ctx->supports = ZIP_SOURCE_SUPPORTS_WRITABLE;
- }
- }
- }
- else {
- stat_valid = fstat(fileno(ctx->f), &sb) >= 0;
- }
-
- if (!stat_valid) {
- zip_error_set(&ctx->stat_error, ZIP_ER_READ, errno);
- }
- else {
- if ((ctx->st.valid & ZIP_STAT_MTIME) == 0) {
- ctx->st.mtime = sb.st_mtime;
- ctx->st.valid |= ZIP_STAT_MTIME;
- }
- if (S_ISREG(sb.st_mode)) {
- ctx->supports = ZIP_SOURCE_SUPPORTS_SEEKABLE;
-
- if (ctx->start + ctx->end > (zip_uint64_t)sb.st_size) {
- zip_error_set(error, ZIP_ER_INVAL, 0);
- free(ctx->fname);
- free(ctx);
- return NULL;
- }
-
- if (ctx->end == 0) {
- ctx->st.size = (zip_uint64_t)sb.st_size - ctx->start;
- ctx->st.valid |= ZIP_STAT_SIZE;
-
- if (ctx->fname && start == 0) {
- ctx->supports = ZIP_SOURCE_SUPPORTS_WRITABLE;
- }
- }
- }
- }
-
-#ifdef CAN_CLONE
- if (ctx->supports & ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_BEGIN_WRITE)) {
- ctx->supports |= ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_BEGIN_WRITE_CLONING);
- }
-#endif
-
- if ((zs = zip_source_function_create(read_file, ctx, error)) == NULL) {
- free(ctx->fname);
- free(ctx);
- return NULL;
- }
-
- return zs;
-}
-
-
-static int
-create_temp_output(struct read_file *ctx) {
- char *temp;
- int tfd;
- mode_t mask;
- FILE *tfp;
-
- if ((temp = (char *)malloc(strlen(ctx->fname) + 8)) == NULL) {
- zip_error_set(&ctx->error, ZIP_ER_MEMORY, 0);
- return -1;
- }
- sprintf(temp, "%s.XXXXXX", ctx->fname);
-
- mask = umask(_SAFE_MASK);
- if ((tfd = mkstemp(temp)) == -1) {
- zip_error_set(&ctx->error, ZIP_ER_TMPOPEN, errno);
- umask(mask);
- free(temp);
- return -1;
- }
- umask(mask);
-
- if ((tfp = fdopen(tfd, "r+b")) == NULL) {
- zip_error_set(&ctx->error, ZIP_ER_TMPOPEN, errno);
- close(tfd);
- (void)remove(temp);
- free(temp);
- return -1;
- }
-
-#ifdef _WIN32
- /*
- According to Pierre Joye, Windows in some environments per
- default creates text files, so force binary mode.
- */
- _setmode(_fileno(tfp), _O_BINARY);
-#endif
-
- ctx->fout = tfp;
- ctx->tmpname = temp;
-
- return 0;
-}
-
-#ifdef CAN_CLONE
-zip_int64_t static create_temp_output_cloning(struct read_file *ctx, zip_uint64_t offset) {
- char *temp;
- FILE *tfp;
-
- if (offset > ZIP_OFF_MAX) {
- zip_error_set(&ctx->error, ZIP_ER_SEEK, E2BIG);
- return -1;
- }
-
- if ((temp = (char *)malloc(strlen(ctx->fname) + 8)) == NULL) {
- zip_error_set(&ctx->error, ZIP_ER_MEMORY, 0);
- return -1;
- }
- sprintf(temp, "%s.XXXXXX", ctx->fname);
-
-#ifdef HAVE_CLONEFILE
-#ifndef __clang_analyzer__
- /* we can't use mkstemp, since clonefile insists on creating the file */
- if (mktemp(temp) == NULL) {
- zip_error_set(&ctx->error, ZIP_ER_TMPOPEN, errno);
- free(temp);
- return -1;
- }
-#endif
-
- if (clonefile(ctx->fname, temp, 0) < 0) {
- zip_error_set(&ctx->error, ZIP_ER_TMPOPEN, errno);
- free(temp);
- return -1;
- }
- if ((tfp = fopen(temp, "r+b")) == NULL) {
- zip_error_set(&ctx->error, ZIP_ER_TMPOPEN, errno);
- (void)remove(temp);
- free(temp);
- return -1;
- }
-#else
- {
- int fd;
- struct file_clone_range range;
- struct stat st;
-
- if (fstat(fileno(ctx->f), &st) < 0) {
- zip_error_set(&ctx->error, ZIP_ER_TMPOPEN, errno);
- return -1;
- }
-
- if ((fd = mkstemp(temp)) < 0) {
- zip_error_set(&ctx->error, ZIP_ER_TMPOPEN, errno);
- free(temp);
- return -1;
- }
-
- range.src_fd = fileno(ctx->f);
- range.src_offset = 0;
- range.src_length = ((offset + st.st_blksize - 1) / st.st_blksize) * st.st_blksize;
- if (range.src_length > st.st_size) {
- range.src_length = 0;
- }
- range.dest_offset = 0;
- if (ioctl(fd, FICLONERANGE, &range) < 0) {
- zip_error_set(&ctx->error, ZIP_ER_TMPOPEN, errno);
- (void)close(fd);
- (void)remove(temp);
- free(temp);
- return -1;
- }
-
- if ((tfp = fdopen(fd, "r+b")) == NULL) {
- zip_error_set(&ctx->error, ZIP_ER_TMPOPEN, errno);
- (void)close(fd);
- (void)remove(temp);
- free(temp);
- return -1;
- }
- }
-#endif
-
- if (ftruncate(fileno(tfp), (off_t)offset) < 0) {
- (void)fclose(tfp);
- (void)remove(temp);
- free(temp);
- return -1;
- }
- if (fseeko(tfp, (off_t)offset, SEEK_SET) < 0) {
- (void)fclose(tfp);
- (void)remove(temp);
- free(temp);
- zip_error_set(&ctx->error, ZIP_ER_TMPOPEN, errno);
- }
-
- ctx->fout = tfp;
- ctx->tmpname = temp;
-
- return 0;
-}
-#endif
-
-
-static zip_int64_t
-read_file(void *state, void *data, zip_uint64_t len, zip_source_cmd_t cmd) {
- struct read_file *ctx;
- char *buf;
- zip_uint64_t n;
- size_t i;
-
- ctx = (struct read_file *)state;
- buf = (char *)data;
-
- switch (cmd) {
- case ZIP_SOURCE_BEGIN_WRITE:
- if (ctx->fname == NULL) {
- zip_error_set(&ctx->error, ZIP_ER_OPNOTSUPP, 0);
- return -1;
- }
- return create_temp_output(ctx);
-
-#ifdef CAN_CLONE
- case ZIP_SOURCE_BEGIN_WRITE_CLONING:
- if (ctx->fname == NULL) {
- zip_error_set(&ctx->error, ZIP_ER_OPNOTSUPP, 0);
- return -1;
- }
- return create_temp_output_cloning(ctx, len);
-#endif
-
- case ZIP_SOURCE_COMMIT_WRITE: {
- mode_t mode;
- struct stat st;
-
- if (fclose(ctx->fout) < 0) {
- ctx->fout = NULL;
- zip_error_set(&ctx->error, ZIP_ER_WRITE, errno);
- }
- ctx->fout = NULL;
- if (stat(ctx->fname, &st) == 0) {
- mode = st.st_mode;
- } else {
- mode_t mask = umask(022);
- umask(mask);
- mode = 0666 & ~mask;
- }
- if (rename(ctx->tmpname, ctx->fname) < 0) {
- zip_error_set(&ctx->error, ZIP_ER_RENAME, errno);
- return -1;
- }
- /* not much we can do if chmod fails except make the whole commit fail */
- (void)chmod(ctx->fname, mode);
- free(ctx->tmpname);
- ctx->tmpname = NULL;
- return 0;
- }
-
- case ZIP_SOURCE_CLOSE:
- if (ctx->fname) {
- fclose(ctx->f);
- ctx->f = NULL;
- }
- return 0;
-
- case ZIP_SOURCE_ERROR:
- return zip_error_to_data(&ctx->error, data, len);
-
- case ZIP_SOURCE_FREE:
- free(ctx->fname);
- free(ctx->tmpname);
- if (ctx->f)
- fclose(ctx->f);
- free(ctx);
- return 0;
-
- case ZIP_SOURCE_OPEN:
- if (ctx->fname) {
- if ((ctx->f = fopen(ctx->fname, "rb")) == NULL) {
- zip_error_set(&ctx->error, ZIP_ER_OPEN, errno);
- return -1;
- }
- }
-
- if (ctx->start > 0) {
- if (_zip_fseek_u(ctx->f, ctx->start, SEEK_SET, &ctx->error) < 0) {
- /* TODO: skip by reading */
- return -1;
- }
- }
- ctx->current = 0;
- return 0;
-
- case ZIP_SOURCE_READ:
- if (ctx->end > 0) {
- n = ctx->end - ctx->current;
- if (n > len) {
- n = len;
- }
- }
- else {
- n = len;
- }
-
- if (n > SIZE_MAX)
- n = SIZE_MAX;
-
- if ((i = fread(buf, 1, (size_t)n, ctx->f)) == 0) {
- if (ferror(ctx->f)) {
- zip_error_set(&ctx->error, ZIP_ER_READ, errno);
- return -1;
- }
- }
- ctx->current += i;
-
- return (zip_int64_t)i;
-
- case ZIP_SOURCE_REMOVE:
- if (remove(ctx->fname) < 0) {
- zip_error_set(&ctx->error, ZIP_ER_REMOVE, errno);
- return -1;
- }
- return 0;
-
- case ZIP_SOURCE_ROLLBACK_WRITE:
- if (ctx->fout) {
- fclose(ctx->fout);
- ctx->fout = NULL;
- }
- (void)remove(ctx->tmpname);
- free(ctx->tmpname);
- ctx->tmpname = NULL;
- return 0;
-
- case ZIP_SOURCE_SEEK: {
- zip_int64_t new_current;
- int need_seek;
- zip_source_args_seek_t *args = ZIP_SOURCE_GET_ARGS(zip_source_args_seek_t, data, len, &ctx->error);
-
- if (args == NULL)
- return -1;
-
- need_seek = 1;
-
- switch (args->whence) {
- case SEEK_SET:
- new_current = args->offset;
- break;
-
- case SEEK_END:
- if (ctx->end == 0) {
- if (_zip_fseek(ctx->f, args->offset, SEEK_END, &ctx->error) < 0) {
- return -1;
- }
- if ((new_current = ftello(ctx->f)) < 0) {
- zip_error_set(&ctx->error, ZIP_ER_SEEK, errno);
- return -1;
- }
- new_current -= (zip_int64_t)ctx->start;
- need_seek = 0;
- }
- else {
- new_current = (zip_int64_t)ctx->end + args->offset;
- }
- break;
-
- case SEEK_CUR:
- new_current = (zip_int64_t)ctx->current + args->offset;
- break;
-
- default:
- zip_error_set(&ctx->error, ZIP_ER_INVAL, 0);
- return -1;
- }
-
- if (new_current < 0 || (ctx->end != 0 && (zip_uint64_t)new_current > ctx->end) || (zip_uint64_t)new_current + ctx->start < ctx->start) {
- zip_error_set(&ctx->error, ZIP_ER_INVAL, 0);
- return -1;
- }
-
- ctx->current = (zip_uint64_t)new_current;
-
- if (need_seek) {
- if (_zip_fseek_u(ctx->f, ctx->current + ctx->start, SEEK_SET, &ctx->error) < 0) {
- return -1;
- }
- }
- return 0;
- }
-
- case ZIP_SOURCE_SEEK_WRITE: {
- zip_source_args_seek_t *args;
-
- args = ZIP_SOURCE_GET_ARGS(zip_source_args_seek_t, data, len, &ctx->error);
- if (args == NULL) {
- return -1;
- }
-
- if (_zip_fseek(ctx->fout, args->offset, args->whence, &ctx->error) < 0) {
- return -1;
- }
- return 0;
- }
-
- case ZIP_SOURCE_STAT: {
- if (len < sizeof(ctx->st))
- return -1;
-
- if (zip_error_code_zip(&ctx->stat_error) != 0) {
- zip_error_set(&ctx->error, zip_error_code_zip(&ctx->stat_error), zip_error_code_system(&ctx->stat_error));
- return -1;
- }
-
- memcpy(data, &ctx->st, sizeof(ctx->st));
- return sizeof(ctx->st);
- }
-
- case ZIP_SOURCE_SUPPORTS:
- return ctx->supports;
-
- case ZIP_SOURCE_TELL:
- return (zip_int64_t)ctx->current;
-
- case ZIP_SOURCE_TELL_WRITE: {
- off_t ret = ftello(ctx->fout);
-
- if (ret < 0) {
- zip_error_set(&ctx->error, ZIP_ER_TELL, errno);
- return -1;
- }
- return ret;
- }
-
- case ZIP_SOURCE_WRITE: {
- size_t ret;
-
- clearerr(ctx->fout);
- ret = fwrite(data, 1, len, ctx->fout);
- if (ret != len || ferror(ctx->fout)) {
- zip_error_set(&ctx->error, ZIP_ER_WRITE, errno);
- return -1;
- }
-
- return (zip_int64_t)ret;
- }
-
- default:
- zip_error_set(&ctx->error, ZIP_ER_OPNOTSUPP, 0);
- return -1;
- }
-}
-
-
-static int
-_zip_fseek_u(FILE *f, zip_uint64_t offset, int whence, zip_error_t *error) {
- if (offset > ZIP_INT64_MAX) {
- zip_error_set(error, ZIP_ER_SEEK, EOVERFLOW);
- return -1;
- }
- return _zip_fseek(f, (zip_int64_t)offset, whence, error);
-}
-
-
-static int
-_zip_fseek(FILE *f, zip_int64_t offset, int whence, zip_error_t *error) {
- if (offset > ZIP_FSEEK_MAX || offset < ZIP_FSEEK_MIN) {
- zip_error_set(error, ZIP_ER_SEEK, EOVERFLOW);
- return -1;
- }
- if (fseeko(f, (off_t)offset, whence) < 0) {
- zip_error_set(error, ZIP_ER_SEEK, errno);
- return -1;
- }
- return 0;
-}
diff --git a/src/Common/libzip/zip_source_free.c b/src/Common/libzip/zip_source_free.c
index dd3c6df..2f10ef8 100644
--- a/src/Common/libzip/zip_source_free.c
+++ b/src/Common/libzip/zip_source_free.c
@@ -1,6 +1,6 @@
/*
zip_source_free.c -- free zip data source
- Copyright (C) 1999-2018 Dieter Baron and Thomas Klausner
+ Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
diff --git a/src/Common/libzip/zip_source_function.c b/src/Common/libzip/zip_source_function.c
index c9730c9..d5c1b5b 100644
--- a/src/Common/libzip/zip_source_function.c
+++ b/src/Common/libzip/zip_source_function.c
@@ -1,6 +1,6 @@
/*
zip_source_function.c -- create zip data source from callback function
- Copyright (C) 1999-2018 Dieter Baron and Thomas Klausner
+ Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
diff --git a/src/Common/libzip/zip_source_get_file_attributes.c b/src/Common/libzip/zip_source_get_file_attributes.c
new file mode 100644
index 0000000..acbede1
--- /dev/null
+++ b/src/Common/libzip/zip_source_get_file_attributes.c
@@ -0,0 +1,104 @@
+/*
+ zip_source_get_file_attributes.c -- get attributes for file from source
+ Copyright (C) 2020 Dieter Baron and Thomas Klausner
+
+ This file is part of libzip, a library to manipulate ZIP archives.
+ The authors can be contacted at <libzip@nih.at>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+ 3. The names of the authors may not be used to endorse or promote
+ products derived from this software without specific prior
+ written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
+ OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "zipint.h"
+
+ZIP_EXTERN void
+zip_file_attributes_init(zip_file_attributes_t *attributes) {
+ attributes->valid = 0;
+ attributes->version = 1;
+}
+
+int
+zip_source_get_file_attributes(zip_source_t *src, zip_file_attributes_t *attributes) {
+ if (src->source_closed) {
+ return -1;
+ }
+ if (attributes == NULL) {
+ zip_error_set(&src->error, ZIP_ER_INVAL, 0);
+ return -1;
+ }
+
+ zip_file_attributes_init(attributes);
+
+ if (src->supports & ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_GET_FILE_ATTRIBUTES)) {
+ if (_zip_source_call(src, attributes, sizeof(*attributes), ZIP_SOURCE_GET_FILE_ATTRIBUTES) < 0) {
+ return -1;
+ }
+ }
+
+ if (ZIP_SOURCE_IS_LAYERED(src)) {
+ zip_file_attributes_t lower_attributes;
+
+ if (zip_source_get_file_attributes(src->src, &lower_attributes) < 0) {
+ _zip_error_set_from_source(&src->error, src->src);
+ return -1;
+ }
+
+ if ((lower_attributes.valid & ZIP_FILE_ATTRIBUTES_HOST_SYSTEM) && (attributes->valid & ZIP_FILE_ATTRIBUTES_HOST_SYSTEM) == 0) {
+ attributes->host_system = lower_attributes.host_system;
+ attributes->valid |= ZIP_FILE_ATTRIBUTES_HOST_SYSTEM;
+ }
+ if ((lower_attributes.valid & ZIP_FILE_ATTRIBUTES_ASCII) && (attributes->valid & ZIP_FILE_ATTRIBUTES_ASCII) == 0) {
+ attributes->ascii = lower_attributes.ascii;
+ attributes->valid |= ZIP_FILE_ATTRIBUTES_ASCII;
+ }
+ if ((lower_attributes.valid & ZIP_FILE_ATTRIBUTES_VERSION_NEEDED)) {
+ if (attributes->valid & ZIP_FILE_ATTRIBUTES_VERSION_NEEDED) {
+ attributes->version_needed = ZIP_MAX(lower_attributes.version_needed, attributes->version_needed);
+ }
+ else {
+ attributes->version_needed = lower_attributes.version_needed;
+ attributes->valid |= ZIP_FILE_ATTRIBUTES_VERSION_NEEDED;
+ }
+ }
+ if ((lower_attributes.valid & ZIP_FILE_ATTRIBUTES_EXTERNAL_FILE_ATTRIBUTES) && (attributes->valid & ZIP_FILE_ATTRIBUTES_EXTERNAL_FILE_ATTRIBUTES) == 0) {
+ attributes->external_file_attributes = lower_attributes.external_file_attributes;
+ attributes->valid |= ZIP_FILE_ATTRIBUTES_EXTERNAL_FILE_ATTRIBUTES;
+ }
+ if ((lower_attributes.valid & ZIP_FILE_ATTRIBUTES_GENERAL_PURPOSE_BIT_FLAGS)) {
+ if (attributes->valid & ZIP_FILE_ATTRIBUTES_GENERAL_PURPOSE_BIT_FLAGS) {
+ attributes->general_purpose_bit_flags &= ~lower_attributes.general_purpose_bit_mask;
+ attributes->general_purpose_bit_flags |= lower_attributes.general_purpose_bit_flags & lower_attributes.general_purpose_bit_mask;
+ attributes->general_purpose_bit_mask |= lower_attributes.general_purpose_bit_mask;
+ }
+ else {
+ attributes->valid |= ZIP_FILE_ATTRIBUTES_GENERAL_PURPOSE_BIT_FLAGS;
+ attributes->general_purpose_bit_flags = lower_attributes.general_purpose_bit_flags;
+ attributes->general_purpose_bit_mask = lower_attributes.general_purpose_bit_mask;
+ }
+ }
+ }
+
+ return 0;
+}
diff --git a/src/Common/libzip/zip_source_is_deleted.c b/src/Common/libzip/zip_source_is_deleted.c
index 090a67b..edd10ca 100644
--- a/src/Common/libzip/zip_source_is_deleted.c
+++ b/src/Common/libzip/zip_source_is_deleted.c
@@ -1,6 +1,6 @@
/*
zip_source_is_deleted.c -- was archive was removed?
- Copyright (C) 2014-2018 Dieter Baron and Thomas Klausner
+ Copyright (C) 2014-2019 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
diff --git a/src/Common/libzip/zip_source_layered.c b/src/Common/libzip/zip_source_layered.c
index 580bff0..d02bc85 100644
--- a/src/Common/libzip/zip_source_layered.c
+++ b/src/Common/libzip/zip_source_layered.c
@@ -1,6 +1,6 @@
/*
zip_source_layered.c -- create layered source
- Copyright (C) 2009-2018 Dieter Baron and Thomas Klausner
+ Copyright (C) 2009-2019 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
diff --git a/src/Common/libzip/zip_source_open.c b/src/Common/libzip/zip_source_open.c
index d10a3c5..414c677 100644
--- a/src/Common/libzip/zip_source_open.c
+++ b/src/Common/libzip/zip_source_open.c
@@ -1,6 +1,6 @@
/*
zip_source_open.c -- open zip_source (prepare for reading)
- Copyright (C) 2009-2018 Dieter Baron and Thomas Klausner
+ Copyright (C) 2009-2019 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
diff --git a/src/Common/libzip/zip_source_pkware.c b/src/Common/libzip/zip_source_pkware_decode.c
index cc510ea..c85b590 100644
--- a/src/Common/libzip/zip_source_pkware.c
+++ b/src/Common/libzip/zip_source_pkware_decode.c
@@ -1,6 +1,6 @@
/*
- zip_source_pkware.c -- Traditional PKWARE de/encryption routines
- Copyright (C) 2009-2018 Dieter Baron and Thomas Klausner
+ zip_source_pkware_decode.c -- Traditional PKWARE decryption routines
+ Copyright (C) 2009-2020 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
@@ -38,24 +38,20 @@
#include "zipint.h"
struct trad_pkware {
+ char *password;
+ zip_pkware_keys_t keys;
zip_error_t error;
- zip_uint32_t key[3];
};
-#define HEADERLEN 12
-#define KEY0 305419896
-#define KEY1 591751049
-#define KEY2 878082192
-
-static void decrypt(struct trad_pkware *, zip_uint8_t *, const zip_uint8_t *, zip_uint64_t, int);
static int decrypt_header(zip_source_t *, struct trad_pkware *);
static zip_int64_t pkware_decrypt(zip_source_t *, void *, void *, zip_uint64_t, zip_source_cmd_t);
-static void pkware_free(struct trad_pkware *);
+static struct trad_pkware *trad_pkware_new(const char *password, zip_error_t *error);
+static void trad_pkware_free(struct trad_pkware *);
zip_source_t *
-zip_source_pkware(zip_t *za, zip_source_t *src, zip_uint16_t em, int flags, const char *password) {
+zip_source_pkware_decode(zip_t *za, zip_source_t *src, zip_uint16_t em, int flags, const char *password) {
struct trad_pkware *ctx;
zip_source_t *s2;
@@ -68,20 +64,12 @@ zip_source_pkware(zip_t *za, zip_source_t *src, zip_uint16_t em, int flags, cons
return NULL;
}
- if ((ctx = (struct trad_pkware *)malloc(sizeof(*ctx))) == NULL) {
- zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
+ if ((ctx = trad_pkware_new(password, &za->error)) == NULL) {
return NULL;
}
- zip_error_init(&ctx->error);
-
- ctx->key[0] = KEY0;
- ctx->key[1] = KEY1;
- ctx->key[2] = KEY2;
- decrypt(ctx, NULL, (const zip_uint8_t *)password, strlen(password), 1);
-
if ((s2 = zip_source_layered(za, src, pkware_decrypt, ctx)) == NULL) {
- pkware_free(ctx);
+ trad_pkware_free(ctx);
return NULL;
}
@@ -89,62 +77,52 @@ zip_source_pkware(zip_t *za, zip_source_t *src, zip_uint16_t em, int flags, cons
}
-static void
-decrypt(struct trad_pkware *ctx, zip_uint8_t *out, const zip_uint8_t *in, zip_uint64_t len, int update_only) {
- zip_uint16_t tmp;
- zip_uint64_t i;
- Bytef b;
-
- for (i = 0; i < len; i++) {
- b = in[i];
-
- if (!update_only) {
- /* decrypt next byte */
- tmp = (zip_uint16_t)(ctx->key[2] | 2);
- tmp = (zip_uint16_t)(((zip_uint32_t)tmp * (tmp ^ 1)) >> 8);
- b ^= (Bytef)tmp;
- }
-
- /* store cleartext */
- if (out)
- out[i] = b;
-
- /* update keys */
- ctx->key[0] = (zip_uint32_t)crc32(ctx->key[0] ^ 0xffffffffUL, &b, 1) ^ 0xffffffffUL;
- ctx->key[1] = (ctx->key[1] + (ctx->key[0] & 0xff)) * 134775813 + 1;
- b = (Bytef)(ctx->key[1] >> 24);
- ctx->key[2] = (zip_uint32_t)crc32(ctx->key[2] ^ 0xffffffffUL, &b, 1) ^ 0xffffffffUL;
- }
-}
-
-
static int
decrypt_header(zip_source_t *src, struct trad_pkware *ctx) {
- zip_uint8_t header[HEADERLEN];
+ zip_uint8_t header[ZIP_CRYPTO_PKWARE_HEADERLEN];
struct zip_stat st;
zip_int64_t n;
- unsigned short dostime, dosdate;
+ bool ok;
- if ((n = zip_source_read(src, header, HEADERLEN)) < 0) {
+ if ((n = zip_source_read(src, header, ZIP_CRYPTO_PKWARE_HEADERLEN)) < 0) {
_zip_error_set_from_source(&ctx->error, src);
return -1;
}
- if (n != HEADERLEN) {
+ if (n != ZIP_CRYPTO_PKWARE_HEADERLEN) {
zip_error_set(&ctx->error, ZIP_ER_EOF, 0);
return -1;
}
- decrypt(ctx, header, header, HEADERLEN, 0);
+ _zip_pkware_decrypt(&ctx->keys, header, header, ZIP_CRYPTO_PKWARE_HEADERLEN);
- if (zip_source_stat(src, &st) < 0) {
+ if (zip_source_stat(src, &st)) {
/* stat failed, skip password validation */
return 0;
}
- _zip_u2d_time(st.mtime, &dostime, &dosdate);
+ /* password verification - two ways:
+ * mtime - InfoZIP way, to avoid computing complete CRC before encrypting data
+ * CRC - old PKWare way
+ */
+
+ ok = false;
+
+ if (st.valid & ZIP_STAT_MTIME) {
+ unsigned short dostime, dosdate;
+ _zip_u2d_time(st.mtime, &dostime, &dosdate);
+ if (header[ZIP_CRYPTO_PKWARE_HEADERLEN - 1] == dostime >> 8) {
+ ok = true;
+ }
+ }
+
+ if (st.valid & ZIP_STAT_CRC) {
+ if (header[ZIP_CRYPTO_PKWARE_HEADERLEN - 1] == st.crc >> 24) {
+ ok = true;
+ }
+ }
- if (header[HEADERLEN - 1] != st.crc >> 24 && header[HEADERLEN - 1] != dostime >> 8) {
+ if (!ok && ((st.valid & (ZIP_STAT_MTIME | ZIP_STAT_CRC)) != 0)) {
zip_error_set(&ctx->error, ZIP_ER_WRONGPASSWD, 0);
return -1;
}
@@ -162,8 +140,11 @@ pkware_decrypt(zip_source_t *src, void *ud, void *data, zip_uint64_t len, zip_so
switch (cmd) {
case ZIP_SOURCE_OPEN:
- if (decrypt_header(src, ctx) < 0)
+ _zip_pkware_keys_reset(&ctx->keys);
+ _zip_pkware_decrypt(&ctx->keys, NULL, (const zip_uint8_t *)ctx->password, strlen(ctx->password));
+ if (decrypt_header(src, ctx) < 0) {
return -1;
+ }
return 0;
case ZIP_SOURCE_READ:
@@ -172,7 +153,7 @@ pkware_decrypt(zip_source_t *src, void *ud, void *data, zip_uint64_t len, zip_so
return -1;
}
- decrypt((struct trad_pkware *)ud, (zip_uint8_t *)data, (zip_uint8_t *)data, (zip_uint64_t)n, 0);
+ _zip_pkware_decrypt(&ctx->keys, (zip_uint8_t *)data, (zip_uint8_t *)data, (zip_uint64_t)n);
return n;
case ZIP_SOURCE_CLOSE:
@@ -185,9 +166,9 @@ pkware_decrypt(zip_source_t *src, void *ud, void *data, zip_uint64_t len, zip_so
st->encryption_method = ZIP_EM_NONE;
st->valid |= ZIP_STAT_ENCRYPTION_METHOD;
- /* TODO: deduce HEADERLEN from size for uncompressed */
- if (st->valid & ZIP_STAT_COMP_SIZE)
- st->comp_size -= HEADERLEN;
+ if (st->valid & ZIP_STAT_COMP_SIZE) {
+ st->comp_size -= ZIP_CRYPTO_PKWARE_HEADERLEN;
+ }
return 0;
}
@@ -199,7 +180,7 @@ pkware_decrypt(zip_source_t *src, void *ud, void *data, zip_uint64_t len, zip_so
return zip_error_to_data(&ctx->error, data, len);
case ZIP_SOURCE_FREE:
- pkware_free(ctx);
+ trad_pkware_free(ctx);
return 0;
default:
@@ -209,7 +190,33 @@ pkware_decrypt(zip_source_t *src, void *ud, void *data, zip_uint64_t len, zip_so
}
+static struct trad_pkware *
+trad_pkware_new(const char *password, zip_error_t *error) {
+ struct trad_pkware *ctx;
+
+ if ((ctx = (struct trad_pkware *)malloc(sizeof(*ctx))) == NULL) {
+ zip_error_set(error, ZIP_ER_MEMORY, 0);
+ return NULL;
+ }
+
+ if ((ctx->password = strdup(password)) == NULL) {
+ zip_error_set(error, ZIP_ER_MEMORY, 0);
+ free(ctx);
+ return NULL;
+ }
+
+ zip_error_init(&ctx->error);
+
+ return ctx;
+}
+
+
static void
-pkware_free(struct trad_pkware *ctx) {
+trad_pkware_free(struct trad_pkware *ctx) {
+ if (ctx == NULL) {
+ return;
+ }
+
+ free(ctx->password);
free(ctx);
}
diff --git a/src/Common/libzip/zip_source_pkware_encode.c b/src/Common/libzip/zip_source_pkware_encode.c
new file mode 100644
index 0000000..1e8f42c
--- /dev/null
+++ b/src/Common/libzip/zip_source_pkware_encode.c
@@ -0,0 +1,249 @@
+/*
+ zip_source_pkware_encode.c -- Traditional PKWARE encryption routines
+ Copyright (C) 2009-2020 Dieter Baron and Thomas Klausner
+
+ This file is part of libzip, a library to manipulate ZIP archives.
+ The authors can be contacted at <libzip@nih.at>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+ 3. The names of the authors may not be used to endorse or promote
+ products derived from this software without specific prior
+ written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
+ OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "zipint.h"
+
+struct trad_pkware {
+ char *password;
+ zip_pkware_keys_t keys;
+ zip_buffer_t *buffer;
+ bool eof;
+ zip_error_t error;
+};
+
+
+static int encrypt_header(zip_source_t *, struct trad_pkware *);
+static zip_int64_t pkware_encrypt(zip_source_t *, void *, void *, zip_uint64_t, zip_source_cmd_t);
+static void trad_pkware_free(struct trad_pkware *);
+static struct trad_pkware *trad_pkware_new(const char *password, zip_error_t *error);
+
+
+zip_source_t *
+zip_source_pkware_encode(zip_t *za, zip_source_t *src, zip_uint16_t em, int flags, const char *password) {
+ struct trad_pkware *ctx;
+ zip_source_t *s2;
+
+ if (password == NULL || src == NULL || em != ZIP_EM_TRAD_PKWARE) {
+ zip_error_set(&za->error, ZIP_ER_INVAL, 0);
+ return NULL;
+ }
+ if (!(flags & ZIP_CODEC_ENCODE)) {
+ zip_error_set(&za->error, ZIP_ER_ENCRNOTSUPP, 0);
+ return NULL;
+ }
+
+ if ((ctx = trad_pkware_new(password, &za->error)) == NULL) {
+ return NULL;
+ }
+
+ if ((s2 = zip_source_layered(za, src, pkware_encrypt, ctx)) == NULL) {
+ trad_pkware_free(ctx);
+ return NULL;
+ }
+
+ return s2;
+}
+
+
+static int
+encrypt_header(zip_source_t *src, struct trad_pkware *ctx) {
+ struct zip_stat st;
+ unsigned short dostime, dosdate;
+ zip_uint8_t *header;
+
+ if (zip_source_stat(src, &st) != 0) {
+ _zip_error_set_from_source(&ctx->error, src);
+ return -1;
+ }
+
+ _zip_u2d_time(st.mtime, &dostime, &dosdate);
+
+ if ((ctx->buffer = _zip_buffer_new(NULL, ZIP_CRYPTO_PKWARE_HEADERLEN)) == NULL) {
+ zip_error_set(&ctx->error, ZIP_ER_MEMORY, 0);
+ return -1;
+ }
+
+ header = _zip_buffer_data(ctx->buffer);
+
+ /* generate header from random bytes and mtime
+ see appnote.iz, XIII. Decryption, Step 2, last paragraph */
+ if (!zip_secure_random(header, ZIP_CRYPTO_PKWARE_HEADERLEN - 1)) {
+ zip_error_set(&ctx->error, ZIP_ER_INTERNAL, 0);
+ _zip_buffer_free(ctx->buffer);
+ ctx->buffer = NULL;
+ return -1;
+ }
+ header[ZIP_CRYPTO_PKWARE_HEADERLEN - 1] = (zip_uint8_t)((dostime >> 8) & 0xff);
+
+ _zip_pkware_encrypt(&ctx->keys, header, header, ZIP_CRYPTO_PKWARE_HEADERLEN);
+
+ return 0;
+}
+
+
+static zip_int64_t
+pkware_encrypt(zip_source_t *src, void *ud, void *data, zip_uint64_t length, zip_source_cmd_t cmd) {
+ struct trad_pkware *ctx;
+ zip_int64_t n;
+ zip_uint64_t buffer_n;
+
+ ctx = (struct trad_pkware *)ud;
+
+ switch (cmd) {
+ case ZIP_SOURCE_OPEN:
+ ctx->eof = false;
+
+ /* initialize keys */
+ _zip_pkware_keys_reset(&ctx->keys);
+ _zip_pkware_encrypt(&ctx->keys, NULL, (const zip_uint8_t *)ctx->password, strlen(ctx->password));
+
+ if (encrypt_header(src, ctx) < 0) {
+ return -1;
+ }
+ return 0;
+
+ case ZIP_SOURCE_READ:
+ buffer_n = 0;
+
+ if (ctx->buffer) {
+ /* write header values to data */
+ buffer_n = _zip_buffer_read(ctx->buffer, data, length);
+ data = (zip_uint8_t *)data + buffer_n;
+ length -= buffer_n;
+
+ if (_zip_buffer_eof(ctx->buffer)) {
+ _zip_buffer_free(ctx->buffer);
+ ctx->buffer = NULL;
+ }
+ }
+
+ if (ctx->eof) {
+ return (zip_int64_t)buffer_n;
+ }
+
+ if ((n = zip_source_read(src, data, length)) < 0) {
+ _zip_error_set_from_source(&ctx->error, src);
+ return -1;
+ }
+
+ _zip_pkware_encrypt(&ctx->keys, (zip_uint8_t *)data, (zip_uint8_t *)data, (zip_uint64_t)n);
+
+ if ((zip_uint64_t)n < length) {
+ ctx->eof = true;
+ }
+
+ return (zip_int64_t)buffer_n + n;
+
+ case ZIP_SOURCE_CLOSE:
+ _zip_buffer_free(ctx->buffer);
+ ctx->buffer = NULL;
+ return 0;
+
+ case ZIP_SOURCE_STAT: {
+ zip_stat_t *st;
+
+ st = (zip_stat_t *)data;
+ st->encryption_method = ZIP_EM_TRAD_PKWARE;
+ st->valid |= ZIP_STAT_ENCRYPTION_METHOD;
+ if (st->valid & ZIP_STAT_COMP_SIZE) {
+ st->comp_size += ZIP_CRYPTO_PKWARE_HEADERLEN;
+ }
+
+ return 0;
+ }
+
+ case ZIP_SOURCE_GET_FILE_ATTRIBUTES: {
+ zip_file_attributes_t *attributes = (zip_file_attributes_t *)data;
+ if (length < sizeof(*attributes)) {
+ zip_error_set(&ctx->error, ZIP_ER_INVAL, 0);
+ return -1;
+ }
+ attributes->valid |= ZIP_FILE_ATTRIBUTES_VERSION_NEEDED;
+ attributes->version_needed = 20;
+
+ return 0;
+ }
+
+ case ZIP_SOURCE_SUPPORTS:
+ return zip_source_make_command_bitmap(ZIP_SOURCE_OPEN, ZIP_SOURCE_READ, ZIP_SOURCE_CLOSE, ZIP_SOURCE_STAT, ZIP_SOURCE_ERROR, ZIP_SOURCE_FREE, ZIP_SOURCE_GET_FILE_ATTRIBUTES, -1);
+
+ case ZIP_SOURCE_ERROR:
+ return zip_error_to_data(&ctx->error, data, length);
+
+ case ZIP_SOURCE_FREE:
+ trad_pkware_free(ctx);
+ return 0;
+
+ default:
+ zip_error_set(&ctx->error, ZIP_ER_INVAL, 0);
+ return -1;
+ }
+}
+
+
+static struct trad_pkware *
+trad_pkware_new(const char *password, zip_error_t *error) {
+ struct trad_pkware *ctx;
+
+ if ((ctx = (struct trad_pkware *)malloc(sizeof(*ctx))) == NULL) {
+ zip_error_set(error, ZIP_ER_MEMORY, 0);
+ return NULL;
+ }
+
+ if ((ctx->password = strdup(password)) == NULL) {
+ zip_error_set(error, ZIP_ER_MEMORY, 0);
+ free(ctx);
+ return NULL;
+ }
+ ctx->buffer = NULL;
+ zip_error_init(&ctx->error);
+
+ return ctx;
+}
+
+
+static void
+trad_pkware_free(struct trad_pkware *ctx) {
+ if (ctx == NULL) {
+ return;
+ }
+
+ free(ctx->password);
+ _zip_buffer_free(ctx->buffer);
+ zip_error_fini(&ctx->error);
+ free(ctx);
+}
diff --git a/src/Common/libzip/zip_source_read.c b/src/Common/libzip/zip_source_read.c
index 816fb3d..33088cb 100644
--- a/src/Common/libzip/zip_source_read.c
+++ b/src/Common/libzip/zip_source_read.c
@@ -1,6 +1,6 @@
/*
zip_source_read.c -- read data from zip_source
- Copyright (C) 2009-2018 Dieter Baron and Thomas Klausner
+ Copyright (C) 2009-2019 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
diff --git a/src/Common/libzip/zip_source_remove.c b/src/Common/libzip/zip_source_remove.c
index 6841b74..14eddb8 100644
--- a/src/Common/libzip/zip_source_remove.c
+++ b/src/Common/libzip/zip_source_remove.c
@@ -1,6 +1,6 @@
/*
zip_source_remove.c -- remove empty archive
- Copyright (C) 2014-2018 Dieter Baron and Thomas Klausner
+ Copyright (C) 2014-2019 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
diff --git a/src/Common/libzip/zip_source_rollback_write.c b/src/Common/libzip/zip_source_rollback_write.c
index 04aa938..e8259bf 100644
--- a/src/Common/libzip/zip_source_rollback_write.c
+++ b/src/Common/libzip/zip_source_rollback_write.c
@@ -1,6 +1,6 @@
/*
zip_source_rollback_write.c -- discard changes
- Copyright (C) 2014-2018 Dieter Baron and Thomas Klausner
+ Copyright (C) 2014-2019 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
diff --git a/src/Common/libzip/zip_source_seek.c b/src/Common/libzip/zip_source_seek.c
index c7bd8e6..163daf1 100644
--- a/src/Common/libzip/zip_source_seek.c
+++ b/src/Common/libzip/zip_source_seek.c
@@ -1,6 +1,6 @@
/*
zip_source_seek.c -- seek to offset
- Copyright (C) 2014-2018 Dieter Baron and Thomas Klausner
+ Copyright (C) 2014-2019 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
diff --git a/src/Common/libzip/zip_source_seek_write.c b/src/Common/libzip/zip_source_seek_write.c
index a20dc82..6b0aa78 100644
--- a/src/Common/libzip/zip_source_seek_write.c
+++ b/src/Common/libzip/zip_source_seek_write.c
@@ -1,6 +1,6 @@
/*
zip_source_seek_write.c -- seek to offset for writing
- Copyright (C) 2014-2018 Dieter Baron and Thomas Klausner
+ Copyright (C) 2014-2019 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
diff --git a/src/Common/libzip/zip_source_stat.c b/src/Common/libzip/zip_source_stat.c
index f3af3be..3421d2c 100644
--- a/src/Common/libzip/zip_source_stat.c
+++ b/src/Common/libzip/zip_source_stat.c
@@ -1,6 +1,6 @@
/*
zip_source_stat.c -- get meta information from zip_source
- Copyright (C) 2009-2018 Dieter Baron and Thomas Klausner
+ Copyright (C) 2009-2019 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
diff --git a/src/Common/libzip/zip_source_supports.c b/src/Common/libzip/zip_source_supports.c
index 394f06e..8471559 100644
--- a/src/Common/libzip/zip_source_supports.c
+++ b/src/Common/libzip/zip_source_supports.c
@@ -1,6 +1,6 @@
/*
zip_source_supports.c -- check for supported functions
- Copyright (C) 2014-2018 Dieter Baron and Thomas Klausner
+ Copyright (C) 2014-2019 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
diff --git a/src/Common/libzip/zip_source_tell.c b/src/Common/libzip/zip_source_tell.c
index da13cf5..772e252 100644
--- a/src/Common/libzip/zip_source_tell.c
+++ b/src/Common/libzip/zip_source_tell.c
@@ -1,6 +1,6 @@
/*
zip_source_tell.c -- report current offset
- Copyright (C) 2014-2018 Dieter Baron and Thomas Klausner
+ Copyright (C) 2014-2019 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
diff --git a/src/Common/libzip/zip_source_tell_write.c b/src/Common/libzip/zip_source_tell_write.c
index d20139f..96ad7e2 100644
--- a/src/Common/libzip/zip_source_tell_write.c
+++ b/src/Common/libzip/zip_source_tell_write.c
@@ -1,6 +1,6 @@
/*
zip_source_tell_write.c -- report current offset for writing
- Copyright (C) 2014-2018 Dieter Baron and Thomas Klausner
+ Copyright (C) 2014-2019 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
diff --git a/src/Common/libzip/zip_source_win32a.c b/src/Common/libzip/zip_source_win32a.c
deleted file mode 100644
index b4b060a..0000000
--- a/src/Common/libzip/zip_source_win32a.c
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- zip_source_win32a.c -- create data source from Windows file (ANSI)
- Copyright (C) 1999-2018 Dieter Baron and Thomas Klausner
-
- This file is part of libzip, a library to manipulate ZIP archives.
- The authors can be contacted at <libzip@nih.at>
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
- 1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in
- the documentation and/or other materials provided with the
- distribution.
- 3. The names of the authors may not be used to endorse or promote
- products derived from this software without specific prior
- written permission.
-
- THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
- OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
- DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
- IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-/* 0x0501 => Windows XP; needs to be at least this value because of GetFileSizeEx */
-#if !defined(MS_UWP) && !defined(_WIN32_WINNT)
-#define _WIN32_WINNT 0x0501
-#endif
-#include <windows.h>
-
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "zipint.h"
-#include "zipwin32.h"
-
-static void *_win32_strdup_a(const void *str);
-static HANDLE _win32_open_a(_zip_source_win32_read_file_t *ctx);
-static HANDLE _win32_create_temp_a(_zip_source_win32_read_file_t *ctx, void **temp, zip_uint32_t value, PSECURITY_ATTRIBUTES sa);
-static int _win32_rename_temp_a(_zip_source_win32_read_file_t *ctx);
-static int _win32_remove_a(const void *fname);
-
-// clang-format off
-static _zip_source_win32_file_ops_t win32_ops_a = {
- _win32_strdup_a,
- _win32_open_a,
- _win32_create_temp_a,
- _win32_rename_temp_a,
- _win32_remove_a
-};
-// clang-format on
-
-ZIP_EXTERN zip_source_t *
-zip_source_win32a(zip_t *za, const char *fname, zip_uint64_t start, zip_int64_t len) {
- if (za == NULL)
- return NULL;
-
- return zip_source_win32a_create(fname, start, len, &za->error);
-}
-
-
-ZIP_EXTERN zip_source_t *
-zip_source_win32a_create(const char *fname, zip_uint64_t start, zip_int64_t length, zip_error_t *error) {
- if (fname == NULL || length < -1) {
- zip_error_set(error, ZIP_ER_INVAL, 0);
- return NULL;
- }
-
- return _zip_source_win32_handle_or_name(fname, INVALID_HANDLE_VALUE, start, length, 1, NULL, &win32_ops_a, error);
-}
-
-
-static void *
-_win32_strdup_a(const void *str) {
- return strdup((const char *)str);
-}
-
-
-static HANDLE
-_win32_open_a(_zip_source_win32_read_file_t *ctx) {
- return CreateFileA(ctx->fname, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
-}
-
-
-static HANDLE
-_win32_create_temp_a(_zip_source_win32_read_file_t *ctx, void **temp, zip_uint32_t value, PSECURITY_ATTRIBUTES sa) {
- size_t len;
-
- len = strlen((const char *)ctx->fname) + 10;
- if (*temp == NULL) {
- if ((*temp = malloc(sizeof(char) * len)) == NULL) {
- zip_error_set(&ctx->error, ZIP_ER_MEMORY, 0);
- return INVALID_HANDLE_VALUE;
- }
- }
- if (sprintf((char *)*temp, "%s.%08x", (const char *)ctx->fname, value) != len - 1) {
- return INVALID_HANDLE_VALUE;
- }
-
- return CreateFileA((const char *)*temp, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, sa, CREATE_NEW, FILE_ATTRIBUTE_NORMAL | FILE_ATTRIBUTE_TEMPORARY, NULL);
-}
-
-
-static int
-_win32_rename_temp_a(_zip_source_win32_read_file_t *ctx) {
- if (!MoveFileExA(ctx->tmpname, ctx->fname, MOVEFILE_REPLACE_EXISTING))
- return -1;
- return 0;
-}
-
-
-static int
-_win32_remove_a(const void *fname) {
- DeleteFileA((const char *)fname);
- return 0;
-}
diff --git a/src/Common/libzip/zip_source_win32handle.c b/src/Common/libzip/zip_source_win32handle.c
deleted file mode 100644
index 3a2f52e..0000000
--- a/src/Common/libzip/zip_source_win32handle.c
+++ /dev/null
@@ -1,597 +0,0 @@
-/*
- zip_source_win32file.c -- create data source from HANDLE (Win32)
- Copyright (C) 1999-2018 Dieter Baron and Thomas Klausner
-
- This file is part of libzip, a library to manipulate ZIP archives.
- The authors can be contacted at <libzip@nih.at>
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
- 1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in
- the documentation and/or other materials provided with the
- distribution.
- 3. The names of the authors may not be used to endorse or promote
- products derived from this software without specific prior
- written permission.
-
- THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
- OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
- DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
- IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-
-#include <aclapi.h>
-#include <stdlib.h>
-#include <string.h>
-#include <wchar.h>
-
-#include "zipint.h"
-#include "zipwin32.h"
-
-static zip_int64_t _win32_read_file(void *state, void *data, zip_uint64_t len, zip_source_cmd_t cmd);
-static int _win32_create_temp_file(_zip_source_win32_read_file_t *ctx);
-static int _zip_filetime_to_time_t(FILETIME ft, time_t *t);
-static int _zip_seek_win32_u(void *h, zip_uint64_t offset, int whence, zip_error_t *error);
-static int _zip_seek_win32(void *h, zip_int64_t offset, int whence, zip_error_t *error);
-static int _zip_win32_error_to_errno(unsigned long win32err);
-static int _zip_stat_win32(void *h, zip_stat_t *st, _zip_source_win32_read_file_t *ctx);
-
-ZIP_EXTERN zip_source_t *
-zip_source_win32handle(zip_t *za, HANDLE h, zip_uint64_t start, zip_int64_t len) {
- if (za == NULL)
- return NULL;
-
- return zip_source_win32handle_create(h, start, len, &za->error);
-}
-
-
-ZIP_EXTERN zip_source_t *
-zip_source_win32handle_create(HANDLE h, zip_uint64_t start, zip_int64_t length, zip_error_t *error) {
- if (h == INVALID_HANDLE_VALUE || length < -1) {
- zip_error_set(error, ZIP_ER_INVAL, 0);
- return NULL;
- }
-
- return _zip_source_win32_handle_or_name(NULL, h, start, length, 1, NULL, NULL, error);
-}
-
-
-zip_source_t *
-_zip_source_win32_handle_or_name(const void *fname, HANDLE h, zip_uint64_t start, zip_int64_t len, int closep, const zip_stat_t *st, _zip_source_win32_file_ops_t *ops, zip_error_t *error) {
- _zip_source_win32_read_file_t *ctx;
- zip_source_t *zs;
-
- if (h == INVALID_HANDLE_VALUE && fname == NULL) {
- zip_error_set(error, ZIP_ER_INVAL, 0);
- return NULL;
- }
-
- if ((ctx = (_zip_source_win32_read_file_t *)malloc(sizeof(_zip_source_win32_read_file_t))) == NULL) {
- zip_error_set(error, ZIP_ER_MEMORY, 0);
- return NULL;
- }
-
- ctx->fname = NULL;
- if (fname) {
- if ((ctx->fname = ops->op_strdup(fname)) == NULL) {
- zip_error_set(error, ZIP_ER_MEMORY, 0);
- free(ctx);
- return NULL;
- }
- }
-
- ctx->ops = ops;
- ctx->h = h;
- ctx->start = start;
- ctx->end = (len < 0 ? 0 : start + (zip_uint64_t)len);
- ctx->closep = ctx->fname ? 1 : closep;
- if (st) {
- memcpy(&ctx->st, st, sizeof(ctx->st));
- ctx->st.name = NULL;
- ctx->st.valid &= ~ZIP_STAT_NAME;
- }
- else {
- zip_stat_init(&ctx->st);
- }
-
- ctx->tmpname = NULL;
- ctx->hout = INVALID_HANDLE_VALUE;
-
- zip_error_init(&ctx->error);
-
- ctx->supports = ZIP_SOURCE_SUPPORTS_READABLE | zip_source_make_command_bitmap(ZIP_SOURCE_SUPPORTS, ZIP_SOURCE_TELL, -1);
- if (ctx->fname) {
- HANDLE th;
-
- th = ops->op_open(ctx);
- if (th == INVALID_HANDLE_VALUE || GetFileType(th) == FILE_TYPE_DISK) {
- ctx->supports = ZIP_SOURCE_SUPPORTS_WRITABLE;
- }
- if (th != INVALID_HANDLE_VALUE) {
- CloseHandle(th);
- }
- }
- else if (GetFileType(ctx->h) == FILE_TYPE_DISK) {
- ctx->supports = ZIP_SOURCE_SUPPORTS_SEEKABLE;
- }
-
- if ((zs = zip_source_function_create(_win32_read_file, ctx, error)) == NULL) {
- free(ctx->fname);
- free(ctx);
- return NULL;
- }
-
- return zs;
-}
-
-
-static zip_int64_t
-_win32_read_file(void *state, void *data, zip_uint64_t len, zip_source_cmd_t cmd) {
- _zip_source_win32_read_file_t *ctx;
- char *buf;
- zip_uint64_t n;
- DWORD i;
-
- ctx = (_zip_source_win32_read_file_t *)state;
- buf = (char *)data;
-
- switch (cmd) {
- case ZIP_SOURCE_BEGIN_WRITE:
- if (ctx->fname == NULL) {
- zip_error_set(&ctx->error, ZIP_ER_OPNOTSUPP, 0);
- return -1;
- }
- return _win32_create_temp_file(ctx);
-
- case ZIP_SOURCE_COMMIT_WRITE: {
- if (!CloseHandle(ctx->hout)) {
- ctx->hout = INVALID_HANDLE_VALUE;
- zip_error_set(&ctx->error, ZIP_ER_WRITE, _zip_win32_error_to_errno(GetLastError()));
- }
- ctx->hout = INVALID_HANDLE_VALUE;
- if (ctx->ops->op_rename_temp(ctx) < 0) {
- zip_error_set(&ctx->error, ZIP_ER_RENAME, _zip_win32_error_to_errno(GetLastError()));
- return -1;
- }
- free(ctx->tmpname);
- ctx->tmpname = NULL;
- return 0;
- }
-
- case ZIP_SOURCE_CLOSE:
- if (ctx->fname) {
- CloseHandle(ctx->h);
- ctx->h = INVALID_HANDLE_VALUE;
- }
- return 0;
-
- case ZIP_SOURCE_ERROR:
- return zip_error_to_data(&ctx->error, data, len);
-
- case ZIP_SOURCE_FREE:
- free(ctx->fname);
- free(ctx->tmpname);
- if (ctx->closep && ctx->h != INVALID_HANDLE_VALUE)
- CloseHandle(ctx->h);
- free(ctx);
- return 0;
-
- case ZIP_SOURCE_OPEN:
- if (ctx->fname) {
- if ((ctx->h = ctx->ops->op_open(ctx)) == INVALID_HANDLE_VALUE) {
- zip_error_set(&ctx->error, ZIP_ER_OPEN, _zip_win32_error_to_errno(GetLastError()));
- return -1;
- }
- }
-
- if (ctx->closep && ctx->start > 0) {
- if (_zip_seek_win32_u(ctx->h, ctx->start, SEEK_SET, &ctx->error) < 0) {
- return -1;
- }
- }
- ctx->current = ctx->start;
- return 0;
-
- case ZIP_SOURCE_READ:
- if (ctx->end > 0) {
- n = ctx->end - ctx->current;
- if (n > len) {
- n = len;
- }
- }
- else {
- n = len;
- }
-
- if (n > SIZE_MAX)
- n = SIZE_MAX;
-
- if (!ctx->closep) {
- if (_zip_seek_win32_u(ctx->h, ctx->current, SEEK_SET, &ctx->error) < 0) {
- return -1;
- }
- }
-
- if (!ReadFile(ctx->h, buf, (DWORD)n, &i, NULL)) {
- zip_error_set(&ctx->error, ZIP_ER_READ, _zip_win32_error_to_errno(GetLastError()));
- return -1;
- }
- ctx->current += i;
-
- return (zip_int64_t)i;
-
- case ZIP_SOURCE_REMOVE:
- if (ctx->ops->op_remove(ctx->fname) < 0) {
- zip_error_set(&ctx->error, ZIP_ER_REMOVE, _zip_win32_error_to_errno(GetLastError()));
- return -1;
- }
- return 0;
-
- case ZIP_SOURCE_ROLLBACK_WRITE:
- if (ctx->hout) {
- CloseHandle(ctx->hout);
- ctx->hout = INVALID_HANDLE_VALUE;
- }
- ctx->ops->op_remove(ctx->tmpname);
- free(ctx->tmpname);
- ctx->tmpname = NULL;
- return 0;
-
- case ZIP_SOURCE_SEEK: {
- zip_int64_t new_current;
- int need_seek;
- zip_source_args_seek_t *args = ZIP_SOURCE_GET_ARGS(zip_source_args_seek_t, data, len, &ctx->error);
-
- if (args == NULL)
- return -1;
-
- need_seek = ctx->closep;
-
- switch (args->whence) {
- case SEEK_SET:
- new_current = args->offset;
- break;
-
- case SEEK_END:
- if (ctx->end == 0) {
- LARGE_INTEGER zero;
- LARGE_INTEGER new_offset;
-
- if (_zip_seek_win32(ctx->h, args->offset, SEEK_END, &ctx->error) < 0) {
- return -1;
- }
- zero.QuadPart = 0;
- if (!SetFilePointerEx(ctx->h, zero, &new_offset, FILE_CURRENT)) {
- zip_error_set(&ctx->error, ZIP_ER_SEEK, _zip_win32_error_to_errno(GetLastError()));
- return -1;
- }
- new_current = new_offset.QuadPart;
- need_seek = 0;
- }
- else {
- new_current = (zip_int64_t)ctx->end + args->offset;
- }
- break;
- case SEEK_CUR:
- new_current = (zip_int64_t)ctx->current + args->offset;
- break;
-
- default:
- zip_error_set(&ctx->error, ZIP_ER_INVAL, 0);
- return -1;
- }
-
- if (new_current < 0 || (zip_uint64_t)new_current < ctx->start || (ctx->end != 0 && (zip_uint64_t)new_current > ctx->end)) {
- zip_error_set(&ctx->error, ZIP_ER_INVAL, 0);
- return -1;
- }
-
- ctx->current = (zip_uint64_t)new_current;
-
- if (need_seek) {
- if (_zip_seek_win32_u(ctx->h, ctx->current, SEEK_SET, &ctx->error) < 0) {
- return -1;
- }
- }
- return 0;
- }
-
- case ZIP_SOURCE_SEEK_WRITE: {
- zip_source_args_seek_t *args;
-
- args = ZIP_SOURCE_GET_ARGS(zip_source_args_seek_t, data, len, &ctx->error);
- if (args == NULL) {
- return -1;
- }
-
- if (_zip_seek_win32(ctx->hout, args->offset, args->whence, &ctx->error) < 0) {
- return -1;
- }
- return 0;
- }
-
- case ZIP_SOURCE_STAT: {
- if (len < sizeof(ctx->st))
- return -1;
-
- if (ctx->st.valid != 0)
- memcpy(data, &ctx->st, sizeof(ctx->st));
- else {
- DWORD win32err;
- zip_stat_t *st;
- HANDLE h;
- int success;
-
- st = (zip_stat_t *)data;
-
- if (ctx->h != INVALID_HANDLE_VALUE) {
- h = ctx->h;
- }
- else {
- h = ctx->ops->op_open(ctx);
- if (h == INVALID_HANDLE_VALUE) {
- win32err = GetLastError();
- if (win32err == ERROR_FILE_NOT_FOUND || win32err == ERROR_PATH_NOT_FOUND) {
- zip_error_set(&ctx->error, ZIP_ER_READ, ENOENT);
- return -1;
- }
- }
- }
-
- success = _zip_stat_win32(h, st, ctx);
- win32err = GetLastError();
-
- /* We're done with the handle, so close it if we just opened it. */
- if (h != ctx->h) {
- CloseHandle(h);
- }
-
- if (success < 0) {
- /* TODO: Is this the correct error to return in all cases? */
- zip_error_set(&ctx->error, ZIP_ER_READ, _zip_win32_error_to_errno(win32err));
- return -1;
- }
- }
- return sizeof(ctx->st);
- }
-
- case ZIP_SOURCE_SUPPORTS:
- return ctx->supports;
-
- case ZIP_SOURCE_TELL:
- return (zip_int64_t)ctx->current;
-
- case ZIP_SOURCE_TELL_WRITE: {
- LARGE_INTEGER zero;
- LARGE_INTEGER offset;
-
- zero.QuadPart = 0;
- if (!SetFilePointerEx(ctx->hout, zero, &offset, FILE_CURRENT)) {
- zip_error_set(&ctx->error, ZIP_ER_TELL, _zip_win32_error_to_errno(GetLastError()));
- return -1;
- }
-
- return offset.QuadPart;
- }
-
- case ZIP_SOURCE_WRITE: {
- DWORD ret;
- if (!WriteFile(ctx->hout, data, (DWORD)len, &ret, NULL) || ret != len) {
- zip_error_set(&ctx->error, ZIP_ER_WRITE, _zip_win32_error_to_errno(GetLastError()));
- return -1;
- }
-
- return (zip_int64_t)ret;
- }
-
- default:
- zip_error_set(&ctx->error, ZIP_ER_OPNOTSUPP, 0);
- return -1;
- }
-}
-
-
-static int
-_win32_create_temp_file(_zip_source_win32_read_file_t *ctx) {
- zip_uint32_t value;
- /*
- Windows has GetTempFileName(), but it closes the file after
- creation, leaving it open to a horrible race condition. So
- we reinvent the wheel.
- */
- int i;
- HANDLE th = INVALID_HANDLE_VALUE;
- void *temp = NULL;
- PSECURITY_DESCRIPTOR psd = NULL;
- PSECURITY_ATTRIBUTES psa = NULL;
- SECURITY_ATTRIBUTES sa;
- SECURITY_INFORMATION si;
- DWORD success;
- PACL dacl = NULL;
-
- /*
- Read the DACL from the original file, so we can copy it to the temp file.
- If there is no original file, or if we can't read the DACL, we'll use the
- default security descriptor.
- */
- if (ctx->h != INVALID_HANDLE_VALUE && GetFileType(ctx->h) == FILE_TYPE_DISK) {
- si = DACL_SECURITY_INFORMATION | UNPROTECTED_DACL_SECURITY_INFORMATION;
- success = GetSecurityInfo(ctx->h, SE_FILE_OBJECT, si, NULL, NULL, &dacl, NULL, &psd);
- if (success == ERROR_SUCCESS) {
- sa.nLength = sizeof(SECURITY_ATTRIBUTES);
- sa.bInheritHandle = FALSE;
- sa.lpSecurityDescriptor = psd;
- psa = &sa;
- }
- }
-
-
-#ifndef MS_UWP
- value = GetTickCount();
-#else
- value = (zip_uint32_t)GetTickCount64();
-#endif
-
- for (i = 0; i < 1024 && th == INVALID_HANDLE_VALUE; i++) {
- th = ctx->ops->op_create_temp(ctx, &temp, value + i, psa);
- if (th == INVALID_HANDLE_VALUE && GetLastError() != ERROR_FILE_EXISTS)
- break;
- }
-
- if (th == INVALID_HANDLE_VALUE) {
- free(temp);
- LocalFree(psd);
- zip_error_set(&ctx->error, ZIP_ER_TMPOPEN, _zip_win32_error_to_errno(GetLastError()));
- return -1;
- }
-
- LocalFree(psd);
- ctx->hout = th;
- ctx->tmpname = temp;
-
- return 0;
-}
-
-
-static int
-_zip_seek_win32_u(HANDLE h, zip_uint64_t offset, int whence, zip_error_t *error) {
- if (offset > ZIP_INT64_MAX) {
- zip_error_set(error, ZIP_ER_SEEK, EOVERFLOW);
- return -1;
- }
- return _zip_seek_win32(h, (zip_int64_t)offset, whence, error);
-}
-
-
-static int
-_zip_seek_win32(HANDLE h, zip_int64_t offset, int whence, zip_error_t *error) {
- LARGE_INTEGER li;
- DWORD method;
-
- switch (whence) {
- case SEEK_SET:
- method = FILE_BEGIN;
- break;
- case SEEK_END:
- method = FILE_END;
- break;
- case SEEK_CUR:
- method = FILE_CURRENT;
- break;
- default:
- zip_error_set(error, ZIP_ER_SEEK, EINVAL);
- return -1;
- }
-
- li.QuadPart = (LONGLONG)offset;
- if (!SetFilePointerEx(h, li, NULL, method)) {
- zip_error_set(error, ZIP_ER_SEEK, _zip_win32_error_to_errno(GetLastError()));
- return -1;
- }
-
- return 0;
-}
-
-
-static int
-_zip_win32_error_to_errno(DWORD win32err) {
- /*
- Note: This list isn't exhaustive, but should cover common cases.
- */
- switch (win32err) {
- case ERROR_INVALID_PARAMETER:
- return EINVAL;
- case ERROR_FILE_NOT_FOUND:
- return ENOENT;
- case ERROR_INVALID_HANDLE:
- return EBADF;
- case ERROR_ACCESS_DENIED:
- return EACCES;
- case ERROR_FILE_EXISTS:
- return EEXIST;
- case ERROR_TOO_MANY_OPEN_FILES:
- return EMFILE;
- case ERROR_DISK_FULL:
- return ENOSPC;
- default:
- return 0;
- }
-}
-
-
-static int
-_zip_stat_win32(HANDLE h, zip_stat_t *st, _zip_source_win32_read_file_t *ctx) {
- FILETIME mtimeft;
- time_t mtime;
- LARGE_INTEGER size;
- int regularp;
-
- if (!GetFileTime(h, NULL, NULL, &mtimeft)) {
- zip_error_set(&ctx->error, ZIP_ER_READ, _zip_win32_error_to_errno(GetLastError()));
- return -1;
- }
- if (_zip_filetime_to_time_t(mtimeft, &mtime) < 0) {
- zip_error_set(&ctx->error, ZIP_ER_READ, ERANGE);
- return -1;
- }
-
- regularp = 0;
- if (GetFileType(h) == FILE_TYPE_DISK) {
- regularp = 1;
- }
-
- if (!GetFileSizeEx(h, &size)) {
- zip_error_set(&ctx->error, ZIP_ER_READ, _zip_win32_error_to_errno(GetLastError()));
- return -1;
- }
-
- zip_stat_init(st);
- st->mtime = mtime;
- st->valid |= ZIP_STAT_MTIME;
- if (ctx->end != 0) {
- st->size = ctx->end - ctx->start;
- st->valid |= ZIP_STAT_SIZE;
- }
- else if (regularp) {
- st->size = (zip_uint64_t)size.QuadPart;
- st->valid |= ZIP_STAT_SIZE;
- }
-
- return 0;
-}
-
-
-static int
-_zip_filetime_to_time_t(FILETIME ft, time_t *t) {
- /*
- Inspired by http://stackoverflow.com/questions/6161776/convert-windows-filetime-to-second-in-unix-linux
- */
- const zip_int64_t WINDOWS_TICK = 10000000LL;
- const zip_int64_t SEC_TO_UNIX_EPOCH = 11644473600LL;
- ULARGE_INTEGER li;
- zip_int64_t secs;
- time_t temp;
-
- li.LowPart = ft.dwLowDateTime;
- li.HighPart = ft.dwHighDateTime;
- secs = (li.QuadPart / WINDOWS_TICK - SEC_TO_UNIX_EPOCH);
-
- temp = (time_t)secs;
- if (secs != (zip_int64_t)temp)
- return -1;
-
- *t = temp;
- return 0;
-}
diff --git a/src/Common/libzip/zip_source_win32w.c b/src/Common/libzip/zip_source_win32w.c
deleted file mode 100644
index 4097214..0000000
--- a/src/Common/libzip/zip_source_win32w.c
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
- zip_source_win32w.c -- create data source from Windows file (UTF-16)
- Copyright (C) 1999-2018 Dieter Baron and Thomas Klausner
-
- This file is part of libzip, a library to manipulate ZIP archives.
- The authors can be contacted at <libzip@nih.at>
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
- 1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in
- the documentation and/or other materials provided with the
- distribution.
- 3. The names of the authors may not be used to endorse or promote
- products derived from this software without specific prior
- written permission.
-
- THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
- OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
- DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
- IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-/* 0x0501 => Windows XP; needs to be at least this value because of GetFileSizeEx */
-#if !defined(MS_UWP) && !defined(_WIN32_WINNT)
-#define _WIN32_WINNT 0x0501
-#endif
-#include <windows.h>
-
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "zipint.h"
-#include "zipwin32.h"
-
-static void *_win32_strdup_w(const void *str);
-static HANDLE _win32_open_w(_zip_source_win32_read_file_t *ctx);
-static HANDLE _win32_create_temp_w(_zip_source_win32_read_file_t *ctx, void **temp, zip_uint32_t value, PSECURITY_ATTRIBUTES sa);
-static int _win32_rename_temp_w(_zip_source_win32_read_file_t *ctx);
-static int _win32_remove_w(const void *fname);
-
-// clang-format off
-static _zip_source_win32_file_ops_t win32_ops_w = {
- _win32_strdup_w,
- _win32_open_w,
- _win32_create_temp_w,
- _win32_rename_temp_w,
- _win32_remove_w
-};
-// clang-format on
-
-ZIP_EXTERN zip_source_t *
-zip_source_win32w(zip_t *za, const wchar_t *fname, zip_uint64_t start, zip_int64_t len) {
- if (za == NULL)
- return NULL;
-
- return zip_source_win32w_create(fname, start, len, &za->error);
-}
-
-
-ZIP_EXTERN zip_source_t *
-zip_source_win32w_create(const wchar_t *fname, zip_uint64_t start, zip_int64_t length, zip_error_t *error) {
- if (fname == NULL || length < -1) {
- zip_error_set(error, ZIP_ER_INVAL, 0);
- return NULL;
- }
-
- return _zip_source_win32_handle_or_name(fname, INVALID_HANDLE_VALUE, start, length, 1, NULL, &win32_ops_w, error);
-}
-
-
-static void *
-_win32_strdup_w(const void *str) {
- return _wcsdup((const wchar_t *)str);
-}
-
-
-static HANDLE
-_win32_open_w(_zip_source_win32_read_file_t *ctx) {
-#ifdef MS_UWP
- CREATEFILE2_EXTENDED_PARAMETERS extParams = {0};
- extParams.dwFileAttributes = FILE_ATTRIBUTE_NORMAL;
- extParams.dwFileFlags = FILE_FLAG_RANDOM_ACCESS;
- extParams.dwSecurityQosFlags = SECURITY_ANONYMOUS;
- extParams.dwSize = sizeof(extParams);
- extParams.hTemplateFile = NULL;
- extParams.lpSecurityAttributes = NULL;
-
- return CreateFile2(ctx->fname, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, OPEN_EXISTING, &extParams);
-#else
- return CreateFileW(ctx->fname, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
-#endif
-}
-
-
-static HANDLE
-_win32_create_temp_w(_zip_source_win32_read_file_t *ctx, void **temp, zip_uint32_t value, PSECURITY_ATTRIBUTES sa) {
- size_t len;
-
- len = wcslen((const wchar_t *)ctx->fname) + 10;
- if (*temp == NULL) {
- if ((*temp = malloc(sizeof(wchar_t) * len)) == NULL) {
- zip_error_set(&ctx->error, ZIP_ER_MEMORY, 0);
- return INVALID_HANDLE_VALUE;
- }
- }
- if (_snwprintf((wchar_t *)*temp, len, L"%s.%08x", (const wchar_t *)ctx->fname, value) != len - 1) {
- return INVALID_HANDLE_VALUE;
- }
-
-#ifdef MS_UWP
- CREATEFILE2_EXTENDED_PARAMETERS extParams = {0};
- extParams.dwFileAttributes = FILE_ATTRIBUTE_NORMAL | FILE_ATTRIBUTE_TEMPORARY;
- extParams.dwFileFlags = FILE_FLAG_RANDOM_ACCESS;
- extParams.dwSecurityQosFlags = SECURITY_ANONYMOUS;
- extParams.dwSize = sizeof(extParams);
- extParams.hTemplateFile = NULL;
- extParams.lpSecurityAttributes = NULL;
-
- return CreateFile2((const wchar_t *)*temp, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, CREATE_NEW, &extParams);
-#else
- return CreateFileW((const wchar_t *)*temp, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, sa, CREATE_NEW, FILE_ATTRIBUTE_NORMAL | FILE_ATTRIBUTE_TEMPORARY, NULL);
-#endif
-}
-
-
-static int
-_win32_rename_temp_w(_zip_source_win32_read_file_t *ctx) {
- if (!MoveFileExW(ctx->tmpname, ctx->fname, MOVEFILE_REPLACE_EXISTING))
- return -1;
- return 0;
-}
-
-
-static int
-_win32_remove_w(const void *fname) {
- DeleteFileW((const wchar_t *)fname);
- return 0;
-}
diff --git a/src/Common/libzip/zip_source_window.c b/src/Common/libzip/zip_source_window.c
index d9e90bf..d996015 100644
--- a/src/Common/libzip/zip_source_window.c
+++ b/src/Common/libzip/zip_source_window.c
@@ -1,6 +1,6 @@
/*
zip_source_window.c -- return part of lower source
- Copyright (C) 2012-2018 Dieter Baron and Thomas Klausner
+ Copyright (C) 2012-2019 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
@@ -48,7 +48,7 @@ struct window {
zip_uint64_t offset; /* offset in src for next read */
zip_stat_t stat;
- zip_int8_t compression_flags;
+ zip_file_attributes_t attributes;
zip_error_t error;
zip_int64_t supports;
bool needs_seek;
@@ -64,7 +64,7 @@ zip_source_window(zip_t *za, zip_source_t *src, zip_uint64_t start, zip_uint64_t
zip_source_t *
-_zip_source_window_new(zip_source_t *src, zip_uint64_t start, zip_uint64_t length, zip_stat_t *st, zip_int8_t compression_flags, zip_t *source_archive, zip_uint64_t source_index, zip_error_t *error) {
+_zip_source_window_new(zip_source_t *src, zip_uint64_t start, zip_uint64_t length, zip_stat_t *st, zip_file_attributes_t *attributes, zip_t *source_archive, zip_uint64_t source_index, zip_error_t *error) {
struct window *ctx;
if (src == NULL || start + length < start || (source_archive == NULL && source_index != 0)) {
@@ -80,11 +80,16 @@ _zip_source_window_new(zip_source_t *src, zip_uint64_t start, zip_uint64_t lengt
ctx->start = start;
ctx->end = start + length;
zip_stat_init(&ctx->stat);
- ctx->compression_flags = compression_flags;
+ if (attributes != NULL) {
+ memcpy(&ctx->attributes, attributes, sizeof(ctx->attributes));
+ }
+ else {
+ zip_file_attributes_init(&ctx->attributes);
+ }
ctx->source_archive = source_archive;
ctx->source_index = source_index;
zip_error_init(&ctx->error);
- ctx->supports = (zip_source_supports(src) & ZIP_SOURCE_SUPPORTS_SEEKABLE) | (zip_source_make_command_bitmap(ZIP_SOURCE_GET_COMPRESSION_FLAGS, ZIP_SOURCE_SUPPORTS, ZIP_SOURCE_TELL, -1));
+ ctx->supports = (zip_source_supports(src) & ZIP_SOURCE_SUPPORTS_SEEKABLE) | (zip_source_make_command_bitmap(ZIP_SOURCE_GET_FILE_ATTRIBUTES, ZIP_SOURCE_SUPPORTS, ZIP_SOURCE_TELL, -1));
ctx->needs_seek = (ctx->supports & ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_SEEK)) ? true : false;
if (st) {
@@ -173,7 +178,7 @@ window_read(zip_source_t *src, void *_ctx, void *data, zip_uint64_t len, zip_sou
return -1;
}
}
-
+
byte_array_fini(b);
}
@@ -231,8 +236,14 @@ window_read(zip_source_t *src, void *_ctx, void *data, zip_uint64_t len, zip_sou
return 0;
}
- case ZIP_SOURCE_GET_COMPRESSION_FLAGS:
- return ctx->compression_flags;
+ case ZIP_SOURCE_GET_FILE_ATTRIBUTES:
+ if (len < sizeof(ctx->attributes)) {
+ zip_error_set(&ctx->error, ZIP_ER_INVAL, 0);
+ return -1;
+ }
+
+ memcpy(data, &ctx->attributes, sizeof(ctx->attributes));
+ return sizeof(ctx->attributes);
case ZIP_SOURCE_SUPPORTS:
return ctx->supports;
diff --git a/src/Common/libzip/zip_source_write.c b/src/Common/libzip/zip_source_write.c
index 9f494e0..73fc3a3 100644
--- a/src/Common/libzip/zip_source_write.c
+++ b/src/Common/libzip/zip_source_write.c
@@ -1,6 +1,6 @@
/*
zip_source_write.c -- start a new file for writing
- Copyright (C) 2014-2018 Dieter Baron and Thomas Klausner
+ Copyright (C) 2014-2019 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
diff --git a/src/Common/libzip/zip_source_zip.c b/src/Common/libzip/zip_source_zip.c
index 3fd90ab..8a7feaa 100644
--- a/src/Common/libzip/zip_source_zip.c
+++ b/src/Common/libzip/zip_source_zip.c
@@ -1,6 +1,6 @@
/*
zip_source_zip.c -- create data source from zip file
- Copyright (C) 1999-2018 Dieter Baron and Thomas Klausner
+ Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
@@ -33,7 +33,6 @@
#include <stdlib.h>
-#include <string.h>
#include "zipint.h"
diff --git a/src/Common/libzip/zip_source_zip_new.c b/src/Common/libzip/zip_source_zip_new.c
index ab78561..6d547f0 100644
--- a/src/Common/libzip/zip_source_zip_new.c
+++ b/src/Common/libzip/zip_source_zip_new.c
@@ -1,6 +1,6 @@
/*
zip_source_zip_new.c -- prepare data structures for zip_fopen/zip_source_zip
- Copyright (C) 2012-2018 Dieter Baron and Thomas Klausner
+ Copyright (C) 2012-2019 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
@@ -36,15 +36,19 @@
#include "zipint.h"
+static void _zip_file_attributes_from_dirent(zip_file_attributes_t *attributes, zip_dirent_t *de);
zip_source_t *
_zip_source_zip_new(zip_t *za, zip_t *srcza, zip_uint64_t srcidx, zip_flags_t flags, zip_uint64_t start, zip_uint64_t len, const char *password) {
zip_source_t *src, *s2;
- struct zip_stat st;
+ zip_stat_t st;
+ zip_file_attributes_t attributes;
+ zip_dirent_t *de;
bool partial_data, needs_crc, needs_decrypt, needs_decompress;
- if (za == NULL)
+ if (za == NULL) {
return NULL;
+ }
if (srcza == NULL || srcidx >= srcza->nentry) {
zip_error_set(&za->error, ZIP_ER_INVAL, 0);
@@ -61,8 +65,9 @@ _zip_source_zip_new(zip_t *za, zip_t *srcza, zip_uint64_t srcidx, zip_flags_t fl
return NULL;
}
- if (flags & ZIP_FL_ENCRYPTED)
+ if (flags & ZIP_FL_ENCRYPTED) {
flags |= ZIP_FL_COMPRESSED;
+ }
if ((start > 0 || len > 0) && (flags & ZIP_FL_COMPRESSED)) {
zip_error_set(&za->error, ZIP_ER_INVAL, 0);
@@ -95,8 +100,13 @@ _zip_source_zip_new(zip_t *za, zip_t *srcza, zip_uint64_t srcidx, zip_flags_t fl
}
}
+ if ((de = _zip_get_dirent(srcza, srcidx, flags, &za->error)) == NULL) {
+ return NULL;
+ }
+ _zip_file_attributes_from_dirent(&attributes, de);
+
if (st.comp_size == 0) {
- return zip_source_buffer(za, NULL, 0, 0);
+ return zip_source_buffer_with_attributes(za, NULL, 0, 0, &attributes);
}
if (partial_data && !needs_decrypt && !needs_decompress) {
@@ -108,17 +118,12 @@ _zip_source_zip_new(zip_t *za, zip_t *srcza, zip_uint64_t srcidx, zip_flags_t fl
st2.mtime = st.mtime;
st2.valid = ZIP_STAT_SIZE | ZIP_STAT_COMP_SIZE | ZIP_STAT_COMP_METHOD | ZIP_STAT_MTIME;
- if ((src = _zip_source_window_new(srcza->src, start, len, &st2, 0, srcza, srcidx, &za->error)) == NULL) {
+ if ((src = _zip_source_window_new(srcza->src, start, len, &st2, &attributes, srcza, srcidx, &za->error)) == NULL) {
return NULL;
}
}
else {
- zip_dirent_t *de;
-
- if ((de = _zip_get_dirent(srcza, srcidx, flags, &za->error)) == NULL) {
- return NULL;
- }
- if ((src = _zip_source_window_new(srcza->src, 0, st.comp_size, &st, (de->bitflags >> 1) & 3, srcza, srcidx, &za->error)) == NULL) {
+ if ((src = _zip_source_window_new(srcza->src, 0, st.comp_size, &st, &attributes, srcza, srcidx, &za->error)) == NULL) {
return NULL;
}
}
@@ -173,3 +178,14 @@ _zip_source_zip_new(zip_t *za, zip_t *srcza, zip_uint64_t srcidx, zip_flags_t fl
return src;
}
+
+static void
+_zip_file_attributes_from_dirent(zip_file_attributes_t *attributes, zip_dirent_t *de) {
+ zip_file_attributes_init(attributes);
+ attributes->valid = ZIP_FILE_ATTRIBUTES_ASCII | ZIP_FILE_ATTRIBUTES_HOST_SYSTEM | ZIP_FILE_ATTRIBUTES_EXTERNAL_FILE_ATTRIBUTES | ZIP_FILE_ATTRIBUTES_GENERAL_PURPOSE_BIT_FLAGS;
+ attributes->ascii = de->int_attrib & 1;
+ attributes->host_system = de->version_madeby >> 8;
+ attributes->external_file_attributes = de->ext_attrib;
+ attributes->general_purpose_bit_flags = de->bitflags;
+ attributes->general_purpose_bit_mask = ZIP_FILE_ATTRIBUTES_GENERAL_PURPOSE_BIT_FLAGS_ALLOWED_MASK;
+}
diff --git a/src/Common/libzip/zip_stat.c b/src/Common/libzip/zip_stat.c
index 237d985..341c6f7 100644
--- a/src/Common/libzip/zip_stat.c
+++ b/src/Common/libzip/zip_stat.c
@@ -1,6 +1,6 @@
/*
zip_stat.c -- get information about file by name
- Copyright (C) 1999-2018 Dieter Baron and Thomas Klausner
+ Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
diff --git a/src/Common/libzip/zip_stat_index.c b/src/Common/libzip/zip_stat_index.c
index d19e76a..71f8049 100644
--- a/src/Common/libzip/zip_stat_index.c
+++ b/src/Common/libzip/zip_stat_index.c
@@ -1,6 +1,6 @@
/*
zip_stat_index.c -- get information about file by index
- Copyright (C) 1999-2018 Dieter Baron and Thomas Klausner
+ Copyright (C) 1999-2020 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
@@ -48,10 +48,17 @@ zip_stat_index(zip_t *za, zip_uint64_t index, zip_flags_t flags, zip_stat_t *st)
if ((flags & ZIP_FL_UNCHANGED) == 0 && ZIP_ENTRY_DATA_CHANGED(za->entry + index)) {
- if (zip_source_stat(za->entry[index].source, st) < 0) {
+ zip_entry_t *entry = za->entry+index;
+
+ if (zip_source_stat(entry->source, st) < 0) {
zip_error_set(&za->error, ZIP_ER_CHANGED, 0);
return -1;
}
+
+ if (entry->changes->changed & ZIP_DIRENT_LAST_MOD) {
+ st->mtime = de->last_mod;
+ st->valid |= ZIP_STAT_MTIME;
+ }
}
else {
zip_stat_init(st);
diff --git a/src/Common/libzip/zip_stat_init.c b/src/Common/libzip/zip_stat_init.c
index 46fa404..6d0903d 100644
--- a/src/Common/libzip/zip_stat_init.c
+++ b/src/Common/libzip/zip_stat_init.c
@@ -1,6 +1,6 @@
/*
zip_stat_init.c -- initialize struct zip_stat.
- Copyright (C) 2006-2018 Dieter Baron and Thomas Klausner
+ Copyright (C) 2006-2019 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
diff --git a/src/Common/libzip/zip_strerror.c b/src/Common/libzip/zip_strerror.c
index eb94198..906c7f7 100644
--- a/src/Common/libzip/zip_strerror.c
+++ b/src/Common/libzip/zip_strerror.c
@@ -1,6 +1,6 @@
/*
zip_sterror.c -- get string representation of zip error
- Copyright (C) 1999-2018 Dieter Baron and Thomas Klausner
+ Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
diff --git a/src/Common/libzip/zip_string.c b/src/Common/libzip/zip_string.c
index 7e16a72..122721d 100644
--- a/src/Common/libzip/zip_string.c
+++ b/src/Common/libzip/zip_string.c
@@ -1,6 +1,6 @@
/*
zip_string.c -- string handling (with encoding)
- Copyright (C) 2012-2018 Dieter Baron and Thomas Klausner
+ Copyright (C) 2012-2019 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
@@ -34,10 +34,10 @@
#include <stdlib.h>
#include <string.h>
+#include <zlib.h>
#include "zipint.h"
-
zip_uint32_t
_zip_string_crc32(const zip_string_t *s) {
zip_uint32_t crc;
@@ -145,7 +145,7 @@ _zip_string_new(const zip_uint8_t *raw, zip_uint16_t length, zip_flags_t flags,
return NULL;
}
- if ((s->raw = (zip_uint8_t *)malloc((size_t)(length + 1))) == NULL) {
+ if ((s->raw = (zip_uint8_t *)malloc((size_t)length + 1)) == NULL) {
free(s);
return NULL;
}
diff --git a/src/Common/libzip/zip_unchange.c b/src/Common/libzip/zip_unchange.c
index 8285707..1a78e2c 100644
--- a/src/Common/libzip/zip_unchange.c
+++ b/src/Common/libzip/zip_unchange.c
@@ -1,6 +1,6 @@
/*
zip_unchange.c -- undo changes to file in zip archive
- Copyright (C) 1999-2018 Dieter Baron and Thomas Klausner
+ Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
diff --git a/src/Common/libzip/zip_unchange_all.c b/src/Common/libzip/zip_unchange_all.c
index 6a43358..2ae742f 100644
--- a/src/Common/libzip/zip_unchange_all.c
+++ b/src/Common/libzip/zip_unchange_all.c
@@ -1,6 +1,6 @@
/*
zip_unchange.c -- undo changes to all files in zip archive
- Copyright (C) 1999-2018 Dieter Baron and Thomas Klausner
+ Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
@@ -32,8 +32,6 @@
*/
-#include <stdlib.h>
-
#include "zipint.h"
diff --git a/src/Common/libzip/zip_unchange_archive.c b/src/Common/libzip/zip_unchange_archive.c
index 404f1ed..bd223ef 100644
--- a/src/Common/libzip/zip_unchange_archive.c
+++ b/src/Common/libzip/zip_unchange_archive.c
@@ -1,6 +1,6 @@
/*
zip_unchange_archive.c -- undo global changes to ZIP archive
- Copyright (C) 2006-2018 Dieter Baron and Thomas Klausner
+ Copyright (C) 2006-2019 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
diff --git a/src/Common/libzip/zip_unchange_data.c b/src/Common/libzip/zip_unchange_data.c
index f1df2bd..74a429c 100644
--- a/src/Common/libzip/zip_unchange_data.c
+++ b/src/Common/libzip/zip_unchange_data.c
@@ -1,6 +1,6 @@
/*
zip_unchange_data.c -- undo helper function
- Copyright (C) 1999-2018 Dieter Baron and Thomas Klausner
+ Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
diff --git a/src/Common/libzip/zip_utf-8.c b/src/Common/libzip/zip_utf-8.c
index 684eba5..099db9b 100644
--- a/src/Common/libzip/zip_utf-8.c
+++ b/src/Common/libzip/zip_utf-8.c
@@ -1,6 +1,6 @@
/*
zip_utf-8.c -- UTF-8 support functions for libzip
- Copyright (C) 2011-2018 Dieter Baron and Thomas Klausner
+ Copyright (C) 2011-2019 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
diff --git a/src/Common/libzip/zipint.h b/src/Common/libzip/zipint.h
index 093a1b2..5f504ca 100644
--- a/src/Common/libzip/zipint.h
+++ b/src/Common/libzip/zipint.h
@@ -3,7 +3,7 @@
/*
zipint.h -- internal declarations.
- Copyright (C) 1999-2018 Dieter Baron and Thomas Klausner
+ Copyright (C) 1999-2020 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
@@ -34,10 +34,7 @@
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifdef HAVE_CONFIG_H
#include "config.h"
-#endif
-
#include "compat.h"
#ifdef ZIP_ALLOCATE_BUFFER
@@ -69,6 +66,9 @@
#define BUFSIZE 8192
#define EFZIP64SIZE 28
#define EF_WINZIP_AES_SIZE 7
+#define MAX_DATA_DESCRIPTOR_LENGTH 24
+
+#define ZIP_CRYPTO_PKWARE_HEADERLEN 12
#define ZIP_CM_REPLACED_DEFAULT (-2)
#define ZIP_CM_WINZIP_AES 99 /* Winzip AES encrypted */
@@ -95,6 +95,7 @@
/* according to unzip-6.0's zipinfo.c, this corresponds to a directory with rwx permissions for everyone */
#define ZIP_EXT_ATTRIB_DEFAULT_DIR (0040777u << 16)
+#define ZIP_FILE_ATTRIBUTES_GENERAL_PURPOSE_BIT_FLAGS_ALLOWED_MASK 0x0836
#define ZIP_MAX(a, b) ((a) > (b) ? (a) : (b))
#define ZIP_MIN(a, b) ((a) < (b) ? (a) : (b))
@@ -111,14 +112,14 @@ typedef zip_source_t *(*zip_encryption_implementation)(zip_t *, zip_source_t *,
zip_encryption_implementation _zip_get_encryption_implementation(zip_uint16_t method, int operation);
-// clang-format off
+/* clang-format off */
enum zip_compression_status {
ZIP_COMPRESSION_OK,
ZIP_COMPRESSION_END,
ZIP_COMPRESSION_ERROR,
ZIP_COMPRESSION_NEED_DATA
};
-// clang-format on
+/* clang-format on */
typedef enum zip_compression_status zip_compression_status_t;
struct zip_compression_algorithm {
@@ -128,7 +129,9 @@ struct zip_compression_algorithm {
void (*deallocate)(void *ctx);
/* get compression specific general purpose bitflags */
- int (*compression_flags)(void *ctx);
+ zip_uint16_t (*general_purpose_bit_flags)(void *ctx);
+ /* minimum version needed when using this algorithm */
+ zip_uint8_t version_needed;
/* start processing */
bool (*start)(void *ctx);
@@ -150,8 +153,9 @@ extern zip_compression_algorithm_t zip_algorithm_bzip2_compress;
extern zip_compression_algorithm_t zip_algorithm_bzip2_decompress;
extern zip_compression_algorithm_t zip_algorithm_deflate_compress;
extern zip_compression_algorithm_t zip_algorithm_deflate_decompress;
+extern zip_compression_algorithm_t zip_algorithm_xz_compress;
+extern zip_compression_algorithm_t zip_algorithm_xz_decompress;
-bool zip_compression_method_supported(zip_int32_t method, bool compress);
/* This API is not final yet, but we need it internally, so it's private for now. */
@@ -167,13 +171,14 @@ zip_source_t *zip_source_crc(zip_t *, zip_source_t *, int);
zip_source_t *zip_source_decompress(zip_t *za, zip_source_t *src, zip_int32_t cm);
zip_source_t *zip_source_layered(zip_t *, zip_source_t *, zip_source_layered_callback, void *);
zip_source_t *zip_source_layered_create(zip_source_t *src, zip_source_layered_callback cb, void *ud, zip_error_t *error);
-zip_source_t *zip_source_pkware(zip_t *, zip_source_t *, zip_uint16_t, int, const char *);
+zip_source_t *zip_source_pkware_decode(zip_t *, zip_source_t *, zip_uint16_t, int, const char *);
+zip_source_t *zip_source_pkware_encode(zip_t *, zip_source_t *, zip_uint16_t, int, const char *);
int zip_source_remove(zip_source_t *);
zip_int64_t zip_source_supports(zip_source_t *src);
zip_source_t *zip_source_window(zip_t *, zip_source_t *, zip_uint64_t, zip_uint64_t);
zip_source_t *zip_source_winzip_aes_decode(zip_t *, zip_source_t *, zip_uint16_t, int, const char *);
zip_source_t *zip_source_winzip_aes_encode(zip_t *, zip_source_t *, zip_uint16_t, int, const char *);
-
+zip_source_t *zip_source_buffer_with_attributes(zip_t *za, const void *data, zip_uint64_t len, int freep, zip_file_attributes_t *attributes);
/* error source for layered sources */
@@ -378,13 +383,13 @@ struct zip_string {
for those, use malloc()/free() */
#ifdef ZIP_ALLOCATE_BUFFER
-#define DEFINE_BYTE_ARRAY(buf, size) zip_uint8_t *buf
-#define byte_array_init(buf, size) (((buf) = (zip_uint8_t *)malloc(size)) != NULL)
-#define byte_array_fini(buf) (free(buf))
+#define DEFINE_BYTE_ARRAY(buf, size) zip_uint8_t *buf
+#define byte_array_init(buf, size) (((buf) = (zip_uint8_t *)malloc(size)) != NULL)
+#define byte_array_fini(buf) (free(buf))
#else
-#define DEFINE_BYTE_ARRAY(buf, size) zip_uint8_t buf[size]
-#define byte_array_init(buf, size) (1)
-#define byte_array_fini(buf) ((void)0)
+#define DEFINE_BYTE_ARRAY(buf, size) zip_uint8_t buf[size]
+#define byte_array_init(buf, size) (1)
+#define byte_array_fini(buf) ((void)0)
#endif
@@ -411,6 +416,11 @@ typedef struct zip_filelist zip_filelist_t;
struct _zip_winzip_aes;
typedef struct _zip_winzip_aes zip_winzip_aes_t;
+struct _zip_pkware_keys {
+ zip_uint32_t key[3];
+};
+typedef struct _zip_pkware_keys zip_pkware_keys_t;
+
extern const char *const _zip_err_str[];
extern const int _zip_nerr_str;
extern const int _zip_err_type[];
@@ -463,13 +473,14 @@ int _zip_buffer_skip(zip_buffer_t *buffer, zip_uint64_t length);
int _zip_buffer_set_offset(zip_buffer_t *buffer, zip_uint64_t offset);
zip_uint64_t _zip_buffer_size(zip_buffer_t *buffer);
-int _zip_cdir_compute_crc(zip_t *, uLong *);
void _zip_cdir_free(zip_cdir_t *);
bool _zip_cdir_grow(zip_cdir_t *cd, zip_uint64_t additional_entries, zip_error_t *error);
zip_cdir_t *_zip_cdir_new(zip_uint64_t, zip_error_t *);
zip_int64_t _zip_cdir_write(zip_t *za, const zip_filelist_t *filelist, zip_uint64_t survivors);
+time_t _zip_d2u_time(zip_uint16_t, zip_uint16_t);
void _zip_deregister_source(zip_t *za, zip_source_t *src);
+void _zip_dirent_apply_attributes(zip_dirent_t *, zip_file_attributes_t *, bool, zip_uint32_t);
zip_dirent_t *_zip_dirent_clone(const zip_dirent_t *);
void _zip_dirent_free(zip_dirent_t *);
void _zip_dirent_finalize(zip_dirent_t *);
@@ -508,8 +519,6 @@ int _zip_file_fillbuf(void *, size_t, zip_file_t *);
zip_uint64_t _zip_file_get_end(const zip_t *za, zip_uint64_t index, zip_error_t *error);
zip_uint64_t _zip_file_get_offset(const zip_t *, zip_uint64_t, zip_error_t *);
-int _zip_filerange_crc(zip_source_t *src, zip_uint64_t offset, zip_uint64_t length, uLong *crcp, zip_error_t *error);
-
zip_dirent_t *_zip_get_dirent(zip_t *, zip_uint64_t, zip_flags_t, zip_error_t *);
enum zip_encoding_type _zip_guess_encoding(zip_string_t *, enum zip_encoding_type);
@@ -523,35 +532,38 @@ zip_hash_t *_zip_hash_new(zip_error_t *error);
bool _zip_hash_reserve_capacity(zip_hash_t *hash, zip_uint64_t capacity, zip_error_t *error);
bool _zip_hash_revert(zip_hash_t *hash, zip_error_t *error);
+int _zip_mkstempm(char *path, int mode);
+
zip_t *_zip_open(zip_source_t *, unsigned int, zip_error_t *);
void _zip_progress_end(zip_progress_t *progress);
void _zip_progress_free(zip_progress_t *progress);
-zip_progress_t *_zip_progress_new(zip_t *za, double precision, zip_progress_callback callback, void (*ud_free)(void *), void *ud);
-void _zip_progress_start(zip_progress_t *progress);
-void _zip_progress_subrange(zip_progress_t *progress, double start, double end);
-void _zip_progress_update(zip_progress_t *progress, double value);
+int _zip_progress_start(zip_progress_t *progress);
+int _zip_progress_subrange(zip_progress_t *progress, double start, double end);
+int _zip_progress_update(zip_progress_t *progress, double value);
-ZIP_EXTERN bool zip_random(zip_uint8_t *buffer, zip_uint16_t length);
+/* this symbol is extern so it can be overridden for regression testing */
+ZIP_EXTERN bool zip_secure_random(zip_uint8_t *buffer, zip_uint16_t length);
+zip_uint32_t zip_random_uint32(void);
int _zip_read(zip_source_t *src, zip_uint8_t *data, zip_uint64_t length, zip_error_t *error);
int _zip_read_at_offset(zip_source_t *src, zip_uint64_t offset, unsigned char *b, size_t length, zip_error_t *error);
zip_uint8_t *_zip_read_data(zip_buffer_t *buffer, zip_source_t *src, size_t length, bool nulp, zip_error_t *error);
int _zip_read_local_ef(zip_t *, zip_uint64_t);
-zip_string_t *_zip_read_string(zip_buffer_t *buffer, zip_source_t *src, zip_uint16_t lenght, bool nulp, zip_error_t *error);
+zip_string_t *_zip_read_string(zip_buffer_t *buffer, zip_source_t *src, zip_uint16_t length, bool nulp, zip_error_t *error);
int _zip_register_source(zip_t *za, zip_source_t *src);
void _zip_set_open_error(int *zep, const zip_error_t *err, int ze);
+bool zip_source_accept_empty(zip_source_t *src);
zip_int64_t _zip_source_call(zip_source_t *src, void *data, zip_uint64_t length, zip_source_cmd_t command);
bool _zip_source_eof(zip_source_t *);
zip_source_t *_zip_source_file_or_p(const char *, FILE *, zip_uint64_t, zip_int64_t, const zip_stat_t *, zip_error_t *error);
-zip_int8_t zip_source_get_compression_flags(zip_source_t *);
bool _zip_source_had_error(zip_source_t *);
void _zip_source_invalidate(zip_source_t *src);
zip_source_t *_zip_source_new(zip_error_t *error);
int _zip_source_set_source_archive(zip_source_t *, zip_t *);
-zip_source_t *_zip_source_window_new(zip_source_t *src, zip_uint64_t start, zip_uint64_t length, zip_stat_t *st, zip_int8_t compression_flags, zip_t *source_archive, zip_uint64_t source_index, zip_error_t *error);
+zip_source_t *_zip_source_window_new(zip_source_t *src, zip_uint64_t start, zip_uint64_t length, zip_stat_t *st, zip_file_attributes_t *attributes, zip_t *source_archive, zip_uint64_t source_index, zip_error_t *error);
zip_source_t *_zip_source_zip_new(zip_t *, zip_t *, zip_uint64_t, zip_flags_t, zip_uint64_t, zip_uint64_t, const char *);
int _zip_stat_merge(zip_stat_t *dst, const zip_stat_t *src, zip_error_t *error);
@@ -568,6 +580,12 @@ bool _zip_winzip_aes_finish(zip_winzip_aes_t *ctx, zip_uint8_t *hmac);
void _zip_winzip_aes_free(zip_winzip_aes_t *ctx);
zip_winzip_aes_t *_zip_winzip_aes_new(const zip_uint8_t *password, zip_uint64_t password_length, const zip_uint8_t *salt, zip_uint16_t key_size, zip_uint8_t *password_verify, zip_error_t *error);
+void _zip_pkware_encrypt(zip_pkware_keys_t *keys, zip_uint8_t *out, const zip_uint8_t *in, zip_uint64_t len);
+void _zip_pkware_decrypt(zip_pkware_keys_t *keys, zip_uint8_t *out, const zip_uint8_t *in, zip_uint64_t len);
+zip_pkware_keys_t *_zip_pkware_keys_new(zip_error_t *error);
+void _zip_pkware_keys_free(zip_pkware_keys_t *keys);
+void _zip_pkware_keys_reset(zip_pkware_keys_t *keys);
+
int _zip_changed(const zip_t *, zip_uint64_t *);
const char *_zip_get_name(zip_t *, zip_uint64_t, zip_flags_t, zip_error_t *);
int _zip_local_header_read(zip_t *, int);
diff --git a/src/Common/libzip/zipwin32.h b/src/Common/libzip/zipwin32.h
deleted file mode 100644
index 7d3ac76..0000000
--- a/src/Common/libzip/zipwin32.h
+++ /dev/null
@@ -1,85 +0,0 @@
-#ifndef _HAD_ZIPWIN32_H
-#define _HAD_ZIPWIN32_H
-
-/*
- zipwin32.h -- internal declarations for Windows.
- Copyright (C) 1999-2018 Dieter Baron and Thomas Klausner
-
- This file is part of libzip, a library to manipulate ZIP archives.
- The authors can be contacted at <libzip@nih.at>
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
- 1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in
- the documentation and/or other materials provided with the
- distribution.
- 3. The names of the authors may not be used to endorse or promote
- products derived from this software without specific prior
- written permission.
-
- THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
- OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
- DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
- IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-/* 0x0501 => Windows XP; needs to be at least this value because of GetFileSizeEx */
-#if !defined(MS_UWP) && !defined(_WIN32_WINNT)
-#define _WIN32_WINNT 0x0501
-#endif
-
-#include <windows.h>
-
-/* context for Win32 source */
-
-struct _zip_source_win32_file_ops;
-
-struct _zip_source_win32_read_file {
- zip_error_t error; /* last error information */
- zip_int64_t supports;
-
- /* operations */
- struct _zip_source_win32_file_ops *ops;
-
- /* reading */
- void *fname; /* name of file to read from - ANSI (char *) or Unicode (wchar_t *) */
- void *h; /* HANDLE for file to read from */
- int closep; /* whether to close f on ZIP_CMD_FREE */
- struct zip_stat st; /* stat information passed in */
- zip_uint64_t start; /* start offset of data to read */
- zip_uint64_t end; /* end offset of data to read, 0 for up to EOF */
- zip_uint64_t current; /* current offset */
-
- /* writing */
- void *tmpname; /* name of temp file - ANSI (char *) or Unicode (wchar_t *) */
- void *hout; /* HANDLE for output file */
-};
-
-typedef struct _zip_source_win32_read_file _zip_source_win32_read_file_t;
-
-/* internal operations for Win32 source */
-
-struct _zip_source_win32_file_ops {
- void *(*op_strdup)(const void *);
- void *(*op_open)(_zip_source_win32_read_file_t *);
- void *(*op_create_temp)(_zip_source_win32_read_file_t *, void **, zip_uint32_t, PSECURITY_ATTRIBUTES);
- int (*op_rename_temp)(_zip_source_win32_read_file_t *);
- int (*op_remove)(const void *);
-};
-
-typedef struct _zip_source_win32_file_ops _zip_source_win32_file_ops_t;
-
-zip_source_t *_zip_source_win32_handle_or_name(const void *, void *, zip_uint64_t, zip_int64_t, int, const zip_stat_t *, _zip_source_win32_file_ops_t *, zip_error_t *);
-
-#endif /* zipwin32.h */
diff --git a/src/Core/Core.h b/src/Core/Core.h
index 97e35b2..3a2235a 100644
--- a/src/Core/Core.h
+++ b/src/Core/Core.h
@@ -17,8 +17,8 @@
namespace VeraCrypt
{
- extern auto_ptr <CoreBase> Core;
- extern auto_ptr <CoreBase> CoreDirect;
+ extern unique_ptr <CoreBase> Core;
+ extern unique_ptr <CoreBase> CoreDirect;
class WaitThreadRoutine
{
diff --git a/src/Core/CoreBase.cpp b/src/Core/CoreBase.cpp
index 01d3981..29bfb74 100644
--- a/src/Core/CoreBase.cpp
+++ b/src/Core/CoreBase.cpp
@@ -254,7 +254,11 @@ namespace VeraCrypt
bool CoreBase::IsVolumeMounted (const VolumePath &volumePath) const
{
- return GetMountedVolume (volumePath);
+ shared_ptr<VolumeInfo> mountedVolume = GetMountedVolume (volumePath);
+ if (mountedVolume)
+ return true;
+ else
+ return false;
}
shared_ptr <Volume> CoreBase::OpenVolume (shared_ptr <VolumePath> volumePath, bool preserveTimestamps, shared_ptr <VolumePassword> password, int pim, shared_ptr<Pkcs5Kdf> kdf, bool truecryptMode, shared_ptr <KeyfileList> keyfiles, VolumeProtection::Enum protection, shared_ptr <VolumePassword> protectionPassword, int protectionPim, shared_ptr<Pkcs5Kdf> protectionKdf, shared_ptr <KeyfileList> protectionKeyfiles, bool sharedAccessAllowed, VolumeType::Enum volumeType, bool useBackupHeaders, bool partitionInSystemEncryptionScope) const
diff --git a/src/Core/RandomNumberGenerator.cpp b/src/Core/RandomNumberGenerator.cpp
index 70c4649..91247d8 100644
--- a/src/Core/RandomNumberGenerator.cpp
+++ b/src/Core/RandomNumberGenerator.cpp
@@ -14,6 +14,11 @@
#include <sys/types.h>
#include <errno.h>
#include <fcntl.h>
+
+#ifndef ERESTART
+#define ERESTART EINTR
+#endif
+
#endif
#include "RandomNumberGenerator.h"
@@ -44,7 +49,29 @@ namespace VeraCrypt
throw_sys_sub_if (random == -1, L"/dev/random");
finally_do_arg (int, random, { close (finally_arg); });
- throw_sys_sub_if (read (random, buffer, buffer.Size()) == -1 && errno != EAGAIN, L"/dev/random");
+ // ensure that we have read at least 32 bytes from /dev/random before allowing it to fail gracefully
+ while (true)
+ {
+ int rndCount = read (random, buffer, buffer.Size());
+ throw_sys_sub_if ((rndCount == -1) && errno != EAGAIN && errno != ERESTART && errno != EINTR, L"/dev/random");
+ if (rndCount == -1 && (!DevRandomSucceeded || (DevRandomBytesCount < 32)))
+ {
+ // wait 250ms before querying /dev/random again
+ ::usleep (250 * 1000);
+ }
+ else
+ {
+ if (rndCount != -1)
+ {
+ // We count returned bytes untill 32-bytes treshold reached
+ if (DevRandomBytesCount < 32)
+ DevRandomBytesCount += rndCount;
+ DevRandomSucceeded = true;
+ }
+ break;
+ }
+ }
+
AddToPool (buffer);
/* use JitterEntropy library to get good quality random bytes based on CPU timing jitter */
@@ -218,6 +245,8 @@ namespace VeraCrypt
EnrichedByUser = false;
Running = false;
+ DevRandomSucceeded = false;
+ DevRandomBytesCount = 0;
}
void RandomNumberGenerator::Test ()
@@ -255,4 +284,6 @@ namespace VeraCrypt
bool RandomNumberGenerator::Running = false;
size_t RandomNumberGenerator::WriteOffset;
struct rand_data *RandomNumberGenerator::JitterRngCtx = NULL;
+ bool RandomNumberGenerator::DevRandomSucceeded = false;
+ int RandomNumberGenerator::DevRandomBytesCount = 0;
}
diff --git a/src/Core/RandomNumberGenerator.h b/src/Core/RandomNumberGenerator.h
index 6df31ae..8f44063 100644
--- a/src/Core/RandomNumberGenerator.h
+++ b/src/Core/RandomNumberGenerator.h
@@ -55,6 +55,8 @@ namespace VeraCrypt
static bool Running;
static size_t WriteOffset;
static struct rand_data *JitterRngCtx;
+ static bool DevRandomSucceeded;
+ static int DevRandomBytesCount;
};
}
diff --git a/src/Core/Unix/CoreService.cpp b/src/Core/Unix/CoreService.cpp
index 2a77c90..4438961 100644
--- a/src/Core/Unix/CoreService.cpp
+++ b/src/Core/Unix/CoreService.cpp
@@ -28,9 +28,9 @@
namespace VeraCrypt
{
template <class T>
- auto_ptr <T> CoreService::GetResponse ()
+ unique_ptr <T> CoreService::GetResponse ()
{
- auto_ptr <Serializable> deserializedObject (Serializable::DeserializeNew (ServiceOutputStream));
+ unique_ptr <Serializable> deserializedObject (Serializable::DeserializeNew (ServiceOutputStream));
Exception *deserializedException = dynamic_cast <Exception*> (deserializedObject.get());
if (deserializedException)
@@ -39,7 +39,7 @@ namespace VeraCrypt
if (dynamic_cast <T *> (deserializedObject.get()) == nullptr)
throw ParameterIncorrect (SRC_POS);
- return auto_ptr <T> (dynamic_cast <T *> (deserializedObject.release()));
+ return unique_ptr <T> (dynamic_cast <T *> (deserializedObject.release()));
}
void CoreService::ProcessElevatedRequests ()
@@ -90,7 +90,7 @@ namespace VeraCrypt
{
try
{
- Core = CoreDirect;
+ Core = move_ptr(CoreDirect);
shared_ptr <Stream> inputStream (new FileStream (inputFD != -1 ? inputFD : InputPipe->GetReadFD()));
shared_ptr <Stream> outputStream (new FileStream (outputFD != -1 ? outputFD : OutputPipe->GetWriteFD()));
@@ -278,7 +278,7 @@ namespace VeraCrypt
}
template <class T>
- auto_ptr <T> CoreService::SendRequest (CoreServiceRequest &request)
+ unique_ptr <T> CoreService::SendRequest (CoreServiceRequest &request)
{
static Mutex mutex;
ScopeLock lock (mutex);
@@ -341,7 +341,7 @@ namespace VeraCrypt
try
{
request.Serialize (ServiceInputStream);
- auto_ptr <T> response (GetResponse <T>());
+ unique_ptr <T> response (GetResponse <T>());
ElevatedServiceAvailable = true;
return response;
}
@@ -390,8 +390,8 @@ namespace VeraCrypt
void CoreService::StartElevated (const CoreServiceRequest &request)
{
- auto_ptr <Pipe> inPipe (new Pipe());
- auto_ptr <Pipe> outPipe (new Pipe());
+ unique_ptr <Pipe> inPipe (new Pipe());
+ unique_ptr <Pipe> outPipe (new Pipe());
Pipe errPipe;
int forkedPid = fork();
@@ -460,7 +460,7 @@ namespace VeraCrypt
if (write (inPipe->GetWriteFD(), &adminPassword.front(), adminPassword.size())) { } // Errors ignored
- Memory::Erase (&adminPassword.front(), adminPassword.size());
+ burn (&adminPassword.front(), adminPassword.size());
throw_sys_if (fcntl (outPipe->GetReadFD(), F_SETFL, O_NONBLOCK) == -1);
throw_sys_if (fcntl (errPipe.GetReadFD(), F_SETFL, O_NONBLOCK) == -1);
@@ -533,7 +533,7 @@ namespace VeraCrypt
if (!errOutput.empty())
{
- auto_ptr <Serializable> deserializedObject;
+ unique_ptr <Serializable> deserializedObject;
Exception *deserializedException = nullptr;
try
@@ -573,8 +573,8 @@ namespace VeraCrypt
byte sync[] = { 0, 0x11, 0x22 };
ServiceInputStream->Write (ConstBufferPtr (sync, array_capacity (sync)));
- AdminInputPipe = inPipe;
- AdminOutputPipe = outPipe;
+ AdminInputPipe = move_ptr(inPipe);
+ AdminOutputPipe = move_ptr(outPipe);
}
void CoreService::Stop ()
@@ -585,11 +585,11 @@ namespace VeraCrypt
shared_ptr <GetStringFunctor> CoreService::AdminPasswordCallback;
- auto_ptr <Pipe> CoreService::AdminInputPipe;
- auto_ptr <Pipe> CoreService::AdminOutputPipe;
+ unique_ptr <Pipe> CoreService::AdminInputPipe;
+ unique_ptr <Pipe> CoreService::AdminOutputPipe;
- auto_ptr <Pipe> CoreService::InputPipe;
- auto_ptr <Pipe> CoreService::OutputPipe;
+ unique_ptr <Pipe> CoreService::InputPipe;
+ unique_ptr <Pipe> CoreService::OutputPipe;
shared_ptr <Stream> CoreService::ServiceInputStream;
shared_ptr <Stream> CoreService::ServiceOutputStream;
diff --git a/src/Core/Unix/CoreService.h b/src/Core/Unix/CoreService.h
index e25b856..dfb8b35 100644
--- a/src/Core/Unix/CoreService.h
+++ b/src/Core/Unix/CoreService.h
@@ -39,17 +39,17 @@ namespace VeraCrypt
static void Stop ();
protected:
- template <class T> static auto_ptr <T> GetResponse ();
- template <class T> static auto_ptr <T> SendRequest (CoreServiceRequest &request);
+ template <class T> static unique_ptr <T> GetResponse ();
+ template <class T> static unique_ptr <T> SendRequest (CoreServiceRequest &request);
static void StartElevated (const CoreServiceRequest &request);
static shared_ptr <GetStringFunctor> AdminPasswordCallback;
- static auto_ptr <Pipe> AdminInputPipe;
- static auto_ptr <Pipe> AdminOutputPipe;
+ static unique_ptr <Pipe> AdminInputPipe;
+ static unique_ptr <Pipe> AdminOutputPipe;
- static auto_ptr <Pipe> InputPipe;
- static auto_ptr <Pipe> OutputPipe;
+ static unique_ptr <Pipe> InputPipe;
+ static unique_ptr <Pipe> OutputPipe;
static shared_ptr <Stream> ServiceInputStream;
static shared_ptr <Stream> ServiceOutputStream;
diff --git a/src/Core/Unix/CoreUnix.cpp b/src/Core/Unix/CoreUnix.cpp
index 499ea43..a648520 100644
--- a/src/Core/Unix/CoreUnix.cpp
+++ b/src/Core/Unix/CoreUnix.cpp
@@ -477,7 +477,7 @@ namespace VeraCrypt
const uint32 devSectorSize = volume->GetFile()->GetDeviceSectorSize();
const size_t volSectorSize = volume->GetSectorSize();
if (devSectorSize != volSectorSize)
- throw DeviceSectorSizeMismatch (SRC_POS, StringConverter::ToWide(devSectorSize) + L" != " + StringConverter::ToWide(volSectorSize));
+ throw DeviceSectorSizeMismatch (SRC_POS, StringConverter::ToWide(devSectorSize) + L" != " + StringConverter::ToWide((uint32) volSectorSize));
}
// Find a free mount point for FUSE service
diff --git a/src/Core/Unix/FreeBSD/CoreFreeBSD.cpp b/src/Core/Unix/FreeBSD/CoreFreeBSD.cpp
index ff3e04b..01463c3 100644
--- a/src/Core/Unix/FreeBSD/CoreFreeBSD.cpp
+++ b/src/Core/Unix/FreeBSD/CoreFreeBSD.cpp
@@ -200,7 +200,7 @@ namespace VeraCrypt
}
#ifdef TC_FREEBSD
- auto_ptr <CoreBase> Core (new CoreServiceProxy <CoreFreeBSD>);
- auto_ptr <CoreBase> CoreDirect (new CoreFreeBSD);
+ unique_ptr <CoreBase> Core (new CoreServiceProxy <CoreFreeBSD>);
+ unique_ptr <CoreBase> CoreDirect (new CoreFreeBSD);
#endif
}
diff --git a/src/Core/Unix/Linux/CoreLinux.cpp b/src/Core/Unix/Linux/CoreLinux.cpp
index 7f18fff..47ec8fb 100644
--- a/src/Core/Unix/Linux/CoreLinux.cpp
+++ b/src/Core/Unix/Linux/CoreLinux.cpp
@@ -489,6 +489,6 @@ namespace VeraCrypt
}
}
- auto_ptr <CoreBase> Core (new CoreServiceProxy <CoreLinux>);
- auto_ptr <CoreBase> CoreDirect (new CoreLinux);
+ unique_ptr <CoreBase> Core (new CoreServiceProxy <CoreLinux>);
+ unique_ptr <CoreBase> CoreDirect (new CoreLinux);
}
diff --git a/src/Core/Unix/MacOSX/CoreMacOSX.cpp b/src/Core/Unix/MacOSX/CoreMacOSX.cpp
index 251e4c6..c3809ef 100644
--- a/src/Core/Unix/MacOSX/CoreMacOSX.cpp
+++ b/src/Core/Unix/MacOSX/CoreMacOSX.cpp
@@ -229,6 +229,6 @@ namespace VeraCrypt
}
}
- auto_ptr <CoreBase> Core (new CoreServiceProxy <CoreMacOSX>);
- auto_ptr <CoreBase> CoreDirect (new CoreMacOSX);
+ unique_ptr <CoreBase> Core (new CoreServiceProxy <CoreMacOSX>);
+ unique_ptr <CoreBase> CoreDirect (new CoreMacOSX);
}
diff --git a/src/Core/Unix/Solaris/CoreSolaris.cpp b/src/Core/Unix/Solaris/CoreSolaris.cpp
index 5705e1c..15a79c4 100644
--- a/src/Core/Unix/Solaris/CoreSolaris.cpp
+++ b/src/Core/Unix/Solaris/CoreSolaris.cpp
@@ -173,6 +173,6 @@ namespace VeraCrypt
}
}
- auto_ptr <CoreBase> Core (new CoreServiceProxy <CoreSolaris>);
- auto_ptr <CoreBase> CoreDirect (new CoreSolaris);
+ unique_ptr <CoreBase> Core (new CoreServiceProxy <CoreSolaris>);
+ unique_ptr <CoreBase> CoreDirect (new CoreSolaris);
}
diff --git a/src/Core/VolumeCreator.h b/src/Core/VolumeCreator.h
index 6b8f143..3e051bc 100644
--- a/src/Core/VolumeCreator.h
+++ b/src/Core/VolumeCreator.h
@@ -16,6 +16,13 @@
#include "Platform/Platform.h"
#include "Volume/Volume.h"
#include "RandomNumberGenerator.h"
+#if defined (TC_LINUX)
+#include "Platform/Unix/Process.h"
+#include <errno.h>
+#endif
+
+#define VC_MIN_LARGE_BTRFS_VOLUME_SIZE 114294784ULL
+#define VC_MIN_SMALL_BTRFS_VOLUME_SIZE 16777216ULL
namespace VeraCrypt
{
@@ -44,6 +51,7 @@ namespace VeraCrypt
Ext2,
Ext3,
Ext4,
+ Btrfs,
MacOsExt,
APFS,
UFS
@@ -63,6 +71,67 @@ namespace VeraCrypt
return VolumeCreationOptions::FilesystemType::FAT;
#endif
}
+
+ static const char* GetFsFormatter (VolumeCreationOptions::FilesystemType::Enum fsType)
+ {
+ switch (fsType)
+ {
+ #if defined (TC_LINUX)
+ case VolumeCreationOptions::FilesystemType::Ext2: return "mkfs.ext2";
+ case VolumeCreationOptions::FilesystemType::Ext3: return "mkfs.ext3";
+ case VolumeCreationOptions::FilesystemType::Ext4: return "mkfs.ext4";
+ case VolumeCreationOptions::FilesystemType::NTFS: return "mkfs.ntfs";
+ case VolumeCreationOptions::FilesystemType::exFAT: return "mkfs.exfat";
+ case VolumeCreationOptions::FilesystemType::Btrfs: return "mkfs.btrfs";
+ #elif defined (TC_MACOSX)
+ case VolumeCreationOptions::FilesystemType::MacOsExt: return "newfs_hfs";
+ case VolumeCreationOptions::FilesystemType::exFAT: return "newfs_exfat";
+ case VolumeCreationOptions::FilesystemType::APFS: return "newfs_apfs";
+ #elif defined (TC_FREEBSD) || defined (TC_SOLARIS)
+ case VolumeCreationOptions::FilesystemType::UFS: return "newfs" ;
+ #endif
+ default: return NULL;
+ }
+ }
+
+ static bool IsFsFormatterPresent (VolumeCreationOptions::FilesystemType::Enum fsType)
+ {
+ bool bRet = false;
+ const char* fsFormatter = GetFsFormatter (fsType);
+ if (fsFormatter)
+ {
+#if defined (TC_LINUX)
+ try
+ {
+ list <string> args;
+
+ args.push_back ("-V");
+ Process::Execute (fsFormatter, args);
+
+ bRet = true;
+ }
+ catch (ExecutedProcessFailed& epe)
+ {
+ // only permission error is accepted in case of failure of the command
+ if (epe.GetExitCode () == EPERM || epe.GetExitCode () == EACCES)
+ bRet = true;
+ }
+ catch (SystemException& se)
+ {
+ // if a permission error occured, then we consider that the command exists
+ if (se.GetErrorCode () == EPERM || se.GetErrorCode () == EACCES)
+ bRet = true;
+ }
+ catch (exception &e)
+ {
+ }
+#else
+ bRet = true;
+#endif
+ }
+
+ return bRet;
+ }
};
FilesystemType::Enum Filesystem;
diff --git a/src/Crypto/Aes_hw_cpu.h b/src/Crypto/Aes_hw_cpu.h
index 8977cbc..b294e2e 100644
--- a/src/Crypto/Aes_hw_cpu.h
+++ b/src/Crypto/Aes_hw_cpu.h
@@ -20,7 +20,9 @@ extern "C"
{
#endif
+#if defined (TC_WINDOWS_BOOT)
byte is_aes_hw_cpu_supported ();
+#endif
void aes_hw_cpu_enable_sse ();
void aes_hw_cpu_decrypt (const byte *ks, byte *data);
void aes_hw_cpu_decrypt_32_blocks (const byte *ks, byte *data);
diff --git a/src/Crypto/Aeskey.c b/src/Crypto/Aeskey.c
index c9ab026..9b7bfd1 100644
--- a/src/Crypto/Aeskey.c
+++ b/src/Crypto/Aeskey.c
@@ -27,6 +27,7 @@
#include "Aesopt.h"
#include "Aestab.h"
+#include "Common/Tcdefs.h"
#ifdef USE_VIA_ACE_IF_PRESENT
# include "aes_via_ace.h"
@@ -95,6 +96,8 @@ AES_RETURN aes_encrypt_key128(const unsigned char *key, aes_encrypt_ctx cx[1])
cx->inf.b[1] = 0xff;
#endif
+ burn(ss, sizeof(ss));
+
#if defined( AES_ERR_CHK )
return EXIT_SUCCESS;
#endif
@@ -147,6 +150,8 @@ AES_RETURN aes_encrypt_key192(const unsigned char *key, aes_encrypt_ctx cx[1])
cx->inf.b[1] = 0xff;
#endif
+ burn(ss, sizeof(ss));
+
#if defined( AES_ERR_CHK )
return EXIT_SUCCESS;
#endif
@@ -202,6 +207,8 @@ AES_RETURN aes_encrypt_key256(const unsigned char *key, aes_encrypt_ctx cx[1])
cx->inf.b[1] = 0xff;
#endif
+ burn(ss, sizeof(ss));
+
#if defined( AES_ERR_CHK )
return EXIT_SUCCESS;
#endif
@@ -352,6 +359,8 @@ AES_RETURN aes_decrypt_key128(const unsigned char *key, aes_decrypt_ctx cx[1])
cx->inf.b[1] = 0xff;
#endif
+ burn(ss, sizeof(ss));
+
#if defined( AES_ERR_CHK )
return EXIT_SUCCESS;
#endif
@@ -439,6 +448,8 @@ AES_RETURN aes_decrypt_key192(const unsigned char *key, aes_decrypt_ctx cx[1])
cx->inf.b[1] = 0xff;
#endif
+ burn(ss, sizeof(ss));
+
#if defined( AES_ERR_CHK )
return EXIT_SUCCESS;
#endif
@@ -538,6 +549,8 @@ AES_RETURN aes_decrypt_key256(const unsigned char *key, aes_decrypt_ctx cx[1])
cx->inf.b[1] = 0xff;
#endif
+ burn(ss, sizeof(ss));
+
#if defined( AES_ERR_CHK )
return EXIT_SUCCESS;
#endif
diff --git a/src/Crypto/Camellia.c b/src/Crypto/Camellia.c
index 49bc767..b3a3578 100644
--- a/src/Crypto/Camellia.c
+++ b/src/Crypto/Camellia.c
@@ -3,7 +3,7 @@
#include "Crypto/cpu.h"
#include "Crypto/misc.h"
-#if CRYPTOPP_BOOL_X64
+#if CRYPTOPP_BOOL_X64 && !defined(CRYPTOPP_DISABLE_ASM)
/* camellia.c ver 1.2.0-x86_64_asm1.1
*
diff --git a/src/Crypto/Camellia.h b/src/Crypto/Camellia.h
index 988203d..a1cb832 100644
--- a/src/Crypto/Camellia.h
+++ b/src/Crypto/Camellia.h
@@ -17,7 +17,7 @@ void camellia_set_key(const unsigned __int8 userKey[], unsigned __int8 *ks);
void camellia_encrypt(const unsigned __int8 *inBlock, unsigned __int8 *outBlock, unsigned __int8 *ks);
void camellia_decrypt(const unsigned __int8 *inBlock, unsigned __int8 *outBlock, unsigned __int8 *ks);
-#if CRYPTOPP_BOOL_X64
+#if CRYPTOPP_BOOL_X64 && !defined(CRYPTOPP_DISABLE_ASM)
void camellia_encrypt_blocks(unsigned __int8 *ks, const byte* in_blk, byte* out_blk, uint32 blockCount);
void camellia_decrypt_blocks(unsigned __int8 *ks, const byte* in_blk, byte* out_blk, uint32 blockCount);
#endif
diff --git a/src/Crypto/Sha2.c b/src/Crypto/Sha2.c
index f214f6d..31cba7f 100644
--- a/src/Crypto/Sha2.c
+++ b/src/Crypto/Sha2.c
@@ -10,7 +10,7 @@ and released into public domain.
#include "Crypto/cpu.h"
#include "Crypto/misc.h"
-#ifdef _UEFI
+#if defined(_UEFI) || defined(CRYPTOPP_DISABLE_ASM)
#define NO_OPTIMIZED_VERSIONS
#endif
@@ -774,7 +774,7 @@ void sha256_begin(sha256_ctx* ctx)
if (!sha256transfunc)
{
#ifndef NO_OPTIMIZED_VERSIONS
-#ifdef _M_X64
+#if CRYPTOPP_BOOL_X64
if (g_isIntel && HasSAVX2() && HasSBMI2())
sha256transfunc = Avx2Sha256Transform;
else if (g_isIntel && HasSAVX())
diff --git a/src/Crypto/Sha2.h b/src/Crypto/Sha2.h
index 37625ce..7e90abf 100644
--- a/src/Crypto/Sha2.h
+++ b/src/Crypto/Sha2.h
@@ -22,7 +22,7 @@ extern "C" {
#define SHA512_DIGEST_SIZE 64
#define SHA512_BLOCK_SIZE 128
-#if CRYPTOPP_BOOL_X64
+#if CRYPTOPP_BOOL_X64 && !defined(CRYPTOPP_DISABLE_ASM)
#define SHA2_ALIGN CRYPTOPP_ALIGN_DATA(32)
#else
#define SHA2_ALIGN CRYPTOPP_ALIGN_DATA(16)
diff --git a/src/Crypto/Streebog.c b/src/Crypto/Streebog.c
index e443eca..eb52300 100644
--- a/src/Crypto/Streebog.c
+++ b/src/Crypto/Streebog.c
@@ -276,103 +276,6 @@ STREEBOG_ALIGN(16) static const unsigned long long C[12][8] = {
};
#endif
-#ifndef __GOST3411_BIG_ENDIAN__
-static const unsigned long long A[64] = {
- 0x8e20faa72ba0b470ULL, 0x47107ddd9b505a38ULL, 0xad08b0e0c3282d1cULL,
- 0xd8045870ef14980eULL, 0x6c022c38f90a4c07ULL, 0x3601161cf205268dULL,
- 0x1b8e0b0e798c13c8ULL, 0x83478b07b2468764ULL, 0xa011d380818e8f40ULL,
- 0x5086e740ce47c920ULL, 0x2843fd2067adea10ULL, 0x14aff010bdd87508ULL,
- 0x0ad97808d06cb404ULL, 0x05e23c0468365a02ULL, 0x8c711e02341b2d01ULL,
- 0x46b60f011a83988eULL, 0x90dab52a387ae76fULL, 0x486dd4151c3dfdb9ULL,
- 0x24b86a840e90f0d2ULL, 0x125c354207487869ULL, 0x092e94218d243cbaULL,
- 0x8a174a9ec8121e5dULL, 0x4585254f64090fa0ULL, 0xaccc9ca9328a8950ULL,
- 0x9d4df05d5f661451ULL, 0xc0a878a0a1330aa6ULL, 0x60543c50de970553ULL,
- 0x302a1e286fc58ca7ULL, 0x18150f14b9ec46ddULL, 0x0c84890ad27623e0ULL,
- 0x0642ca05693b9f70ULL, 0x0321658cba93c138ULL, 0x86275df09ce8aaa8ULL,
- 0x439da0784e745554ULL, 0xafc0503c273aa42aULL, 0xd960281e9d1d5215ULL,
- 0xe230140fc0802984ULL, 0x71180a8960409a42ULL, 0xb60c05ca30204d21ULL,
- 0x5b068c651810a89eULL, 0x456c34887a3805b9ULL, 0xac361a443d1c8cd2ULL,
- 0x561b0d22900e4669ULL, 0x2b838811480723baULL, 0x9bcf4486248d9f5dULL,
- 0xc3e9224312c8c1a0ULL, 0xeffa11af0964ee50ULL, 0xf97d86d98a327728ULL,
- 0xe4fa2054a80b329cULL, 0x727d102a548b194eULL, 0x39b008152acb8227ULL,
- 0x9258048415eb419dULL, 0x492c024284fbaec0ULL, 0xaa16012142f35760ULL,
- 0x550b8e9e21f7a530ULL, 0xa48b474f9ef5dc18ULL, 0x70a6a56e2440598eULL,
- 0x3853dc371220a247ULL, 0x1ca76e95091051adULL, 0x0edd37c48a08a6d8ULL,
- 0x07e095624504536cULL, 0x8d70c431ac02a736ULL, 0xc83862965601dd1bULL,
- 0x641c314b2b8ee083ULL
-};
-#else
-static const unsigned long long A[64] = {
- 0x70b4a02ba7fa208eULL, 0x385a509bdd7d1047ULL, 0x1c2d28c3e0b008adULL,
- 0x0e9814ef705804d8ULL, 0x074c0af9382c026cULL, 0x8d2605f21c160136ULL,
- 0xc8138c790e0b8e1bULL, 0x648746b2078b4783ULL, 0x408f8e8180d311a0ULL,
- 0x20c947ce40e78650ULL, 0x10eaad6720fd4328ULL, 0x0875d8bd10f0af14ULL,
- 0x04b46cd00878d90aULL, 0x025a3668043ce205ULL, 0x012d1b34021e718cULL,
- 0x8e98831a010fb646ULL, 0x6fe77a382ab5da90ULL, 0xb9fd3d1c15d46d48ULL,
- 0xd2f0900e846ab824ULL, 0x6978480742355c12ULL, 0xba3c248d21942e09ULL,
- 0x5d1e12c89e4a178aULL, 0xa00f09644f258545ULL, 0x50898a32a99cccacULL,
- 0x5114665f5df04d9dULL, 0xa60a33a1a078a8c0ULL, 0x530597de503c5460ULL,
- 0xa78cc56f281e2a30ULL, 0xdd46ecb9140f1518ULL, 0xe02376d20a89840cULL,
- 0x709f3b6905ca4206ULL, 0x38c193ba8c652103ULL, 0xa8aae89cf05d2786ULL,
- 0x5455744e78a09d43ULL, 0x2aa43a273c50c0afULL, 0x15521d9d1e2860d9ULL,
- 0x842980c00f1430e2ULL, 0x429a4060890a1871ULL, 0x214d2030ca050cb6ULL,
- 0x9ea81018658c065bULL, 0xb905387a88346c45ULL, 0xd28c1c3d441a36acULL,
- 0x69460e90220d1b56ULL, 0xba2307481188832bULL, 0x5d9f8d248644cf9bULL,
- 0xa0c1c8124322e9c3ULL, 0x50ee6409af11faefULL, 0x2877328ad9867df9ULL,
- 0x9c320ba85420fae4ULL, 0x4e198b542a107d72ULL, 0x2782cb2a1508b039ULL,
- 0x9d41eb1584045892ULL, 0xc0aefb8442022c49ULL, 0x6057f342210116aaULL,
- 0x30a5f7219e8e0b55ULL, 0x18dcf59e4f478ba4ULL, 0x8e5940246ea5a670ULL,
- 0x47a2201237dc5338ULL, 0xad511009956ea71cULL, 0xd8a6088ac437dd0eULL,
- 0x6c5304456295e007ULL, 0x36a702ac31c4708dULL, 0x1bdd0156966238c8ULL,
- 0x83e08e2b4b311c64ULL
-};
-#endif
-
-static const unsigned char Tau[64] = {
- 0, 8, 16, 24, 32, 40, 48, 56,
- 1, 9, 17, 25, 33, 41, 49, 57,
- 2, 10, 18, 26, 34, 42, 50, 58,
- 3, 11, 19, 27, 35, 43, 51, 59,
- 4, 12, 20, 28, 36, 44, 52, 60,
- 5, 13, 21, 29, 37, 45, 53, 61,
- 6, 14, 22, 30, 38, 46, 54, 62,
- 7, 15, 23, 31, 39, 47, 55, 63
-};
-
-static const unsigned char Pi[256] = {
- 252, 238, 221, 17, 207, 110, 49, 22,
- 251, 196, 250, 218, 35, 197, 4, 77,
- 233, 119, 240, 219, 147, 46, 153, 186,
- 23, 54, 241, 187, 20, 205, 95, 193,
- 249, 24, 101, 90, 226, 92, 239, 33,
- 129, 28, 60, 66, 139, 1, 142, 79,
- 5, 132, 2, 174, 227, 106, 143, 160,
- 6, 11, 237, 152, 127, 212, 211, 31,
- 235, 52, 44, 81, 234, 200, 72, 171,
- 242, 42, 104, 162, 253, 58, 206, 204,
- 181, 112, 14, 86, 8, 12, 118, 18,
- 191, 114, 19, 71, 156, 183, 93, 135,
- 21, 161, 150, 41, 16, 123, 154, 199,
- 243, 145, 120, 111, 157, 158, 178, 177,
- 50, 117, 25, 61, 255, 53, 138, 126,
- 109, 84, 198, 128, 195, 189, 13, 87,
- 223, 245, 36, 169, 62, 168, 67, 201,
- 215, 121, 214, 246, 124, 34, 185, 3,
- 224, 15, 236, 222, 122, 148, 176, 188,
- 220, 232, 40, 80, 78, 51, 10, 74,
- 167, 151, 96, 115, 30, 0, 98, 68,
- 26, 184, 56, 130, 100, 159, 38, 65,
- 173, 69, 70, 146, 39, 94, 85, 47,
- 140, 163, 165, 125, 105, 213, 149, 59,
- 7, 88, 179, 64, 134, 172, 29, 247,
- 48, 55, 107, 228, 136, 217, 231, 137,
- 225, 27, 131, 73, 76, 63, 248, 254,
- 141, 83, 170, 144, 202, 216, 133, 97,
- 32, 113, 103, 164, 45, 43, 9, 91,
- 203, 155, 37, 208, 190, 229, 108, 82,
- 89, 166, 116, 210, 230, 244, 180, 192,
- 209, 102, 175, 194, 57, 75, 99, 182
-};
#endif // CONSTS
#if 1
@@ -1995,10 +1898,10 @@ VC_INLINE __m128i _mm_set_epi64x_a(uint64 i0, uint64 i1) {
#define LOAD(P, xmm0, xmm1, xmm2, xmm3) { \
const __m128i *__m128p = (const __m128i *) &P[0]; \
- xmm0 = _mm_load_si128(&__m128p[0]); \
- xmm1 = _mm_load_si128(&__m128p[1]); \
- xmm2 = _mm_load_si128(&__m128p[2]); \
- xmm3 = _mm_load_si128(&__m128p[3]); \
+ xmm0 = _mm_loadu_si128(&__m128p[0]); \
+ xmm1 = _mm_loadu_si128(&__m128p[1]); \
+ xmm2 = _mm_loadu_si128(&__m128p[2]); \
+ xmm3 = _mm_loadu_si128(&__m128p[3]); \
}
#define UNLOAD(P, xmm0, xmm1, xmm2, xmm3) { \
@@ -2018,10 +1921,10 @@ VC_INLINE __m128i _mm_set_epi64x_a(uint64 i0, uint64 i1) {
#define X128M(P, xmm0, xmm1, xmm2, xmm3) { \
const __m128i *__m128p = (const __m128i *) &P[0]; \
- xmm0 = _mm_xor_si128(xmm0, _mm_load_si128(&__m128p[0])); \
- xmm1 = _mm_xor_si128(xmm1, _mm_load_si128(&__m128p[1])); \
- xmm2 = _mm_xor_si128(xmm2, _mm_load_si128(&__m128p[2])); \
- xmm3 = _mm_xor_si128(xmm3, _mm_load_si128(&__m128p[3])); \
+ xmm0 = _mm_xor_si128(xmm0, _mm_loadu_si128(&__m128p[0])); \
+ xmm1 = _mm_xor_si128(xmm1, _mm_loadu_si128(&__m128p[1])); \
+ xmm2 = _mm_xor_si128(xmm2, _mm_loadu_si128(&__m128p[2])); \
+ xmm3 = _mm_xor_si128(xmm3, _mm_loadu_si128(&__m128p[3])); \
}
#define _mm_xor_64(mm0, mm1) _mm_xor_si64(mm0, _mm_cvtsi64_m64(mm1))
diff --git a/src/Crypto/Twofish.c b/src/Crypto/Twofish.c
index 8ab5908..f0906f1 100644
--- a/src/Crypto/Twofish.c
+++ b/src/Crypto/Twofish.c
@@ -54,7 +54,7 @@
#define UNROLL_TWOFISH
#endif
-#if CRYPTOPP_BOOL_X64
+#if CRYPTOPP_BOOL_X64 && !defined(CRYPTOPP_DISABLE_ASM)
/* these are 64-bit assembly implementation taken from https://github.com/jkivilin/supercop-blockciphers
Copyright 2011-2013 Jussi Kivilinna <jussi.kivilinna@iki.fi>
@@ -630,7 +630,7 @@ void twofish_set_key(TwofishInstance *instance, const u4byte in_key[])
uint32 b = rotl32(MDSQ[0][Q[0][Q[0][Q[1][Q[1][i + 1] ^ key[28]] ^ key[20]] ^ key[12]] ^ key[4]] ^ MDSQ[1][Q[0][Q[1][Q[1][Q[0][i + 1] ^ key[29]] ^ key[21]] ^ key[13]] ^ key[5]]
^ MDSQ[2][Q[1][Q[0][Q[0][Q[0][i + 1] ^ key[30]] ^ key[22]] ^ key[14]] ^ key[6]] ^ MDSQ[3][Q[1][Q[1][Q[0][Q[1][i + 1] ^ key[31]] ^ key[23]] ^ key[15]] ^ key[7]], 8);
a += b;
-#if CRYPTOPP_BOOL_X64
+#if CRYPTOPP_BOOL_X64 && !defined(CRYPTOPP_DISABLE_ASM)
if (i < 8)
{
instance->w[i] = a;
@@ -998,7 +998,7 @@ void twofish_set_key(TwofishInstance *instance, const u4byte in_key[])
#ifndef TC_MINIMIZE_CODE_SIZE
-#if (CRYPTOPP_BOOL_X64 == 0)
+#if (CRYPTOPP_BOOL_X64 == 0) || defined(CRYPTOPP_DISABLE_ASM)
void twofish_encrypt(TwofishInstance *ks, const u4byte in_blk[4], u4byte out_blk[4])
{
uint32* rk = ks->l_key;
@@ -1071,7 +1071,7 @@ void twofish_encrypt(TwofishInstance *instance, const u4byte in_blk[4], u4byte o
#ifndef TC_MINIMIZE_CODE_SIZE
-#if (CRYPTOPP_BOOL_X64 == 0)
+#if (CRYPTOPP_BOOL_X64 == 0) || defined(CRYPTOPP_DISABLE_ASM)
void twofish_decrypt(TwofishInstance *ks, const u4byte in_blk[4], u4byte out_blk[4])
{
uint32* rk = ks->l_key;
diff --git a/src/Crypto/Twofish.h b/src/Crypto/Twofish.h
index cec99c7..e74826e 100644
--- a/src/Crypto/Twofish.h
+++ b/src/Crypto/Twofish.h
@@ -35,7 +35,7 @@ extern "C"
#endif
typedef struct
{
-#if CRYPTOPP_BOOL_X64
+#if CRYPTOPP_BOOL_X64 && !defined(CRYPTOPP_DISABLE_ASM)
u4byte mk_tab[4][256], w[8], k[32];
#else
u4byte l_key[40];
@@ -54,7 +54,7 @@ typedef struct
/* in_key must be 32-bytes long */
void twofish_set_key(TwofishInstance *instance, const u4byte in_key[]);
-#if CRYPTOPP_BOOL_X64
+#if CRYPTOPP_BOOL_X64 && !defined(CRYPTOPP_DISABLE_ASM)
void twofish_encrypt_blocks(TwofishInstance *instance, const byte* in_blk, byte* out_blk, uint32 blockCount);
void twofish_decrypt_blocks(TwofishInstance *instance, const byte* in_blk, byte* out_blk, uint32 blockCount);
#define twofish_encrypt(instance,in_blk,out_blk) twofish_encrypt_blocks(instance, (const byte*) in_blk, (byte*) out_blk, 1)
diff --git a/src/Crypto/Whirlpool.c b/src/Crypto/Whirlpool.c
index 9452951..98ba318 100644
--- a/src/Crypto/Whirlpool.c
+++ b/src/Crypto/Whirlpool.c
@@ -947,7 +947,6 @@ void WHIRLPOOL_add(const unsigned char * input,
HashMultipleBlocks(ctx, dataBuf, 64);
input += (64-num);
len -= (64-num);
- num = 0;
// drop through and do the rest
}
else
diff --git a/src/Crypto/cpu.c b/src/Crypto/cpu.c
index 4aeb8d3..99b8170 100644
--- a/src/Crypto/cpu.c
+++ b/src/Crypto/cpu.c
@@ -422,28 +422,6 @@ void DetectX86Features()
*((volatile int*)&g_x86DetectionDone) = 1;
}
-int is_aes_hw_cpu_supported ()
-{
- int bHasAESNI = 0;
- uint32 cpuid[4];
-
- if (CpuId(1, cpuid))
- {
- if (cpuid[2] & (1<<25))
- bHasAESNI = 1;
-#if !defined (_UEFI) && ((defined(__AES__) && defined(__PCLMUL__)) || defined(__INTEL_COMPILER) || CRYPTOPP_BOOL_AESNI_INTRINSICS_AVAILABLE)
- // Hypervisor = bit 31 of ECX of CPUID leaf 0x1
- // reference: http://artemonsecurity.com/vmde.pdf
- if (!bHasAESNI && (cpuid[2] & (1<<31)))
- {
- bHasAESNI = Detect_MS_HyperV_AES ();
- }
-#endif
- }
-
- return bHasAESNI;
-}
-
void DisableCPUExtendedFeatures ()
{
g_hasSSE2 = 0;
diff --git a/src/Crypto/jitterentropy-base-user.h b/src/Crypto/jitterentropy-base-user.h
index a4f5cb4..bfb3a60 100644
--- a/src/Crypto/jitterentropy-base-user.h
+++ b/src/Crypto/jitterentropy-base-user.h
@@ -157,7 +157,7 @@ static
#endif
VC_INLINE int jent_fips_enabled(void)
{
- return 0;
+ return 1;
}
/* --- helpers needed in user space -- */
diff --git a/src/Driver/DriveFilter.c b/src/Driver/DriveFilter.c
index 3813992..f89e6e9 100644
--- a/src/Driver/DriveFilter.c
+++ b/src/Driver/DriveFilter.c
@@ -2234,6 +2234,11 @@ static VOID DecoySystemWipeThreadProc (PVOID threadArg)
goto err;
}
+#ifdef _WIN64
+ if (IsRamEncryptionEnabled ())
+ VcProtectKeys (wipeCryptoInfo, VcGetEncryptionID (wipeCryptoInfo));
+#endif
+
EncryptDataUnits (wipeRandBuffer, &dataUnit, wipeBlockSize / ENCRYPTION_DATA_UNIT_SIZE, wipeCryptoInfo);
memcpy (wipeRandChars, wipeRandBuffer, sizeof (wipeRandChars));
diff --git a/src/Driver/Driver.rc b/src/Driver/Driver.rc
index f992ece..3001934 100644
--- a/src/Driver/Driver.rc
+++ b/src/Driver/Driver.rc
@@ -27,8 +27,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
//
VS_VERSION_INFO VERSIONINFO
- FILEVERSION 1,24,8,1
- PRODUCTVERSION 1,24,8,1
+ FILEVERSION 1,24,20,0
+ PRODUCTVERSION 1,24,20,0
FILEFLAGSMASK 0x17L
#ifdef _DEBUG
FILEFLAGS 0x1L
diff --git a/src/Driver/Fuse/FuseService.cpp b/src/Driver/Fuse/FuseService.cpp
index 026883d..a2c769f 100644
--- a/src/Driver/Fuse/FuseService.cpp
+++ b/src/Driver/Fuse/FuseService.cpp
@@ -592,5 +592,5 @@ namespace VeraCrypt
VolumeSlotNumber FuseService::SlotNumber;
uid_t FuseService::UserId;
gid_t FuseService::GroupId;
- auto_ptr <Pipe> FuseService::SignalHandlerPipe;
+ unique_ptr <Pipe> FuseService::SignalHandlerPipe;
}
diff --git a/src/Driver/Fuse/FuseService.h b/src/Driver/Fuse/FuseService.h
index 4b84401..872cb36 100644
--- a/src/Driver/Fuse/FuseService.h
+++ b/src/Driver/Fuse/FuseService.h
@@ -70,7 +70,7 @@ namespace VeraCrypt
static VolumeSlotNumber SlotNumber;
static uid_t UserId;
static gid_t GroupId;
- static auto_ptr <Pipe> SignalHandlerPipe;
+ static unique_ptr <Pipe> SignalHandlerPipe;
};
}
diff --git a/src/Driver/Ntdriver.c b/src/Driver/Ntdriver.c
index 1327c12..957853c 100644
--- a/src/Driver/Ntdriver.c
+++ b/src/Driver/Ntdriver.c
@@ -143,6 +143,9 @@ static KeSaveExtendedProcessorStateFn KeSaveExtendedProcessorStatePtr = NULL;
static KeRestoreExtendedProcessorStateFn KeRestoreExtendedProcessorStatePtr = NULL;
static ExGetFirmwareEnvironmentVariableFn ExGetFirmwareEnvironmentVariablePtr = NULL;
static KeAreAllApcsDisabledFn KeAreAllApcsDisabledPtr = NULL;
+static KeSetSystemGroupAffinityThreadFn KeSetSystemGroupAffinityThreadPtr = NULL;
+static KeQueryActiveGroupCountFn KeQueryActiveGroupCountPtr = NULL;
+static KeQueryActiveProcessorCountExFn KeQueryActiveProcessorCountExPtr = NULL;
POOL_TYPE ExDefaultNonPagedPoolType = NonPagedPool;
ULONG ExDefaultMdlProtection = 0;
@@ -283,13 +286,20 @@ NTSTATUS DriverEntry (PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
}
// KeSaveExtendedProcessorState/KeRestoreExtendedProcessorState are available starting from Windows 7
+ // KeQueryActiveGroupCount/KeQueryActiveProcessorCountEx/KeSetSystemGroupAffinityThread are available starting from Windows 7
if ((OsMajorVersion > 6) || (OsMajorVersion == 6 && OsMinorVersion >= 1))
{
- UNICODE_STRING saveFuncName, restoreFuncName;
+ UNICODE_STRING saveFuncName, restoreFuncName, groupCountFuncName, procCountFuncName, setAffinityFuncName;
RtlInitUnicodeString(&saveFuncName, L"KeSaveExtendedProcessorState");
RtlInitUnicodeString(&restoreFuncName, L"KeRestoreExtendedProcessorState");
+ RtlInitUnicodeString(&groupCountFuncName, L"KeQueryActiveGroupCount");
+ RtlInitUnicodeString(&procCountFuncName, L"KeQueryActiveProcessorCountEx");
+ RtlInitUnicodeString(&setAffinityFuncName, L"KeSetSystemGroupAffinityThread");
KeSaveExtendedProcessorStatePtr = (KeSaveExtendedProcessorStateFn) MmGetSystemRoutineAddress(&saveFuncName);
KeRestoreExtendedProcessorStatePtr = (KeRestoreExtendedProcessorStateFn) MmGetSystemRoutineAddress(&restoreFuncName);
+ KeSetSystemGroupAffinityThreadPtr = (KeSetSystemGroupAffinityThreadFn) MmGetSystemRoutineAddress(&setAffinityFuncName);
+ KeQueryActiveGroupCountPtr = (KeQueryActiveGroupCountFn) MmGetSystemRoutineAddress(&groupCountFuncName);
+ KeQueryActiveProcessorCountExPtr = (KeQueryActiveProcessorCountExFn) MmGetSystemRoutineAddress(&procCountFuncName);
}
// ExGetFirmwareEnvironmentVariable is available starting from Windows 8
@@ -1384,7 +1394,8 @@ NTSTATUS ProcessVolumeDeviceControlIrp (PDEVICE_OBJECT DeviceObject, PEXTENSION
else
{
IO_STATUS_BLOCK ioStatus;
- PVOID buffer = TCalloc (max (pVerifyInformation->Length, PAGE_SIZE));
+ DWORD dwBuffersize = min (pVerifyInformation->Length, 16 * PAGE_SIZE);
+ PVOID buffer = TCalloc (dwBuffersize);
if (!buffer)
{
@@ -1392,14 +1403,29 @@ NTSTATUS ProcessVolumeDeviceControlIrp (PDEVICE_OBJECT DeviceObject, PEXTENSION
}
else
{
- LARGE_INTEGER offset = pVerifyInformation->StartingOffset;
+ LARGE_INTEGER offset;
+ DWORD dwRemainingBytes = pVerifyInformation->Length, dwReadCount;
offset.QuadPart = ullNewOffset;
- Irp->IoStatus.Status = ZwReadFile (Extension->hDeviceFile, NULL, NULL, NULL, &ioStatus, buffer, pVerifyInformation->Length, &offset, NULL);
- TCfree (buffer);
+ while (dwRemainingBytes)
+ {
+ dwReadCount = min (dwBuffersize, dwRemainingBytes);
+ Irp->IoStatus.Status = ZwReadFile (Extension->hDeviceFile, NULL, NULL, NULL, &ioStatus, buffer, dwReadCount, &offset, NULL);
+
+ if (NT_SUCCESS (Irp->IoStatus.Status) && ioStatus.Information != dwReadCount)
+ {
+ Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+ else if (!NT_SUCCESS (Irp->IoStatus.Status))
+ break;
- if (NT_SUCCESS (Irp->IoStatus.Status) && ioStatus.Information != pVerifyInformation->Length)
- Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
+ dwRemainingBytes -= dwReadCount;
+ offset.QuadPart += (ULONGLONG) dwReadCount;
+ }
+
+ burn (buffer, dwBuffersize);
+ TCfree (buffer);
}
}
@@ -3403,31 +3429,21 @@ void TCDeleteDeviceObject (PDEVICE_OBJECT DeviceObject, PEXTENSION Extension)
if (Extension->SecurityClientContextValid)
{
- if (OsMajorVersion == 5 && OsMinorVersion == 0)
- {
- ObDereferenceObject (Extension->SecurityClientContext.ClientToken);
- }
- else
- {
- // Windows 2000 does not support PsDereferenceImpersonationToken() used by SeDeleteClientSecurity().
- // TODO: Use only SeDeleteClientSecurity() once support for Windows 2000 is dropped.
-
- VOID (*PsDereferenceImpersonationTokenD) (PACCESS_TOKEN ImpersonationToken);
- UNICODE_STRING name;
- RtlInitUnicodeString (&name, L"PsDereferenceImpersonationToken");
+ VOID (*PsDereferenceImpersonationTokenD) (PACCESS_TOKEN ImpersonationToken);
+ UNICODE_STRING name;
+ RtlInitUnicodeString (&name, L"PsDereferenceImpersonationToken");
- PsDereferenceImpersonationTokenD = MmGetSystemRoutineAddress (&name);
- if (!PsDereferenceImpersonationTokenD)
- TC_BUG_CHECK (STATUS_NOT_IMPLEMENTED);
+ PsDereferenceImpersonationTokenD = MmGetSystemRoutineAddress (&name);
+ if (!PsDereferenceImpersonationTokenD)
+ TC_BUG_CHECK (STATUS_NOT_IMPLEMENTED);
-# define PsDereferencePrimaryToken
-# define PsDereferenceImpersonationToken PsDereferenceImpersonationTokenD
+# define PsDereferencePrimaryToken
+# define PsDereferenceImpersonationToken PsDereferenceImpersonationTokenD
- SeDeleteClientSecurity (&Extension->SecurityClientContext);
+ SeDeleteClientSecurity (&Extension->SecurityClientContext);
-# undef PsDereferencePrimaryToken
-# undef PsDereferenceImpersonationToken
- }
+# undef PsDereferencePrimaryToken
+# undef PsDereferenceImpersonationToken
}
VirtualVolumeDeviceObjects[Extension->nDosDriveNo] = NULL;
@@ -3627,11 +3643,16 @@ NTSTATUS ProbeRealDriveSize (PDEVICE_OBJECT driveDeviceObject, LARGE_INTEGER *dr
LARGE_INTEGER offset;
byte *sectorBuffer;
ULONGLONG startTime;
+ ULONG sectorSize;
if (!UserCanAccessDriveDevice())
return STATUS_ACCESS_DENIED;
- sectorBuffer = TCalloc (TC_SECTOR_SIZE_BIOS);
+ status = GetDeviceSectorSize (driveDeviceObject, &sectorSize);
+ if (!NT_SUCCESS (status))
+ return status;
+
+ sectorBuffer = TCalloc (sectorSize);
if (!sectorBuffer)
return STATUS_INSUFFICIENT_RESOURCES;
@@ -3646,12 +3667,12 @@ NTSTATUS ProbeRealDriveSize (PDEVICE_OBJECT driveDeviceObject, LARGE_INTEGER *dr
}
startTime = KeQueryInterruptTime ();
- for (offset.QuadPart = sysLength.QuadPart; ; offset.QuadPart += TC_SECTOR_SIZE_BIOS)
+ for (offset.QuadPart = sysLength.QuadPart; ; offset.QuadPart += sectorSize)
{
- status = TCReadDevice (driveDeviceObject, sectorBuffer, offset, TC_SECTOR_SIZE_BIOS);
+ status = TCReadDevice (driveDeviceObject, sectorBuffer, offset, sectorSize);
if (NT_SUCCESS (status))
- status = TCWriteDevice (driveDeviceObject, sectorBuffer, offset, TC_SECTOR_SIZE_BIOS);
+ status = TCWriteDevice (driveDeviceObject, sectorBuffer, offset, sectorSize);
if (!NT_SUCCESS (status))
{
@@ -4470,18 +4491,35 @@ NTSTATUS TCCompleteDiskIrp (PIRP irp, NTSTATUS status, ULONG_PTR information)
}
-size_t GetCpuCount ()
+size_t GetCpuCount (WORD* pGroupCount)
{
- KAFFINITY activeCpuMap = KeQueryActiveProcessors();
- size_t mapSize = sizeof (activeCpuMap) * 8;
size_t cpuCount = 0;
+ if (KeQueryActiveGroupCountPtr && KeQueryActiveProcessorCountExPtr)
+ {
+ USHORT i, groupCount = KeQueryActiveGroupCountPtr ();
+ for (i = 0; i < groupCount; i++)
+ {
+ cpuCount += (size_t) KeQueryActiveProcessorCountExPtr (i);
+ }
- while (mapSize--)
+ if (pGroupCount)
+ *pGroupCount = groupCount;
+ }
+ else
{
- if (activeCpuMap & 1)
- ++cpuCount;
+ KAFFINITY activeCpuMap = KeQueryActiveProcessors();
+ size_t mapSize = sizeof (activeCpuMap) * 8;
- activeCpuMap >>= 1;
+ while (mapSize--)
+ {
+ if (activeCpuMap & 1)
+ ++cpuCount;
+
+ activeCpuMap >>= 1;
+ }
+
+ if (pGroupCount)
+ *pGroupCount = 1;
}
if (cpuCount == 0)
@@ -4490,6 +4528,35 @@ size_t GetCpuCount ()
return cpuCount;
}
+USHORT GetCpuGroup (size_t index)
+{
+ if (KeQueryActiveGroupCountPtr && KeQueryActiveProcessorCountExPtr)
+ {
+ USHORT i, groupCount = KeQueryActiveGroupCountPtr ();
+ size_t cpuCount = 0;
+ for (i = 0; i < groupCount; i++)
+ {
+ cpuCount += (size_t) KeQueryActiveProcessorCountExPtr (i);
+ if (cpuCount >= index)
+ {
+ return i;
+ }
+ }
+ }
+
+ return 0;
+}
+
+void SetThreadCpuGroupAffinity (USHORT index)
+{
+ if (KeSetSystemGroupAffinityThreadPtr)
+ {
+ GROUP_AFFINITY groupAffinity = {0};
+ groupAffinity.Mask = ~0ULL;
+ groupAffinity.Group = index;
+ KeSetSystemGroupAffinityThreadPtr (&groupAffinity, NULL);
+ }
+}
void EnsureNullTerminatedString (wchar_t *str, size_t maxSizeInBytes)
{
diff --git a/src/Driver/Ntdriver.h b/src/Driver/Ntdriver.h
index 2e4d655..47ae49f 100644
--- a/src/Driver/Ntdriver.h
+++ b/src/Driver/Ntdriver.h
@@ -173,7 +173,9 @@ NTSTATUS TCCompleteIrp (PIRP irp, NTSTATUS status, ULONG_PTR information);
NTSTATUS TCCompleteDiskIrp (PIRP irp, NTSTATUS status, ULONG_PTR information);
NTSTATUS ProbeRealDriveSize (PDEVICE_OBJECT driveDeviceObject, LARGE_INTEGER *driveSize);
BOOL UserCanAccessDriveDevice ();
-size_t GetCpuCount ();
+size_t GetCpuCount (WORD* pGroupCount);
+USHORT GetCpuGroup (size_t index);
+void SetThreadCpuGroupAffinity (USHORT index);
void EnsureNullTerminatedString (wchar_t *str, size_t maxSizeInBytes);
void *AllocateMemoryWithTimeout (size_t size, int retryDelay, int timeout);
BOOL IsDriveLetterAvailable (int nDosDriveNo, DeviceNamespaceType namespaceType);
diff --git a/src/Driver/Ntvol.c b/src/Driver/Ntvol.c
index e88105c..f9e11d3 100644
--- a/src/Driver/Ntvol.c
+++ b/src/Driver/Ntvol.c
@@ -55,7 +55,7 @@ NTSTATUS TCOpenVolume (PDEVICE_OBJECT DeviceObject,
int volumeType;
char *readBuffer = 0;
NTSTATUS ntStatus = 0;
- BOOL forceAccessCheck = (!bRawDevice && !(OsMajorVersion == 5 &&OsMinorVersion == 0)); // Windows 2000 does not support OBJ_FORCE_ACCESS_CHECK attribute
+ BOOL forceAccessCheck = !bRawDevice;
BOOL disableBuffering = TRUE;
BOOL exclusiveAccess = mount->bExclusiveAccess;
@@ -224,7 +224,7 @@ NTSTATUS TCOpenVolume (PDEVICE_OBJECT DeviceObject,
lDiskLength.QuadPart = pix.PartitionLength.QuadPart;
partitionStartingOffset = pix.StartingOffset.QuadPart;
}
- // Windows 2000 does not support IOCTL_DISK_GET_PARTITION_INFO_EX
+ // If IOCTL_DISK_GET_PARTITION_INFO_EX fails, switch to IOCTL_DISK_GET_PARTITION_INFO
else if (NT_SUCCESS (TCSendHostDeviceIoControlRequest (DeviceObject, Extension, IOCTL_DISK_GET_PARTITION_INFO, (char *) &pi, sizeof (pi))))
{
lDiskLength.QuadPart = pi.PartitionLength.QuadPart;
diff --git a/src/ExpandVolume/ExpandVolume.c b/src/ExpandVolume/ExpandVolume.c
index 8db2b57..e340a8b 100644
--- a/src/ExpandVolume/ExpandVolume.c
+++ b/src/ExpandVolume/ExpandVolume.c
@@ -512,6 +512,11 @@ static int ExpandVolume (HWND hwndDlg, wchar_t *lpszVolume, Password *pVolumePas
BOOL backupHeader;
byte *wipeBuffer = NULL;
uint32 workChunkSize = TC_VOLUME_HEADER_GROUP_SIZE;
+#ifdef _WIN64
+ CRYPTO_INFO tmpCI;
+ PCRYPTO_INFO cryptoInfoBackup = NULL;
+ BOOL bIsRamEncryptionEnabled = IsRamEncryptionEnabled();
+#endif
if (pVolumePassword->Length == 0) return -1;
@@ -680,7 +685,7 @@ static int ExpandVolume (HWND hwndDlg, wchar_t *lpszVolume, Password *pVolumePas
}
#ifdef _WIN64
- if (IsRamEncryptionEnabled())
+ if (bIsRamEncryptionEnabled)
{
VcProtectKeys (cryptoInfo, VcGetEncryptionID (cryptoInfo));
}
@@ -851,6 +856,17 @@ static int ExpandVolume (HWND hwndDlg, wchar_t *lpszVolume, Password *pVolumePas
else
DebugAddProgressDlgStatus(hwndDlg, L"Writing re-encrypted primary header ...\r\n");
+#ifdef _WIN64
+ if (bIsRamEncryptionEnabled)
+ {
+ VirtualLock (&tmpCI, sizeof (CRYPTO_INFO));
+ memcpy (&tmpCI, cryptoInfo, sizeof (CRYPTO_INFO));
+ VcUnprotectKeys (&tmpCI, VcGetEncryptionID (cryptoInfo));
+ cryptoInfoBackup = cryptoInfo;
+ cryptoInfo = &tmpCI;
+ }
+#endif
+
// Prepare new volume header
nStatus = CreateVolumeHeaderInMemory (hwndDlg, FALSE,
buffer,
@@ -870,6 +886,15 @@ static int ExpandVolume (HWND hwndDlg, wchar_t *lpszVolume, Password *pVolumePas
cryptoInfo->SectorSize,
FALSE ); // use slow poll
+#ifdef _WIN64
+ if (bIsRamEncryptionEnabled)
+ {
+ cryptoInfo = cryptoInfoBackup;
+ burn (&tmpCI, sizeof (CRYPTO_INFO));
+ VirtualUnlock (&tmpCI, sizeof (CRYPTO_INFO));
+ }
+#endif
+
if (ci != NULL)
crypto_close (ci);
@@ -901,7 +926,26 @@ static int ExpandVolume (HWND hwndDlg, wchar_t *lpszVolume, Password *pVolumePas
PCRYPTO_INFO dummyInfo = NULL;
LARGE_INTEGER hiddenOffset;
+#ifdef _WIN64
+ if (bIsRamEncryptionEnabled)
+ {
+ VirtualLock (&tmpCI, sizeof (CRYPTO_INFO));
+ memcpy (&tmpCI, cryptoInfo, sizeof (CRYPTO_INFO));
+ VcUnprotectKeys (&tmpCI, VcGetEncryptionID (cryptoInfo));
+ cryptoInfoBackup = cryptoInfo;
+ cryptoInfo = &tmpCI;
+ }
+#endif
+
nStatus = WriteRandomDataToReservedHeaderAreas (hwndDlg, dev, cryptoInfo, newDataAreaSize, !backupHeader, backupHeader);
+#ifdef _WIN64
+ if (bIsRamEncryptionEnabled)
+ {
+ cryptoInfo = cryptoInfoBackup;
+ burn (&tmpCI, sizeof (CRYPTO_INFO));
+ VirtualUnlock (&tmpCI, sizeof (CRYPTO_INFO));
+ }
+#endif
if (nStatus != ERR_SUCCESS)
goto error;
diff --git a/src/ExpandVolume/ExpandVolume.rc b/src/ExpandVolume/ExpandVolume.rc
index 860130e..0315ea3 100644
--- a/src/ExpandVolume/ExpandVolume.rc
+++ b/src/ExpandVolume/ExpandVolume.rc
@@ -193,8 +193,8 @@ IDR_MOUNT_RSRC_HEADER HEADER "resource.h"
//
VS_VERSION_INFO VERSIONINFO
- FILEVERSION 1,24,8,0
- PRODUCTVERSION 1,24,8,0
+ FILEVERSION 1,24,23,0
+ PRODUCTVERSION 1,24,23,0
FILEFLAGSMASK 0x17L
#ifdef _DEBUG
FILEFLAGS 0x1L
@@ -211,11 +211,11 @@ BEGIN
BEGIN
VALUE "CompanyName", "IDRIX"
VALUE "FileDescription", "VeraCrypt Expander"
- VALUE "FileVersion", "1.24-Hotfix2"
+ VALUE "FileVersion", "1.24-Update7"
VALUE "LegalTrademarks", "VeraCrypt"
VALUE "OriginalFilename", "VeraCryptExpander.exe"
VALUE "ProductName", "VeraCrypt"
- VALUE "ProductVersion", "1.24-Hotfix2"
+ VALUE "ProductVersion", "1.24-Update7"
END
END
BLOCK "VarFileInfo"
diff --git a/src/ExpandVolume/InitDataArea.c b/src/ExpandVolume/InitDataArea.c
index afca230..709f44b 100644
--- a/src/ExpandVolume/InitDataArea.c
+++ b/src/ExpandVolume/InitDataArea.c
@@ -56,6 +56,9 @@ int FormatNoFs (HWND hwndDlg, unsigned __int64 startSector, __int64 num_sectors,
LARGE_INTEGER startOffset;
LARGE_INTEGER newOffset;
+#ifdef _WIN64
+ CRYPTO_INFO tmpCI;
+#endif
// Seek to start sector
startOffset.QuadPart = startSector * FormatSectorSize;
@@ -74,6 +77,16 @@ int FormatNoFs (HWND hwndDlg, unsigned __int64 startSector, __int64 num_sectors,
memset (sector, 0, sizeof (sector));
+#ifdef _WIN64
+ if (IsRamEncryptionEnabled ())
+ {
+ VirtualLock (&tmpCI, sizeof (tmpCI));
+ memcpy (&tmpCI, cryptoInfo, sizeof (CRYPTO_INFO));
+ VcUnprotectKeys (&tmpCI, VcGetEncryptionID (cryptoInfo));
+ cryptoInfo = &tmpCI;
+ }
+#endif
+
// Remember the original secondary key (XTS mode) before generating a temporary one
memcpy (originalK2, cryptoInfo->k2, sizeof (cryptoInfo->k2));
@@ -103,6 +116,11 @@ int FormatNoFs (HWND hwndDlg, unsigned __int64 startSector, __int64 num_sectors,
goto fail;
}
+#ifdef _WIN64
+ if (IsRamEncryptionEnabled ())
+ VcProtectKeys (cryptoInfo, VcGetEncryptionID (cryptoInfo));
+#endif
+
while (num_sectors--)
{
if (WriteSector (dev, sector, write_buf, &write_buf_cnt, &nSecNo,
@@ -136,6 +154,13 @@ int FormatNoFs (HWND hwndDlg, unsigned __int64 startSector, __int64 num_sectors,
VirtualUnlock (temporaryKey, sizeof (temporaryKey));
VirtualUnlock (originalK2, sizeof (originalK2));
TCfree (write_buf);
+#ifdef _WIN64
+ if (IsRamEncryptionEnabled ())
+ {
+ burn (&tmpCI, sizeof (CRYPTO_INFO));
+ VirtualUnlock (&tmpCI, sizeof (tmpCI));
+ }
+#endif
return 0;
@@ -147,6 +172,13 @@ fail:
VirtualUnlock (temporaryKey, sizeof (temporaryKey));
VirtualUnlock (originalK2, sizeof (originalK2));
TCfree (write_buf);
+#ifdef _WIN64
+ if (IsRamEncryptionEnabled ())
+ {
+ burn (&tmpCI, sizeof (CRYPTO_INFO));
+ VirtualUnlock (&tmpCI, sizeof (tmpCI));
+ }
+#endif
SetLastError (err);
return (retVal ? retVal : ERR_OS_ERROR);
diff --git a/src/ExpandVolume/WinMain.cpp b/src/ExpandVolume/WinMain.cpp
index ffeabe0..4942231 100644
--- a/src/ExpandVolume/WinMain.cpp
+++ b/src/ExpandVolume/WinMain.cpp
@@ -490,6 +490,17 @@ BOOL CALLBACK ExtcvPasswordDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARA
SetWindowPos (hwndDlg, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
}
+
+ if (!bSecureDesktopOngoing)
+ {
+ PasswordEditDropTarget* pTarget = new PasswordEditDropTarget ();
+ if (pTarget->Register (hwndDlg))
+ {
+ SetWindowLongPtr (hwndDlg, DWLP_USER, (LONG_PTR) pTarget);
+ }
+ else
+ delete pTarget;
+ }
}
return 0;
@@ -782,6 +793,19 @@ BOOL CALLBACK ExtcvPasswordDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARA
DragFinish (hdrop);
}
return 1;
+
+ case WM_NCDESTROY:
+ {
+ /* unregister drap-n-drop support */
+ PasswordEditDropTarget* pTarget = (PasswordEditDropTarget*) GetWindowLongPtr (hwndDlg, DWLP_USER);
+ if (pTarget)
+ {
+ SetWindowLongPtr (hwndDlg, DWLP_USER, (LONG_PTR) 0);
+ pTarget->Revoke ();
+ pTarget->Release();
+ }
+ }
+ return 0;
}
return 0;
@@ -866,6 +890,67 @@ static BOOL SelectPartition (HWND hwndDlg)
return FALSE;
}
+void ExtractCommandLine (HWND hwndDlg, wchar_t *lpszCommandLine)
+{
+ wchar_t **lpszCommandLineArgs = NULL; /* Array of command line arguments */
+ int nNoCommandLineArgs; /* The number of arguments in the array */
+
+ /* Extract command line arguments */
+ nNoCommandLineArgs = Win32CommandLine (&lpszCommandLineArgs);
+ if (nNoCommandLineArgs > 0)
+ {
+ int i;
+
+ for (i = 0; i < nNoCommandLineArgs; i++)
+ {
+ enum
+ {
+ OptionEnableMemoryProtection,
+ };
+
+ argument args[]=
+ {
+ { OptionEnableMemoryProtection, L"/protectMemory", NULL, FALSE },
+ };
+
+ argumentspec as;
+
+ int x;
+
+ if (lpszCommandLineArgs[i] == NULL)
+ continue;
+
+ as.args = args;
+ as.arg_cnt = sizeof(args)/ sizeof(args[0]);
+
+ x = GetArgumentID (&as, lpszCommandLineArgs[i]);
+
+ switch (x)
+ {
+
+ case OptionEnableMemoryProtection:
+ EnableMemoryProtection = TRUE;
+ break;
+
+ default:
+ DialogBoxParamW (hInst, MAKEINTRESOURCEW (IDD_COMMANDHELP_DLG), hwndDlg, (DLGPROC)
+ CommandHelpDlgProc, (LPARAM) &as);
+
+ exit(0);
+ }
+ }
+ }
+
+ /* Free up the command line arguments */
+ while (--nNoCommandLineArgs >= 0)
+ {
+ free (lpszCommandLineArgs[nNoCommandLineArgs]);
+ }
+
+ if (lpszCommandLineArgs)
+ free (lpszCommandLineArgs);
+}
+
/* Except in response to the WM_INITDIALOG and WM_ENDSESSION messages, the dialog box procedure
should return nonzero if it processes a message, and zero if it does not. */
@@ -890,6 +975,8 @@ BOOL CALLBACK MainDialogProc (HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPa
bUseSecureDesktop = FALSE;
bUseLegacyMaxPasswordLength = FALSE;
+ VeraCryptExpander::ExtractCommandLine (hwndDlg, (wchar_t *) lParam);
+
if (UsePreferences)
{
// General preferences
@@ -900,6 +987,12 @@ BOOL CALLBACK MainDialogProc (HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPa
RestoreDefaultKeyFilesParam ();
}
+ if (EnableMemoryProtection)
+ {
+ /* Protect this process memory from being accessed by non-admin users */
+ EnableProcessProtection ();
+ }
+
InitMainDialog (hwndDlg);
// Quit
diff --git a/src/Format/Format.rc b/src/Format/Format.rc
index 01ee4a5..0e5ccce 100644
--- a/src/Format/Format.rc
+++ b/src/Format/Format.rc
@@ -28,8 +28,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
//
VS_VERSION_INFO VERSIONINFO
- FILEVERSION 1,24,8,0
- PRODUCTVERSION 1,24,8,0
+ FILEVERSION 1,24,23,0
+ PRODUCTVERSION 1,24,23,0
FILEFLAGSMASK 0x17L
#ifdef _DEBUG
FILEFLAGS 0x1L
@@ -46,11 +46,11 @@ BEGIN
BEGIN
VALUE "CompanyName", "IDRIX"
VALUE "FileDescription", "VeraCrypt Format"
- VALUE "FileVersion", "1.24-Hotfix2"
+ VALUE "FileVersion", "1.24-Update7"
VALUE "LegalTrademarks", "VeraCrypt"
VALUE "OriginalFilename", "VeraCrypt Format.exe"
VALUE "ProductName", "VeraCrypt"
- VALUE "ProductVersion", "1.24-Hotfix2"
+ VALUE "ProductVersion", "1.24-Update7"
END
END
BLOCK "VarFileInfo"
@@ -90,7 +90,7 @@ BEGIN
DEFPUSHBUTTON "",IDC_NEXT,310,234,60,14
PUSHBUTTON "Cancel",IDCANCEL,382,234,60,14
LTEXT "",IDC_BOX_TITLE,160,8,283,17
- GROUPBOX "",IDC_STATIC,51,0,392,230
+ GROUPBOX "",IDC_STATIC,4,0,439,230
CONTROL 116,IDC_BITMAP_WIZARD,"Static",SS_BITMAP | SS_SUNKEN,10,9,137,193
LTEXT "",IDC_POS_BOX,160,24,281,193
END
@@ -129,7 +129,7 @@ IDD_SIZE_PAGE_DLG DIALOGEX 0, 0, 276, 193
STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD
FONT 8, "MS Shell Dlg", 0, 0, 0x0
BEGIN
- EDITTEXT IDC_SIZEBOX,25,22,71,14,ES_AUTOHSCROLL | ES_NUMBER
+ EDITTEXT IDC_SIZEBOX,0,22,96,14,ES_AUTOHSCROLL | ES_NUMBER
CONTROL "&KB",IDC_KB,"Button",BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,105,25,27,10
CONTROL "&MB",IDC_MB,"Button",BS_AUTORADIOBUTTON,140,25,27,10
CONTROL "&GB",IDC_GB,"Button",BS_AUTORADIOBUTTON,175,25,27,10
diff --git a/src/Format/FormatCom.cpp b/src/Format/FormatCom.cpp
index 1075776..7c15560 100644
--- a/src/Format/FormatCom.cpp
+++ b/src/Format/FormatCom.cpp
@@ -96,7 +96,7 @@ public:
}
virtual int STDMETHODCALLTYPE AnalyzeHiddenVolumeHost (
- LONG_PTR hwndDlg, int *driveNo, __int64 hiddenVolHostSize, int *realClusterSize, __int64 *nbrFreeClusters)
+ __int64 hwndDlg, int *driveNo, __int64 hiddenVolHostSize, int *realClusterSize, __int64 *nbrFreeClusters)
{
return ::AnalyzeHiddenVolumeHost (
(HWND) hwndDlg, driveNo, hiddenVolHostSize, realClusterSize, nbrFreeClusters);
@@ -283,7 +283,7 @@ extern "C" int UacAnalyzeHiddenVolumeHost (HWND hwndDlg, int *driveNo, __int64 h
CoInitialize (NULL);
if (ComGetInstance (hwndDlg, &tc))
- r = tc->AnalyzeHiddenVolumeHost ((LONG_PTR) hwndDlg, driveNo, hiddenVolHostSize, realClusterSize, nbrFreeClusters);
+ r = tc->AnalyzeHiddenVolumeHost ((__int64) hwndDlg, driveNo, hiddenVolHostSize, realClusterSize, nbrFreeClusters);
else
r = 0;
@@ -291,3 +291,42 @@ extern "C" int UacAnalyzeHiddenVolumeHost (HWND hwndDlg, int *driveNo, __int64 h
return r;
}
+
+extern "C" BOOL UacWriteLocalMachineRegistryDword (HWND hwndDlg, wchar_t *keyPath, wchar_t *valueName, DWORD value)
+{
+ CComPtr<ITrueCryptFormatCom> tc;
+ int r = 0;
+
+ CoInitialize (NULL);
+
+ if (ComGetInstance (hwndDlg, &tc))
+ {
+ CComBSTR keyPathBstr, valueNameBstr;
+ BSTR bstr = W2BSTR(keyPath);
+ if (bstr)
+ {
+ keyPathBstr.Attach (bstr);
+ bstr = W2BSTR(valueName);
+ if (bstr)
+ {
+ valueNameBstr.Attach (bstr);
+ r = tc->WriteLocalMachineRegistryDwordValue (keyPathBstr, valueNameBstr, value);
+ }
+ else
+ r = ERROR_OUTOFMEMORY;
+ }
+ else
+ r = ERROR_OUTOFMEMORY;
+ }
+
+ CoUninitialize ();
+
+ if (r == ERROR_SUCCESS)
+ return TRUE;
+ else
+ {
+ SetLastError (r);
+ return FALSE;
+ }
+}
+
diff --git a/src/Format/FormatCom.h b/src/Format/FormatCom.h
index 5f03961..5ab6bd5 100644
--- a/src/Format/FormatCom.h
+++ b/src/Format/FormatCom.h
@@ -29,6 +29,7 @@ int UacFormatFs (HWND hWnd, int driveNo, int clusterSize, int fsType);
int UacAnalyzeHiddenVolumeHost (HWND hwndDlg, int *driveNo, __int64 hiddenVolHostSize, int *realClusterSize, __int64 *nbrFreeClusters);
int UacFormatVolume (char *cvolumePath , BOOL bDevice , unsigned __int64 size , unsigned __int64 hiddenVolHostSize , Password *password , int cipher , int pkcs5 , BOOL quickFormat, BOOL sparseFileSwitch, int fileSystem , int clusterSize, HWND hwndDlg , BOOL hiddenVol , int *realClusterSize);
BOOL UacUpdateProgressBar (__int64 nSecNo, BOOL *bVolTransformThreadCancel);
+BOOL UacWriteLocalMachineRegistryDword (HWND hwndDlg, wchar_t *keyPath, wchar_t *valueName, DWORD value);
#ifdef __cplusplus
}
diff --git a/src/Format/FormatCom.idl b/src/Format/FormatCom.idl
index e513519..9df43f6 100644
--- a/src/Format/FormatCom.idl
+++ b/src/Format/FormatCom.idl
@@ -16,7 +16,7 @@ import "..\Common\Password.h";
[
uuid(56327DDA-F1A7-4e13-B128-520D129BDEF6),
helpstring("VeraCrypt Format UAC Support Library"),
- version(2.8) // Update ComSetup.cpp when changing version number
+ version(2.9) // Update ComSetup.cpp when changing version number
]
library TrueCryptFormatCom
{
@@ -28,7 +28,7 @@ library TrueCryptFormatCom
]
interface ITrueCryptFormatCom : IUnknown
{
- int AnalyzeHiddenVolumeHost (LONG_PTR hwndDlg, int *driveNo, __int64 hiddenVolHostSize, int *realClusterSize, __int64 *nbrFreeClusters);
+ int AnalyzeHiddenVolumeHost (__int64 hwndDlg, int *driveNo, __int64 hiddenVolHostSize, int *realClusterSize, __int64 *nbrFreeClusters);
DWORD CallDriver (DWORD ioctl, BSTR input, BSTR *output);
DWORD CopyFile (BSTR sourceFile, BSTR destinationFile);
DWORD DeleteFile (BSTR file);
diff --git a/src/Format/InPlace.c b/src/Format/InPlace.c
index 7117a8a..4a16fd4 100644
--- a/src/Format/InPlace.c
+++ b/src/Format/InPlace.c
@@ -774,6 +774,9 @@ int EncryptPartitionInPlaceResume (HANDLE dev,
int pim = volParams->pim;
DISK_GEOMETRY driveGeometry;
HWND hwndDlg = volParams->hwndDlg;
+#ifdef _WIN64
+ BOOL bIsRamEncryptionEnabled = IsRamEncryptionEnabled();
+#endif
bInPlaceEncNonSysResumed = TRUE;
@@ -870,7 +873,7 @@ int EncryptPartitionInPlaceResume (HANDLE dev,
goto closing_seq;
#ifdef _WIN64
- if (IsRamEncryptionEnabled ())
+ if (bIsRamEncryptionEnabled)
{
VcProtectKeys (masterCryptoInfo, VcGetEncryptionID (masterCryptoInfo));
VcProtectKeys (headerCryptoInfo, VcGetEncryptionID (headerCryptoInfo));
@@ -1097,6 +1100,19 @@ inplace_enc_read:
{
PCRYPTO_INFO dummyInfo = NULL;
+#ifdef _WIN64
+ CRYPTO_INFO tmpCI;
+ PCRYPTO_INFO cryptoInfoBackup = NULL;
+ if (bIsRamEncryptionEnabled)
+ {
+ VirtualLock (&tmpCI, sizeof(tmpCI));
+ memcpy (&tmpCI, masterCryptoInfo, sizeof (CRYPTO_INFO));
+ VcUnprotectKeys (&tmpCI, VcGetEncryptionID (masterCryptoInfo));
+ cryptoInfoBackup = masterCryptoInfo;
+ masterCryptoInfo = &tmpCI;
+ }
+#endif
+
nStatus = CreateVolumeHeaderInMemory (hwndDlg, FALSE,
header,
headerCryptoInfo->ea,
@@ -1115,6 +1131,15 @@ inplace_enc_read:
masterCryptoInfo->SectorSize,
wipeAlgorithm == TC_WIPE_NONE ? FALSE : (wipePass < PRAND_HEADER_WIPE_PASSES - 1));
+#ifdef _WIN64
+ if (bIsRamEncryptionEnabled)
+ {
+ masterCryptoInfo = cryptoInfoBackup;
+ burn (&tmpCI, sizeof (CRYPTO_INFO));
+ VirtualUnlock (&tmpCI, sizeof(tmpCI));
+ }
+#endif
+
if (nStatus != ERR_SUCCESS)
goto closing_seq;
@@ -1128,9 +1153,28 @@ inplace_enc_read:
goto closing_seq;
}
+#ifdef _WIN64
+ if (bIsRamEncryptionEnabled)
+ {
+ VirtualLock (&tmpCI, sizeof(tmpCI));
+ memcpy (&tmpCI, headerCryptoInfo, sizeof (CRYPTO_INFO));
+ VcUnprotectKeys (&tmpCI, VcGetEncryptionID (headerCryptoInfo));
+ cryptoInfoBackup = headerCryptoInfo;
+ headerCryptoInfo = &tmpCI;
+ }
+#endif
// Fill the reserved sectors of the header area with random data
nStatus = WriteRandomDataToReservedHeaderAreas (hwndDlg, dev, headerCryptoInfo, masterCryptoInfo->VolumeSize.Value, TRUE, FALSE);
+#ifdef _WIN64
+ if (bIsRamEncryptionEnabled)
+ {
+ headerCryptoInfo = cryptoInfoBackup;
+ burn (&tmpCI, sizeof (CRYPTO_INFO));
+ VirtualUnlock (&tmpCI, sizeof(tmpCI));
+ }
+#endif
+
if (nStatus != ERR_SUCCESS)
goto closing_seq;
@@ -1290,6 +1334,9 @@ int DecryptPartitionInPlace (volatile FORMAT_VOL_PARAMETERS *volParams, volatile
int pkcs5_prf = volParams->pkcs5;
int pim = volParams->pim;
DISK_GEOMETRY driveGeometry;
+#ifdef _WIN64
+ BOOL bIsRamEncryptionEnabled = IsRamEncryptionEnabled();
+#endif
buf = (char *) TCalloc (TC_MAX_NONSYS_INPLACE_ENC_WORK_CHUNK_SIZE);
@@ -1397,7 +1444,7 @@ int DecryptPartitionInPlace (volatile FORMAT_VOL_PARAMETERS *volParams, volatile
goto closing_seq;
#ifdef _WIN64
- if (IsRamEncryptionEnabled ())
+ if (bIsRamEncryptionEnabled)
{
VcProtectKeys (masterCryptoInfo, VcGetEncryptionID (masterCryptoInfo));
VcProtectKeys (headerCryptoInfo, VcGetEncryptionID (headerCryptoInfo));
@@ -1799,6 +1846,9 @@ int FastVolumeHeaderUpdate (HANDLE dev, CRYPTO_INFO *headerCryptoInfo, CRYPTO_IN
uint32 headerCrc32;
byte *fieldPos;
PCRYPTO_INFO pCryptoInfo = headerCryptoInfo;
+#ifdef _WIN64
+ BOOL bIsRamEncryptionEnabled = IsRamEncryptionEnabled();
+#endif
header = (byte *) TCalloc (TC_VOLUME_HEADER_EFFECTIVE_SIZE);
@@ -1820,7 +1870,7 @@ int FastVolumeHeaderUpdate (HANDLE dev, CRYPTO_INFO *headerCryptoInfo, CRYPTO_IN
}
#ifdef _WIN64
- if (IsRamEncryptionEnabled())
+ if (bIsRamEncryptionEnabled)
{
pCryptoInfo = crypto_open();
if (!pCryptoInfo)
@@ -1874,7 +1924,7 @@ closing_seq:
dwError = GetLastError();
#ifdef _WIN64
- if (IsRamEncryptionEnabled() && pCryptoInfo)
+ if (bIsRamEncryptionEnabled && pCryptoInfo)
{
crypto_close(pCryptoInfo);
}
diff --git a/src/Format/Tcformat.c b/src/Format/Tcformat.c
index 013e27c..c986096 100644
--- a/src/Format/Tcformat.c
+++ b/src/Format/Tcformat.c
@@ -233,10 +233,12 @@ BOOL bKeybLayoutAltKeyWarningShown = FALSE; /* TRUE if the user has been informe
BOOL bWarnOuterVolSuitableFileSys = TRUE;
Password volumePassword; /* User password */
+Password outerVolumePassword; /* Outer volume user password */
char szVerify[MAX_PASSWORD + 1]; /* Tmp password buffer */
char szRawPassword[MAX_PASSWORD + 1]; /* Password before keyfile was applied to it */
int volumePim = 0;
+int outerVolumePim = 0;
BOOL bHistoryCmdLine = FALSE; /* History control is always disabled */
BOOL ComServerMode = FALSE;
@@ -250,6 +252,7 @@ int CmdVolumeFilesystem = FILESYS_NONE;
unsigned __int64 CmdVolumeFileSize = 0;
BOOL CmdSparseFileSwitch = FALSE;
BOOL CmdQuickFormat = FALSE;
+BOOL CmdFastCreateFile = FALSE;
BOOL bForceOperation = FALSE;
@@ -259,6 +262,8 @@ BOOL bGuiMode = TRUE;
BOOL bSystemIsGPT = FALSE;
+KeyFile *FirstCmdKeyFile = NULL;
+
int nPbar = 0; /* Control ID of progress bar:- for format code */
wchar_t HeaderKeyGUIView [KEY_GUI_VIEW_SIZE];
@@ -282,6 +287,7 @@ BOOL bDisplayPoolContents = TRUE;
volatile BOOL bSparseFileSwitch = FALSE;
volatile BOOL quickFormat = FALSE;
+volatile BOOL fastCreateFile = FALSE;
volatile BOOL dynamicFormat = FALSE; /* this variable represents the sparse file flag. */
volatile int fileSystem = FILESYS_NONE;
volatile int clusterSize = 0;
@@ -407,15 +413,17 @@ static BOOL ElevateWholeWizardProcess (wstring arguments)
}
}
-static void WipePasswordsAndKeyfiles (void)
+static void WipePasswordsAndKeyfiles (bool bFull)
{
wchar_t tmp[MAX_PASSWORD+1];
// Attempt to wipe passwords stored in the input field buffers
wmemset (tmp, L'X', MAX_PASSWORD);
tmp [MAX_PASSWORD] = 0;
- SetWindowText (hPasswordInputField, tmp);
- SetWindowText (hVerifyPasswordInputField, tmp);
+ if (hPasswordInputField)
+ SetWindowText (hPasswordInputField, tmp);
+ if (hVerifyPasswordInputField)
+ SetWindowText (hVerifyPasswordInputField, tmp);
burn (&szVerify[0], sizeof (szVerify));
burn (&volumePassword, sizeof (volumePassword));
@@ -424,8 +432,16 @@ static void WipePasswordsAndKeyfiles (void)
burn (&CmdVolumePassword, sizeof (CmdVolumePassword));
burn (&CmdVolumePim, sizeof (CmdVolumePim));
- SetWindowText (hPasswordInputField, L"");
- SetWindowText (hVerifyPasswordInputField, L"");
+ if (bFull)
+ {
+ burn (&outerVolumePassword, sizeof (outerVolumePassword));
+ burn (&outerVolumePim, sizeof (outerVolumePim));
+ }
+
+ if (hPasswordInputField)
+ SetWindowText (hPasswordInputField, L"");
+ if (hVerifyPasswordInputField)
+ SetWindowText (hVerifyPasswordInputField, L"");
KeyFileRemoveAll (&FirstKeyFile);
KeyFileRemoveAll (&defaultKeyFilesParam.FirstKeyFile);
@@ -471,7 +487,7 @@ static void localcleanup (void)
WipeAbort();
- WipePasswordsAndKeyfiles ();
+ WipePasswordsAndKeyfiles (true);
RandStop (TRUE);
@@ -486,6 +502,8 @@ static void localcleanup (void)
burn (szFileName, sizeof(szFileName));
burn (szDiskFile, sizeof(szDiskFile));
+ KeyFileRemoveAll (&FirstCmdKeyFile);
+
// Attempt to wipe the GUI fields showing portions of randpool, of the master and header keys
wmemset (tmp, L'X', ARRAYSIZE(tmp));
tmp [ARRAYSIZE(tmp)-1] = 0;
@@ -703,7 +721,7 @@ static BOOL ChangeWizardMode (int newWizardMode)
// If the previous mode was different, the password may have been typed using a different
// keyboard layout (which might confuse the user and cause other problems if system encryption
// was or will be involved).
- WipePasswordsAndKeyfiles();
+ WipePasswordsAndKeyfiles(true);
}
if (newWizardMode != WIZARD_MODE_NONSYS_DEVICE)
@@ -2635,6 +2653,7 @@ static void __cdecl volTransformThreadFunction (void *hwndDlgArg)
volParams->clusterSize = clusterSize;
volParams->sparseFileSwitch = dynamicFormat;
volParams->quickFormat = quickFormat;
+ volParams->fastCreateFile = fastCreateFile;
volParams->sectorSize = GetFormatSectorSize();
volParams->realClusterSize = &realClusterSize;
volParams->password = &volumePassword;
@@ -4312,6 +4331,8 @@ BOOL CALLBACK PageDialogProc (HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPa
/* make autodetection the default */
SendMessage (hComboBox, CB_SETCURSEL, 0, 0);
+ hPasswordInputField = GetDlgItem (hwndDlg, IDC_PASSWORD_DIRECT);
+ hVerifyPasswordInputField = NULL;
ToNormalPwdField (hwndDlg, IDC_PASSWORD_DIRECT);
SetPassword (hwndDlg, IDC_PASSWORD_DIRECT, szRawPassword);
@@ -4559,6 +4580,7 @@ BOOL CALLBACK PageDialogProc (HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPa
SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_NEXT), GetString ("NEXT"));
SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_PREV), GetString ("PREV"));
SetWindowTextW (GetDlgItem (hwndDlg, IDT_RESCUE_DISK_INFO), bSystemIsGPT? GetString ("RESCUE_DISK_EFI_INFO"): GetString ("RESCUE_DISK_INFO"));
+ SetCheckBox (hwndDlg, IDC_SKIP_RESCUE_VERIFICATION, bDontVerifyRescueDisk);
SetDlgItemText (hwndDlg, IDC_RESCUE_DISK_ISO_PATH, szRescueDiskISO);
EnableWindow (GetDlgItem (GetParent (hwndDlg), IDC_NEXT), (GetWindowTextLength (GetDlgItem (hwndDlg, IDC_RESCUE_DISK_ISO_PATH)) > 1));
EnableWindow (GetDlgItem (GetParent (hwndDlg), IDC_PREV), TRUE);
@@ -5611,8 +5633,24 @@ BOOL CALLBACK PageDialogProc (HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPa
if (hw == CBN_EDITCHANGE && nCurPageNo == VOLUME_LOCATION_PAGE)
{
+ BOOL bValidEntry = (GetWindowTextLength (GetDlgItem (hCurPage, IDC_COMBO_BOX)) > 0)? TRUE : FALSE;
+
+ if (bValidEntry && !bDevice)
+ {
+ /* check that the entered path is not for an existing directory */
+ WCHAR szEnteredFilePath[TC_MAX_PATH + 1] = {0};
+ GetWindowTextW (GetDlgItem (hCurPage, IDC_COMBO_BOX), szEnteredFilePath, ARRAYSIZE (szEnteredFilePath));
+ RelativePath2Absolute (szEnteredFilePath);
+
+ DWORD dwAttr = GetFileAttributes (szEnteredFilePath);
+ if ((dwAttr != INVALID_FILE_ATTRIBUTES) && (dwAttr & FILE_ATTRIBUTE_DIRECTORY))
+ {
+ /* this is a directory. Consider it as invalid */
+ bValidEntry = FALSE;
+ }
+ }
EnableWindow (GetDlgItem (GetParent (hwndDlg), IDC_NEXT),
- GetWindowTextLength (GetDlgItem (hCurPage, IDC_COMBO_BOX)) > 0);
+ bValidEntry);
bDeviceTransformModeChoiceMade = FALSE;
bInPlaceEncNonSys = FALSE;
@@ -6141,6 +6179,12 @@ BOOL CALLBACK MainDialogProc (HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPa
ExtractCommandLine (hwndDlg, (wchar_t *) lParam);
+ if (EnableMemoryProtection)
+ {
+ /* Protect this process memory from being accessed by non-admin users */
+ EnableProcessProtection ();
+ }
+
if (ComServerMode)
{
InitDialog (hwndDlg);
@@ -6153,6 +6197,8 @@ BOOL CALLBACK MainDialogProc (HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPa
exit (0);
}
+ fastCreateFile = CmdFastCreateFile;
+
if (DirectCreationMode)
{
wchar_t root[TC_MAX_PATH];
@@ -6164,7 +6210,7 @@ BOOL CALLBACK MainDialogProc (HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPa
showKeys = FALSE;
bGuiMode = FALSE;
- if (CmdVolumePassword.Length == 0)
+ if (CmdVolumePassword.Length == 0 && !FirstCmdKeyFile)
AbortProcess ("ERR_PASSWORD_MISSING");
if (CmdVolumeFileSize == 0)
@@ -6319,6 +6365,11 @@ BOOL CALLBACK MainDialogProc (HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPa
}
}
+ if (!KeyFilesApply (hwndDlg, &volumePassword, FirstCmdKeyFile, NULL))
+ {
+ exit (1);
+ }
+
volTransformThreadFunction (hwndDlg);
exit (bOperationSuccess? 0 : 1);
@@ -6343,6 +6394,14 @@ BOOL CALLBACK MainDialogProc (HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPa
strcpy (szRawPassword, "q");
#endif
+ PasswordEditDropTarget* pTarget = new PasswordEditDropTarget ();
+ if (pTarget->Register (hwndDlg))
+ {
+ SetWindowLongPtr (hwndDlg, DWLP_USER, (LONG_PTR) pTarget);
+ }
+ else
+ delete pTarget;
+
PostMessage (hwndDlg, TC_APPMSG_PERFORM_POST_WMINIT_TASKS, 0, 0);
}
return 0;
@@ -6598,7 +6657,7 @@ BOOL CALLBACK MainDialogProc (HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPa
{
// Keyboard layout is not standard US
- WipePasswordsAndKeyfiles ();
+ WipePasswordsAndKeyfiles (true);
SetPassword (hCurPage, IDC_PASSWORD, szRawPassword);
SetPassword (hCurPage, IDC_VERIFY, szVerify);
@@ -7638,6 +7697,18 @@ BOOL CALLBACK MainDialogProc (HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPa
nNewPageNo = PIM_PAGE;
volumePim = 0;
+ if (!CreatingHiddenSysVol() && bHiddenVol && !bHiddenVolHost)
+ {
+ if ( (volumePim == outerVolumePim)
+ && (volumePassword.Length == outerVolumePassword.Length)
+ && (0 == memcmp (volumePassword.Text, outerVolumePassword.Text, volumePassword.Length))
+ )
+ {
+ Warning ("HIDDEN_CREDS_SAME_AS_OUTER", hwndDlg);
+ return 1;
+ }
+ }
+
if (SysEncInEffect ())
{
nNewPageNo = SYSENC_COLLECTING_RANDOM_DATA_PAGE - 1; // Skip irrelevant pages
@@ -7668,6 +7739,18 @@ BOOL CALLBACK MainDialogProc (HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPa
return 1;
}
+ if (!CreatingHiddenSysVol() && bHiddenVol && !bHiddenVolHost)
+ {
+ if ( (volumePim == outerVolumePim)
+ && (volumePassword.Length == outerVolumePassword.Length)
+ && (0 == memcmp (volumePassword.Text, outerVolumePassword.Text, volumePassword.Length))
+ )
+ {
+ Warning ("HIDDEN_CREDS_SAME_AS_OUTER", hwndDlg);
+ return 1;
+ }
+ }
+
if (volumePassword.Length > 0)
{
// Password character encoding
@@ -7835,8 +7918,12 @@ BOOL CALLBACK MainDialogProc (HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPa
bHiddenVolHost = FALSE;
bHiddenVolFinished = FALSE;
+ // save the outer volume password to use it for comparison with hidden volume one
+ memcpy (&outerVolumePassword, &volumePassword, sizeof (volumePassword));
+ outerVolumePim = volumePim;
+
// Clear the outer volume password
- WipePasswordsAndKeyfiles ();
+ WipePasswordsAndKeyfiles (false);
RestoreDefaultKeyFilesParam ();
@@ -8382,6 +8469,7 @@ retryCDDriveCheck:
else if (nCurPageNo == FORMAT_PAGE)
{
/* Format start (the 'Next' button has been clicked on the Format page) */
+ static BOOL g_bFastStartupCheckDone = FALSE;
if (bVolTransformThreadRunning || bVolTransformThreadToRun)
return 1;
@@ -8390,6 +8478,23 @@ retryCDDriveCheck:
bVolTransformThreadToRun = TRUE;
+ // check if Fast Startup is enabled and if yes then offer to disable it
+ if (!g_bFastStartupCheckDone)
+ {
+ BOOL bHibernateEnabled = FALSE, bHiberbootEnabled = FALSE;
+ if (GetHibernateStatus (bHibernateEnabled, bHiberbootEnabled) && bHiberbootEnabled)
+ {
+ if (AskWarnYesNo ("CONFIRM_DISABLE_FAST_STARTUP", hwndDlg) == IDYES)
+ {
+ if (!IsAdmin () && IsUacSupported ())
+ UacWriteLocalMachineRegistryDword (hwndDlg, L"SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Power", L"HiberbootEnabled", 0);
+ else
+ WriteLocalMachineRegistryDword (L"SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Power", L"HiberbootEnabled", 0);
+ }
+ }
+ g_bFastStartupCheckDone = true;
+ }
+
fileSystem = (int) SendMessage (GetDlgItem (hCurPage, IDC_FILESYS), CB_GETITEMDATA,
SendMessage (GetDlgItem (hCurPage, IDC_FILESYS), CB_GETCURSEL, 0, 0) , 0);
@@ -8466,13 +8571,7 @@ retryCDDriveCheck:
if (fileSystem == FILESYS_NTFS || fileSystem == FILESYS_EXFAT) // The file system may have been changed in the previous block
{
- if (nCurrentOS == WIN_2000)
- {
- Error("HIDDEN_VOL_HOST_UNSUPPORTED_FILESYS_WIN2000", hwndDlg);
- bVolTransformThreadToRun = FALSE;
- return 1;
- }
- else if ((fileSystem == FILESYS_NTFS) && (GetVolumeDataAreaSize (FALSE, nVolumeSize) <= TC_MAX_FAT_SECTOR_COUNT * GetFormatSectorSize())
+ if ((fileSystem == FILESYS_NTFS) && (GetVolumeDataAreaSize (FALSE, nVolumeSize) <= TC_MAX_FAT_SECTOR_COUNT * GetFormatSectorSize())
&& AskYesNo("HIDDEN_VOL_HOST_NTFS_ASK", hwndDlg) == IDNO)
{
bVolTransformThreadToRun = FALSE;
@@ -8566,7 +8665,7 @@ retryCDDriveCheck:
SetWindowTextW (GetDlgItem (MainDlg, IDCANCEL), GetString ("CANCEL"));
bHiddenVolFinished = FALSE;
- WipePasswordsAndKeyfiles ();
+ WipePasswordsAndKeyfiles (true);
return 1;
}
@@ -8668,8 +8767,12 @@ retryCDDriveCheck:
nNewPageNo = HIDDEN_VOL_HOST_PRE_CIPHER_PAGE;
+ // save the outer volume password to use it for comparison with hidden volume one
+ memcpy (&outerVolumePassword, &volumePassword, sizeof (volumePassword));
+ outerVolumePim = volumePim;
+
// Clear the outer volume password
- WipePasswordsAndKeyfiles ();
+ WipePasswordsAndKeyfiles (false);
EnableWindow (GetDlgItem (MainDlg, IDC_NEXT), TRUE);
NormalCursor ();
@@ -8940,6 +9043,22 @@ ovf_end:
case WM_CLOSE:
PostMessage (hwndDlg, TC_APPMSG_FORMAT_USER_QUIT, 0, 0);
return 1;
+
+ case WM_NCDESTROY:
+ {
+ hPasswordInputField = NULL;
+ hVerifyPasswordInputField = NULL;
+
+ /* unregister drap-n-drop support */
+ PasswordEditDropTarget* pTarget = (PasswordEditDropTarget*) GetWindowLongPtr (hwndDlg, DWLP_USER);
+ if (pTarget)
+ {
+ SetWindowLongPtr (hwndDlg, DWLP_USER, (LONG_PTR) 0);
+ pTarget->Revoke ();
+ pTarget->Release();
+ }
+ }
+ return 0;
}
return 0;
@@ -8994,6 +9113,10 @@ void ExtractCommandLine (HWND hwndDlg, wchar_t *lpszCommandLine)
OptionForce,
OptionNoSizeCheck,
OptionQuickFormat,
+ OptionFastCreateFile,
+ OptionEnableMemoryProtection,
+ OptionKeyfile,
+ OptionSecureDesktop,
};
argument args[]=
@@ -9016,6 +9139,10 @@ void ExtractCommandLine (HWND hwndDlg, wchar_t *lpszCommandLine)
{ OptionForce, L"/force", NULL, FALSE },
{ OptionNoSizeCheck, L"/nosizecheck", NULL, FALSE },
{ OptionQuickFormat, L"/quick", NULL, FALSE },
+ { OptionFastCreateFile, L"/fastcreatefile", NULL, FALSE },
+ { OptionEnableMemoryProtection, L"/protectMemory", NULL, FALSE },
+ { OptionKeyfile, L"/keyfile", L"/k", FALSE },
+ { OptionSecureDesktop, L"/secureDesktop", NULL, FALSE },
// Internal
{ CommandResumeSysEncLogOn, L"/acsysenc", L"/a", TRUE },
@@ -9372,6 +9499,14 @@ void ExtractCommandLine (HWND hwndDlg, wchar_t *lpszCommandLine)
CmdQuickFormat = TRUE;
break;
+ case OptionFastCreateFile:
+ CmdFastCreateFile = TRUE;
+ break;
+
+ case OptionEnableMemoryProtection:
+ EnableMemoryProtection = TRUE;
+ break;
+
case OptionHistory:
{
wchar_t szTmp[8] = {0};
@@ -9426,6 +9561,46 @@ void ExtractCommandLine (HWND hwndDlg, wchar_t *lpszCommandLine)
}
break;
+ case OptionKeyfile:
+ {
+ wchar_t tmpPath [2 * TC_MAX_PATH] = {0};
+ if (HAS_ARGUMENT == GetArgumentValue (lpszCommandLineArgs, &i,
+ nNoCommandLineArgs, tmpPath, ARRAYSIZE (tmpPath)))
+ {
+ KeyFile *kf;
+ RelativePath2Absolute (tmpPath);
+ kf = (KeyFile *) malloc (sizeof (KeyFile));
+ if (kf)
+ {
+ StringCchCopyW (kf->FileName, ARRAYSIZE(kf->FileName), tmpPath);
+ FirstCmdKeyFile = KeyFileAdd (FirstCmdKeyFile, kf);
+ }
+ }
+ else
+ AbortProcess ("COMMAND_LINE_ERROR");
+ }
+
+ break;
+
+ case OptionSecureDesktop:
+ {
+ wchar_t szTmp[16] = {0};
+ bCmdUseSecureDesktop = TRUE;
+ bCmdUseSecureDesktopValid = TRUE;
+
+ if (HAS_ARGUMENT == GetArgumentValue (lpszCommandLineArgs, &i, nNoCommandLineArgs,
+ szTmp, ARRAYSIZE (szTmp)))
+ {
+ if (!_wcsicmp(szTmp,L"n") || !_wcsicmp(szTmp,L"no"))
+ bCmdUseSecureDesktop = FALSE;
+ else if (!_wcsicmp(szTmp,L"y") || !_wcsicmp(szTmp,L"yes"))
+ bCmdUseSecureDesktop = TRUE;
+ else
+ AbortProcess ("COMMAND_LINE_ERROR");
+ }
+ }
+ break;
+
default:
DialogBoxParamW (hInst, MAKEINTRESOURCEW (IDD_COMMANDHELP_DLG), hwndDlg, (DLGPROC)
CommandHelpDlgProc, (LPARAM) &as);
@@ -9597,12 +9772,6 @@ int AnalyzeHiddenVolumeHost (HWND hwndDlg, int *driveNo, __int64 hiddenVolHostSi
// NTFS
bool bIsNtfs = (0 == wcsncmp (szFileSystemNameBuffer, L"NTFS", 4));
- if (nCurrentOS == WIN_2000)
- {
- Error("HIDDEN_VOL_HOST_UNSUPPORTED_FILESYS_WIN2000", hwndDlg);
- return 0;
- }
-
if (bIsNtfs && bHiddenVolDirect && GetVolumeDataAreaSize (FALSE, hiddenVolHostSize) <= TC_MAX_FAT_SECTOR_COUNT * GetFormatSectorSize())
Info ("HIDDEN_VOL_HOST_NTFS", hwndDlg);
@@ -9633,7 +9802,7 @@ int AnalyzeHiddenVolumeHost (HWND hwndDlg, int *driveNo, __int64 hiddenVolHostSi
{
// Unsupported file system
- Error ((nCurrentOS == WIN_2000) ? "HIDDEN_VOL_HOST_UNSUPPORTED_FILESYS_WIN2000" : "HIDDEN_VOL_HOST_UNSUPPORTED_FILESYS", hwndDlg);
+ Error ("HIDDEN_VOL_HOST_UNSUPPORTED_FILESYS", hwndDlg);
return 0;
}
@@ -10360,9 +10529,11 @@ int WINAPI wWinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, wchar_t *lpsz
atexit (localcleanup);
VirtualLock (&volumePassword, sizeof(volumePassword));
+ VirtualLock (&outerVolumePassword, sizeof(outerVolumePassword));
VirtualLock (szVerify, sizeof(szVerify));
VirtualLock (szRawPassword, sizeof(szRawPassword));
VirtualLock (&volumePim, sizeof(volumePim));
+ VirtualLock (&outerVolumePim, sizeof(outerVolumePim));
VirtualLock (&CmdVolumePassword, sizeof (CmdVolumePassword));
VirtualLock (MasterKeyGUIView, sizeof(MasterKeyGUIView));
diff --git a/src/Format/VeraCrypt_Wizard.bmp b/src/Format/VeraCrypt_Wizard.bmp
index a368a3a..24f3028 100644
--- a/src/Format/VeraCrypt_Wizard.bmp
+++ b/src/Format/VeraCrypt_Wizard.bmp
Binary files differ
diff --git a/src/Main/CommandLineInterface.cpp b/src/Main/CommandLineInterface.cpp
index b5f18dd..0ae246c 100644
--- a/src/Main/CommandLineInterface.cpp
+++ b/src/Main/CommandLineInterface.cpp
@@ -318,6 +318,8 @@ namespace VeraCrypt
ArgFilesystem = VolumeCreationOptions::FilesystemType::NTFS;
else if (str.IsSameAs (L"exFAT", false))
ArgFilesystem = VolumeCreationOptions::FilesystemType::exFAT;
+ else if (str.IsSameAs (L"Btrfs", false))
+ ArgFilesystem = VolumeCreationOptions::FilesystemType::Btrfs;
#elif defined (TC_MACOSX)
else if ( str.IsSameAs (L"HFS", false)
|| str.IsSameAs (L"HFS+", false)
@@ -328,6 +330,8 @@ namespace VeraCrypt
}
else if (str.IsSameAs (L"exFAT", false))
ArgFilesystem = VolumeCreationOptions::FilesystemType::exFAT;
+ else if (str.IsSameAs (L"Btrfs", false))
+ ArgFilesystem = VolumeCreationOptions::FilesystemType::Btrfs;
else if (str.IsSameAs (L"APFS", false))
ArgFilesystem = VolumeCreationOptions::FilesystemType::APFS;
#elif defined (TC_FREEBSD) || defined (TC_SOLARIS)
@@ -828,5 +832,5 @@ namespace VeraCrypt
return shared_ptr<SecureBuffer>(new SecureBuffer ());
}
- auto_ptr <CommandLineInterface> CmdLine;
+ unique_ptr <CommandLineInterface> CmdLine;
}
diff --git a/src/Main/CommandLineInterface.h b/src/Main/CommandLineInterface.h
index 00dabfd..2369333 100644
--- a/src/Main/CommandLineInterface.h
+++ b/src/Main/CommandLineInterface.h
@@ -105,7 +105,7 @@ namespace VeraCrypt
shared_ptr<VolumePassword> ToUTF8Password (const wchar_t* str, size_t charCount, size_t maxUtf8Len);
shared_ptr<SecureBuffer> ToUTF8Buffer (const wchar_t* str, size_t charCount, size_t maxUtf8Len);
- extern auto_ptr <CommandLineInterface> CmdLine;
+ extern unique_ptr <CommandLineInterface> CmdLine;
}
#endif // TC_HEADER_Main_CommandInterface
diff --git a/src/Main/Forms/AboutDialog.cpp b/src/Main/Forms/AboutDialog.cpp
index 60edc58..300db72 100644
--- a/src/Main/Forms/AboutDialog.cpp
+++ b/src/Main/Forms/AboutDialog.cpp
@@ -57,7 +57,7 @@ namespace VeraCrypt
L"Paulo Barreto, Brian Gladman, Wei Dai, Peter Gutmann, and many others.\n\n"
L"Portions of this software:\n"
- L"Copyright \xA9 2013-2019 IDRIX. All rights reserved.\n"
+ L"Copyright \xA9 2013-2020 IDRIX. All rights reserved.\n"
L"Copyright \xA9 2003-2012 TrueCrypt Developers Association. All Rights Reserved.\n"
L"Copyright \xA9 1998-2000 Paul Le Roux. All Rights Reserved.\n"
L"Copyright \xA9 1998-2008 Brian Gladman. All Rights Reserved.\n"
@@ -66,10 +66,10 @@ namespace VeraCrypt
L"Copyright \xA9 1999-2017 Dieter Baron and Thomas Klausner.\n"
L"Copyright \xA9 2013, Alexey Degtyarev. All rights reserved.\n"
L"Copyright \xA9 1999-2016 Jack Lloyd. All rights reserved.\n"
- L"Copyright \xA9 2013-2018 Stephan Mueller <smueller@chronox.de>\n\n"
+ L"Copyright \xA9 2013-2019 Stephan Mueller <smueller@chronox.de>\n\n"
L"\nThis software as a whole:\n"
- L"Copyright \xA9 2013-2019 IDRIX. All rights reserved.\n\n"
+ L"Copyright \xA9 2013-2020 IDRIX. All rights reserved.\n\n"
L"This software uses wxWidgets library, which is copyright \xA9 1998-2011 Julian Smart, Robert Roebling et al.\n\n"
diff --git a/src/Main/Forms/MainFrame.cpp b/src/Main/Forms/MainFrame.cpp
index 9abe255..417c2a6 100644
--- a/src/Main/Forms/MainFrame.cpp
+++ b/src/Main/Forms/MainFrame.cpp
@@ -99,6 +99,9 @@ namespace VeraCrypt
Connect( wxID_ANY, wxEVT_COMMAND_PREF_UPDATED, wxCommandEventHandler( MainFrame::OnPreferencesUpdated ) );
Connect( wxID_ANY, wxEVT_COMMAND_OPEN_VOLUME_REQUEST, wxCommandEventHandler( MainFrame::OnOpenVolumeSystemRequest ) );
+#ifdef TC_MACOSX
+ Connect( wxID_ANY, wxEVT_MOVE, wxMoveEventHandler( MainFrame::OnMoveHandler ) );
+#endif
}
MainFrame::~MainFrame ()
@@ -119,6 +122,9 @@ namespace VeraCrypt
Disconnect( wxID_ANY, wxEVT_COMMAND_UPDATE_VOLUME_LIST, wxCommandEventHandler( MainFrame::OnUpdateVolumeList ) );
Disconnect( wxID_ANY, wxEVT_COMMAND_PREF_UPDATED, wxCommandEventHandler( MainFrame::OnPreferencesUpdated ) );
Disconnect( wxID_ANY, wxEVT_COMMAND_OPEN_VOLUME_REQUEST, wxCommandEventHandler( MainFrame::OnOpenVolumeSystemRequest ) );
+#ifdef TC_MACOSX
+ Disconnect( wxID_ANY, wxEVT_MOVE, wxMoveEventHandler( MainFrame::OnMoveHandler ) );
+#endif
Core->VolumeMountedEvent.Disconnect (this);
Core->VolumeDismountedEvent.Disconnect (this);
Gui->OpenVolumeSystemRequestEvent.Disconnect (this);
@@ -503,7 +509,7 @@ namespace VeraCrypt
wxMenu *CreatePopupMenu ()
{
- auto_ptr <wxMenu> popup (new wxMenu);
+ unique_ptr <wxMenu> popup (new wxMenu);
Gui->AppendToMenu (*popup, LangString[Gui->IsInBackgroundMode() ? "SHOW_TC" : "HIDE_TC"], this, wxCommandEventHandler (TaskBarIcon::OnShowHideMenuItemSelected));
@@ -725,6 +731,7 @@ namespace VeraCrypt
#ifdef TC_MACOSX
if (Gui->IsInBackgroundMode())
Gui->SetBackgroundMode (false);
+ EnsureVisible ();
#endif
AboutDialog dialog (this);
dialog.ShowModal();
@@ -1722,4 +1729,11 @@ namespace VeraCrypt
Core->WipePasswordCache();
UpdateWipeCacheButton();
}
+
+#ifdef TC_MACOSX
+ void MainFrame::OnMoveHandler(wxMoveEvent& event)
+ {
+ EnsureVisible (true);
+ }
+#endif
}
diff --git a/src/Main/Forms/MainFrame.h b/src/Main/Forms/MainFrame.h
index 39c411a..9089ce7 100644
--- a/src/Main/Forms/MainFrame.h
+++ b/src/Main/Forms/MainFrame.h
@@ -15,6 +15,9 @@
#include "Forms.h"
#include "ChangePasswordDialog.h"
+#ifdef TC_MACOSX
+#include <wx/display.h>
+#endif
namespace VeraCrypt
{
@@ -162,6 +165,35 @@ namespace VeraCrypt
void UpdateWipeCacheButton ();
void WipeCache ();
+#ifdef TC_MACOSX
+ void OnMoveHandler(wxMoveEvent& event);
+
+ void EnsureVisible(bool bOnlyHeadingBar = false)
+ {
+ wxDisplay display (this);
+ wxRect displayRect = display.GetClientArea();
+
+ bool bMove = false;
+ wxPoint p = GetScreenPosition();
+ wxRect r = GetRect ();
+ wxRect rc = GetClientRect ();
+ int titleBarHeight = r.height - rc.height;
+
+ if (!bOnlyHeadingBar && (p.x < displayRect.x))
+ p.x = 0, bMove = true;
+ if (p.y < displayRect.y)
+ p.y = displayRect.y, bMove = true;
+ if (!bOnlyHeadingBar && (p.x + r.width > displayRect.x + displayRect.width))
+ p.x = displayRect.x + displayRect.width - r.width, bMove = true;
+ if (!bOnlyHeadingBar && (p.y + r.height > displayRect.y + displayRect.height))
+ p.y = displayRect.y + displayRect.height - r.height, bMove = true;
+ if (bOnlyHeadingBar && (p.y > (displayRect.y + displayRect.height - titleBarHeight)))
+ p.y = displayRect.y + displayRect.height - titleBarHeight, bMove = true;
+ if (bMove)
+ Move (p);
+ }
+#endif
+
struct VolumeActivityMapEntry
{
VolumeActivityMapEntry () { }
@@ -182,8 +214,8 @@ namespace VeraCrypt
map <int, FavoriteVolume> FavoriteVolumesMenuMap;
bool ListItemRightClickEventPending;
VolumeInfoList MountedVolumes;
- auto_ptr <wxTaskBarIcon> mTaskBarIcon;
- auto_ptr <wxTimer> mTimer;
+ unique_ptr <wxTaskBarIcon> mTaskBarIcon;
+ unique_ptr <wxTimer> mTimer;
long SelectedItemIndex;
VolumeSlotNumber SelectedSlotNumber;
int ShowRequestFifo;
diff --git a/src/Main/Forms/PreferencesDialog.cpp b/src/Main/Forms/PreferencesDialog.cpp
index e2b4f62..ee4b2d5 100644
--- a/src/Main/Forms/PreferencesDialog.cpp
+++ b/src/Main/Forms/PreferencesDialog.cpp
@@ -87,7 +87,7 @@ namespace VeraCrypt
// Encryption
AesHwCpuSupportedStaticText->SetLabel (
#ifdef TC_AES_HW_CPU
- (is_aes_hw_cpu_supported() ? LangString["UISTR_YES"] : LangString["UISTR_NO"]));
+ (HasAESNI() ? LangString["UISTR_YES"] : LangString["UISTR_NO"]));
#else
LangString["NOT_APPLICABLE_OR_NOT_AVAILABLE"]);
#endif
diff --git a/src/Main/Forms/PreferencesDialog.h b/src/Main/Forms/PreferencesDialog.h
index 25a0f85..0cd1482 100644
--- a/src/Main/Forms/PreferencesDialog.h
+++ b/src/Main/Forms/PreferencesDialog.h
@@ -54,7 +54,7 @@ namespace VeraCrypt
KeyfilesPanel *DefaultKeyfilesPanel;
int LastVirtualKeyPressed;
- auto_ptr <wxTimer> mTimer;
+ unique_ptr <wxTimer> mTimer;
UserPreferences Preferences;
bool RestoreValidatorBell;
HotkeyList UnregisteredHotkeys;
diff --git a/src/Main/Forms/ProgressWizardPage.h b/src/Main/Forms/ProgressWizardPage.h
index cc50fa6..34f5cf4 100644
--- a/src/Main/Forms/ProgressWizardPage.h
+++ b/src/Main/Forms/ProgressWizardPage.h
@@ -36,7 +36,7 @@ namespace VeraCrypt
void OnAbortButtonClick (wxCommandEvent& event);
void OnTimer ();
- auto_ptr <wxTimer> mTimer;
+ unique_ptr <wxTimer> mTimer;
int PreviousGaugeValue;
uint64 ProgressBarRange;
int RealProgressBarRange;
diff --git a/src/Main/Forms/VolumeCreationProgressWizardPage.h b/src/Main/Forms/VolumeCreationProgressWizardPage.h
index 345ee59..fad4ac9 100644
--- a/src/Main/Forms/VolumeCreationProgressWizardPage.h
+++ b/src/Main/Forms/VolumeCreationProgressWizardPage.h
@@ -48,7 +48,7 @@ namespace VeraCrypt
int PreviousGaugeValue;
uint64 ProgressBarRange;
- auto_ptr <wxTimer> RandomPoolTimer;
+ unique_ptr <wxTimer> RandomPoolTimer;
int RealProgressBarRange;
wxLongLong StartTime;
bool VolumeCreatorRunning;
diff --git a/src/Main/Forms/VolumeCreationWizard.cpp b/src/Main/Forms/VolumeCreationWizard.cpp
index b6d60f4..5d814e8 100644
--- a/src/Main/Forms/VolumeCreationWizard.cpp
+++ b/src/Main/Forms/VolumeCreationWizard.cpp
@@ -14,6 +14,7 @@
#include "Platform/SystemInfo.h"
#ifdef TC_UNIX
#include <unistd.h>
+#include <sys/statvfs.h> // header for statvfs
#include "Platform/Unix/Process.h"
#endif
#include "Core/RandomNumberGenerator.h"
@@ -58,6 +59,7 @@ namespace VeraCrypt
SelectedVolumeHostType (VolumeHostType::File),
SelectedVolumeType (VolumeType::Normal),
Pim (0),
+ OuterPim (0),
SectorSize (0),
VolumeSize (0)
{
@@ -92,6 +94,8 @@ namespace VeraCrypt
VolumeCreationWizard::~VolumeCreationWizard ()
{
+ burn (&Pim, sizeof (Pim));
+ burn (&OuterPim, sizeof (OuterPim));
}
WizardPage *VolumeCreationWizard::GetPage (WizardStep step)
@@ -254,7 +258,10 @@ namespace VeraCrypt
case Step::FormatOptions:
{
- VolumeFormatOptionsWizardPage *page = new VolumeFormatOptionsWizardPage (GetPageParent(), VolumeSize, SectorSize,
+ shared_ptr <VolumeLayout> layout ((OuterVolume || SelectedVolumeType != VolumeType::Hidden)? (VolumeLayout*) new VolumeLayoutV2Normal() : (VolumeLayout*) new VolumeLayoutV2Hidden());
+ uint64 filesystemSize = layout->GetMaxDataSize (VolumeSize);
+
+ VolumeFormatOptionsWizardPage *page = new VolumeFormatOptionsWizardPage (GetPageParent(), filesystemSize, SectorSize,
SelectedVolumePath.IsDevice() && (OuterVolume || SelectedVolumeType != VolumeType::Hidden), OuterVolume, LargeFilesSupport);
page->SetPageTitle (_("Format Options"));
@@ -462,25 +469,7 @@ namespace VeraCrypt
#ifdef TC_UNIX
// Format non-FAT filesystem
- const char *fsFormatter = nullptr;
-
- switch (SelectedFilesystemType)
- {
-#if defined (TC_LINUX)
- case VolumeCreationOptions::FilesystemType::Ext2: fsFormatter = "mkfs.ext2"; break;
- case VolumeCreationOptions::FilesystemType::Ext3: fsFormatter = "mkfs.ext3"; break;
- case VolumeCreationOptions::FilesystemType::Ext4: fsFormatter = "mkfs.ext4"; break;
- case VolumeCreationOptions::FilesystemType::NTFS: fsFormatter = "mkfs.ntfs"; break;
- case VolumeCreationOptions::FilesystemType::exFAT: fsFormatter = "mkfs.exfat"; break;
-#elif defined (TC_MACOSX)
- case VolumeCreationOptions::FilesystemType::MacOsExt: fsFormatter = "newfs_hfs"; break;
- case VolumeCreationOptions::FilesystemType::exFAT: fsFormatter = "newfs_exfat"; break;
- case VolumeCreationOptions::FilesystemType::APFS: fsFormatter = "newfs_apfs"; break;
-#elif defined (TC_FREEBSD) || defined (TC_SOLARIS)
- case VolumeCreationOptions::FilesystemType::UFS: fsFormatter = "newfs" ; break;
-#endif
- default: break;
- }
+ const char *fsFormatter = VolumeCreationOptions::FilesystemType::GetFsFormatter (SelectedFilesystemType);
if (fsFormatter)
{
@@ -498,6 +487,9 @@ namespace VeraCrypt
shared_ptr <VolumeInfo> volume = Core->MountVolume (mountOptions);
finally_do_arg (shared_ptr <VolumeInfo>, volume, { Core->DismountVolume (finally_arg, true); });
+
+ shared_ptr <VolumeLayout> layout((volume->Type == VolumeType::Normal)? (VolumeLayout*) new VolumeLayoutV2Normal() : (VolumeLayout*) new VolumeLayoutV2Hidden());
+ uint64 filesystemSize = layout->GetMaxDataSize (VolumeSize);
Thread::Sleep (2000); // Try to prevent race conditions caused by OS
@@ -540,6 +532,16 @@ namespace VeraCrypt
if (SelectedFilesystemType == VolumeCreationOptions::FilesystemType::NTFS)
args.push_back ("-f");
+ if (SelectedFilesystemType == VolumeCreationOptions::FilesystemType::Btrfs)
+ {
+ args.push_back ("-f");
+ if (filesystemSize < VC_MIN_LARGE_BTRFS_VOLUME_SIZE)
+ {
+ // use mixed mode for small BTRFS volumes
+ args.push_back ("-M");
+ }
+ }
+
args.push_back (string (virtualDevice));
Process::Execute (fsFormatter, args);
@@ -792,13 +794,31 @@ namespace VeraCrypt
// Clear PIM
Pim = 0;
- // Skip PIM
- if (forward && OuterVolume)
+ if (forward && !OuterVolume && SelectedVolumeType == VolumeType::Hidden)
{
- // Use FAT to prevent problems with free space
- QuickFormatEnabled = false;
- SelectedFilesystemType = VolumeCreationOptions::FilesystemType::FAT;
- return Step::CreationProgress;
+ shared_ptr <VolumePassword> hiddenPassword;
+ try
+ {
+ hiddenPassword = Keyfile::ApplyListToPassword (Keyfiles, Password);
+ }
+ catch (...)
+ {
+ hiddenPassword = Password;
+ }
+
+ // check if Outer and Hidden passwords are the same
+ if ( (hiddenPassword && !hiddenPassword->IsEmpty() && OuterPassword && !OuterPassword->IsEmpty() && (*(OuterPassword.get()) == *(hiddenPassword.get())))
+ ||
+ ((!hiddenPassword || hiddenPassword->IsEmpty()) && (!OuterPassword || OuterPassword->IsEmpty()))
+ )
+ {
+ //check if they have also the same PIM
+ if (OuterPim == Pim)
+ {
+ Gui->ShowError (_("The Hidden volume can't have the same password, PIM and keyfiles as the Outer volume"));
+ return GetCurrentStep();
+ }
+ }
}
if (VolumeSize > 4 * BYTES_PER_GB)
@@ -818,15 +838,42 @@ namespace VeraCrypt
VolumePimWizardPage *page = dynamic_cast <VolumePimWizardPage *> (GetCurrentPage());
Pim = page->GetVolumePim();
- if (forward && Password && !Password->IsEmpty())
+ if (-1 == Pim)
+ {
+ // PIM invalid: don't go anywhere
+ Gui->ShowError ("PIM_TOO_BIG");
+ return GetCurrentStep();
+ }
+
+ if (forward && !OuterVolume && SelectedVolumeType == VolumeType::Hidden)
{
- if (-1 == Pim)
+ shared_ptr <VolumePassword> hiddenPassword;
+ try
{
- // PIM invalid: don't go anywhere
- Gui->ShowError ("PIM_TOO_BIG");
- return GetCurrentStep();
+ hiddenPassword = Keyfile::ApplyListToPassword (Keyfiles, Password);
+ }
+ catch (...)
+ {
+ hiddenPassword = Password;
+ }
+
+ // check if Outer and Hidden passwords are the same
+ if ( (hiddenPassword && !hiddenPassword->IsEmpty() && OuterPassword && !OuterPassword->IsEmpty() && (*(OuterPassword.get()) == *(hiddenPassword.get())))
+ ||
+ ((!hiddenPassword || hiddenPassword->IsEmpty()) && (!OuterPassword || OuterPassword->IsEmpty()))
+ )
+ {
+ //check if they have also the same PIM
+ if (OuterPim == Pim)
+ {
+ Gui->ShowError (_("The Hidden volume can't have the same password, PIM and keyfiles as the Outer volume"));
+ return GetCurrentStep();
+ }
}
+ }
+ if (forward && Password && !Password->IsEmpty())
+ {
if (Password->Size() < VolumePassword::WarningSizeThreshold)
{
if (Pim > 0 && Pim < 485)
@@ -844,15 +891,6 @@ namespace VeraCrypt
}
}
-
- if (forward && OuterVolume)
- {
- // Use FAT to prevent problems with free space
- QuickFormatEnabled = false;
- SelectedFilesystemType = VolumeCreationOptions::FilesystemType::FAT;
- return Step::CreationProgress;
- }
-
if (VolumeSize > 4 * BYTES_PER_GB)
{
if (VolumeSize <= TC_MAX_FAT_SECTOR_COUNT * SectorSize)
@@ -888,6 +926,22 @@ namespace VeraCrypt
case Step::FormatOptions:
{
VolumeFormatOptionsWizardPage *page = dynamic_cast <VolumeFormatOptionsWizardPage *> (GetCurrentPage());
+
+ if (forward && OuterVolume)
+ {
+ if (page->GetFilesystemType() != VolumeCreationOptions::FilesystemType::FAT)
+ {
+ if (!Gui->AskYesNo (_("WARNING: You have selected a filesystem other than FAT for the outer volume.\n"
+ "Please Note that in this case VeraCrypt can't calculate the exact maximum allowed size for the hidden volume and it will use only an estimation that can be wrong.\n"
+ "Thus, it is your responsibility to use an adequate value for the size of the hidden volume so that it doesn\'t overlap the outer volume.\n\n"
+ "Do you want to continue using the selected filesystem for the outer volume?")
+ , false, true))
+ {
+ return GetCurrentStep();
+ }
+ }
+ }
+
SelectedFilesystemType = page->GetFilesystemType();
QuickFormatEnabled = page->IsQuickFormatEnabled();
@@ -1026,6 +1080,12 @@ namespace VeraCrypt
Creator.reset();
SetCancelButtonText (L"");
+ // clear saved credentials
+ Password.reset();
+ OuterPassword.reset();
+ burn (&Pim, sizeof (Pim));
+ burn (&OuterPim, sizeof (OuterPim));
+
return Step::VolumeHostType;
case Step::OuterVolumeContents:
@@ -1035,12 +1095,23 @@ namespace VeraCrypt
// require using FUSE and loop device which cannot be used for devices with sectors larger than 512.
wxBusyCursor busy;
+ bool outerVolumeAvailableSpaceValid = false;
+ uint64 outerVolumeAvailableSpace = 0;
MaxHiddenVolumeSize = 0;
Gui->SetActiveFrame (this);
if (MountedOuterVolume)
{
+#ifdef TC_UNIX
+ const DirectoryPath &outerVolumeMountPoint = MountedOuterVolume->MountPoint;
+ struct statvfs stat;
+ if (statvfs(((string)outerVolumeMountPoint).c_str(), &stat) == 0)
+ {
+ outerVolumeAvailableSpace = (uint64) stat.f_bsize * (uint64) stat.f_bavail;
+ outerVolumeAvailableSpaceValid = true;
+ }
+#endif
Core->DismountVolume (MountedOuterVolume);
MountedOuterVolume.reset();
}
@@ -1063,7 +1134,21 @@ namespace VeraCrypt
#endif
shared_ptr <Volume> outerVolume = Core->OpenVolume (make_shared <VolumePath> (SelectedVolumePath), true, Password, Pim, Kdf, false, Keyfiles, VolumeProtection::ReadOnly);
- MaxHiddenVolumeSize = Core->GetMaxHiddenVolumeSize (outerVolume);
+ try
+ {
+ MaxHiddenVolumeSize = Core->GetMaxHiddenVolumeSize (outerVolume);
+ }
+ catch (ParameterIncorrect& )
+ {
+ // Outer volume not using FAT
+ // estimate maximum hidden volume size as 80% of available size of outer volume
+ if (outerVolumeAvailableSpaceValid)
+ {
+ MaxHiddenVolumeSize =(4ULL * outerVolumeAvailableSpace) / 5ULL;
+ }
+ else
+ throw;
+ }
// Add a reserve (in case the user mounts the outer volume and creates new files
// on it by accident or OS writes some new data behind his or her back, such as
@@ -1079,6 +1164,18 @@ namespace VeraCrypt
MaxHiddenVolumeSize -= reservedSize;
MaxHiddenVolumeSize -= MaxHiddenVolumeSize % outerVolume->GetSectorSize(); // Must be a multiple of the sector size
+
+ // remember Outer password and keyfiles in order to be able to compare it with those of Hidden volume
+ try
+ {
+ OuterPassword = Keyfile::ApplyListToPassword (Keyfiles, Password);
+ }
+ catch (...)
+ {
+ OuterPassword = Password;
+ }
+
+ OuterPim = Pim;
}
catch (exception &e)
{
diff --git a/src/Main/Forms/VolumeCreationWizard.h b/src/Main/Forms/VolumeCreationWizard.h
index c408742..fd4b3e0 100644
--- a/src/Main/Forms/VolumeCreationWizard.h
+++ b/src/Main/Forms/VolumeCreationWizard.h
@@ -67,8 +67,8 @@ namespace VeraCrypt
bool CrossPlatformSupport;
static bool DeviceWarningConfirmed;
bool DisplayKeyInfo;
- auto_ptr <wxTimer> ProgressTimer;
- auto_ptr <wxTimer> RandomPoolUpdateTimer;
+ unique_ptr <wxTimer> ProgressTimer;
+ unique_ptr <wxTimer> RandomPoolUpdateTimer;
shared_ptr <KeyfileList> Keyfiles;
bool LargeFilesSupport;
uint64 MaxHiddenVolumeSize;
@@ -82,7 +82,9 @@ namespace VeraCrypt
VolumeHostType::Enum SelectedVolumeHostType;
VolumeType::Enum SelectedVolumeType;
shared_ptr <VolumePassword> Password;
+ shared_ptr <VolumePassword> OuterPassword;
int Pim;
+ int OuterPim;
shared_ptr <Pkcs5Kdf> Kdf;
uint32 SectorSize;
shared_ptr <Hash> SelectedHash;
diff --git a/src/Main/Forms/VolumeFormatOptionsWizardPage.cpp b/src/Main/Forms/VolumeFormatOptionsWizardPage.cpp
index 3865705..d3bd521 100644
--- a/src/Main/Forms/VolumeFormatOptionsWizardPage.cpp
+++ b/src/Main/Forms/VolumeFormatOptionsWizardPage.cpp
@@ -17,7 +17,7 @@
namespace VeraCrypt
{
- VolumeFormatOptionsWizardPage::VolumeFormatOptionsWizardPage (wxPanel* parent, uint64 volumeSize, uint32 sectorSize, bool enableQuickFormatButton, bool disableNoneFilesystem, bool disable32bitFilesystems)
+ VolumeFormatOptionsWizardPage::VolumeFormatOptionsWizardPage (wxPanel* parent, uint64 filesystemSize, uint32 sectorSize, bool enableQuickFormatButton, bool disableNoneFilesystem, bool disable32bitFilesystems)
: VolumeFormatOptionsWizardPageBase (parent)
{
InfoStaticText->SetLabel (_(
@@ -26,7 +26,7 @@ namespace VeraCrypt
if (!disableNoneFilesystem)
FilesystemTypeChoice->Append (LangString["NONE"], (void *) VolumeCreationOptions::FilesystemType::None);
- if (!disable32bitFilesystems && volumeSize <= TC_MAX_FAT_SECTOR_COUNT * sectorSize)
+ if (!disable32bitFilesystems && filesystemSize <= TC_MAX_FAT_SECTOR_COUNT * sectorSize)
FilesystemTypeChoice->Append (L"FAT", (void *) VolumeCreationOptions::FilesystemType::FAT);
#ifdef TC_WINDOWS
@@ -35,9 +35,18 @@ namespace VeraCrypt
#elif defined (TC_LINUX)
FilesystemTypeChoice->Append (L"Linux Ext2", (void *) VolumeCreationOptions::FilesystemType::Ext2);
FilesystemTypeChoice->Append (L"Linux Ext3", (void *) VolumeCreationOptions::FilesystemType::Ext3);
- FilesystemTypeChoice->Append (L"Linux Ext4", (void *) VolumeCreationOptions::FilesystemType::Ext4);
- FilesystemTypeChoice->Append (L"NTFS", (void *) VolumeCreationOptions::FilesystemType::NTFS);
- FilesystemTypeChoice->Append (L"exFAT", (void *) VolumeCreationOptions::FilesystemType::exFAT);
+ if (VolumeCreationOptions::FilesystemType::IsFsFormatterPresent (VolumeCreationOptions::FilesystemType::Ext4))
+ FilesystemTypeChoice->Append (L"Linux Ext4", (void *) VolumeCreationOptions::FilesystemType::Ext4);
+ if (VolumeCreationOptions::FilesystemType::IsFsFormatterPresent (VolumeCreationOptions::FilesystemType::NTFS))
+ FilesystemTypeChoice->Append (L"NTFS", (void *) VolumeCreationOptions::FilesystemType::NTFS);
+ if (VolumeCreationOptions::FilesystemType::IsFsFormatterPresent (VolumeCreationOptions::FilesystemType::exFAT))
+ FilesystemTypeChoice->Append (L"exFAT", (void *) VolumeCreationOptions::FilesystemType::exFAT);
+ if (VolumeCreationOptions::FilesystemType::IsFsFormatterPresent (VolumeCreationOptions::FilesystemType::Btrfs))
+ {
+ // minimum size to be able to format as Btrfs is 16777216 bytes
+ if (filesystemSize >= VC_MIN_SMALL_BTRFS_VOLUME_SIZE)
+ FilesystemTypeChoice->Append (L"Btrfs", (void *) VolumeCreationOptions::FilesystemType::Btrfs);
+ }
#elif defined (TC_MACOSX)
FilesystemTypeChoice->Append (L"Mac OS Extended", (void *) VolumeCreationOptions::FilesystemType::MacOsExt);
FilesystemTypeChoice->Append (L"exFAT", (void *) VolumeCreationOptions::FilesystemType::exFAT);
@@ -47,7 +56,7 @@ namespace VeraCrypt
FilesystemTypeChoice->Append (L"UFS", (void *) VolumeCreationOptions::FilesystemType::UFS);
#endif
- if (!disable32bitFilesystems && volumeSize <= TC_MAX_FAT_SECTOR_COUNT * sectorSize)
+ if (!disable32bitFilesystems && filesystemSize <= TC_MAX_FAT_SECTOR_COUNT * sectorSize)
SetFilesystemType (VolumeCreationOptions::FilesystemType::FAT);
else
SetFilesystemType (VolumeCreationOptions::FilesystemType::GetPlatformNative());
@@ -83,6 +92,7 @@ namespace VeraCrypt
case VolumeCreationOptions::FilesystemType::Ext2: FilesystemTypeChoice->SetStringSelection (L"Linux Ext2"); break;
case VolumeCreationOptions::FilesystemType::Ext3: FilesystemTypeChoice->SetStringSelection (L"Linux Ext3"); break;
case VolumeCreationOptions::FilesystemType::Ext4: FilesystemTypeChoice->SetStringSelection (L"Linux Ext4"); break;
+ case VolumeCreationOptions::FilesystemType::Btrfs: FilesystemTypeChoice->SetStringSelection (L"Btrfs"); break;
case VolumeCreationOptions::FilesystemType::MacOsExt: FilesystemTypeChoice->SetStringSelection (L"Mac OS Extended"); break;
case VolumeCreationOptions::FilesystemType::APFS: FilesystemTypeChoice->SetStringSelection (L"APFS"); break;
case VolumeCreationOptions::FilesystemType::UFS: FilesystemTypeChoice->SetStringSelection (L"UFS"); break;
diff --git a/src/Main/Forms/VolumeFormatOptionsWizardPage.h b/src/Main/Forms/VolumeFormatOptionsWizardPage.h
index 25ca2b3..b38f6e9 100644
--- a/src/Main/Forms/VolumeFormatOptionsWizardPage.h
+++ b/src/Main/Forms/VolumeFormatOptionsWizardPage.h
@@ -21,7 +21,7 @@ namespace VeraCrypt
class VolumeFormatOptionsWizardPage : public VolumeFormatOptionsWizardPageBase
{
public:
- VolumeFormatOptionsWizardPage (wxPanel* parent, uint64 volumeSize, uint32 sectorSize, bool enableQuickFormatButton = true, bool disableNoneFilesystem = false, bool disable32bitFilesystems = false);
+ VolumeFormatOptionsWizardPage (wxPanel* parent, uint64 filesystemSize, uint32 sectorSize, bool enableQuickFormatButton = true, bool disableNoneFilesystem = false, bool disable32bitFilesystems = false);
VolumeCreationOptions::FilesystemType::Enum GetFilesystemType () const;
bool IsValid () { return true; }
diff --git a/src/Main/Forms/VolumeSizeWizardPage.cpp b/src/Main/Forms/VolumeSizeWizardPage.cpp
index 3781b05..fc045b5 100644
--- a/src/Main/Forms/VolumeSizeWizardPage.cpp
+++ b/src/Main/Forms/VolumeSizeWizardPage.cpp
@@ -103,7 +103,7 @@ namespace VeraCrypt
try
{
uint64 uiVolumeSize = GetVolumeSize();
- if (uiVolumeSize >= MinVolumeSize && (!MaxVolumeSizeValid || uiVolumeSize <= MaxVolumeSize) && (CmdLine->ArgDisableFileSizeCheck || !AvailableDiskSpace || uiVolumeSize <= AvailableDiskSpace))
+ if (uiVolumeSize >= MinVolumeSize && (!MaxVolumeSizeValid || uiVolumeSize <= MaxVolumeSize) && (MaxVolumeSizeValid || CmdLine->ArgDisableFileSizeCheck || !AvailableDiskSpace || uiVolumeSize <= AvailableDiskSpace))
return true;
}
catch (...) { }
diff --git a/src/Main/GraphicUserInterface.cpp b/src/Main/GraphicUserInterface.cpp
index b7b4cf4..f1bb87b 100755
--- a/src/Main/GraphicUserInterface.cpp
+++ b/src/Main/GraphicUserInterface.cpp
@@ -344,7 +344,7 @@ namespace VeraCrypt
void GraphicUserInterface::BeginInteractiveBusyState (wxWindow *window)
{
- static auto_ptr <wxCursor> arrowWaitCursor;
+ static unique_ptr <wxCursor> arrowWaitCursor;
if (arrowWaitCursor.get() == nullptr)
arrowWaitCursor.reset (new wxCursor (wxCURSOR_ARROWWAIT));
@@ -409,7 +409,7 @@ namespace VeraCrypt
void GraphicUserInterface::EndInteractiveBusyState (wxWindow *window) const
{
- static auto_ptr <wxCursor> arrowCursor;
+ static unique_ptr <wxCursor> arrowCursor;
if (arrowCursor.get() == nullptr)
arrowCursor.reset (new wxCursor (wxCURSOR_ARROW));
@@ -632,7 +632,7 @@ namespace VeraCrypt
try
{
- SecurityToken::InitLibrary (Preferences.SecurityTokenModule, auto_ptr <GetPinFunctor> (new PinRequestHandler), auto_ptr <SendExceptionFunctor> (new WarningHandler));
+ SecurityToken::InitLibrary (Preferences.SecurityTokenModule, unique_ptr <GetPinFunctor> (new PinRequestHandler), unique_ptr <SendExceptionFunctor> (new WarningHandler));
}
catch (Exception &e)
{
@@ -965,8 +965,8 @@ namespace VeraCrypt
wxConnectionBase *OnMakeConnection () { return new Connection; }
};
- auto_ptr <wxDDEClient> client (new Client);
- auto_ptr <wxConnectionBase> connection (client->MakeConnection (L"localhost", serverName, L"raise"));
+ unique_ptr <wxDDEClient> client (new Client);
+ unique_ptr <wxConnectionBase> connection (client->MakeConnection (L"localhost", serverName, L"raise"));
if (connection.get() && connection->Execute (nullptr))
{
diff --git a/src/Main/GraphicUserInterface.h b/src/Main/GraphicUserInterface.h
index 01f385a..06ea677 100644
--- a/src/Main/GraphicUserInterface.h
+++ b/src/Main/GraphicUserInterface.h
@@ -129,10 +129,10 @@ namespace VeraCrypt
wxFrame *ActiveFrame;
bool BackgroundMode;
#ifdef TC_WINDOWS
- auto_ptr <wxDDEServer> DDEServer;
+ unique_ptr <wxDDEServer> DDEServer;
#endif
wxFrame *mMainFrame;
- auto_ptr <wxSingleInstanceChecker> SingleInstanceChecker;
+ unique_ptr <wxSingleInstanceChecker> SingleInstanceChecker;
mutable WaitDialog* mWaitDialog;
public:
diff --git a/src/Main/Main.make b/src/Main/Main.make
index a154a84..18efba6 100755
--- a/src/Main/Main.make
+++ b/src/Main/Main.make
@@ -82,14 +82,10 @@ CXXFLAGS += -I$(BASE_DIR)/Main
#------ wxWidgets configuration ------
ifdef TC_NO_GUI
-ifdef VC_WX_STATIC
WX_CONFIG_LIBS := base
else
WX_CONFIG_LIBS := adv,core,base
endif
-else
-WX_CONFIG_LIBS := adv,core,base
-endif
ifeq "$(TC_BUILD_CONFIG)" "Release"
diff --git a/src/Main/TextUserInterface.cpp b/src/Main/TextUserInterface.cpp
index 4de2cb2..0ad0b95 100644
--- a/src/Main/TextUserInterface.cpp
+++ b/src/Main/TextUserInterface.cpp
@@ -785,6 +785,7 @@ namespace VeraCrypt
ShowInfo (L" 5) Linux Ext4"); filesystems.push_back (VolumeCreationOptions::FilesystemType::Ext4);
ShowInfo (L" 6) NTFS"); filesystems.push_back (VolumeCreationOptions::FilesystemType::NTFS);
ShowInfo (L" 7) exFAT"); filesystems.push_back (VolumeCreationOptions::FilesystemType::exFAT);
+ ShowInfo (L" 8) Btrfs"); filesystems.push_back (VolumeCreationOptions::FilesystemType::Btrfs);
#elif defined (TC_MACOSX)
ShowInfo (L" 3) Mac OS Extended"); filesystems.push_back (VolumeCreationOptions::FilesystemType::MacOsExt);
ShowInfo (L" 4) exFAT"); filesystems.push_back (VolumeCreationOptions::FilesystemType::exFAT);
@@ -808,6 +809,12 @@ namespace VeraCrypt
throw_err (_("Specified volume size cannot be used with FAT filesystem."));
}
+ if (options->Filesystem == VolumeCreationOptions::FilesystemType::Btrfs
+ && (filesystemSize < VC_MIN_SMALL_BTRFS_VOLUME_SIZE))
+ {
+ throw_err (_("Specified volume size is too small to be used with Btrfs filesystem."));
+ }
+
// Password
if (!options->Password && !Preferences.NonInteractive)
{
@@ -875,25 +882,9 @@ namespace VeraCrypt
if (options->Filesystem != VolumeCreationOptions::FilesystemType::None
&& options->Filesystem != VolumeCreationOptions::FilesystemType::FAT)
{
- const char *fsFormatter = nullptr;
-
- switch (options->Filesystem)
- {
-#if defined (TC_LINUX)
- case VolumeCreationOptions::FilesystemType::Ext2: fsFormatter = "mkfs.ext2"; break;
- case VolumeCreationOptions::FilesystemType::Ext3: fsFormatter = "mkfs.ext3"; break;
- case VolumeCreationOptions::FilesystemType::Ext4: fsFormatter = "mkfs.ext4"; break;
- case VolumeCreationOptions::FilesystemType::NTFS: fsFormatter = "mkfs.ntfs"; break;
- case VolumeCreationOptions::FilesystemType::exFAT: fsFormatter = "mkfs.exfat"; break;
-#elif defined (TC_MACOSX)
- case VolumeCreationOptions::FilesystemType::MacOsExt: fsFormatter = "newfs_hfs"; break;
- case VolumeCreationOptions::FilesystemType::exFAT: fsFormatter = "newfs_exfat"; break;
- case VolumeCreationOptions::FilesystemType::APFS: fsFormatter = "newfs_apfs"; break;
-#elif defined (TC_FREEBSD) || defined (TC_SOLARIS)
- case VolumeCreationOptions::FilesystemType::UFS: fsFormatter = "newfs" ; break;
-#endif
- default: throw ParameterIncorrect (SRC_POS);
- }
+ const char *fsFormatter = VolumeCreationOptions::FilesystemType::GetFsFormatter (options->Filesystem);
+ if (!fsFormatter)
+ throw ParameterIncorrect (SRC_POS);
MountOptions mountOptions (GetPreferences().DefaultMountOptions);
mountOptions.Path = make_shared <VolumePath> (options->Path);
@@ -947,6 +938,16 @@ namespace VeraCrypt
if (options->Filesystem == VolumeCreationOptions::FilesystemType::NTFS)
args.push_back ("-f");
+ if (options->Filesystem == VolumeCreationOptions::FilesystemType::Btrfs)
+ {
+ args.push_back ("-f");
+ if (filesystemSize < VC_MIN_LARGE_BTRFS_VOLUME_SIZE)
+ {
+ // use mixed mode for small BTRFS volumes
+ args.push_back ("-M");
+ }
+ }
+
args.push_back (string (virtualDevice));
Process::Execute (fsFormatter, args);
@@ -1156,7 +1157,7 @@ namespace VeraCrypt
try
{
- SecurityToken::InitLibrary (Preferences.SecurityTokenModule, auto_ptr <GetPinFunctor> (new PinRequestHandler (this)), auto_ptr <SendExceptionFunctor> (new WarningHandler (this)));
+ SecurityToken::InitLibrary (Preferences.SecurityTokenModule, unique_ptr <GetPinFunctor> (new PinRequestHandler (this)), unique_ptr <SendExceptionFunctor> (new WarningHandler (this)));
}
catch (Exception &e)
{
diff --git a/src/Main/TextUserInterface.h b/src/Main/TextUserInterface.h
index 95db02d..14eb2c0 100644
--- a/src/Main/TextUserInterface.h
+++ b/src/Main/TextUserInterface.h
@@ -47,7 +47,9 @@ namespace VeraCrypt
virtual void ExportSecurityTokenKeyfile () const;
virtual shared_ptr <GetStringFunctor> GetAdminPasswordRequestHandler ();
virtual void ImportSecurityTokenKeyfiles () const;
+#ifndef TC_NO_GUI
virtual bool Initialize (int &argc, wxChar **argv) { return wxAppBase::Initialize(argc, argv); }
+#endif
virtual void InitSecurityTokenLibrary () const;
virtual void ListSecurityTokenKeyfiles () const;
virtual VolumeInfoList MountAllDeviceHostedVolumes (MountOptions &options) const;
@@ -67,8 +69,8 @@ namespace VeraCrypt
virtual void ReadInputStreamLine (wxString &line) const;
virtual wxString ReadInputStreamLine () const;
- auto_ptr <wxFFileInputStream> FInputStream;
- auto_ptr <wxTextInputStream> TextInputStream;
+ unique_ptr <wxFFileInputStream> FInputStream;
+ unique_ptr <wxTextInputStream> TextInputStream;
private:
TextUserInterface (const TextUserInterface &);
diff --git a/src/Main/UserPreferences.cpp b/src/Main/UserPreferences.cpp
index e4cc494..db54b4a 100644
--- a/src/Main/UserPreferences.cpp
+++ b/src/Main/UserPreferences.cpp
@@ -21,7 +21,7 @@ namespace VeraCrypt
{
if (cfgText == L"0")
cfgVar = false;
- else if (cfgText == L"1")
+ else
cfgVar = true;
}
@@ -93,7 +93,7 @@ namespace VeraCrypt
TC_CONFIG_SET (MountDevicesOnLogon);
TC_CONFIG_SET (MountFavoritesOnLogon);
- bool readOnly;
+ bool readOnly = false;
SetValue (configMap[L"MountVolumesReadOnly"], readOnly);
DefaultMountOptions.Protection = readOnly ? VolumeProtection::ReadOnly : VolumeProtection::None;
diff --git a/src/Main/Xml.h b/src/Main/Xml.h
index 78c3027..27f0b82 100644
--- a/src/Main/Xml.h
+++ b/src/Main/Xml.h
@@ -66,8 +66,8 @@ namespace VeraCrypt
protected:
int CurrentIndentLevel;
- auto_ptr <wxMemoryOutputStream> MemOutStream;
- auto_ptr <wxTextOutputStream> TextOutStream;
+ unique_ptr <wxMemoryOutputStream> MemOutStream;
+ unique_ptr <wxTextOutputStream> TextOutStream;
File OutFile;
private:
diff --git a/src/Makefile b/src/Makefile
index fe0c143..a1e1e43 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -69,7 +69,7 @@ endif
ifeq "$(origin NOGUI)" "command line"
export TC_NO_GUI := 1
- C_CXX_FLAGS += -DTC_NO_GUI
+ C_CXX_FLAGS += -DTC_NO_GUI -DwxUSE_GUI=0
WX_CONFIGURE_FLAGS += --disable-gui
endif
@@ -151,6 +151,7 @@ endif
ifeq "$(origin NOASM)" "command line"
CPU_ARCH = unknown
+ C_CXX_FLAGS += -DCRYPTOPP_DISABLE_X86ASM
endif
ifeq "$(CPU_ARCH)" "x86"
@@ -299,6 +300,7 @@ ifeq "$(shell uname -s)" "Darwin"
LFLAGS += -arch i386
WX_CONFIGURE_FLAGS += --enable-universal_binary=i386,x86_64
else
+ CXXFLAGS += -std=c++11
WX_CONFIGURE_FLAGS += --disable-universal_binary
endif
diff --git a/src/Mount/MainCom.cpp b/src/Mount/MainCom.cpp
index a409670..8525a28 100644
--- a/src/Mount/MainCom.cpp
+++ b/src/Mount/MainCom.cpp
@@ -71,19 +71,19 @@ public:
return S_OK;
}
- virtual void STDMETHODCALLTYPE AnalyzeKernelMiniDump (LONG_PTR hwndDlg)
+ virtual void STDMETHODCALLTYPE AnalyzeKernelMiniDump (__int64 hwndDlg)
{
// Do nothing
MainDlg = (HWND) hwndDlg;
}
- virtual int STDMETHODCALLTYPE BackupVolumeHeader (LONG_PTR hwndDlg, BOOL bRequireConfirmation, BSTR lpszVolume)
+ virtual int STDMETHODCALLTYPE BackupVolumeHeader (__int64 hwndDlg, BOOL bRequireConfirmation, BSTR lpszVolume)
{
MainDlg = (HWND) hwndDlg;
return ::BackupVolumeHeader ((HWND) hwndDlg, bRequireConfirmation, lpszVolume);
}
- virtual int STDMETHODCALLTYPE RestoreVolumeHeader (LONG_PTR hwndDlg, BSTR lpszVolume)
+ virtual int STDMETHODCALLTYPE RestoreVolumeHeader (__int64 hwndDlg, BSTR lpszVolume)
{
MainDlg = (HWND) hwndDlg;
return ::RestoreVolumeHeader ((HWND) hwndDlg, lpszVolume);
@@ -94,7 +94,7 @@ public:
return BaseCom::CallDriver (ioctl, input, output);
}
- virtual int STDMETHODCALLTYPE ChangePassword (BSTR volumePath, Password *oldPassword, Password *newPassword, int pkcs5, int wipePassCount, LONG_PTR hWnd)
+ virtual int STDMETHODCALLTYPE ChangePassword (BSTR volumePath, Password *oldPassword, Password *newPassword, int pkcs5, int wipePassCount, __int64 hWnd)
{
MainDlg = (HWND) hWnd;
return ::ChangePwd (volumePath, oldPassword, 0, 0, FALSE, newPassword, pkcs5, 0, wipePassCount, (HWND) hWnd);
@@ -140,19 +140,19 @@ public:
return BaseCom::WriteLocalMachineRegistryDwordValue (keyPath, valueName, value);
}
- virtual int STDMETHODCALLTYPE ChangePasswordEx (BSTR volumePath, Password *oldPassword, int old_pkcs5, Password *newPassword, int pkcs5, int wipePassCount, LONG_PTR hWnd)
+ virtual int STDMETHODCALLTYPE ChangePasswordEx (BSTR volumePath, Password *oldPassword, int old_pkcs5, Password *newPassword, int pkcs5, int wipePassCount, __int64 hWnd)
{
MainDlg = (HWND) hWnd;
return ::ChangePwd (volumePath, oldPassword, old_pkcs5, 0, FALSE, newPassword, pkcs5, 0, wipePassCount, (HWND) hWnd);
}
- virtual int STDMETHODCALLTYPE ChangePasswordEx2 (BSTR volumePath, Password *oldPassword, int old_pkcs5, BOOL truecryptMode, Password *newPassword, int pkcs5, int wipePassCount, LONG_PTR hWnd)
+ virtual int STDMETHODCALLTYPE ChangePasswordEx2 (BSTR volumePath, Password *oldPassword, int old_pkcs5, BOOL truecryptMode, Password *newPassword, int pkcs5, int wipePassCount, __int64 hWnd)
{
MainDlg = (HWND) hWnd;
return ::ChangePwd (volumePath, oldPassword, old_pkcs5, 0, truecryptMode, newPassword, pkcs5, 0, wipePassCount, (HWND) hWnd);
}
- virtual int STDMETHODCALLTYPE ChangePasswordEx3 (BSTR volumePath, Password *oldPassword, int old_pkcs5, int old_pim, BOOL truecryptMode, Password *newPassword, int pkcs5, int pim, int wipePassCount, LONG_PTR hWnd)
+ virtual int STDMETHODCALLTYPE ChangePasswordEx3 (BSTR volumePath, Password *oldPassword, int old_pkcs5, int old_pim, BOOL truecryptMode, Password *newPassword, int pkcs5, int pim, int wipePassCount, __int64 hWnd)
{
MainDlg = (HWND) hWnd;
return ::ChangePwd (volumePath, oldPassword, old_pkcs5, old_pim, truecryptMode, newPassword, pkcs5, pim, wipePassCount, (HWND) hWnd);
@@ -274,7 +274,7 @@ extern "C" int UacBackupVolumeHeader (HWND hwndDlg, BOOL bRequireConfirmation, w
if (bstr)
{
volumeBstr.Attach (bstr);
- r = tc->BackupVolumeHeader ((LONG_PTR) hwndDlg, bRequireConfirmation, volumeBstr);
+ r = tc->BackupVolumeHeader ((__int64) hwndDlg, bRequireConfirmation, volumeBstr);
}
else
r = ERR_OUTOFMEMORY;
@@ -302,7 +302,7 @@ extern "C" int UacRestoreVolumeHeader (HWND hwndDlg, wchar_t *lpszVolume)
if (bstr)
{
volumeBstr.Attach (bstr);
- r = tc->RestoreVolumeHeader ((LONG_PTR) hwndDlg, volumeBstr);
+ r = tc->RestoreVolumeHeader ((__int64) hwndDlg, volumeBstr);
}
else
r = ERR_OUTOFMEMORY;
@@ -327,7 +327,7 @@ extern "C" int UacChangePwd (wchar_t *lpszVolume, Password *oldPassword, int old
{
CComBSTR bstrVolume (lpszVolume);
WaitCursor ();
- r = tc->ChangePasswordEx3 (bstrVolume, oldPassword, old_pkcs5, old_pim, truecryptMode, newPassword, pkcs5, pim, wipePassCount, (LONG_PTR) hwndDlg);
+ r = tc->ChangePasswordEx3 (bstrVolume, oldPassword, old_pkcs5, old_pim, truecryptMode, newPassword, pkcs5, pim, wipePassCount, (__int64) hwndDlg);
NormalCursor ();
}
else
diff --git a/src/Mount/MainCom.idl b/src/Mount/MainCom.idl
index bb94975..fae86c5 100644
--- a/src/Mount/MainCom.idl
+++ b/src/Mount/MainCom.idl
@@ -16,7 +16,7 @@ import "..\Common\Password.h";
[
uuid(9ACF6176-5FC4-4690-A025-B3306A50EB6A),
helpstring("VeraCrypt Main UAC Support Library"),
- version(2.10) // Update ComSetup.cpp when changing version number
+ version(2.11) // Update ComSetup.cpp when changing version number
]
library TrueCryptMainCom
{
@@ -28,22 +28,22 @@ library TrueCryptMainCom
]
interface ITrueCryptMainCom : IUnknown
{
- void AnalyzeKernelMiniDump (LONG_PTR hwndDlg);
- int BackupVolumeHeader (LONG_PTR hwndDlg, BOOL bRequireConfirmation, BSTR lpszVolume);
+ void AnalyzeKernelMiniDump (__int64 hwndDlg);
+ int BackupVolumeHeader (__int64 hwndDlg, BOOL bRequireConfirmation, BSTR lpszVolume);
DWORD CallDriver (DWORD ioctl, BSTR input, BSTR *output);
- int ChangePassword (BSTR volumePath, Password *oldPassword, Password *newPassword, int pkcs5, int wipePassCount, LONG_PTR hWnd);
+ int ChangePassword (BSTR volumePath, Password *oldPassword, Password *newPassword, int pkcs5, int wipePassCount, __int64 hWnd);
DWORD CopyFile (BSTR sourceFile, BSTR destinationFile);
DWORD DeleteFile (BSTR file);
BOOL IsPagingFileActive (BOOL checkNonWindowsPartitionsOnly);
DWORD ReadWriteFile (BOOL write, BOOL device, BSTR filePath, BSTR *bufferBstr, unsigned __int64 offset, unsigned __int32 size, DWORD *sizeDone);
DWORD RegisterFilterDriver (BOOL registerDriver, int filterType);
DWORD RegisterSystemFavoritesService (BOOL registerService);
- int RestoreVolumeHeader (LONG_PTR hwndDlg, BSTR lpszVolume);
+ int RestoreVolumeHeader (__int64 hwndDlg, BSTR lpszVolume);
DWORD SetDriverServiceStartType (DWORD startType);
DWORD WriteLocalMachineRegistryDwordValue (BSTR keyPath, BSTR valueName, DWORD value);
- int ChangePasswordEx (BSTR volumePath, Password *oldPassword, int old_pkcs5, Password *newPassword, int pkcs5, int wipePassCount, LONG_PTR hWnd);
- int ChangePasswordEx2 (BSTR volumePath, Password *oldPassword, int old_pkcs5, BOOL truecryptMode, Password *newPassword, int pkcs5, int wipePassCount, LONG_PTR hWnd);
- int ChangePasswordEx3 (BSTR volumePath, Password *oldPassword, int old_pkcs5, int old_pim, BOOL truecryptMode, Password *newPassword, int pkcs5, int pim, int wipePassCount, LONG_PTR hWnd);
+ int ChangePasswordEx (BSTR volumePath, Password *oldPassword, int old_pkcs5, Password *newPassword, int pkcs5, int wipePassCount, __int64 hWnd);
+ int ChangePasswordEx2 (BSTR volumePath, Password *oldPassword, int old_pkcs5, BOOL truecryptMode, Password *newPassword, int pkcs5, int wipePassCount, __int64 hWnd);
+ int ChangePasswordEx3 (BSTR volumePath, Password *oldPassword, int old_pkcs5, int old_pim, BOOL truecryptMode, Password *newPassword, int pkcs5, int pim, int wipePassCount, __int64 hWnd);
DWORD GetFileSize (BSTR filePath, unsigned __int64* pSize);
DWORD DeviceIoControl (BOOL readOnly, BOOL device, BSTR filePath, DWORD dwIoControlCode, BSTR input, BSTR *output);
DWORD InstallEfiBootLoader (BOOL preserveUserConfig, BOOL hiddenOSCreation, int pim, int hashAlg);
diff --git a/src/Mount/Mount.c b/src/Mount/Mount.c
index 9130eae..07980c7 100644
--- a/src/Mount/Mount.c
+++ b/src/Mount/Mount.c
@@ -49,6 +49,7 @@
#include "../Platform/Finally.h"
#include "../Platform/ForEach.h"
#include "../Setup/SelfExtract.h"
+#include "../Common/EncryptionThreadPool.h"
#include <Strsafe.h>
#include <InitGuid.h>
@@ -64,6 +65,17 @@
typedef BOOL (WINAPI *WTSREGISTERSESSIONNOTIFICATION)(HWND, DWORD);
typedef BOOL (WINAPI *WTSUNREGISTERSESSIONNOTIFICATION)(HWND);
+#ifndef _HPOWERNOTIFY_DEF_
+#define _HPOWERNOTIFY_DEF_
+
+typedef PVOID HPOWERNOTIFY;
+typedef HPOWERNOTIFY *PHPOWERNOTIFY;
+
+#endif
+
+typedef HPOWERNOTIFY (WINAPI *REGISTERSUSPENDRESUMENOTIFICATION)(HANDLE hRecipient, DWORD Flags);
+typedef BOOL (WINAPI *UNREGISTERSUSPENDRESUMENOTIFICATION) (HPOWERNOTIFY Handle);
+
using namespace VeraCrypt;
enum timer_ids
@@ -158,14 +170,14 @@ MountOptions CmdMountOptions;
BOOL CmdMountOptionsValid = FALSE;
MountOptions mountOptions;
MountOptions defaultMountOptions;
-KeyFile *FirstCmdKeyFile;
+KeyFile *FirstCmdKeyFile = NULL;
HBITMAP hbmLogoBitmapRescaled = NULL;
wchar_t OrigKeyboardLayout [8+1] = L"00000409";
BOOL bKeyboardLayoutChanged = FALSE; /* TRUE if the keyboard layout was changed to the standard US keyboard layout (from any other layout). */
BOOL bKeybLayoutAltKeyWarningShown = FALSE; /* TRUE if the user has been informed that it is not possible to type characters by pressing keys while the right Alt key is held down. */
-static KeyFilesDlgParam hidVolProtKeyFilesParam;
+static KeyFilesDlgParam hidVolProtKeyFilesParam = {0};
static MOUNT_LIST_STRUCT LastKnownMountList = {0};
VOLUME_NOTIFICATIONS_LIST VolumeNotificationsList;
@@ -181,12 +193,20 @@ static int bPrebootPasswordDlgMode = FALSE;
static int NoCmdLineArgs;
static BOOL CmdLineVolumeSpecified;
static int LastDriveListVolumeColumnWidth;
+static BOOL ExitMailSlotSpecified = FALSE;
+static TCHAR ExitMailSlotName[MAX_PATH];
// WTS handling
static HMODULE hWtsLib = NULL;
static WTSREGISTERSESSIONNOTIFICATION fnWtsRegisterSessionNotification = NULL;
static WTSUNREGISTERSESSIONNOTIFICATION fnWtsUnRegisterSessionNotification = NULL;
-static void RegisterWtsNotification(HWND hWnd)
+// Used to opt-in to receive notification about power events.
+// This is mandatory to support Windows 10 Modern Standby and Windows 8.1 Connected Standby power model.
+// https://docs.microsoft.com/en-us/windows-hardware/design/device-experiences/prepare-software-for-modern-standby
+// https://docs.microsoft.com/en-us/windows/win32/w8cookbook/desktop-activity-moderator?redirectedfrom=MSDN
+static HPOWERNOTIFY g_hPowerNotify = NULL;
+
+static void RegisterWtsAndPowerNotification(HWND hWnd)
{
if (!hWtsLib)
{
@@ -213,9 +233,19 @@ static void RegisterWtsNotification(HWND hWnd)
}
}
}
+
+ if (IsOSAtLeast (WIN_8))
+ {
+ REGISTERSUSPENDRESUMENOTIFICATION fnRegisterSuspendResumeNotification = (REGISTERSUSPENDRESUMENOTIFICATION) GetProcAddress (GetModuleHandle (L"user32.dll"), "RegisterSuspendResumeNotification");
+ if (fnRegisterSuspendResumeNotification)
+ {
+ g_hPowerNotify = fnRegisterSuspendResumeNotification ((HANDLE) hWnd, DEVICE_NOTIFY_WINDOW_HANDLE);
+ }
+
+ }
}
-static void UnregisterWtsNotification(HWND hWnd)
+static void UnregisterWtsAndPowerNotification(HWND hWnd)
{
if (hWtsLib && fnWtsUnRegisterSessionNotification)
{
@@ -225,6 +255,14 @@ static void UnregisterWtsNotification(HWND hWnd)
fnWtsRegisterSessionNotification = NULL;
fnWtsUnRegisterSessionNotification = NULL;
}
+
+ if (IsOSAtLeast (WIN_8) && g_hPowerNotify)
+ {
+ UNREGISTERSUSPENDRESUMENOTIFICATION fnUnregisterSuspendResumeNotification = (UNREGISTERSUSPENDRESUMENOTIFICATION) GetProcAddress (GetModuleHandle (L"user32.dll"), "UnregisterSuspendResumeNotification");
+ if (fnUnregisterSuspendResumeNotification)
+ fnUnregisterSuspendResumeNotification (g_hPowerNotify);
+ g_hPowerNotify = NULL;
+ }
}
static std::vector<MSXML2::IXMLDOMNodePtr> GetReadChildNodes (MSXML2::IXMLDOMNodeListPtr childs)
@@ -375,6 +413,9 @@ static void localcleanup (void)
burn (&defaultMountOptions, sizeof (defaultMountOptions));
burn (szFileName, sizeof(szFileName));
+ KeyFileRemoveAll (&FirstCmdKeyFile);
+ KeyFileRemoveAll (&hidVolProtKeyFilesParam.FirstKeyFile);
+
/* Cleanup common code resources */
cleanup ();
@@ -430,7 +471,7 @@ void EndMainDlg (HWND hwndDlg)
KillTimer (hwndDlg, TIMER_ID_MAIN);
KillTimer (hwndDlg, TIMER_ID_UPDATE_DEVICE_LIST);
TaskBarIconRemove (hwndDlg);
- UnregisterWtsNotification(hwndDlg);
+ UnregisterWtsAndPowerNotification(hwndDlg);
EndDialog (hwndDlg, 0);
}
}
@@ -2374,6 +2415,17 @@ BOOL CALLBACK PasswordChangeDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPAR
}
CheckCapsLock (hwndDlg, FALSE);
+
+ if (!bSecureDesktopOngoing)
+ {
+ PasswordEditDropTarget* pTarget = new PasswordEditDropTarget ();
+ if (pTarget->Register (hwndDlg))
+ {
+ SetWindowLongPtr (hwndDlg, DWLP_USER, (LONG_PTR) pTarget);
+ }
+ else
+ delete pTarget;
+ }
return 0;
}
@@ -2839,6 +2891,19 @@ err:
return 1;
}
return 0;
+
+ case WM_NCDESTROY:
+ {
+ /* unregister drap-n-drop support */
+ PasswordEditDropTarget* pTarget = (PasswordEditDropTarget*) GetWindowLongPtr (hwndDlg, DWLP_USER);
+ if (pTarget)
+ {
+ SetWindowLongPtr (hwndDlg, DWLP_USER, (LONG_PTR) 0);
+ pTarget->Revoke ();
+ pTarget->Release();
+ }
+ }
+ return 0;
}
return 0;
@@ -2973,9 +3038,18 @@ BOOL CALLBACK PasswordDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lPa
SetFocus (GetDlgItem (hwndDlg, IDC_PASSWORD));
/* Start the timer to check if we are foreground only if Secure Desktop is not used */
+ /* Implement Text drag-n-drop in order to support droping password from KeePass directly only if Secure Desktop is not used */
if (!bSecureDesktopOngoing)
{
SetTimer (hwndDlg, TIMER_ID_CHECK_FOREGROUND, TIMER_INTERVAL_CHECK_FOREGROUND, NULL);
+
+ PasswordEditDropTarget* pTarget = new PasswordEditDropTarget ();
+ if (pTarget->Register (hwndDlg))
+ {
+ SetWindowLongPtr (hwndDlg, DWLP_USER, (LONG_PTR) pTarget);
+ }
+ else
+ delete pTarget;
}
}
return 0;
@@ -3240,6 +3314,19 @@ BOOL CALLBACK PasswordDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lPa
}
return 0;
+ case WM_NCDESTROY:
+ {
+ /* unregister drap-n-drop support */
+ PasswordEditDropTarget* pTarget = (PasswordEditDropTarget*) GetWindowLongPtr (hwndDlg, DWLP_USER);
+ if (pTarget)
+ {
+ SetWindowLongPtr (hwndDlg, DWLP_USER, (LONG_PTR) 0);
+ pTarget->Revoke ();
+ pTarget->Release();
+ }
+ }
+ return 0;
+
case WM_CONTEXTMENU:
{
RECT buttonRect;
@@ -3653,6 +3740,17 @@ BOOL CALLBACK MountOptionsDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM
ToHyperlink (hwndDlg, IDC_LINK_HIDVOL_PROTECTION_INFO);
+ if (!bSecureDesktopOngoing)
+ {
+ PasswordEditDropTarget* pTarget = new PasswordEditDropTarget ();
+ if (pTarget->Register (hwndDlg))
+ {
+ SetWindowLongPtr (hwndDlg, DWLP_USER, (LONG_PTR) pTarget);
+ }
+ else
+ delete pTarget;
+ }
+
}
return 0;
@@ -3810,6 +3908,19 @@ BOOL CALLBACK MountOptionsDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM
}
return 0;
+
+ case WM_NCDESTROY:
+ {
+ /* unregister drap-n-drop support */
+ PasswordEditDropTarget* pTarget = (PasswordEditDropTarget*) GetWindowLongPtr (hwndDlg, DWLP_USER);
+ if (pTarget)
+ {
+ SetWindowLongPtr (hwndDlg, DWLP_USER, (LONG_PTR) 0);
+ pTarget->Revoke ();
+ pTarget->Release();
+ }
+ }
+ return 0;
}
return 0;
@@ -5061,7 +5172,7 @@ static BOOL Mount (HWND hwndDlg, int nDosDriveNo, wchar_t *szFileName, int pim,
else if (!Silent)
{
int GuiPkcs5 = EffectiveVolumePkcs5;
- BOOL GuiTrueCryptMode = EffectiveVolumeTrueCryptMode;
+ BOOL GuiTrueCryptMode = EffectiveVolumeTrueCryptMode || IsTrueCryptFileExtension (szFileName)? TRUE : FALSE;
int GuiPim = EffectiveVolumePim;
StringCbCopyW (PasswordDlgVolume, sizeof(PasswordDlgVolume), szFileName);
@@ -5155,7 +5266,14 @@ static BOOL Dismount (HWND hwndDlg, int nDosDriveNo)
WaitCursor ();
if (nDosDriveNo == -2)
+ {
nDosDriveNo = (char) (HIWORD (GetSelectedLong (GetDlgItem (hwndDlg, IDC_DRIVELIST))) - L'A');
+ if (nDosDriveNo < 0 || nDosDriveNo >= 26)
+ {
+ NormalCursor ();
+ return FALSE;
+ }
+ }
if (bCloseDismountedWindows)
{
@@ -5169,9 +5287,6 @@ static BOOL Dismount (HWND hwndDlg, int nDosDriveNo)
if (bBeep)
MessageBeep (0xFFFFFFFF);
RefreshMainDlg (hwndDlg);
-
- if (nCurrentOS == WIN_2000 && RemoteSession && !IsAdmin ())
- LoadDriveLetters (hwndDlg, GetDlgItem (hwndDlg, IDC_DRIVELIST), 0);
}
NormalCursor ();
@@ -5346,9 +5461,6 @@ retry:
RefreshMainDlg (hwndDlg);
- if (nCurrentOS == WIN_2000 && RemoteSession && !IsAdmin ())
- LoadDriveLetters (hwndDlg, GetDlgItem (hwndDlg, IDC_DRIVELIST), 0);
-
NormalCursor();
if (unmount.nReturnCode != 0)
@@ -6780,6 +6892,41 @@ void DisplayDriveListContextMenu (HWND hwndDlg, LPARAM lParam)
}
}
+// broadcast signal to WAITFOR.EXE MailSlot to notify any waiting instance that we are exiting
+static void SignalExitCode (int exitCode)
+{
+ if (ExitMailSlotSpecified)
+ {
+ HANDLE hFile;
+ hFile = CreateFile (ExitMailSlotName,
+ GENERIC_WRITE,
+ FILE_SHARE_READ,
+ (LPSECURITY_ATTRIBUTES) NULL,
+ OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL,
+ (HANDLE) NULL);
+ if ((hFile == INVALID_HANDLE_VALUE) && (GetLastError () == ERROR_FILE_NOT_FOUND))
+ {
+ // MailSlot not found, wait 1 second and try again in case we exited too quickly
+ Sleep (1000);
+ hFile = CreateFile (ExitMailSlotName,
+ GENERIC_WRITE,
+ FILE_SHARE_READ,
+ (LPSECURITY_ATTRIBUTES) NULL,
+ OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL,
+ (HANDLE) NULL);
+ }
+ if (hFile != INVALID_HANDLE_VALUE)
+ {
+ char szMsg[64];
+ DWORD cbWritten;
+ StringCbPrintfA (szMsg, sizeof (szMsg), "VeraCrypt Exit %d", exitCode);
+ WriteFile(hFile, szMsg, (DWORD) (strlen (szMsg) +1), &cbWritten, (LPOVERLAPPED) NULL);
+ CloseHandle (hFile);
+ }
+ }
+}
/* Except in response to the WM_INITDIALOG and WM_ENDSESSION messages, the dialog box procedure
should return nonzero if it processes a message, and zero if it does not. */
@@ -6859,6 +7006,12 @@ BOOL CALLBACK MainDialogProc (HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPa
AbortProcess ("COMMAND_LINE_ERROR");
}
+ if (EnableMemoryProtection)
+ {
+ /* Protect this process memory from being accessed by non-admin users */
+ EnableProcessProtection ();
+ }
+
if (ComServerMode)
{
InitDialog (hwndDlg);
@@ -6984,7 +7137,7 @@ BOOL CALLBACK MainDialogProc (HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPa
if (FirstCmdKeyFile)
{
KeyFileRemoveAll (&FirstKeyFile);
- FirstKeyFile = FirstCmdKeyFile;
+ KeyFileCloneAll (FirstCmdKeyFile, &FirstKeyFile);
KeyFilesEnable = TRUE;
}
@@ -7120,7 +7273,10 @@ BOOL CALLBACK MainDialogProc (HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPa
if (Quit)
{
if (TaskBarIconMutex == NULL)
+ {
+ SignalExitCode (exitCode);
exit (exitCode);
+ }
MainWindowHidden = TRUE;
@@ -7132,6 +7288,7 @@ BOOL CALLBACK MainDialogProc (HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPa
{
if (TaskBarIconMutex)
TaskBarIconRemove (hwndDlg);
+ SignalExitCode (exitCode);
exit (exitCode);
}
else
@@ -7233,7 +7390,7 @@ BOOL CALLBACK MainDialogProc (HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPa
}
if (TaskBarIconMutex != NULL)
- RegisterWtsNotification(hwndDlg);
+ RegisterWtsAndPowerNotification(hwndDlg);
DoPostInstallTasks (hwndDlg);
ResetCurrentDirectory ();
}
@@ -7318,7 +7475,7 @@ BOOL CALLBACK MainDialogProc (HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPa
}
TaskBarIconRemove (hwndDlg);
- UnregisterWtsNotification(hwndDlg);
+ UnregisterWtsAndPowerNotification(hwndDlg);
}
EndMainDlg (hwndDlg);
localcleanup ();
@@ -7536,7 +7693,7 @@ BOOL CALLBACK MainDialogProc (HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPa
&& GetDriverRefCount () < 2)
{
TaskBarIconRemove (hwndDlg);
- UnregisterWtsNotification(hwndDlg);
+ UnregisterWtsAndPowerNotification(hwndDlg);
EndMainDlg (hwndDlg);
}
}
@@ -7663,7 +7820,7 @@ BOOL CALLBACK MainDialogProc (HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPa
EnumWindows (CloseTCWindowsEnum, 0);
TaskBarIconRemove (hwndDlg);
- UnregisterWtsNotification(hwndDlg);
+ UnregisterWtsAndPowerNotification(hwndDlg);
SendMessage (hwndDlg, WM_COMMAND, sel, 0);
}
}
@@ -7684,7 +7841,7 @@ BOOL CALLBACK MainDialogProc (HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPa
case TC_APPMSG_CLOSE_BKG_TASK:
if (TaskBarIconMutex != NULL)
TaskBarIconRemove (hwndDlg);
- UnregisterWtsNotification(hwndDlg);
+ UnregisterWtsAndPowerNotification(hwndDlg);
return 1;
@@ -8360,12 +8517,12 @@ BOOL CALLBACK MainDialogProc (HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPa
if (bEnableBkgTask)
{
TaskBarIconAdd (hwndDlg);
- RegisterWtsNotification(hwndDlg);
+ RegisterWtsAndPowerNotification(hwndDlg);
}
else
{
TaskBarIconRemove (hwndDlg);
- UnregisterWtsNotification(hwndDlg);
+ UnregisterWtsAndPowerNotification(hwndDlg);
if (MainWindowHidden)
EndMainDlg (hwndDlg);
}
@@ -8635,12 +8792,10 @@ BOOL CALLBACK MainDialogProc (HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPa
WaitCursor ();
- if (!(nCurrentOS == WIN_2000 && RemoteSession))
- {
- BroadcastDeviceChange (DBT_DEVICEREMOVECOMPLETE, 0, ~driveMap);
- Sleep (100);
- BroadcastDeviceChange (DBT_DEVICEARRIVAL, 0, driveMap);
- }
+
+ BroadcastDeviceChange (DBT_DEVICEREMOVECOMPLETE, 0, ~driveMap);
+ Sleep (100);
+ BroadcastDeviceChange (DBT_DEVICEARRIVAL, 0, driveMap);
LoadDriveLetters (hwndDlg, GetDlgItem (hwndDlg, IDC_DRIVELIST), 0);
@@ -8883,6 +9038,8 @@ void ExtractCommandLine (HWND hwndDlg, wchar_t *lpszCommandLine)
OptionNoWaitDlg,
OptionSecureDesktop,
OptionDisableDeviceUpdate,
+ OptionEnableMemoryProtection,
+ OptionSignalExit,
};
argument args[]=
@@ -8912,6 +9069,8 @@ void ExtractCommandLine (HWND hwndDlg, wchar_t *lpszCommandLine)
{ OptionNoWaitDlg, L"/nowaitdlg", NULL, FALSE },
{ OptionSecureDesktop, L"/secureDesktop", NULL, FALSE },
{ OptionDisableDeviceUpdate, L"/disableDeviceUpdate", NULL, FALSE },
+ { OptionEnableMemoryProtection, L"/protectMemory", NULL, FALSE },
+ { OptionSignalExit, L"/signalExit", NULL, FALSE },
};
argumentspec as;
@@ -9008,6 +9167,23 @@ void ExtractCommandLine (HWND hwndDlg, wchar_t *lpszCommandLine)
}
break;
+ case OptionEnableMemoryProtection:
+ {
+ EnableMemoryProtection = TRUE;
+ }
+ break;
+
+ case OptionSignalExit:
+ if (HAS_ARGUMENT == GetArgumentValue (lpszCommandLineArgs, &i,
+ nNoCommandLineArgs, tmpPath, ARRAYSIZE (tmpPath)))
+ {
+ StringCbPrintfW (ExitMailSlotName, sizeof (ExitMailSlotName), L"\\\\.\\mailslot\\WAITFOR.EXE\\%s", tmpPath);
+ ExitMailSlotSpecified = TRUE;
+ }
+ else
+ AbortProcess ("COMMAND_LINE_ERROR");
+ break;
+
case OptionCache:
{
wchar_t szTmp[16] = {0};
@@ -9427,7 +9603,7 @@ static DWORD WINAPI SystemFavoritesServiceCtrlHandler ( DWORD dwControl,
case SERVICE_CONTROL_STOP:
SystemFavoritesServiceSetStatus (SERVICE_STOP_PENDING);
- if (!(BootEncObj->ReadServiceConfigurationFlags () & VC_SYSTEM_FAVORITES_SERVICE_CONFIG_DONT_UPDATE_LOADER))
+ if (!(BootEncObj->ReadServiceConfigurationFlags () & VC_SYSTEM_FAVORITES_SERVICE_CONFIG_DONT_UPDATE_LOADER))
{
try
{
@@ -9748,7 +9924,7 @@ BOOL TaskBarIconAdd (HWND hwnd)
ScreenDPI >= 120 ? 0 : 16,
(ScreenDPI >= 120 ? LR_DEFAULTSIZE : 0)
| LR_SHARED
- | (nCurrentOS != WIN_2000 ? LR_DEFAULTCOLOR : LR_VGACOLOR)); // Windows 2000 cannot display more than 16 fixed colors in notification tray
+ | LR_DEFAULTCOLOR);
StringCbCopyW (tnid.szTip, sizeof(tnid.szTip), L"VeraCrypt");
@@ -9800,7 +9976,7 @@ BOOL TaskBarIconChange (HWND hwnd, int iconId)
ScreenDPI >= 120 ? 0 : 16,
(ScreenDPI >= 120 ? LR_DEFAULTSIZE : 0)
| LR_SHARED
- | (nCurrentOS != WIN_2000 ? LR_DEFAULTCOLOR : LR_VGACOLOR)); // Windows 2000 cannot display more than 16 fixed colors in notification tray
+ | LR_DEFAULTCOLOR);
return Shell_NotifyIcon (NIM_MODIFY, &tnid);
}
@@ -10345,7 +10521,7 @@ static void HandleHotKey (HWND hwndDlg, WPARAM wParam)
MessageBeep (0xFFFFFFFF);
}
TaskBarIconRemove (hwndDlg);
- UnregisterWtsNotification(hwndDlg);
+ UnregisterWtsAndPowerNotification(hwndDlg);
EndMainDlg (hwndDlg);
break;
@@ -11134,6 +11310,11 @@ void SetDriverConfigurationFlag (uint32 flag, BOOL state)
BootEncObj->SetDriverConfigurationFlag (flag, state ? true : false);
}
+void SetServiceConfigurationFlag (uint32 flag, BOOL state)
+{
+ if (BootEncObj)
+ BootEncObj->SetServiceConfigurationFlag (flag, state ? true : false);
+}
static BOOL CALLBACK PerformanceSettingsDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
@@ -11180,26 +11361,25 @@ static BOOL CALLBACK PerformanceSettingsDlgProc (HWND hwndDlg, UINT msg, WPARAM
EnableWindow (GetDlgItem (hwndDlg, IDC_ENABLE_RAM_ENCRYPTION), FALSE);
}
- SYSTEM_INFO sysInfo;
- GetSystemInfo (&sysInfo);
+ size_t cpuCount = GetCpuCount(NULL);
HWND freeCpuCombo = GetDlgItem (hwndDlg, IDC_ENCRYPTION_FREE_CPU_COUNT);
uint32 encryptionFreeCpuCount = ReadEncryptionThreadPoolFreeCpuCountLimit();
- if (encryptionFreeCpuCount > sysInfo.dwNumberOfProcessors - 1)
- encryptionFreeCpuCount = sysInfo.dwNumberOfProcessors - 1;
+ if (encryptionFreeCpuCount > (uint32) (cpuCount - 1))
+ encryptionFreeCpuCount = (uint32) (cpuCount - 1);
- for (uint32 i = 1; i < sysInfo.dwNumberOfProcessors; ++i)
+ for (uint32 i = 1; i < cpuCount; ++i)
{
wstringstream s;
s << i;
AddComboPair (freeCpuCombo, s.str().c_str(), i);
}
- if (sysInfo.dwNumberOfProcessors < 2 || encryptionFreeCpuCount == 0)
+ if (cpuCount < 2 || encryptionFreeCpuCount == 0)
EnableWindow (freeCpuCombo, FALSE);
- if (sysInfo.dwNumberOfProcessors < 2)
+ if (cpuCount < 2)
EnableWindow (GetDlgItem (hwndDlg, IDC_LIMIT_ENC_THREAD_POOL), FALSE);
if (encryptionFreeCpuCount != 0)
@@ -11210,7 +11390,7 @@ static BOOL CALLBACK PerformanceSettingsDlgProc (HWND hwndDlg, UINT msg, WPARAM
SetWindowTextW (GetDlgItem (hwndDlg, IDT_LIMIT_ENC_THREAD_POOL_NOTE), GetString("LIMIT_ENC_THREAD_POOL_NOTE"));
- SetDlgItemTextW (hwndDlg, IDC_HW_AES_SUPPORTED_BY_CPU, (wstring (L" ") + (GetString (is_aes_hw_cpu_supported() ? "UISTR_YES" : "UISTR_NO"))).c_str());
+ SetDlgItemTextW (hwndDlg, IDC_HW_AES_SUPPORTED_BY_CPU, (wstring (L" ") + (GetString (HasAESNI() ? "UISTR_YES" : "UISTR_NO"))).c_str());
ToHyperlink (hwndDlg, IDC_MORE_INFO_ON_HW_ACCELERATION);
ToHyperlink (hwndDlg, IDC_MORE_INFO_ON_THREAD_BASED_PARALLELIZATION);
@@ -11287,7 +11467,26 @@ static BOOL CALLBACK PerformanceSettingsDlgProc (HWND hwndDlg, UINT msg, WPARAM
{
BOOL originalRamEncryptionEnabled = (driverConfig & VC_DRIVER_CONFIG_ENABLE_RAM_ENCRYPTION)? TRUE : FALSE;
if (originalRamEncryptionEnabled != enableRamEncryption)
+ {
+ if (enableRamEncryption)
+ {
+ // Disable Hibernate and Fast Startup if they are enabled
+ BOOL bHibernateEnabled, bHiberbootEnabled;
+ if (GetHibernateStatus (bHibernateEnabled, bHiberbootEnabled))
+ {
+ if (bHibernateEnabled)
+ {
+ BootEncObj->WriteLocalMachineRegistryDwordValue (L"SYSTEM\\CurrentControlSet\\Control\\Power", L"HibernateEnabled", 0);
+ }
+
+ if (bHiberbootEnabled)
+ {
+ BootEncObj->WriteLocalMachineRegistryDwordValue (L"SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Power", L"HiberbootEnabled", 0);
+ }
+ }
+ }
rebootRequired = true;
+ }
SetDriverConfigurationFlag (VC_DRIVER_CONFIG_ENABLE_RAM_ENCRYPTION, enableRamEncryption);
}
@@ -11363,7 +11562,25 @@ static BOOL CALLBACK PerformanceSettingsDlgProc (HWND hwndDlg, UINT msg, WPARAM
BOOL enableRamEncryption = IsDlgButtonChecked (hwndDlg, IDC_ENABLE_RAM_ENCRYPTION);
if (originalRamEncryptionEnabled != enableRamEncryption)
+ {
+ if (enableRamEncryption)
+ {
+ // check if Hibernate or Fast Startup are enabled
+ BOOL bHibernateEnabled, bHiberbootEnabled;
+ if (GetHibernateStatus (bHibernateEnabled, bHiberbootEnabled))
+ {
+ if (bHibernateEnabled || bHiberbootEnabled)
+ {
+ if (AskWarnYesNo ("RAM_ENCRYPTION_DISABLE_HIBERNATE", hwndDlg) == IDNO)
+ {
+ CheckDlgButton (hwndDlg, IDC_ENABLE_RAM_ENCRYPTION, BST_UNCHECKED);
+ return 1;
+ }
+ }
+ }
+ }
Warning ("SETTING_REQUIRES_REBOOT", hwndDlg);
+ }
}
return 1;
@@ -11636,6 +11853,7 @@ static BOOL CALLBACK BootLoaderPreferencesDlgProc (HWND hwndDlg, UINT msg, WPARA
{
LocalizeDialog (hwndDlg, "IDD_SYSENC_SETTINGS");
uint32 driverConfig = ReadDriverConfigurationFlags();
+ uint32 serviceConfig = ReadServiceConfigurationFlags();
byte userConfig;
string customUserMessage;
uint16 bootLoaderVersion = 0;
@@ -11643,6 +11861,17 @@ static BOOL CALLBACK BootLoaderPreferencesDlgProc (HWND hwndDlg, UINT msg, WPARA
BOOL bPimCacheEnabled = (driverConfig & TC_DRIVER_CONFIG_CACHE_BOOT_PIM)? TRUE : FALSE;
BOOL bBlockSysEncTrimEnabled = (driverConfig & VC_DRIVER_CONFIG_BLOCK_SYS_TRIM)? TRUE : FALSE;
BOOL bClearKeysEnabled = (driverConfig & VC_DRIVER_CONFIG_CLEAR_KEYS_ON_NEW_DEVICE_INSERTION)? TRUE : FALSE;
+ BOOL bAutoFixBootloader = (serviceConfig & VC_SYSTEM_FAVORITES_SERVICE_CONFIG_DONT_UPDATE_LOADER)? FALSE : TRUE;
+ BOOL bForceVeraCryptNextBoot = FALSE;
+ BOOL bForceSetVeraCryptBootEntry = TRUE;
+ BOOL bForceVeraCryptFirstEntry = TRUE;
+ if (bSystemIsGPT)
+ {
+ bForceVeraCryptNextBoot = (serviceConfig & VC_SYSTEM_FAVORITES_SERVICE_CONFIG_FORCE_SET_BOOTNEXT)? TRUE : FALSE;
+ bForceSetVeraCryptBootEntry = (serviceConfig & VC_SYSTEM_FAVORITES_SERVICE_CONFIG_DONT_SET_BOOTENTRY)? FALSE : TRUE;
+ bForceVeraCryptFirstEntry = (serviceConfig & VC_SYSTEM_FAVORITES_SERVICE_CONFIG_DONT_FORCE_FIRST_BOOTENTRY)? FALSE : TRUE;
+ }
+
BOOL bIsHiddenOS = IsHiddenOSRunning ();
if (bClearKeysEnabled)
@@ -11707,6 +11936,25 @@ static BOOL CALLBACK BootLoaderPreferencesDlgProc (HWND hwndDlg, UINT msg, WPARA
}
else
CheckDlgButton (hwndDlg, IDC_BLOCK_SYSENC_TRIM, bBlockSysEncTrimEnabled ? BST_CHECKED : BST_UNCHECKED);
+
+ CheckDlgButton (hwndDlg, IDC_UPDATE_BOOTLOADER_ON_SHUTDOWN, bAutoFixBootloader? BST_CHECKED : BST_UNCHECKED);
+ if (bSystemIsGPT)
+ {
+ if (!bAutoFixBootloader || bIsHiddenOS)
+ {
+ // we disable other options if updating bootloader is not allowed or if hidden OS us running
+ EnableWindow (GetDlgItem (hwndDlg, IDC_FORCE_NEXT_BOOT_VERACRYPT), FALSE);
+ EnableWindow (GetDlgItem (hwndDlg, IDC_FORCE_VERACRYPT_BOOT_ENTRY), FALSE);
+ EnableWindow (GetDlgItem (hwndDlg, IDC_FORCE_VERACRYPT_FIRST_BOOT_ENTRY), FALSE);
+ }
+
+ if (!bIsHiddenOS)
+ {
+ CheckDlgButton (hwndDlg, IDC_FORCE_NEXT_BOOT_VERACRYPT, bForceVeraCryptNextBoot? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton (hwndDlg, IDC_FORCE_VERACRYPT_BOOT_ENTRY, bForceSetVeraCryptBootEntry? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton (hwndDlg, IDC_FORCE_VERACRYPT_FIRST_BOOT_ENTRY, bForceVeraCryptFirstEntry? BST_CHECKED : BST_UNCHECKED);
+ }
+ }
}
catch (Exception &e)
{
@@ -11817,6 +12065,17 @@ static BOOL CALLBACK BootLoaderPreferencesDlgProc (HWND hwndDlg, UINT msg, WPARA
BOOL bBlockSysEncTrimEnabled = IsDlgButtonChecked (hwndDlg, IDC_BLOCK_SYSENC_TRIM);
BOOL bClearKeysEnabled = IsDlgButtonChecked (hwndDlg, IDC_CLEAR_KEYS_ON_NEW_DEVICE_INSERTION);
+ BOOL bAutoFixBootloader = IsDlgButtonChecked (hwndDlg, IDC_UPDATE_BOOTLOADER_ON_SHUTDOWN);
+ BOOL bForceVeraCryptNextBoot = FALSE;
+ BOOL bForceSetVeraCryptBootEntry = TRUE;
+ BOOL bForceVeraCryptFirstEntry = TRUE;
+ if (bSystemIsGPT)
+ {
+ bForceVeraCryptNextBoot = IsDlgButtonChecked (hwndDlg, IDC_FORCE_NEXT_BOOT_VERACRYPT);
+ bForceSetVeraCryptBootEntry = IsDlgButtonChecked (hwndDlg, IDC_FORCE_VERACRYPT_BOOT_ENTRY);
+ bForceVeraCryptFirstEntry = IsDlgButtonChecked (hwndDlg, IDC_FORCE_VERACRYPT_FIRST_BOOT_ENTRY);
+ }
+
if (bClearKeysEnabled && !BootEncObj->IsSystemFavoritesServiceRunning())
{
// the system favorite service service should be running
@@ -11835,8 +12094,23 @@ static BOOL CALLBACK BootLoaderPreferencesDlgProc (HWND hwndDlg, UINT msg, WPARA
SetDriverConfigurationFlag (TC_DRIVER_CONFIG_CACHE_BOOT_PIM, (bPasswordCacheEnabled && bPimCacheEnabled)? TRUE : FALSE);
SetDriverConfigurationFlag (TC_DRIVER_CONFIG_DISABLE_EVIL_MAID_ATTACK_DETECTION, IsDlgButtonChecked (hwndDlg, IDC_DISABLE_EVIL_MAID_ATTACK_DETECTION));
SetDriverConfigurationFlag (VC_DRIVER_CONFIG_CLEAR_KEYS_ON_NEW_DEVICE_INSERTION, bClearKeysEnabled);
- if (!IsHiddenOSRunning ()) /* we don't need to update TRIM config for hidden OS since it's always blocked */
+ SetServiceConfigurationFlag (VC_SYSTEM_FAVORITES_SERVICE_CONFIG_DONT_UPDATE_LOADER, bAutoFixBootloader? FALSE : TRUE);
+ if (!IsHiddenOSRunning ())
+ {
+ /* we don't need to update TRIM config for hidden OS since it's always blocked */
SetDriverConfigurationFlag (VC_DRIVER_CONFIG_BLOCK_SYS_TRIM, bBlockSysEncTrimEnabled);
+
+ if (bSystemIsGPT)
+ {
+ if (bAutoFixBootloader)
+ {
+ /* we update bootloader settings only if the autofix option is enabled */
+ SetServiceConfigurationFlag (VC_SYSTEM_FAVORITES_SERVICE_CONFIG_FORCE_SET_BOOTNEXT, bForceVeraCryptNextBoot);
+ SetServiceConfigurationFlag (VC_SYSTEM_FAVORITES_SERVICE_CONFIG_DONT_SET_BOOTENTRY, bForceSetVeraCryptBootEntry? FALSE : TRUE);
+ SetServiceConfigurationFlag (VC_SYSTEM_FAVORITES_SERVICE_CONFIG_DONT_FORCE_FIRST_BOOTENTRY, bForceVeraCryptFirstEntry? FALSE : TRUE);
+ }
+ }
+ }
}
catch (Exception &e)
{
@@ -11897,6 +12171,24 @@ static BOOL CALLBACK BootLoaderPreferencesDlgProc (HWND hwndDlg, UINT msg, WPARA
}
break;
+
+ case IDC_UPDATE_BOOTLOADER_ON_SHUTDOWN:
+ if (bSystemIsGPT && !IsHiddenOSRunning ())
+ {
+ if (IsDlgButtonChecked (hwndDlg, IDC_UPDATE_BOOTLOADER_ON_SHUTDOWN))
+ {
+ EnableWindow (GetDlgItem (hwndDlg, IDC_FORCE_NEXT_BOOT_VERACRYPT), TRUE);
+ EnableWindow (GetDlgItem (hwndDlg, IDC_FORCE_VERACRYPT_BOOT_ENTRY), TRUE);
+ EnableWindow (GetDlgItem (hwndDlg, IDC_FORCE_VERACRYPT_FIRST_BOOT_ENTRY), TRUE);
+ }
+ else
+ {
+ EnableWindow (GetDlgItem (hwndDlg, IDC_FORCE_NEXT_BOOT_VERACRYPT), FALSE);
+ EnableWindow (GetDlgItem (hwndDlg, IDC_FORCE_VERACRYPT_BOOT_ENTRY), FALSE);
+ EnableWindow (GetDlgItem (hwndDlg, IDC_FORCE_VERACRYPT_FIRST_BOOT_ENTRY), FALSE);
+ }
+ }
+ break;
}
return 0;
}
diff --git a/src/Mount/Mount.rc b/src/Mount/Mount.rc
index 275559e..e5d102b 100644
--- a/src/Mount/Mount.rc
+++ b/src/Mount/Mount.rc
@@ -195,8 +195,8 @@ BEGIN
EDITTEXT IDC_PIM,69,43,42,14,ES_RIGHT | ES_PASSWORD | ES_AUTOHSCROLL | ES_NUMBER | NOT WS_VISIBLE
CONTROL "Use P&IM",IDC_PIM_ENABLE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,70,48,97,10
CONTROL "Cache passwords and keyfil&es in memory",IDC_CACHE,
- "Button",BS_AUTOCHECKBOX | WS_TABSTOP,70,61,153,10
- CONTROL "&Display password",IDC_SHOW_PASSWORD,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,70,74,83,10
+ "Button",BS_AUTOCHECKBOX | WS_TABSTOP,70,61,241,10
+ CONTROL "&Display password",IDC_SHOW_PASSWORD,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,70,74,244,10
CONTROL "U&se keyfiles",IDC_KEYFILES_ENABLE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,70,87,99,11
PUSHBUTTON "&Keyfiles...",IDC_KEY_FILES,173,84,75,14
PUSHBUTTON "Mount Opti&ons...",IDC_MOUNT_OPTIONS,252,84,69,14
@@ -287,7 +287,7 @@ BEGIN
LTEXT "",IDT_PKCS11_LIB_HELP,16,63,286,65
END
-IDD_EFI_SYSENC_SETTINGS DIALOGEX 0, 0, 375, 194
+IDD_EFI_SYSENC_SETTINGS DIALOGEX 0, 0, 375, 250
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "VeraCrypt - System Encryption Settings"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
@@ -304,13 +304,21 @@ BEGIN
"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,16,83,340,10
CONTROL "Block TRIM command on system partition/drive",IDC_BLOCK_SYSENC_TRIM,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,16,98,340,10
- GROUPBOX "Advanced Options",IDT_ADVANCED_OPTIONS,7,131,355,36
- PUSHBUTTON "Edit Boot Loader Configuration",IDC_EDIT_DCSPROP,10,144,173,14
- PUSHBUTTON "Display EFI Platform Information",IDC_SHOW_PLATFORMINFO,187,144,173,14
- PUSHBUTTON "Cancel",IDCANCEL,313,170,50,14
- DEFPUSHBUTTON "OK",IDOK,255,170,50,14
CONTROL "Clear encryption keys from memory if a new device is inserted",IDC_CLEAR_KEYS_ON_NEW_DEVICE_INSERTION,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,16,112,340,10
+ GROUPBOX "Advanced Options",IDT_ADVANCED_OPTIONS,7,131,355,91
+ CONTROL "Automatically fix boot configuration issues that may prevent Windows from starting",IDC_UPDATE_BOOTLOADER_ON_SHUTDOWN,
+ "Button",BS_AUTOCHECKBOX | WS_TABSTOP,16,144,340,10
+ CONTROL "Force machine to boot on VeraCrypt in the next startup",IDC_FORCE_NEXT_BOOT_VERACRYPT,
+ "Button",BS_AUTOCHECKBOX | WS_TABSTOP,16,158,340,10
+ CONTROL "Force the presence of VeraCrypt entry in the EFI firmware boot menu",IDC_FORCE_VERACRYPT_BOOT_ENTRY,
+ "Button",BS_AUTOCHECKBOX | WS_TABSTOP,16,172,340,10
+ CONTROL "Force VeraCrypt entry to be the first in the EFI firmware boot menu",IDC_FORCE_VERACRYPT_FIRST_BOOT_ENTRY,
+ "Button",BS_AUTOCHECKBOX | WS_TABSTOP,16,186,340,10
+ PUSHBUTTON "Edit Boot Loader Configuration",IDC_EDIT_DCSPROP,10,201,173,14
+ PUSHBUTTON "Display EFI Platform Information",IDC_SHOW_PLATFORMINFO,187,201,173,14
+ PUSHBUTTON "Cancel",IDCANCEL,313,226,50,14
+ DEFPUSHBUTTON "OK",IDOK,255,226,50,14
END
IDD_PERFORMANCE_SETTINGS DIALOGEX 0, 0, 371, 293
@@ -401,7 +409,7 @@ BEGIN
CONTROL "TrueCrypt Mode",IDC_TRUECRYPT_MODE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,7,76,10
END
-IDD_SYSENC_SETTINGS DIALOGEX 0, 0, 371, 310
+IDD_SYSENC_SETTINGS DIALOGEX 0, 0, 371, 344
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "VeraCrypt - System Encryption Settings"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
@@ -414,21 +422,24 @@ BEGIN
CONTROL "&Cache pre-boot authentication password in driver memory (for mounting of non-system volumes)",IDC_BOOT_LOADER_CACHE_PASSWORD,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,18,192,339,10
CONTROL "Include PIM when caching pre-boot authentication password",IDC_BOOT_LOADER_CACHE_PIM,
- "Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,18,207,340,10
+ "Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,18,207,339,10
CONTROL "Allow pre-boot &authentication to be bypassed by pressing the Esc key (enables boot manager)",IDC_ALLOW_ESC_PBA_BYPASS,
- "Button",BS_AUTOCHECKBOX | WS_TABSTOP,18,222,340,10
+ "Button",BS_AUTOCHECKBOX | WS_TABSTOP,18,222,339,10
CONTROL "Disable ""Evil Maid"" attack detection",IDC_DISABLE_EVIL_MAID_ATTACK_DETECTION,
- "Button",BS_AUTOCHECKBOX | WS_TABSTOP,18,237,340,10
+ "Button",BS_AUTOCHECKBOX | WS_TABSTOP,18,237,339,10
CONTROL "Block TRIM command on system partition/drive",IDC_BLOCK_SYSENC_TRIM,
- "Button",BS_AUTOCHECKBOX | WS_TABSTOP,18,251,340,10
- PUSHBUTTON "Cancel",IDCANCEL,314,286,50,14
- DEFPUSHBUTTON "OK",IDOK,257,286,50,14
+ "Button",BS_AUTOCHECKBOX | WS_TABSTOP,18,251,339,10
+ CONTROL "Clear encryption keys from memory if a new device is inserted",IDC_CLEAR_KEYS_ON_NEW_DEVICE_INSERTION,
+ "Button",BS_AUTOCHECKBOX | WS_TABSTOP,18,265,339,10
+ CONTROL "Automatically fix boot configuration issues that may prevent Windows from starting",IDC_UPDATE_BOOTLOADER_ON_SHUTDOWN,
+ "Button",BS_AUTOCHECKBOX | WS_TABSTOP,18,298,339,10
+ PUSHBUTTON "Cancel",IDCANCEL,314,320,50,14
+ DEFPUSHBUTTON "OK",IDOK,257,320,50,14
LTEXT "Display this custom message in the pre-boot authentication screen (24 characters maximum):",IDT_CUSTOM_BOOT_LOADER_MESSAGE,18,39,337,8
- GROUPBOX "Boot Loader Screen Options",IDT_BOOT_LOADER_SCREEN_OPTIONS,9,7,355,165
- GROUPBOX "Security Options",IDT_SECURITY_OPTIONS,9,177,355,105
LTEXT "",IDC_CUSTOM_BOOT_LOADER_MESSAGE_HELP,18,72,337,73
- CONTROL "Clear encryption keys from memory if a new device is inserted",IDC_CLEAR_KEYS_ON_NEW_DEVICE_INSERTION,
- "Button",BS_AUTOCHECKBOX | WS_TABSTOP,18,265,340,10
+ GROUPBOX "Security Options",IDT_SECURITY_OPTIONS,9,177,355,105
+ GROUPBOX "Boot Loader Screen Options",IDT_BOOT_LOADER_SCREEN_OPTIONS,9,7,355,165
+ GROUPBOX "Advanced Options",IDT_ADVANCED_OPTIONS,9,285,355,29
END
/////////////////////////////////////////////////////////////////////////////
@@ -504,7 +515,7 @@ BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 368
TOPMARGIN, 7
- BOTTOMMARGIN, 184
+ BOTTOMMARGIN, 240
END
IDD_PERFORMANCE_SETTINGS, DIALOG
@@ -536,7 +547,7 @@ BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 364
TOPMARGIN, 7
- BOTTOMMARGIN, 300
+ BOTTOMMARGIN, 334
END
END
#endif // APSTUDIO_INVOKED
@@ -548,8 +559,8 @@ END
//
VS_VERSION_INFO VERSIONINFO