Пример #1
0
        //protected uint ClusterToFirstSector (uint cluster)
        //{
        //    return ((cluster - 2) * sectorspercluster) + firstdatasector;
        //}

        protected uint GetClusterEntryValue(uint cluster)
        {
            uint fatoffset = 0;

            if (fatType == FATType.FAT12)
            {
                fatoffset = (cluster + (cluster / 2));
            }
            else if (fatType == FATType.FAT16)
            {
                fatoffset = cluster * 2;
            }
            else             //if (type == FatType.FAT32)
            {
                fatoffset = cluster * 4;
            }

            uint sector       = fatStart + (fatoffset / bytesPerSector);
            uint sectorOffset = fatoffset % bytesPerSector;
            uint nbrSectors   = 1;

            if ((fatType == FATType.FAT12) && (sectorOffset == bytesPerSector - 1))
            {
                nbrSectors = 2;
            }

            BinaryFormat fat = new BinaryFormat(partition.ReadBlock(sector, nbrSectors));

            uint clusterValue;

            if (fatType == FATType.FAT12)
            {
                clusterValue = fat.GetUShort(sectorOffset);
                if (cluster % 2 == 1)
                {
                    clusterValue = clusterValue >> 4;
                }
                else
                {
                    clusterValue = clusterValue & 0x0fff;
                }
            }
            else if (fatType == FATType.FAT16)
            {
                clusterValue = fat.GetUShort(sectorOffset);
            }
            else             //if (type == FatType.FAT32)
            {
                clusterValue = fat.GetUInt(sectorOffset) & 0x0fffffff;
            }

            return(clusterValue);
        }
Пример #2
0
        static public uint GetClusterEntry(byte[] data, uint index, FATType type)
        {
            BinaryFormat entry = new BinaryFormat(data);

            uint cluster = entry.GetUShort((index * Entry.EntrySize) + Entry.FirstCluster);

            if (type == FATType.FAT32)
            {
                uint clusterhi = ((uint)entry.GetUShort((index * Entry.EntrySize) + Entry.EAIndex)) << 16;
                cluster = cluster | clusterhi;
            }

            return(cluster);
        }
Пример #3
0
        static public uint GetClusterEntry(byte[] data, uint index, FatType type)
        {
            BinaryFormat entry   = new BinaryFormat(data);
            uint         cluster = entry.GetUShort(Entry.FirstCluster + (index * Entry.EntrySize));

            if (type == FatType.FAT32)
            {
                cluster |= ((uint)entry.GetUShort(Entry.EAIndex + (index * Entry.EntrySize))) << 16;
            }

            if (cluster == 0)
            {
                cluster = 2;
            }

            return(cluster);
        }
Пример #4
0
        /// <summary>
        /// Reads the LBA48.
        /// </summary>
        /// <param name="operation">The operation.</param>
        /// <param name="drive">The drive.</param>
        /// <param name="lba">The lba.</param>
        /// <param name="data">The data.</param>
        /// <param name="offset">The offset.</param>
        /// <returns></returns>
        protected bool ReadLBA48(SectorOperation operation, uint drive, uint lba, byte[] data, uint offset)
        {
            if (drive > MaximunDriveCount)
            {
                return(false);
            }

            FeaturePort.Write8(0);
            FeaturePort.Write8(0);

            SectorCountPort.Write8(0);
            SectorCountPort.Write8(1);

            LBALowPort.Write8((byte)((lba >> 24) & 0xFF));
            LBALowPort.Write8((byte)(lba & 0xFF));

            LBAMidPort.Write8((byte)((lba >> 32) & 0xFF));
            LBAMidPort.Write8((byte)((lba >> 8) & 0xFF));

            LBAHighPort.Write8((byte)((lba >> 40) & 0xFF));
            LBAHighPort.Write8((byte)((lba >> 16) & 0xFF));

            DeviceHeadPort.Write8((byte)(0x40 | (drive << 4)));

            if (operation == SectorOperation.Write)
            {
                CommandPort.Write8(0x34);
            }
            else
            {
                CommandPort.Write8(0x24);
            }

            if (!WaitForReqisterReady())
            {
                return(false);
            }

            BinaryFormat sector = new BinaryFormat(data);

            //TODO: Don't use PIO
            if (operation == SectorOperation.Read)
            {
                for (uint index = 0; index < 256; index++)
                {
                    sector.SetUShort(offset + (index * 2), DataPort.Read16());
                }
            }
            else
            {
                for (uint index = 0; index < 256; index++)
                {
                    DataPort.Write16(sector.GetUShort(offset + (index * 2)));
                }
            }

            return(true);
        }
