mirror of
https://github.com/veracrypt/VeraCrypt.git
synced 2026-05-21 13:20:53 -05:00
Windows: add read-only recovery mount for interrupted non-system in-place volumes
This commit is contained in:
@@ -173,6 +173,7 @@ Note that turning the password cache off will not clear it (use /w to clear the
|
|||||||
fact that the password needs to be typed in the pre-boot environment (before Windows starts) where non-US Windows keyboard layouts are not available.</p>
|
fact that the password needs to be typed in the pre-boot environment (before Windows starts) where non-US Windows keyboard layouts are not available.</p>
|
||||||
<p><strong>bk</strong> or <strong>headerbak</strong>: Mount volume using embedded backup header. Note: All volumes created by VeraCrypt contain an embedded backup header (located at the end of the volume).</p>
|
<p><strong>bk</strong> or <strong>headerbak</strong>: Mount volume using embedded backup header. Note: All volumes created by VeraCrypt contain an embedded backup header (located at the end of the volume).</p>
|
||||||
<p><strong>recovery</strong>: Do not verify any checksums stored in the volume header. This option should be used only when the volume header is damaged and the volume cannot be mounted even with the mount option headerbak. Example: /m ro</p>
|
<p><strong>recovery</strong>: Do not verify any checksums stored in the volume header. This option should be used only when the volume header is damaged and the volume cannot be mounted even with the mount option headerbak. Example: /m ro</p>
|
||||||
|
<p><strong>recoveryro</strong>, <strong>inplacerecovery</strong>, or <strong>nonsysinplacerecovery</strong>: Recovery-mount an interrupted non-system in-place encryption/decryption device-hosted volume as read-only using the embedded backup header. Use this option only to copy data from a sector-by-sector clone or image.</p>
|
||||||
<p><strong>label=LabelValue</strong>: Use the given string value <strong>LabelValue</strong> as a label of the mounted volume in Windows Explorer. The maximum length for
|
<p><strong>label=LabelValue</strong>: Use the given string value <strong>LabelValue</strong> as a label of the mounted volume in Windows Explorer. The maximum length for
|
||||||
<strong>LabelValue </strong> is 32 characters for NTFS volumes and 11 characters for FAT volumes. For example,
|
<strong>LabelValue </strong> is 32 characters for NTFS volumes and 11 characters for FAT volumes. For example,
|
||||||
<em>/m label=MyDrive</em> will set the label of the drive in Explorer to <em>MyDrive</em>.</p>
|
<em>/m label=MyDrive</em> will set the label of the drive in Explorer to <em>MyDrive</em>.</p>
|
||||||
@@ -320,7 +321,7 @@ If it is followed by <strong>n</strong> or <strong>no</strong>: the password dia
|
|||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
<h4>Syntax</h4>
|
<h4>Syntax</h4>
|
||||||
<p>VeraCrypt.exe [/tc] [/hash {sha256|sha-256|sha512|sha-512|whirlpool |blake2s|blake2s-256}][/a [devices|favorites]] [/b] [/c [y|n|f]] [/d [drive letter]] [/e] [/f] [/h [y|n]] [/k keyfile or search path] [tryemptypass [y|n]] [/l drive letter] [/m {bk|rm|recovery|ro|sm|ts|noattach}]
|
<p>VeraCrypt.exe [/tc] [/hash {sha256|sha-256|sha512|sha-512|whirlpool |blake2s|blake2s-256}][/a [devices|favorites]] [/b] [/c [y|n|f]] [/d [drive letter]] [/e] [/f] [/h [y|n]] [/k keyfile or search path] [tryemptypass [y|n]] [/l drive letter] [/m {bk|rm|recovery|recoveryro|ro|sm|ts|noattach}]
|
||||||
[/p password] [/pim pimvalue] [/q [background|preferences]] [/s] [/tokenlib path] [/v volume] [/w]</p>
|
[/p password] [/pim pimvalue] [/q [background|preferences]] [/s] [/tokenlib path] [/v volume] [/w]</p>
|
||||||
<p>"VeraCrypt Format.exe" [/n] [/create] [/size number[{K|M|G|T}]] [/p password] [/encryption {AES | Serpent | Twofish | Camellia | Kuznyechik | AES(Twofish) | AES(Twofish(Serpent)) | Serpent(AES) | Serpent(Twofish(AES)) | Twofish(Serpent) | Camellia(Kuznyechik) | Kuznyechik(Twofish) | Camellia(Serpent) | Kuznyechik(AES) | Kuznyechik(Serpent(Camellia)))}] [/hash {sha256|sha-256|sha512|sha-512|whirlpool|blake2s|blake2s-256}]
|
<p>"VeraCrypt Format.exe" [/n] [/create] [/size number[{K|M|G|T}]] [/p password] [/encryption {AES | Serpent | Twofish | Camellia | Kuznyechik | AES(Twofish) | AES(Twofish(Serpent)) | Serpent(AES) | Serpent(Twofish(AES)) | Twofish(Serpent) | Camellia(Kuznyechik) | Kuznyechik(Twofish) | Camellia(Serpent) | Kuznyechik(AES) | Kuznyechik(Serpent(Camellia)))}] [/hash {sha256|sha-256|sha512|sha-512|whirlpool|blake2s|blake2s-256}]
|
||||||
[/filesystem {None|FAT|NTFS|ExFAT|ReFS}] [/dynamic] [/force] [/silent] [/noisocheck] [FastCreateFile] [/quick]</p>
|
[/filesystem {None|FAT|NTFS|ExFAT|ReFS}] [/dynamic] [/force] [/silent] [/noisocheck] [FastCreateFile] [/quick]</p>
|
||||||
|
|||||||
@@ -168,6 +168,7 @@
|
|||||||
что пароль требуется вводить на этапе до загрузки операционной системы (до запуска Windows), когда раскладки клавиатуры, отличные от американской, ещё недоступны.</p>
|
что пароль требуется вводить на этапе до загрузки операционной системы (до запуска Windows), когда раскладки клавиатуры, отличные от американской, ещё недоступны.</p>
|
||||||
<p><strong>bk</strong> или <strong>headerbak</strong>: смонтировать том, используя встроенную резервную копию заголовка. Примечание: встроенная резервная копия заголовка содержится во всех томах, созданных VeraCrypt (эта копия располагается в конце тома).</p>
|
<p><strong>bk</strong> или <strong>headerbak</strong>: смонтировать том, используя встроенную резервную копию заголовка. Примечание: встроенная резервная копия заголовка содержится во всех томах, созданных VeraCrypt (эта копия располагается в конце тома).</p>
|
||||||
<p><strong>recovery</strong>: не проверять контрольные суммы, хранящиеся в заголовке тома. Этот параметр следует использовать только при повреждении заголовка тома и когда такой том невозможно смонтировать даже с параметром headerbak. Пример: /m ro</p>
|
<p><strong>recovery</strong>: не проверять контрольные суммы, хранящиеся в заголовке тома. Этот параметр следует использовать только при повреждении заголовка тома и когда такой том невозможно смонтировать даже с параметром headerbak. Пример: /m ro</p>
|
||||||
|
<p><strong>recoveryro</strong>, <strong>inplacerecovery</strong> или <strong>nonsysinplacerecovery</strong>: восстановительное монтирование прерванного несистемного тома с шифрованием/расшифровкой на месте, размещённого на устройстве, только для чтения с использованием встроенного резервного заголовка. Используйте этот параметр только для копирования данных с посекторного клона или образа.</p>
|
||||||
<p><strong>label=LabelValue</strong>: использовать указанную строку <strong>LabelValue</strong> как метку смонтированного тома в Проводнике Windows. Максимальная длина
|
<p><strong>label=LabelValue</strong>: использовать указанную строку <strong>LabelValue</strong> как метку смонтированного тома в Проводнике Windows. Максимальная длина
|
||||||
<strong>LabelValue </strong> – 32 символа для томов NTFS и 11 символов для томов FAT. Например,
|
<strong>LabelValue </strong> – 32 символа для томов NTFS и 11 символов для томов FAT. Например,
|
||||||
<code>/m label=MyDrive</code> установит для диска в Проводнике метку тома <em>MyDrive</em>.</p>
|
<code>/m label=MyDrive</code> установит для диска в Проводнике метку тома <em>MyDrive</em>.</p>
|
||||||
@@ -305,7 +306,7 @@
|
|||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
<h4>Синтаксис</h4>
|
<h4>Синтаксис</h4>
|
||||||
<p><code>VeraCrypt.exe [/tc] [/hash {sha256|sha-256|sha512|sha-512|whirlpool |blake2s|blake2s-256}][/a [devices|favorites]] [/b] [/c [y|n|f]] [/d [буква диска]] [/e] [/f] [/h [y|n]] [/k ключевой файл или путь поиска] [tryemptypass [y|n]] [/l буква диска] [/m {bk|rm|recovery|ro|sm|ts|noattach}]
|
<p><code>VeraCrypt.exe [/tc] [/hash {sha256|sha-256|sha512|sha-512|whirlpool |blake2s|blake2s-256}][/a [devices|favorites]] [/b] [/c [y|n|f]] [/d [буква диска]] [/e] [/f] [/h [y|n]] [/k ключевой файл или путь поиска] [tryemptypass [y|n]] [/l буква диска] [/m {bk|rm|recovery|recoveryro|ro|sm|ts|noattach}]
|
||||||
[/p пароль] [/pim значение pim] [/q [background|preferences]] [/s] [/tokenlib путь] [/v том] [/w]</code></p>
|
[/p пароль] [/pim значение pim] [/q [background|preferences]] [/s] [/tokenlib путь] [/v том] [/w]</code></p>
|
||||||
<p><code>"VeraCrypt Format.exe" [/n] [/create] [/size число[{K|M|G|T}]] [/p пароль] [/encryption {AES | Serpent | Twofish | Camellia | Kuznyechik | AES(Twofish) | AES(Twofish(Serpent)) | Serpent(AES) | Serpent(Twofish(AES)) | Twofish(Serpent) | Camellia(Kuznyechik) | Kuznyechik(Twofish) | Camellia(Serpent) | Kuznyechik(AES) | Kuznyechik(Serpent(Camellia))}] [/hash {sha256|sha-256|sha512|sha-512|whirlpool|blake2s|blake2s-256}]
|
<p><code>"VeraCrypt Format.exe" [/n] [/create] [/size число[{K|M|G|T}]] [/p пароль] [/encryption {AES | Serpent | Twofish | Camellia | Kuznyechik | AES(Twofish) | AES(Twofish(Serpent)) | Serpent(AES) | Serpent(Twofish(AES)) | Twofish(Serpent) | Camellia(Kuznyechik) | Kuznyechik(Twofish) | Camellia(Serpent) | Kuznyechik(AES) | Kuznyechik(Serpent(Camellia))}] [/hash {sha256|sha-256|sha512|sha-512|whirlpool|blake2s|blake2s-256}]
|
||||||
[/filesystem {пусто|FAT|NTFS|ExFAT|ReFS}] [/dynamic] [/force] [/silent] [/noisocheck] [FastCreateFile] [/quick]</code></p>
|
[/filesystem {пусто|FAT|NTFS|ExFAT|ReFS}] [/dynamic] [/force] [/silent] [/noisocheck] [FastCreateFile] [/quick]</code></p>
|
||||||
|
|||||||
@@ -165,6 +165,7 @@
|
|||||||
<p><strong>sm</strong> 或 <strong>system</strong>:无需预启动验证,挂载位于系统加密密钥范围内的分区(例如,位于未运行的其他操作系统的加密系统驱动器上的分区)。 例如,用于备份或修复操作。注意:如果您将密码作为 /p 的参数提供,请确保使用标准美式键盘布局键入密码(相比之下,GUI 会自动确保这一点)。这是必需的,因为密码需要在预启动环境(Windows 启动之前)中键入,而在该环境中非美式 Windows 键盘布局不可用。</p>
|
<p><strong>sm</strong> 或 <strong>system</strong>:无需预启动验证,挂载位于系统加密密钥范围内的分区(例如,位于未运行的其他操作系统的加密系统驱动器上的分区)。 例如,用于备份或修复操作。注意:如果您将密码作为 /p 的参数提供,请确保使用标准美式键盘布局键入密码(相比之下,GUI 会自动确保这一点)。这是必需的,因为密码需要在预启动环境(Windows 启动之前)中键入,而在该环境中非美式 Windows 键盘布局不可用。</p>
|
||||||
<p><strong>bk</strong> 或 <strong>headerbak</strong>:使用嵌入式备份头挂载卷。注意:VeraCrypt 创建的所有卷都包含一个嵌入式备份头(位于卷的末尾)。</p>
|
<p><strong>bk</strong> 或 <strong>headerbak</strong>:使用嵌入式备份头挂载卷。注意:VeraCrypt 创建的所有卷都包含一个嵌入式备份头(位于卷的末尾)。</p>
|
||||||
<p><strong>recovery</strong>:不验证存储在卷头中的任何校验和。仅当卷头损坏且即使使用挂载选项 headerbak 也无法挂载卷时,才应使用此选项。示例:/m ro</p>
|
<p><strong>recovery</strong>:不验证存储在卷头中的任何校验和。仅当卷头损坏且即使使用挂载选项 headerbak 也无法挂载卷时,才应使用此选项。示例:/m ro</p>
|
||||||
|
<p><strong>recoveryro</strong>、<strong>inplacerecovery</strong> 或 <strong>nonsysinplacerecovery</strong>:使用嵌入式备份头,以只读方式恢复挂载已中断的非系统就地加密/解密设备托管卷。仅应使用此选项从逐扇区克隆或映像中复制数据。</p>
|
||||||
<p><strong>label=LabelValue</strong>:使用给定的字符串值 <strong>LabelValue</strong> 作为 Windows 资源管理器中挂载卷的标签。对于 NTFS 卷,
|
<p><strong>label=LabelValue</strong>:使用给定的字符串值 <strong>LabelValue</strong> 作为 Windows 资源管理器中挂载卷的标签。对于 NTFS 卷,
|
||||||
<strong>LabelValue </strong> 的最大长度为 32 个字符,对于 FAT 卷,最大长度为 11 个字符。例如,
|
<strong>LabelValue </strong> 的最大长度为 32 个字符,对于 FAT 卷,最大长度为 11 个字符。例如,
|
||||||
<em>/m label=我的驱动器</em> 将资源管理器中的驱动器标签设置为 <em>我的驱动器</em>。</p>
|
<em>/m label=我的驱动器</em> 将资源管理器中的驱动器标签设置为 <em>我的驱动器</em>。</p>
|
||||||
@@ -299,7 +300,7 @@
|
|||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
<h4>语法</h4>
|
<h4>语法</h4>
|
||||||
<p>VeraCrypt.exe [/tc] [/hash {sha256|sha-256|sha512|sha-512|whirlpool |blake2s|blake2s-256}][/a [devices|favorites]] [/b] [/c [y|n|f]] [/d [drive letter]] [/e] [/f] [/h [y|n]] [/k keyfile or search path] [tryemptypass [y|n]] [/l drive letter] [/m {bk|rm|recovery|ro|sm|ts|noattach}]
|
<p>VeraCrypt.exe [/tc] [/hash {sha256|sha-256|sha512|sha-512|whirlpool |blake2s|blake2s-256}][/a [devices|favorites]] [/b] [/c [y|n|f]] [/d [drive letter]] [/e] [/f] [/h [y|n]] [/k keyfile or search path] [tryemptypass [y|n]] [/l drive letter] [/m {bk|rm|recovery|recoveryro|ro|sm|ts|noattach}]
|
||||||
[/p password] [/pim pimvalue] [/q [background|preferences]] [/s] [/tokenlib path] [/v volume] [/w]</p>
|
[/p password] [/pim pimvalue] [/q [background|preferences]] [/s] [/tokenlib path] [/v volume] [/w]</p>
|
||||||
<p>"VeraCrypt Format.exe" [/n] [/create] [/size number[{K|M|G|T}]] [/p password] [/encryption {AES | Serpent | Twofish | Camellia | Kuznyechik | AES(Twofish) | AES(Twofish(Serpent)) | Serpent(AES) | Serpent(Twofish(AES)) | Twofish(Serpent) | Camellia(Kuznyechik) | Kuznyechik(Twofish) | Camellia(Serpent) | Kuznyechik(AES) | Kuznyechik(Serpent(Camellia))}] [/hash {sha256|sha-256|sha512|sha-512|whirlpool|blake2s|blake2s-256}]
|
<p>"VeraCrypt Format.exe" [/n] [/create] [/size number[{K|M|G|T}]] [/p password] [/encryption {AES | Serpent | Twofish | Camellia | Kuznyechik | AES(Twofish) | AES(Twofish(Serpent)) | Serpent(AES) | Serpent(Twofish(AES)) | Twofish(Serpent) | Camellia(Kuznyechik) | Kuznyechik(Twofish) | Camellia(Serpent) | Kuznyechik(AES) | Kuznyechik(Serpent(Camellia))}] [/hash {sha256|sha-256|sha512|sha-512|whirlpool|blake2s|blake2s-256}]
|
||||||
[/filesystem {None|FAT|NTFS|ExFAT|ReFS}] [/dynamic] [/force] [/silent] [/noisocheck] [FastCreateFile] [/quick]</p>
|
[/filesystem {None|FAT|NTFS|ExFAT|ReFS}] [/dynamic] [/force] [/silent] [/noisocheck] [FastCreateFile] [/quick]</p>
|
||||||
@@ -315,4 +316,4 @@
|
|||||||
<p>使用密码 <em>test</em> 创建一个 10 MB 的文件容器,并使用 FAT 格式化:</p>
|
<p>使用密码 <em>test</em> 创建一个 10 MB 的文件容器,并使用 FAT 格式化:</p>
|
||||||
<p><code>"C:\Program Files\VeraCrypt\VeraCrypt Format.exe" /create c:\Data\test.hc /password test /hash sha512 /encryption serpent /filesystem FAT /size 10M /force</code></p>
|
<p><code>"C:\Program Files\VeraCrypt\VeraCrypt Format.exe" /create c:\Data\test.hc /password test /hash sha512 /encryption serpent /filesystem FAT /size 10M /force</code></p>
|
||||||
</div>
|
</div>
|
||||||
</div><div class="ClearBoth"></div></body></html>
|
</div><div class="ClearBoth"></div></body></html>
|
||||||
|
|||||||
@@ -164,6 +164,7 @@ typedef struct
|
|||||||
Password ProtectedHidVolPassword; /* Password to the hidden volume to be protected against overwriting */
|
Password ProtectedHidVolPassword; /* Password to the hidden volume to be protected against overwriting */
|
||||||
BOOL UseBackupHeader;
|
BOOL UseBackupHeader;
|
||||||
BOOL RecoveryMode;
|
BOOL RecoveryMode;
|
||||||
|
BOOL NonSysInplaceRecoveryReadOnly;
|
||||||
int pkcs5_prf;
|
int pkcs5_prf;
|
||||||
int ProtectedHidVolPkcs5Prf;
|
int ProtectedHidVolPkcs5Prf;
|
||||||
BOOL VolumeMountedReadOnlyAfterPartialSysEnc;
|
BOOL VolumeMountedReadOnlyAfterPartialSysEnc;
|
||||||
|
|||||||
@@ -89,6 +89,7 @@ typedef struct
|
|||||||
Password ProtectedHidVolPassword; /* Password of hidden volume to protect against overwriting */
|
Password ProtectedHidVolPassword; /* Password of hidden volume to protect against overwriting */
|
||||||
BOOL UseBackupHeader;
|
BOOL UseBackupHeader;
|
||||||
BOOL RecoveryMode;
|
BOOL RecoveryMode;
|
||||||
|
BOOL NonSysInplaceRecoveryReadOnly;
|
||||||
int ProtectedHidVolPkcs5Prf;
|
int ProtectedHidVolPkcs5Prf;
|
||||||
int ProtectedHidVolPim;
|
int ProtectedHidVolPim;
|
||||||
wchar_t Label[33]; /* maximum label length is 32 for NTFS and 11 for FAT32 */
|
wchar_t Label[33]; /* maximum label length is 32 for NTFS and 11 for FAT32 */
|
||||||
|
|||||||
+21
-19
@@ -65,7 +65,7 @@ BEGIN
|
|||||||
PUSHBUTTON "Cancel",IDCANCEL,248,190,50,14
|
PUSHBUTTON "Cancel",IDCANCEL,248,190,50,14
|
||||||
END
|
END
|
||||||
|
|
||||||
IDD_MOUNT_OPTIONS DIALOGEX 0, 0, 310, 244
|
IDD_MOUNT_OPTIONS DIALOGEX 0, 0, 310, 258
|
||||||
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||||
CAPTION "VeraCrypt - Mount Options"
|
CAPTION "VeraCrypt - Mount Options"
|
||||||
FONT 8, "MS Shell Dlg", 400, 0, 0x1
|
FONT 8, "MS Shell Dlg", 400, 0, 0x1
|
||||||
@@ -75,29 +75,31 @@ BEGIN
|
|||||||
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,25,231,10
|
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,25,231,10
|
||||||
CONTROL "Use backup header embedded in &volume if available",IDC_USE_EMBEDDED_HEADER_BAK,
|
CONTROL "Use backup header embedded in &volume if available",IDC_USE_EMBEDDED_HEADER_BAK,
|
||||||
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,39,295,11
|
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,39,295,11
|
||||||
CONTROL "Mount partition &using system encryption without pre-boot authentication",IDC_MOUNT_SYSENC_PART_WITHOUT_PBA,
|
CONTROL "Recovery mount interrupted non-system in-place volume as read-only",IDC_NONSYS_INPLACE_RECOVERY_READONLY,
|
||||||
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,53,295,11
|
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,53,295,11
|
||||||
EDITTEXT IDC_VOLUME_LABEL,134,82,167,14,ES_AUTOHSCROLL
|
CONTROL "Mount partition &using system encryption without pre-boot authentication",IDC_MOUNT_SYSENC_PART_WITHOUT_PBA,
|
||||||
|
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,67,295,11
|
||||||
|
EDITTEXT IDC_VOLUME_LABEL,134,96,167,14,ES_AUTOHSCROLL
|
||||||
CONTROL "&Protect hidden volume against damage caused by writing to outer volume",IDC_PROTECT_HIDDEN_VOL,
|
CONTROL "&Protect hidden volume against damage caused by writing to outer volume",IDC_PROTECT_HIDDEN_VOL,
|
||||||
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,16,115,283,10
|
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,16,129,283,10
|
||||||
EDITTEXT IDC_PASSWORD_PROT_HIDVOL,134,133,167,14,ES_PASSWORD | ES_AUTOHSCROLL
|
EDITTEXT IDC_PASSWORD_PROT_HIDVOL,134,147,167,14,ES_PASSWORD | ES_AUTOHSCROLL
|
||||||
COMBOBOX IDC_PKCS5_PRF_ID,134,154,91,90,CBS_DROPDOWNLIST | WS_TABSTOP
|
COMBOBOX IDC_PKCS5_PRF_ID,134,168,91,90,CBS_DROPDOWNLIST | WS_TABSTOP
|
||||||
EDITTEXT IDC_PIM,134,174,42,14,ES_RIGHT | ES_PASSWORD | ES_AUTOHSCROLL | ES_NUMBER | NOT WS_VISIBLE
|
EDITTEXT IDC_PIM,134,188,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,134,179,97,10
|
CONTROL "Use P&IM",IDC_PIM_ENABLE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,134,193,97,10
|
||||||
LTEXT "(Empty or 0 for defaults)",IDC_PIM_HELP,181,177,121,8,NOT WS_VISIBLE
|
LTEXT "(Empty or 0 for defaults)",IDC_PIM_HELP,181,191,121,8,NOT WS_VISIBLE
|
||||||
CONTROL "&Display password",IDC_SHOW_PASSWORD_MO,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,134,192,90,10
|
CONTROL "&Display password",IDC_SHOW_PASSWORD_MO,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,134,206,90,10
|
||||||
CONTROL "U&se keyfiles",IDC_KEYFILES_ENABLE_HIDVOL_PROT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,134,205,90,10
|
CONTROL "U&se keyfiles",IDC_KEYFILES_ENABLE_HIDVOL_PROT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,134,219,90,10
|
||||||
PUSHBUTTON "&Keyfiles...",IDC_KEYFILES_HIDVOL_PROT,239,201,60,14
|
PUSHBUTTON "&Keyfiles...",IDC_KEYFILES_HIDVOL_PROT,239,215,60,14
|
||||||
DEFPUSHBUTTON "OK",IDOK,246,7,60,14
|
DEFPUSHBUTTON "OK",IDOK,246,7,60,14
|
||||||
PUSHBUTTON "Cancel",IDCANCEL,246,24,60,14
|
PUSHBUTTON "Cancel",IDCANCEL,246,24,60,14
|
||||||
LTEXT "What is hidden volume protection?",IDC_LINK_HIDVOL_PROTECTION_INFO,16,220,279,10,SS_NOTIFY
|
LTEXT "What is hidden volume protection?",IDC_LINK_HIDVOL_PROTECTION_INFO,16,234,279,10,SS_NOTIFY
|
||||||
RTEXT "P&assword to hidden volume:\n(if empty, cache is used)",IDT_HIDDEN_PROT_PASSWD,15,132,115,17,0,WS_EX_RIGHT
|
RTEXT "P&assword to hidden volume:\n(if empty, cache is used)",IDT_HIDDEN_PROT_PASSWD,15,146,115,17,0,WS_EX_RIGHT
|
||||||
GROUPBOX "Hidden Volume Protection",IDT_HIDDEN_VOL_PROTECTION,6,101,299,136
|
GROUPBOX "Hidden Volume Protection",IDT_HIDDEN_VOL_PROTECTION,6,115,299,136
|
||||||
RTEXT "KDF:",IDT_KDF,15,155,115,17
|
RTEXT "KDF:",IDT_KDF,15,169,115,17
|
||||||
RTEXT "Volume PIM:",IDT_PIM,15,177,115,17,NOT WS_VISIBLE
|
RTEXT "Volume PIM:",IDT_PIM,15,191,115,17,NOT WS_VISIBLE
|
||||||
LTEXT "Volume Label in Windows:",IDT_VOLUME_LABEL,12,85,115,8
|
LTEXT "Volume Label in Windows:",IDT_VOLUME_LABEL,12,99,115,8
|
||||||
CONTROL "Only create virtual device without mounting on selected drive letter",IDC_DISABLE_MOUNT_MANAGER,
|
CONTROL "Only create virtual device without mounting on selected drive letter",IDC_DISABLE_MOUNT_MANAGER,
|
||||||
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,67,297,10
|
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,81,297,10
|
||||||
END
|
END
|
||||||
|
|
||||||
IDD_KEYFILES DIALOGEX 0, 0, 363, 264
|
IDD_KEYFILES DIALOGEX 0, 0, 363, 264
|
||||||
|
|||||||
+20
-7
@@ -5827,6 +5827,10 @@ void handleError (HWND hwndDlg, int code, const char* srcPos)
|
|||||||
Error ("ERR_NONSYS_INPLACE_ENC_INCOMPLETE", hwndDlg);
|
Error ("ERR_NONSYS_INPLACE_ENC_INCOMPLETE", hwndDlg);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case ERR_NONSYS_INPLACE_RECOVERY_READONLY_UNSUPPORTED:
|
||||||
|
Error ("ERR_NONSYS_INPLACE_RECOVERY_READONLY_UNSUPPORTED", hwndDlg);
|
||||||
|
break;
|
||||||
|
|
||||||
case ERR_SYS_HIDVOL_HEAD_REENC_MODE_WRONG:
|
case ERR_SYS_HIDVOL_HEAD_REENC_MODE_WRONG:
|
||||||
Error ("ERR_SYS_HIDVOL_HEAD_REENC_MODE_WRONG", hwndDlg);
|
Error ("ERR_SYS_HIDVOL_HEAD_REENC_MODE_WRONG", hwndDlg);
|
||||||
break;
|
break;
|
||||||
@@ -8987,7 +8991,7 @@ int MountVolume (HWND hwndDlg,
|
|||||||
BYTE volumeID[VOLUME_ID_SIZE] = {0};
|
BYTE volumeID[VOLUME_ID_SIZE] = {0};
|
||||||
|
|
||||||
#ifdef TCMOUNT
|
#ifdef TCMOUNT
|
||||||
if (mountOptions->PartitionInInactiveSysEncScope)
|
if (!mountOptions->NonSysInplaceRecoveryReadOnly && mountOptions->PartitionInInactiveSysEncScope)
|
||||||
{
|
{
|
||||||
if (!CheckSysEncMountWithoutPBA (hwndDlg, volumePath, quiet))
|
if (!CheckSysEncMountWithoutPBA (hwndDlg, volumePath, quiet))
|
||||||
return -1;
|
return -1;
|
||||||
@@ -9016,8 +9020,9 @@ int MountVolume (HWND hwndDlg,
|
|||||||
ZeroMemory (&mount, sizeof (mount));
|
ZeroMemory (&mount, sizeof (mount));
|
||||||
mount.bExclusiveAccess = sharedAccess ? FALSE : TRUE;
|
mount.bExclusiveAccess = sharedAccess ? FALSE : TRUE;
|
||||||
mount.SystemFavorite = MountVolumesAsSystemFavorite;
|
mount.SystemFavorite = MountVolumesAsSystemFavorite;
|
||||||
mount.UseBackupHeader = mountOptions->UseBackupHeader;
|
mount.UseBackupHeader = mountOptions->UseBackupHeader || mountOptions->NonSysInplaceRecoveryReadOnly;
|
||||||
mount.RecoveryMode = mountOptions->RecoveryMode;
|
mount.RecoveryMode = mountOptions->RecoveryMode;
|
||||||
|
mount.NonSysInplaceRecoveryReadOnly = mountOptions->NonSysInplaceRecoveryReadOnly;
|
||||||
StringCbCopyW (mount.wszLabel, sizeof (mount.wszLabel), mountOptions->Label);
|
StringCbCopyW (mount.wszLabel, sizeof (mount.wszLabel), mountOptions->Label);
|
||||||
|
|
||||||
retry:
|
retry:
|
||||||
@@ -9032,7 +9037,7 @@ retry:
|
|||||||
else
|
else
|
||||||
mount.VolumePassword.Length = 0;
|
mount.VolumePassword.Length = 0;
|
||||||
|
|
||||||
if (!mountOptions->ReadOnly && mountOptions->ProtectHiddenVolume)
|
if (!mountOptions->ReadOnly && !mountOptions->NonSysInplaceRecoveryReadOnly && mountOptions->ProtectHiddenVolume)
|
||||||
{
|
{
|
||||||
mount.ProtectedHidVolPassword = mountOptions->ProtectedHidVolPassword;
|
mount.ProtectedHidVolPassword = mountOptions->ProtectedHidVolPassword;
|
||||||
mount.bProtectHiddenVolume = TRUE;
|
mount.bProtectHiddenVolume = TRUE;
|
||||||
@@ -9042,7 +9047,7 @@ retry:
|
|||||||
else
|
else
|
||||||
mount.bProtectHiddenVolume = FALSE;
|
mount.bProtectHiddenVolume = FALSE;
|
||||||
|
|
||||||
mount.bMountReadOnly = mountOptions->ReadOnly;
|
mount.bMountReadOnly = mountOptions->ReadOnly || mountOptions->NonSysInplaceRecoveryReadOnly;
|
||||||
mount.bMountRemovable = mountOptions->Removable;
|
mount.bMountRemovable = mountOptions->Removable;
|
||||||
mount.bPreserveTimestamp = mountOptions->PreserveTimestamp;
|
mount.bPreserveTimestamp = mountOptions->PreserveTimestamp;
|
||||||
|
|
||||||
@@ -9164,7 +9169,14 @@ retry:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mountOptions->PartitionInInactiveSysEncScope)
|
if (mountOptions->NonSysInplaceRecoveryReadOnly && !bDevice)
|
||||||
|
{
|
||||||
|
if (!quiet)
|
||||||
|
Error ("ERR_NONSYS_INPLACE_RECOVERY_READONLY_UNSUPPORTED", hwndDlg);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!mountOptions->NonSysInplaceRecoveryReadOnly && mountOptions->PartitionInInactiveSysEncScope)
|
||||||
{
|
{
|
||||||
if (mount.wszVolume == NULL || swscanf_s ((const wchar_t *) mount.wszVolume,
|
if (mount.wszVolume == NULL || swscanf_s ((const wchar_t *) mount.wszVolume,
|
||||||
WIDE("\\Device\\Harddisk%d\\Partition"),
|
WIDE("\\Device\\Harddisk%d\\Partition"),
|
||||||
@@ -9299,7 +9311,8 @@ retry:
|
|||||||
|
|
||||||
// Mount successful
|
// Mount successful
|
||||||
|
|
||||||
if (mount.UseBackupHeader != mountOptions->UseBackupHeader
|
if (!mountOptions->NonSysInplaceRecoveryReadOnly
|
||||||
|
&& mount.UseBackupHeader != mountOptions->UseBackupHeader
|
||||||
&& mount.UseBackupHeader)
|
&& mount.UseBackupHeader)
|
||||||
{
|
{
|
||||||
if (bReportWrongPassword && !Silent)
|
if (bReportWrongPassword && !Silent)
|
||||||
@@ -9314,7 +9327,7 @@ retry:
|
|||||||
Warning ("ERR_XTS_MASTERKEY_VULNERABLE", hwndDlg);
|
Warning ("ERR_XTS_MASTERKEY_VULNERABLE", hwndDlg);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mount.FilesystemDirty)
|
if (mount.FilesystemDirty && !mountOptions->NonSysInplaceRecoveryReadOnly)
|
||||||
{
|
{
|
||||||
wchar_t msg[1024];
|
wchar_t msg[1024];
|
||||||
wchar_t mountPoint[] = { (wchar_t) (L'A' + driveNo), L':', 0 };
|
wchar_t mountPoint[] = { (wchar_t) (L'A' + driveNo), L':', 0 };
|
||||||
|
|||||||
@@ -151,6 +151,7 @@
|
|||||||
<entry lang="en" key="IDC_MOUNTALL">&Auto-Mount Devices</entry>
|
<entry lang="en" key="IDC_MOUNTALL">&Auto-Mount Devices</entry>
|
||||||
<entry lang="en" key="IDC_MOUNT_OPTIONS">Mount Opti&ons...</entry>
|
<entry lang="en" key="IDC_MOUNT_OPTIONS">Mount Opti&ons...</entry>
|
||||||
<entry lang="en" key="IDC_MOUNT_READONLY">Mount volume as read-&only</entry>
|
<entry lang="en" key="IDC_MOUNT_READONLY">Mount volume as read-&only</entry>
|
||||||
|
<entry lang="en" key="IDC_NONSYS_INPLACE_RECOVERY_READONLY">Recovery mount interrupted non-system in-place volume as read-only</entry>
|
||||||
<entry lang="en" key="IDC_NEW_KEYFILES">Keyfiles...</entry>
|
<entry lang="en" key="IDC_NEW_KEYFILES">Keyfiles...</entry>
|
||||||
<entry lang="en" key="IDC_OLD_PIM_HELP">(Empty or 0 for defaults)</entry>
|
<entry lang="en" key="IDC_OLD_PIM_HELP">(Empty or 0 for defaults)</entry>
|
||||||
<entry lang="en" key="IDC_PIM_HELP">(Empty or 0 for defaults)</entry>
|
<entry lang="en" key="IDC_PIM_HELP">(Empty or 0 for defaults)</entry>
|
||||||
@@ -1238,6 +1239,8 @@
|
|||||||
<entry lang="en" key="SYSTEM_ENCRYPTION_NOT_COMPLETED">The process of encryption or decryption of the system partition/drive has not been completed. Please wait until it is complete before proceeding.</entry>
|
<entry lang="en" key="SYSTEM_ENCRYPTION_NOT_COMPLETED">The process of encryption or decryption of the system partition/drive has not been completed. Please wait until it is complete before proceeding.</entry>
|
||||||
<entry lang="en" key="ERR_ENCRYPTION_NOT_COMPLETED">Error: The process of encryption of the partition/drive has not been completed. It must be completed first.</entry>
|
<entry lang="en" key="ERR_ENCRYPTION_NOT_COMPLETED">Error: The process of encryption of the partition/drive has not been completed. It must be completed first.</entry>
|
||||||
<entry lang="en" key="ERR_NONSYS_INPLACE_ENC_INCOMPLETE">Error: The process of encryption or decryption of the partition/volume has not been completed. It must be completed first.\n\nNote: To resume the process, select 'Volumes' > 'Resume Interrupted Process' from the menu bar of the main VeraCrypt window.</entry>
|
<entry lang="en" key="ERR_NONSYS_INPLACE_ENC_INCOMPLETE">Error: The process of encryption or decryption of the partition/volume has not been completed. It must be completed first.\n\nNote: To resume the process, select 'Volumes' > 'Resume Interrupted Process' from the menu bar of the main VeraCrypt window.</entry>
|
||||||
|
<entry lang="en" key="ERR_NONSYS_INPLACE_RECOVERY_READONLY_UNSUPPORTED">Error: Recovery read-only mount is supported only for device-hosted volumes with an incomplete non-system in-place encryption/decryption state and a valid embedded backup header layout.\n\nFully encrypted, fully decrypted, hidden, file-hosted, or unsupported-layout volumes cannot be mounted with this option.</entry>
|
||||||
|
<entry lang="en" key="NONSYS_INPLACE_RECOVERY_READONLY_WARNING">This recovery mode is intended only for copying data from a sector-by-sector clone or image of a partition where non-system in-place encryption/decryption was interrupted.\n\nThe volume will be mounted read-only using the embedded backup header. Do not run CHKDSK, formatting, partition repair, or any write-capable recovery tool on the original disk or on the partially transformed volume.\n\nContinue?</entry>
|
||||||
<entry lang="en" key="ERR_SYS_HIDVOL_HEAD_REENC_MODE_WRONG">The password is correct, VeraCrypt has successfully decrypted the volume header and detected that this volume is a hidden system volume. However, you cannot modify the header of a hidden system volume this way.\n\nTo change the password for a hidden system volume, boot the operating system residing in the hidden volume, and then select 'System' > 'Change Password' from the menu bar of the main VeraCrypt window.\n\nTo set the header key derivation algorithm, boot the hidden operating system and then select 'System' > 'Set Header Key Derivation Algorithm'.</entry>
|
<entry lang="en" key="ERR_SYS_HIDVOL_HEAD_REENC_MODE_WRONG">The password is correct, VeraCrypt has successfully decrypted the volume header and detected that this volume is a hidden system volume. However, you cannot modify the header of a hidden system volume this way.\n\nTo change the password for a hidden system volume, boot the operating system residing in the hidden volume, and then select 'System' > 'Change Password' from the menu bar of the main VeraCrypt window.\n\nTo set the header key derivation algorithm, boot the hidden operating system and then select 'System' > 'Set Header Key Derivation Algorithm'.</entry>
|
||||||
<entry lang="en" key="CANNOT_DECRYPT_HIDDEN_OS">VeraCrypt does not support in-place decryption of a hidden system partition.\n\nNote: If you want to decrypt the decoy system partition, boot the decoy system, and then select 'System' > 'Permanently Decrypt System Partition/Drive' from the menu bar of the main VeraCrypt window.</entry>
|
<entry lang="en" key="CANNOT_DECRYPT_HIDDEN_OS">VeraCrypt does not support in-place decryption of a hidden system partition.\n\nNote: If you want to decrypt the decoy system partition, boot the decoy system, and then select 'System' > 'Permanently Decrypt System Partition/Drive' from the menu bar of the main VeraCrypt window.</entry>
|
||||||
<entry lang="en" key="ERR_PARAMETER_INCORRECT">Error: Incorrect/invalid parameter.</entry>
|
<entry lang="en" key="ERR_PARAMETER_INCORRECT">Error: Incorrect/invalid parameter.</entry>
|
||||||
|
|||||||
@@ -227,6 +227,7 @@
|
|||||||
#define IDC_LINK_KEYFILES_EXTENSIONS_WARNING 5144
|
#define IDC_LINK_KEYFILES_EXTENSIONS_WARNING 5144
|
||||||
#define IDC_DISABLE_MEMORY_PROTECTION 5145
|
#define IDC_DISABLE_MEMORY_PROTECTION 5145
|
||||||
#define IDC_DISABLE_MEMORY_PROTECTION_HELP 5146
|
#define IDC_DISABLE_MEMORY_PROTECTION_HELP 5146
|
||||||
|
#define IDC_NONSYS_INPLACE_RECOVERY_READONLY 5147
|
||||||
|
|
||||||
// Next default values for new objects
|
// Next default values for new objects
|
||||||
//
|
//
|
||||||
@@ -235,7 +236,7 @@
|
|||||||
#define _APS_NO_MFC 1
|
#define _APS_NO_MFC 1
|
||||||
#define _APS_NEXT_RESOURCE_VALUE 585
|
#define _APS_NEXT_RESOURCE_VALUE 585
|
||||||
#define _APS_NEXT_COMMAND_VALUE 40001
|
#define _APS_NEXT_COMMAND_VALUE 40001
|
||||||
#define _APS_NEXT_CONTROL_VALUE 5147
|
#define _APS_NEXT_CONTROL_VALUE 5148
|
||||||
#define _APS_NEXT_SYMED_VALUE 101
|
#define _APS_NEXT_SYMED_VALUE 101
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+2
-1
@@ -457,7 +457,8 @@ enum
|
|||||||
ERR_CAPI_INIT_FAILED = 35,
|
ERR_CAPI_INIT_FAILED = 35,
|
||||||
ERR_XTS_MASTERKEY_VULNERABLE = 36,
|
ERR_XTS_MASTERKEY_VULNERABLE = 36,
|
||||||
ERR_SYSENC_XTS_MASTERKEY_VULNERABLE = 37,
|
ERR_SYSENC_XTS_MASTERKEY_VULNERABLE = 37,
|
||||||
ERR_KEY_DERIVATION_FAILED = 38
|
ERR_KEY_DERIVATION_FAILED = 38,
|
||||||
|
ERR_NONSYS_INPLACE_RECOVERY_READONLY_UNSUPPORTED = 39
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // #ifndef TCDEFS_H
|
#endif // #ifndef TCDEFS_H
|
||||||
|
|||||||
@@ -76,6 +76,9 @@ extern "C" {
|
|||||||
|
|
||||||
#define TC_VOLUME_DATA_OFFSET TC_VOLUME_HEADER_GROUP_SIZE
|
#define TC_VOLUME_DATA_OFFSET TC_VOLUME_HEADER_GROUP_SIZE
|
||||||
|
|
||||||
|
#define TC_INITIAL_NTFS_CONCEAL_PORTION_SIZE (2 * TC_MAX_VOLUME_SECTOR_SIZE)
|
||||||
|
#define TC_NTFS_CONCEAL_CONSTANT 0xFF
|
||||||
|
|
||||||
// The offset, in bytes, of the legacy hidden volume header position from the end of the file (a positive value).
|
// The offset, in bytes, of the legacy hidden volume header position from the end of the file (a positive value).
|
||||||
#define TC_HIDDEN_VOLUME_HEADER_OFFSET_LEGACY (TC_VOLUME_HEADER_SIZE_LEGACY + TC_SECTOR_SIZE_LEGACY * 2)
|
#define TC_HIDDEN_VOLUME_HEADER_OFFSET_LEGACY (TC_VOLUME_HEADER_SIZE_LEGACY + TC_SECTOR_SIZE_LEGACY * 2)
|
||||||
|
|
||||||
|
|||||||
@@ -556,6 +556,27 @@ static VOID CompletionThreadProc(PVOID threadArg)
|
|||||||
|
|
||||||
DecryptDataUnits(request->Data + request->EncryptedOffset, &dataUnit, request->EncryptedLength / ENCRYPTION_DATA_UNIT_SIZE, queue->CryptoInfo);
|
DecryptDataUnits(request->Data + request->EncryptedOffset, &dataUnit, request->EncryptedLength / ENCRYPTION_DATA_UNIT_SIZE, queue->CryptoInfo);
|
||||||
}
|
}
|
||||||
|
else if (queue->NonSysInplaceRecoveryMode
|
||||||
|
&& request->EncryptedLength == 0
|
||||||
|
&& queue->NonSysInplaceConcealedPlaintextLength > 0
|
||||||
|
&& NT_SUCCESS(request->Item->Status))
|
||||||
|
{
|
||||||
|
uint64 concealIntersectStart;
|
||||||
|
uint32 concealIntersectLength;
|
||||||
|
uint32 concealBufferOffset;
|
||||||
|
uint32 i;
|
||||||
|
|
||||||
|
GetIntersection ((uint64) request->Offset.QuadPart,
|
||||||
|
request->Length,
|
||||||
|
0,
|
||||||
|
queue->NonSysInplaceConcealedPlaintextLength - 1,
|
||||||
|
&concealIntersectStart,
|
||||||
|
&concealIntersectLength);
|
||||||
|
|
||||||
|
concealBufferOffset = (uint32) (concealIntersectStart - (uint64) request->Offset.QuadPart);
|
||||||
|
for (i = 0; i < concealIntersectLength; ++i)
|
||||||
|
request->Data[concealBufferOffset + i] ^= TC_NTFS_CONCEAL_CONSTANT;
|
||||||
|
}
|
||||||
// Dump("Read sector %lld count %d\n", request->Offset.QuadPart >> 9, request->Length >> 9);
|
// Dump("Read sector %lld count %d\n", request->Offset.QuadPart >> 9, request->Length >> 9);
|
||||||
// Update subst sectors
|
// Update subst sectors
|
||||||
if((queue->SecRegionData != NULL) && (queue->SecRegionSize > 512)) {
|
if((queue->SecRegionData != NULL) && (queue->SecRegionSize > 512)) {
|
||||||
@@ -577,6 +598,17 @@ static VOID CompletionThreadProc(PVOID threadArg)
|
|||||||
|
|
||||||
static NTSTATUS TCCachedRead (EncryptedIoQueue *queue, IO_STATUS_BLOCK *ioStatus, PVOID buffer, LARGE_INTEGER offset, ULONG length)
|
static NTSTATUS TCCachedRead (EncryptedIoQueue *queue, IO_STATUS_BLOCK *ioStatus, PVOID buffer, LARGE_INTEGER offset, ULONG length)
|
||||||
{
|
{
|
||||||
|
if (queue->NonSysInplaceRecoveryMode)
|
||||||
|
{
|
||||||
|
queue->LastReadLength = 0;
|
||||||
|
queue->ReadAheadBufferValid = FALSE;
|
||||||
|
|
||||||
|
if (queue->IsFilterDevice)
|
||||||
|
return TCReadDevice (queue->LowerDeviceObject, buffer, offset, length);
|
||||||
|
|
||||||
|
return ZwReadFile (queue->HostFileHandle, NULL, NULL, NULL, ioStatus, buffer, length, &offset, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
queue->LastReadOffset = offset;
|
queue->LastReadOffset = offset;
|
||||||
queue->LastReadLength = length;
|
queue->LastReadLength = length;
|
||||||
|
|
||||||
@@ -741,6 +773,7 @@ static VOID IoThreadProc (PVOID threadArg)
|
|||||||
request->Data = request->OrigDataBufferFragment;
|
request->Data = request->OrigDataBufferFragment;
|
||||||
|
|
||||||
if (request->CompleteOriginalIrp
|
if (request->CompleteOriginalIrp
|
||||||
|
&& !queue->NonSysInplaceRecoveryMode
|
||||||
&& queue->LastReadLength > 0
|
&& queue->LastReadLength > 0
|
||||||
&& NT_SUCCESS (request->Item->Status)
|
&& NT_SUCCESS (request->Item->Status)
|
||||||
&& InterlockedExchangeAdd (&queue->IoThreadPendingRequestCount, 0) == 0)
|
&& InterlockedExchangeAdd (&queue->IoThreadPendingRequestCount, 0) == 0)
|
||||||
@@ -959,6 +992,12 @@ static VOID MainThreadProc (PVOID threadArg)
|
|||||||
Dump ("Q %I64d [%I64d] %c len=%d\n", item->OriginalOffset.QuadPart, GetElapsedTime (&queue->LastPerformanceCounter), item->Write ? 'W' : 'R', item->OriginalLength);
|
Dump ("Q %I64d [%I64d] %c len=%d\n", item->OriginalOffset.QuadPart, GetElapsedTime (&queue->LastPerformanceCounter), item->Write ? 'W' : 'R', item->OriginalLength);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (queue->NonSysInplaceRecoveryMode && item->Write)
|
||||||
|
{
|
||||||
|
QueueIrpCompletionFromItem(queue, item, STATUS_MEDIA_WRITE_PROTECTED);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (!queue->IsFilterDevice)
|
if (!queue->IsFilterDevice)
|
||||||
{
|
{
|
||||||
// Adjust the offset for host file or device
|
// Adjust the offset for host file or device
|
||||||
@@ -1044,6 +1083,80 @@ static VOID MainThreadProc (PVOID threadArg)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (queue->NonSysInplaceRecoveryMode)
|
||||||
|
{
|
||||||
|
dataRemaining = item->OriginalLength;
|
||||||
|
fragmentOffset = item->OriginalOffset;
|
||||||
|
|
||||||
|
while (dataRemaining > 0)
|
||||||
|
{
|
||||||
|
ULONG queueFragmentSize = queue->FragmentSize;
|
||||||
|
ULONG dataFragmentLength = dataRemaining <= queueFragmentSize ? dataRemaining : queueFragmentSize;
|
||||||
|
BOOL encryptedFragment;
|
||||||
|
BOOL isLastFragment;
|
||||||
|
LARGE_INTEGER physicalFragmentOffset;
|
||||||
|
uint64 logicalFragmentOffset = (uint64) fragmentOffset.QuadPart;
|
||||||
|
|
||||||
|
if (logicalFragmentOffset < (uint64) queue->NonSysInplaceLogicalEncryptedStart)
|
||||||
|
{
|
||||||
|
uint64 bytesToEncryptedStart = (uint64) queue->NonSysInplaceLogicalEncryptedStart - logicalFragmentOffset;
|
||||||
|
if ((uint64) dataFragmentLength > bytesToEncryptedStart)
|
||||||
|
dataFragmentLength = (ULONG) bytesToEncryptedStart;
|
||||||
|
|
||||||
|
encryptedFragment = FALSE;
|
||||||
|
physicalFragmentOffset = fragmentOffset;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
encryptedFragment = TRUE;
|
||||||
|
hResult = ULongLongAdd (logicalFragmentOffset, TC_VOLUME_DATA_OFFSET, &addResult);
|
||||||
|
if (hResult != S_OK || addResult > (ULONGLONG) _I64_MAX)
|
||||||
|
{
|
||||||
|
QueueIrpCompletionFromItem (queue, item, STATUS_INVALID_PARAMETER);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
physicalFragmentOffset.QuadPart = addResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
isLastFragment = dataRemaining == dataFragmentLength;
|
||||||
|
activeFragmentBuffer = (activeFragmentBuffer == queue->FragmentBufferA ? queue->FragmentBufferB : queue->FragmentBufferA);
|
||||||
|
|
||||||
|
InterlockedIncrement (&queue->IoThreadPendingRequestCount);
|
||||||
|
|
||||||
|
request = GetPoolBuffer (queue, sizeof (EncryptedIoRequest));
|
||||||
|
if (!request)
|
||||||
|
{
|
||||||
|
InterlockedDecrement(&queue->IoThreadPendingRequestCount);
|
||||||
|
QueueIrpCompletionFromItem (queue, item, STATUS_INSUFFICIENT_RESOURCES);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
request->Item = item;
|
||||||
|
request->CompleteOriginalIrp = isLastFragment;
|
||||||
|
request->Offset = physicalFragmentOffset;
|
||||||
|
request->Data = activeFragmentBuffer;
|
||||||
|
request->OrigDataBufferFragment = dataBuffer;
|
||||||
|
request->Length = dataFragmentLength;
|
||||||
|
request->EncryptedOffset = 0;
|
||||||
|
request->EncryptedLength = encryptedFragment ? dataFragmentLength : 0;
|
||||||
|
|
||||||
|
AcquireFragmentBuffer (queue, activeFragmentBuffer);
|
||||||
|
|
||||||
|
ExInterlockedInsertTailList (&queue->IoThreadQueue, &request->ListEntry, &queue->IoThreadQueueLock);
|
||||||
|
KeSetEvent (&queue->IoThreadQueueNotEmptyEvent, IO_DISK_INCREMENT, FALSE);
|
||||||
|
|
||||||
|
if (isLastFragment)
|
||||||
|
break;
|
||||||
|
|
||||||
|
dataRemaining -= dataFragmentLength;
|
||||||
|
dataBuffer += dataFragmentLength;
|
||||||
|
fragmentOffset.QuadPart += dataFragmentLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// Divide data block to fragments to enable efficient overlapping of encryption and IO operations
|
// Divide data block to fragments to enable efficient overlapping of encryption and IO operations
|
||||||
|
|
||||||
dataRemaining = item->OriginalLength;
|
dataRemaining = item->OriginalLength;
|
||||||
|
|||||||
@@ -62,6 +62,10 @@ typedef struct _EncryptedIoQueueStruct
|
|||||||
// File-handle-based IO
|
// File-handle-based IO
|
||||||
HANDLE HostFileHandle;
|
HANDLE HostFileHandle;
|
||||||
BOOL bSupportPartialEncryption;
|
BOOL bSupportPartialEncryption;
|
||||||
|
BOOL NonSysInplaceRecoveryMode;
|
||||||
|
int64 NonSysInplaceLogicalEncryptedStart;
|
||||||
|
int64 NonSysInplaceLogicalEncryptedEnd;
|
||||||
|
uint32 NonSysInplaceConcealedPlaintextLength;
|
||||||
int64 VirtualDeviceLength;
|
int64 VirtualDeviceLength;
|
||||||
SECURITY_CLIENT_CONTEXT *SecurityClientContext;
|
SECURITY_CLIENT_CONTEXT *SecurityClientContext;
|
||||||
|
|
||||||
|
|||||||
+144
-53
@@ -795,6 +795,112 @@ IOCTL_STORAGE_GET_HOTPLUG_INFO 0x002D0C14
|
|||||||
IOCTL_STORAGE_QUERY_PROPERTY 0x002D1400
|
IOCTL_STORAGE_QUERY_PROPERTY 0x002D1400
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
static NTSTATUS VerifyBackingReadRange (PEXTENSION Extension, PVOID buffer, ULONG bufferSize, ULONGLONG physicalOffset, ULONG length)
|
||||||
|
{
|
||||||
|
IO_STATUS_BLOCK ioStatus;
|
||||||
|
LARGE_INTEGER offset;
|
||||||
|
ULONG remainingBytes = length;
|
||||||
|
|
||||||
|
if (physicalOffset > (ULONGLONG) _I64_MAX)
|
||||||
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
|
||||||
|
offset.QuadPart = (LONGLONG) physicalOffset;
|
||||||
|
|
||||||
|
while (remainingBytes)
|
||||||
|
{
|
||||||
|
ULONG readCount = min (bufferSize, remainingBytes);
|
||||||
|
NTSTATUS status = ZwReadFile (Extension->hDeviceFile, NULL, NULL, NULL, &ioStatus, buffer, readCount, &offset, NULL);
|
||||||
|
|
||||||
|
if (NT_SUCCESS (status) && ioStatus.Information != readCount)
|
||||||
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
else if (!NT_SUCCESS (status))
|
||||||
|
return status;
|
||||||
|
|
||||||
|
remainingBytes -= readCount;
|
||||||
|
offset.QuadPart += (ULONGLONG) readCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static NTSTATUS VerifyVolumeReadRange (PEXTENSION Extension, ULONGLONG logicalOffset, ULONG length)
|
||||||
|
{
|
||||||
|
HRESULT hResult;
|
||||||
|
ULONGLONG logicalEndOffset;
|
||||||
|
DWORD bufferSize;
|
||||||
|
PVOID buffer;
|
||||||
|
NTSTATUS status = STATUS_SUCCESS;
|
||||||
|
|
||||||
|
if (S_OK != ULongLongAdd (logicalOffset, (ULONGLONG) length, &logicalEndOffset)
|
||||||
|
|| logicalEndOffset > (ULONGLONG) Extension->DiskLength)
|
||||||
|
{
|
||||||
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (length == 0)
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
|
||||||
|
bufferSize = min (length, 16 * PAGE_SIZE);
|
||||||
|
buffer = TCalloc (bufferSize);
|
||||||
|
if (!buffer)
|
||||||
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
|
||||||
|
if (Extension->Queue.NonSysInplaceRecoveryMode)
|
||||||
|
{
|
||||||
|
ULONG remainingBytes = length;
|
||||||
|
ULONGLONG currentLogicalOffset = logicalOffset;
|
||||||
|
|
||||||
|
while (remainingBytes)
|
||||||
|
{
|
||||||
|
ULONG fragmentLength = min (bufferSize, remainingBytes);
|
||||||
|
ULONGLONG physicalOffset;
|
||||||
|
|
||||||
|
if (currentLogicalOffset < (ULONGLONG) Extension->Queue.NonSysInplaceLogicalEncryptedStart)
|
||||||
|
{
|
||||||
|
ULONGLONG bytesToEncryptedStart = (ULONGLONG) Extension->Queue.NonSysInplaceLogicalEncryptedStart - currentLogicalOffset;
|
||||||
|
if ((ULONGLONG) fragmentLength > bytesToEncryptedStart)
|
||||||
|
fragmentLength = (ULONG) bytesToEncryptedStart;
|
||||||
|
|
||||||
|
physicalOffset = currentLogicalOffset;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
hResult = ULongLongAdd (currentLogicalOffset, (ULONGLONG) TC_VOLUME_DATA_OFFSET, &physicalOffset);
|
||||||
|
if (hResult != S_OK)
|
||||||
|
{
|
||||||
|
status = STATUS_INVALID_PARAMETER;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
status = VerifyBackingReadRange (Extension, buffer, bufferSize, physicalOffset, fragmentLength);
|
||||||
|
if (!NT_SUCCESS (status))
|
||||||
|
break;
|
||||||
|
|
||||||
|
currentLogicalOffset += fragmentLength;
|
||||||
|
remainingBytes -= fragmentLength;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ULONGLONG physicalOffset;
|
||||||
|
ULONGLONG volumeOffset = Extension->cryptoInfo->hiddenVolume
|
||||||
|
? Extension->cryptoInfo->hiddenVolumeOffset
|
||||||
|
: Extension->cryptoInfo->volDataAreaOffset;
|
||||||
|
|
||||||
|
hResult = ULongLongAdd (logicalOffset, volumeOffset, &physicalOffset);
|
||||||
|
if (hResult != S_OK)
|
||||||
|
status = STATUS_INVALID_PARAMETER;
|
||||||
|
else
|
||||||
|
status = VerifyBackingReadRange (Extension, buffer, bufferSize, physicalOffset, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
burn (buffer, bufferSize);
|
||||||
|
TCfree (buffer);
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
NTSTATUS ProcessVolumeDeviceControlIrp (PDEVICE_OBJECT DeviceObject, PEXTENSION Extension, PIRP Irp)
|
NTSTATUS ProcessVolumeDeviceControlIrp (PDEVICE_OBJECT DeviceObject, PEXTENSION Extension, PIRP Irp)
|
||||||
{
|
{
|
||||||
PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation (Irp);
|
PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation (Irp);
|
||||||
@@ -1339,65 +1445,16 @@ NTSTATUS ProcessVolumeDeviceControlIrp (PDEVICE_OBJECT DeviceObject, PEXTENSION
|
|||||||
|
|
||||||
case IOCTL_DISK_VERIFY:
|
case IOCTL_DISK_VERIFY:
|
||||||
Dump ("ProcessVolumeDeviceControlIrp (IOCTL_DISK_VERIFY)\n");
|
Dump ("ProcessVolumeDeviceControlIrp (IOCTL_DISK_VERIFY)\n");
|
||||||
|
Irp->IoStatus.Information = 0;
|
||||||
if (ValidateIOBufferSize (Irp, sizeof (VERIFY_INFORMATION), ValidateInput))
|
if (ValidateIOBufferSize (Irp, sizeof (VERIFY_INFORMATION), ValidateInput))
|
||||||
{
|
{
|
||||||
HRESULT hResult;
|
|
||||||
ULONGLONG ullStartingOffset, ullNewOffset, ullEndOffset;
|
|
||||||
PVERIFY_INFORMATION pVerifyInformation;
|
PVERIFY_INFORMATION pVerifyInformation;
|
||||||
ULONGLONG volumeOffset = Extension->cryptoInfo->hiddenVolume
|
|
||||||
? Extension->cryptoInfo->hiddenVolumeOffset
|
|
||||||
: Extension->cryptoInfo->volDataAreaOffset;
|
|
||||||
pVerifyInformation = (PVERIFY_INFORMATION) Irp->AssociatedIrp.SystemBuffer;
|
pVerifyInformation = (PVERIFY_INFORMATION) Irp->AssociatedIrp.SystemBuffer;
|
||||||
|
|
||||||
ullStartingOffset = (ULONGLONG) pVerifyInformation->StartingOffset.QuadPart;
|
if (pVerifyInformation->StartingOffset.QuadPart < 0)
|
||||||
hResult = ULongLongAdd(ullStartingOffset,
|
|
||||||
volumeOffset,
|
|
||||||
&ullNewOffset);
|
|
||||||
if (hResult != S_OK)
|
|
||||||
Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
|
|
||||||
else if (S_OK != ULongLongAdd(ullStartingOffset, (ULONGLONG) pVerifyInformation->Length, &ullEndOffset))
|
|
||||||
Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
|
|
||||||
else if (ullEndOffset > (ULONGLONG) Extension->DiskLength)
|
|
||||||
Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
|
Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
|
||||||
else
|
else
|
||||||
{
|
Irp->IoStatus.Status = VerifyVolumeReadRange (Extension, (ULONGLONG) pVerifyInformation->StartingOffset.QuadPart, pVerifyInformation->Length);
|
||||||
IO_STATUS_BLOCK ioStatus;
|
|
||||||
DWORD dwBuffersize = min (pVerifyInformation->Length, 16 * PAGE_SIZE);
|
|
||||||
PVOID buffer = TCalloc (dwBuffersize);
|
|
||||||
|
|
||||||
if (!buffer)
|
|
||||||
{
|
|
||||||
Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
LARGE_INTEGER offset;
|
|
||||||
DWORD dwRemainingBytes = pVerifyInformation->Length, dwReadCount;
|
|
||||||
offset.QuadPart = ullNewOffset;
|
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
dwRemainingBytes -= dwReadCount;
|
|
||||||
offset.QuadPart += (ULONGLONG) dwReadCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
burn (buffer, dwBuffersize);
|
|
||||||
TCfree (buffer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Irp->IoStatus.Information = 0;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -2614,6 +2671,14 @@ NTSTATUS ProcessMainDeviceControlIrp (PDEVICE_OBJECT DeviceObject, PEXTENSION Ex
|
|||||||
EnsureNullTerminatedString (mount->wszVolume, sizeof (mount->wszVolume));
|
EnsureNullTerminatedString (mount->wszVolume, sizeof (mount->wszVolume));
|
||||||
EnsureNullTerminatedString (mount->wszLabel, sizeof (mount->wszLabel));
|
EnsureNullTerminatedString (mount->wszLabel, sizeof (mount->wszLabel));
|
||||||
|
|
||||||
|
if (mount->NonSysInplaceRecoveryReadOnly)
|
||||||
|
{
|
||||||
|
mount->UseBackupHeader = TRUE;
|
||||||
|
mount->bMountReadOnly = TRUE;
|
||||||
|
mount->bProtectHiddenVolume = FALSE;
|
||||||
|
mount->bPartitionInInactiveSysEncScope = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
Irp->IoStatus.Information = sizeof (MOUNT_STRUCT);
|
Irp->IoStatus.Information = sizeof (MOUNT_STRUCT);
|
||||||
Irp->IoStatus.Status = MountDevice (DeviceObject, mount);
|
Irp->IoStatus.Status = MountDevice (DeviceObject, mount);
|
||||||
|
|
||||||
@@ -3094,7 +3159,33 @@ VOID VolumeThreadProc (PVOID Context)
|
|||||||
Extension->Queue.HostFileHandle = Extension->hDeviceFile;
|
Extension->Queue.HostFileHandle = Extension->hDeviceFile;
|
||||||
Extension->Queue.VirtualDeviceLength = Extension->DiskLength;
|
Extension->Queue.VirtualDeviceLength = Extension->DiskLength;
|
||||||
Extension->Queue.MaxReadAheadOffset.QuadPart = Extension->HostLength;
|
Extension->Queue.MaxReadAheadOffset.QuadPart = Extension->HostLength;
|
||||||
if (bDevice && pThreadBlock->mount->bPartitionInInactiveSysEncScope
|
if (bDevice && pThreadBlock->mount->NonSysInplaceRecoveryReadOnly)
|
||||||
|
{
|
||||||
|
int64 logicalEncryptedStart;
|
||||||
|
int64 logicalEncryptedEnd;
|
||||||
|
uint32 concealedPlaintextLength;
|
||||||
|
|
||||||
|
if (!GetNonSysInplaceRecoveryGeometry (Extension->cryptoInfo, &logicalEncryptedStart, &logicalEncryptedEnd, &concealedPlaintextLength))
|
||||||
|
{
|
||||||
|
TCCloseVolume (DeviceObject, Extension);
|
||||||
|
pThreadBlock->mount->nReturnCode = ERR_NONSYS_INPLACE_RECOVERY_READONLY_UNSUPPORTED;
|
||||||
|
pThreadBlock->ntCreateStatus = STATUS_SUCCESS;
|
||||||
|
KeSetEvent (&Extension->keCreateEvent, 0, FALSE);
|
||||||
|
PsTerminateSystemThread (STATUS_SUCCESS);
|
||||||
|
return; /* Make static analyzer happy */
|
||||||
|
}
|
||||||
|
|
||||||
|
Extension->Queue.NonSysInplaceRecoveryMode = TRUE;
|
||||||
|
Extension->Queue.NonSysInplaceLogicalEncryptedStart = logicalEncryptedStart;
|
||||||
|
Extension->Queue.NonSysInplaceLogicalEncryptedEnd = logicalEncryptedEnd;
|
||||||
|
Extension->Queue.NonSysInplaceConcealedPlaintextLength = concealedPlaintextLength;
|
||||||
|
Extension->Queue.EncryptedAreaStart = -1;
|
||||||
|
Extension->Queue.EncryptedAreaEnd = -1;
|
||||||
|
|
||||||
|
Dump ("Non-system in-place recovery mount: logical encrypted area %I64d-%I64d, concealed plaintext bytes %u\n",
|
||||||
|
logicalEncryptedStart, logicalEncryptedEnd, concealedPlaintextLength);
|
||||||
|
}
|
||||||
|
else if (bDevice && pThreadBlock->mount->bPartitionInInactiveSysEncScope
|
||||||
&& (!Extension->cryptoInfo->hiddenVolume)
|
&& (!Extension->cryptoInfo->hiddenVolume)
|
||||||
&& (Extension->cryptoInfo->EncryptedAreaLength.Value != Extension->cryptoInfo->VolumeSize.Value)
|
&& (Extension->cryptoInfo->EncryptedAreaLength.Value != Extension->cryptoInfo->VolumeSize.Value)
|
||||||
)
|
)
|
||||||
|
|||||||
+94
-3
@@ -36,6 +36,62 @@
|
|||||||
|
|
||||||
volatile BOOL ProbingHostDeviceForWrite = FALSE;
|
volatile BOOL ProbingHostDeviceForWrite = FALSE;
|
||||||
|
|
||||||
|
BOOL GetNonSysInplaceRecoveryGeometry (PCRYPTO_INFO cryptoInfo, int64 *logicalEncryptedStart, int64 *logicalEncryptedEnd, uint32 *concealedPlaintextLength)
|
||||||
|
{
|
||||||
|
uint64 volumeSize;
|
||||||
|
uint64 encryptedAreaStart;
|
||||||
|
uint64 encryptedAreaLength;
|
||||||
|
uint64 encryptedAreaEndExclusive;
|
||||||
|
uint64 expectedAreaEndExclusive;
|
||||||
|
uint64 logicalStart;
|
||||||
|
|
||||||
|
if (!cryptoInfo)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
volumeSize = cryptoInfo->VolumeSize.Value;
|
||||||
|
encryptedAreaStart = cryptoInfo->EncryptedAreaStart.Value;
|
||||||
|
encryptedAreaLength = cryptoInfo->EncryptedAreaLength.Value;
|
||||||
|
|
||||||
|
if (cryptoInfo->hiddenVolume
|
||||||
|
|| (cryptoInfo->HeaderFlags & TC_HEADER_FLAG_NONSYS_INPLACE_ENC) == 0
|
||||||
|
|| (cryptoInfo->HeaderFlags & TC_HEADER_FLAG_ENCRYPTED_SYSTEM) != 0
|
||||||
|
|| volumeSize == 0
|
||||||
|
|| encryptedAreaLength == 0
|
||||||
|
|| encryptedAreaLength >= volumeSize
|
||||||
|
|| encryptedAreaStart < TC_VOLUME_DATA_OFFSET
|
||||||
|
|| volumeSize > (uint64) _I64_MAX
|
||||||
|
|| encryptedAreaStart > (uint64) _I64_MAX
|
||||||
|
|| encryptedAreaLength > (uint64) _I64_MAX
|
||||||
|
|| encryptedAreaStart > ((uint64) _I64_MAX - encryptedAreaLength)
|
||||||
|
|| volumeSize > ((uint64) _I64_MAX - TC_VOLUME_DATA_OFFSET))
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
encryptedAreaEndExclusive = encryptedAreaStart + encryptedAreaLength;
|
||||||
|
expectedAreaEndExclusive = TC_VOLUME_DATA_OFFSET + volumeSize;
|
||||||
|
|
||||||
|
if (encryptedAreaEndExclusive != expectedAreaEndExclusive)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
logicalStart = encryptedAreaStart - TC_VOLUME_DATA_OFFSET;
|
||||||
|
|
||||||
|
if (logicalStart >= volumeSize
|
||||||
|
|| (logicalStart % ENCRYPTION_DATA_UNIT_SIZE) != 0)
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (logicalEncryptedStart)
|
||||||
|
*logicalEncryptedStart = (int64) logicalStart;
|
||||||
|
if (logicalEncryptedEnd)
|
||||||
|
*logicalEncryptedEnd = (int64) (logicalStart + encryptedAreaLength - 1);
|
||||||
|
if (concealedPlaintextLength)
|
||||||
|
*concealedPlaintextLength = logicalStart < TC_INITIAL_NTFS_CONCEAL_PORTION_SIZE ? (uint32) logicalStart : TC_INITIAL_NTFS_CONCEAL_PORTION_SIZE;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
NTSTATUS TCOpenVolume (PDEVICE_OBJECT DeviceObject,
|
NTSTATUS TCOpenVolume (PDEVICE_OBJECT DeviceObject,
|
||||||
PEXTENSION Extension,
|
PEXTENSION Extension,
|
||||||
@@ -58,6 +114,7 @@ NTSTATUS TCOpenVolume (PDEVICE_OBJECT DeviceObject,
|
|||||||
BOOL forceAccessCheck = !bRawDevice;
|
BOOL forceAccessCheck = !bRawDevice;
|
||||||
BOOL disableBuffering = TRUE;
|
BOOL disableBuffering = TRUE;
|
||||||
BOOL exclusiveAccess = mount->bExclusiveAccess;
|
BOOL exclusiveAccess = mount->bExclusiveAccess;
|
||||||
|
int volumeTypeCount;
|
||||||
/* when mounting with hidden volume protection, we cache the passwords after both outer and hidden volumes are mounted successfully*/
|
/* when mounting with hidden volume protection, we cache the passwords after both outer and hidden volumes are mounted successfully*/
|
||||||
BOOL bAutoCachePassword = mount->bProtectHiddenVolume? FALSE : mount->bCache;
|
BOOL bAutoCachePassword = mount->bProtectHiddenVolume? FALSE : mount->bCache;
|
||||||
|
|
||||||
@@ -91,6 +148,21 @@ NTSTATUS TCOpenVolume (PDEVICE_OBJECT DeviceObject,
|
|||||||
mount->VolumeMountedReadOnlyAfterPartialSysEnc = FALSE;
|
mount->VolumeMountedReadOnlyAfterPartialSysEnc = FALSE;
|
||||||
mount->VolumeMasterKeyVulnerable = FALSE;
|
mount->VolumeMasterKeyVulnerable = FALSE;
|
||||||
|
|
||||||
|
if (mount->NonSysInplaceRecoveryReadOnly)
|
||||||
|
{
|
||||||
|
mount->UseBackupHeader = TRUE;
|
||||||
|
mount->bMountReadOnly = TRUE;
|
||||||
|
mount->bProtectHiddenVolume = FALSE;
|
||||||
|
bAutoCachePassword = mount->bCache;
|
||||||
|
|
||||||
|
if (!bRawDevice || mount->bPartitionInInactiveSysEncScope)
|
||||||
|
{
|
||||||
|
mount->nReturnCode = ERR_NONSYS_INPLACE_RECOVERY_READONLY_UNSUPPORTED;
|
||||||
|
ntStatus = STATUS_SUCCESS;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// If we are opening a device, query its size first
|
// If we are opening a device, query its size first
|
||||||
if (bRawDevice)
|
if (bRawDevice)
|
||||||
{
|
{
|
||||||
@@ -467,8 +539,10 @@ NTSTATUS TCOpenVolume (PDEVICE_OBJECT DeviceObject,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Go through all volume types (e.g., normal, hidden)
|
// Go through all volume types (e.g., normal, hidden)
|
||||||
|
volumeTypeCount = mount->NonSysInplaceRecoveryReadOnly ? TC_VOLUME_TYPE_NORMAL + 1 : TC_VOLUME_TYPE_COUNT;
|
||||||
|
|
||||||
for (volumeType = TC_VOLUME_TYPE_NORMAL;
|
for (volumeType = TC_VOLUME_TYPE_NORMAL;
|
||||||
volumeType < TC_VOLUME_TYPE_COUNT;
|
volumeType < volumeTypeCount;
|
||||||
volumeType++)
|
volumeType++)
|
||||||
{
|
{
|
||||||
Dump ("Trying to open volume type %d\n", volumeType);
|
Dump ("Trying to open volume type %d\n", volumeType);
|
||||||
@@ -660,7 +734,19 @@ NTSTATUS TCOpenVolume (PDEVICE_OBJECT DeviceObject,
|
|||||||
|
|
||||||
if (volumeType == TC_VOLUME_TYPE_NORMAL)
|
if (volumeType == TC_VOLUME_TYPE_NORMAL)
|
||||||
{
|
{
|
||||||
if (mount->bPartitionInInactiveSysEncScope)
|
if (mount->NonSysInplaceRecoveryReadOnly)
|
||||||
|
{
|
||||||
|
if (!GetNonSysInplaceRecoveryGeometry (Extension->cryptoInfo, NULL, NULL, NULL))
|
||||||
|
{
|
||||||
|
mount->nReturnCode = ERR_NONSYS_INPLACE_RECOVERY_READONLY_UNSUPPORTED;
|
||||||
|
ntStatus = STATUS_SUCCESS;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
Extension->bReadOnly = mount->bMountReadOnly = TRUE;
|
||||||
|
Extension->TrimEnabled = FALSE;
|
||||||
|
}
|
||||||
|
else if (mount->bPartitionInInactiveSysEncScope)
|
||||||
{
|
{
|
||||||
if (Extension->cryptoInfo->EncryptedAreaStart.Value > (unsigned __int64) partitionStartingOffset
|
if (Extension->cryptoInfo->EncryptedAreaStart.Value > (unsigned __int64) partitionStartingOffset
|
||||||
|| Extension->cryptoInfo->EncryptedAreaStart.Value + Extension->cryptoInfo->VolumeSize.Value <= (unsigned __int64) partitionStartingOffset)
|
|| Extension->cryptoInfo->EncryptedAreaStart.Value + Extension->cryptoInfo->VolumeSize.Value <= (unsigned __int64) partitionStartingOffset)
|
||||||
@@ -709,7 +795,12 @@ NTSTATUS TCOpenVolume (PDEVICE_OBJECT DeviceObject,
|
|||||||
|
|
||||||
Extension->cryptoInfo->hiddenVolume = FALSE;
|
Extension->cryptoInfo->hiddenVolume = FALSE;
|
||||||
|
|
||||||
if (mount->bPartitionInInactiveSysEncScope)
|
if (mount->NonSysInplaceRecoveryReadOnly)
|
||||||
|
{
|
||||||
|
Extension->cryptoInfo->volDataAreaOffset = 0;
|
||||||
|
Extension->DiskLength = Extension->cryptoInfo->VolumeSize.Value;
|
||||||
|
}
|
||||||
|
else if (mount->bPartitionInInactiveSysEncScope)
|
||||||
{
|
{
|
||||||
Extension->cryptoInfo->volDataAreaOffset = 0;
|
Extension->cryptoInfo->volDataAreaOffset = 0;
|
||||||
Extension->DiskLength = lDiskLength.QuadPart;
|
Extension->DiskLength = lDiskLength.QuadPart;
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ extern volatile BOOL ProbingHostDeviceForWrite;
|
|||||||
|
|
||||||
NTSTATUS TCOpenVolume ( PDEVICE_OBJECT DeviceObject , PEXTENSION Extension , MOUNT_STRUCT *mount , PWSTR pwszMountVolume , BOOL bRawDevice );
|
NTSTATUS TCOpenVolume ( PDEVICE_OBJECT DeviceObject , PEXTENSION Extension , MOUNT_STRUCT *mount , PWSTR pwszMountVolume , BOOL bRawDevice );
|
||||||
void TCCloseVolume ( PDEVICE_OBJECT DeviceObject , PEXTENSION Extension );
|
void TCCloseVolume ( PDEVICE_OBJECT DeviceObject , PEXTENSION Extension );
|
||||||
|
BOOL GetNonSysInplaceRecoveryGeometry ( PCRYPTO_INFO cryptoInfo , int64 *logicalEncryptedStart , int64 *logicalEncryptedEnd , uint32 *concealedPlaintextLength );
|
||||||
NTSTATUS TCCompletion ( PDEVICE_OBJECT DeviceObject , PIRP Irp , PVOID pUserBuffer );
|
NTSTATUS TCCompletion ( PDEVICE_OBJECT DeviceObject , PIRP Irp , PVOID pUserBuffer );
|
||||||
NTSTATUS TCSendHostDeviceIoControlRequest ( PDEVICE_OBJECT DeviceObject , PEXTENSION Extension , ULONG IoControlCode , void *OutputBuffer , ULONG OutputBufferSize );
|
NTSTATUS TCSendHostDeviceIoControlRequest ( PDEVICE_OBJECT DeviceObject , PEXTENSION Extension , ULONG IoControlCode , void *OutputBuffer , ULONG OutputBufferSize );
|
||||||
NTSTATUS TCSendHostDeviceIoControlRequestEx ( PDEVICE_OBJECT DeviceObject , PEXTENSION Extension , ULONG IoControlCode , void *InputBuffer , ULONG InputBufferSize , void *OutputBuffer , ULONG OutputBufferSize );
|
NTSTATUS TCSendHostDeviceIoControlRequestEx ( PDEVICE_OBJECT DeviceObject , PEXTENSION Extension , ULONG IoControlCode , void *InputBuffer , ULONG InputBufferSize , void *OutputBuffer , ULONG OutputBufferSize );
|
||||||
|
|||||||
@@ -57,8 +57,6 @@ using namespace VeraCrypt;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define TC_MAX_NONSYS_INPLACE_ENC_WORK_CHUNK_SIZE (2048 * BYTES_PER_KB)
|
#define TC_MAX_NONSYS_INPLACE_ENC_WORK_CHUNK_SIZE (2048 * BYTES_PER_KB)
|
||||||
#define TC_INITIAL_NTFS_CONCEAL_PORTION_SIZE (2 * TC_MAX_VOLUME_SECTOR_SIZE)
|
|
||||||
#define TC_NTFS_CONCEAL_CONSTANT 0xFF
|
|
||||||
#define TC_NONSYS_INPLACE_ENC_HEADER_UPDATE_INTERVAL (64 * BYTES_PER_MB)
|
#define TC_NONSYS_INPLACE_ENC_HEADER_UPDATE_INTERVAL (64 * BYTES_PER_MB)
|
||||||
#define TC_NONSYS_INPLACE_ENC_MIN_VOL_SIZE (TC_TOTAL_VOLUME_HEADERS_SIZE + TC_MIN_NTFS_FS_SIZE * 2)
|
#define TC_NONSYS_INPLACE_ENC_MIN_VOL_SIZE (TC_TOTAL_VOLUME_HEADERS_SIZE + TC_MIN_NTFS_FS_SIZE * 2)
|
||||||
|
|
||||||
|
|||||||
+64
-7
@@ -1089,6 +1089,7 @@ void LoadSettingsAndCheckModified (HWND hwndDlg, BOOL bOnlyCheckModified, BOOL*
|
|||||||
defaultMountOptions.ProtectedHidVolPim = 0;
|
defaultMountOptions.ProtectedHidVolPim = 0;
|
||||||
defaultMountOptions.PartitionInInactiveSysEncScope = FALSE;
|
defaultMountOptions.PartitionInInactiveSysEncScope = FALSE;
|
||||||
defaultMountOptions.RecoveryMode = FALSE;
|
defaultMountOptions.RecoveryMode = FALSE;
|
||||||
|
defaultMountOptions.NonSysInplaceRecoveryReadOnly = FALSE;
|
||||||
defaultMountOptions.UseBackupHeader = FALSE;
|
defaultMountOptions.UseBackupHeader = FALSE;
|
||||||
defaultMountOptions.SkipCachedPasswords = FALSE;
|
defaultMountOptions.SkipCachedPasswords = FALSE;
|
||||||
|
|
||||||
@@ -3923,8 +3924,10 @@ BOOL CALLBACK MountOptionsDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM
|
|||||||
case WM_INITDIALOG:
|
case WM_INITDIALOG:
|
||||||
{
|
{
|
||||||
BOOL protect;
|
BOOL protect;
|
||||||
|
BOOL nonSysInplaceRecovery;
|
||||||
|
|
||||||
pMountOptions = (MountOptions *) lParam;
|
pMountOptions = (MountOptions *) lParam;
|
||||||
|
nonSysInplaceRecovery = !bPrebootPasswordDlgMode && pMountOptions->NonSysInplaceRecoveryReadOnly;
|
||||||
|
|
||||||
LocalizeDialog (hwndDlg, "IDD_MOUNT_OPTIONS");
|
LocalizeDialog (hwndDlg, "IDD_MOUNT_OPTIONS");
|
||||||
|
|
||||||
@@ -3935,6 +3938,9 @@ BOOL CALLBACK MountOptionsDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM
|
|||||||
SendDlgItemMessage (hwndDlg, IDC_DISABLE_MOUNT_MANAGER, BM_SETCHECK,
|
SendDlgItemMessage (hwndDlg, IDC_DISABLE_MOUNT_MANAGER, BM_SETCHECK,
|
||||||
pMountOptions->DisableMountManager ? BST_CHECKED : BST_UNCHECKED, 0);
|
pMountOptions->DisableMountManager ? BST_CHECKED : BST_UNCHECKED, 0);
|
||||||
|
|
||||||
|
SendDlgItemMessage (hwndDlg, IDC_NONSYS_INPLACE_RECOVERY_READONLY, BM_SETCHECK,
|
||||||
|
nonSysInplaceRecovery ? BST_CHECKED : BST_UNCHECKED, 0);
|
||||||
|
|
||||||
SendDlgItemMessage (hwndDlg, IDC_PROTECT_HIDDEN_VOL, BM_SETCHECK,
|
SendDlgItemMessage (hwndDlg, IDC_PROTECT_HIDDEN_VOL, BM_SETCHECK,
|
||||||
pMountOptions->ProtectHiddenVolume ? BST_CHECKED : BST_UNCHECKED, 0);
|
pMountOptions->ProtectHiddenVolume ? BST_CHECKED : BST_UNCHECKED, 0);
|
||||||
|
|
||||||
@@ -3946,7 +3952,18 @@ BOOL CALLBACK MountOptionsDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM
|
|||||||
SendDlgItemMessage (hwndDlg, IDC_USE_EMBEDDED_HEADER_BAK, BM_SETCHECK,
|
SendDlgItemMessage (hwndDlg, IDC_USE_EMBEDDED_HEADER_BAK, BM_SETCHECK,
|
||||||
pMountOptions->UseBackupHeader ? BST_CHECKED : BST_UNCHECKED, 0);
|
pMountOptions->UseBackupHeader ? BST_CHECKED : BST_UNCHECKED, 0);
|
||||||
|
|
||||||
EnableWindow (GetDlgItem (hwndDlg, IDC_MOUNT_SYSENC_PART_WITHOUT_PBA), !bPrebootPasswordDlgMode);
|
if (nonSysInplaceRecovery)
|
||||||
|
{
|
||||||
|
SendDlgItemMessage (hwndDlg, IDC_MOUNT_READONLY, BM_SETCHECK, BST_CHECKED, 0);
|
||||||
|
SendDlgItemMessage (hwndDlg, IDC_USE_EMBEDDED_HEADER_BAK, BM_SETCHECK, BST_CHECKED, 0);
|
||||||
|
SendDlgItemMessage (hwndDlg, IDC_PROTECT_HIDDEN_VOL, BM_SETCHECK, BST_UNCHECKED, 0);
|
||||||
|
SendDlgItemMessage (hwndDlg, IDC_MOUNT_SYSENC_PART_WITHOUT_PBA, BM_SETCHECK, BST_UNCHECKED, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
EnableWindow (GetDlgItem (hwndDlg, IDC_MOUNT_READONLY), !nonSysInplaceRecovery);
|
||||||
|
EnableWindow (GetDlgItem (hwndDlg, IDC_USE_EMBEDDED_HEADER_BAK), !nonSysInplaceRecovery);
|
||||||
|
EnableWindow (GetDlgItem (hwndDlg, IDC_MOUNT_SYSENC_PART_WITHOUT_PBA), !bPrebootPasswordDlgMode && !nonSysInplaceRecovery);
|
||||||
|
EnableWindow (GetDlgItem (hwndDlg, IDC_NONSYS_INPLACE_RECOVERY_READONLY), !bPrebootPasswordDlgMode);
|
||||||
|
|
||||||
SetDlgItemTextW (hwndDlg, IDC_VOLUME_LABEL, pMountOptions->Label);
|
SetDlgItemTextW (hwndDlg, IDC_VOLUME_LABEL, pMountOptions->Label);
|
||||||
SendDlgItemMessage (hwndDlg, IDC_VOLUME_LABEL, EM_LIMITTEXT, 32, 0); // 32 is the maximum possible length for a drive label in Windows
|
SendDlgItemMessage (hwndDlg, IDC_VOLUME_LABEL, EM_LIMITTEXT, 32, 0); // 32 is the maximum possible length for a drive label in Windows
|
||||||
@@ -3975,8 +3992,8 @@ BOOL CALLBACK MountOptionsDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM
|
|||||||
|
|
||||||
protect = IsButtonChecked (GetDlgItem (hwndDlg, IDC_PROTECT_HIDDEN_VOL));
|
protect = IsButtonChecked (GetDlgItem (hwndDlg, IDC_PROTECT_HIDDEN_VOL));
|
||||||
|
|
||||||
EnableWindow (GetDlgItem (hwndDlg, IDC_PROTECT_HIDDEN_VOL), !IsButtonChecked (GetDlgItem (hwndDlg, IDC_MOUNT_READONLY)));
|
EnableWindow (GetDlgItem (hwndDlg, IDC_PROTECT_HIDDEN_VOL), !IsButtonChecked (GetDlgItem (hwndDlg, IDC_MOUNT_READONLY)) && !nonSysInplaceRecovery);
|
||||||
EnableWindow (GetDlgItem (hwndDlg, IDT_HIDDEN_VOL_PROTECTION), !IsButtonChecked (GetDlgItem (hwndDlg, IDC_MOUNT_READONLY)));
|
EnableWindow (GetDlgItem (hwndDlg, IDT_HIDDEN_VOL_PROTECTION), !IsButtonChecked (GetDlgItem (hwndDlg, IDC_MOUNT_READONLY)) && !nonSysInplaceRecovery);
|
||||||
EnableWindow (GetDlgItem (hwndDlg, IDC_PASSWORD_PROT_HIDVOL), protect);
|
EnableWindow (GetDlgItem (hwndDlg, IDC_PASSWORD_PROT_HIDVOL), protect);
|
||||||
EnableWindow (GetDlgItem (hwndDlg, IDC_SHOW_PASSWORD_MO), protect);
|
EnableWindow (GetDlgItem (hwndDlg, IDC_SHOW_PASSWORD_MO), protect);
|
||||||
EnableWindow (GetDlgItem (hwndDlg, IDT_HIDDEN_PROT_PASSWD), protect);
|
EnableWindow (GetDlgItem (hwndDlg, IDT_HIDDEN_PROT_PASSWD), protect);
|
||||||
@@ -4113,6 +4130,10 @@ BOOL CALLBACK MountOptionsDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM
|
|||||||
if (lw == IDOK)
|
if (lw == IDOK)
|
||||||
{
|
{
|
||||||
wchar_t tmp[MAX_PASSWORD+1];
|
wchar_t tmp[MAX_PASSWORD+1];
|
||||||
|
BOOL nonSysInplaceRecovery = IsButtonChecked (GetDlgItem (hwndDlg, IDC_NONSYS_INPLACE_RECOVERY_READONLY));
|
||||||
|
|
||||||
|
if (nonSysInplaceRecovery && AskWarnYesNo ("NONSYS_INPLACE_RECOVERY_READONLY_WARNING", hwndDlg) != IDYES)
|
||||||
|
return 1;
|
||||||
|
|
||||||
pMountOptions->ReadOnly = IsButtonChecked (GetDlgItem (hwndDlg, IDC_MOUNT_READONLY));
|
pMountOptions->ReadOnly = IsButtonChecked (GetDlgItem (hwndDlg, IDC_MOUNT_READONLY));
|
||||||
pMountOptions->Removable = IsButtonChecked (GetDlgItem (hwndDlg, IDC_MOUNT_REMOVABLE));
|
pMountOptions->Removable = IsButtonChecked (GetDlgItem (hwndDlg, IDC_MOUNT_REMOVABLE));
|
||||||
@@ -4120,6 +4141,15 @@ BOOL CALLBACK MountOptionsDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM
|
|||||||
pMountOptions->ProtectHiddenVolume = IsButtonChecked (GetDlgItem (hwndDlg, IDC_PROTECT_HIDDEN_VOL));
|
pMountOptions->ProtectHiddenVolume = IsButtonChecked (GetDlgItem (hwndDlg, IDC_PROTECT_HIDDEN_VOL));
|
||||||
pMountOptions->PartitionInInactiveSysEncScope = IsButtonChecked (GetDlgItem (hwndDlg, IDC_MOUNT_SYSENC_PART_WITHOUT_PBA));
|
pMountOptions->PartitionInInactiveSysEncScope = IsButtonChecked (GetDlgItem (hwndDlg, IDC_MOUNT_SYSENC_PART_WITHOUT_PBA));
|
||||||
pMountOptions->UseBackupHeader = IsButtonChecked (GetDlgItem (hwndDlg, IDC_USE_EMBEDDED_HEADER_BAK));
|
pMountOptions->UseBackupHeader = IsButtonChecked (GetDlgItem (hwndDlg, IDC_USE_EMBEDDED_HEADER_BAK));
|
||||||
|
pMountOptions->NonSysInplaceRecoveryReadOnly = nonSysInplaceRecovery;
|
||||||
|
|
||||||
|
if (pMountOptions->NonSysInplaceRecoveryReadOnly)
|
||||||
|
{
|
||||||
|
pMountOptions->ReadOnly = TRUE;
|
||||||
|
pMountOptions->UseBackupHeader = TRUE;
|
||||||
|
pMountOptions->ProtectHiddenVolume = FALSE;
|
||||||
|
pMountOptions->PartitionInInactiveSysEncScope = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
GetDlgItemTextW (hwndDlg, IDC_VOLUME_LABEL, pMountOptions->Label, sizeof (pMountOptions->Label) /sizeof (wchar_t));
|
GetDlgItemTextW (hwndDlg, IDC_VOLUME_LABEL, pMountOptions->Label, sizeof (pMountOptions->Label) /sizeof (wchar_t));
|
||||||
|
|
||||||
@@ -4154,15 +4184,31 @@ BOOL CALLBACK MountOptionsDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lw == IDC_MOUNT_READONLY || lw == IDC_PROTECT_HIDDEN_VOL || lw == IDC_DISABLE_MOUNT_MANAGER)
|
if (lw == IDC_MOUNT_READONLY || lw == IDC_PROTECT_HIDDEN_VOL || lw == IDC_DISABLE_MOUNT_MANAGER || lw == IDC_NONSYS_INPLACE_RECOVERY_READONLY)
|
||||||
{
|
{
|
||||||
BOOL protect;
|
BOOL protect;
|
||||||
|
BOOL nonSysInplaceRecovery = IsButtonChecked (GetDlgItem (hwndDlg, IDC_NONSYS_INPLACE_RECOVERY_READONLY));
|
||||||
|
|
||||||
|
if (lw == IDC_NONSYS_INPLACE_RECOVERY_READONLY)
|
||||||
|
{
|
||||||
|
if (nonSysInplaceRecovery)
|
||||||
|
{
|
||||||
|
SendDlgItemMessage (hwndDlg, IDC_MOUNT_READONLY, BM_SETCHECK, BST_CHECKED, 0);
|
||||||
|
SendDlgItemMessage (hwndDlg, IDC_USE_EMBEDDED_HEADER_BAK, BM_SETCHECK, BST_CHECKED, 0);
|
||||||
|
SendDlgItemMessage (hwndDlg, IDC_PROTECT_HIDDEN_VOL, BM_SETCHECK, BST_UNCHECKED, 0);
|
||||||
|
SendDlgItemMessage (hwndDlg, IDC_MOUNT_SYSENC_PART_WITHOUT_PBA, BM_SETCHECK, BST_UNCHECKED, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
EnableWindow (GetDlgItem (hwndDlg, IDC_MOUNT_READONLY), !nonSysInplaceRecovery);
|
||||||
|
EnableWindow (GetDlgItem (hwndDlg, IDC_USE_EMBEDDED_HEADER_BAK), !nonSysInplaceRecovery);
|
||||||
|
EnableWindow (GetDlgItem (hwndDlg, IDC_MOUNT_SYSENC_PART_WITHOUT_PBA), !bPrebootPasswordDlgMode && !nonSysInplaceRecovery);
|
||||||
|
}
|
||||||
|
|
||||||
if (lw == IDC_MOUNT_READONLY)
|
if (lw == IDC_MOUNT_READONLY)
|
||||||
{
|
{
|
||||||
SendDlgItemMessage (hwndDlg, IDC_PROTECT_HIDDEN_VOL, BM_SETCHECK, BST_UNCHECKED, 0);
|
SendDlgItemMessage (hwndDlg, IDC_PROTECT_HIDDEN_VOL, BM_SETCHECK, BST_UNCHECKED, 0);
|
||||||
EnableWindow (GetDlgItem (hwndDlg, IDC_PROTECT_HIDDEN_VOL), !IsButtonChecked (GetDlgItem (hwndDlg, IDC_MOUNT_READONLY)));
|
EnableWindow (GetDlgItem (hwndDlg, IDC_PROTECT_HIDDEN_VOL), !IsButtonChecked (GetDlgItem (hwndDlg, IDC_MOUNT_READONLY)) && !nonSysInplaceRecovery);
|
||||||
EnableWindow (GetDlgItem (hwndDlg, IDT_HIDDEN_VOL_PROTECTION), !IsButtonChecked (GetDlgItem (hwndDlg, IDC_MOUNT_READONLY)));
|
EnableWindow (GetDlgItem (hwndDlg, IDT_HIDDEN_VOL_PROTECTION), !IsButtonChecked (GetDlgItem (hwndDlg, IDC_MOUNT_READONLY)) && !nonSysInplaceRecovery);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lw == IDC_DISABLE_MOUNT_MANAGER)
|
if (lw == IDC_DISABLE_MOUNT_MANAGER)
|
||||||
@@ -4171,7 +4217,10 @@ BOOL CALLBACK MountOptionsDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM
|
|||||||
EnableWindow (GetDlgItem (hwndDlg, IDT_VOLUME_LABEL), !IsButtonChecked (GetDlgItem (hwndDlg, IDC_DISABLE_MOUNT_MANAGER)));
|
EnableWindow (GetDlgItem (hwndDlg, IDT_VOLUME_LABEL), !IsButtonChecked (GetDlgItem (hwndDlg, IDC_DISABLE_MOUNT_MANAGER)));
|
||||||
}
|
}
|
||||||
|
|
||||||
protect = IsButtonChecked (GetDlgItem (hwndDlg, IDC_PROTECT_HIDDEN_VOL));
|
EnableWindow (GetDlgItem (hwndDlg, IDC_PROTECT_HIDDEN_VOL), !IsButtonChecked (GetDlgItem (hwndDlg, IDC_MOUNT_READONLY)) && !nonSysInplaceRecovery);
|
||||||
|
EnableWindow (GetDlgItem (hwndDlg, IDT_HIDDEN_VOL_PROTECTION), !IsButtonChecked (GetDlgItem (hwndDlg, IDC_MOUNT_READONLY)) && !nonSysInplaceRecovery);
|
||||||
|
|
||||||
|
protect = IsButtonChecked (GetDlgItem (hwndDlg, IDC_PROTECT_HIDDEN_VOL)) && !nonSysInplaceRecovery;
|
||||||
|
|
||||||
EnableWindow (GetDlgItem (hwndDlg, IDC_PASSWORD_PROT_HIDVOL), protect);
|
EnableWindow (GetDlgItem (hwndDlg, IDC_PASSWORD_PROT_HIDVOL), protect);
|
||||||
EnableWindow (GetDlgItem (hwndDlg, IDT_HIDDEN_PROT_PASSWD), protect);
|
EnableWindow (GetDlgItem (hwndDlg, IDT_HIDDEN_PROT_PASSWD), protect);
|
||||||
@@ -9893,6 +9942,14 @@ void ExtractCommandLine (HWND hwndDlg, wchar_t *lpszCommandLine)
|
|||||||
|
|
||||||
else if (!_wcsicmp (szTmp, L"recovery"))
|
else if (!_wcsicmp (szTmp, L"recovery"))
|
||||||
mountOptions.RecoveryMode = TRUE;
|
mountOptions.RecoveryMode = TRUE;
|
||||||
|
else if (!_wcsicmp (szTmp, L"inplacerecovery") || !_wcsicmp (szTmp, L"nonsysinplacerecovery") || !_wcsicmp (szTmp, L"recoveryro"))
|
||||||
|
{
|
||||||
|
mountOptions.NonSysInplaceRecoveryReadOnly = TRUE;
|
||||||
|
mountOptions.ReadOnly = TRUE;
|
||||||
|
mountOptions.UseBackupHeader = TRUE;
|
||||||
|
mountOptions.ProtectHiddenVolume = FALSE;
|
||||||
|
mountOptions.PartitionInInactiveSysEncScope = FALSE;
|
||||||
|
}
|
||||||
else if ((wcslen(szTmp) > 6) && (wcslen(szTmp) <= 38) && !_wcsnicmp (szTmp, L"label=", 6))
|
else if ((wcslen(szTmp) > 6) && (wcslen(szTmp) <= 38) && !_wcsnicmp (szTmp, L"label=", 6))
|
||||||
{
|
{
|
||||||
// get the label
|
// get the label
|
||||||
|
|||||||
Reference in New Issue
Block a user