|
|
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 "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" ! 24: #include "Random.h" ! 25: #include "Registry.h" ! 26: #include "Volumes.h" ! 27: ! 28: #ifdef VOLFORMAT ! 29: #include "Format/FormatCom.h" ! 30: #elif defined (TCMOUNT) ! 31: #include "Mount/MainCom.h" ! 32: #endif ! 33: ! 34: namespace TrueCrypt ! 35: { ! 36: #if !defined (SETUP) ! 37: ! 38: class Elevator ! 39: { ! 40: public: ! 41: static void CallDriver (DWORD ioctl, void *input, DWORD inputSize, void *output, DWORD outputSize) ! 42: { ! 43: Elevate(); ! 44: ! 45: CComBSTR inputBstr; ! 46: if (input && inputBstr.AppendBytes ((const char *) input, inputSize) != S_OK) ! 47: throw ParameterIncorrect (SRC_POS); ! 48: ! 49: CComBSTR outputBstr; ! 50: if (output && outputBstr.AppendBytes ((const char *) output, outputSize) != S_OK) ! 51: throw ParameterIncorrect (SRC_POS); ! 52: ! 53: DWORD result = ElevatedComInstance->CallDriver (ioctl, inputBstr, &outputBstr); ! 54: if (result != ERROR_SUCCESS) ! 55: { ! 56: SetLastError (result); ! 57: throw SystemException(); ! 58: } ! 59: } ! 60: ! 61: static void ReadWriteFile (BOOL write, BOOL device, const string &filePath, byte *buffer, uint64 offset, uint32 size, DWORD *sizeDone) ! 62: { ! 63: Elevate(); ! 64: ! 65: CComBSTR bufferBstr; ! 66: if (bufferBstr.AppendBytes ((const char *) buffer, size) != S_OK) ! 67: throw ParameterIncorrect (SRC_POS); ! 68: DWORD result = ElevatedComInstance->ReadWriteFile (write, device, CComBSTR (filePath.c_str()), &bufferBstr, offset, size, sizeDone); ! 69: ! 70: if (result != ERROR_SUCCESS) ! 71: { ! 72: SetLastError (result); ! 73: throw SystemException(); ! 74: } ! 75: ! 76: if (!write) ! 77: memcpy (buffer, (BYTE *) bufferBstr.m_str, size); ! 78: } ! 79: ! 80: static void RegisterFilterDriver (bool registerDriver) ! 81: { ! 82: Elevate(); ! 83: ! 84: DWORD result = ElevatedComInstance->RegisterFilterDriver (registerDriver ? TRUE : FALSE); ! 85: if (result != ERROR_SUCCESS) ! 86: { ! 87: SetLastError (result); ! 88: throw SystemException(); ! 89: } ! 90: } ! 91: ! 92: static void Release () ! 93: { ! 94: if (ElevatedComInstance) ! 95: { ! 96: ElevatedComInstance->Release(); ! 97: ElevatedComInstance = nullptr; ! 98: CoUninitialize (); ! 99: } ! 100: } ! 101: ! 102: static void SetDriverServiceStartType (DWORD startType) ! 103: { ! 104: Elevate(); ! 105: ! 106: DWORD result = ElevatedComInstance->SetDriverServiceStartType (startType); ! 107: if (result != ERROR_SUCCESS) ! 108: { ! 109: SetLastError (result); ! 110: throw SystemException(); ! 111: } ! 112: } ! 113: ! 114: protected: ! 115: static void Elevate () ! 116: { ! 117: if (IsAdmin()) ! 118: { ! 119: SetLastError (ERROR_ACCESS_DENIED); ! 120: throw SystemException(); ! 121: } ! 122: ! 123: if (!ElevatedComInstance) ! 124: { ! 125: CoInitialize (NULL); ! 126: ElevatedComInstance = GetElevatedInstance (GetActiveWindow() ? GetActiveWindow() : MainDlg); ! 127: } ! 128: } ! 129: ! 130: #if defined (TCMOUNT) ! 131: static ITrueCryptMainCom *ElevatedComInstance; ! 132: #elif defined (VOLFORMAT) ! 133: static ITrueCryptFormatCom *ElevatedComInstance; ! 134: #endif ! 135: }; ! 136: ! 137: #if defined (TCMOUNT) ! 138: ITrueCryptMainCom *Elevator::ElevatedComInstance; ! 139: #elif defined (VOLFORMAT) ! 140: ITrueCryptFormatCom *Elevator::ElevatedComInstance; ! 141: #endif ! 142: ! 143: #else // SETUP ! 144: ! 145: class Elevator ! 146: { ! 147: public: ! 148: static void CallDriver (DWORD ioctl, void *input, DWORD inputSize, void *output, DWORD outputSize) { throw ParameterIncorrect (SRC_POS); } ! 149: static void ReadWriteFile (BOOL write, BOOL device, const string &filePath, byte *buffer, uint64 offset, uint32 size, DWORD *sizeDone) { throw ParameterIncorrect (SRC_POS); } ! 150: static void RegisterFilterDriver (bool registerDriver) { throw ParameterIncorrect (SRC_POS); } ! 151: static void Release () { } ! 152: static void SetDriverServiceStartType (DWORD startType) { throw ParameterIncorrect (SRC_POS); } ! 153: }; ! 154: ! 155: #endif // SETUP ! 156: ! 157: ! 158: File::File (string path, bool readOnly, bool create) : Elevated (false), FileOpen (false) ! 159: { ! 160: Handle = CreateFile (path.c_str(), ! 161: readOnly ? FILE_READ_DATA : FILE_READ_DATA | FILE_WRITE_DATA, ! 162: FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, create ? CREATE_ALWAYS : OPEN_EXISTING, ! 163: FILE_FLAG_RANDOM_ACCESS | FILE_FLAG_WRITE_THROUGH, NULL); ! 164: ! 165: try ! 166: { ! 167: throw_sys_if (Handle == INVALID_HANDLE_VALUE); ! 168: } ! 169: catch (SystemException &) ! 170: { ! 171: if (GetLastError() == ERROR_ACCESS_DENIED && IsUacSupported()) ! 172: Elevated = true; ! 173: else ! 174: throw; ! 175: } ! 176: ! 177: FileOpen = true; ! 178: FilePointerPosition = 0; ! 179: IsDevice = false; ! 180: Path = path; ! 181: } ! 182: ! 183: void File::Close () ! 184: { ! 185: if (FileOpen) ! 186: { ! 187: if (!Elevated) ! 188: CloseHandle (Handle); ! 189: ! 190: FileOpen = false; ! 191: } ! 192: } ! 193: ! 194: DWORD File::Read (byte *buffer, DWORD size) ! 195: { ! 196: DWORD bytesRead; ! 197: ! 198: if (Elevated) ! 199: { ! 200: DWORD bytesRead; ! 201: ! 202: Elevator::ReadWriteFile (false, IsDevice, Path, buffer, FilePointerPosition, size, &bytesRead); ! 203: FilePointerPosition += bytesRead; ! 204: return bytesRead; ! 205: } ! 206: ! 207: throw_sys_if (!ReadFile (Handle, buffer, size, &bytesRead, NULL)); ! 208: return bytesRead; ! 209: } ! 210: ! 211: void File::SeekAt (int64 position) ! 212: { ! 213: if (Elevated) ! 214: { ! 215: FilePointerPosition = position; ! 216: } ! 217: else ! 218: { ! 219: LARGE_INTEGER pos; ! 220: pos.QuadPart = position; ! 221: throw_sys_if (!SetFilePointerEx (Handle, pos, NULL, FILE_BEGIN)); ! 222: } ! 223: } ! 224: ! 225: void File::Write (byte *buffer, DWORD size) ! 226: { ! 227: DWORD bytesWritten; ! 228: ! 229: if (Elevated) ! 230: { ! 231: Elevator::ReadWriteFile (true, IsDevice, Path, buffer, FilePointerPosition, size, &bytesWritten); ! 232: FilePointerPosition += bytesWritten; ! 233: throw_sys_if (bytesWritten != size); ! 234: } ! 235: else ! 236: { ! 237: throw_sys_if (!WriteFile (Handle, buffer, size, &bytesWritten, NULL) || bytesWritten != size); ! 238: } ! 239: } ! 240: ! 241: void Show (HWND parent, const string &str) ! 242: { ! 243: MessageBox (parent, str.c_str(), NULL, 0); ! 244: } ! 245: ! 246: ! 247: Device::Device (string path, bool readOnly) ! 248: { ! 249: FileOpen = false; ! 250: Elevated = false; ! 251: ! 252: Handle = CreateFile ((string ("\\\\.\\") + path).c_str(), ! 253: readOnly ? FILE_READ_DATA : FILE_READ_DATA | FILE_WRITE_DATA, ! 254: FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, ! 255: FILE_FLAG_RANDOM_ACCESS | FILE_FLAG_WRITE_THROUGH, NULL); ! 256: ! 257: try ! 258: { ! 259: throw_sys_if (Handle == INVALID_HANDLE_VALUE); ! 260: } ! 261: catch (SystemException &) ! 262: { ! 263: if (GetLastError() == ERROR_ACCESS_DENIED && IsUacSupported()) ! 264: Elevated = true; ! 265: else ! 266: throw; ! 267: } ! 268: ! 269: FileOpen = true; ! 270: FilePointerPosition = 0; ! 271: IsDevice = true; ! 272: Path = path; ! 273: } ! 274: ! 275: ! 276: BootEncryption::~BootEncryption () ! 277: { ! 278: if (RescueIsoImage) ! 279: delete RescueIsoImage; ! 280: ! 281: Elevator::Release(); ! 282: } ! 283: ! 284: ! 285: void BootEncryption::CallDriver (DWORD ioctl, void *input, DWORD inputSize, void *output, DWORD outputSize) ! 286: { ! 287: try ! 288: { ! 289: DWORD bytesReturned; ! 290: throw_sys_if (!DeviceIoControl (hDriver, ioctl, input, inputSize, output, outputSize, &bytesReturned, NULL)); ! 291: } ! 292: catch (SystemException &) ! 293: { ! 294: if (GetLastError() == ERROR_ACCESS_DENIED && IsUacSupported()) ! 295: Elevator::CallDriver (ioctl, input, inputSize, output, outputSize); ! 296: else ! 297: throw; ! 298: } ! 299: } ! 300: ! 301: ! 302: DWORD BootEncryption::GetDriverServiceStartType () ! 303: { ! 304: DWORD startType; ! 305: throw_sys_if (!ReadLocalMachineRegistryDword ("SYSTEM\\CurrentControlSet\\Services\\truecrypt", "Start", &startType)); ! 306: return startType; ! 307: } ! 308: ! 309: ! 310: void BootEncryption::SetDriverServiceStartType (DWORD startType) ! 311: { ! 312: if (!IsAdmin() && IsUacSupported()) ! 313: { ! 314: Elevator::SetDriverServiceStartType (startType); ! 315: return; ! 316: } ! 317: ! 318: BOOL startOnBoot = (startType == SERVICE_BOOT_START); ! 319: ! 320: SC_HANDLE serviceManager = OpenSCManager (NULL, NULL, SC_MANAGER_ALL_ACCESS); ! 321: throw_sys_if (!serviceManager); ! 322: ! 323: finally_do_arg (SC_HANDLE, serviceManager, { CloseServiceHandle (finally_arg); }); ! 324: ! 325: SC_HANDLE service = OpenService (serviceManager, "truecrypt", SERVICE_CHANGE_CONFIG); ! 326: throw_sys_if (!service); ! 327: ! 328: finally_do_arg (SC_HANDLE, service, { CloseServiceHandle (finally_arg); }); ! 329: ! 330: throw_sys_if (!ChangeServiceConfig (service, SERVICE_NO_CHANGE, SERVICE_NO_CHANGE, ! 331: startOnBoot ? SERVICE_ERROR_SEVERE : SERVICE_ERROR_NORMAL, NULL, ! 332: startOnBoot ? "Filter" : NULL, ! 333: NULL, NULL, NULL, NULL, NULL)); ! 334: ! 335: // ChangeServiceConfig() rejects SERVICE_BOOT_START with ERROR_INVALID_PARAMETER ! 336: throw_sys_if (!WriteLocalMachineRegistryDword ("SYSTEM\\CurrentControlSet\\Services\\truecrypt", "Start", startType)); ! 337: } ! 338: ! 339: ! 340: void BootEncryption::ProbeRealSystemDriveSize () ! 341: { ! 342: if (RealSystemDriveSizeValid) ! 343: return; ! 344: ! 345: GetSystemDriveConfiguration(); ! 346: ! 347: ProbeRealDriveSizeRequest request; ! 348: _snwprintf (request.DeviceName, array_capacity (request.DeviceName), L"%hs", DriveConfig.DrivePartition.DevicePath.c_str()); ! 349: ! 350: CallDriver (TC_IOCTL_PROBE_REAL_DRIVE_SIZE, &request, sizeof (request), &request, sizeof (request)); ! 351: DriveConfig.DrivePartition.Info.PartitionLength = request.RealDriveSize; ! 352: ! 353: RealSystemDriveSizeValid = TRUE; ! 354: } ! 355: ! 356: ! 357: PartitionList BootEncryption::GetDrivePartitions (int driveNumber) ! 358: { ! 359: PartitionList partList; ! 360: ! 361: for (int partNumber = 0; partNumber < 64; ++partNumber) ! 362: { ! 363: stringstream partPath; ! 364: partPath << "\\Device\\Harddisk" << driveNumber << "\\Partition" << partNumber; ! 365: ! 366: DISK_PARTITION_INFO_STRUCT diskPartInfo; ! 367: _snwprintf (diskPartInfo.deviceName, array_capacity (diskPartInfo.deviceName), L"%hs", partPath.str().c_str()); ! 368: ! 369: try ! 370: { ! 371: CallDriver (TC_IOCTL_GET_DRIVE_PARTITION_INFO, &diskPartInfo, sizeof (diskPartInfo), &diskPartInfo, sizeof (diskPartInfo)); ! 372: } ! 373: catch (...) ! 374: { ! 375: continue; ! 376: } ! 377: ! 378: Partition part; ! 379: part.DevicePath = partPath.str(); ! 380: part.Number = partNumber; ! 381: part.Info = diskPartInfo.partInfo; ! 382: part.IsGPT = diskPartInfo.IsGPT; ! 383: ! 384: // Mount point ! 385: wstringstream ws; ! 386: ws << partPath.str().c_str(); ! 387: int driveNumber = GetDiskDeviceDriveLetter ((wchar_t *) ws.str().c_str()); ! 388: ! 389: if (driveNumber >= 0) ! 390: { ! 391: part.MountPoint += (char) (driveNumber + 'A'); ! 392: part.MountPoint += ":"; ! 393: } ! 394: partList.push_back (part); ! 395: } ! 396: ! 397: return partList; ! 398: } ! 399: ! 400: ! 401: DISK_GEOMETRY BootEncryption::GetDriveGeometry (int driveNumber) ! 402: { ! 403: stringstream devName; ! 404: devName << "\\Device\\Harddisk" << driveNumber << "\\Partition0"; ! 405: ! 406: DISK_GEOMETRY geometry; ! 407: throw_sys_if (!::GetDriveGeometry ((char *) devName.str().c_str(), &geometry)); ! 408: return geometry; ! 409: } ! 410: ! 411: ! 412: string BootEncryption::GetWindowsDirectory () ! 413: { ! 414: char buf[MAX_PATH]; ! 415: if (GetSystemDirectory (buf, sizeof (buf)) > 0) ! 416: return string (buf); ! 417: ! 418: return string(); ! 419: } ! 420: ! 421: ! 422: uint16 BootEncryption::GetInstalledBootLoaderVersion () ! 423: { ! 424: uint16 version; ! 425: CallDriver (TC_IOCTL_GET_BOOT_LOADER_VERSION, NULL, 0, &version, sizeof (version)); ! 426: return version; ! 427: } ! 428: ! 429: ! 430: BootEncryptionStatus BootEncryption::GetStatus () ! 431: { ! 432: /* IMPORTANT: Do NOT add any potentially time-consuming operations to this function. */ ! 433: ! 434: BootEncryptionStatus status; ! 435: CallDriver (TC_IOCTL_GET_BOOT_ENCRYPTION_STATUS, NULL, 0, &status, sizeof (status)); ! 436: return status; ! 437: } ! 438: ! 439: ! 440: void BootEncryption::GetVolumeProperties (VOLUME_PROPERTIES_STRUCT *properties) ! 441: { ! 442: if (properties == NULL) ! 443: throw ParameterIncorrect (SRC_POS); ! 444: ! 445: CallDriver (TC_IOCTL_GET_BOOT_DRIVE_VOLUME_PROPERTIES, NULL, 0, properties, sizeof (*properties)); ! 446: } ! 447: ! 448: ! 449: SystemDriveConfiguration BootEncryption::GetSystemDriveConfiguration () ! 450: { ! 451: if (DriveConfigValid) ! 452: return DriveConfig; ! 453: ! 454: SystemDriveConfiguration config; ! 455: ! 456: string winDir = GetWindowsDirectory(); ! 457: ! 458: // Scan all drives ! 459: for (int driveNumber = 0; driveNumber < 32; ++driveNumber) ! 460: { ! 461: bool windowsFound = false; ! 462: config.SystemLoaderPresent = false; ! 463: ! 464: PartitionList partitions = GetDrivePartitions (driveNumber); ! 465: foreach (const Partition &part, partitions) ! 466: { ! 467: if (_access ((part.MountPoint + "\\bootmgr").c_str(), 0) == 0 || _access ((part.MountPoint + "\\ntldr").c_str(), 0) == 0) ! 468: config.SystemLoaderPresent = true; ! 469: ! 470: if (!windowsFound && !part.MountPoint.empty() && winDir.find (part.MountPoint) == 0) ! 471: { ! 472: config.SystemPartition = part; ! 473: windowsFound = true; ! 474: } ! 475: } ! 476: ! 477: if (windowsFound) ! 478: { ! 479: config.DriveNumber = driveNumber; ! 480: ! 481: stringstream ss; ! 482: ss << "PhysicalDrive" << driveNumber; ! 483: config.DevicePath = ss.str(); ! 484: ! 485: config.DrivePartition = partitions.front(); ! 486: partitions.pop_front(); ! 487: config.Partitions = partitions; ! 488: ! 489: config.InitialUnallocatedSpace = 0x7fffFFFFffffFFFFull; ! 490: config.TotalUnallocatedSpace = config.DrivePartition.Info.PartitionLength.QuadPart; ! 491: ! 492: foreach (const Partition &part, config.Partitions) ! 493: { ! 494: if (part.Info.StartingOffset.QuadPart < config.InitialUnallocatedSpace) ! 495: config.InitialUnallocatedSpace = part.Info.StartingOffset.QuadPart; ! 496: ! 497: config.TotalUnallocatedSpace -= part.Info.PartitionLength.QuadPart; ! 498: } ! 499: ! 500: DriveConfig = config; ! 501: DriveConfigValid = TRUE; ! 502: return DriveConfig; ! 503: } ! 504: } ! 505: ! 506: throw ParameterIncorrect (SRC_POS); ! 507: } ! 508: ! 509: ! 510: bool BootEncryption::SystemPartitionCoversWholeDrive () ! 511: { ! 512: SystemDriveConfiguration config = GetSystemDriveConfiguration(); ! 513: ! 514: return config.Partitions.size() == 1 ! 515: && config.SystemPartition.Info.PartitionLength.QuadPart * 1000 / config.DrivePartition.Info.PartitionLength.QuadPart >= 995; ! 516: } ! 517: ! 518: ! 519: void BootEncryption::InstallBootLoader () ! 520: { ! 521: Device device (GetSystemDriveConfiguration().DevicePath); ! 522: DWORD size; ! 523: ! 524: // MBR ! 525: byte *bootSecImg = MapResource ("BIN", IDR_BOOT_SECTOR, &size); ! 526: if (!bootSecImg || size != SECTOR_SIZE) ! 527: throw ParameterIncorrect (SRC_POS); ! 528: ! 529: byte bootSecBuf[SECTOR_SIZE]; ! 530: ! 531: device.SeekAt (0); ! 532: device.Read (bootSecBuf, sizeof (bootSecBuf)); ! 533: ! 534: memcpy (bootSecBuf, bootSecImg, TC_MAX_MBR_BOOT_CODE_SIZE); ! 535: ! 536: device.SeekAt (0); ! 537: device.Write (bootSecBuf, size); ! 538: ! 539: byte bootSecVerificationBuf[SECTOR_SIZE]; ! 540: device.SeekAt (0); ! 541: device.Read (bootSecVerificationBuf, size); ! 542: ! 543: if (memcmp (bootSecBuf, bootSecVerificationBuf, size) != 0) ! 544: throw ErrorException ("ERROR_MBR_PROTECTED"); ! 545: ! 546: // Boot loader ! 547: byte bootLoaderBuf[TC_BOOT_VOLUME_HEADER_SECTOR_OFFSET - SECTOR_SIZE]; ! 548: byte *bootLoader = MapResource ("BIN", IDR_BOOT_LOADER, &size); ! 549: ! 550: if (!bootLoader || size > sizeof (bootLoaderBuf)) ! 551: throw ParameterIncorrect (SRC_POS); ! 552: ! 553: ZeroMemory (bootLoaderBuf, sizeof (bootLoaderBuf)); ! 554: memcpy (bootLoaderBuf, bootLoader, size); ! 555: ! 556: device.SeekAt (SECTOR_SIZE); ! 557: device.Write (bootLoaderBuf, sizeof (bootLoaderBuf)); ! 558: } ! 559: ! 560: ! 561: string BootEncryption::GetSystemLoaderBackupPath () ! 562: { ! 563: char pathBuf[MAX_PATH]; ! 564: ! 565: throw_sys_if (!SUCCEEDED (SHGetFolderPath (NULL, CSIDL_COMMON_APPDATA | CSIDL_FLAG_CREATE, NULL, 0, pathBuf))); ! 566: ! 567: string path = string (pathBuf) + "\\" TC_APP_NAME; ! 568: CreateDirectory (path.c_str(), NULL); ! 569: ! 570: return path + '\\' + TC_SYS_BOOT_LOADER_BACKUP_NAME; ! 571: } ! 572: ! 573: void BootEncryption::CreateRescueIsoImage (bool initialSetup, const string &isoImagePath) ! 574: { ! 575: BootEncryptionStatus encStatus = GetStatus(); ! 576: if (encStatus.SetupInProgress) ! 577: throw ParameterIncorrect (SRC_POS); ! 578: ! 579: Buffer imageBuf (RescueIsoImageSize); ! 580: ! 581: byte *image = imageBuf.Ptr(); ! 582: memset (image, 0, RescueIsoImageSize); ! 583: ! 584: // Primary volume descriptor ! 585: int offset = 0x8000; ! 586: ! 587: // Boot record volume descriptor ! 588: strcpy ((char *)image + 0x8801, "CD001\001EL TORITO SPECIFICATION"); ! 589: image[0x8800 + 0x47] = 0x19; ! 590: ! 591: // Validation entry ! 592: image[0xc800] = 1; ! 593: offset = 0xc800 + 0x1c; ! 594: image[offset++] = 0xaa; ! 595: image[offset++] = 0x55; ! 596: image[offset++] = 0x55; ! 597: image[offset] = 0xaa; ! 598: ! 599: // Initial entry ! 600: offset = 0xc820; ! 601: image[offset++] = 0x88; ! 602: image[offset++] = 2; ! 603: image[0xc820 + 6] = 1; ! 604: image[0xc820 + 8] = TC_CD_BOOT_LOADER_SECTOR; ! 605: ! 606: // TrueCrypt Boot Loader ! 607: DWORD size; ! 608: byte *bootSecResourceImg = MapResource ("BIN", IDR_BOOT_SECTOR, &size); ! 609: if (!bootSecResourceImg || size != SECTOR_SIZE) ! 610: throw ParameterIncorrect (SRC_POS); ! 611: ! 612: byte bootSecImg[SECTOR_SIZE]; ! 613: memcpy (bootSecImg, bootSecResourceImg, sizeof (bootSecImg)); ! 614: ! 615: bootSecImg[TC_BOOT_SECTOR_CONFIG_OFFSET] |= TC_BOOT_CFG_FLAG_RESCUE_DISK; ! 616: memcpy (image + TC_CD_BOOTSECTOR_OFFSET, bootSecImg, SECTOR_SIZE); ! 617: ! 618: byte *bootLoader = MapResource ("BIN", IDR_BOOT_LOADER, &size); ! 619: if (!bootLoader) ! 620: throw ParameterIncorrect (SRC_POS); ! 621: ! 622: memcpy (image + TC_CD_BOOTSECTOR_OFFSET + SECTOR_SIZE, bootLoader, size); ! 623: ! 624: // Volume header ! 625: if (initialSetup) ! 626: { ! 627: if (!RescueVolumeHeaderValid) ! 628: throw ParameterIncorrect (SRC_POS); ! 629: ! 630: memcpy (image + TC_CD_BOOTSECTOR_OFFSET + TC_BOOT_VOLUME_HEADER_SECTOR_OFFSET, RescueVolumeHeader, HEADER_SIZE); ! 631: } ! 632: else ! 633: { ! 634: Device bootDevice (GetSystemDriveConfiguration().DevicePath, true); ! 635: bootDevice.SeekAt (TC_BOOT_VOLUME_HEADER_SECTOR_OFFSET); ! 636: bootDevice.Read (image + TC_CD_BOOTSECTOR_OFFSET + TC_BOOT_VOLUME_HEADER_SECTOR_OFFSET, HEADER_SIZE); ! 637: } ! 638: ! 639: // Original system loader ! 640: try ! 641: { ! 642: File sysBakFile (GetSystemLoaderBackupPath(), true); ! 643: sysBakFile.Read (image + TC_CD_BOOTSECTOR_OFFSET + TC_ORIG_BOOT_LOADER_BACKUP_SECTOR_OFFSET, TC_BOOT_LOADER_AREA_SIZE); ! 644: ! 645: image[TC_CD_BOOTSECTOR_OFFSET + TC_BOOT_SECTOR_CONFIG_OFFSET] |= TC_BOOT_CFG_FLAG_RESCUE_DISK_ORIG_SYS_LOADER; ! 646: } ! 647: catch (Exception &e) ! 648: { ! 649: e.Show (ParentWindow); ! 650: Warning ("SYS_LOADER_UNAVAILABLE_FOR_RESCUE_DISK"); ! 651: } ! 652: ! 653: RescueIsoImage = new byte[RescueIsoImageSize]; ! 654: if (!RescueIsoImage) ! 655: throw bad_alloc(); ! 656: memcpy (RescueIsoImage, image, RescueIsoImageSize); ! 657: ! 658: if (!isoImagePath.empty()) ! 659: { ! 660: File isoFile (isoImagePath, false, true); ! 661: isoFile.Write (image, RescueIsoImageSize); ! 662: } ! 663: } ! 664: ! 665: ! 666: bool BootEncryption::VerifyRescueDisk () ! 667: { ! 668: if (!RescueIsoImage) ! 669: throw ParameterIncorrect (SRC_POS); ! 670: ! 671: for (char drive = 'Z'; drive >= 'D'; --drive) ! 672: { ! 673: try ! 674: { ! 675: string path = "X:"; ! 676: path[0] = drive; ! 677: ! 678: Device driveDevice (path, true); ! 679: size_t verifiedSectorCount = (TC_CD_BOOTSECTOR_OFFSET + TC_ORIG_BOOT_LOADER_BACKUP_SECTOR_OFFSET + TC_BOOT_LOADER_AREA_SIZE) / 2048; ! 680: Buffer buffer ((verifiedSectorCount + 1) * 2048); ! 681: ! 682: DWORD bytesRead = driveDevice.Read (buffer.Ptr(), buffer.Size()); ! 683: if (bytesRead != buffer.Size()) ! 684: continue; ! 685: ! 686: if (memcmp (buffer.Ptr(), RescueIsoImage, buffer.Size()) == 0) ! 687: return true; ! 688: } ! 689: catch (...) { } ! 690: } ! 691: ! 692: return false; ! 693: } ! 694: ! 695: ! 696: #ifndef SETUP ! 697: ! 698: void BootEncryption::CreateVolumeHeader (uint64 volumeSize, uint64 encryptedAreaStart, Password *password, int ea, int mode, int pkcs5) ! 699: { ! 700: PCRYPTO_INFO cryptoInfo = NULL; ! 701: ! 702: throw_sys_if (Randinit () != 0); ! 703: throw_sys_if (VolumeWriteHeader (TRUE, (char *) VolumeHeader, ea, mode, password, pkcs5, NULL, 0, &cryptoInfo, ! 704: volumeSize, 0, encryptedAreaStart, 0, FALSE) != 0); ! 705: ! 706: finally_do_arg (PCRYPTO_INFO*, &cryptoInfo, { crypto_close (*finally_arg); }); ! 707: ! 708: // Initial rescue disk assumes encryption of the drive has been completed (EncryptedAreaLength == volumeSize) ! 709: memcpy (RescueVolumeHeader, VolumeHeader, sizeof (RescueVolumeHeader)); ! 710: VolumeReadHeader (TRUE, (char *) RescueVolumeHeader, password, NULL, cryptoInfo); ! 711: ! 712: DecryptBuffer (RescueVolumeHeader + HEADER_ENCRYPTED_DATA_OFFSET, HEADER_ENCRYPTED_DATA_SIZE, cryptoInfo); ! 713: ! 714: if (GetHeaderField32 (RescueVolumeHeader, TC_HEADER_OFFSET_MAGIC) != 0x54525545) ! 715: throw ParameterIncorrect (SRC_POS); ! 716: ! 717: byte *fieldPos = RescueVolumeHeader + TC_HEADER_OFFSET_ENCRYPTED_AREA_LENGTH; ! 718: mputInt64 (fieldPos, volumeSize); ! 719: ! 720: EncryptBuffer (RescueVolumeHeader + HEADER_ENCRYPTED_DATA_OFFSET, HEADER_ENCRYPTED_DATA_SIZE, cryptoInfo); ! 721: ! 722: VolumeHeaderValid = true; ! 723: RescueVolumeHeaderValid = true; ! 724: } ! 725: ! 726: ! 727: void BootEncryption::InstallVolumeHeader () ! 728: { ! 729: if (!VolumeHeaderValid) ! 730: throw ParameterIncorrect (SRC_POS); ! 731: ! 732: Device device (GetSystemDriveConfiguration().DevicePath); ! 733: ! 734: device.SeekAt (TC_BOOT_VOLUME_HEADER_SECTOR_OFFSET); ! 735: device.Write ((byte *) VolumeHeader, sizeof (VolumeHeader)); ! 736: } ! 737: ! 738: ! 739: // For synchronous operations use AbortSetupWait() ! 740: void BootEncryption::AbortSetup () ! 741: { ! 742: CallDriver (TC_IOCTL_ABORT_BOOT_ENCRYPTION_SETUP); ! 743: } ! 744: ! 745: ! 746: // For asynchronous operations use AbortSetup() ! 747: void BootEncryption::AbortSetupWait () ! 748: { ! 749: CallDriver (TC_IOCTL_ABORT_BOOT_ENCRYPTION_SETUP); ! 750: ! 751: BootEncryptionStatus encStatus = GetStatus(); ! 752: ! 753: while (encStatus.SetupInProgress) ! 754: { ! 755: Sleep (TC_ABORT_TRANSFORM_WAIT_INTERVAL); ! 756: encStatus = GetStatus(); ! 757: } ! 758: } ! 759: ! 760: ! 761: void BootEncryption::BackupSystemLoader () ! 762: { ! 763: Device device (GetSystemDriveConfiguration().DevicePath, true); ! 764: ! 765: byte bootLoaderBuf[TC_BOOT_LOADER_AREA_SECTOR_COUNT * SECTOR_SIZE]; ! 766: ! 767: device.SeekAt (0); ! 768: device.Read (bootLoaderBuf, sizeof (bootLoaderBuf)); ! 769: ! 770: // Prevent TrueCrypt loader from being backed up ! 771: for (size_t i = 0; i < sizeof (bootLoaderBuf) - strlen (TC_APP_NAME); ++i) ! 772: { ! 773: if (memcmp (bootLoaderBuf + i, TC_APP_NAME, strlen (TC_APP_NAME)) == 0) ! 774: { ! 775: if (AskWarnNoYes ("TC_BOOT_LOADER_ALREADY_INSTALLED") == IDNO) ! 776: throw UserAbort (SRC_POS); ! 777: return; ! 778: } ! 779: } ! 780: ! 781: File backupFile (GetSystemLoaderBackupPath(), false, true); ! 782: backupFile.Write (bootLoaderBuf, sizeof (bootLoaderBuf)); ! 783: } ! 784: ! 785: ! 786: void BootEncryption::RestoreSystemLoader () ! 787: { ! 788: byte bootLoaderBuf[TC_BOOT_LOADER_AREA_SECTOR_COUNT * SECTOR_SIZE]; ! 789: ! 790: File backupFile (GetSystemLoaderBackupPath(), true); ! 791: ! 792: if (backupFile.Read (bootLoaderBuf, sizeof (bootLoaderBuf)) != sizeof (bootLoaderBuf)) ! 793: throw ParameterIncorrect (SRC_POS); ! 794: ! 795: Device device (GetSystemDriveConfiguration().DevicePath); ! 796: device.SeekAt (0); ! 797: device.Write (bootLoaderBuf, sizeof (bootLoaderBuf)); ! 798: } ! 799: ! 800: ! 801: void BootEncryption::RegisterFilterDriver (bool registerDriver) ! 802: { ! 803: if (!IsAdmin() && IsUacSupported()) ! 804: { ! 805: Elevator::RegisterFilterDriver (registerDriver); ! 806: return; ! 807: } ! 808: ! 809: HKEY classRegKey = SetupDiOpenClassRegKey (&GUID_DEVCLASS_DISKDRIVE, KEY_READ | KEY_WRITE); ! 810: throw_sys_if (classRegKey == INVALID_HANDLE_VALUE); ! 811: finally_do_arg (HKEY, classRegKey, { RegCloseKey (finally_arg); }); ! 812: ! 813: if (registerDriver) ! 814: { ! 815: // Place our filter in front of others already registered ! 816: size_t strSize = strlen ("truecrypt") + 1; ! 817: byte regKeyBuf[65536]; ! 818: DWORD size = sizeof (regKeyBuf) - strSize; ! 819: ! 820: // SetupInstallFromInfSection() does not support prepending of values so we have to modify the registry directly ! 821: strncpy ((char *) regKeyBuf, "truecrypt", sizeof (regKeyBuf)); ! 822: ! 823: if (RegQueryValueEx (classRegKey, "UpperFilters", NULL, NULL, regKeyBuf + strSize, &size) != ERROR_SUCCESS) ! 824: size = 1; ! 825: ! 826: throw_sys_if (RegSetValueEx (classRegKey, "UpperFilters", 0, REG_MULTI_SZ, regKeyBuf, strSize + size) != ERROR_SUCCESS); ! 827: } ! 828: else ! 829: { ! 830: // Deregister filter ! 831: char tempPath[MAX_PATH]; ! 832: GetTempPath (sizeof (tempPath), tempPath); ! 833: string infFileName = string (tempPath) + "\\truecrypt_filter.inf"; ! 834: ! 835: finally_do_arg (string, infFileName, { DeleteFile (finally_arg.c_str()); }); ! 836: File infFile (infFileName, false, true); ! 837: ! 838: string infTxt = "[truecrypt]\r\nDelReg=truecrypt_reg\r\n\r\n" ! 839: "[truecrypt_reg]\r\nHKR,,\"UpperFilters\",0x00018002,\"truecrypt\"\r\n"; ! 840: ! 841: infFile.Write ((byte *) infTxt.c_str(), infTxt.size()); ! 842: infFile.Close(); ! 843: ! 844: HINF hInf = SetupOpenInfFile (infFileName.c_str(), NULL, INF_STYLE_OLDNT | INF_STYLE_WIN4, NULL); ! 845: throw_sys_if (hInf == INVALID_HANDLE_VALUE); ! 846: finally_do_arg (HINF, hInf, { SetupCloseInfFile (finally_arg); }); ! 847: ! 848: throw_sys_if (!SetupInstallFromInfSection (ParentWindow, hInf, "truecrypt", SPINST_REGISTRY, classRegKey, NULL, 0, NULL, NULL, NULL, NULL)); ! 849: } ! 850: } ! 851: ! 852: ! 853: void BootEncryption::CheckRequirements () ! 854: { ! 855: if (nCurrentOS == WIN_2000) ! 856: throw ErrorException ("SYS_ENCRYPTION_UNSUPPORTED_ON_CURRENT_OS"); ! 857: ! 858: if (IsNonInstallMode()) ! 859: throw ErrorException ("FEATURE_REQUIRES_INSTALLATION"); ! 860: ! 861: SystemDriveConfiguration config = GetSystemDriveConfiguration (); ! 862: ! 863: if (config.SystemPartition.IsGPT) ! 864: throw ErrorException ("GPT_BOOT_DRIVE_UNSUPPORTED"); ! 865: ! 866: if (config.InitialUnallocatedSpace < TC_BOOT_LOADER_AREA_SIZE) ! 867: throw ErrorException ("NO_SPACE_FOR_BOOT_LOADER"); ! 868: ! 869: DISK_GEOMETRY geometry = GetDriveGeometry (config.DriveNumber); ! 870: ! 871: if (geometry.BytesPerSector != SECTOR_SIZE) ! 872: throw ErrorException ("LARGE_SECTOR_UNSUPPORTED"); ! 873: ! 874: if (geometry.SectorsPerTrack < 63) ! 875: throw ErrorException ("UNSUPPORTED_BOOT_DRIVE_GEOMETRY"); ! 876: ! 877: if (!config.SystemLoaderPresent) ! 878: throw ErrorException ("WINDOWS_NOT_ON_BOOT_DRIVE_ERROR"); ! 879: } ! 880: ! 881: ! 882: void BootEncryption::Deinstall () ! 883: { ! 884: BootEncryptionStatus encStatus = GetStatus(); ! 885: ! 886: if (encStatus.DriveEncrypted || encStatus.DriveMounted) ! 887: throw ParameterIncorrect (SRC_POS); ! 888: ! 889: SystemDriveConfiguration config = GetSystemDriveConfiguration (); ! 890: ! 891: if (encStatus.VolumeHeaderPresent) ! 892: { ! 893: // Verify CRC of header salt ! 894: Device device (config.DevicePath, true); ! 895: byte header[SECTOR_SIZE]; ! 896: ! 897: device.SeekAt (TC_BOOT_VOLUME_HEADER_SECTOR_OFFSET); ! 898: device.Read (header, sizeof (header)); ! 899: ! 900: if (encStatus.VolumeHeaderSaltCrc32 != GetCrc32 ((byte *) header, PKCS5_SALT_SIZE)) ! 901: throw ParameterIncorrect (SRC_POS); ! 902: } ! 903: ! 904: RegisterFilterDriver (false); ! 905: SetDriverServiceStartType (SERVICE_SYSTEM_START); ! 906: ! 907: try ! 908: { ! 909: RestoreSystemLoader (); ! 910: } ! 911: catch (Exception &e) ! 912: { ! 913: e.Show (ParentWindow); ! 914: throw ErrorException ("SYS_LOADER_RESTORE_FAILED"); ! 915: } ! 916: } ! 917: ! 918: ! 919: int BootEncryption::ChangePassword (Password *oldPassword, Password *newPassword, int pkcs5) ! 920: { ! 921: if (GetStatus().SetupInProgress) ! 922: throw ParameterIncorrect (SRC_POS); ! 923: ! 924: SystemDriveConfiguration config = GetSystemDriveConfiguration (); ! 925: ! 926: char header[HEADER_SIZE]; ! 927: Device device (config.DevicePath); ! 928: ! 929: // Only one algorithm is currently supported ! 930: if (pkcs5 != 0) ! 931: throw ParameterIncorrect (SRC_POS); ! 932: ! 933: device.SeekAt (TC_BOOT_VOLUME_HEADER_SECTOR_OFFSET); ! 934: device.Read ((byte *) header, sizeof (header)); ! 935: ! 936: PCRYPTO_INFO cryptoInfo = NULL; ! 937: ! 938: int status = VolumeReadHeader (TRUE, header, oldPassword, &cryptoInfo, NULL); ! 939: finally_do_arg (PCRYPTO_INFO, cryptoInfo, { if (finally_arg) crypto_close (finally_arg); }); ! 940: ! 941: if (status != 0) ! 942: { ! 943: handleError (ParentWindow, status); ! 944: return status; ! 945: } ! 946: ! 947: // Change the PKCS-5 PRF if requested by user ! 948: if (pkcs5 != 0) ! 949: cryptoInfo->pkcs5 = pkcs5; ! 950: ! 951: throw_sys_if (Randinit () != 0); ! 952: ! 953: /* The header will be re-encrypted PRAND_DISK_WIPE_PASSES times to prevent adversaries from using ! 954: techniques such as magnetic force microscopy or magnetic force scanning tunnelling microscopy ! 955: to recover the overwritten header. According to Peter Gutmann, data should be overwritten 22 ! 956: times (ideally, 35 times) using non-random patterns and pseudorandom data. However, as users might ! 957: impatiently interupt the process (etc.) we will not use the Gutmann's patterns but will write the ! 958: valid re-encrypted header, i.e. pseudorandom data, and there will be many more passes than Guttman ! 959: recommends. During each pass we will write a valid working header. Each pass will use the same master ! 960: key, and also the same header key, secondary key (XTS), etc., derived from the new password. The only ! 961: item that will be different for each pass will be the salt. This is sufficient to cause each "version" ! 962: of the header to differ substantially and in a random manner from the versions written during the ! 963: other passes. */ ! 964: ! 965: bool headerUpdated = false; ! 966: int result = ERR_SUCCESS; ! 967: ! 968: try ! 969: { ! 970: for (int wipePass = 0; wipePass < PRAND_DISK_WIPE_PASSES; wipePass++) ! 971: { ! 972: PCRYPTO_INFO tmpCryptoInfo = NULL; ! 973: ! 974: status = VolumeWriteHeader (TRUE, ! 975: header, ! 976: cryptoInfo->ea, ! 977: cryptoInfo->mode, ! 978: newPassword, ! 979: cryptoInfo->pkcs5, ! 980: (char *) cryptoInfo->master_keydata, ! 981: cryptoInfo->volume_creation_time, ! 982: &tmpCryptoInfo, ! 983: cryptoInfo->VolumeSize.Value, ! 984: cryptoInfo->hiddenVolumeSize, ! 985: cryptoInfo->EncryptedAreaStart.Value, ! 986: cryptoInfo->EncryptedAreaLength.Value, ! 987: wipePass < PRAND_DISK_WIPE_PASSES - 1); ! 988: ! 989: if (tmpCryptoInfo) ! 990: crypto_close (tmpCryptoInfo); ! 991: ! 992: if (status != 0) ! 993: { ! 994: handleError (ParentWindow, status); ! 995: return status; ! 996: } ! 997: ! 998: device.SeekAt (TC_BOOT_VOLUME_HEADER_SECTOR_OFFSET); ! 999: device.Write ((byte *) header, sizeof (header)); ! 1000: headerUpdated = true; ! 1001: } ! 1002: } ! 1003: catch (Exception &e) ! 1004: { ! 1005: e.Show (ParentWindow); ! 1006: result = ERR_OS_ERROR; ! 1007: } ! 1008: ! 1009: if (headerUpdated) ! 1010: { ! 1011: ReopenBootVolumeHeaderRequest reopenRequest; ! 1012: reopenRequest.VolumePassword = *newPassword; ! 1013: finally_do_arg (ReopenBootVolumeHeaderRequest*, &reopenRequest, { burn (finally_arg, sizeof (*finally_arg)); }); ! 1014: ! 1015: CallDriver (TC_IOCTL_REOPEN_BOOT_VOLUME_HEADER, &reopenRequest, sizeof (reopenRequest)); ! 1016: } ! 1017: ! 1018: return result; ! 1019: } ! 1020: ! 1021: ! 1022: void BootEncryption::CheckEncryptionSetupResult () ! 1023: { ! 1024: CallDriver (TC_IOCTL_GET_BOOT_ENCRYPTION_SETUP_RESULT); ! 1025: } ! 1026: ! 1027: ! 1028: void BootEncryption::Install () ! 1029: { ! 1030: BootEncryptionStatus encStatus = GetStatus(); ! 1031: if (encStatus.DriveMounted) ! 1032: throw ParameterIncorrect (SRC_POS); ! 1033: ! 1034: try ! 1035: { ! 1036: InstallBootLoader (); ! 1037: InstallVolumeHeader (); ! 1038: ! 1039: SetDriverServiceStartType (SERVICE_BOOT_START); ! 1040: ! 1041: try ! 1042: { ! 1043: RegisterFilterDriver (false); ! 1044: } ! 1045: catch (...) { } ! 1046: ! 1047: RegisterFilterDriver (true); ! 1048: } ! 1049: catch (Exception &) ! 1050: { ! 1051: try ! 1052: { ! 1053: RestoreSystemLoader (); ! 1054: } ! 1055: catch (Exception &e) ! 1056: { ! 1057: e.Show (ParentWindow); ! 1058: } ! 1059: ! 1060: throw; ! 1061: } ! 1062: } ! 1063: ! 1064: ! 1065: void BootEncryption::PrepareInstallation (bool systemPartitionOnly, Password &password, int ea, int mode, int pkcs5, const string &rescueIsoImagePath) ! 1066: { ! 1067: if (!systemPartitionOnly && !RealSystemDriveSizeValid) ! 1068: ProbeRealSystemDriveSize(); ! 1069: ! 1070: BootEncryptionStatus encStatus = GetStatus(); ! 1071: if (encStatus.DriveMounted) ! 1072: throw ParameterIncorrect (SRC_POS); ! 1073: ! 1074: CheckRequirements (); ! 1075: ! 1076: SystemDriveConfiguration config = GetSystemDriveConfiguration(); ! 1077: BackupSystemLoader (); ! 1078: ! 1079: uint64 volumeSize; ! 1080: uint64 encryptedAreaStart; ! 1081: ! 1082: if (systemPartitionOnly) ! 1083: { ! 1084: volumeSize = config.SystemPartition.Info.PartitionLength.QuadPart; ! 1085: encryptedAreaStart = config.SystemPartition.Info.StartingOffset.QuadPart; ! 1086: } ! 1087: else ! 1088: { ! 1089: volumeSize = config.DrivePartition.Info.PartitionLength.QuadPart - TC_BOOT_LOADER_AREA_SIZE; ! 1090: encryptedAreaStart = config.DrivePartition.Info.StartingOffset.QuadPart + TC_BOOT_LOADER_AREA_SIZE; ! 1091: } ! 1092: ! 1093: CreateVolumeHeader (volumeSize, encryptedAreaStart, &password, ea, mode, pkcs5); ! 1094: ! 1095: if (!rescueIsoImagePath.empty()) ! 1096: CreateRescueIsoImage (true, rescueIsoImagePath); ! 1097: } ! 1098: ! 1099: ! 1100: void BootEncryption::StartDecryption () ! 1101: { ! 1102: BootEncryptionStatus encStatus = GetStatus(); ! 1103: ! 1104: if (!encStatus.DeviceFilterActive || !encStatus.DriveMounted || encStatus.SetupInProgress) ! 1105: throw ParameterIncorrect (SRC_POS); ! 1106: ! 1107: BootEncryptionSetupRequest request; ! 1108: ZeroMemory (&request, sizeof (request)); ! 1109: ! 1110: request.SetupMode = SetupDecryption; ! 1111: ! 1112: CallDriver (TC_IOCTL_BOOT_ENCRYPTION_SETUP, &request, sizeof (request), NULL, 0); ! 1113: } ! 1114: ! 1115: ! 1116: void BootEncryption::StartEncryption (WipeAlgorithmId wipeAlgorithm) ! 1117: { ! 1118: BootEncryptionStatus encStatus = GetStatus(); ! 1119: ! 1120: if (!encStatus.DeviceFilterActive || !encStatus.DriveMounted || encStatus.SetupInProgress) ! 1121: throw ParameterIncorrect (SRC_POS); ! 1122: ! 1123: BootEncryptionSetupRequest request; ! 1124: ZeroMemory (&request, sizeof (request)); ! 1125: ! 1126: request.SetupMode = SetupEncryption; ! 1127: request.WipeAlgorithm = wipeAlgorithm; ! 1128: ! 1129: CallDriver (TC_IOCTL_BOOT_ENCRYPTION_SETUP, &request, sizeof (request), NULL, 0); ! 1130: } ! 1131: ! 1132: ! 1133: bool BootEncryption::RestartComputer (void) ! 1134: { ! 1135: TOKEN_PRIVILEGES tokenPrivil; ! 1136: HANDLE hTkn; ! 1137: ! 1138: if (!OpenProcessToken (GetCurrentProcess (), TOKEN_QUERY|TOKEN_ADJUST_PRIVILEGES, &hTkn)) ! 1139: { ! 1140: return false; ! 1141: } ! 1142: ! 1143: LookupPrivilegeValue (NULL, SE_SHUTDOWN_NAME, &tokenPrivil.Privileges[0].Luid); ! 1144: tokenPrivil.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; ! 1145: tokenPrivil.PrivilegeCount = 1; ! 1146: ! 1147: AdjustTokenPrivileges (hTkn, false, &tokenPrivil, 0, (PTOKEN_PRIVILEGES) NULL, 0); ! 1148: if (GetLastError() != ERROR_SUCCESS) ! 1149: return false; ! 1150: ! 1151: if (!ExitWindowsEx (EWX_REBOOT | EWX_FORCE, ! 1152: SHTDN_REASON_MAJOR_OTHER | SHTDN_REASON_MINOR_OTHER | SHTDN_REASON_FLAG_PLANNED)) ! 1153: return false; ! 1154: ! 1155: return true; ! 1156: } ! 1157: ! 1158: ! 1159: #endif // !SETUP ! 1160: ! 1161: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.