示例#1
0
        public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information,
                                   Encoding encoding)
        {
            Encoding    = encoding ?? Encoding.GetEncoding("iso-8859-1");
            information = "";

            StringBuilder sb = new StringBuilder();

            byte[] hbSector = imagePlugin.ReadSector(1 + partition.Start);

            GCHandle     handle    = GCHandle.Alloc(hbSector, GCHandleType.Pinned);
            OdsHomeBlock homeblock =
                (OdsHomeBlock)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(OdsHomeBlock));

            handle.Free();

            // Optical disc
            if (imagePlugin.Info.XmlMediaType == XmlMediaType.OpticalDisc &&
                StringHandlers.CToString(homeblock.format) != "DECFILE11A  " &&
                StringHandlers.CToString(homeblock.format) != "DECFILE11B  ")
            {
                if (hbSector.Length < 0x400)
                {
                    return;
                }

                byte[] tmp = imagePlugin.ReadSector(partition.Start);
                hbSector = new byte[0x200];
                Array.Copy(tmp, 0x200, hbSector, 0, 0x200);

                handle    = GCHandle.Alloc(hbSector, GCHandleType.Pinned);
                homeblock = (OdsHomeBlock)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(OdsHomeBlock));
                handle.Free();

                if (StringHandlers.CToString(homeblock.format) != "DECFILE11A  " &&
                    StringHandlers.CToString(homeblock.format) != "DECFILE11B  ")
                {
                    return;
                }
            }

            if ((homeblock.struclev & 0xFF00) != 0x0200 || (homeblock.struclev & 0xFF) != 1 ||
                StringHandlers.CToString(homeblock.format) != "DECFILE11B  ")
            {
                sb.AppendLine("The following information may be incorrect for this volume.");
            }
            if (homeblock.resfiles < 5 || homeblock.devtype != 0)
            {
                sb.AppendLine("This volume may be corrupted.");
            }

            sb.AppendFormat("Volume format is {0}", StringHandlers.SpacePaddedToString(homeblock.format, Encoding))
            .AppendLine();
            sb.AppendFormat("Volume is Level {0} revision {1}", (homeblock.struclev & 0xFF00) >> 8,
                            homeblock.struclev & 0xFF).AppendLine();
            sb.AppendFormat("Lowest structure in the volume is Level {0}, revision {1}",
                            (homeblock.lowstruclev & 0xFF00) >> 8, homeblock.lowstruclev & 0xFF).AppendLine();
            sb.AppendFormat("Highest structure in the volume is Level {0}, revision {1}",
                            (homeblock.highstruclev & 0xFF00) >> 8, homeblock.highstruclev & 0xFF).AppendLine();
            sb.AppendFormat("{0} sectors per cluster ({1} bytes)", homeblock.cluster, homeblock.cluster * 512)
            .AppendLine();
            sb.AppendFormat("This home block is on sector {0} (VBN {1})", homeblock.homelbn, homeblock.homevbn)
            .AppendLine();
            sb.AppendFormat("Secondary home block is on sector {0} (VBN {1})", homeblock.alhomelbn, homeblock.alhomevbn)
            .AppendLine();
            sb.AppendFormat("Volume bitmap starts in sector {0} (VBN {1})", homeblock.ibmaplbn, homeblock.ibmapvbn)
            .AppendLine();
            sb.AppendFormat("Volume bitmap runs for {0} sectors ({1} bytes)", homeblock.ibmapsize,
                            homeblock.ibmapsize * 512).AppendLine();
            sb.AppendFormat("Backup INDEXF.SYS;1 is in sector {0} (VBN {1})", homeblock.altidxlbn, homeblock.altidxvbn)
            .AppendLine();
            sb.AppendFormat("{0} maximum files on the volume", homeblock.maxfiles).AppendLine();
            sb.AppendFormat("{0} reserved files", homeblock.resfiles).AppendLine();
            if (homeblock.rvn > 0 && homeblock.setcount > 0 &&
                StringHandlers.CToString(homeblock.strucname) != "            ")
            {
                sb.AppendFormat("Volume is {0} of {1} in set \"{2}\".", homeblock.rvn, homeblock.setcount,
                                StringHandlers.SpacePaddedToString(homeblock.strucname, Encoding)).AppendLine();
            }
            sb.AppendFormat("Volume owner is \"{0}\" (ID 0x{1:X8})",
                            StringHandlers.SpacePaddedToString(homeblock.ownername, Encoding), homeblock.volowner)
            .AppendLine();
            sb.AppendFormat("Volume label: \"{0}\"", StringHandlers.SpacePaddedToString(homeblock.volname, Encoding))
            .AppendLine();
            sb.AppendFormat("Drive serial number: 0x{0:X8}", homeblock.serialnum).AppendLine();
            sb.AppendFormat("Volume was created on {0}", DateHandlers.VmsToDateTime(homeblock.credate)).AppendLine();
            if (homeblock.revdate > 0)
            {
                sb.AppendFormat("Volume was last modified on {0}", DateHandlers.VmsToDateTime(homeblock.revdate))
                .AppendLine();
            }
            if (homeblock.copydate > 0)
            {
                sb.AppendFormat("Volume copied on {0}", DateHandlers.VmsToDateTime(homeblock.copydate)).AppendLine();
            }
            sb.AppendFormat("Checksums: 0x{0:X4} and 0x{1:X4}", homeblock.checksum1, homeblock.checksum2).AppendLine();
            sb.AppendLine("Flags:");
            sb.AppendFormat("Window: {0}", homeblock.window).AppendLine();
            sb.AppendFormat("Cached directores: {0}", homeblock.lru_lim).AppendLine();
            sb.AppendFormat("Default allocation: {0} blocks", homeblock.extend).AppendLine();
            if ((homeblock.volchar & 0x01) == 0x01)
            {
                sb.AppendLine("Readings should be verified");
            }
            if ((homeblock.volchar & 0x02) == 0x02)
            {
                sb.AppendLine("Writings should be verified");
            }
            if ((homeblock.volchar & 0x04) == 0x04)
            {
                sb.AppendLine("Files should be erased or overwritten when deleted");
            }
            if ((homeblock.volchar & 0x08) == 0x08)
            {
                sb.AppendLine("Highwater mark is to be disabled");
            }
            if ((homeblock.volchar & 0x10) == 0x10)
            {
                sb.AppendLine("Classification checks are enabled");
            }
            sb.AppendLine("Volume permissions (r = read, w = write, c = create, d = delete)");
            sb.AppendLine("System, owner, group, world");
            // System
            sb.Append((homeblock.protect & 0x1000) == 0x1000 ? "-" : "r");
            sb.Append((homeblock.protect & 0x2000) == 0x2000 ? "-" : "w");
            sb.Append((homeblock.protect & 0x4000) == 0x4000 ? "-" : "c");
            sb.Append((homeblock.protect & 0x8000) == 0x8000 ? "-" : "d");
            // Owner
            sb.Append((homeblock.protect & 0x100) == 0x100 ? "-" : "r");
            sb.Append((homeblock.protect & 0x200) == 0x200 ? "-" : "w");
            sb.Append((homeblock.protect & 0x400) == 0x400 ? "-" : "c");
            sb.Append((homeblock.protect & 0x800) == 0x800 ? "-" : "d");
            // Group
            sb.Append((homeblock.protect & 0x10) == 0x10 ? "-" : "r");
            sb.Append((homeblock.protect & 0x20) == 0x20 ? "-" : "w");
            sb.Append((homeblock.protect & 0x40) == 0x40 ? "-" : "c");
            sb.Append((homeblock.protect & 0x80) == 0x80 ? "-" : "d");
            // World (other)
            sb.Append((homeblock.protect & 0x1) == 0x1 ? "-" : "r");
            sb.Append((homeblock.protect & 0x2) == 0x2 ? "-" : "w");
            sb.Append((homeblock.protect & 0x4) == 0x4 ? "-" : "c");
            sb.Append((homeblock.protect & 0x8) == 0x8 ? "-" : "d");

            sb.AppendLine();

            sb.AppendLine("Unknown structures:");
            sb.AppendFormat("Security mask: 0x{0:X8}", homeblock.sec_mask).AppendLine();
            sb.AppendFormat("File protection: 0x{0:X4}", homeblock.fileprot).AppendLine();
            sb.AppendFormat("Record protection: 0x{0:X4}", homeblock.recprot).AppendLine();

            XmlFsType = new FileSystemType
            {
                Type         = "FILES-11",
                ClusterSize  = homeblock.cluster * 512,
                Clusters     = (long)partition.Size / (homeblock.cluster * 512),
                VolumeName   = StringHandlers.SpacePaddedToString(homeblock.volname, Encoding),
                VolumeSerial = $"{homeblock.serialnum:X8}"
            };
            if (homeblock.credate > 0)
            {
                XmlFsType.CreationDate          = DateHandlers.VmsToDateTime(homeblock.credate);
                XmlFsType.CreationDateSpecified = true;
            }
            if (homeblock.revdate > 0)
            {
                XmlFsType.ModificationDate          = DateHandlers.VmsToDateTime(homeblock.revdate);
                XmlFsType.ModificationDateSpecified = true;
            }

            information = sb.ToString();
        }