Пример #5
0
        protected bool SetClusterEntryValue(uint cluster, uint nextcluster)
        {
            uint fatOffset = 0;

            if (fatType == FATType.FAT12)
            {
                fatOffset = (cluster + (cluster / 2));
            }
            else if (fatType == FATType.FAT16)
            {
                fatOffset = cluster * 2;
            }
            else             //if (type == FatType.FAT32)
            {
                fatOffset = cluster * 4;
            }

            uint sector       = fatStart + (fatOffset / bytesPerSector);
            uint sectorOffset = fatOffset % bytesPerSector;
            uint nbrSectors   = 1;

            if ((fatType == FATType.FAT12) && (sectorOffset == bytesPerSector - 1))
            {
                nbrSectors = 2;
            }

            BinaryFormat fat = new BinaryFormat(partition.ReadBlock(sector, nbrSectors));

            if (fatType == FATType.FAT12)
            {
                uint clustervalue = fat.GetUShort(sectorOffset);

                if (cluster % 2 == 1)
                {
                    clustervalue = ((clustervalue & 0xF) | (nextcluster << 4));
                }
                else
                {
                    clustervalue = ((clustervalue & 0xf000) | (nextcluster));
                }

                fat.SetUShort(sectorOffset, (ushort)clustervalue);
            }
            else if (fatType == FATType.FAT16)
            {
                fat.SetUShort(sectorOffset, (ushort)nextcluster);
            }
            else             //if (type == FatType.FAT32)
            {
                fat.SetUInt(sectorOffset, nextcluster);
            }

            partition.WriteBlock(sector, nbrSectors, fat.Data);

            return(true);
        }
Пример #6
0
        // doesn't work since uint should be uint64
        //protected bool ReadLBA48 (SectorOperation operation, uint drive, uint lba, MemoryBlock memory)
        //{
        //    FeaturePort.Write8 (0);
        //    FeaturePort.Write8 (0);

        //    SectorCountPort.Write8 (0);
        //    SectorCountPort.Write8 (1);

        //    LBALowPort.Write8 ((byte)((lba >> 24) & 0xFF));
        //    LBALowPort.Write8 ((byte)(lba & 0xFF));

        //    LBAMidPort.Write8 ((byte)((lba >> 32) & 0xFF));
        //    LBAMidPort.Write8 ((byte)((lba >> 8) & 0xFF));

        //    LBAHighPort.Write8 ((byte)((lba >> 40) & 0xFF));
        //    LBAHighPort.Write8 ((byte)((lba >> 16) & 0xFF));

        //    DeviceHeadPort.Write8 ((byte)(0x40 | (drive << 4)));

        //    if (operation == SectorOperation.Write)
        //        CommandPort.Write8 (0x34);
        //    else
        //        CommandPort.Write8 (0x24);

        //    if (!WaitForReqisterReady ())
        //        return false;

        //    //TODO: Don't use PIO
        //    if (operation == SectorOperation.Read) {
        //        for (uint index = 0; index < 256; index++)
        //            memory.SetUShort (index * 2, DataPort.Read16 ());
        //    }
        //    else {
        //        for (uint index = 0; index < 256; index++)
        //            DataPort.WriteUShort (memory.GetUShort (index * 2));
        //    }

        //    return true;
        //}

        public bool Open(uint driveNbr)
        {
            if (driveNbr == 0)
            {
                DeviceHeadPort.Write8(0xA0);
            }
            else
            if (driveNbr == 1)
            {
                DeviceHeadPort.Write8(0xB0);
            }
            else
            {
                return(false);
            }

            CommandPort.Write8(IDECommand.IdentifyDrive);

            if (!WaitForReqisterReady())
            {
                return(false);
            }

            BinaryFormat info = new BinaryFormat(new byte[512]);

            for (uint index = 0; index < 256; index++)
            {
                info.SetUShort(index * 2, DataPort.Read16());
            }

            driveInfo[driveNbr].MaxLBA = info.GetUInt(IdentifyDrive.MaxLBA28);

            // legacy info
            driveInfo[driveNbr].Heads           = info.GetUShort(IdentifyDrive.LogicalHeads);
            driveInfo[driveNbr].Cylinders       = info.GetUShort(IdentifyDrive.LogicalCylinders);
            driveInfo[driveNbr].SectorsPerTrack = info.GetUShort(IdentifyDrive.LogicalSectors);

            return(true);
        }
