//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); }
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); }
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); }
/// <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); }
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); }
// 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); }
/// <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); }
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); }
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); }