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