Annotation of truecrypt/common/format.c, revision 1.1.1.3

1.1.1.3 ! root        1: /* The source code contained in this file has been derived from the source code
        !             2:    of Encryption for the Masses 2.02a by Paul Le Roux. Modifications and
        !             3:    additions to that source code contained in this file are Copyright (c) 2004
        !             4:    TrueCrypt Team and Copyright (c) 2004 TrueCrypt Foundation. Unmodified
        !             5:    parts are Copyright (c) 1998-99 Paul Le Roux. This is a TrueCrypt Foundation
        !             6:    release. Please see the file license.txt for full license details. */
1.1       root        7: 
                      8: #include "TCdefs.h"
                      9: 
                     10: #include "crypto.h"
                     11: #include "fat.h"
                     12: #include "format.h"
                     13: #include "volumes.h"
                     14: #include "progress.h"
                     15: #include "apidrvr.h"
                     16: #include "dlgcode.h"
                     17: 
1.1.1.3 ! root       18: 
        !            19: static int GetAvailableDrive ()
        !            20: {
        !            21:        DWORD dwUsedDrives = GetLogicalDrives();
        !            22:        int i;
        !            23: 
        !            24:        for (i = 25; i > 2; i--)
        !            25:        {
        !            26:                if (!(dwUsedDrives & 1 << i))
        !            27:                        return i;
        !            28:        }
        !            29: 
        !            30:        return -1;
        !            31: }
        !            32: 
        !            33: static BOOL MountVolume (HWND hwndDlg, int driveNo, char *volumePath, char *szPassword)
        !            34: {
        !            35:        extern HANDLE hDriver;
        !            36: 
        !            37:        MOUNT_STRUCT driver;
        !            38:        DWORD dwResult;
        !            39:        BOOL bResult, bDevice;
        !            40: 
        !            41:        VirtualLock (&driver, sizeof (driver));
        !            42: 
        !            43:        driver.nDosDriveNo = driveNo;
        !            44:        driver.bCache = 0;
        !            45:        driver.time = 0;
        !            46:        driver.nPasswordLen = strlen (szPassword);
        !            47:        strcpy (driver.szPassword, szPassword);
        !            48: 
        !            49:        CreateFullVolumePath ((char *) driver.wszVolume, volumePath, &bDevice);
        !            50:        ToUNICODE ((char *) driver.wszVolume);
        !            51: 
        !            52:        bResult = DeviceIoControl (hDriver, MOUNT, &driver,
        !            53:                sizeof (driver), &driver, sizeof (driver), &dwResult, NULL);
        !            54: 
        !            55:        burn (&driver.szPassword, sizeof (driver.szPassword));
        !            56: 
        !            57:        VirtualUnlock (&driver, sizeof (driver));
        !            58: 
        !            59:        if (bResult == FALSE)
        !            60:        {
        !            61:                handleWin32Error (hwndDlg);
        !            62:                return FALSE;
        !            63:        }
        !            64:        else
        !            65:        {
        !            66:                if (driver.nReturnCode == 0)
        !            67:                {
        !            68:                        if (nCurrentOS == WIN_NT)
        !            69:                        {
        !            70:                                char *lpszPipeName = "\\\\.\\pipe\\truecryptservice";
        !            71:                                DWORD bytesRead;
        !            72:                                char inbuf[80];
        !            73:                                char outbuf[80];
        !            74: 
        !            75:                                sprintf (outbuf, "mount %d", driver.nDosDriveNo);
        !            76: 
        !            77:                                bResult = CallNamedPipe (lpszPipeName,
        !            78:                                        outbuf, sizeof (outbuf),
        !            79:                                        inbuf, sizeof (inbuf),
        !            80:                                        &bytesRead, NMPWAIT_WAIT_FOREVER);
        !            81: 
        !            82:                                if (bResult == FALSE)
        !            83:                                {
        !            84:                                        handleWin32Error (hwndDlg);
        !            85:                                }
        !            86:                                else
        !            87:                                {
        !            88:                                        DWORD os_err = 0;
        !            89:                                        int err = 0;
        !            90: 
        !            91:                                        sscanf (inbuf, "%s %d %lu", outbuf, &err, &os_err);
        !            92: 
        !            93:                                        if (*inbuf == '-')
        !            94:                                        {
        !            95:                                                if (err == ERR_OS_ERROR)
        !            96:                                                {
        !            97:                                                        SetLastError (os_err);
        !            98:                                                        handleWin32Error (hwndDlg);
        !            99:                                                }
        !           100:                                                else
        !           101:                                                {
        !           102:                                                        handleError (hwndDlg, err);
        !           103:                                                }
        !           104: 
        !           105:                                                bResult = FALSE;
        !           106:                                        }
        !           107:                                }
        !           108:                                return bResult;
        !           109:                        }
        !           110:                }
        !           111:                else
        !           112:                {
        !           113:                        handleError (hwndDlg, driver.nReturnCode);
        !           114:                        return FALSE;
        !           115:                }
        !           116:        }
        !           117: 
        !           118:        return TRUE;
        !           119: }
        !           120: 
