Annotation of truecrypt/common/bootencryption.cpp, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.