|
|
1.1 root 1: /*
2: Copyright (c) 2008 TrueCrypt Foundation. All rights reserved.
3:
1.1.1.5 ! root 4: Governed by the TrueCrypt License 2.5 the full text of which is contained
1.1 root 5: in the file License.txt included in TrueCrypt binary and source code
6: distribution packages.
7: */
8:
9: #include "Tcdefs.h"
10: #include "Platform/Finally.h"
11: #include "Platform/ForEach.h"
12: #include <Setupapi.h>
13: #include <devguid.h>
14: #include <io.h>
15: #include <shlobj.h>
16: #include <atlbase.h>
17: #include "BootEncryption.h"
18: #include "Boot/Windows/BootCommon.h"
19: #include "Common/Resource.h"
20: #include "Crc.h"
21: #include "Crypto.h"
22: #include "Dlgcode.h"
23: #include "Endian.h"
1.1.1.5 ! root 24: #include "Language.h"
1.1 root 25: #include "Random.h"
26: #include "Registry.h"
27: #include "Volumes.h"
28:
29: #ifdef VOLFORMAT
30: #include "Format/FormatCom.h"
31: #elif defined (TCMOUNT)
32: #include "Mount/MainCom.h"
33: #endif
34:
35: namespace TrueCrypt
36: {
37: #if !defined (SETUP)
38:
39: class Elevator
40: {
41: public:
42: static void CallDriver (DWORD ioctl, void *input, DWORD inputSize, void *output, DWORD outputSize)
43: {
44: Elevate();
45:
46: CComBSTR inputBstr;
47: if (input && inputBstr.AppendBytes ((const char *) input, inputSize) != S_OK)
48: throw ParameterIncorrect (SRC_POS);
49:
50: CComBSTR outputBstr;
51: if (output && outputBstr.AppendBytes ((const char *) output, outputSize) != S_OK)
52: throw ParameterIncorrect (SRC_POS);
53:
54: DWORD result = ElevatedComInstance->CallDriver (ioctl, inputBstr, &outputBstr);
1.1.1.5 ! root 55:
! 56: if (output)
! 57: memcpy (output, *(void **) &outputBstr, outputSize);
! 58:
1.1 root 59: if (result != ERROR_SUCCESS)
60: {
61: SetLastError (result);
62: throw SystemException();
63: }
64: }
65:
66: static void ReadWriteFile (BOOL write, BOOL device, const string &filePath, byte *buffer, uint64 offset, uint32 size, DWORD *sizeDone)
67: {
68: Elevate();
69:
70: CComBSTR bufferBstr;
71: if (bufferBstr.AppendBytes ((const char *) buffer, size) != S_OK)
72: throw ParameterIncorrect (SRC_POS);
73: DWORD result = ElevatedComInstance->ReadWriteFile (write, device, CComBSTR (filePath.c_str()), &bufferBstr, offset, size, sizeDone);
74:
75: if (result != ERROR_SUCCESS)
76: {
77: SetLastError (result);
78: throw SystemException();
79: }
80:
81: if (!write)
82: memcpy (buffer, (BYTE *) bufferBstr.m_str, size);
83: }
84:
1.1.1.5 ! root 85: static BOOL IsPagingFileActive ()
! 86: {
! 87: Elevate();
! 88:
! 89: return ElevatedComInstance->IsPagingFileActive ();
! 90: }
! 91:
! 92: static void WriteLocalMachineRegistryDwordValue (char *keyPath, char *valueName, DWORD value)
1.1 root 93: {
94: Elevate();
95:
1.1.1.5 ! root 96: DWORD result = ElevatedComInstance->WriteLocalMachineRegistryDwordValue (CComBSTR (keyPath), CComBSTR (valueName), value);
! 97:
! 98: if (result != ERROR_SUCCESS)
! 99: {
! 100: SetLastError (result);
! 101: throw SystemException();
! 102: }
! 103: }
! 104:
! 105: static void RegisterFilterDriver (bool registerDriver, bool volumeClass)
! 106: {
! 107: Elevate();
! 108:
! 109: DWORD result = ElevatedComInstance->RegisterFilterDriver (registerDriver ? TRUE : FALSE, volumeClass ? TRUE : FALSE);
1.1 root 110: if (result != ERROR_SUCCESS)
111: {
112: SetLastError (result);
113: throw SystemException();
114: }
115: }
116:
117: static void Release ()
118: {
119: if (ElevatedComInstance)
120: {
121: ElevatedComInstance->Release();
122: ElevatedComInstance = nullptr;
123: CoUninitialize ();
124: }
125: }
126:
127: static void SetDriverServiceStartType (DWORD startType)
128: {
129: Elevate();
130:
131: DWORD result = ElevatedComInstance->SetDriverServiceStartType (startType);
132: if (result != ERROR_SUCCESS)
133: {
134: SetLastError (result);
135: throw SystemException();
136: }
137: }
138:
139: protected:
140: static void Elevate ()
141: {
142: if (IsAdmin())
143: {
144: SetLastError (ERROR_ACCESS_DENIED);
145: throw SystemException();
146: }
147:
1.1.1.5 ! root 148: if (!ElevatedComInstance || ElevatedComInstanceThreadId != GetCurrentThreadId())
1.1 root 149: {
150: CoInitialize (NULL);
151: ElevatedComInstance = GetElevatedInstance (GetActiveWindow() ? GetActiveWindow() : MainDlg);
1.1.1.5 ! root 152: ElevatedComInstanceThreadId = GetCurrentThreadId();
1.1 root 153: }
154: }
155:
156: #if defined (TCMOUNT)
157: static ITrueCryptMainCom *ElevatedComInstance;
158: #elif defined (VOLFORMAT)
159: static ITrueCryptFormatCom *ElevatedComInstance;
160: #endif
1.1.1.5 ! root 161: static DWORD ElevatedComInstanceThreadId;
1.1 root 162: };
163:
164: #if defined (TCMOUNT)
165: ITrueCryptMainCom *Elevator::ElevatedComInstance;
166: #elif defined (VOLFORMAT)
167: ITrueCryptFormatCom *Elevator::ElevatedComInstance;
168: #endif
1.1.1.5 ! root 169: DWORD Elevator::ElevatedComInstanceThreadId;
1.1 root 170:
171: #else // SETUP
172:
173: class Elevator
174: {
175: public:
176: static void CallDriver (DWORD ioctl, void *input, DWORD inputSize, void *output, DWORD outputSize) { throw ParameterIncorrect (SRC_POS); }
177: static void ReadWriteFile (BOOL write, BOOL device, const string &filePath, byte *buffer, uint64 offset, uint32 size, DWORD *sizeDone) { throw ParameterIncorrect (SRC_POS); }
1.1.1.5 ! root 178: static void RegisterFilterDriver (bool registerDriver, bool volumeClass) { throw ParameterIncorrect (SRC_POS); }
1.1 root 179: static void Release () { }
180: static void SetDriverServiceStartType (DWORD startType) { throw ParameterIncorrect (SRC_POS); }
181: };
182:
183: #endif // SETUP
184:
185:
186: File::File (string path, bool readOnly, bool create) : Elevated (false), FileOpen (false)
187: {
188: Handle = CreateFile (path.c_str(),
189: readOnly ? FILE_READ_DATA : FILE_READ_DATA | FILE_WRITE_DATA,
190: FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, create ? CREATE_ALWAYS : OPEN_EXISTING,
191: FILE_FLAG_RANDOM_ACCESS | FILE_FLAG_WRITE_THROUGH, NULL);
192:
193: try
194: {
195: throw_sys_if (Handle == INVALID_HANDLE_VALUE);
196: }
197: catch (SystemException &)
198: {
199: if (GetLastError() == ERROR_ACCESS_DENIED && IsUacSupported())
200: Elevated = true;
201: else
202: throw;
203: }
204:
205: FileOpen = true;
206: FilePointerPosition = 0;
207: IsDevice = false;
208: Path = path;
209: }
210:
211: void File::Close ()
212: {
213: if (FileOpen)
214: {
215: if (!Elevated)
216: CloseHandle (Handle);
217:
218: FileOpen = false;
219: }
220: }
221:
222: DWORD File::Read (byte *buffer, DWORD size)
223: {
224: DWORD bytesRead;
225:
226: if (Elevated)
227: {
228: DWORD bytesRead;
229:
230: Elevator::ReadWriteFile (false, IsDevice, Path, buffer, FilePointerPosition, size, &bytesRead);
231: FilePointerPosition += bytesRead;
232: return bytesRead;
233: }
234:
235: throw_sys_if (!ReadFile (Handle, buffer, size, &bytesRead, NULL));
236: return bytesRead;
237: }
238:
239: void File::SeekAt (int64 position)
240: {
241: if (Elevated)
242: {
243: FilePointerPosition = position;
244: }
245: else
246: {
247: LARGE_INTEGER pos;
248: pos.QuadPart = position;
249: throw_sys_if (!SetFilePointerEx (Handle, pos, NULL, FILE_BEGIN));
250: }
251: }
252:
253: void File::Write (byte *buffer, DWORD size)
254: {
255: DWORD bytesWritten;
256:
257: if (Elevated)
258: {
259: Elevator::ReadWriteFile (true, IsDevice, Path, buffer, FilePointerPosition, size, &bytesWritten);
260: FilePointerPosition += bytesWritten;
261: throw_sys_if (bytesWritten != size);
262: }
263: else
264: {
265: throw_sys_if (!WriteFile (Handle, buffer, size, &bytesWritten, NULL) || bytesWritten != size);
266: }
267: }
268:
269: void Show (HWND parent, const string &str)
270: {
271: MessageBox (parent, str.c_str(), NULL, 0);
272: }
273:
274:
275: Device::Device (string path, bool readOnly)
276: {
277: FileOpen = false;
278: Elevated = false;
279:
280: Handle = CreateFile ((string ("\\\\.\\") + path).c_str(),
281: readOnly ? FILE_READ_DATA : FILE_READ_DATA | FILE_WRITE_DATA,
282: FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
283: FILE_FLAG_RANDOM_ACCESS | FILE_FLAG_WRITE_THROUGH, NULL);
284:
285: try
286: {
287: throw_sys_if (Handle == INVALID_HANDLE_VALUE);
288: }
289: catch (SystemException &)
290: {
291: if (GetLastError() == ERROR_ACCESS_DENIED && IsUacSupported())
292: Elevated = true;
293: else
294: throw;
295: }
296:
297: FileOpen = true;
298: FilePointerPosition = 0;
299: IsDevice = true;
300: Path = path;
301: }
302:
303:
304: BootEncryption::~BootEncryption ()
305: {
306: if (RescueIsoImage)
307: delete RescueIsoImage;
308:
309: Elevator::Release();
310: }
311:
312:
313: void BootEncryption::CallDriver (DWORD ioctl, void *input, DWORD inputSize, void *output, DWORD outputSize)
314: {
315: try
316: {
317: DWORD bytesReturned;
318: throw_sys_if (!DeviceIoControl (hDriver, ioctl, input, inputSize, output, outputSize, &bytesReturned, NULL));
319: }
320: catch (SystemException &)
321: {
322: if (GetLastError() == ERROR_ACCESS_DENIED && IsUacSupported())
323: Elevator::CallDriver (ioctl, input, inputSize, output, outputSize);
324: else
325: throw;
326: }
327: }
328:
329:
1.1.1.5 ! root 330: // Finds the first partition physically located behind the active one and returns its properties
! 331: Partition BootEncryption::GetPartitionForHiddenOS ()
! 332: {
! 333: Partition candidatePartition;
! 334:
! 335: memset (&candidatePartition, 0, sizeof(candidatePartition));
! 336:
! 337: // The user may have modified/added/deleted partitions since the time the partition table was last scanned
! 338: InvalidateCachedSysDriveProperties();
! 339:
! 340: SystemDriveConfiguration config = GetSystemDriveConfiguration ();
! 341: bool activePartitionFound = false;
! 342: bool candidateForHiddenOSFound = false;
! 343:
! 344: if (config.SystemPartition.IsGPT)
! 345: throw ParameterIncorrect (SRC_POS); // It is assumed that CheckRequirements() had been called
! 346:
! 347: // Find the first active partition on the system drive
! 348: foreach (const Partition &partition, config.Partitions)
! 349: {
! 350: if (partition.Info.BootIndicator)
! 351: {
! 352: if (partition.Info.PartitionNumber != config.SystemPartition.Number)
! 353: {
! 354: throw ErrorException (wstring (GetString ("SYSTEM_PARTITION_NOT_ACTIVE"))
! 355: + GetRemarksOnHiddenOS());
! 356: }
! 357:
! 358: activePartitionFound = true;
! 359: break;
! 360: }
! 361: }
! 362:
! 363: /* WARNING: Note that the partition number at the end of a device path (\Device\HarddiskY\PartitionX) must
! 364: NOT be used to find the first partition physically located behind the active one. The reason is that the
! 365: user may have deleted and created partitions during this session and e.g. the second partition could have
! 366: a higer number than the third one. */
! 367:
! 368:
! 369: // Find the first partition physically located behind the active partition
! 370: if (activePartitionFound)
! 371: {
! 372: int64 minOffsetFound = config.DrivePartition.Info.PartitionLength.QuadPart;
! 373:
! 374: foreach (const Partition &partition, config.Partitions)
! 375: {
! 376: if (partition.Info.StartingOffset.QuadPart > config.SystemPartition.Info.StartingOffset.QuadPart
! 377: && partition.Info.StartingOffset.QuadPart < minOffsetFound)
! 378: {
! 379: minOffsetFound = partition.Info.StartingOffset.QuadPart;
! 380:
! 381: candidatePartition = partition;
! 382:
! 383: candidateForHiddenOSFound = true;
! 384: }
! 385: }
! 386:
! 387: if (!candidateForHiddenOSFound)
! 388: {
! 389: throw ErrorException (wstring (GetString ("NO_PARTITION_FOLLOWS_BOOT_PARTITION"))
! 390: + GetRemarksOnHiddenOS());
! 391: }
! 392:
! 393: if (config.SystemPartition.Info.PartitionLength.QuadPart > TC_MAX_FAT_FS_SIZE)
! 394: {
! 395: if ((double) candidatePartition.Info.PartitionLength.QuadPart / config.SystemPartition.Info.PartitionLength.QuadPart < MIN_HIDDENOS_DECOY_PARTITION_SIZE_RATIO_NTFS)
! 396: {
! 397: throw ErrorException (wstring (GetString ("PARTITION_TOO_SMALL_FOR_HIDDEN_OS_NTFS"))
! 398: + GetRemarksOnHiddenOS());
! 399: }
! 400: }
! 401: else if ((double) candidatePartition.Info.PartitionLength.QuadPart / config.SystemPartition.Info.PartitionLength.QuadPart < MIN_HIDDENOS_DECOY_PARTITION_SIZE_RATIO_FAT)
! 402: {
! 403: throw ErrorException (wstring (GetString ("PARTITION_TOO_SMALL_FOR_HIDDEN_OS"))
! 404: + GetRemarksOnHiddenOS());
! 405: }
! 406: }
! 407: else
! 408: {
! 409: // No active partition on the system drive
! 410: throw ErrorException ("WINDOWS_NOT_ON_BOOT_DRIVE_ERROR");
! 411: }
! 412:
! 413: return candidatePartition;
! 414: }
! 415:
! 416:
1.1 root 417: DWORD BootEncryption::GetDriverServiceStartType ()
418: {
419: DWORD startType;
420: throw_sys_if (!ReadLocalMachineRegistryDword ("SYSTEM\\CurrentControlSet\\Services\\truecrypt", "Start", &startType));
421: return startType;
422: }
423:
424:
1.1.1.5 ! root 425: wstring BootEncryption::GetRemarksOnHiddenOS ()
! 426: {
! 427: return (wstring (L"\n\n")
! 428: + GetString ("TWO_SYSTEMS_IN_ONE_PARTITION_REMARK")
! 429: + L"\n\n"
! 430: + GetString ("FOR_MORE_INFO_ON_PARTITIONS"));
! 431: }
! 432:
! 433:
1.1 root 434: void BootEncryption::SetDriverServiceStartType (DWORD startType)
435: {
436: if (!IsAdmin() && IsUacSupported())
437: {
438: Elevator::SetDriverServiceStartType (startType);
439: return;
440: }
441:
442: BOOL startOnBoot = (startType == SERVICE_BOOT_START);
443:
444: SC_HANDLE serviceManager = OpenSCManager (NULL, NULL, SC_MANAGER_ALL_ACCESS);
445: throw_sys_if (!serviceManager);
446:
447: finally_do_arg (SC_HANDLE, serviceManager, { CloseServiceHandle (finally_arg); });
448:
449: SC_HANDLE service = OpenService (serviceManager, "truecrypt", SERVICE_CHANGE_CONFIG);
450: throw_sys_if (!service);
451:
452: finally_do_arg (SC_HANDLE, service, { CloseServiceHandle (finally_arg); });
453:
1.1.1.5 ! root 454: // Windows versions preceding Vista can be installed on FAT filesystem which does not
! 455: // support long filenames during boot. Convert the driver path to short form if required.
! 456: string driverPath;
! 457: if (startOnBoot && nCurrentOS != WIN_VISTA_OR_LATER)
! 458: {
! 459: char pathBuf[MAX_PATH];
! 460: char filesystem[128];
! 461:
! 462: string path (GetWindowsDirectory());
! 463: path += "\\drivers\\truecrypt.sys";
! 464:
! 465: if (GetVolumePathName (path.c_str(), pathBuf, sizeof (pathBuf))
! 466: && GetVolumeInformation (pathBuf, NULL, 0, NULL, NULL, NULL, filesystem, sizeof(filesystem))
! 467: && memcmp (filesystem, "FAT", 3) == 0)
! 468: {
! 469: throw_sys_if (GetShortPathName (path.c_str(), pathBuf, sizeof (pathBuf)) == 0);
! 470:
! 471: // Convert absolute path to relative to the Windows directory
! 472: driverPath = pathBuf;
! 473: driverPath = driverPath.substr (driverPath.rfind ("\\", driverPath.rfind ("\\", driverPath.rfind ("\\") - 1) - 1) + 1);
! 474:
! 475: if (Is64BitOs())
! 476: driverPath = "SysWOW64" + driverPath.substr (driverPath.find ("\\"));
! 477: }
! 478: }
! 479:
1.1 root 480: throw_sys_if (!ChangeServiceConfig (service, SERVICE_NO_CHANGE, SERVICE_NO_CHANGE,
1.1.1.5 ! root 481: startOnBoot ? SERVICE_ERROR_SEVERE : SERVICE_ERROR_NORMAL,
! 482: driverPath.empty() ? NULL : driverPath.c_str(),
1.1 root 483: startOnBoot ? "Filter" : NULL,
484: NULL, NULL, NULL, NULL, NULL));
485:
486: // ChangeServiceConfig() rejects SERVICE_BOOT_START with ERROR_INVALID_PARAMETER
487: throw_sys_if (!WriteLocalMachineRegistryDword ("SYSTEM\\CurrentControlSet\\Services\\truecrypt", "Start", startType));
488: }
489:
490:
491: void BootEncryption::ProbeRealSystemDriveSize ()
492: {
493: if (RealSystemDriveSizeValid)
494: return;
495:
496: GetSystemDriveConfiguration();
497:
498: ProbeRealDriveSizeRequest request;
499: _snwprintf (request.DeviceName, array_capacity (request.DeviceName), L"%hs", DriveConfig.DrivePartition.DevicePath.c_str());
500:
501: CallDriver (TC_IOCTL_PROBE_REAL_DRIVE_SIZE, &request, sizeof (request), &request, sizeof (request));
502: DriveConfig.DrivePartition.Info.PartitionLength = request.RealDriveSize;
503:
1.1.1.5 ! root 504: RealSystemDriveSizeValid = true;
1.1.1.3 root 505:
506: if (request.TimeOut)
507: throw TimeOut (SRC_POS);
1.1 root 508: }
509:
510:
1.1.1.5 ! root 511: void BootEncryption::InvalidateCachedSysDriveProperties ()
! 512: {
! 513: DriveConfigValid = false;
! 514: RealSystemDriveSizeValid = false;
! 515: }
! 516:
! 517:
1.1 root 518: PartitionList BootEncryption::GetDrivePartitions (int driveNumber)
519: {
520: PartitionList partList;
521:
522: for (int partNumber = 0; partNumber < 64; ++partNumber)
523: {
524: stringstream partPath;
525: partPath << "\\Device\\Harddisk" << driveNumber << "\\Partition" << partNumber;
526:
527: DISK_PARTITION_INFO_STRUCT diskPartInfo;
528: _snwprintf (diskPartInfo.deviceName, array_capacity (diskPartInfo.deviceName), L"%hs", partPath.str().c_str());
529:
530: try
531: {
532: CallDriver (TC_IOCTL_GET_DRIVE_PARTITION_INFO, &diskPartInfo, sizeof (diskPartInfo), &diskPartInfo, sizeof (diskPartInfo));
533: }
534: catch (...)
535: {
536: continue;
537: }
538:
539: Partition part;
540: part.DevicePath = partPath.str();
541: part.Number = partNumber;
542: part.Info = diskPartInfo.partInfo;
543: part.IsGPT = diskPartInfo.IsGPT;
544:
545: // Mount point
546: wstringstream ws;
547: ws << partPath.str().c_str();
548: int driveNumber = GetDiskDeviceDriveLetter ((wchar_t *) ws.str().c_str());
549:
550: if (driveNumber >= 0)
551: {
552: part.MountPoint += (char) (driveNumber + 'A');
553: part.MountPoint += ":";
554: }
555: partList.push_back (part);
556: }
557:
558: return partList;
559: }
560:
561:
562: DISK_GEOMETRY BootEncryption::GetDriveGeometry (int driveNumber)
563: {
564: stringstream devName;
565: devName << "\\Device\\Harddisk" << driveNumber << "\\Partition0";
566:
567: DISK_GEOMETRY geometry;
568: throw_sys_if (!::GetDriveGeometry ((char *) devName.str().c_str(), &geometry));
569: return geometry;
570: }
571:
572:
573: string BootEncryption::GetWindowsDirectory ()
574: {
575: char buf[MAX_PATH];
1.1.1.5 ! root 576: throw_sys_if (GetSystemDirectory (buf, sizeof (buf)) == 0);
! 577:
! 578: return string (buf);
1.1 root 579: }
580:
581:
582: uint16 BootEncryption::GetInstalledBootLoaderVersion ()
583: {
584: uint16 version;
585: CallDriver (TC_IOCTL_GET_BOOT_LOADER_VERSION, NULL, 0, &version, sizeof (version));
586: return version;
587: }
588:
589:
1.1.1.3 root 590: // Note that this does not require admin rights (it just requires the driver to be running)
591: bool BootEncryption::IsBootLoaderOnDrive (char *devicePath)
592: {
593: try
594: {
595: OPEN_TEST_STRUCT openTestStruct;
596: DWORD dwResult;
597:
598: strcpy ((char *) &openTestStruct.wszFileName[0], devicePath);
599: ToUNICODE ((char *) &openTestStruct.wszFileName[0]);
600:
601: openTestStruct.bDetectTCBootLoader = TRUE;
602:
603: return (DeviceIoControl (hDriver, TC_IOCTL_OPEN_TEST,
604: &openTestStruct, sizeof (OPEN_TEST_STRUCT),
605: NULL, 0,
606: &dwResult, NULL) == TRUE);
607: }
608: catch (...)
609: {
610: return false;
611: }
612: }
613:
614:
1.1 root 615: BootEncryptionStatus BootEncryption::GetStatus ()
616: {
617: /* IMPORTANT: Do NOT add any potentially time-consuming operations to this function. */
618:
619: BootEncryptionStatus status;
620: CallDriver (TC_IOCTL_GET_BOOT_ENCRYPTION_STATUS, NULL, 0, &status, sizeof (status));
621: return status;
622: }
623:
624:
625: void BootEncryption::GetVolumeProperties (VOLUME_PROPERTIES_STRUCT *properties)
626: {
627: if (properties == NULL)
628: throw ParameterIncorrect (SRC_POS);
629:
630: CallDriver (TC_IOCTL_GET_BOOT_DRIVE_VOLUME_PROPERTIES, NULL, 0, properties, sizeof (*properties));
631: }
632:
633:
1.1.1.5 ! root 634: bool BootEncryption::IsHiddenSystemRunning ()
! 635: {
! 636: int hiddenSystemStatus;
! 637:
! 638: CallDriver (TC_IOCTL_IS_HIDDEN_SYSTEM_RUNNING, nullptr, 0, &hiddenSystemStatus, sizeof (hiddenSystemStatus));
! 639: return hiddenSystemStatus != 0;
! 640: }
! 641:
! 642:
1.1.1.2 root 643: bool BootEncryption::SystemDriveContainsPartitionType (byte type)
644: {
645: Device device (GetSystemDriveConfiguration().DevicePath, true);
646:
647: byte mbrBuf[SECTOR_SIZE];
648: device.SeekAt (0);
649: device.Read (mbrBuf, sizeof (mbrBuf));
650:
651: MBR *mbr = reinterpret_cast <MBR *> (mbrBuf);
652: if (mbr->Signature != 0xaa55)
653: throw ParameterIncorrect (SRC_POS);
654:
655: for (size_t i = 0; i < array_capacity (mbr->Partitions); ++i)
656: {
657: if (mbr->Partitions[i].Type == type)
658: return true;
659: }
660:
661: return false;
662: }
663:
664:
665: bool BootEncryption::SystemDriveContainsExtendedPartition ()
666: {
667: return SystemDriveContainsPartitionType (PARTITION_EXTENDED) || SystemDriveContainsPartitionType (PARTITION_XINT13_EXTENDED);
668: }
669:
670:
671: bool BootEncryption::SystemDriveIsDynamic ()
672: {
1.1.1.5 ! root 673: GetSystemDriveConfigurationRequest request;
! 674: _snwprintf (request.DevicePath, array_capacity (request.DevicePath), L"%hs", GetSystemDriveConfiguration().DeviceKernelPath.c_str());
! 675:
! 676: CallDriver (TC_IOCTL_GET_SYSTEM_DRIVE_CONFIG, &request, sizeof (request), &request, sizeof (request));
! 677: return request.DriveIsDynamic ? true : false;
1.1.1.2 root 678: }
679:
680:
1.1 root 681: SystemDriveConfiguration BootEncryption::GetSystemDriveConfiguration ()
682: {
683: if (DriveConfigValid)
684: return DriveConfig;
685:
686: SystemDriveConfiguration config;
687:
688: string winDir = GetWindowsDirectory();
689:
690: // Scan all drives
691: for (int driveNumber = 0; driveNumber < 32; ++driveNumber)
692: {
693: bool windowsFound = false;
694: config.SystemLoaderPresent = false;
695:
696: PartitionList partitions = GetDrivePartitions (driveNumber);
697: foreach (const Partition &part, partitions)
698: {
1.1.1.5 ! root 699: if (!part.MountPoint.empty()
! 700: && (_access ((part.MountPoint + "\\bootmgr").c_str(), 0) == 0 || _access ((part.MountPoint + "\\ntldr").c_str(), 0) == 0))
! 701: {
1.1 root 702: config.SystemLoaderPresent = true;
1.1.1.5 ! root 703: }
1.1 root 704:
705: if (!windowsFound && !part.MountPoint.empty() && winDir.find (part.MountPoint) == 0)
706: {
707: config.SystemPartition = part;
708: windowsFound = true;
709: }
710: }
711:
712: if (windowsFound)
713: {
714: config.DriveNumber = driveNumber;
715:
716: stringstream ss;
717: ss << "PhysicalDrive" << driveNumber;
718: config.DevicePath = ss.str();
719:
1.1.1.5 ! root 720: stringstream kernelPath;
! 721: kernelPath << "\\Device\\Harddisk" << driveNumber << "\\Partition0";
! 722: config.DeviceKernelPath = kernelPath.str();
! 723:
1.1 root 724: config.DrivePartition = partitions.front();
725: partitions.pop_front();
726: config.Partitions = partitions;
727:
728: config.InitialUnallocatedSpace = 0x7fffFFFFffffFFFFull;
729: config.TotalUnallocatedSpace = config.DrivePartition.Info.PartitionLength.QuadPart;
730:
731: foreach (const Partition &part, config.Partitions)
732: {
733: if (part.Info.StartingOffset.QuadPart < config.InitialUnallocatedSpace)
734: config.InitialUnallocatedSpace = part.Info.StartingOffset.QuadPart;
735:
736: config.TotalUnallocatedSpace -= part.Info.PartitionLength.QuadPart;
737: }
738:
739: DriveConfig = config;
1.1.1.5 ! root 740: DriveConfigValid = true;
1.1 root 741: return DriveConfig;
742: }
743: }
744:
745: throw ParameterIncorrect (SRC_POS);
746: }
747:
748:
749: bool BootEncryption::SystemPartitionCoversWholeDrive ()
750: {
751: SystemDriveConfiguration config = GetSystemDriveConfiguration();
752:
753: return config.Partitions.size() == 1
1.1.1.3 root 754: && config.DrivePartition.Info.PartitionLength.QuadPart - config.SystemPartition.Info.PartitionLength.QuadPart < 64 * BYTES_PER_MB;
1.1 root 755: }
756:
757:
1.1.1.3 root 758: uint32 BootEncryption::GetChecksum (byte *data, size_t size)
1.1 root 759: {
1.1.1.3 root 760: uint32 sum = 0;
761:
762: while (size-- > 0)
763: {
764: sum += *data++;
765: sum = _rotl (sum, 1);
766: }
767:
768: return sum;
769: }
770:
771:
1.1.1.5 ! root 772: void BootEncryption::CreateBootLoaderInMemory (byte *buffer, size_t bufferSize, bool rescueDisk)
1.1.1.3 root 773: {
1.1.1.5 ! root 774: if (bufferSize < TC_BOOT_LOADER_AREA_SIZE - TC_BOOT_ENCRYPTION_VOLUME_HEADER_SIZE)
1.1.1.3 root 775: throw ParameterIncorrect (SRC_POS);
776:
777: ZeroMemory (buffer, bufferSize);
778:
779: int ea = 0;
780: if (GetStatus().DriveMounted)
781: {
782: try
783: {
784: GetBootEncryptionAlgorithmNameRequest request;
785: CallDriver (TC_IOCTL_GET_BOOT_ENCRYPTION_ALGORITHM_NAME, NULL, 0, &request, sizeof (request));
786:
787: if (_stricmp (request.BootEncryptionAlgorithmName, "AES") == 0)
788: ea = AES;
789: else if (_stricmp (request.BootEncryptionAlgorithmName, "Serpent") == 0)
790: ea = SERPENT;
791: else if (_stricmp (request.BootEncryptionAlgorithmName, "Twofish") == 0)
792: ea = TWOFISH;
793: }
794: catch (...)
795: {
796: try
797: {
798: VOLUME_PROPERTIES_STRUCT properties;
799: GetVolumeProperties (&properties);
800: ea = properties.ea;
801: }
802: catch (...) { }
803: }
804: }
805: else
806: {
807: if (SelectedEncryptionAlgorithmId == 0)
808: throw ParameterIncorrect (SRC_POS);
809:
810: ea = SelectedEncryptionAlgorithmId;
811: }
812:
1.1.1.5 ! root 813: int bootSectorId = rescueDisk ? IDR_RESCUE_BOOT_SECTOR : IDR_BOOT_SECTOR;
! 814: int bootLoaderId = rescueDisk ? IDR_RESCUE_LOADER : IDR_BOOT_LOADER;
1.1.1.3 root 815:
816: switch (ea)
817: {
818: case AES:
1.1.1.5 ! root 819: bootSectorId = rescueDisk ? IDR_RESCUE_BOOT_SECTOR_AES : IDR_BOOT_SECTOR_AES;
! 820: bootLoaderId = rescueDisk ? IDR_RESCUE_LOADER_AES : IDR_BOOT_LOADER_AES;
1.1.1.3 root 821: break;
822:
823: case SERPENT:
1.1.1.5 ! root 824: bootSectorId = rescueDisk ? IDR_RESCUE_BOOT_SECTOR_SERPENT : IDR_BOOT_SECTOR_SERPENT;
! 825: bootLoaderId = rescueDisk ? IDR_RESCUE_LOADER_SERPENT : IDR_BOOT_LOADER_SERPENT;
1.1.1.3 root 826: break;
827:
828: case TWOFISH:
1.1.1.5 ! root 829: bootSectorId = rescueDisk ? IDR_RESCUE_BOOT_SECTOR_TWOFISH : IDR_BOOT_SECTOR_TWOFISH;
! 830: bootLoaderId = rescueDisk ? IDR_RESCUE_LOADER_TWOFISH : IDR_BOOT_LOADER_TWOFISH;
1.1.1.3 root 831: break;
832: }
833:
834: // Boot sector
1.1 root 835: DWORD size;
1.1.1.3 root 836: byte *bootSecResourceImg = MapResource ("BIN", bootSectorId, &size);
837: if (!bootSecResourceImg || size != SECTOR_SIZE)
838: throw ParameterIncorrect (SRC_POS);
839:
840: memcpy (buffer, bootSecResourceImg, size);
1.1 root 841:
1.1.1.3 root 842: if (nCurrentOS == WIN_VISTA_OR_LATER)
843: buffer[TC_BOOT_SECTOR_CONFIG_OFFSET] |= TC_BOOT_CFG_FLAG_WINDOWS_VISTA_OR_LATER;
844:
845: // Decompressor
846: byte *decompressor = MapResource ("BIN", IDR_BOOT_LOADER_DECOMPRESSOR, &size);
847: if (!decompressor || size > TC_BOOT_LOADER_DECOMPRESSOR_SECTOR_COUNT * SECTOR_SIZE)
1.1 root 848: throw ParameterIncorrect (SRC_POS);
849:
1.1.1.3 root 850: memcpy (buffer + SECTOR_SIZE, decompressor, size);
1.1 root 851:
1.1.1.3 root 852: // Compressed boot loader
853: byte *bootLoader = MapResource ("BIN", bootLoaderId, &size);
854: if (!bootLoader || size > TC_MAX_BOOT_LOADER_SECTOR_COUNT * SECTOR_SIZE)
855: throw ParameterIncorrect (SRC_POS);
1.1 root 856:
1.1.1.3 root 857: memcpy (buffer + SECTOR_SIZE + TC_BOOT_LOADER_DECOMPRESSOR_SECTOR_COUNT * SECTOR_SIZE, bootLoader, size);
1.1 root 858:
1.1.1.3 root 859: // Boot loader and decompressor checksum
860: *(uint16 *) (buffer + TC_BOOT_SECTOR_LOADER_LENGTH_OFFSET) = static_cast <uint16> (size);
861: *(uint32 *) (buffer + TC_BOOT_SECTOR_LOADER_CHECKSUM_OFFSET) = GetChecksum (buffer + SECTOR_SIZE,
862: TC_BOOT_LOADER_DECOMPRESSOR_SECTOR_COUNT * SECTOR_SIZE + size);
863:
864: // Backup of decompressor and boot loader
865: if (size + TC_BOOT_LOADER_DECOMPRESSOR_SECTOR_COUNT * SECTOR_SIZE <= TC_BOOT_LOADER_BACKUP_SECTOR_COUNT * SECTOR_SIZE)
866: {
867: memcpy (buffer + SECTOR_SIZE + TC_BOOT_LOADER_BACKUP_SECTOR_COUNT * SECTOR_SIZE,
868: buffer + SECTOR_SIZE, TC_BOOT_LOADER_BACKUP_SECTOR_COUNT * SECTOR_SIZE);
869:
870: buffer[TC_BOOT_SECTOR_CONFIG_OFFSET] |= TC_BOOT_CFG_FLAG_BACKUP_LOADER_AVAILABLE;
871: }
1.1.1.5 ! root 872: else if (!rescueDisk && bootLoaderId != IDR_BOOT_LOADER)
1.1.1.3 root 873: {
874: throw ParameterIncorrect (SRC_POS);
875: }
876: }
877:
878:
1.1.1.5 ! root 879: void BootEncryption::ReadBootSectorConfig (byte *config, size_t bufLength)
! 880: {
! 881: if (bufLength < TC_BOOT_CFG_FLAG_AREA_SIZE)
! 882: throw ParameterIncorrect (SRC_POS);
! 883:
! 884: GetSystemDriveConfigurationRequest request;
! 885: _snwprintf (request.DevicePath, array_capacity (request.DevicePath), L"%hs", GetSystemDriveConfiguration().DeviceKernelPath.c_str());
! 886:
! 887: try
! 888: {
! 889: CallDriver (TC_IOCTL_GET_SYSTEM_DRIVE_CONFIG, &request, sizeof (request), &request, sizeof (request));
! 890: *config = request.Configuration;
! 891: }
! 892: catch (...)
! 893: {
! 894: *config = 0;
! 895: }
! 896: }
! 897:
! 898:
! 899: void BootEncryption::WriteBootSectorConfig (const byte newConfig[])
! 900: {
! 901: Device device (GetSystemDriveConfiguration().DevicePath);
! 902: byte mbr[SECTOR_SIZE];
! 903:
! 904: device.SeekAt (0);
! 905: device.Read (mbr, sizeof (mbr));
! 906:
! 907: memcpy (mbr + TC_BOOT_SECTOR_CONFIG_OFFSET, newConfig, TC_BOOT_CFG_FLAG_AREA_SIZE);
! 908:
! 909: device.SeekAt (0);
! 910: device.Write (mbr, sizeof (mbr));
! 911:
! 912: byte mbrVerificationBuf[SECTOR_SIZE];
! 913: device.SeekAt (0);
! 914: device.Read (mbrVerificationBuf, sizeof (mbr));
! 915:
! 916: if (memcmp (mbr, mbrVerificationBuf, sizeof (mbr)) != 0)
! 917: throw ErrorException ("ERROR_MBR_PROTECTED");
! 918: }
! 919:
! 920:
! 921: unsigned int BootEncryption::GetHiddenOSCreationPhase ()
! 922: {
! 923: byte configFlags [TC_BOOT_CFG_FLAG_AREA_SIZE];
! 924:
! 925: ReadBootSectorConfig (configFlags, sizeof(configFlags));
! 926:
! 927: return (configFlags[0] & TC_BOOT_CFG_MASK_HIDDEN_OS_CREATION_PHASE);
! 928: }
! 929:
! 930:
! 931: void BootEncryption::SetHiddenOSCreationPhase (unsigned int newPhase)
! 932: {
! 933: #if TC_BOOT_CFG_FLAG_AREA_SIZE != 1
! 934: # error TC_BOOT_CFG_FLAG_AREA_SIZE != 1; revise GetHiddenOSCreationPhase() and SetHiddenOSCreationPhase()
! 935: #endif
! 936: byte configFlags [TC_BOOT_CFG_FLAG_AREA_SIZE];
! 937:
! 938: ReadBootSectorConfig (configFlags, sizeof(configFlags));
! 939:
! 940: configFlags[0] &= (byte) ~TC_BOOT_CFG_MASK_HIDDEN_OS_CREATION_PHASE;
! 941:
! 942: configFlags[0] |= newPhase;
! 943:
! 944: WriteBootSectorConfig (configFlags);
! 945: }
! 946:
! 947:
1.1.1.3 root 948: void BootEncryption::InstallBootLoader ()
949: {
1.1.1.5 ! root 950: byte bootLoaderBuf[TC_BOOT_LOADER_AREA_SIZE - TC_BOOT_ENCRYPTION_VOLUME_HEADER_SIZE];
! 951: CreateBootLoaderInMemory (bootLoaderBuf, sizeof (bootLoaderBuf), false);
1.1.1.3 root 952:
953: // Write MBR
954: Device device (GetSystemDriveConfiguration().DevicePath);
955: byte mbr[SECTOR_SIZE];
1.1 root 956:
957: device.SeekAt (0);
1.1.1.3 root 958: device.Read (mbr, sizeof (mbr));
1.1 root 959:
1.1.1.3 root 960: memcpy (mbr, bootLoaderBuf, TC_MAX_MBR_BOOT_CODE_SIZE);
1.1 root 961:
1.1.1.3 root 962: device.SeekAt (0);
963: device.Write (mbr, sizeof (mbr));
1.1 root 964:
1.1.1.3 root 965: byte mbrVerificationBuf[SECTOR_SIZE];
966: device.SeekAt (0);
967: device.Read (mbrVerificationBuf, sizeof (mbr));
1.1 root 968:
1.1.1.3 root 969: if (memcmp (mbr, mbrVerificationBuf, sizeof (mbr)) != 0)
970: throw ErrorException ("ERROR_MBR_PROTECTED");
1.1 root 971:
1.1.1.3 root 972: // Write boot loader
1.1 root 973: device.SeekAt (SECTOR_SIZE);
1.1.1.3 root 974: device.Write (bootLoaderBuf + SECTOR_SIZE, sizeof (bootLoaderBuf) - SECTOR_SIZE);
1.1 root 975: }
976:
977:
978: string BootEncryption::GetSystemLoaderBackupPath ()
979: {
980: char pathBuf[MAX_PATH];
981:
982: throw_sys_if (!SUCCEEDED (SHGetFolderPath (NULL, CSIDL_COMMON_APPDATA | CSIDL_FLAG_CREATE, NULL, 0, pathBuf)));
983:
984: string path = string (pathBuf) + "\\" TC_APP_NAME;
985: CreateDirectory (path.c_str(), NULL);
986:
987: return path + '\\' + TC_SYS_BOOT_LOADER_BACKUP_NAME;
988: }
989:
1.1.1.3 root 990:
1.1.1.5 ! root 991: void BootEncryption::RenameDeprecatedSystemLoaderBackup ()
! 992: {
! 993: char pathBuf[MAX_PATH];
! 994:
! 995: if (SUCCEEDED (SHGetFolderPath (NULL, CSIDL_COMMON_APPDATA, NULL, 0, pathBuf)))
! 996: {
! 997: string path = string (pathBuf) + "\\" TC_APP_NAME + '\\' + TC_SYS_BOOT_LOADER_BACKUP_NAME_LEGACY;
! 998:
! 999: if (FileExists (path.c_str()) && !FileExists (GetSystemLoaderBackupPath().c_str()))
! 1000: throw_sys_if (rename (path.c_str(), GetSystemLoaderBackupPath().c_str()) != 0);
! 1001: }
! 1002: }
! 1003:
! 1004:
1.1.1.2 root 1005: #ifndef SETUP
1.1 root 1006: void BootEncryption::CreateRescueIsoImage (bool initialSetup, const string &isoImagePath)
1007: {
1008: BootEncryptionStatus encStatus = GetStatus();
1009: if (encStatus.SetupInProgress)
1010: throw ParameterIncorrect (SRC_POS);
1011:
1012: Buffer imageBuf (RescueIsoImageSize);
1013:
1014: byte *image = imageBuf.Ptr();
1015: memset (image, 0, RescueIsoImageSize);
1016:
1017: // Primary volume descriptor
1.1.1.2 root 1018: strcpy ((char *)image + 0x8000, "\001CD001\001");
1019: strcpy ((char *)image + 0x7fff + 41, "TrueCrypt Rescue Disk ");
1020: *(uint32 *) (image + 0x7fff + 81) = RescueIsoImageSize / 2048;
1021: *(uint32 *) (image + 0x7fff + 85) = BE32 (RescueIsoImageSize / 2048);
1022: image[0x7fff + 121] = 1;
1023: image[0x7fff + 124] = 1;
1024: image[0x7fff + 125] = 1;
1025: image[0x7fff + 128] = 1;
1026: image[0x7fff + 130] = 8;
1027: image[0x7fff + 131] = 8;
1028:
1029: image[0x7fff + 133] = 10;
1030: image[0x7fff + 140] = 10;
1031: image[0x7fff + 141] = 0x14;
1032: image[0x7fff + 157] = 0x22;
1033: image[0x7fff + 159] = 0x18;
1.1 root 1034:
1035: // Boot record volume descriptor
1036: strcpy ((char *)image + 0x8801, "CD001\001EL TORITO SPECIFICATION");
1037: image[0x8800 + 0x47] = 0x19;
1038:
1.1.1.2 root 1039: // Volume descriptor set terminator
1040: strcpy ((char *)image + 0x9000, "\377CD001\001");
1041:
1042: // Path table
1043: image[0xA000 + 0] = 1;
1044: image[0xA000 + 2] = 0x18;
1045: image[0xA000 + 6] = 1;
1046:
1047: // Root directory
1048: image[0xc000 + 0] = 0x22;
1049: image[0xc000 + 2] = 0x18;
1050: image[0xc000 + 9] = 0x18;
1051: image[0xc000 + 11] = 0x08;
1052: image[0xc000 + 16] = 0x08;
1053: image[0xc000 + 25] = 0x02;
1054: image[0xc000 + 28] = 0x01;
1055: image[0xc000 + 31] = 0x01;
1056: image[0xc000 + 32] = 0x01;
1057: image[0xc000 + 34] = 0x22;
1058: image[0xc000 + 36] = 0x18;
1059: image[0xc000 + 43] = 0x18;
1060: image[0xc000 + 45] = 0x08;
1061: image[0xc000 + 50] = 0x08;
1062: image[0xc000 + 59] = 0x02;
1063: image[0xc000 + 62] = 0x01;
1064: *(uint32 *) (image + 0xc000 + 65) = 0x010101;
1065:
1.1 root 1066: // Validation entry
1067: image[0xc800] = 1;
1.1.1.2 root 1068: int offset = 0xc800 + 0x1c;
1.1 root 1069: image[offset++] = 0xaa;
1070: image[offset++] = 0x55;
1071: image[offset++] = 0x55;
1072: image[offset] = 0xaa;
1073:
1074: // Initial entry
1075: offset = 0xc820;
1076: image[offset++] = 0x88;
1077: image[offset++] = 2;
1078: image[0xc820 + 6] = 1;
1079: image[0xc820 + 8] = TC_CD_BOOT_LOADER_SECTOR;
1080:
1081: // TrueCrypt Boot Loader
1.1.1.5 ! root 1082: CreateBootLoaderInMemory (image + TC_CD_BOOTSECTOR_OFFSET, TC_BOOT_LOADER_AREA_SIZE, true);
1.1 root 1083:
1084: // Volume header
1085: if (initialSetup)
1086: {
1087: if (!RescueVolumeHeaderValid)
1088: throw ParameterIncorrect (SRC_POS);
1089:
1.1.1.5 ! root 1090: memcpy (image + TC_CD_BOOTSECTOR_OFFSET + TC_BOOT_VOLUME_HEADER_SECTOR_OFFSET, RescueVolumeHeader, TC_BOOT_ENCRYPTION_VOLUME_HEADER_SIZE);
1.1 root 1091: }
1092: else
1093: {
1094: Device bootDevice (GetSystemDriveConfiguration().DevicePath, true);
1095: bootDevice.SeekAt (TC_BOOT_VOLUME_HEADER_SECTOR_OFFSET);
1.1.1.5 ! root 1096: bootDevice.Read (image + TC_CD_BOOTSECTOR_OFFSET + TC_BOOT_VOLUME_HEADER_SECTOR_OFFSET, TC_BOOT_ENCRYPTION_VOLUME_HEADER_SIZE);
1.1 root 1097: }
1098:
1099: // Original system loader
1100: try
1101: {
1102: File sysBakFile (GetSystemLoaderBackupPath(), true);
1103: sysBakFile.Read (image + TC_CD_BOOTSECTOR_OFFSET + TC_ORIG_BOOT_LOADER_BACKUP_SECTOR_OFFSET, TC_BOOT_LOADER_AREA_SIZE);
1104:
1105: image[TC_CD_BOOTSECTOR_OFFSET + TC_BOOT_SECTOR_CONFIG_OFFSET] |= TC_BOOT_CFG_FLAG_RESCUE_DISK_ORIG_SYS_LOADER;
1106: }
1107: catch (Exception &e)
1108: {
1109: e.Show (ParentWindow);
1110: Warning ("SYS_LOADER_UNAVAILABLE_FOR_RESCUE_DISK");
1111: }
1112:
1.1.1.5 ! root 1113: // Boot loader backup
! 1114: CreateBootLoaderInMemory (image + TC_CD_BOOTSECTOR_OFFSET + TC_BOOT_LOADER_BACKUP_RESCUE_DISK_SECTOR_OFFSET, TC_BOOT_LOADER_AREA_SIZE, false);
! 1115:
1.1 root 1116: RescueIsoImage = new byte[RescueIsoImageSize];
1117: if (!RescueIsoImage)
1118: throw bad_alloc();
1119: memcpy (RescueIsoImage, image, RescueIsoImageSize);
1120:
1121: if (!isoImagePath.empty())
1122: {
1123: File isoFile (isoImagePath, false, true);
1124: isoFile.Write (image, RescueIsoImageSize);
1125: }
1126: }
1.1.1.2 root 1127: #endif
1.1 root 1128:
1129: bool BootEncryption::VerifyRescueDisk ()
1130: {
1131: if (!RescueIsoImage)
1132: throw ParameterIncorrect (SRC_POS);
1133:
1134: for (char drive = 'Z'; drive >= 'D'; --drive)
1135: {
1136: try
1137: {
1138: string path = "X:";
1139: path[0] = drive;
1140:
1141: Device driveDevice (path, true);
1142: size_t verifiedSectorCount = (TC_CD_BOOTSECTOR_OFFSET + TC_ORIG_BOOT_LOADER_BACKUP_SECTOR_OFFSET + TC_BOOT_LOADER_AREA_SIZE) / 2048;
1143: Buffer buffer ((verifiedSectorCount + 1) * 2048);
1144:
1145: DWORD bytesRead = driveDevice.Read (buffer.Ptr(), buffer.Size());
1146: if (bytesRead != buffer.Size())
1147: continue;
1148:
1149: if (memcmp (buffer.Ptr(), RescueIsoImage, buffer.Size()) == 0)
1150: return true;
1151: }
1152: catch (...) { }
1153: }
1154:
1155: return false;
1156: }
1157:
1158:
1159: #ifndef SETUP
1160:
1161: void BootEncryption::CreateVolumeHeader (uint64 volumeSize, uint64 encryptedAreaStart, Password *password, int ea, int mode, int pkcs5)
1162: {
1163: PCRYPTO_INFO cryptoInfo = NULL;
1.1.1.5 ! root 1164:
1.1 root 1165: throw_sys_if (Randinit () != 0);
1.1.1.5 ! root 1166: throw_sys_if (VolumeWriteHeader (TRUE, (char *) VolumeHeader, ea, mode, password, pkcs5, NULL, &cryptoInfo,
! 1167: volumeSize, 0, encryptedAreaStart, 0, TC_SYSENC_KEYSCOPE_MIN_REQ_PROG_VERSION, TC_HEADER_FLAG_ENCRYPTED_SYSTEM, FALSE) != 0);
1.1 root 1168:
1169: finally_do_arg (PCRYPTO_INFO*, &cryptoInfo, { crypto_close (*finally_arg); });
1170:
1171: // Initial rescue disk assumes encryption of the drive has been completed (EncryptedAreaLength == volumeSize)
1172: memcpy (RescueVolumeHeader, VolumeHeader, sizeof (RescueVolumeHeader));
1173: VolumeReadHeader (TRUE, (char *) RescueVolumeHeader, password, NULL, cryptoInfo);
1174:
1175: DecryptBuffer (RescueVolumeHeader + HEADER_ENCRYPTED_DATA_OFFSET, HEADER_ENCRYPTED_DATA_SIZE, cryptoInfo);
1176:
1177: if (GetHeaderField32 (RescueVolumeHeader, TC_HEADER_OFFSET_MAGIC) != 0x54525545)
1178: throw ParameterIncorrect (SRC_POS);
1179:
1180: byte *fieldPos = RescueVolumeHeader + TC_HEADER_OFFSET_ENCRYPTED_AREA_LENGTH;
1181: mputInt64 (fieldPos, volumeSize);
1.1.1.5 ! root 1182:
! 1183: // CRC of the header fields
! 1184: uint32 crc = GetCrc32 (RescueVolumeHeader + TC_HEADER_OFFSET_MAGIC, TC_HEADER_OFFSET_HEADER_CRC - TC_HEADER_OFFSET_MAGIC);
! 1185: fieldPos = RescueVolumeHeader + TC_HEADER_OFFSET_HEADER_CRC;
! 1186: mputLong (fieldPos, crc);
! 1187:
1.1 root 1188: EncryptBuffer (RescueVolumeHeader + HEADER_ENCRYPTED_DATA_OFFSET, HEADER_ENCRYPTED_DATA_SIZE, cryptoInfo);
1189:
1190: VolumeHeaderValid = true;
1191: RescueVolumeHeaderValid = true;
1192: }
1193:
1194:
1195: void BootEncryption::InstallVolumeHeader ()
1196: {
1197: if (!VolumeHeaderValid)
1198: throw ParameterIncorrect (SRC_POS);
1199:
1200: Device device (GetSystemDriveConfiguration().DevicePath);
1201:
1202: device.SeekAt (TC_BOOT_VOLUME_HEADER_SECTOR_OFFSET);
1203: device.Write ((byte *) VolumeHeader, sizeof (VolumeHeader));
1204: }
1205:
1206:
1207: // For synchronous operations use AbortSetupWait()
1208: void BootEncryption::AbortSetup ()
1209: {
1210: CallDriver (TC_IOCTL_ABORT_BOOT_ENCRYPTION_SETUP);
1211: }
1212:
1213:
1214: // For asynchronous operations use AbortSetup()
1215: void BootEncryption::AbortSetupWait ()
1216: {
1217: CallDriver (TC_IOCTL_ABORT_BOOT_ENCRYPTION_SETUP);
1218:
1219: BootEncryptionStatus encStatus = GetStatus();
1220:
1221: while (encStatus.SetupInProgress)
1222: {
1223: Sleep (TC_ABORT_TRANSFORM_WAIT_INTERVAL);
1224: encStatus = GetStatus();
1225: }
1226: }
1227:
1228:
1229: void BootEncryption::BackupSystemLoader ()
1230: {
1231: Device device (GetSystemDriveConfiguration().DevicePath, true);
1232:
1233: byte bootLoaderBuf[TC_BOOT_LOADER_AREA_SECTOR_COUNT * SECTOR_SIZE];
1234:
1235: device.SeekAt (0);
1236: device.Read (bootLoaderBuf, sizeof (bootLoaderBuf));
1237:
1238: // Prevent TrueCrypt loader from being backed up
1239: for (size_t i = 0; i < sizeof (bootLoaderBuf) - strlen (TC_APP_NAME); ++i)
1240: {
1241: if (memcmp (bootLoaderBuf + i, TC_APP_NAME, strlen (TC_APP_NAME)) == 0)
1242: {
1243: if (AskWarnNoYes ("TC_BOOT_LOADER_ALREADY_INSTALLED") == IDNO)
1244: throw UserAbort (SRC_POS);
1245: return;
1246: }
1247: }
1248:
1249: File backupFile (GetSystemLoaderBackupPath(), false, true);
1250: backupFile.Write (bootLoaderBuf, sizeof (bootLoaderBuf));
1251: }
1252:
1253:
1254: void BootEncryption::RestoreSystemLoader ()
1255: {
1256: byte bootLoaderBuf[TC_BOOT_LOADER_AREA_SECTOR_COUNT * SECTOR_SIZE];
1257:
1258: File backupFile (GetSystemLoaderBackupPath(), true);
1259:
1260: if (backupFile.Read (bootLoaderBuf, sizeof (bootLoaderBuf)) != sizeof (bootLoaderBuf))
1261: throw ParameterIncorrect (SRC_POS);
1262:
1263: Device device (GetSystemDriveConfiguration().DevicePath);
1.1.1.4 root 1264:
1265: // Preserve current partition table
1266: byte mbr[SECTOR_SIZE];
1267: device.SeekAt (0);
1268: device.Read (mbr, sizeof (mbr));
1269: memcpy (bootLoaderBuf + TC_MAX_MBR_BOOT_CODE_SIZE, mbr + TC_MAX_MBR_BOOT_CODE_SIZE, sizeof (mbr) - TC_MAX_MBR_BOOT_CODE_SIZE);
1270:
1.1 root 1271: device.SeekAt (0);
1272: device.Write (bootLoaderBuf, sizeof (bootLoaderBuf));
1273: }
1274:
1.1.1.3 root 1275: #endif // SETUP
1.1 root 1276:
1.1.1.5 ! root 1277: void BootEncryption::RegisterDeviceClassFilter (bool registerFilter, const GUID *deviceClassGuid)
1.1 root 1278: {
1.1.1.5 ! root 1279: HKEY classRegKey = SetupDiOpenClassRegKey (deviceClassGuid, KEY_READ | KEY_WRITE);
1.1 root 1280: throw_sys_if (classRegKey == INVALID_HANDLE_VALUE);
1281: finally_do_arg (HKEY, classRegKey, { RegCloseKey (finally_arg); });
1282:
1.1.1.5 ! root 1283: if (registerFilter)
1.1 root 1284: {
1.1.1.5 ! root 1285: // Register class filter below all other filters in the stack
! 1286:
1.1 root 1287: size_t strSize = strlen ("truecrypt") + 1;
1288: byte regKeyBuf[65536];
1289: DWORD size = sizeof (regKeyBuf) - strSize;
1290:
1291: // SetupInstallFromInfSection() does not support prepending of values so we have to modify the registry directly
1292: strncpy ((char *) regKeyBuf, "truecrypt", sizeof (regKeyBuf));
1293:
1294: if (RegQueryValueEx (classRegKey, "UpperFilters", NULL, NULL, regKeyBuf + strSize, &size) != ERROR_SUCCESS)
1295: size = 1;
1296:
1297: throw_sys_if (RegSetValueEx (classRegKey, "UpperFilters", 0, REG_MULTI_SZ, regKeyBuf, strSize + size) != ERROR_SUCCESS);
1298: }
1299: else
1300: {
1.1.1.5 ! root 1301: // Unregister a class filter
! 1302:
1.1 root 1303: char tempPath[MAX_PATH];
1304: GetTempPath (sizeof (tempPath), tempPath);
1.1.1.5 ! root 1305: string infFileName = string (tempPath) + "\\truecrypt_device_filter.inf";
1.1 root 1306:
1307: File infFile (infFileName, false, true);
1.1.1.5 ! root 1308: finally_do_arg (string, infFileName, { DeleteFile (finally_arg.c_str()); });
1.1 root 1309:
1.1.1.5 ! root 1310: string infTxt = "[truecrypt]\r\n"
! 1311: "DelReg=truecrypt_reg\r\n\r\n"
! 1312: "[truecrypt_reg]\r\n"
! 1313: "HKR,,\"UpperFilters\",0x00018002,\"truecrypt\"\r\n";
1.1 root 1314:
1315: infFile.Write ((byte *) infTxt.c_str(), infTxt.size());
1316: infFile.Close();
1317:
1318: HINF hInf = SetupOpenInfFile (infFileName.c_str(), NULL, INF_STYLE_OLDNT | INF_STYLE_WIN4, NULL);
1319: throw_sys_if (hInf == INVALID_HANDLE_VALUE);
1320: finally_do_arg (HINF, hInf, { SetupCloseInfFile (finally_arg); });
1321:
1322: throw_sys_if (!SetupInstallFromInfSection (ParentWindow, hInf, "truecrypt", SPINST_REGISTRY, classRegKey, NULL, 0, NULL, NULL, NULL, NULL));
1323: }
1324: }
1.1.1.5 ! root 1325:
! 1326: void BootEncryption::RegisterFilterDriver (bool registerDriver, bool volumeClass)
! 1327: {
! 1328: if (!IsAdmin() && IsUacSupported())
! 1329: {
! 1330: Elevator::RegisterFilterDriver (registerDriver, volumeClass);
! 1331: return;
! 1332: }
! 1333:
! 1334: if (volumeClass)
! 1335: {
! 1336: RegisterDeviceClassFilter (registerDriver, &GUID_DEVCLASS_VOLUME);
! 1337: RegisterDeviceClassFilter (registerDriver, &GUID_DEVCLASS_FLOPPYDISK);
! 1338: }
! 1339: else
! 1340: {
! 1341: RegisterDeviceClassFilter (registerDriver, &GUID_DEVCLASS_DISKDRIVE);
! 1342: }
! 1343: }
1.1 root 1344:
1.1.1.3 root 1345: #ifndef SETUP
1.1 root 1346:
1347: void BootEncryption::CheckRequirements ()
1348: {
1349: if (nCurrentOS == WIN_2000)
1350: throw ErrorException ("SYS_ENCRYPTION_UNSUPPORTED_ON_CURRENT_OS");
1351:
1352: if (IsNonInstallMode())
1353: throw ErrorException ("FEATURE_REQUIRES_INSTALLATION");
1354:
1355: SystemDriveConfiguration config = GetSystemDriveConfiguration ();
1356:
1357: if (config.SystemPartition.IsGPT)
1358: throw ErrorException ("GPT_BOOT_DRIVE_UNSUPPORTED");
1359:
1.1.1.5 ! root 1360: if (SystemDriveIsDynamic())
! 1361: throw ErrorException ("SYSENC_UNSUPPORTED_FOR_DYNAMIC_DISK");
! 1362:
1.1 root 1363: if (config.InitialUnallocatedSpace < TC_BOOT_LOADER_AREA_SIZE)
1364: throw ErrorException ("NO_SPACE_FOR_BOOT_LOADER");
1365:
1366: DISK_GEOMETRY geometry = GetDriveGeometry (config.DriveNumber);
1367:
1368: if (geometry.BytesPerSector != SECTOR_SIZE)
1369: throw ErrorException ("LARGE_SECTOR_UNSUPPORTED");
1370:
1371: if (!config.SystemLoaderPresent)
1372: throw ErrorException ("WINDOWS_NOT_ON_BOOT_DRIVE_ERROR");
1.1.1.5 ! root 1373:
! 1374: if (!config.SystemPartition.IsGPT)
! 1375: {
! 1376: // Determine whether there is an Active partition on the system drive
! 1377: bool activePartitionFound = false;
! 1378: foreach (const Partition &partition, config.Partitions)
! 1379: {
! 1380: if (partition.Info.BootIndicator)
! 1381: {
! 1382: activePartitionFound = true;
! 1383: break;
! 1384: }
! 1385: }
! 1386:
! 1387: if (!activePartitionFound)
! 1388: throw ErrorException ("WINDOWS_NOT_ON_BOOT_DRIVE_ERROR");
! 1389: }
! 1390: }
! 1391:
! 1392:
! 1393: void BootEncryption::CheckRequirementsHiddenOS ()
! 1394: {
! 1395: // It is assumed that CheckRequirements() had been called (so we don't check e.g. whether it's GPT).
! 1396:
! 1397: // The user may have modified/added/deleted partitions since the partition table was last scanned.
! 1398: InvalidateCachedSysDriveProperties ();
! 1399:
! 1400: GetPartitionForHiddenOS ();
1.1 root 1401: }
1402:
1403:
1404: void BootEncryption::Deinstall ()
1405: {
1406: BootEncryptionStatus encStatus = GetStatus();
1407:
1408: if (encStatus.DriveEncrypted || encStatus.DriveMounted)
1409: throw ParameterIncorrect (SRC_POS);
1410:
1411: SystemDriveConfiguration config = GetSystemDriveConfiguration ();
1412:
1413: if (encStatus.VolumeHeaderPresent)
1414: {
1415: // Verify CRC of header salt
1416: Device device (config.DevicePath, true);
1.1.1.5 ! root 1417: byte header[TC_BOOT_ENCRYPTION_VOLUME_HEADER_SIZE];
1.1 root 1418:
1419: device.SeekAt (TC_BOOT_VOLUME_HEADER_SECTOR_OFFSET);
1420: device.Read (header, sizeof (header));
1421:
1422: if (encStatus.VolumeHeaderSaltCrc32 != GetCrc32 ((byte *) header, PKCS5_SALT_SIZE))
1423: throw ParameterIncorrect (SRC_POS);
1424: }
1425:
1.1.1.5 ! root 1426: RegisterFilterDriver (false, false);
! 1427: RegisterFilterDriver (false, true);
1.1 root 1428: SetDriverServiceStartType (SERVICE_SYSTEM_START);
1429:
1.1.1.5 ! root 1430: SetHiddenOSCreationPhase (TC_HIDDEN_OS_CREATION_PHASE_NONE); // In case RestoreSystemLoader() fails
! 1431:
1.1 root 1432: try
1433: {
1434: RestoreSystemLoader ();
1435: }
1436: catch (Exception &e)
1437: {
1438: e.Show (ParentWindow);
1439: throw ErrorException ("SYS_LOADER_RESTORE_FAILED");
1440: }
1441: }
1442:
1443:
1444: int BootEncryption::ChangePassword (Password *oldPassword, Password *newPassword, int pkcs5)
1445: {
1.1.1.5 ! root 1446: BootEncryptionStatus encStatus = GetStatus();
! 1447:
! 1448: if (encStatus.SetupInProgress)
1.1 root 1449: throw ParameterIncorrect (SRC_POS);
1450:
1451: SystemDriveConfiguration config = GetSystemDriveConfiguration ();
1452:
1.1.1.5 ! root 1453: char header[TC_BOOT_ENCRYPTION_VOLUME_HEADER_SIZE];
1.1 root 1454: Device device (config.DevicePath);
1455:
1456: // Only one algorithm is currently supported
1457: if (pkcs5 != 0)
1458: throw ParameterIncorrect (SRC_POS);
1459:
1.1.1.5 ! root 1460: int64 headerOffset = TC_BOOT_VOLUME_HEADER_SECTOR_OFFSET;
! 1461: int64 backupHeaderOffset = -1;
! 1462:
! 1463: if (encStatus.HiddenSystem)
! 1464: {
! 1465: headerOffset = encStatus.HiddenSystemPartitionStart + TC_HIDDEN_VOLUME_HEADER_OFFSET;
! 1466:
! 1467: // Find hidden system partition
! 1468: foreach (const Partition &partition, config.Partitions)
! 1469: {
! 1470: if (partition.Info.StartingOffset.QuadPart == encStatus.HiddenSystemPartitionStart)
! 1471: {
! 1472: backupHeaderOffset = partition.Info.StartingOffset.QuadPart + partition.Info.PartitionLength.QuadPart - TC_VOLUME_HEADER_SIZE;
! 1473: break;
! 1474: }
! 1475: }
! 1476:
! 1477: if (backupHeaderOffset == -1)
! 1478: throw ParameterIncorrect (SRC_POS);
! 1479: }
! 1480:
! 1481: device.SeekAt (headerOffset);
1.1 root 1482: device.Read ((byte *) header, sizeof (header));
1483:
1484: PCRYPTO_INFO cryptoInfo = NULL;
1485:
1.1.1.5 ! root 1486: int status = VolumeReadHeader (!encStatus.HiddenSystem, header, oldPassword, &cryptoInfo, NULL);
1.1 root 1487: finally_do_arg (PCRYPTO_INFO, cryptoInfo, { if (finally_arg) crypto_close (finally_arg); });
1488:
1489: if (status != 0)
1490: {
1491: handleError (ParentWindow, status);
1492: return status;
1493: }
1494:
1495: // Change the PKCS-5 PRF if requested by user
1496: if (pkcs5 != 0)
1497: cryptoInfo->pkcs5 = pkcs5;
1498:
1499: throw_sys_if (Randinit () != 0);
1500:
1501: /* The header will be re-encrypted PRAND_DISK_WIPE_PASSES times to prevent adversaries from using
1502: techniques such as magnetic force microscopy or magnetic force scanning tunnelling microscopy
1503: to recover the overwritten header. According to Peter Gutmann, data should be overwritten 22
1504: times (ideally, 35 times) using non-random patterns and pseudorandom data. However, as users might
1505: impatiently interupt the process (etc.) we will not use the Gutmann's patterns but will write the
1506: valid re-encrypted header, i.e. pseudorandom data, and there will be many more passes than Guttman
1507: recommends. During each pass we will write a valid working header. Each pass will use the same master
1508: key, and also the same header key, secondary key (XTS), etc., derived from the new password. The only
1509: item that will be different for each pass will be the salt. This is sufficient to cause each "version"
1510: of the header to differ substantially and in a random manner from the versions written during the
1511: other passes. */
1512:
1513: bool headerUpdated = false;
1514: int result = ERR_SUCCESS;
1515:
1516: try
1517: {
1.1.1.5 ! root 1518: BOOL backupHeader = FALSE;
! 1519: while (TRUE)
1.1 root 1520: {
1.1.1.5 ! root 1521: for (int wipePass = 0; wipePass < PRAND_DISK_WIPE_PASSES; wipePass++)
1.1 root 1522: {
1.1.1.5 ! root 1523: PCRYPTO_INFO tmpCryptoInfo = NULL;
! 1524:
! 1525: status = VolumeWriteHeader (!encStatus.HiddenSystem,
! 1526: header,
! 1527: cryptoInfo->ea,
! 1528: cryptoInfo->mode,
! 1529: newPassword,
! 1530: cryptoInfo->pkcs5,
! 1531: (char *) cryptoInfo->master_keydata,
! 1532: &tmpCryptoInfo,
! 1533: cryptoInfo->VolumeSize.Value,
! 1534: cryptoInfo->hiddenVolumeSize,
! 1535: cryptoInfo->EncryptedAreaStart.Value,
! 1536: cryptoInfo->EncryptedAreaLength.Value,
! 1537: cryptoInfo->RequiredProgramVersion,
! 1538: cryptoInfo->HeaderFlags | TC_HEADER_FLAG_ENCRYPTED_SYSTEM,
! 1539: wipePass < PRAND_DISK_WIPE_PASSES - 1);
! 1540:
! 1541: if (tmpCryptoInfo)
! 1542: crypto_close (tmpCryptoInfo);
! 1543:
! 1544: if (status != 0)
! 1545: {
! 1546: handleError (ParentWindow, status);
! 1547: return status;
! 1548: }
! 1549:
! 1550: device.SeekAt (headerOffset);
! 1551: device.Write ((byte *) header, sizeof (header));
! 1552: headerUpdated = true;
1.1 root 1553: }
1554:
1.1.1.5 ! root 1555: if (!encStatus.HiddenSystem || backupHeader)
! 1556: break;
! 1557:
! 1558: backupHeader = TRUE;
! 1559: headerOffset = backupHeaderOffset;
1.1 root 1560: }
1561: }
1562: catch (Exception &e)
1563: {
1564: e.Show (ParentWindow);
1565: result = ERR_OS_ERROR;
1566: }
1567:
1568: if (headerUpdated)
1569: {
1570: ReopenBootVolumeHeaderRequest reopenRequest;
1571: reopenRequest.VolumePassword = *newPassword;
1572: finally_do_arg (ReopenBootVolumeHeaderRequest*, &reopenRequest, { burn (finally_arg, sizeof (*finally_arg)); });
1573:
1574: CallDriver (TC_IOCTL_REOPEN_BOOT_VOLUME_HEADER, &reopenRequest, sizeof (reopenRequest));
1575: }
1576:
1577: return result;
1578: }
1579:
1580:
1581: void BootEncryption::CheckEncryptionSetupResult ()
1582: {
1583: CallDriver (TC_IOCTL_GET_BOOT_ENCRYPTION_SETUP_RESULT);
1584: }
1585:
1586:
1587: void BootEncryption::Install ()
1588: {
1589: BootEncryptionStatus encStatus = GetStatus();
1590: if (encStatus.DriveMounted)
1591: throw ParameterIncorrect (SRC_POS);
1592:
1593: try
1594: {
1595: InstallBootLoader ();
1596: InstallVolumeHeader ();
1.1.1.3 root 1597: RegisterBootDriver ();
1.1 root 1598:
1.1.1.3 root 1599: // Prevent system log errors caused by rejecting crash dumps
1600: WriteLocalMachineRegistryDword ("System\\CurrentControlSet\\Control\\CrashControl", "CrashDumpEnabled", 0);
1.1 root 1601: }
1602: catch (Exception &)
1603: {
1604: try
1605: {
1606: RestoreSystemLoader ();
1607: }
1608: catch (Exception &e)
1609: {
1610: e.Show (ParentWindow);
1611: }
1612:
1613: throw;
1614: }
1615: }
1616:
1617:
1618: void BootEncryption::PrepareInstallation (bool systemPartitionOnly, Password &password, int ea, int mode, int pkcs5, const string &rescueIsoImagePath)
1619: {
1620: BootEncryptionStatus encStatus = GetStatus();
1621: if (encStatus.DriveMounted)
1622: throw ParameterIncorrect (SRC_POS);
1623:
1624: CheckRequirements ();
1625:
1626: SystemDriveConfiguration config = GetSystemDriveConfiguration();
1627: BackupSystemLoader ();
1628:
1629: uint64 volumeSize;
1630: uint64 encryptedAreaStart;
1631:
1632: if (systemPartitionOnly)
1633: {
1634: volumeSize = config.SystemPartition.Info.PartitionLength.QuadPart;
1635: encryptedAreaStart = config.SystemPartition.Info.StartingOffset.QuadPart;
1636: }
1637: else
1638: {
1639: volumeSize = config.DrivePartition.Info.PartitionLength.QuadPart - TC_BOOT_LOADER_AREA_SIZE;
1640: encryptedAreaStart = config.DrivePartition.Info.StartingOffset.QuadPart + TC_BOOT_LOADER_AREA_SIZE;
1641: }
1642:
1.1.1.3 root 1643: SelectedEncryptionAlgorithmId = ea;
1.1 root 1644: CreateVolumeHeader (volumeSize, encryptedAreaStart, &password, ea, mode, pkcs5);
1645:
1646: if (!rescueIsoImagePath.empty())
1647: CreateRescueIsoImage (true, rescueIsoImagePath);
1648: }
1649:
1650:
1.1.1.5 ! root 1651: bool BootEncryption::IsPagingFileActive ()
! 1652: {
! 1653: if (!IsAdmin() && IsUacSupported())
! 1654: return Elevator::IsPagingFileActive() ? true : false;
! 1655:
! 1656: return ::IsPagingFileActive() ? true : false;
! 1657: }
! 1658:
! 1659:
! 1660: void BootEncryption::WriteLocalMachineRegistryDwordValue (char *keyPath, char *valueName, DWORD value)
! 1661: {
! 1662: if (!IsAdmin() && IsUacSupported())
! 1663: {
! 1664: Elevator::WriteLocalMachineRegistryDwordValue (keyPath, valueName, value);
! 1665: return;
! 1666: }
! 1667:
! 1668: throw_sys_if (!WriteLocalMachineRegistryDword (keyPath, valueName, value));
! 1669: }
! 1670:
! 1671:
1.1 root 1672: void BootEncryption::StartDecryption ()
1673: {
1674: BootEncryptionStatus encStatus = GetStatus();
1675:
1676: if (!encStatus.DeviceFilterActive || !encStatus.DriveMounted || encStatus.SetupInProgress)
1677: throw ParameterIncorrect (SRC_POS);
1678:
1679: BootEncryptionSetupRequest request;
1680: ZeroMemory (&request, sizeof (request));
1681:
1682: request.SetupMode = SetupDecryption;
1683:
1684: CallDriver (TC_IOCTL_BOOT_ENCRYPTION_SETUP, &request, sizeof (request), NULL, 0);
1685: }
1686:
1687:
1688: void BootEncryption::StartEncryption (WipeAlgorithmId wipeAlgorithm)
1689: {
1690: BootEncryptionStatus encStatus = GetStatus();
1691:
1692: if (!encStatus.DeviceFilterActive || !encStatus.DriveMounted || encStatus.SetupInProgress)
1693: throw ParameterIncorrect (SRC_POS);
1694:
1695: BootEncryptionSetupRequest request;
1696: ZeroMemory (&request, sizeof (request));
1697:
1698: request.SetupMode = SetupEncryption;
1699: request.WipeAlgorithm = wipeAlgorithm;
1700:
1701: CallDriver (TC_IOCTL_BOOT_ENCRYPTION_SETUP, &request, sizeof (request), NULL, 0);
1702: }
1703:
1.1.1.2 root 1704: #endif // !SETUP
1.1 root 1705:
1.1.1.3 root 1706: void BootEncryption::RegisterBootDriver (void)
1707: {
1708: SetDriverServiceStartType (SERVICE_BOOT_START);
1709:
1710: try
1711: {
1.1.1.5 ! root 1712: RegisterFilterDriver (false, false);
! 1713: RegisterFilterDriver (false, true);
1.1.1.3 root 1714: }
1715: catch (...) { }
1716:
1.1.1.5 ! root 1717: RegisterFilterDriver (true, false);
! 1718: RegisterFilterDriver (true, true);
1.1.1.3 root 1719: }
1720:
1721:
1.1 root 1722: bool BootEncryption::RestartComputer (void)
1723: {
1.1.1.5 ! root 1724: return (::RestartComputer() != FALSE);
1.1 root 1725: }
1726: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.