1.1       root      121: int
                    122: FormatVolume (char *lpszFilename,
                    123:              BOOL bDevice,
1.1.1.3 ! root      124:                  char *volumePath,
1.1       root      125:              unsigned __int64 size,
                    126:              char *lpszPassword,
                    127:              int cipher,
                    128:              int pkcs5,
                    129:                  BOOL quickFormat,
1.1.1.3 ! root      130:                  int fileSystem,
        !           131:                  int clusterSize,
        !           132:                  char * summaryMsg,
1.1       root      133:              HWND hwndDlg)
                    134: {
                    135:        int nStatus;
                    136:        PCRYPTO_INFO cryptoInfo;
                    137:        void *dev = INVALID_HANDLE_VALUE;
                    138:        OPEN_TEST_STRUCT driver;
                    139:        DISKIO_STRUCT win9x_r0;
1.1.1.3 ! root      140:        DWORD dwError, dwThen, dwNow;
1.1       root      141:        diskio_f write;
1.1.1.3 ! root      142:        char header[SECTOR_SIZE];
        !           143:        __int64 num_sectors;
        !           144:        fatparams ft;
        !           145:        
        !           146:        size -= SECTOR_SIZE;    // less the first TC sector
        !           147:        num_sectors = size / SECTOR_SIZE;
1.1       root      148: 
1.1.1.3 ! root      149:        if (fileSystem == FILESYS_FAT)
1.1       root      150:        {
1.1.1.3 ! root      151:                if (num_sectors > 0xFFFFffff)
        !           152:                        return ERR_VOL_SIZE_WRONG;
1.1       root      153: 
1.1.1.3 ! root      154:                ft.num_sectors = (unsigned int) (num_sectors);
        !           155:                ft.cluster_size = clusterSize;
        !           156:                memcpy (ft.volume_name, "           ", 11);
        !           157:                /* Calculate the fats, root dir etc, and update ft */
        !           158:                GetFatParams (&ft);
1.1       root      159:        }
                    160: 
1.1.1.3 ! root      161:        VirtualLock (header, sizeof (header));
1.1       root      162: 
1.1.1.3 ! root      163:        /* Copies any header structures into header, but does not do any
1.1       root      164:           disk io */
1.1.1.3 ! root      165:        nStatus = VolumeWriteHeader (header,
1.1       root      166:                                     cipher,
                    167:                                     lpszPassword,
                    168:                                     pkcs5,
                    169:                                         0,
                    170:                                         0,
                    171:                                     &cryptoInfo);
                    172: 
                    173:        if (nStatus != 0)
1.1.1.3 ! root      174:        {
        !           175:                burn (header, sizeof (header));
        !           176:                VirtualUnlock (header, sizeof (header));
1.1       root      177:                return nStatus;
1.1.1.3 ! root      178:        }
        !           179: 
        !           180:        write = (diskio_f) _lwrite;
        !           181: 
        !           182:        if (bDevice == TRUE)
        !           183:        {
        !           184:                dev = CreateFile (lpszFilename, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
        !           185:        }
        !           186:        else
        !           187:        {
        !           188:                /* We could support FILE_ATTRIBUTE_HIDDEN as an
        !           189:                option! */
        !           190:                dev = CreateFile (lpszFilename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
        !           191:        }
        !           192: 
        !           193:        if (dev == INVALID_HANDLE_VALUE)
        !           194:        {
        !           195:                return ERR_OS_ERROR;
        !           196:        }
1.1       root      197: 
                    198:        KillTimer (hwndDlg, 0xff);
                    199: 
1.1.1.3 ! root      200:        InitProgressBar (num_sectors);
        !           201:        dwThen = GetTickCount ();
1.1.1.2   root      202: 
1.1.1.3 ! root      203:        switch (fileSystem)
        !           204:        {
        !           205:        case FILESYS_NONE:
        !           206:        case FILESYS_NTFS:
        !           207:                nStatus = FormatNoFs (num_sectors, header, (HFILE) dev, cryptoInfo, 1000, write, bDevice==TRUE ? quickFormat:FALSE);
        !           208:                break;
        !           209: 
        !           210:        case FILESYS_FAT:
        !           211:                /* This does the disk io, both copying out the header, init the
        !           212:                sectors, and writing the FAT tables etc */
        !           213:                nStatus = FormatFat (&ft, header, (HFILE) dev, cryptoInfo, 1000, write, bDevice==TRUE ? quickFormat:FALSE);
        !           214:                break;
        !           215:        }
1.1       root      216: 
1.1.1.3 ! root      217:        dwNow = GetTickCount ();
        !           218: 
        !           219:        burn (header, sizeof (header));
        !           220:        VirtualUnlock (header, sizeof (header));
1.1       root      221: 
                    222:        crypto_close (cryptoInfo);
1.1.1.3 ! root      223:        CloseHandle (dev);
1.1       root      224: 
1.1.1.3 ! root      225:        dwError = GetLastError();
1.1       root      226: 
                    227:        if (nStatus!=0)
                    228:                SetLastError(dwError);
1.1.1.3 ! root      229:        else
        !           230:        {
        !           231:                switch (fileSystem)
        !           232:                {
        !           233:                case FILESYS_NONE:
        !           234:                        sprintf (summaryMsg, "Volume size:\t\t%I64d sectors (%I64d MB)\nFile system:\t\tNone"
        !           235:                                "\n\nFormatting took %lu seconds."
        !           236:                                , num_sectors, num_sectors*512/1024/1024
        !           237:                                , (dwNow - dwThen)/1000);
        !           238:                        break;
        !           239: 
        !           240:                case FILESYS_FAT:
        !           241:                        sprintf (summaryMsg, 
        !           242:                                "Volume size:\t\t%d sectors (%I64d MB)\nFile system:\t\tFAT%d\n"
        !           243:                                "FAT size:\t\t%d bytes\nCluster size:\t\t%d bytes\nClusters available:\t%d"
        !           244:                                "\n\nFormatting took %lu seconds."
        !           245:                                , ft.num_sectors, ((__int64) ft.num_sectors*512)/1024/1024, ft.size_fat
        !           246:                                , (int) (512*ft.fats*ft.fat_length),
        !           247:                                (int) (512*ft.cluster_size), ft.cluster_count,
        !           248:                                (dwNow - dwThen)/1000);
        !           249:                        break;
        !           250: 
        !           251:                case FILESYS_NTFS:
        !           252:                        {
        !           253:                                int driveNo = GetAvailableDrive ();
        !           254:                                DWORD os_error;
        !           255:                                int err;
        !           256: 
        !           257:                                if (driveNo == -1)
        !           258:                                {
        !           259:                                        MessageBox (hwndDlg, "No free drives available. NTFS formatting cannot continue.", lpszTitle, ICON_HAND);
        !           260:                                        return ERR_NO_FREE_DRIVES;
        !           261:                                }
        !           262: 
        !           263:                                if (!MountVolume (hwndDlg, driveNo, volumePath, lpszPassword))
        !           264:                                {
        !           265:                                        MessageBox (hwndDlg, "Cannot mount volume. NTFS formatting cannot continue.", lpszTitle, ICON_HAND);
        !           266:                                        return ERR_VOL_MOUNT_FAILED;
        !           267:                                }
        !           268: 
        !           269:                                if (!FormatNtfs (driveNo, clusterSize))
        !           270:                                {
        !           271:                                        MessageBox (hwndDlg, "NTFS formatting failed. Try using FAT filesystem.", lpszTitle, MB_ICONERROR);
        !           272:                                        UnmountVolume (driveNo, &os_error, &err);
        !           273:                                        return ERR_VOL_FORMAT_BAD;
        !           274:                                }
        !           275: 
        !           276:                                UnmountVolume (driveNo, &os_error, &err);
        !           277: 
        !           278:                                dwNow = GetTickCount ();
        !           279: 
        !           280:                                sprintf (summaryMsg, "Volume size:\t\t%I64d sectors (%I64d MB)\nFile system:\t\tNTFS"
        !           281:                                        "\n\nFormatting took %lu seconds."
        !           282:                                        , num_sectors, num_sectors*512/1024/1024
        !           283:                                        , (dwNow - dwThen)/1000);
        !           284: 
        !           285:                                break;
        !           286:                        }
        !           287:                }
        !           288:        }
        !           289: 
        !           290:        NormalCursor ();
        !           291: 
1.1       root      292:        return nStatus;
1.1.1.3 ! root      293: }
1.1       root      294: 
1.1.1.3 ! root      295: 
        !           296: int FormatNoFs (__int64 num_sectors, char *header, HFILE dev, PCRYPTO_INFO cryptoInfo, int nFrequency, diskio_f write, BOOL quickFormat)
        !           297: {
        !           298:        int write_buf_cnt = 0;
        !           299:        char sector[SECTOR_SIZE], *write_buf;
        !           300:        int progress = 0;
        !           301:        unsigned __int64 nSecNo = 1;
        !           302: 
        !           303:        if ((*write) (dev, header, SECTOR_SIZE) == HFILE_ERROR)
        !           304:                return ERR_OS_ERROR;
        !           305: 
        !           306:        write_buf = TCalloc (WRITE_BUF_SIZE);
        !           307: 
        !           308:        memset (sector, 0, sizeof (sector));
        !           309: 
        !           310:        /* write data area */
        !           311:        if(!quickFormat)
        !           312:        {
        !           313:                while (num_sectors--)
        !           314:                {
        !           315:                        if (WriteSector (dev, sector, write_buf, &write_buf_cnt, &nSecNo, &progress,
        !           316:                                cryptoInfo, nFrequency, write) == FALSE)
        !           317:                                goto fail;
        !           318:                }
        !           319:                if (write_buf_cnt != 0 && (*write) (dev, write_buf, write_buf_cnt) == HFILE_ERROR)
        !           320:                        goto fail;
        !           321:        }
        !           322:        else
        !           323:                nSecNo = num_sectors;
        !           324: 
        !           325:        UpdateProgressBar (nSecNo);
        !           326: 
        !           327:        TCfree (write_buf);
        !           328:        return 0;
        !           329: 
        !           330: fail:
        !           331: 
        !           332:        TCfree (write_buf);
        !           333:        return ERR_OS_ERROR;
1.1       root      334: }
1.1.1.3 ! root      335: 
        !           336: 
        !           337: volatile BOOLEAN FormatExResult;
        !           338: 
        !           339: BOOLEAN __stdcall FormatExCallback (int command, DWORD subCommand, PVOID parameter)
        !           340: {
        !           341:        if (command == FMIFS_DONE)
        !           342:                FormatExResult = *(BOOLEAN *) parameter;
        !           343:        return TRUE;
        !           344: }
        !           345: 
        !           346: BOOL FormatNtfs (int driveNo, int clusterSize)
        !           347: {
        !           348:        WCHAR dir[8] = { driveNo + 'A', 0 };
        !           349:        PFORMATEX FormatEx;
        !           350:        HMODULE hModule = LoadLibrary ("fmifs.dll");
        !           351: 
        !           352:        if (hModule == NULL)
        !           353:                return FALSE;
        !           354: 
        !           355:        if (!(FormatEx = (void *) GetProcAddress (GetModuleHandle("fmifs.dll"), "FormatEx")))
        !           356:        {
        !           357:                FreeLibrary (hModule);
        !           358:                return FALSE;
        !           359:        }
        !           360: 
        !           361:        wcscat (dir, L":\\");
        !           362: 
        !           363:        FormatExResult = FALSE;
        !           364: 
        !           365:        if (*(char *)dir > 'C' && *(char *)dir <= 'Z')
        !           366:                FormatEx (dir, FMIFS_HARDDISK, L"NTFS", L"", TRUE, clusterSize * 512, FormatExCallback);
        !           367: 
        !           368:        FreeLibrary (hModule);
        !           369:        return FormatExResult;
        !           370: }
        !           371: 
        !           372: BOOL
        !           373: WriteSector (HFILE dev, char *sector,
        !           374:             char *write_buf, int *write_buf_cnt,
        !           375:             __int64 *nSecNo, int *progress, PCRYPTO_INFO cryptoInfo,
        !           376:             int nFrequency, diskio_f write)
        !           377: {
        !           378:        (*cryptoInfo->encrypt_sector) ((unsigned long *) sector,
        !           379:        (*nSecNo)++, 1, cryptoInfo->ks, cryptoInfo->iv, cryptoInfo->cipher);
        !           380:        memcpy (write_buf + *write_buf_cnt, sector, SECTOR_SIZE);
        !           381:        (*write_buf_cnt) += SECTOR_SIZE;
        !           382: 
        !           383: 
        !           384:        if (*write_buf_cnt == WRITE_BUF_SIZE)
        !           385:        {
        !           386:                if ((*write) (dev, write_buf, WRITE_BUF_SIZE) == HFILE_ERROR)
        !           387:                        return FALSE;
        !           388:                else
        !           389:                        *write_buf_cnt = 0;
        !           390:        }
        !           391: 
        !           392:        if (++(*progress) == nFrequency)
        !           393:        {
        !           394:                if (UpdateProgressBar (*nSecNo) == TRUE)
        !           395:                        return FALSE;
        !           396:                *progress = 0;
        !           397:        }
        !           398: 
        !           399:        return TRUE;
        !           400: 
        !           401: }
        !           402: 
        !           403: 
        !           404: 

unix.superglobalmegacorp.com

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