Пример #7
0
        /// <summary>
        /// Reads the master boot block.
        /// </summary>
        /// <returns></returns>
        public bool Read()
        {
            valid = false;

            if (diskDevice.BlockSize != 512)
            {
                return(false);                                          // only going to work with 512 sector sizes
            }
            if (diskDevice.TotalBlocks < 3)
            {
                return(false);
            }

            BinaryFormat masterboot = new BinaryFormat(diskDevice.ReadBlock(0, 1));

            if (masterboot.GetUShort(MBR.MBRSignature) != MBRConstant.MBRSignature)
            {
                return(false);
            }

            valid = true;

            diskSignature = masterboot.GetUInt(MBR.DiskSignature);

            for (uint index = 0; index < MaxMBRPartitions; index++)
            {
                uint offset = MBR.FirstPartition + (index * MBRConstant.PartitionSize);

                GenericPartition partition = new GenericPartition(index);

                partition.Bootable      = masterboot.GetByte(offset + PartitionRecord.Status) == MBRConstant.Bootable;
                partition.PartitionType = masterboot.GetByte(offset + PartitionRecord.PartitionType);
                partition.StartLBA      = masterboot.GetUInt(offset + PartitionRecord.LBA);
                partition.TotalBlocks   = masterboot.GetUInt(offset + PartitionRecord.Sectors);

                Partitions[index] = partition;
            }

            //TODO: Extended Partitions

            code = new byte[MBRConstant.CodeAreaSize];
            for (uint index = 0; index < MBRConstant.CodeAreaSize; index++)
            {
                code[index] = masterboot.GetByte(index);
            }

            return(valid);
        }
Пример #8
0
        protected bool PerformLBA28(SectorOperation operation, uint driveNbr, uint lba, byte[] data, uint offset)
        {
            FeaturePort.Write8(0);
            SectorCountPort.Write8(1);

            LBALowPort.Write8((byte)(lba & 0xFF));
            LBAMidPort.Write8((byte)((lba >> 8) & 0xFF));
            LBAHighPort.Write8((byte)((lba >> 16) & 0xFF));

            DeviceHeadPort.Write8((byte)(0xE0 | (driveNbr << 4) | ((lba >> 24) & 0x0F)));

            if (operation == SectorOperation.Write)
            {
                CommandPort.Write8(IDECommand.WriteSectorsWithRetry);
            }
            else
            {
                CommandPort.Write8(IDECommand.ReadSectorsWithRetry);
            }

            if (!WaitForReqisterReady())
            {
                return(false);
            }

            BinaryFormat sector = new BinaryFormat(data);

            //TODO: Don't use PIO
            if (operation == SectorOperation.Read)
            {
                for (uint index = 0; index < 256; index++)
                {
                    sector.SetUShort(offset + (index * 2), DataPort.Read16());
                }
            }
            else
            {
                for (uint index = 0; index < 256; index++)
                {
                    DataPort.Write16(sector.GetUShort(offset + (index * 2)));
                }
            }

            return(true);
        }
