Annotation of truecrypt/common/fat.c, revision 1.1

1.1     ! root        1: /* Copyright (C) 2004 TrueCrypt Team, truecrypt.org
        !             2:    This product uses components written by Paul Le Roux <[email protected]> */
        !             3: 
        !             4: #include "TCdefs.h"
        !             5: 
        !             6: #include "crypto.h"
        !             7: #include "random.h"
        !             8: #include "fat.h"
        !             9: #include "progress.h"
        !            10: 
        !            11: 
        !            12: #include <time.h>
        !            13: 
        !            14: #define WRITE_BUF_SIZE 65536
        !            15: 
        !            16: void
        !            17: GetFatParams (fatparams * ft)
        !            18: {
        !            19:        int fatsecs;
        !            20: 
        !            21:        if(ft->cluster_size == 0)
        !            22:        {
        !            23:                if (ft->num_sectors >= 1024I64 *1024*1024*2)
        !            24:                        ft->cluster_size = 128;
        !            25:                else if (ft->num_sectors >= 256*1024*1024*2)
        !            26:                        ft->cluster_size = 64;
        !            27:                else if (ft->num_sectors >= 32*1024*1024*2)
        !            28:                        ft->cluster_size = 32;
        !            29:                else if (ft->num_sectors >= 8*1024*1024*2)
        !            30:                        ft->cluster_size = 16;
        !            31:                else if (ft->num_sectors >= 512*1024*2)
        !            32:                        ft->cluster_size = 8;
        !            33:                else if (ft->num_sectors >= 64*1024*2)
        !            34:                        ft->cluster_size = 4;
        !            35:                else if (ft->num_sectors >= 66600)
        !            36:                        ft->cluster_size = 2;
        !            37:                else
        !            38:                        ft->cluster_size = 1;
        !            39:        }
        !            40: 
        !            41: /*     for (j = 2;; j = j << 1)
        !            42:        {
        !            43:                if ((ft->num_sectors * SECTOR_SIZE) / SECTOR_SIZE / j < 65536)
        !            44:                        break;
        !            45:        }
        !            46: 
        !            47:        ft->secs_track = (ft->num_sectors * SECTOR_SIZE) / SECTOR_SIZE / j;
        !            48:        ft->heads = j;
        !            49: */
        !            50: 
        !            51:        // Geometry always set to SECTORS/1/1
        !            52:        ft->secs_track = 1; 
        !            53:        ft->heads = 1; 
        !            54: 
        !            55:        ft->dir_entries = 512;
        !            56:        ft->fats = 2;
        !            57:        ft->create_time = (long) time (NULL);
        !            58:        ft->media = 0xf8;
        !            59:        ft->sector_size = SECTOR_SIZE;
        !            60:        ft->hidden = 0;
        !            61: 
        !            62:        ft->size_root_dir = ft->dir_entries * 32;
        !            63:        fatsecs = ft->num_sectors - (ft->size_root_dir + SECTOR_SIZE + 1) / SECTOR_SIZE - 1;
        !            64: 
        !            65:        ft->size_fat = 12;
        !            66:        ft->cluster_count = (int) (((__int64) fatsecs * SECTOR_SIZE) /
        !            67:            (ft->cluster_size * SECTOR_SIZE + 3));
        !            68:        ft->fat_length = (((ft->cluster_count * 3 + 1) >> 1) + SECTOR_SIZE + 1) /
        !            69:            SECTOR_SIZE;
        !            70: 
        !            71:        if (ft->cluster_count >= 4085) //FAT16
        !            72:        {
        !            73:                ft->size_fat = 16;
        !            74:                ft->cluster_count = (int) (((__int64) fatsecs * SECTOR_SIZE) /
        !            75:                    (ft->cluster_size * SECTOR_SIZE + 4));
        !            76:                ft->fat_length = (ft->cluster_count * 2 + SECTOR_SIZE + 1) /
        !            77:                    SECTOR_SIZE;
        !            78:        }
        !            79:        if(ft->cluster_count >= 65525) //FAT32
        !            80:        {
        !            81:                ft->size_fat = 32;
        !            82:                fatsecs = ft->num_sectors - 32 - ft->cluster_size * SECTOR_SIZE;
        !            83:                ft->size_root_dir = ft->cluster_size * SECTOR_SIZE;
        !            84:                ft->cluster_count = (int) (((__int64) fatsecs * SECTOR_SIZE) /
        !            85:                    (ft->cluster_size * SECTOR_SIZE + 4));
        !            86:                ft->fat_length = (ft->cluster_count * 4 + SECTOR_SIZE + 1) /
        !            87:                    SECTOR_SIZE;
        !            88:        }
        !            89: 
        !            90:        /* MS recommended cut-over safety net for buggy code out there */
        !            91:        #define UNSAFE_AREA 32
        !            92:        if(ft->cluster_count > 4085-UNSAFE_AREA  &&  ft->cluster_count < 4085)
        !            93:                ft->cluster_count = 4085-UNSAFE_AREA;
        !            94: 
        !            95:        if(ft->cluster_count > 65525-UNSAFE_AREA  &&  ft->cluster_count < 65525)
        !            96:                ft->cluster_count = 65525-UNSAFE_AREA;
        !            97: 
        !            98: 
        !            99:        if (ft->num_sectors >= 65536 || ft->size_fat == 32)
        !           100:        {
        !           101:                ft->sectors = 0;
        !           102:                ft->total_sect = ft->num_sectors;
        !           103:        }
        !           104:        else
        !           105:        {
        !           106:                ft->sectors = ft->num_sectors;
        !           107:                ft->total_sect = 0;
        !           108:        }
        !           109: 
        !           110: 
        !           111: }
        !           112: 
        !           113: void
        !           114: PutBoot (fatparams * ft, unsigned char *boot)
        !           115: {
        !           116:        int cnt = 0;
        !           117: 
        !           118:        boot[cnt++] = 0xeb;     /* boot jump */
        !           119:        boot[cnt++] = 0x3c;
        !           120:        boot[cnt++] = 0x90;
        !           121:        memcpy (boot + cnt, "MSWIN4.1", 8); /* system id */
        !           122:        cnt += 8;
        !           123:        memcpy (boot + cnt, (short *) &ft->sector_size, 2);     /* bytes per sector */
        !           124:        cnt += 2;
        !           125:        memcpy (boot + cnt, (char *) &ft->cluster_size, 1);     /* sectors per cluster */
        !           126:        cnt++;
        !           127:        boot[cnt++] = ft->size_fat == 32 ? 32 : 1;      /* reserved sectors */
        !           128:        boot[cnt++] = 0x00;
        !           129:        memcpy (boot + cnt, (char *) &ft->fats, 1);     /* 2 fats */
        !           130:        cnt++;
        !           131: 
        !           132:        if(ft->size_fat == 32)
        !           133:        {
        !           134:                boot[cnt++] = 0x00;
        !           135:                boot[cnt++] = 0x00;
        !           136:        }
        !           137:        else
        !           138:        {
        !           139:                memcpy (boot + cnt, (short *) &ft->dir_entries, 2);     /* 512 root entries */
        !           140:                cnt += 2;
        !           141:        }
        !           142: 
        !           143:        memcpy (boot + cnt, (short *) &ft->sectors, 2); /* # sectors */
        !           144:        cnt += 2;
        !           145:        memcpy (boot + cnt, (char *) &ft->media, 1);    /* media byte */
        !           146:        cnt++;
        !           147: 
        !           148:        if(ft->size_fat == 32)  
        !           149:        {
        !           150:                boot[cnt++] = 0x00;
        !           151:                boot[cnt++] = 0x00;
        !           152:        }
        !           153:        else 
        !           154:        { 
        !           155:                memcpy (boot + cnt, (short *) &ft->fat_length, 2);      /* fat size */
        !           156:                cnt += 2;
        !           157:        }
        !           158: 
        !           159:        memcpy (boot + cnt, (short *) &ft->secs_track, 2);      /* # sectors per track */
        !           160:        cnt += 2;
        !           161:        memcpy (boot + cnt, (short *) &ft->heads, 2);   /* # heads */
        !           162:        cnt += 2;
        !           163:        boot[cnt++] = 0x00;     /* 0 hidden sectors */
        !           164:        boot[cnt++] = 0x00;
        !           165:        boot[cnt++] = 0x00;
        !           166:        boot[cnt++] = 0x00;
        !           167:        memcpy (boot + cnt, (long *) &ft->total_sect, 4);       /* # huge sectors */
        !           168: 
        !           169:        cnt += 4;
        !           170: 
        !           171:        if(ft->size_fat == 32)
        !           172:        {
        !           173:                memcpy (boot + cnt, &ft->fat_length, 4); cnt += 4;      /* fat size 32 */
        !           174:                boot[cnt++] = 0x01;     /* ExtFlags */
        !           175:                boot[cnt++] = 0x00;
        !           176:                boot[cnt++] = 0x00;     /* FSVer */
        !           177:                boot[cnt++] = 0x00;
        !           178:                boot[cnt++] = 0x02;     /* RootClus */
        !           179:                boot[cnt++] = 0x00;
        !           180:                boot[cnt++] = 0x00;
        !           181:                boot[cnt++] = 0x00;
        !           182:                boot[cnt++] = 0x01;     /* FSInfo */
        !           183:                boot[cnt++] = 0x00;
        !           184:                boot[cnt++] = 0x06;     /* BkBootSec */
        !           185:                boot[cnt++] = 0x00;
        !           186:                memset(boot+cnt, 0, 12); cnt+=12;       /* Reserved */
        !           187:                
        !           188:        }
        !           189: 
        !           190:        boot[cnt++] = 0x80;     /* drive number */   // FIXED 80 > 00
        !           191:        boot[cnt++] = 0x00;     /* reserved */
        !           192:        boot[cnt++] = 0x29;     /* boot sig */
        !           193:        memcpy (boot + cnt, (long *) &ft->create_time, 4);      /* vol id */
        !           194:        cnt += 4;
        !           195:        memcpy (boot + cnt, (char *) ft->volume_name, 11);      /* vol title */
        !           196:        cnt += 11;
        !           197: 
        !           198:        switch(ft->size_fat) /* filesystem type */
        !           199:        {
        !           200:                case 12: memcpy (boot + cnt, "FAT12   ", 8); break;
        !           201:                case 16: memcpy (boot + cnt, "FAT16   ", 8); break;
        !           202:                case 32: memcpy (boot + cnt, "FAT32   ", 8); break;
        !           203:        }
        !           204:        cnt += 8;
        !           205: 
        !           206:        memset (boot + cnt, 0, ft->size_fat==32 ? 420:448);     /* boot code */
        !           207:        cnt += ft->size_fat==32 ? 420:448;
        !           208:        boot[cnt++] = 0x55;
        !           209:        boot[cnt++] = 0xaa;     /* boot sig */
        !           210: }
        !           211: 
        !           212: /* FAT32 FSInfo */
        !           213: PutFSInfo (unsigned char *sector)
        !           214: {
        !           215: 
        !           216:                memset (sector, 0, 512);
        !           217:                sector[3]=0x41; /* LeadSig */
        !           218:                sector[2]=0x61; 
        !           219:                sector[1]=0x52; 
        !           220:                sector[0]=0x52; 
        !           221:                sector[484+3]=0x61; /* StrucSig */
        !           222:                sector[484+2]=0x41; 
        !           223:                sector[484+1]=0x72; 
        !           224:                sector[484+0]=0x72; 
        !           225:                sector[488+3]=0xff; /* Free_Count */
        !           226:                sector[488+2]=0xff;
        !           227:                sector[488+1]=0xff;
        !           228:                sector[488+0]=0xff;
        !           229:                sector[492+3]=0xff; /* Nxt_Free */
        !           230:                sector[492+2]=0xff;
        !           231:                sector[492+1]=0xff;
        !           232:                sector[492+0]=0xff;
        !           233:                sector[508+3]=0xaa; /* TrailSig */
        !           234:                sector[508+2]=0x55;
        !           235:                sector[508+1]=0x00;
        !           236:                sector[508+0]=0x00;
        !           237: }
        !           238: 
        !           239: BOOL
        !           240: WriteSector (HFILE dev, char *sector,
        !           241:             char *write_buf, int *write_buf_cnt,
        !           242:             __int64 *nSecNo, int *progress, PCRYPTO_INFO cryptoInfo,
        !           243:             int nFrequency, diskio_f write)
        !           244: {
        !           245:        (*cryptoInfo->encrypt_sector) ((unsigned long *) sector,
        !           246:        (*nSecNo)++, 1, cryptoInfo->ks, cryptoInfo->iv, cryptoInfo->cipher);
        !           247:        memcpy (write_buf + *write_buf_cnt, sector, SECTOR_SIZE);
        !           248:        (*write_buf_cnt) += SECTOR_SIZE;
        !           249: 
        !           250: 
        !           251:        if (*write_buf_cnt == WRITE_BUF_SIZE)
        !           252:        {
        !           253:                if ((*write) (dev, write_buf, WRITE_BUF_SIZE) == HFILE_ERROR)
        !           254:                        return FALSE;
        !           255:                else
        !           256:                        *write_buf_cnt = 0;
        !           257:        }
        !           258: 
        !           259:        if (++(*progress) == nFrequency)
        !           260:        {
        !           261:                if (UpdateProgressBar (*nSecNo) == TRUE)
        !           262:                        return FALSE;
        !           263:                *progress = 0;
        !           264:        }
        !           265: 
        !           266:        return TRUE;
        !           267: 
        !           268: }
        !           269: 
        !           270: int
        !           271: Format (fatparams * ft, HFILE dev, PCRYPTO_INFO cryptoInfo, int nFrequency, diskio_f write, BOOL quickFormat)
        !           272: {
        !           273:        int write_buf_cnt = 0;
        !           274:        char sector[SECTOR_SIZE], *write_buf;
        !           275:        int progress = 0;
        !           276:        unsigned __int64 nSecNo = 1;
        !           277:        int x, n;
        !           278: 
        !           279:        if ((*write) (dev, (char *) &ft->header, SECTOR_SIZE) == HFILE_ERROR)
        !           280:                return ERR_OS_ERROR;
        !           281: 
        !           282:        write_buf = TCalloc (WRITE_BUF_SIZE);
        !           283: 
        !           284:        memset (sector, 0, sizeof (sector));
        !           285: 
        !           286:        PutBoot (ft, (unsigned char *) sector);
        !           287:        if (WriteSector (dev, sector, write_buf, &write_buf_cnt, &nSecNo, &progress,
        !           288:                cryptoInfo, nFrequency, write) == FALSE)
        !           289:                goto fail;
        !           290: 
        !           291:        /* fat32 boot area */
        !           292:        if (ft->size_fat == 32)                         
        !           293:        {
        !           294:                /* fsinfo */
        !           295:                PutFSInfo((unsigned char *) sector);
        !           296:                if (WriteSector (dev, sector, write_buf, &write_buf_cnt, &nSecNo, &progress,
        !           297:                        cryptoInfo, nFrequency, write) == FALSE)
        !           298:                        goto fail;
        !           299: 
        !           300:                /* reserved */
        !           301:                while (nSecNo<=6)
        !           302:                {
        !           303:                        memset (sector, 0, sizeof (sector));
        !           304:                        sector[508+3]=0xaa; /* TrailSig */
        !           305:                        sector[508+2]=0x55;
        !           306:                        if (WriteSector (dev, sector, write_buf, &write_buf_cnt, &nSecNo, &progress,
        !           307:                                cryptoInfo, nFrequency, write) == FALSE)
        !           308:                                goto fail;
        !           309:                }
        !           310:                
        !           311:                /* bootsector backup */
        !           312:                memset (sector, 0, sizeof (sector));
        !           313:                PutBoot (ft, (unsigned char *) sector);
        !           314:                if (WriteSector (dev, sector, write_buf, &write_buf_cnt, &nSecNo, &progress,
        !           315:                                 cryptoInfo, nFrequency, write) == FALSE)
        !           316:                        goto fail;
        !           317: 
        !           318:                PutFSInfo((unsigned char *) sector);
        !           319:                if (WriteSector (dev, sector, write_buf, &write_buf_cnt, &nSecNo, &progress,
        !           320:                        cryptoInfo, nFrequency, write) == FALSE)
        !           321:                        goto fail;
        !           322: 
        !           323:                /* reserved */
        !           324:                while (nSecNo<=32)
        !           325:                {
        !           326:                        memset (sector, 0, sizeof (sector));
        !           327:                        if (WriteSector (dev, sector, write_buf, &write_buf_cnt, &nSecNo, &progress,
        !           328:                                cryptoInfo, nFrequency, write) == FALSE)
        !           329:                                goto fail;
        !           330:                }
        !           331:        }
        !           332: 
        !           333: 
        !           334:        /* write fat */
        !           335:        for (x = 1; x <= ft->fats; x++)
        !           336:        {
        !           337:                for (n = 0; n < ft->fat_length; n++)
        !           338:                {
        !           339:                        memset (sector, 0, SECTOR_SIZE);
        !           340: 
        !           341:                        if (n == 0)
        !           342:                        {
        !           343:                                unsigned char fat_sig[12];
        !           344:                                if (ft->size_fat == 32)
        !           345:                                {
        !           346:                                        fat_sig[0] = (unsigned char) ft->media;
        !           347:                                        fat_sig[1] = fat_sig[2] = 0xff;
        !           348:                                        fat_sig[3] = 0x0f;
        !           349:                                        fat_sig[4] = fat_sig[5] = fat_sig[6] = 0xff;
        !           350:                                        fat_sig[7] = 0x0f;
        !           351:                                        fat_sig[8] = fat_sig[9] = fat_sig[10] = 0xff;
        !           352:                                        fat_sig[11] = 0x0f;
        !           353:                                        memcpy (sector, fat_sig, 12);
        !           354:                                }                               
        !           355:                                else if (ft->size_fat == 16)
        !           356:                                {
        !           357:                                        fat_sig[0] = (unsigned char) ft->media;
        !           358:                                        fat_sig[1] = 0xff;
        !           359:                                        fat_sig[2] = 0xff;
        !           360:                                        fat_sig[3] = 0xff;
        !           361:                                        memcpy (sector, fat_sig, 4);
        !           362:                                }
        !           363:                                else if (ft->size_fat == 12)
        !           364:                                {
        !           365:                                        fat_sig[0] = (unsigned char) ft->media;
        !           366:                                        fat_sig[1] = 0xff;
        !           367:                                        fat_sig[2] = 0xff;
        !           368:                                        fat_sig[3] = 0x00;
        !           369:                                        memcpy (sector, fat_sig, 4);
        !           370:                                }
        !           371:                        }
        !           372: 
        !           373:                        if (WriteSector (dev, sector, write_buf, &write_buf_cnt, &nSecNo, &progress,
        !           374:                                    cryptoInfo, nFrequency, write) == FALSE)
        !           375:                                goto fail;
        !           376:                }
        !           377:        }
        !           378: 
        !           379: 
        !           380:        /* write rootdir */
        !           381:        for (x = 0; x < ft->size_root_dir / SECTOR_SIZE; x++)
        !           382:        {
        !           383:                memset (sector, 0, SECTOR_SIZE);
        !           384:                if (WriteSector (dev, sector, write_buf, &write_buf_cnt, &nSecNo, &progress,
        !           385:                                 cryptoInfo, nFrequency, write) == FALSE)
        !           386:                        goto fail;
        !           387: 
        !           388:        }
        !           389: 
        !           390:        /* write data area */
        !           391:        if(!quickFormat)
        !           392:        {
        !           393:                char key[MAX_CIPHER_KEY];
        !           394: 
        !           395:                // Generate a random key and IV to randomize data area
        !           396:                // and support a possible hidden volume
        !           397:                RandgetBytes (key, MAX_CIPHER_KEY); 
        !           398:                RandgetBytes (cryptoInfo->iv, sizeof cryptoInfo->iv); 
        !           399:                init_cipher (cryptoInfo->cipher, key, cryptoInfo->ks);
        !           400:                ZeroMemory (sector, 512); 
        !           401: 
        !           402:                x = ft->num_sectors - (ft->size_fat==32 ? 32 : 1) - ft->size_root_dir / SECTOR_SIZE - ft->fat_length * 2;
        !           403:                while (x--)
        !           404:                {
        !           405:                        if (WriteSector (dev, sector, write_buf, &write_buf_cnt, &nSecNo, &progress,
        !           406:                                cryptoInfo, nFrequency, write) == FALSE)
        !           407:                                goto fail;
        !           408:                }
        !           409:        }
        !           410: 
        !           411:        if (write_buf_cnt != 0 && (*write) (dev, write_buf, write_buf_cnt) == HFILE_ERROR)
        !           412:                goto fail;
        !           413: 
        !           414:        UpdateProgressBar (nSecNo);
        !           415: 
        !           416:        TCfree (write_buf);
        !           417:        return 0;
        !           418: 
        !           419:       fail:
        !           420: 
        !           421:        TCfree (write_buf);
        !           422:        return ERR_OS_ERROR;
        !           423: }

unix.superglobalmegacorp.com

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