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; }
public bool Compare (byte[] data, uint offset, FATType type) { BinaryFormat entry = new BinaryFormat (data); byte first = entry.GetByte (offset + Entry.DOSName); if (first == FileNameAttribute.LastEntry) return false; if ((first == FileNameAttribute.Deleted) | (first == FileNameAttribute.Dot)) return false; if (first == FileNameAttribute.Escape) return false; uint startcluster = FAT.GetClusterEntry (data, offset, type); if (startcluster == cluster) return true; return false; }
public DirectoryEntryLocation FindEntry (FAT.ICompare compare, uint startCluster) { uint activeSector = (startCluster == 0) ? firstRootDirectorySector : (startCluster * this.sectorsPerCluster); uint increment = 0; for (; ; ) { BinaryFormat directory = new BinaryFormat (partition.ReadBlock (activeSector, 1)); for (uint index = 0; index < entriesPerSector; index++) { if (directory.GetByte ((index * Entry.EntrySize) + Entry.DOSName) == FileNameAttribute.LastEntry) return new DirectoryEntryLocation (); FileAttributes attribute = (FileAttributes)directory.GetByte ((index * Entry.EntrySize) + Entry.FileAttributes); if (compare.Compare (directory.Data, index * 32, fatType)) return new DirectoryEntryLocation (GetClusterEntry (directory.Data, index, fatType), activeSector, index, (attribute & FileAttributes.SubDirectory) != 0); } ++increment; if (startCluster == 0) { // root directory if (increment >= rootDirSectors) return new DirectoryEntryLocation (); activeSector = startCluster + increment; continue; } else { // subdirectory if (increment < sectorsPerCluster) { // still within cluster activeSector = startCluster + increment; continue; } // exiting cluster // goto next cluster (if any) uint cluster = GetClusterBySector (startCluster); if (cluster == 0) return new DirectoryEntryLocation (); uint nextCluster = GetClusterEntryValue (cluster); if ((IsClusterLast (nextCluster)) || (IsClusterBad (nextCluster)) || (IsClusterFree (nextCluster)) || (IsClusterReserved (nextCluster))) return new DirectoryEntryLocation (); activeSector = (uint)(dataAreaStart + (nextCluster - 1 * sectorsPerCluster)); continue; } } }
public static string ExtractFileName (byte[] directory, uint index) { BinaryFormat entry = new BinaryFormat (directory); char[] name = new char[12]; for (uint i = 0; i < 8; i++) name[i] = (char)entry.GetByte (index + i + Entry.DOSName); int len = 8; for (int i = 7; i > 0; i--) if (name[i] == ' ') len--; else break; // special case where real character is same as the delete if ((len >= 1) && (name[0] == (char)FileNameAttribute.Escape)) name[0] = (char)FileNameAttribute.Deleted; name[len] = '.'; len++; for (uint i = 0; i < 3; i++) name[len + i] = (char)entry.GetByte (index + i + Entry.DOSExtension); len = len + 3; int spaces = 0; for (int i = len - 1; i >= 0; i--) if (name[i] == ' ') spaces++; else break; if (spaces == 3) spaces = 4; len = len - spaces; string result = SharpOS.Kernel.Foundation.Convert.ToString (name, 0, len); //Runtime.Free (name); return result; }
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 bool Compare (byte[] data, uint offset, FATType type) { BinaryFormat entry = new BinaryFormat (data); byte first = entry.GetByte (offset + Entry.DOSName); if (first == FileNameAttribute.LastEntry) return false; if ((first == FileNameAttribute.Deleted) | (first == FileNameAttribute.Dot)) return false; if (first == FileNameAttribute.Escape) return false; string entryname = FAT.ExtractFileName (data, offset); if (entryname == name) return true; return false; }