public bool Format() { if (!diskDevice.CanWrite) { return(false); } BinaryFormat masterboot = new BinaryFormat(new byte[512]); masterboot.SetUInt(MasterBootRecord.DiskSignature, diskSignature); masterboot.SetUShort(MasterBootRecord.MBRSignature, MasterBootConstants.MBRSignature); if (code != null) { for (uint index = 0; index < MasterBootConstants.CodeAreaSize; index++) { masterboot.SetByte(index, code[index]); } } //TODO: write partitions diskDevice.WriteBlock(0, 1, masterboot.Data); return(true); }
public bool Format () { if (!diskDevice.CanWrite) return false; BinaryFormat masterboot = new BinaryFormat (new byte[512]); masterboot.SetUInt (MasterBootRecord.DiskSignature, diskSignature); masterboot.SetUShort (MasterBootRecord.MBRSignature, MasterBootConstants.MBRSignature); if (code != null) for (uint index = 0; index < MasterBootConstants.CodeAreaSize; index++) masterboot.SetByte (index, code[index]); //TODO: write partitions diskDevice.WriteBlock (0, 1, masterboot.Data); 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; }
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; }
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; }
public bool Format (FATSettings fatSettings) { if (!partition.CanWrite) return false; this.fatType = fatSettings.FatType; bytesPerSector = 512; totalSectors = partition.BlockCount; sectorsPerCluster = GetSectorsPerClusterByTotalSectors (fatType, totalSectors); nbrFats = 2; if (fatType == FATType.FAT32) { reservedSectors = 32; rootEntries = 0; } else { reservedSectors = 1; rootEntries = 512; } rootDirSectors = (((rootEntries * 32) + (bytesPerSector - 1)) / bytesPerSector); fatStart = reservedSectors; uint val1 = totalSectors - (reservedSectors + rootDirSectors); uint val2 = (uint)((256 * sectorsPerCluster) + nbrFats); if (fatType == FATType.FAT32) val2 = val2 / 2; uint sectorsperfat = (val1 + (val2 - 1)) / val2; BinaryFormat bootSector = new BinaryFormat (512); bootSector.SetUInt (BootSector.JumpInstruction, 0); bootSector.SetString (BootSector.EOMName, "MSWIN4.1"); bootSector.SetUShort (BootSector.BytesPerSector, (ushort)bytesPerSector); bootSector.SetByte (BootSector.SectorsPerCluster, (byte)sectorsPerCluster); bootSector.SetUShort (BootSector.ReservedSectors, (ushort)reservedSectors); bootSector.SetByte (BootSector.FatAllocationTables, nbrFats); bootSector.SetUShort (BootSector.MaxRootDirEntries, (ushort)rootEntries); if (totalSectors > 0xFFFF) { bootSector.SetUShort (BootSector.TotalSectors, 0); bootSector.SetUInt (BootSector.FAT32_TotalSectors, totalClusters); } else { bootSector.SetUShort (BootSector.TotalSectors, (ushort)totalSectors); bootSector.SetUInt (BootSector.FAT32_TotalSectors, 0); } bootSector.SetByte (BootSector.MediaDescriptor, 0xF8); if (fatType == FATType.FAT32) bootSector.SetUShort (BootSector.SectorsPerFAT, 0); else bootSector.SetUShort (BootSector.SectorsPerFAT, (ushort)sectorsperfat); bootSector.SetUShort (BootSector.SectorsPerTrack, 0); ////FIXME bootSector.SetUInt (BootSector.HiddenSectors, 0); if (fatType != FATType.FAT32) { bootSector.SetByte (BootSector.PhysicalDriveNbr, 0x80); bootSector.SetByte (BootSector.ReservedCurrentHead, 0); bootSector.SetByte (BootSector.ExtendedBootSignature, 0x29); bootSector.SetBytes (BootSector.IDSerialNumber, fatSettings.SerialID, 0, (uint)(fatSettings.SerialID.Length <= 4 ? fatSettings.SerialID.Length : 4)); bootSector.SetString (BootSector.VolumeLabel, " "); // 12 blank spaces bootSector.SetString (BootSector.VolumeLabel, fatSettings.VolumeLabel, (uint)(fatSettings.VolumeLabel.Length <= 12 ? fatSettings.VolumeLabel.Length : 12)); bootSector.SetUShort (BootSector.BootSectorSignature, 0x55AA); //BootSector.OSBootCode // TODO } if (fatType == FATType.FAT12) bootSector.SetString (BootSector.FATType, "FAT12 "); else if (fatType == FATType.FAT16) bootSector.SetString (BootSector.FATType, "FAT16 "); else // if (type == FatType.FAT32) bootSector.SetString (BootSector.FATType, "FAT32 "); if (fatType == FATType.FAT32) { bootSector.SetUInt (BootSector.FAT32_SectorPerFAT, sectorsperfat); bootSector.SetByte (BootSector.FAT32_Flags, 0); bootSector.SetUShort (BootSector.FAT32_Version, 0); bootSector.SetUInt (BootSector.FAT32_ClusterNumberOfRoot, 2); bootSector.SetUShort (BootSector.FAT32_SectorFSInformation, 1); bootSector.SetUShort (BootSector.FAT32_SecondBootSector, 6); //FAT32_Reserved1 bootSector.SetByte (BootSector.FAT32_PhysicalDriveNbr, 0x80); bootSector.SetByte (BootSector.FAT32_Reserved2, 0); bootSector.SetByte (BootSector.FAT32_ExtendedBootSignature, 0x29); bootSector.SetBytes (BootSector.FAT32_IDSerialNumber, fatSettings.SerialID, 0, (uint)(fatSettings.SerialID.Length <= 4 ? fatSettings.SerialID.Length : 4)); bootSector.SetString (BootSector.FAT32_VolumeLabel, " "); // 12 blank spaces bootSector.SetString (BootSector.FAT32_VolumeLabel, fatSettings.VolumeLabel, (uint)(fatSettings.VolumeLabel.Length <= 12 ? fatSettings.VolumeLabel.Length : 12)); bootSector.SetString (BootSector.FAT32_FATType, "FAT32 "); //BootSector.OSBootCode // TODO } // Write Boot Sector partition.WriteBlock (0, 1, bootSector.Data); // Write backup Boot Sector if (fatType == FATType.FAT32) { partition.WriteBlock (0, 1, bootSector.Data); // FIXME: wrong block # } // create FSInfo Structure if (fatType == FATType.FAT32) { BinaryFormat infoSector = new BinaryFormat (512); infoSector.SetUInt (FSInfo.FSI_LeadSignature, 0x41615252); //FSInfo.FSI_Reserved1 infoSector.SetUInt (FSInfo.FSI_StructureSigature, 0x61417272); infoSector.SetUInt (FSInfo.FSI_FreeCount, 0xFFFFFFFF); infoSector.SetUInt (FSInfo.FSI_NextFree, 0xFFFFFFFF); //FSInfo.FSI_Reserved2 bootSector.SetUInt (FSInfo.FSI_TrailSignature, 0xAA550000); partition.WriteBlock (1, 1, infoSector.Data); partition.WriteBlock (7, 1, infoSector.Data); // create 2nd sector BinaryFormat secondSector = new BinaryFormat (512); secondSector.SetUInt ((ushort)FSInfo.FSI_TrailSignature2, 0xAA55); partition.WriteBlock (2, 1, secondSector.Data); partition.WriteBlock (8, 1, secondSector.Data); } // create fats /// TODO: incomplete BinaryFormat emptyFat = new BinaryFormat (512); // clear primary & secondary fats entries for (uint i = fatStart; i < fatStart + 1; i++) { //FIXME partition.WriteBlock (i, 1, emptyFat.Data); } // first block is special BinaryFormat firstFat = new BinaryFormat (512); // TODO: incomplete partition.WriteBlock (reservedSectors, 1, emptyFat.Data); return ReadBootSector (); }