示例#1
0
        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);
        }
示例#2
0
 internal BlockDevice(vfs.BlockDevice Parent, long Lba, long LbaLen)
 {
     parent  = Parent;
     lba     = Lba;
     lba_len = LbaLen;
 }