public GetUShort ( uint offset ) : ushort | ||
offset | uint | The offset. |
return | ushort |
/// <summary> /// Gets the cluster entry. /// </summary> /// <param name="data">The data.</param> /// <param name="index">The index.</param> /// <param name="type">The type.</param> /// <returns></returns> public static 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; return cluster; }
/// <summary> /// Sets the cluster entry value. /// </summary> /// <param name="cluster">The cluster.</param> /// <param name="nextcluster">The nextcluster.</param> /// <returns></returns> 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 = reservedSectors + (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 & 0x000F) | (nextcluster << 4)); else clustervalue = ((clustervalue & 0xF000) | (nextcluster & 0x0FFF)); fat.SetUShort(sectorOffset, (ushort)clustervalue); } else if (fatType == FatType.FAT16) fat.SetUShort(sectorOffset, (ushort)(nextcluster & 0xFFFF)); else //if (type == FatType.FAT32) fat.SetUInt(sectorOffset, nextcluster); partition.WriteBlock(sector, nbrSectors, fat.Data); return true; }
/// <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; }
/// <summary> /// Gets the cluster entry value. /// </summary> /// <param name="cluster">The cluster.</param> /// <returns></returns> 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 = reservedSectors + (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> /// 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 (!WaitForRegisterReady()) return false; var 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; }
/// <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; }