private bool ReadMasterBootBlock() { valid = false; if (diskDevice.BlockSize != 512) // only going to work with 512 sector sizes { return(false); } BinaryFormat masterboot = new BinaryFormat(diskDevice.ReadBlock(0, 1)); ushort mbrsignature = masterboot.GetUShort(MasterBootRecord.MBRSignature); diskSignature = masterboot.GetUInt(MasterBootRecord.DiskSignature); valid = (mbrsignature == MasterBootConstants.MBRSignature); if (valid) { for (uint index = 0; index < MaxMBRPartitions; index++) { uint offset = MasterBootRecord.PrimaryPartitions + (index * 16); GenericPartition partition = new GenericPartition(index); partition.Bootable = masterboot.GetByte(offset + PartitionRecord.Status) == 0x80; 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[MasterBootConstants.CodeAreaSize]; for (uint index = 0; index < MasterBootConstants.CodeAreaSize; index++) { code[index] = masterboot.GetByte(index); } return(valid); }
private bool ReadMasterBootBlock () { valid = false; if (diskDevice.BlockSize != 512) // only going to work with 512 sector sizes return false; BinaryFormat masterboot = new BinaryFormat (diskDevice.ReadBlock (0, 1)); ushort mbrsignature = masterboot.GetUShort (MasterBootRecord.MBRSignature); diskSignature = masterboot.GetUInt (MasterBootRecord.DiskSignature); valid = (mbrsignature == MasterBootConstants.MBRSignature); if (valid) { for (uint index = 0; index < MaxMBRPartitions; index++) { uint offset = MasterBootRecord.PrimaryPartitions + (index * 16); GenericPartition partition = new GenericPartition (index); partition.Bootable = masterboot.GetByte (offset + PartitionRecord.Status) == 0x80; 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[MasterBootConstants.CodeAreaSize]; for (uint index = 0; index < MasterBootConstants.CodeAreaSize; index++) code[index] = masterboot.GetByte (index); return valid; }
// 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; }
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; }
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; }
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; }
//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; }
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; }