Annotation of truecrypt/boot/windows/bootdiskio.cpp, revision 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 "Bios.h"
        !            10: #include "BootConsoleIo.h"
        !            11: #include "BootDebug.h"
        !            12: #include "BootDiskIo.h"
        !            13: 
        !            14: 
        !            15: bool IsLbaSupported (byte drive)
        !            16: {
        !            17:        uint16 result = 0;
        !            18:        __asm
        !            19:        {
        !            20:                mov bx, 0x55aa
        !            21:                mov dl, drive
        !            22:                mov ah, 0x41
        !            23:                int 0x13
        !            24:                jc err
        !            25:                mov result, bx
        !            26:        err:
        !            27:        }
        !            28: 
        !            29:        return result == 0xaa55;
        !            30: }
        !            31: 
        !            32: 
        !            33: void PrintDiskError (BiosResult error, bool write, byte drive, const uint64 *sector, const ChsAddress *chs)
        !            34: {
        !            35:        PrintEndl();
        !            36:        Print (write ? "Write" : "Read"); Print (" error:");
        !            37:        PrintHex (error);
        !            38:        Print (" Drive:");
        !            39:        Print (drive < TC_FIRST_BIOS_DRIVE ? drive : drive - TC_FIRST_BIOS_DRIVE);
        !            40: 
        !            41:        if (sector)
        !            42:        {
        !            43:                Print (" Sector:");
        !            44:                Print (*sector);
        !            45:        }
        !            46: 
        !            47:        if (chs)
        !            48:        {
        !            49:                Print (" CHS:");
        !            50:                Print (*chs);
        !            51:        }
        !            52: 
        !            53:        PrintEndl();
        !            54:        Beep();
        !            55: }
        !            56: 
        !            57: 
        !            58: void Print (const ChsAddress &chs)
        !            59: {
        !            60:        Print (chs.Cylinder);
        !            61:        PrintChar ('/');
        !            62:        Print (chs.Head);
        !            63:        PrintChar ('/');
        !            64:        Print (chs.Sector);
        !            65: }
        !            66: 
        !            67: 
        !            68: BiosResult ReadWriteSectors (bool write, byte *buffer, byte drive, const ChsAddress &chs, byte sectorCount, bool silent)
        !            69: {
        !            70:        byte cylinderLow = (byte) chs.Cylinder;
        !            71:        byte sector = chs.Sector;
        !            72:        sector |= byte (chs.Cylinder >> 2) & 0xc0;
        !            73:        byte function = write ? 0x03 : 0x02;
        !            74:        
        !            75:        BiosResult result;
        !            76:        __asm
        !            77:        {
        !            78:                push es
        !            79:                mov ax, ds
        !            80:                mov     es, ax
        !            81:                mov     bx, ss:buffer
        !            82:                mov dl, ss:drive
        !            83:                mov ch, ss:cylinderLow
        !            84:                mov si, chs
        !            85:                mov dh, ss:[si].Head
        !            86:                mov cl, ss:sector
        !            87:                mov     al, ss:sectorCount
        !            88:                mov     ah, function
        !            89:                int     0x13
        !            90:                mov     result, ah
        !            91:                pop es
        !            92:        }
        !            93: 
        !            94:        if (result == BiosResultEccCorrected)
        !            95:                result = BiosResultSuccess;
        !            96: 
        !            97:        if (!silent && result != BiosResultSuccess)
        !            98:                PrintDiskError (result, write, drive, nullptr, &chs);
        !            99: 
        !           100:        return result;
        !           101: }
        !           102: 
        !           103: 
        !           104: BiosResult ReadSectors (byte *buffer, byte drive, const ChsAddress &chs, byte sectorCount, bool silent)
        !           105: {
        !           106:        return ReadWriteSectors (false, buffer, drive, chs, sectorCount, silent);
        !           107: }
        !           108: 
        !           109: 
        !           110: BiosResult WriteSectors (byte *buffer, byte drive, const ChsAddress &chs, byte sectorCount, bool silent)
        !           111: {
        !           112:        return ReadWriteSectors (true, buffer, drive, chs, sectorCount, silent);
        !           113: }
        !           114: 
        !           115: 
        !           116: static BiosResult ReadWriteSectors (bool write, BiosLbaPacket &dapPacket, byte drive, const uint64 &sector, uint16 sectorCount, bool silent)
        !           117: {
        !           118:        dapPacket.Size = sizeof (dapPacket);
        !           119:        dapPacket.Reserved = 0;
        !           120:        dapPacket.SectorCount = sectorCount;
        !           121:        dapPacket.Sector = sector;
        !           122: 
        !           123:        byte function = write ? 0x43 : 0x42;
        !           124:        
        !           125:        BiosResult result;
        !           126:        __asm
        !           127:        {
        !           128:                mov     bx, 0x55aa
        !           129:                mov     dl, drive
        !           130:                mov si, [dapPacket]
        !           131:                mov     ah, function
        !           132:                xor al, al
        !           133:                int     0x13
        !           134:                mov     result, ah
        !           135:        }
        !           136: 
        !           137:        if (result == BiosResultEccCorrected)
        !           138:                result = BiosResultSuccess;
        !           139: 
        !           140:        if (!silent && result != BiosResultSuccess)
        !           141:                PrintDiskError (result, write, drive, &sector);
        !           142: 
        !           143:        return result;
        !           144: }
        !           145: 
        !           146: 
        !           147: static BiosResult ReadWriteSectors (bool write, byte *buffer, byte drive, const uint64 &sector, uint16 sectorCount, bool silent)
        !           148: {
        !           149:        BiosLbaPacket dapPacket;
        !           150:        dapPacket.Buffer = (uint32) buffer;
        !           151:        return ReadWriteSectors (write, dapPacket, drive, sector, sectorCount, silent);
        !           152: }
        !           153: 
        !           154: 
        !           155: BiosResult ReadWriteSectors (bool write, uint16 bufferSegment, uint16 bufferOffset, byte drive, const uint64 &sector, uint16 sectorCount, bool silent)
        !           156: {
        !           157:        BiosLbaPacket dapPacket;
        !           158:        dapPacket.Buffer = ((uint32) bufferSegment << 16) | bufferOffset;
        !           159:        return ReadWriteSectors (write, dapPacket, drive, sector, sectorCount, silent);
        !           160: }
        !           161: 
        !           162: 
        !           163: BiosResult ReadSectors (byte *buffer, byte drive, const uint64 &sector, uint16 sectorCount, bool silent)
        !           164: {
        !           165:        if (IsLbaSupported (drive))
        !           166:                return ReadWriteSectors (false, buffer, drive, sector, sectorCount, silent);
        !           167: 
        !           168:        DriveGeometry geometry;
        !           169: 
        !           170:        BiosResult result = GetDriveGeometry (drive, geometry, silent);
        !           171:        if (result != BiosResultSuccess)
        !           172:                return result;
        !           173: 
        !           174:        ChsAddress chs;
        !           175:        LbaToChs (geometry, sector, chs);
        !           176:        return ReadWriteSectors (false, buffer, drive, chs, sectorCount, silent);
        !           177: }
        !           178: 
        !           179: 
        !           180: BiosResult WriteSectors (byte *buffer, byte drive, const uint64 &sector, uint16 sectorCount, bool silent)
        !           181: {
        !           182:        return ReadWriteSectors (true, buffer, drive, sector, sectorCount, silent);
        !           183: }
        !           184: 
        !           185: 
        !           186: BiosResult GetDriveGeometry (byte drive, DriveGeometry &geometry, bool silent)
        !           187: {
        !           188:        byte maxCylinderLow, maxHead, maxSector;
        !           189:        BiosResult result;
        !           190:        __asm
        !           191:        {
        !           192:                push es
        !           193:                mov dl, drive
        !           194:                mov ah, 0x08
        !           195:                int     0x13
        !           196: 
        !           197:                mov     result, ah
        !           198:                jc err
        !           199:                mov maxCylinderLow, ch
        !           200:                mov maxSector, cl
        !           201:                mov maxHead, dh
        !           202: err:
        !           203:                pop es
        !           204:        }
        !           205: 
        !           206:        if (result == BiosResultSuccess)
        !           207:        {
        !           208:                geometry.Cylinders = (maxCylinderLow | (uint16 (maxSector & 0xc0) << 2)) + 1;
        !           209:                geometry.Heads = maxHead + 1;
        !           210:                geometry.Sectors = maxSector & ~0xc0;
        !           211:        }
        !           212:        else if (!silent)
        !           213:        {
        !           214:                PrintError ("Cannot get geometry of drive ", true, false);
        !           215:                Print (drive);
        !           216:                PrintEndl();
        !           217:        }
        !           218: 
        !           219:        return result;
        !           220: }
        !           221: 
        !           222: 
        !           223: void ChsToLba (const DriveGeometry &geometry, const ChsAddress &chs, uint64 &lba)
        !           224: {
        !           225:        lba.HighPart = 0;
        !           226:        lba.LowPart = (uint32 (chs.Cylinder) * geometry.Heads + chs.Head) * geometry.Sectors + chs.Sector - 1;
        !           227: }
        !           228: 
        !           229: 
        !           230: void LbaToChs (const DriveGeometry &geometry, const uint64 &lba, ChsAddress &chs)
        !           231: {
        !           232:        chs.Sector = (lba.LowPart % geometry.Sectors) + 1;
        !           233:        uint32 ch = lba.LowPart / geometry.Sectors;
        !           234:        chs.Head = ch % geometry.Heads;
        !           235:        chs.Cylinder = ch / geometry.Heads;
        !           236: }
        !           237: 
        !           238: 
        !           239: BiosResult ReadMBR (byte drive, MBR &mbr, bool silent)
        !           240: {
        !           241:        ChsAddress chs;
        !           242:        chs.Cylinder = 0;
        !           243:        chs.Head = 0;
        !           244:        chs.Sector = 1;
        !           245: 
        !           246:        return ReadSectors ((byte *) &mbr, drive, chs, 1, silent);
        !           247: }
        !           248: 
        !           249: 
        !           250: void PartitionEntryMBRToPartition (const PartitionEntryMBR &partEntry, Partition &partition)
        !           251: {
        !           252:        partition.Active = partEntry.BootIndicator == 0x80;
        !           253:        partition.EndSector.HighPart = 0;
        !           254:        partition.EndSector.LowPart = partEntry.StartLBA + partEntry.SectorCountLBA - 1;
        !           255:        partition.SectorCount.HighPart = 0;
        !           256:        partition.SectorCount.LowPart = partEntry.SectorCountLBA;
        !           257:        partition.StartSector.HighPart = 0;
        !           258:        partition.StartSector.LowPart = partEntry.StartLBA;
        !           259: 
        !           260:        partition.StartChsAddress.Cylinder = partEntry.StartCylinder | (uint16 (partEntry.StartCylSector & 0xc0) << 2);
        !           261:        partition.StartChsAddress.Head = partEntry.StartHead;
        !           262:        partition.StartChsAddress.Sector = partEntry.StartCylSector & ~0xc0;
        !           263: 
        !           264:        partition.Type = partEntry.Type;
        !           265: }
        !           266: 
        !           267: 
        !           268: BiosResult GetDrivePartitions (byte drive, Partition *partitionArray, size_t partitionArrayCapacity, size_t &partitionCount, bool activeOnly, bool silent)
        !           269: {
        !           270:        MBR mbr;
        !           271:        BiosResult result = ReadMBR (drive, mbr, silent);
        !           272:        partitionCount = 0;
        !           273:        
        !           274:        if (result != BiosResultSuccess || mbr.Signature != 0xaa55)
        !           275:                return result;
        !           276: 
        !           277:        size_t partitionArrayPos = 0, partitionNumber;
        !           278:        
        !           279:        for (partitionNumber = 0;
        !           280:                partitionNumber < array_capacity (mbr.Partitions) && partitionArrayPos < partitionArrayCapacity;
        !           281:                ++partitionNumber)
        !           282:        {
        !           283:                const PartitionEntryMBR &partEntry = mbr.Partitions[partitionNumber];
        !           284:                
        !           285:                if (partEntry.SectorCountLBA > 0)
        !           286:                {
        !           287:                        Partition &partition = partitionArray[partitionArrayPos];
        !           288:                        PartitionEntryMBRToPartition (partEntry, partition);
        !           289: 
        !           290:                        if (activeOnly && !partition.Active)
        !           291:                                continue;
        !           292: 
        !           293:                        partition.Drive = drive;
        !           294:                        partition.Number = partitionNumber;
        !           295: 
        !           296:                        if (partEntry.Type == 0x5 || partEntry.Type == 0xf) // Extended partition
        !           297:                        {
        !           298:                                if (IsLbaSupported (drive))
        !           299:                                {
        !           300:                                        // Find all extended partitions
        !           301:                                        uint64 firstExtStartLBA = partition.StartSector;
        !           302:                                        uint64 extStartLBA = partition.StartSector;
        !           303:                                        MBR extMbr;
        !           304: 
        !           305:                                        while (partitionArrayPos < partitionArrayCapacity &&
        !           306:                                                (result = ReadSectors ((byte *) &extMbr, drive, extStartLBA, 1, silent)) == BiosResultSuccess
        !           307:                                                && extMbr.Signature == 0xaa55)
        !           308:                                        {
        !           309:                                                if (extMbr.Partitions[0].SectorCountLBA > 0)
        !           310:                                                {
        !           311:                                                        Partition &logPart = partitionArray[partitionArrayPos++];
        !           312:                                                        PartitionEntryMBRToPartition (extMbr.Partitions[0], logPart);
        !           313:                                                        logPart.Drive = drive;
        !           314: 
        !           315:                                                        logPart.Number = partitionNumber++;
        !           316:                                                        logPart.Primary = false;
        !           317: 
        !           318:                                                        logPart.StartSector.LowPart += extStartLBA.LowPart;
        !           319:                                                        logPart.EndSector.LowPart += extStartLBA.LowPart;
        !           320:                                                }
        !           321: 
        !           322:                                                // Secondary extended
        !           323:                                                if (extMbr.Partitions[1].Type != 0x5 && extMbr.Partitions[1].Type == 0xf
        !           324:                                                        || extMbr.Partitions[1].SectorCountLBA == 0)
        !           325:                                                        break;
        !           326: 
        !           327:                                                extStartLBA.LowPart = extMbr.Partitions[1].StartLBA + firstExtStartLBA.LowPart;
        !           328:                                        }
        !           329:                                }
        !           330:                        }
        !           331:                        else
        !           332:                        {
        !           333:                                ++partitionArrayPos;
        !           334:                                partition.Primary = true;
        !           335:                        }
        !           336:                }
        !           337:        }
        !           338: 
        !           339:        partitionCount = partitionArrayPos;
        !           340:        return result;
        !           341: }
        !           342: 
        !           343: 
        !           344: BiosResult GetActivePartition (byte drive, Partition &partition, size_t &partitionCount, bool silent)
        !           345: {
        !           346:        return GetDrivePartitions (drive, &partition, 1, partitionCount, true, silent);
        !           347: }

unix.superglobalmegacorp.com

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