/// <summary> /// Identifies the drive. /// </summary> protected void IdentifyDrive() { byte drive = (byte)(((deviceHead & 0x10) != 0x10) ? 0 : 1); byte d = (byte)('0' + drive + 1); BinaryFormat data = new BinaryFormat(bufferData); data.Fill(0, 0, 512); // fixed drive and over 5Mb/sec data.SetUShort(0x00, 0x140); // Serial Number data.Fill(0x0A * 2, d, 20); data.SetByte(0x0A * 2, d); // Firmware version data.Fill(0x17 * 2, d, 8); data.SetChar(0x17 * 2 + 0, '1'); data.SetChar(0x17 * 2 + 1, '.'); data.SetChar(0x17 * 2 + 2, '0'); // Model Number data.Fill(0x1B * 2, d, 40); data.SetChar(0x17 * 2 + 0, 'D'); data.SetChar(0x17 * 2 + 1, 'R'); data.SetChar(0x17 * 2 + 2, 'I'); data.SetChar(0x17 * 2 + 3, 'V'); data.SetChar(0x17 * 2 + 4, 'E'); data.SetByte(0x1B * 2 + 5, d); // lba28 data.SetUInt(0x3C * 2, (uint)(driveFiles[drive].Length / 512)); commandStatus = (byte)((commandStatus | 0x08) & ~0x80); // Set DRQ (bit 3), clear BUSY (bit 7) status = DeviceStatus.IdentifyDrive; }
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); } } }