/// <summary> /// Reads the boot sector. /// </summary> /// <returns></returns> 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)); if (bootSector.GetUShort(BootSector.BootSectorSignature) != 0xAA55) return false; byte extendedBootSignature = bootSector.GetByte(BootSector.ExtendedBootSignature); byte extendedBootSignature32 = bootSector.GetByte(BootSector.FAT32_ExtendedBootSignature); if ((extendedBootSignature != 0x29) && (extendedBootSignature != 0x28) && (extendedBootSignature32 != 0x29)) return false; volumeLabel = bootSector.GetString(BootSector.VolumeLabel, 8).ToString().TrimEnd(); 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); rootCluster32 = bootSector.GetUInt(BootSector.FAT32_ClusterNumberOfRoot); uint sectorsPerFat16 = bootSector.GetUShort(BootSector.SectorsPerFAT); uint sectorsPerFat32 = bootSector.GetUInt(BootSector.FAT32_SectorPerFAT); uint totalSectors16 = bootSector.GetUShort(BootSector.TotalSectors16); uint totalSectors32 = bootSector.GetUInt(BootSector.TotalSectors32); uint sectorsPerFat = (sectorsPerFat16 != 0) ? sectorsPerFat16 : sectorsPerFat32; uint fatSectors = 0; try { fatSectors = nbrFats * sectorsPerFat; clusterSizeInBytes = sectorsPerCluster * blockSize; rootDirSectors = (((rootEntries * 32) + (bytesPerSector - 1)) / bytesPerSector); firstDataSector = reservedSectors + (nbrFats * sectorsPerFat) + rootDirSectors; totalSectors = (totalSectors16 != 0) ? totalSectors16 : totalSectors32; dataSectors = totalSectors - (reservedSectors + (nbrFats * sectorsPerFat) + rootDirSectors); totalClusters = dataSectors / sectorsPerCluster; entriesPerSector = (bytesPerSector / 32); firstRootDirectorySector = reservedSectors + fatSectors; dataAreaStart = firstRootDirectorySector + rootDirSectors; } catch { return false; } // Some basic checks if ((nbrFats == 0) || (nbrFats > 2) || (totalSectors == 0) || (sectorsPerFat == 0)) return false; if (totalClusters < 4085) fatType = FatType.FAT12; else if (totalClusters < 65525) fatType = FatType.FAT16; else fatType = FatType.FAT32; if (fatType == FatType.FAT12) { reservedClusterMark = 0xFF0; endOfClusterMark = 0x0FF8; badClusterMark = 0x0FF7; fatMask = 0xFFFFFFFF; fatEntries = sectorsPerFat * 3 * blockSize / 2; } else if (fatType == FatType.FAT16) { reservedClusterMark = 0xFFF0; endOfClusterMark = 0xFFF8; badClusterMark = 0xFFF7; fatMask = 0xFFFFFFFF; fatEntries = sectorsPerFat * blockSize / 2; } else { // if (type == FatType.FAT32) { reservedClusterMark = 0xFFF0; endOfClusterMark = 0x0FFFFFF8; badClusterMark = 0x0FFFFFF7; fatMask = 0x0FFFFFFF; fatEntries = sectorsPerFat * blockSize / 4; } // More basic checks if ((fatType == FatType.FAT32) && (rootCluster32 == 0)) return false; valid = true; serialNbr = bootSector.GetBytes(fatType != FatType.FAT32 ? BootSector.IDSerialNumber : BootSector.FAT32_IDSerialNumber, 4); return true; }