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

1.1.1.6   root        1: /* Legal Notice: The source code contained in this file has been derived from
                      2:    the source code of Encryption for the Masses 2.02a, which is Copyright (c)
                      3:    1998-99 Paul Le Roux and which is covered by the 'License Agreement for
                      4:    Encryption for the Masses'. Modifications and additions to that source code
                      5:    contained in this file are Copyright (c) 2004-2005 TrueCrypt Foundation and
                      6:    Copyright (c) 2004 TrueCrypt Team, and are covered by TrueCrypt License 2.0
                      7:    the full text of which is contained in the file License.txt included in
                      8:    TrueCrypt binary and source code distribution archives.  */
                      9: 
                     10: #include "Tcdefs.h"
                     11: 
                     12: #include "Crypto.h"
                     13: #include "Fat.h"
                     14: #include "Format.h"
                     15: #include "Volumes.h"
                     16: #include "Progress.h"
                     17: #include "Apidrvr.h"
                     18: #include "Dlgcode.h"
                     19: #include "Language.h"
                     20: #include "Resource.h"
                     21: #include "Common.h"
                     22: #include "Random.h"
1.1.1.3   root       23: 
1.1       root       24: int
                     25: FormatVolume (char *lpszFilename,
                     26:              BOOL bDevice,
1.1.1.3   root       27:                  char *volumePath,
1.1       root       28:              unsigned __int64 size,
1.1.1.4   root       29:                  unsigned __int64 hiddenVolHostSize,
1.1.1.6   root       30:              Password *password,
1.1.1.7 ! root       31:              int ea,
1.1       root       32:              int pkcs5,
                     33:                  BOOL quickFormat,
1.1.1.3   root       34:                  int fileSystem,
                     35:                  int clusterSize,
1.1.1.6   root       36:                  wchar_t *summaryMsg,
1.1.1.4   root       37:              HWND hwndDlg,
                     38:                  BOOL hiddenVol,
                     39:                  int *realClusterSize)
