/// <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 uint GetClusterEntryValue(uint cluster) { uint fatoffset = 0; fatoffset = cluster * 4; uint sector = ReservedSector + (fatoffset / BytePerSector); uint sectorOffset = fatoffset % BytePerSector; uint nbrSectors = 1; if ((FatType == FatType.FAT12) && (sectorOffset == BytePerSector - 1)) { nbrSectors = 2; } var xdata = new byte[512 * nbrSectors]; this.IDevice.Read(sector, nbrSectors, xdata); BinaryFormat fat = new BinaryFormat(xdata); uint clusterValue; clusterValue = fat.GetUInt(sectorOffset) & 0x0FFFFFFF; return(clusterValue); }
/// <summary> /// Reads the master boot block. /// </summary> /// <returns></returns> public bool Read() { valid = false; MasterBootBlock mbr = new MasterBootBlock(diskDevice); if (!mbr.Valid) { return(false); } if ((mbr.Partitions[0].PartitionType != PartitionType.GPT) || (mbr.Partitions[1].PartitionType != PartitionType.Empty) || (mbr.Partitions[2].PartitionType != PartitionType.Empty) || (mbr.Partitions[3].PartitionType != PartitionType.Empty) || (!mbr.Partitions[0].Bootable) || (mbr.Partitions[0].StartLBA != 1)) { return(false); } BinaryFormat gpt = new BinaryFormat(diskDevice.ReadBlock(1, 1)); if ((gpt.GetByte(0) != 45) && (gpt.GetByte(1) != 46) && (gpt.GetByte(2) != 49) && (gpt.GetByte(3) != 20) && (gpt.GetByte(4) != 50) && (gpt.GetByte(5) != 41) && (gpt.GetByte(6) != 52) && (gpt.GetByte(7) != 54)) { return(false); } if ((gpt.GetUInt(GPT.Revision) != GPTConstant.SupportedRevision) || (gpt.GetUInt(GPT.HeaderSize) != GPTConstant.HeaderSize) || (gpt.GetUInt(GPT.Reserved) != 0) || (gpt.GetUInt(GPT.PartitionStartingLBA) != 2) ) { return(false); } valid = true; return(valid); }
//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); }
/// <summary> /// Opens the specified drive NBR. /// </summary> /// <param name="drive">The drive NBR.</param> /// <returns></returns> public bool Open(uint drive) { if (drive > MaximunDriveCount) { return(false); } if (!driveInfo[drive].Present) { return(false); } if (drive == 0) { DeviceHeadPort.Write8(0xA0); } else if (drive == 1) { DeviceHeadPort.Write8(0xB0); } else { return(false); } CommandPort.Write8(IDECommands.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[drive].MaxLBA = info.GetUInt(IdentifyDrive.MaxLBA28); 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); }
public uint GetFileSize(uint directoryBlock, uint index) { BinaryFormat directory = new BinaryFormat(partition.ReadBlock(directoryBlock, 1)); return(directory.GetUInt((index * Entry.EntrySize) + Entry.FileSize)); }
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); }
public static void PatchSyslinux_3_72(PartitionDevice partitionDevice, FatFileSystem fat) { // Locate ldlinux.sys file for patching string filename = "ldlinux.sys"; string name = (Path.GetFileNameWithoutExtension(filename) + Path.GetExtension(filename).PadRight(4).Substring(0, 4)).ToUpper(); var location = fat.FindEntry(name); if (location.IsValid) { // Read boot sector var bootSector = new BinaryFormat(partitionDevice.ReadBlock(0, 1)); // Set the first sector location of the file bootSector.SetUInt(0x1F8, fat.GetSectorByCluster(location.FirstCluster)); // Change jump address bootSector.SetUInt(0x01, 0x58); // Write back patched boot sector partitionDevice.WriteBlock(0, 1, bootSector.Data); // Get the file size & number of sectors used uint fileSize = fat.GetFileSize(location.DirectorySector, location.DirectorySectorIndex); uint sectorCount = (fileSize + 511) >> 9; uint[] sectors = new uint[65]; uint nsec = 0; // Create list of the first 65 sectors of the file for (uint cluster = location.FirstCluster; ((cluster != 0) & (nsec <= 64)); cluster = fat.GetNextCluster(cluster)) { uint sec = fat.GetSectorByCluster(cluster); for (uint s = 0; s < fat.SectorsPerCluster; s++) { sectors[nsec++] = sec + s; } } // Read the first cluster of the file var firstCluster = new BinaryFormat(fat.ReadCluster(location.FirstCluster)); uint patchArea = 0; // Search for 0x3EB202FE (magic) for (patchArea = 0; (firstCluster.GetUInt(patchArea) != 0x3EB202FE) && (patchArea < fat.ClusterSizeInBytes); patchArea += 4) { ; } patchArea = patchArea + 8; if (patchArea < fat.ClusterSizeInBytes) { // Set up the totals firstCluster.SetUShort(patchArea, (ushort)(fileSize >> 2)); firstCluster.SetUShort(patchArea + 2, (ushort)(sectorCount - 1)); // Clear sector entries firstCluster.Fill(patchArea + 8, 0, 64 * 4); // Set sector entries for (nsec = 0; nsec < 64; nsec++) { firstCluster.SetUInt(patchArea + 8 + (nsec * 4), sectors[nsec + 1]); } // Clear out checksum firstCluster.SetUInt(patchArea + 4, 0); // Write back the updated cluster fat.WriteCluster(location.FirstCluster, firstCluster.Data); // Re-Calculate checksum by opening the file var file = new FatFileStream(fat, location); uint csum = 0x3EB202FE; for (uint index = 0; index < (file.Length >> 2); index++) { uint value = (uint)file.ReadByte() | ((uint)file.ReadByte() << 8) | ((uint)file.ReadByte() << 16) | ((uint)file.ReadByte() << 24); csum -= value; } // Set the checksum firstCluster.SetUInt(patchArea + 4, csum); // Write patched cluster back to disk fat.WriteCluster(location.FirstCluster, firstCluster.Data); } } }
public FatFileLocation FindEntry(ACompare compare, uint startCluster) { uint activeSector = ((startCluster - RootCluster) * SectorsPerCluster) + DataSector; if (startCluster == 0) { activeSector = (FatType == FatType.FAT32) ? GetSectorByCluster(RootCluster) : RootSector; } byte[] aData = new byte[512 * SectorsPerCluster]; this.IDevice.Read(activeSector, SectorsPerCluster, aData); BinaryFormat directory = new BinaryFormat(aData); for (uint index = 0; index < EntriesPerSector * SectorsPerCluster; index++) { Console.WriteLine("Lawl: %d\n" + ((uint)(index * 32)).ToString()); if (compare.Compare(directory.Data, index * 32, FatType)) { FatFileAttributes attribute = (FatFileAttributes)directory.GetByte((index * Entry.EntrySize) + Entry.FileAttributes); return(new FatFileLocation(GetClusterEntry(directory.Data, index, FatType), activeSector, index, (attribute & FatFileAttributes.SubDirectory) != 0, directory.GetUInt((index * Entry.EntrySize) + Entry.FileSize))); } if (directory.GetByte(Entry.DOSName + (index * Entry.EntrySize)) == FileNameAttribute.LastEntry) { return(null); } } return(null); }