|
|
1.1 ! root 1: /* ! 2: Copyright (c) 2008 TrueCrypt Foundation. All rights reserved. ! 3: ! 4: Governed by the TrueCrypt License 2.4 the full text of which is contained ! 5: in the file License.txt included in TrueCrypt binary and source code ! 6: distribution packages. ! 7: */ ! 8: ! 9: #include "Crc.h" ! 10: #include "Crypto.h" ! 11: #include "Password.h" ! 12: #include "Volumes.h" ! 13: ! 14: #include "Platform.h" ! 15: #include "Bios.h" ! 16: #include "BootConfig.h" ! 17: #include "BootMain.h" ! 18: #include "BootDefs.h" ! 19: #include "BootCommon.h" ! 20: #include "BootConsoleIo.h" ! 21: #include "BootDebug.h" ! 22: #include "BootDiskIo.h" ! 23: #include "BootEncryptedIo.h" ! 24: #include "IntFilter.h" ! 25: ! 26: ! 27: static void InitScreen () ! 28: { ! 29: ClearScreen(); ! 30: ! 31: Print (" TrueCrypt Boot Loader " VERSION_STRING " Copyright (C) 2008 TrueCrypt Foundation\r\n"); ! 32: PrintRepeatedChar ('\xDC', TC_BIOS_MAX_CHARS_PER_LINE); ! 33: ! 34: PrintEndl (2); ! 35: } ! 36: ! 37: ! 38: static void PrintMainMenu () ! 39: { ! 40: Print (" Keyboard Controls:\r\n"); ! 41: Print (" [Esc] Skip Authentication (Boot Manager)\r\n"); ! 42: Print (" [F8] "); Print ("Repair Options"); ! 43: ! 44: PrintEndl (3); ! 45: } ! 46: ! 47: ! 48: static bool IsMenuKey (byte scanCode) ! 49: { ! 50: return scanCode == TC_MENU_KEY_REPAIR; ! 51: } ! 52: ! 53: ! 54: static bool AskYesNo (const char *message) ! 55: { ! 56: Print (message); ! 57: Print ("? (y/n): "); ! 58: while (true) ! 59: { ! 60: switch (GetKeyboardChar()) ! 61: { ! 62: case 'y': ! 63: case 'Y': ! 64: PrintEndl(); ! 65: return true; ! 66: ! 67: case 'n': ! 68: case 'N': ! 69: PrintEndl(); ! 70: return false; ! 71: ! 72: default: ! 73: Beep(); ! 74: } ! 75: } ! 76: } ! 77: ! 78: ! 79: static int AskSelection (const char *options[], size_t optionCount) ! 80: { ! 81: for (int i = 0; i < optionCount; ++i) ! 82: { ! 83: Print ("["); Print (i + 1); Print ("] "); ! 84: Print (options[i]); ! 85: PrintEndl(); ! 86: } ! 87: Print ("[Esc] Cancel\r\n\r\n"); ! 88: ! 89: Print ("To select, press 1-9: "); ! 90: ! 91: char str; ! 92: ! 93: while (true) ! 94: { ! 95: if (GetString (&str, 1) == 0) ! 96: return 0; ! 97: ! 98: if (str >= '1' && str <= optionCount + '0') ! 99: return str - '0'; ! 100: ! 101: Beep(); ! 102: PrintBackspace(); ! 103: } ! 104: } ! 105: ! 106: ! 107: static byte AskPassword (Password &password) ! 108: { ! 109: size_t pos = 0; ! 110: byte scanCode; ! 111: byte asciiCode; ! 112: ! 113: Print ("Enter password: "); ! 114: ! 115: while (true) ! 116: { ! 117: asciiCode = GetKeyboardChar (&scanCode); ! 118: ! 119: switch (scanCode) ! 120: { ! 121: case TC_BIOS_KEY_ENTER: ! 122: PrintEndl(); ! 123: goto ret; ! 124: ! 125: case TC_BIOS_KEY_BACKSPACE: ! 126: if (pos > 0) ! 127: { ! 128: if (pos < MAX_PASSWORD) ! 129: PrintBackspace(); ! 130: else ! 131: PrintCharAtCusor (' '); ! 132: ! 133: --pos; ! 134: } ! 135: continue; ! 136: ! 137: default: ! 138: if (scanCode == TC_BIOS_KEY_ESC || IsMenuKey (scanCode)) ! 139: { ! 140: burn (password.Text, sizeof (password.Text)); ! 141: PrintEndl(); ! 142: return scanCode; ! 143: } ! 144: } ! 145: ! 146: if (!IsPrintable (asciiCode) || pos == MAX_PASSWORD) ! 147: { ! 148: Beep(); ! 149: continue; ! 150: } ! 151: ! 152: password.Text[pos++] = asciiCode; ! 153: if (pos < MAX_PASSWORD) ! 154: PrintChar ('*'); ! 155: else ! 156: PrintCharAtCusor ('*'); ! 157: } ! 158: ! 159: ret: ! 160: password.Length = pos; ! 161: return TC_BIOS_KEY_ENTER; ! 162: } ! 163: ! 164: ! 165: static void ExecuteBootSector (byte drive, byte *sectorBuffer) ! 166: { ! 167: Print ("Booting...\r\n"); ! 168: CopyMemory (sectorBuffer, 0x0000, 0x7c00, TC_LB_SIZE); ! 169: Jump (0x0000, 0x7c00, drive); ! 170: } ! 171: ! 172: ! 173: static bool OpenVolume (byte drive, Password &password, CRYPTO_INFO **cryptoInfo, uint32 *headSaltCrc32) ! 174: { ! 175: byte header[HEADER_SIZE]; ! 176: uint64 headerSec; ! 177: headerSec.HighPart = 0; ! 178: headerSec.LowPart = TC_BOOT_VOLUME_HEADER_SECTOR; ! 179: ! 180: if (ReadSectors (header, drive, headerSec, 1) != BiosResultSuccess) ! 181: return false; ! 182: ! 183: if (VolumeReadHeader (TRUE, (char *) header, &password, cryptoInfo, nullptr) == 0) ! 184: { ! 185: if (headSaltCrc32) ! 186: *headSaltCrc32 = GetCrc32 (header, PKCS5_SALT_SIZE); ! 187: return true; ! 188: } ! 189: ! 190: return false; ! 191: } ! 192: ! 193: ! 194: static bool MountVolume (byte drive, byte &exitKey) ! 195: { ! 196: BootArguments *bootArguments = (BootArguments *) TC_BOOT_LOADER_ARGS_OFFSET; ! 197: ! 198: // Open volume header ! 199: while (true) ! 200: { ! 201: exitKey = AskPassword (bootArguments->BootPassword); ! 202: ! 203: if (exitKey != TC_BIOS_KEY_ENTER) ! 204: return false; ! 205: ! 206: if (OpenVolume (BootDrive, bootArguments->BootPassword, &BootCryptoInfo, &bootArguments->HeaderSaltCrc32)) ! 207: break; ! 208: ! 209: Print ("Incorrect password or not a TrueCrypt volume.\r\n\r\n"); ! 210: } ! 211: ! 212: // Check memory ! 213: uint16 codeSeg; ! 214: __asm mov codeSeg, cs ! 215: if (codeSeg == TC_BOOT_LOADER_LOWMEM_SEGMENT) ! 216: { ! 217: PrintError ("Insufficient memory for encryption"); ! 218: EncryptedVirtualPartition.Drive = TC_FIRST_BIOS_DRIVE - 1; ! 219: GetKeyboardChar (); ! 220: return false; ! 221: } ! 222: ! 223: // Setup boot arguments ! 224: bootArguments->CryptoInfoOffset = (uint16) BootCryptoInfo; ! 225: bootArguments->CryptoInfoLength = sizeof (*BootCryptoInfo); ! 226: bootArguments->BootLoaderVersion = VERSION_NUM; ! 227: TC_SET_BOOT_ARGUMENTS_SIGNATURE (bootArguments->Signature); ! 228: ! 229: if (BootCryptoInfo->EncryptedAreaLength.HighPart != 0 || BootCryptoInfo->EncryptedAreaLength.LowPart != 0) ! 230: { ! 231: // Setup virtual encrypted partition ! 232: EncryptedVirtualPartition.Drive = BootDrive; ! 233: ! 234: EncryptedVirtualPartition.StartSector.HighPart = BootCryptoInfo->EncryptedAreaStart.HighPart; ! 235: EncryptedVirtualPartition.StartSector.LowPart = BootCryptoInfo->EncryptedAreaStart.LowPart; ! 236: EncryptedVirtualPartition.StartSector = EncryptedVirtualPartition.StartSector >> TC_LB_SIZE_BIT_SHIFT_DIVISOR; ! 237: ! 238: EncryptedVirtualPartition.EndSector.HighPart = BootCryptoInfo->EncryptedAreaLength.HighPart; ! 239: EncryptedVirtualPartition.EndSector.LowPart = BootCryptoInfo->EncryptedAreaLength.LowPart; ! 240: EncryptedVirtualPartition.EndSector = (EncryptedVirtualPartition.EndSector - 1) >> TC_LB_SIZE_BIT_SHIFT_DIVISOR; ! 241: EncryptedVirtualPartition.EndSector = EncryptedVirtualPartition.EndSector + EncryptedVirtualPartition.StartSector; ! 242: } ! 243: else ! 244: { ! 245: // Drive not encrypted ! 246: EncryptedVirtualPartition.Drive = TC_FIRST_BIOS_DRIVE - 1; ! 247: } ! 248: ! 249: return true; ! 250: } ! 251: ! 252: ! 253: static byte BootEncryptedDrive () ! 254: { ! 255: Partition partition; ! 256: size_t partCount; ! 257: ! 258: // Find active partition ! 259: if (GetActivePartition (BootDrive, partition, partCount, false) != BiosResultSuccess || partCount < 1) ! 260: { ! 261: PrintError ("No bootable partition found"); ! 262: goto err; ! 263: } ! 264: ! 265: byte exitKey; ! 266: if (!MountVolume (BootDrive, exitKey)) ! 267: return exitKey; ! 268: ! 269: InstallInterruptFilters(); ! 270: ! 271: // Execute boot sector of the active partition ! 272: byte bootSector[TC_LB_SIZE]; ! 273: if (ReadSectors (bootSector, partition.Drive, partition.StartSector, 1) == BiosResultSuccess) ! 274: { ! 275: ExecuteBootSector (partition.Drive, bootSector); ! 276: } ! 277: ! 278: err: ! 279: byte scanCode; ! 280: GetKeyboardChar (&scanCode); ! 281: return scanCode; ! 282: } ! 283: ! 284: ! 285: static void BootMenu () ! 286: { ! 287: BiosResult result; ! 288: Partition partitions[16]; ! 289: Partition bootablePartitions[9]; ! 290: size_t partitionCount; ! 291: size_t bootablePartitionCount = 0; ! 292: ! 293: for (byte drive = TC_FIRST_BIOS_DRIVE; drive <= TC_LAST_BIOS_DRIVE; ++drive) ! 294: { ! 295: if (GetDrivePartitions (drive, partitions, array_capacity (partitions), partitionCount, false, true) == BiosResultSuccess) ! 296: { ! 297: for (size_t i = 0; i < partitionCount; ++i) ! 298: { ! 299: const Partition &partition = partitions[i]; ! 300: ! 301: byte bootSector[TC_LB_SIZE]; ! 302: result = ReadSectors (bootSector, drive, partition.StartSector, 1); ! 303: ! 304: if (result == BiosResultSuccess && *(uint16 *) (bootSector + TC_LB_SIZE - 2) == 0xaa55) ! 305: { ! 306: // Windows writes boot loader on all NTFS/FAT filesytems it creates and, therefore, ! 307: // NTFS/FAT partitions must have the boot indicator set to be considered bootable. ! 308: if (!partition.Active ! 309: && (*(uint32 *) (bootSector + 3) == 0x5346544e // 'NTFS' ! 310: || *(uint16 *) (bootSector + 54) == 0x4146 && bootSector[56] == 'T' // 'FAT' ! 311: || *(uint16 *) (bootSector + 82) == 0x4146 && bootSector[84] == 'T')) ! 312: { ! 313: continue; ! 314: } ! 315: ! 316: // Bootable sector found ! 317: if (bootablePartitionCount < array_capacity (bootablePartitions)) ! 318: bootablePartitions[bootablePartitionCount++] = partition; ! 319: } ! 320: } ! 321: } ! 322: } ! 323: ! 324: if (bootablePartitionCount < 1) ! 325: { ! 326: PrintError ("No bootable partition found"); ! 327: GetKeyboardChar(); ! 328: return; ! 329: } ! 330: ! 331: char partChar; ! 332: while (true) ! 333: { ! 334: InitScreen(); ! 335: Print ("Bootable Partitions:\r\n"); ! 336: PrintRepeatedChar ('\xC4', 20); ! 337: Print ("\r\n"); ! 338: ! 339: for (size_t i = 0; i < bootablePartitionCount; ++i) ! 340: { ! 341: const Partition &partition = bootablePartitions[i]; ! 342: Print ("["); Print (i + 1); Print ("] "); ! 343: Print ("Drive: "); Print (partition.Drive - TC_FIRST_BIOS_DRIVE); ! 344: Print (", Partition: "); Print (partition.Number + 1); ! 345: Print (", Size: "); Print (partition.SectorCount >> 11); Print (" MB\r\n"); ! 346: } ! 347: ! 348: if (bootablePartitionCount == 1) ! 349: { ! 350: // There's only one bootable partition so we'll boot it directly instead of showing boot manager ! 351: partChar = '1'; ! 352: } ! 353: else ! 354: { ! 355: Print ("[Esc] Cancel\r\n\r\n"); ! 356: Print ("Press 1-9 to select partition: "); ! 357: ! 358: if (GetString (&partChar, 1) == 0) ! 359: return; ! 360: ! 361: PrintEndl(); ! 362: ! 363: if (partChar < '1' || partChar > '0' + bootablePartitionCount) ! 364: { ! 365: Beep(); ! 366: continue; ! 367: } ! 368: } ! 369: ! 370: const Partition &partition = bootablePartitions[partChar - '0' - 1]; ! 371: ! 372: byte bootSector[TC_LB_SIZE]; ! 373: if (ReadSectors (bootSector, partition.Drive, partition.StartSector, 1) == BiosResultSuccess) ! 374: { ! 375: ExecuteBootSector (partition.Drive, bootSector); ! 376: } ! 377: } ! 378: } ! 379: ! 380: ! 381: static void DecryptDrive (byte drive) ! 382: { ! 383: byte exitKey; ! 384: if (!MountVolume (drive, exitKey)) ! 385: return; ! 386: ! 387: const int sectorsPerIoBlock = 0x7f; // Maximum safe value supported by BIOS ! 388: ! 389: bool headerUpdateRequired = false; ! 390: uint64 sectorsRemaining = EncryptedVirtualPartition.EndSector + 1 - EncryptedVirtualPartition.StartSector; ! 391: uint64 sector = EncryptedVirtualPartition.EndSector + 1; ! 392: ! 393: byte sectorBuf[TC_LB_SIZE]; ! 394: int fragmentSectorCount = sectorsPerIoBlock; ! 395: int statCount; ! 396: ! 397: if (EncryptedVirtualPartition.Drive == TC_FIRST_BIOS_DRIVE - 1) ! 398: { ! 399: // Drive not encrypted ! 400: sectorsRemaining.HighPart = 0; ! 401: sectorsRemaining.LowPart = 0; ! 402: headerUpdateRequired = true; ! 403: } ! 404: else ! 405: { ! 406: Print ("\r\nDo NOT turn off power. Press ESC to abort.\r\n"); ! 407: } ! 408: ! 409: while (sectorsRemaining.HighPart != 0 || sectorsRemaining.LowPart != 0) ! 410: { ! 411: if (IsKeyboardCharAvailable ()) ! 412: { ! 413: byte keyScanCode; ! 414: GetKeyboardChar (&keyScanCode); ! 415: if (keyScanCode == TC_BIOS_KEY_ESC) ! 416: break; ! 417: } ! 418: ! 419: if (sectorsRemaining.HighPart == 0 && sectorsRemaining.LowPart < fragmentSectorCount) ! 420: fragmentSectorCount = sectorsRemaining.LowPart; ! 421: ! 422: sector = sector - fragmentSectorCount; ! 423: ! 424: if (!(statCount++ & 0xf)) ! 425: { ! 426: Print ("\rRemaining: "); ! 427: Print (sectorsRemaining >> 11); Print (" MB "); ! 428: } ! 429: ! 430: if (ReadWriteSectors (false, TC_BOOT_LOADER_BUFFER_SEGMENT, 0, drive, sector, fragmentSectorCount, false) != BiosResultSuccess) ! 431: break; ! 432: ! 433: for (int i = 0; i < fragmentSectorCount; ++i) ! 434: { ! 435: CopyMemory (TC_BOOT_LOADER_BUFFER_SEGMENT, i * sizeof (sectorBuf), sectorBuf, sizeof (sectorBuf)); ! 436: ! 437: uint64 s = sector + i; ! 438: DecryptDataUnits (sectorBuf, &s, 1, BootCryptoInfo); ! 439: ! 440: CopyMemory (sectorBuf, TC_BOOT_LOADER_BUFFER_SEGMENT, i * sizeof (sectorBuf), sizeof (sectorBuf)); ! 441: } ! 442: ! 443: if (ReadWriteSectors (true, TC_BOOT_LOADER_BUFFER_SEGMENT, 0, drive, sector, fragmentSectorCount, false) != BiosResultSuccess) ! 444: break; ! 445: ! 446: sectorsRemaining = sectorsRemaining - fragmentSectorCount; ! 447: headerUpdateRequired = true; ! 448: } ! 449: ! 450: crypto_close (BootCryptoInfo); ! 451: BootArguments *bootArguments = (BootArguments *) TC_BOOT_LOADER_ARGS_OFFSET; ! 452: ! 453: if (headerUpdateRequired) ! 454: { ! 455: byte header[HEADER_SIZE]; ! 456: uint64 headerSector; ! 457: headerSector.HighPart = 0; ! 458: headerSector.LowPart = TC_BOOT_VOLUME_HEADER_SECTOR; ! 459: ! 460: if (sectorsRemaining.HighPart == 0 && sectorsRemaining.LowPart == 0) ! 461: { ! 462: memset (header, 0, sizeof (header)); ! 463: Print ("\rDrive decrypted.\r\n"); ! 464: } ! 465: else ! 466: { ! 467: // Update encrypted area size in volume header ! 468: ! 469: CRYPTO_INFO *headerCryptoInfo = crypto_open(); ! 470: ReadSectors (header, drive, headerSector, 1); ! 471: ! 472: if (VolumeReadHeader (TRUE, (char *) header, &bootArguments->BootPassword, NULL, headerCryptoInfo) == 0) ! 473: { ! 474: DecryptBuffer (header + HEADER_ENCRYPTED_DATA_OFFSET, HEADER_ENCRYPTED_DATA_SIZE, headerCryptoInfo); ! 475: ! 476: byte *sizeField = header + TC_HEADER_OFFSET_ENCRYPTED_AREA_LENGTH; ! 477: uint64 encryptedAreaLength = sectorsRemaining << TC_LB_SIZE_BIT_SHIFT_DIVISOR; ! 478: ! 479: for (int i = 7; i >= 0; --i) ! 480: { ! 481: sizeField[i] = (byte) encryptedAreaLength.LowPart; ! 482: encryptedAreaLength = encryptedAreaLength >> 8; ! 483: } ! 484: ! 485: EncryptBuffer (header + HEADER_ENCRYPTED_DATA_OFFSET, HEADER_ENCRYPTED_DATA_SIZE, headerCryptoInfo); ! 486: } ! 487: ! 488: crypto_close (headerCryptoInfo); ! 489: Print ("\r\nAborted.\r\n"); ! 490: } ! 491: ! 492: WriteSectors (header, drive, headerSector, 1); ! 493: } ! 494: ! 495: err: ! 496: memset (bootArguments, 0, sizeof (*bootArguments)); ! 497: GetKeyboardChar(); ! 498: } ! 499: ! 500: ! 501: static void RepairMenu () ! 502: { ! 503: DriveGeometry bootLoaderDriveGeometry; ! 504: if (GetDriveGeometry (BootLoaderDrive, bootLoaderDriveGeometry) != BiosResultSuccess) ! 505: { ! 506: GetKeyboardChar(); ! 507: return; ! 508: } ! 509: ! 510: while (true) ! 511: { ! 512: InitScreen(); ! 513: Print ("Available "); Print ("Repair Options"); Print (":\r\n"); ! 514: PrintRepeatedChar ('\xC4', 25); ! 515: Print ("\r\n"); ! 516: ! 517: enum ! 518: { ! 519: RestoreNone = 0, ! 520: DecryptVolume, ! 521: RestoreTrueCryptLoader, ! 522: RestoreVolumeHeader, ! 523: RestoreOriginalSystemLoader ! 524: }; ! 525: ! 526: static const char *options[] = { "Permanently decrypt system partition/drive", "Restore TrueCrypt Boot Loader", "Restore key data (volume header)", "Restore original system loader" }; ! 527: ! 528: int optionCount = 1; ! 529: if (BootSectorFlags & TC_BOOT_CFG_FLAG_RESCUE_DISK_ORIG_SYS_LOADER) ! 530: optionCount = array_capacity (options); ! 531: else if (BootSectorFlags & TC_BOOT_CFG_FLAG_RESCUE_DISK) ! 532: optionCount = array_capacity (options) - 1; ! 533: ! 534: int selection = AskSelection (options, optionCount); ! 535: PrintEndl(); ! 536: ! 537: if (selection == RestoreNone) ! 538: return; ! 539: ! 540: if (selection == DecryptVolume) ! 541: { ! 542: DecryptDrive (BootDrive); ! 543: continue; ! 544: } ! 545: ! 546: bool writeConfirmed = false; ! 547: BiosResult result; ! 548: byte sectorBuf[TC_LB_SIZE]; ! 549: ! 550: uint64 sector; ! 551: sector.HighPart = 0; ! 552: ChsAddress chs; ! 553: ! 554: for (int i = (selection == RestoreVolumeHeader ? TC_BOOT_VOLUME_HEADER_SECTOR : TC_MBR_SECTOR); ! 555: i < TC_BOOT_LOADER_AREA_SECTOR_COUNT; ++i) ! 556: { ! 557: sector.LowPart = (selection == RestoreOriginalSystemLoader ? TC_ORIG_BOOT_LOADER_BACKUP_SECTOR : 0) + i; ! 558: ! 559: // The backup medium may be a floppy-emulated bootable CD. The emulation may fail if LBA addressing is used. ! 560: // Therefore, only CHS addressing can be used. ! 561: LbaToChs (bootLoaderDriveGeometry, sector, chs); ! 562: ! 563: result = ReadSectors (sectorBuf, BootLoaderDrive, chs, 1); ! 564: if (result != BiosResultSuccess) ! 565: goto err; ! 566: ! 567: sector.LowPart = i; ! 568: ! 569: // MBR ! 570: if (i == TC_MBR_SECTOR) ! 571: { ! 572: // Preserve partition table ! 573: byte bootSecBuf[TC_LB_SIZE]; ! 574: ! 575: result = ReadSectors (bootSecBuf, TC_FIRST_BIOS_DRIVE, sector, 1); ! 576: if (result != BiosResultSuccess) ! 577: goto err; ! 578: ! 579: memcpy (sectorBuf + TC_MAX_MBR_BOOT_CODE_SIZE, ! 580: bootSecBuf + TC_MAX_MBR_BOOT_CODE_SIZE, ! 581: sizeof (bootSecBuf) - TC_MAX_MBR_BOOT_CODE_SIZE); ! 582: ! 583: // Clear rescue disk flags ! 584: if (selection == RestoreTrueCryptLoader) ! 585: sectorBuf[TC_BOOT_SECTOR_CONFIG_OFFSET] &= ~(TC_BOOT_CFG_FLAG_RESCUE_DISK | TC_BOOT_CFG_FLAG_RESCUE_DISK_ORIG_SYS_LOADER); ! 586: } ! 587: ! 588: // Volume header ! 589: if (i == TC_BOOT_VOLUME_HEADER_SECTOR) ! 590: { ! 591: if (selection == RestoreTrueCryptLoader) ! 592: continue; ! 593: ! 594: if (selection == RestoreVolumeHeader) ! 595: { ! 596: while (true) ! 597: { ! 598: Password password; ! 599: byte exitKey = AskPassword (password); ! 600: ! 601: if (exitKey != TC_BIOS_KEY_ENTER) ! 602: goto abort; ! 603: ! 604: CRYPTO_INFO *cryptoInfo; ! 605: ! 606: // Restore volume header only if the current one cannot be used ! 607: if (OpenVolume (TC_FIRST_BIOS_DRIVE, password, &cryptoInfo)) ! 608: { ! 609: Print ("Original header preserved.\r\n"); ! 610: crypto_close (cryptoInfo); ! 611: goto err; ! 612: } ! 613: ! 614: if (VolumeReadHeader (TRUE, (char *) sectorBuf, &password, &cryptoInfo, nullptr) == 0) ! 615: { ! 616: crypto_close (cryptoInfo); ! 617: break; ! 618: } ! 619: ! 620: Print ("Incorrect password or not a TrueCrypt volume.\r\n\r\n"); ! 621: } ! 622: } ! 623: } ! 624: ! 625: if (!writeConfirmed && !AskYesNo ("Modify Drive 0")) ! 626: goto abort; ! 627: writeConfirmed = true; ! 628: ! 629: if (WriteSectors (sectorBuf, TC_FIRST_BIOS_DRIVE, sector, 1) != BiosResultSuccess) ! 630: goto err; ! 631: } ! 632: done: ! 633: switch (selection) ! 634: { ! 635: case RestoreTrueCryptLoader: ! 636: Print ("TrueCrypt Boot Loader"); ! 637: break; ! 638: ! 639: case RestoreVolumeHeader: ! 640: Print ("Header"); ! 641: break; ! 642: ! 643: case RestoreOriginalSystemLoader: ! 644: Print ("System loader"); ! 645: break; ! 646: } ! 647: Print (" restored.\r\n"); ! 648: ! 649: err: GetKeyboardChar(); ! 650: abort: ; ! 651: } ! 652: } ! 653: ! 654: ! 655: #ifndef DEBUG ! 656: extern "C" void _acrtused () { } // Required by linker ! 657: #endif ! 658: ! 659: ! 660: void main () ! 661: { ! 662: __asm mov BootLoaderDrive, dl ! 663: __asm mov BootSectorFlags, dh ! 664: ! 665: #ifdef TC_TRACING_ENABLED ! 666: InitDebugPort(); ! 667: #endif ! 668: ! 669: BootDrive = BootLoaderDrive; ! 670: if (BootDrive < TC_FIRST_BIOS_DRIVE) ! 671: BootDrive = TC_FIRST_BIOS_DRIVE; ! 672: ! 673: if (GetDriveGeometry (BootDrive, BootDriveGeometry, true) != BiosResultSuccess) ! 674: { ! 675: BootDrive = TC_FIRST_BIOS_DRIVE; ! 676: if (GetDriveGeometry (BootDrive, BootDriveGeometry) == BiosResultSuccess) ! 677: BootDriveGeometryValid = TRUE; ! 678: } ! 679: else ! 680: BootDriveGeometryValid = TRUE; ! 681: ! 682: while (true) ! 683: { ! 684: InitScreen(); ! 685: PrintMainMenu(); ! 686: ! 687: byte exitKey = BootEncryptedDrive(); ! 688: ! 689: if (exitKey == TC_MENU_KEY_REPAIR) ! 690: { ! 691: RepairMenu(); ! 692: continue; ! 693: } ! 694: ! 695: BootMenu(); ! 696: } ! 697: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.