public override bool InitServer() { System.Diagnostics.Debugger.Log(0, "disk", "Disk driver started"); /* Get our ports and interrupt */ foreach (var r in root) { if (r.Name == "blockdev" && (r.Value is vfs.BlockDevice)) { bdev = r.Value as vfs.BlockDevice; } } if (bdev == null) { System.Diagnostics.Debugger.Log(0, "disk", "No blockdev property found"); return(false); } /* Get the first sector of the device */ byte[] sect_1 = new byte[bdev.SectorSize]; tysos.lib.MonoIOError err; long read = bdev.Read(0, 1, sect_1, 0, out err); if (err != MonoIOError.ERROR_SUCCESS) { System.Diagnostics.Debugger.Log(0, "disk", "Attempt to read first sector failed: bytes_read: " + read.ToString() + ", error: " + err.ToString()); return(false); } /*StringBuilder sb = null; * for(int i = 0; i < bdev.SectorSize; i++) * { * if(i % 8 == 0) * { * if (sb != null) * System.Diagnostics.Debugger.Log(0, "disk", sb.ToString()); * sb = new StringBuilder(); * sb.Append(i.ToString() + ": "); * } * * sb.Append(sect_1[i].ToString("X2")); * sb.Append(" "); * } * * if (sb != null) * System.Diagnostics.Debugger.Log(0, "disk", sb.ToString()); */ /* Try and identify the disk */ if (bdev.SectorSize < 512 || sect_1[510] != 0x55 || sect_1[511] != 0xaa) { System.Diagnostics.Debugger.Log(0, "disk", "Treating as one big partition (" + "SectorSize: " + bdev.SectorSize.ToString() + ", signature: " + sect_1[510].ToString("X2") + " " + sect_1[511].ToString("X2") + ")"); /* Treat as one big partition */ string part_type = IdentifyPartition(sect_1); List <File.Property> props = new List <File.Property>(); props.Add(new File.Property { Name = "blockdev", Value = bdev }); if (part_type != null) { props.Add(new File.Property { Name = "driver", Value = part_type }); } children.Add("volume", props); } else { if (sect_1[0] == 0xeb || sect_1[0] == 0xe9) { System.Diagnostics.Debugger.Log(0, "disk", "Treating as VBR"); /* VBR signature - treat as one big partition */ string part_type = IdentifyPartition(sect_1); List <File.Property> props = new List <File.Property>(); props.Add(new File.Property { Name = "blockdev", Value = bdev }); if (part_type != null) { props.Add(new File.Property { Name = "driver", Value = part_type }); } children.Add("volume", props); } else { /* Try and treat as a MBR if the partition entries appear valid */ bool is_valid = true; bool is_gpt = false; for (int i = 0; i < 4; i++) { int offset = 446 + i * 16; byte ptype = sect_1[offset + 4]; uint lba = BitConverter.ToUInt32(sect_1, offset + 8); uint sect_count = BitConverter.ToUInt32(sect_1, offset + 0xc); System.Diagnostics.Debugger.Log(0, "disk", "MBR: partition " + i.ToString() + ": ptype: " + ptype.ToString("X2") + ", lba: " + lba.ToString() + ", sect_count: " + sect_count.ToString()); if (ptype == 0) { continue; } if (ptype == 0xee) { is_gpt = true; break; } if (lba + sect_count > bdev.SectorCount) { is_valid = false; break; } else { /* Load up first sector of partition to identify type */ byte[] part_sect_1 = new byte[bdev.SectorSize]; read = bdev.Read(lba, 1, part_sect_1, 0, out err); string part_type; if (err != MonoIOError.ERROR_SUCCESS || read == bdev.SectorSize || (part_type = IdentifyPartition(part_sect_1)) == null) { /* There was an issue loading the first sector - resort to using * MBR partition type */ part_type = IdentifyPartition(ptype); } /* Create a child object */ List <File.Property> props = new List <File.Property>(); props.Add(new File.Property { Name = "blockdev", Value = new BlockDevice(bdev, lba, sect_count) }); if (part_type != null) { props.Add(new File.Property { Name = "driver", Value = part_type }); } children.Add("volume_" + i.ToString(), props); System.Diagnostics.Debugger.Log(0, "disk", "MBR: partition " + i.ToString() + ": ptype: " + (part_type == null ? "null" : part_type)); } } if (is_gpt) { children.Clear(); throw new NotImplementedException("GPT not implemented"); } if (is_valid == false) { /* The MBR was not valid, treat it as one large partition */ System.Diagnostics.Debugger.Log(0, "disk", "Invalid MBR - treating as one big partition"); children.Clear(); string part_type = IdentifyPartition(sect_1); List <File.Property> props = new List <File.Property>(); props.Add(new File.Property { Name = "blockdev", Value = bdev }); if (part_type != null) { props.Add(new File.Property { Name = "driver", Value = part_type }); } children.Add("volume", props); } } } /* Dump the identified partitions */ foreach (var part in children) { System.Diagnostics.Debugger.Log(0, "disk", part.Key); foreach (var prop in part.Value) { System.Diagnostics.Debugger.Log(0, "disk", " " + prop.Name + ": " + prop.Value.ToString()); } } root.Add(new File.Property { Name = "class", Value = "block" }); Tags.Add("class"); return(true); }
internal BlockDevice(vfs.BlockDevice Parent, long Lba, long LbaLen) { parent = Parent; lba = Lba; lba_len = LbaLen; }