Пример #9
0
        protected bool ReadBootSector()
        {
            valid = false;

            if (blockSize != 512)               // only going to work with 512 sector sizes (for now)
            {
                return(false);
            }

            BinaryFormat bootSector = new BinaryFormat(partition.ReadBlock(0, 1));

            byte bootSignature = bootSector.GetByte(BootSector.ExtendedBootSignature);

            if ((bootSignature != 0x29) && (bootSignature != 0x28))
            {
                return(false);
            }

            //TextMode.Write ("EOM NAME: ");

            //for (uint i = 0; i < 8; i++)
            //    TextMode.WriteChar (bootsector.GetByte (BootSector.EOMName + i));

            //TextMode.WriteLine ();

            bytesPerSector    = bootSector.GetUShort(BootSector.BytesPerSector);
            sectorsPerCluster = bootSector.GetByte(BootSector.SectorsPerCluster);
            reservedSectors   = bootSector.GetByte(BootSector.ReservedSectors);
            nbrFats           = bootSector.GetByte(BootSector.FatAllocationTables);
            rootEntries       = bootSector.GetUShort(BootSector.MaxRootDirEntries);

            uint sectorsPerFat16 = bootSector.GetUShort(BootSector.SectorsPerFAT);
            uint sectorsPerFat32 = bootSector.GetUInt(BootSector.FAT32_SectorPerFAT);
            uint totalSectors16  = bootSector.GetUShort(BootSector.TotalSectors);
            uint totalSectors32  = bootSector.GetUInt(BootSector.FAT32_TotalSectors);
            uint sectorsPerFat   = (sectorsPerFat16 != 0) ? sectorsPerFat16 : sectorsPerFat32;
            uint fatSectors      = nbrFats * sectorsPerFat;

            clusterSizeInBytes = sectorsPerCluster * blockSize;
            rootDirSectors     = (((rootEntries * 32) + (bytesPerSector - 1)) / bytesPerSector);
            firstDataSector    = reservedSectors + (nbrFats * sectorsPerFat) + rootDirSectors;

            if (totalSectors16 != 0)
            {
                totalSectors = totalSectors16;
            }
            else
            {
                totalSectors = totalSectors32;
            }

            dataSectors              = totalSectors - (reservedSectors + (nbrFats * sectorsPerFat) + rootDirSectors);
            totalClusters            = dataSectors / sectorsPerCluster;
            entriesPerSector         = (bytesPerSector / 32);
            firstRootDirectorySector = reservedSectors + fatSectors;
            dataAreaStart            = firstRootDirectorySector + rootDirSectors;
            fatStart = reservedSectors;

            if (totalClusters < 4085)
            {
                fatType = FATType.FAT12;
            }
            else if (totalClusters < 65525)
            {
                fatType = FATType.FAT16;
            }
            else
            {
                fatType = FATType.FAT32;
            }

            if (fatType == FATType.FAT12)
            {
                reserved   = 0xFF0;
                last       = 0x0FF8;
                bad        = 0x0FF7;
                fatMask    = 0xFFFFFFFF;
                fatEntries = sectorsPerFat * 3 * blockSize / 2;
            }
            else if (fatType == FATType.FAT16)
            {
                reserved   = 0xFFF0;
                last       = 0xFFF8;
                bad        = 0xFFF7;
                fatMask    = 0xFFFFFFFF;
                fatEntries = sectorsPerFat * blockSize / 2;
            }
            else               //  if (type == FatType.FAT32) {
            {
                reserved   = 0xFFF0;
                last       = 0x0FFFFFF8;
                bad        = 0x0FFFFFF7;
                fatMask    = 0x0FFFFFFF;
                fatEntries = sectorsPerFat * blockSize / 4;
            }

            // some basic checks

            if ((nbrFats == 0) || (nbrFats > 2))
            {
                valid = false;
            }
            else if (totalSectors == 0)
            {
                valid = false;
            }
            else if (sectorsPerFat == 0)
            {
                valid = false;
            }
            else if (!((fatType == FATType.FAT12) || (fatType == FATType.FAT16)))             // no support for Fat32 yet
            {
                valid = false;
            }
            else
            {
                valid = true;
            }

            if (valid)
            {
                base.volumeLabel = bootSector.GetString(fatType != FATType.FAT32 ? BootSector.VolumeLabel : BootSector.FAT32_VolumeLabel, 11);
                base.serialNbr   = bootSector.GetBytes(fatType != FATType.FAT32 ? BootSector.IDSerialNumber : BootSector.FAT32_IDSerialNumber, 4);
            }

            return(valid);
        }