1.1       root       40: {
                     41:        int nStatus;
                     42:        PCRYPTO_INFO cryptoInfo;
1.1.1.4   root       43:        HANDLE dev = INVALID_HANDLE_VALUE;
1.1.1.3   root       44:        DWORD dwError, dwThen, dwNow;
1.1       root       45:        diskio_f write;
1.1.1.3   root       46:        char header[SECTOR_SIZE];
1.1.1.4   root       47:        unsigned __int64 num_sectors, startSector;
1.1.1.3   root       48:        fatparams ft;
1.1.1.4   root       49:        FILETIME ftCreationTime;
                     50:        FILETIME ftLastWriteTime;
                     51:        FILETIME ftLastAccessTime;
                     52:        BOOL bTimeStampValid = FALSE;
1.1.1.3   root       53:        
1.1.1.4   root       54:        if (!hiddenVol)
                     55:                size -= HEADER_SIZE;    
1.1       root       56: 
1.1.1.4   root       57:        num_sectors = size / SECTOR_SIZE;
1.1.1.3   root       58:        VirtualLock (header, sizeof (header));
1.1       root       59: 
1.1.1.3   root       60:        /* Copies any header structures into header, but does not do any
1.1       root       61:           disk io */
1.1.1.3   root       62:        nStatus = VolumeWriteHeader (header,
1.1.1.7 ! root       63:                                     ea,
        !            64:                                         LRW, // The only supported mode of operation when creating new volumes
1.1.1.6   root       65:                                     password,
1.1       root       66:                                     pkcs5,
                     67:                                         0,
                     68:                                         0,
1.1.1.4   root       69:                                     &cryptoInfo,
1.1.1.6   root       70:                                         hiddenVol ? size : 0,
                     71:                                         FALSE);
1.1       root       72: 
                     73:        if (nStatus != 0)
1.1.1.3   root       74:        {
                     75:                burn (header, sizeof (header));
                     76:                VirtualUnlock (header, sizeof (header));
1.1       root       77:                return nStatus;
1.1.1.3   root       78:        }
                     79: 
                     80:        write = (diskio_f) _lwrite;
                     81: 
1.1.1.6   root       82:        if (bDevice)
1.1.1.3   root       83:        {
                     84:                dev = CreateFile (lpszFilename, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
1.1.1.4   root       85:                if (dev == INVALID_HANDLE_VALUE)
                     86:                {
1.1.1.7 ! root       87:                        // Try opening the device in shared mode
1.1.1.4   root       88:                        dev = CreateFile (lpszFilename, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
                     89:                        if (dev != INVALID_HANDLE_VALUE)
                     90:                        {
1.1.1.6   root       91:                                if (IDNO == MessageBoxW (hwndDlg, GetString ("DEVICE_IN_USE_FORMAT"), lpszTitle, MB_YESNO|MB_ICONWARNING|MB_DEFBUTTON2))
1.1.1.4   root       92:                                {
                     93:                                        CloseHandle (dev);
                     94:                                        dev = INVALID_HANDLE_VALUE;
                     95:                                }
                     96:                        }
                     97:                }
1.1.1.3   root       98:        }
                     99:        else
                    100:        {
1.1.1.4   root      101:                // We could support FILE_ATTRIBUTE_HIDDEN as an option
                    102:                // (Now if the container has hidden or system file attribute, the OS will not allow
                    103:                // overwritting it; so the user will have to delete it manually).
                    104:                dev = CreateFile (lpszFilename, GENERIC_WRITE,
                    105:                        hiddenVol ? (FILE_SHARE_READ | FILE_SHARE_WRITE) : 0,
                    106:                        NULL, hiddenVol ? OPEN_EXISTING : CREATE_ALWAYS, 0, NULL);
1.1.1.6   root      107: 
                    108:                if (!hiddenVol)
                    109:                {
1.1.1.7 ! root      110:                        // Preallocate the file
1.1.1.6   root      111:                        LARGE_INTEGER volumeSize;
                    112:                        volumeSize.QuadPart = size;
                    113: 
                    114:                        if (!SetFilePointerEx (dev, volumeSize, NULL, FILE_BEGIN)
                    115:                                || !SetEndOfFile (dev)
                    116:                                || SetFilePointer (dev, 0, NULL, FILE_BEGIN) != 0)
                    117:                        {
                    118:                                handleWin32Error (hwndDlg);
1.1.1.7 ! root      119:                                nStatus = ERR_OS_ERROR;
        !           120:                                goto error;
1.1.1.6   root      121:                        }
                    122:                }
1.1.1.3   root      123:        }
                    124: 
                    125:        if (dev == INVALID_HANDLE_VALUE)
                    126:        {
1.1.1.6   root      127:                handleWin32Error (hwndDlg);
                    128:                nStatus = ERR_OS_ERROR; 
                    129:                goto error;
1.1.1.4   root      130:        }
                    131: 
1.1.1.6   root      132:        if (hiddenVol && !bDevice && bPreserveTimestamp)
1.1.1.4   root      133:        {
                    134:                /* Remember the container timestamp (used to reset file date and time of file-hosted
                    135:                containers to preserve plausible deniability of hidden volume)  */
                    136:                if (GetFileTime ((HANDLE) dev, &ftCreationTime, &ftLastAccessTime, &ftLastWriteTime) == 0)
                    137:                {
                    138:                        bTimeStampValid = FALSE;
1.1.1.6   root      139:                        MessageBoxW (hwndDlg, GetString ("GETFILETIME_FAILED_IMPLANT"), lpszTitle, MB_OK | MB_ICONEXCLAMATION);
1.1.1.4   root      140:                }
                    141:                else
                    142:                        bTimeStampValid = TRUE;
1.1.1.3   root      143:        }
1.1       root      144: 
                    145:        KillTimer (hwndDlg, 0xff);
                    146: 
1.1.1.3   root      147:        InitProgressBar (num_sectors);
                    148:        dwThen = GetTickCount ();
1.1.1.2   root      149: 
1.1.1.4   root      150: 
1.1.1.6   root      151:        /* Volume header */
1.1.1.4   root      152: 
                    153:        // Hidden volume setup
                    154:        if (hiddenVol)
                    155:        {
                    156:                // Check hidden volume size
                    157:                if (hiddenVolHostSize < MIN_HIDDEN_VOLUME_HOST_SIZE || hiddenVolHostSize > MAX_HIDDEN_VOLUME_HOST_SIZE)
                    158:                {               
1.1.1.7 ! root      159:                        nStatus = ERR_VOL_SIZE_WRONG;
        !           160:                        goto error;
1.1.1.4   root      161:                }
                    162: 
                    163:                // Seek to hidden volume header location
                    164:                if (!SeekHiddenVolHeader ((HFILE) dev, hiddenVolHostSize, bDevice))
                    165:                {
1.1.1.7 ! root      166:                        nStatus = ERR_VOL_SEEKING;
        !           167:                        goto error;
1.1.1.4   root      168:                }
                    169: 
                    170:        }
                    171: 
                    172:        // Write the volume header
                    173:        if ((*write) ((HFILE) dev, header, HEADER_SIZE) == HFILE_ERROR)
                    174:                return ERR_OS_ERROR;
                    175: 
                    176: 
1.1.1.6   root      177:        /* Data area */
1.1.1.4   root      178: 
                    179:        startSector = 1;        // Data area of normal volume starts right after volume header
                    180: 
                    181:        if (hiddenVol)
                    182:        {
                    183:                // Calculate data area position of hidden volume
                    184:                unsigned __int64 startOffset = hiddenVolHostSize - size - HIDDEN_VOL_HEADER_OFFSET;
1.1.1.7 ! root      185:                cryptoInfo->hiddenVolumeOffset = startOffset;
1.1.1.4   root      186: 
                    187:                // Validate the offset
                    188:                if (startOffset % SECTOR_SIZE != 0)
                    189:                {
1.1.1.6   root      190:                        nStatus = ERR_VOL_SIZE_WRONG; 
                    191:                        goto error;
1.1.1.4   root      192:                }
                    193: 
                    194:                startSector = startOffset / SECTOR_SIZE;        
                    195:                quickFormat = TRUE;             // To entirely format a hidden volume would be redundant
                    196:        }
                    197: 
                    198:        // Format filesystem
                    199: 
1.1.1.3   root      200:        switch (fileSystem)
                    201:        {
                    202:        case FILESYS_NONE:
1.1.1.4   root      203:        case FILESYS_NTFS: // NTFS volume is just prepared for quick format performed by system
1.1.1.6   root      204:                nStatus = FormatNoFs (startSector, num_sectors, (HFILE) dev, cryptoInfo, write, quickFormat);
1.1.1.3   root      205:                break;
                    206: 
                    207:        case FILESYS_FAT:
1.1.1.4   root      208:                if (num_sectors > 0xFFFFffff)
                    209:                {
1.1.1.6   root      210:                        nStatus = ERR_VOL_SIZE_WRONG; 
                    211:                        goto error;
1.1.1.4   root      212:                }
                    213: 
                    214:                // Calculate the fats, root dir etc
                    215:                ft.num_sectors = (unsigned int) (num_sectors);
                    216:                ft.cluster_size = clusterSize;
1.1.1.6   root      217:                memcpy (ft.volume_name, "NO NAME    ", 11);
1.1.1.4   root      218:                GetFatParams (&ft); 
                    219:                *realClusterSize = ft.cluster_size * SECTOR_SIZE;
                    220: 
1.1.1.6   root      221:                nStatus = FormatFat (startSector, &ft, (HFILE) dev, cryptoInfo, write, quickFormat);
1.1.1.3   root      222:                break;
                    223:        }
1.1       root      224: 
1.1.1.4   root      225: error:
                    226: 
1.1.1.3   root      227:        dwNow = GetTickCount ();
                    228: 
                    229:        burn (header, sizeof (header));
                    230:        VirtualUnlock (header, sizeof (header));
1.1       root      231: 
                    232:        crypto_close (cryptoInfo);
1.1.1.4   root      233: 
                    234:        if (bTimeStampValid)
                    235:        {
                    236:                // Restore the container timestamp (to preserve plausible deniability of the hidden volume) 
                    237:                if (SetFileTime (dev, &ftCreationTime, &ftLastAccessTime, &ftLastWriteTime) == 0)
1.1.1.6   root      238:                        MessageBoxW (hwndDlg, GetString ("SETFILETIME_FAILED_IMPLANT"), lpszTitle, MB_OK | MB_ICONEXCLAMATION);
                    239:        }
                    240: 
                    241:        if (!bDevice && !hiddenVol && nStatus != 0)
                    242:        {
                    243:                // Remove preallocated part before closing file handle if format failed
                    244:                if (SetFilePointer (dev, 0, NULL, FILE_BEGIN) == 0)
                    245:                        SetEndOfFile (dev);
1.1.1.4   root      246:        }
                    247: 
1.1.1.3   root      248:        CloseHandle (dev);
1.1       root      249: 
1.1.1.3   root      250:        dwError = GetLastError();
1.1       root      251: 
1.1.1.6   root      252:        if (nStatus != 0)
1.1       root      253:                SetLastError(dwError);
1.1.1.3   root      254:        else
                    255:        {
                    256:                switch (fileSystem)
                    257:                {
                    258:                case FILESYS_NONE:
1.1.1.6   root      259:                        swprintf (summaryMsg
                    260:                                , GetString ("FORMAT_STAT")
1.1.1.3   root      261:                                , num_sectors, num_sectors*512/1024/1024
1.1.1.6   root      262:                                , GetString ("NONE")
1.1.1.3   root      263:                                , (dwNow - dwThen)/1000);
                    264:                        break;
                    265: 
                    266:                case FILESYS_FAT:
1.1.1.6   root      267:                        swprintf (summaryMsg 
                    268:                                , GetString ("FORMAT_STAT_FAT")
1.1.1.3   root      269:                                , ft.num_sectors, ((__int64) ft.num_sectors*512)/1024/1024, ft.size_fat
                    270:                                , (int) (512*ft.fats*ft.fat_length),
                    271:                                (int) (512*ft.cluster_size), ft.cluster_count,
                    272:                                (dwNow - dwThen)/1000);
                    273:                        break;
                    274: 
                    275:                case FILESYS_NTFS:
                    276:                        {
1.1.1.4   root      277:                                // NTFS format is performed by system so we first need to mount the volume
                    278:                                int driveNo = GetLastAvailableDrive ();
1.1.1.5   root      279:                                MountOptions mountOptions;
                    280:                                
1.1.1.3   root      281:                                if (driveNo == -1)
                    282:                                {
1.1.1.6   root      283:                                        MessageBoxW (hwndDlg, GetString ("NO_FREE_DRIVES"), lpszTitle, ICON_HAND);
                    284:                                        MessageBoxW (hwndDlg, GetString ("FORMAT_NTFS_STOP"), lpszTitle, ICON_HAND);
                    285: 
1.1.1.3   root      286:                                        return ERR_NO_FREE_DRIVES;
                    287:                                }
                    288: 
1.1.1.5   root      289:                                mountOptions.ReadOnly = FALSE;
                    290:                                mountOptions.Removable = FALSE;
1.1.1.6   root      291:                                mountOptions.ProtectHiddenVolume = FALSE;
                    292:                                mountOptions.PreserveTimestamp = bPreserveTimestamp;
1.1.1.5   root      293: 
1.1.1.6   root      294:                                if (MountVolume (hwndDlg, driveNo, volumePath, password, FALSE, TRUE, &mountOptions, FALSE, TRUE) < 1)
1.1.1.3   root      295:                                {
1.1.1.6   root      296:                                        MessageBoxW (hwndDlg, GetString ("CANT_MOUNT_VOLUME"), lpszTitle, ICON_HAND);
                    297:                                        MessageBoxW (hwndDlg, GetString ("FORMAT_NTFS_STOP"), lpszTitle, ICON_HAND);
1.1.1.3   root      298:                                        return ERR_VOL_MOUNT_FAILED;
                    299:                                }
                    300: 
1.1.1.7 ! root      301:                                // Quick-format volume as NTFS
1.1.1.3   root      302:                                if (!FormatNtfs (driveNo, clusterSize))
                    303:                                {
1.1.1.6   root      304:                                        MessageBoxW (hwndDlg, GetString ("FORMAT_NTFS_FAILED"), lpszTitle, MB_ICONERROR);
1.1.1.4   root      305:                                
                    306:                                        if (!UnmountVolume (hwndDlg, driveNo, FALSE))
1.1.1.6   root      307:                                                MessageBoxW (hwndDlg, GetString ("CANT_DISMOUNT_VOLUME"), lpszTitle, ICON_HAND);
1.1.1.4   root      308: 
1.1.1.3   root      309:                                        return ERR_VOL_FORMAT_BAD;
                    310:                                }
                    311: 
1.1.1.4   root      312:                                if (!UnmountVolume (hwndDlg, driveNo, FALSE))
1.1.1.6   root      313:                                        MessageBoxW (hwndDlg, GetString ("CANT_DISMOUNT_VOLUME"), lpszTitle, ICON_HAND);
1.1.1.3   root      314: 
                    315:                                dwNow = GetTickCount ();
                    316: 
1.1.1.6   root      317:                                swprintf (summaryMsg,
                    318:                                        GetString ("FORMAT_STAT")
                    319:                                        , num_sectors
                    320:                                        , num_sectors*512/1024/1024
                    321:                                        , L"NTFS"
1.1.1.3   root      322:                                        , (dwNow - dwThen)/1000);
                    323: 
                    324:                                break;
                    325:                        }
                    326:                }
                    327:        }
                    328: 
1.1       root      329:        return nStatus;
1.1.1.3   root      330: }
1.1       root      331: 
1.1.1.3   root      332: 
1.1.1.6   root      333: int FormatNoFs (unsigned __int64 startSector, __int64 num_sectors, HFILE dev, PCRYPTO_INFO cryptoInfo, diskio_f write, BOOL quickFormat)
1.1.1.3   root      334: {
                    335:        int write_buf_cnt = 0;
                    336:        char sector[SECTOR_SIZE], *write_buf;
1.1.1.4   root      337:        unsigned __int64 nSecNo = startSector;
                    338:        LARGE_INTEGER startOffset;
                    339:        LARGE_INTEGER newOffset;
1.1.1.6   root      340:        int retVal;
1.1.1.7 ! root      341:        char temporaryKey[DISKKEY_SIZE];
1.1.1.4   root      342: 
                    343:        // Seek to start sector
                    344:        startOffset.QuadPart = startSector * SECTOR_SIZE;
1.1.1.6   root      345:        if (!SetFilePointerEx ((HANDLE) dev, startOffset, &newOffset, FILE_BEGIN)
                    346:                || newOffset.QuadPart != startOffset.QuadPart)
1.1.1.4   root      347:        {
                    348:                return ERR_VOL_SEEKING;
                    349:        }
1.1.1.3   root      350: 
                    351:        write_buf = TCalloc (WRITE_BUF_SIZE);
                    352:        memset (sector, 0, sizeof (sector));
                    353: 
1.1.1.7 ! root      354:        /* Fill the rest of the data area with random data */
        !           355: 
1.1.1.3   root      356:        if(!quickFormat)
                    357:        {
1.1.1.7 ! root      358:                /* Generate a random temporary key set to be used for "dummy" encryption that will fill
        !           359:                the free disk space (data area) with random data.  This is necessary for plausible
        !           360:                deniability of hidden volumes (and also reduces the amount of predictable plaintext
        !           361:                within the volume). */
1.1.1.6   root      362: 
1.1.1.7 ! root      363:                RandgetBytes (temporaryKey, DISKKEY_SIZE, FALSE);                               // Temporary master key
        !           364:                RandgetBytes (cryptoInfo->iv, sizeof cryptoInfo->iv, FALSE);    // Secondary key (LRW mode)
        !           365: 
        !           366:                retVal = EAInit (cryptoInfo->ea, temporaryKey, cryptoInfo->ks);
1.1.1.6   root      367:                if (retVal != 0)
1.1.1.7 ! root      368:                {
        !           369:                        burn (temporaryKey, sizeof(temporaryKey));
1.1.1.6   root      370:                        return retVal;
1.1.1.7 ! root      371:                }
        !           372:                if (!EAInitMode (cryptoInfo))
        !           373:                {
        !           374:                        burn (temporaryKey, sizeof(temporaryKey));
        !           375:                        return ERR_MODE_INIT_FAILED;
        !           376:                }
1.1.1.4   root      377: 
1.1.1.3   root      378:                while (num_sectors--)
                    379:                {
1.1.1.7 ! root      380:                        /* Generate random plaintext. Note that reused plaintext blocks are not a concern
        !           381:                        here since LRW mode is designed to hide patterns. Furthermore, patterns in plaintext
        !           382:                        do occur commonly on media in the "real world", so it might actually be a fatal
        !           383:                        mistake to try to avoid them completely. */
        !           384: #if RNG_POOL_SIZE < SECTOR_SIZE
        !           385:                        RandpeekBytes (sector, RNG_POOL_SIZE);
        !           386:                        RandpeekBytes (sector + RNG_POOL_SIZE, SECTOR_SIZE - RNG_POOL_SIZE);
        !           387: #else
        !           388:                        RandpeekBytes (sector, SECTOR_SIZE);
        !           389: #endif
        !           390: 
        !           391:                        // Encrypt the random plaintext and write it to the disk
1.1.1.6   root      392:                        if (WriteSector (dev, sector, write_buf, &write_buf_cnt, &nSecNo,
                    393:                                cryptoInfo, write) == FALSE)
1.1.1.3   root      394:                                goto fail;
                    395:                }
                    396:                if (write_buf_cnt != 0 && (*write) (dev, write_buf, write_buf_cnt) == HFILE_ERROR)
                    397:                        goto fail;
                    398:        }
                    399:        else
                    400:                nSecNo = num_sectors;
                    401: 
                    402:        UpdateProgressBar (nSecNo);
                    403: 
                    404:        TCfree (write_buf);
1.1.1.7 ! root      405:        burn (temporaryKey, sizeof(temporaryKey));
1.1.1.3   root      406:        return 0;
                    407: 
                    408: fail:
                    409: 
                    410:        TCfree (write_buf);
1.1.1.7 ! root      411:        burn (temporaryKey, sizeof(temporaryKey));
1.1.1.3   root      412:        return ERR_OS_ERROR;
1.1       root      413: }
1.1.1.3   root      414: 
                    415: 
                    416: volatile BOOLEAN FormatExResult;
                    417: 
                    418: BOOLEAN __stdcall FormatExCallback (int command, DWORD subCommand, PVOID parameter)
                    419: {
                    420:        if (command == FMIFS_DONE)
                    421:                FormatExResult = *(BOOLEAN *) parameter;
                    422:        return TRUE;
                    423: }
                    424: 
                    425: BOOL FormatNtfs (int driveNo, int clusterSize)
                    426: {
                    427:        WCHAR dir[8] = { driveNo + 'A', 0 };
                    428:        PFORMATEX FormatEx;
                    429:        HMODULE hModule = LoadLibrary ("fmifs.dll");
                    430: 
                    431:        if (hModule == NULL)
                    432:                return FALSE;
                    433: 
                    434:        if (!(FormatEx = (void *) GetProcAddress (GetModuleHandle("fmifs.dll"), "FormatEx")))
                    435:        {
                    436:                FreeLibrary (hModule);
                    437:                return FALSE;
                    438:        }
                    439: 
                    440:        wcscat (dir, L":\\");
                    441: 
                    442:        FormatExResult = FALSE;
                    443: 
                    444:        if (*(char *)dir > 'C' && *(char *)dir <= 'Z')
                    445:                FormatEx (dir, FMIFS_HARDDISK, L"NTFS", L"", TRUE, clusterSize * 512, FormatExCallback);
                    446: 
                    447:        FreeLibrary (hModule);
                    448:        return FormatExResult;
                    449: }
                    450: 
                    451: BOOL
                    452: WriteSector (HFILE dev, char *sector,
                    453:             char *write_buf, int *write_buf_cnt,
1.1.1.6   root      454:             __int64 *nSecNo, PCRYPTO_INFO cryptoInfo,
                    455:             diskio_f write)
1.1.1.3   root      456: {
1.1.1.6   root      457:        static DWORD updateTime = 0;
1.1.1.4   root      458: 
1.1.1.6   root      459:        EncryptSectors ((unsigned __int32 *) sector,
1.1.1.7 ! root      460:                (*nSecNo)++, 1, cryptoInfo);
1.1.1.4   root      461: 
1.1.1.3   root      462:        memcpy (write_buf + *write_buf_cnt, sector, SECTOR_SIZE);
                    463:        (*write_buf_cnt) += SECTOR_SIZE;
                    464: 
                    465:        if (*write_buf_cnt == WRITE_BUF_SIZE)
                    466:        {
                    467:                if ((*write) (dev, write_buf, WRITE_BUF_SIZE) == HFILE_ERROR)
                    468:                        return FALSE;
                    469:                else
                    470:                        *write_buf_cnt = 0;
                    471:        }
1.1.1.6   root      472:        
                    473:        if (GetTickCount () - updateTime > 25)
1.1.1.3   root      474:        {
1.1.1.6   root      475:                if (UpdateProgressBar (*nSecNo))
1.1.1.3   root      476:                        return FALSE;
1.1.1.6   root      477: 
                    478:                updateTime = GetTickCount ();
1.1.1.3   root      479:        }
                    480: 
                    481:        return TRUE;
                    482: 
                    483: }

unix.superglobalmegacorp.com

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