Пример #1
0
 internal Dictionary <ChecksumType, string> End() => new Dictionary <ChecksumType, string>
 {
     [ChecksumType.Crc32]  = _crc32Ctx.End(),
     [ChecksumType.Md5]    = _md5Ctx.End(),
     [ChecksumType.Sha1]   = _sha1Ctx.End(),
     [ChecksumType.Sha256] = _sha256Ctx.End(),
     [ChecksumType.Sha384] = _sha384Ctx.End(),
     [ChecksumType.Sha512] = _sha512Ctx.End()
 };
Пример #2
0
        public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information,
                                   Encoding encoding)
        {
            Encoding = encoding ?? Encoding.GetEncoding("iso-8859-1");
            StringBuilder sbInformation = new StringBuilder();

            XmlFsType   = new FileSystemType();
            information = null;
            BigEndianBitConverter.IsLittleEndian = BitConverter.IsLittleEndian;

            byte[] bootBlockSectors = imagePlugin.ReadSectors(0 + partition.Start, 2);

            BootBlock bootBlk = Marshal.ByteArrayToStructureBigEndian <BootBlock>(bootBlockSectors);

            bootBlk.bootCode = new byte[bootBlockSectors.Length - 12];
            Array.Copy(bootBlockSectors, 12, bootBlk.bootCode, 0, bootBlk.bootCode.Length);
            bootBlockSectors[4] = bootBlockSectors[5] = bootBlockSectors[6] = bootBlockSectors[7] = 0;
            uint bsum = AmigaBootChecksum(bootBlockSectors);

            ulong bRootPtr = 0;

            // If bootblock is correct, let's take its rootblock pointer
            if (bsum == bootBlk.checksum)
            {
                bRootPtr = bootBlk.root_ptr + partition.Start;
                DicConsole.DebugWriteLine("AmigaDOS plugin", "Bootblock points to {0} as Rootblock", bRootPtr);
            }

            ulong[] rootPtrs =
            {
                bRootPtr + partition.Start,                                      (partition.End - partition.Start + 1) / 2 + partition.Start - 2,
                (partition.End - partition.Start + 1) / 2 + partition.Start - 1,
                (partition.End - partition.Start + 1) / 2 +
                partition.Start,
                (partition.End - partition.Start + 1) / 2 + partition.Start + 4
            };

            RootBlock rootBlk = new RootBlock();

            byte[] rootBlockSector = null;

            bool rootFound = false;
            uint blockSize = 0;

            // So to handle even number of sectors
            foreach (ulong rootPtr in rootPtrs.Where(rootPtr => rootPtr < partition.End && rootPtr >= partition.Start))
            {
                DicConsole.DebugWriteLine("AmigaDOS plugin", "Searching for Rootblock in sector {0}", rootPtr);

                rootBlockSector = imagePlugin.ReadSector(rootPtr);

                rootBlk.type = BigEndianBitConverter.ToUInt32(rootBlockSector, 0x00);
                DicConsole.DebugWriteLine("AmigaDOS plugin", "rootBlk.type = {0}", rootBlk.type);
                if (rootBlk.type != TYPE_HEADER)
                {
                    continue;
                }

                rootBlk.hashTableSize = BigEndianBitConverter.ToUInt32(rootBlockSector, 0x0C);

                DicConsole.DebugWriteLine("AmigaDOS plugin", "rootBlk.hashTableSize = {0}", rootBlk.hashTableSize);

                blockSize = (rootBlk.hashTableSize + 56) * 4;
                uint sectorsPerBlock = (uint)(blockSize / rootBlockSector.Length);

                DicConsole.DebugWriteLine("AmigaDOS plugin", "blockSize = {0}", blockSize);
                DicConsole.DebugWriteLine("AmigaDOS plugin", "sectorsPerBlock = {0}", sectorsPerBlock);

                if (blockSize % rootBlockSector.Length > 0)
                {
                    sectorsPerBlock++;
                }

                if (rootPtr + sectorsPerBlock >= partition.End)
                {
                    continue;
                }

                rootBlockSector = imagePlugin.ReadSectors(rootPtr, sectorsPerBlock);

                // Clear checksum on sector
                rootBlk.checksum    = BigEndianBitConverter.ToUInt32(rootBlockSector, 20);
                rootBlockSector[20] = rootBlockSector[21] = rootBlockSector[22] = rootBlockSector[23] = 0;
                uint rsum = AmigaChecksum(rootBlockSector);

                DicConsole.DebugWriteLine("AmigaDOS plugin", "rootBlk.checksum = 0x{0:X8}", rootBlk.checksum);
                DicConsole.DebugWriteLine("AmigaDOS plugin", "rsum = 0x{0:X8}", rsum);

                rootBlk.sec_type = BigEndianBitConverter.ToUInt32(rootBlockSector, rootBlockSector.Length - 4);
                DicConsole.DebugWriteLine("AmigaDOS plugin", "rootBlk.sec_type = {0}", rootBlk.sec_type);

                if (rootBlk.sec_type != SUBTYPE_ROOT || rootBlk.checksum != rsum)
                {
                    continue;
                }

                rootBlockSector = imagePlugin.ReadSectors(rootPtr, sectorsPerBlock);
                rootFound       = true;
                break;
            }

            if (!rootFound)
            {
                return;
            }

            rootBlk = MarshalRootBlock(rootBlockSector);

            string diskName = StringHandlers.PascalToString(rootBlk.diskName, Encoding);

            switch (bootBlk.diskType & 0xFF)
            {
            case 0:
                sbInformation.Append("Amiga Original File System");
                XmlFsType.Type = "Amiga OFS";
                break;

            case 1:
                sbInformation.Append("Amiga Fast File System");
                XmlFsType.Type = "Amiga FFS";
                break;

            case 2:
                sbInformation.Append("Amiga Original File System with international characters");
                XmlFsType.Type = "Amiga OFS";
                break;

            case 3:
                sbInformation.Append("Amiga Fast File System with international characters");
                XmlFsType.Type = "Amiga FFS";
                break;

            case 4:
                sbInformation.Append("Amiga Original File System with directory cache");
                XmlFsType.Type = "Amiga OFS";
                break;

            case 5:
                sbInformation.Append("Amiga Fast File System with directory cache");
                XmlFsType.Type = "Amiga FFS";
                break;

            case 6:
                sbInformation.Append("Amiga Original File System with long filenames");
                XmlFsType.Type = "Amiga OFS2";
                break;

            case 7:
                sbInformation.Append("Amiga Fast File System with long filenames");
                XmlFsType.Type = "Amiga FFS2";
                break;
            }

            if ((bootBlk.diskType & 0x6D754600) == 0x6D754600)
            {
                sbInformation.Append(", with multi-user patches");
            }

            sbInformation.AppendLine();

            sbInformation.AppendFormat("Volume name: {0}", diskName).AppendLine();

            if (bootBlk.checksum == bsum)
            {
                Sha1Context sha1Ctx = new Sha1Context();
                sha1Ctx.Update(bootBlk.bootCode);
                sbInformation.AppendLine("Volume is bootable");
                sbInformation.AppendFormat("Boot code SHA1 is {0}", sha1Ctx.End()).AppendLine();
            }

            if (rootBlk.bitmapFlag == 0xFFFFFFFF)
            {
                sbInformation.AppendLine("Volume bitmap is valid");
            }

            if (rootBlk.bitmapExtensionBlock != 0x00000000 && rootBlk.bitmapExtensionBlock != 0xFFFFFFFF)
            {
                sbInformation.AppendFormat("Bitmap extension at block {0}", rootBlk.bitmapExtensionBlock).AppendLine();
            }

            if ((bootBlk.diskType & 0xFF) == 4 || (bootBlk.diskType & 0xFF) == 5)
            {
                sbInformation.AppendFormat("Directory cache starts at block {0}", rootBlk.extension).AppendLine();
            }

            ulong blocks = (partition.End - partition.Start + 1) * imagePlugin.Info.SectorSize / blockSize;

            sbInformation.AppendFormat("Volume block size is {0} bytes", blockSize).AppendLine();
            sbInformation.AppendFormat("Volume has {0} blocks", blocks).AppendLine();
            sbInformation.AppendFormat("Volume created on {0}",
                                       DateHandlers.AmigaToDateTime(rootBlk.cDays, rootBlk.cMins, rootBlk.cTicks))
            .AppendLine();
            sbInformation.AppendFormat("Volume last modified on {0}",
                                       DateHandlers.AmigaToDateTime(rootBlk.vDays, rootBlk.vMins, rootBlk.vTicks))
            .AppendLine();
            sbInformation.AppendFormat("Volume root directory last modified on on {0}",
                                       DateHandlers.AmigaToDateTime(rootBlk.rDays, rootBlk.rMins, rootBlk.rTicks))
            .AppendLine();
            sbInformation.AppendFormat("Root block checksum is 0x{0:X8}", rootBlk.checksum).AppendLine();
            information = sbInformation.ToString();

            XmlFsType.CreationDate =
                DateHandlers.AmigaToDateTime(rootBlk.cDays, rootBlk.cMins, rootBlk.cTicks);
            XmlFsType.CreationDateSpecified = true;
            XmlFsType.ModificationDate      =
                DateHandlers.AmigaToDateTime(rootBlk.vDays, rootBlk.vMins, rootBlk.vTicks);
            XmlFsType.ModificationDateSpecified = true;
            XmlFsType.Dirty       = rootBlk.bitmapFlag != 0xFFFFFFFF;
            XmlFsType.Clusters    = blocks;
            XmlFsType.ClusterSize = blockSize;
            XmlFsType.VolumeName  = diskName;
            XmlFsType.Bootable    = bsum == bootBlk.checksum;
            // Useful as a serial
            XmlFsType.VolumeSerial = $"{rootBlk.checksum:X8}";
        }
Пример #3
0
        public bool Open(IFilter imageFilter)
        {
            Stream imageStream = imageFilter.GetDataForkStream();

            byte[] header = new byte[512];
            byte[] footer;

            imageStream.Seek(0, SeekOrigin.Begin);
            imageStream.Read(header, 0, 512);

            if (imageStream.Length % 2 == 0)
            {
                footer = new byte[512];
                imageStream.Seek(-512, SeekOrigin.End);
                imageStream.Read(footer, 0, 512);
            }
            else
            {
                footer = new byte[511];
                imageStream.Seek(-511, SeekOrigin.End);
                imageStream.Read(footer, 0, 511);
            }

            BigEndianBitConverter.IsLittleEndian = BitConverter.IsLittleEndian;

            uint  headerChecksum = BigEndianBitConverter.ToUInt32(header, 0x40);
            uint  footerChecksum = BigEndianBitConverter.ToUInt32(footer, 0x40);
            ulong headerCookie   = BigEndianBitConverter.ToUInt64(header, 0);
            ulong footerCookie   = BigEndianBitConverter.ToUInt64(footer, 0);

            header[0x40] = 0;
            header[0x41] = 0;
            header[0x42] = 0;
            header[0x43] = 0;
            footer[0x40] = 0;
            footer[0x41] = 0;
            footer[0x42] = 0;
            footer[0x43] = 0;

            uint headerCalculatedChecksum = VhdChecksum(header);
            uint footerCalculatedChecksum = VhdChecksum(footer);

            DicConsole.DebugWriteLine("VirtualPC plugin", "Header checksum = 0x{0:X8}, calculated = 0x{1:X8}",
                                      headerChecksum, headerCalculatedChecksum);
            DicConsole.DebugWriteLine("VirtualPC plugin", "Header checksum = 0x{0:X8}, calculated = 0x{1:X8}",
                                      footerChecksum, footerCalculatedChecksum);

            byte[] usableHeader;
            uint   usableChecksum;

            if (headerCookie == IMAGE_COOKIE && headerChecksum == headerCalculatedChecksum)
            {
                usableHeader   = header;
                usableChecksum = headerChecksum;
            }
            else if (footerCookie == IMAGE_COOKIE && footerChecksum == footerCalculatedChecksum)
            {
                usableHeader   = footer;
                usableChecksum = footerChecksum;
            }
            else
            {
                throw new
                      ImageNotSupportedException("(VirtualPC plugin): Both header and footer are corrupt, image cannot be opened.");
            }

            thisFooter = new HardDiskFooter
            {
                Cookie             = BigEndianBitConverter.ToUInt64(usableHeader, 0x00),
                Features           = BigEndianBitConverter.ToUInt32(usableHeader, 0x08),
                Version            = BigEndianBitConverter.ToUInt32(usableHeader, 0x0C),
                Offset             = BigEndianBitConverter.ToUInt64(usableHeader, 0x10),
                Timestamp          = BigEndianBitConverter.ToUInt32(usableHeader, 0x18),
                CreatorApplication = BigEndianBitConverter.ToUInt32(usableHeader, 0x1C),
                CreatorVersion     = BigEndianBitConverter.ToUInt32(usableHeader, 0x20),
                CreatorHostOs      = BigEndianBitConverter.ToUInt32(usableHeader, 0x24),
                OriginalSize       = BigEndianBitConverter.ToUInt64(usableHeader, 0x28),
                CurrentSize        = BigEndianBitConverter.ToUInt64(usableHeader, 0x30),
                DiskGeometry       = BigEndianBitConverter.ToUInt32(usableHeader, 0x38),
                DiskType           = BigEndianBitConverter.ToUInt32(usableHeader, 0x3C),
                Checksum           = usableChecksum,
                UniqueId           = BigEndianBitConverter.ToGuid(usableHeader, 0x44),
                SavedState         = usableHeader[0x54],
                Reserved           = new byte[usableHeader.Length - 0x55]
            };
            Array.Copy(usableHeader, 0x55, thisFooter.Reserved, 0, usableHeader.Length - 0x55);

            thisDateTime = new DateTime(2000, 1, 1, 0, 0, 0, DateTimeKind.Utc);
            thisDateTime = thisDateTime.AddSeconds(thisFooter.Timestamp);

            Sha1Context sha1Ctx = new Sha1Context();

            sha1Ctx.Update(thisFooter.Reserved);

            DicConsole.DebugWriteLine("VirtualPC plugin", "footer.cookie = 0x{0:X8}", thisFooter.Cookie);
            DicConsole.DebugWriteLine("VirtualPC plugin", "footer.features = 0x{0:X8}", thisFooter.Features);
            DicConsole.DebugWriteLine("VirtualPC plugin", "footer.version = 0x{0:X8}", thisFooter.Version);
            DicConsole.DebugWriteLine("VirtualPC plugin", "footer.offset = {0}", thisFooter.Offset);
            DicConsole.DebugWriteLine("VirtualPC plugin", "footer.timestamp = 0x{0:X8} ({1})", thisFooter.Timestamp,
                                      thisDateTime);
            DicConsole.DebugWriteLine("VirtualPC plugin", "footer.creatorApplication = 0x{0:X8} (\"{1}\")",
                                      thisFooter.CreatorApplication,
                                      Encoding.ASCII.GetString(BigEndianBitConverter.GetBytes(thisFooter
                                                                                              .CreatorApplication)));
            DicConsole.DebugWriteLine("VirtualPC plugin", "footer.creatorVersion = 0x{0:X8}",
                                      thisFooter.CreatorVersion);
            DicConsole.DebugWriteLine("VirtualPC plugin", "footer.creatorHostOS = 0x{0:X8} (\"{1}\")",
                                      thisFooter.CreatorHostOs,
                                      Encoding.ASCII.GetString(BigEndianBitConverter
                                                               .GetBytes(thisFooter.CreatorHostOs)));
            DicConsole.DebugWriteLine("VirtualPC plugin", "footer.originalSize = {0}", thisFooter.OriginalSize);
            DicConsole.DebugWriteLine("VirtualPC plugin", "footer.currentSize = {0}", thisFooter.CurrentSize);
            DicConsole.DebugWriteLine("VirtualPC plugin", "footer.diskGeometry = 0x{0:X8} (C/H/S: {1}/{2}/{3})",
                                      thisFooter.DiskGeometry, (thisFooter.DiskGeometry & 0xFFFF0000) >> 16,
                                      (thisFooter.DiskGeometry & 0xFF00) >> 8,
                                      thisFooter.DiskGeometry & 0xFF);
            DicConsole.DebugWriteLine("VirtualPC plugin", "footer.diskType = 0x{0:X8}", thisFooter.DiskType);
            DicConsole.DebugWriteLine("VirtualPC plugin", "footer.checksum = 0x{0:X8}", thisFooter.Checksum);
            DicConsole.DebugWriteLine("VirtualPC plugin", "footer.uniqueId = {0}", thisFooter.UniqueId);
            DicConsole.DebugWriteLine("VirtualPC plugin", "footer.savedState = 0x{0:X2}", thisFooter.SavedState);
            DicConsole.DebugWriteLine("VirtualPC plugin", "footer.reserved's SHA1 = 0x{0}", sha1Ctx.End());

            if (thisFooter.Version == VERSION1)
            {
                imageInfo.Version = "1.0";
            }
            else
            {
                throw new
                      ImageNotSupportedException($"(VirtualPC plugin): Unknown image type {thisFooter.DiskType} found. Please submit a bug with an example image.");
            }

            switch (thisFooter.CreatorApplication)
            {
            case CREATOR_QEMU:
            {
                imageInfo.Application = "QEMU";
                // QEMU always set same version
                imageInfo.ApplicationVersion = "Unknown";

                break;
            }

            case CREATOR_VIRTUAL_BOX:
            {
                imageInfo.ApplicationVersion =
                    $"{(thisFooter.CreatorVersion & 0xFFFF0000) >> 16}.{thisFooter.CreatorVersion & 0x0000FFFF:D2}";
                switch (thisFooter.CreatorHostOs)
                {
                case CREATOR_MACINTOSH:
                case CREATOR_MACINTOSH_OLD:
                    imageInfo.Application = "VirtualBox for Mac";
                    break;

                case CREATOR_WINDOWS:
                    // VirtualBox uses Windows creator for any other OS
                    imageInfo.Application = "VirtualBox";
                    break;

                default:
                    imageInfo.Application =
                        $"VirtualBox for unknown OS \"{Encoding.ASCII.GetString(BigEndianBitConverter.GetBytes(thisFooter.CreatorHostOs))}\"";
                    break;
                }

                break;
            }

            case CREATOR_VIRTUAL_SERVER:
            {
                imageInfo.Application = "Microsoft Virtual Server";
                switch (thisFooter.CreatorVersion)
                {
                case VERSION_VIRTUAL_SERVER2004:
                    imageInfo.ApplicationVersion = "2004";
                    break;

                default:
                    imageInfo.ApplicationVersion = $"Unknown version 0x{thisFooter.CreatorVersion:X8}";
                    break;
                }

                break;
            }

            case CREATOR_VIRTUAL_PC:
            {
                switch (thisFooter.CreatorHostOs)
                {
                case CREATOR_MACINTOSH:
                case CREATOR_MACINTOSH_OLD:
                    switch (thisFooter.CreatorVersion)
                    {
                    case VERSION_VIRTUAL_PC_MAC:
                        imageInfo.Application        = "Connectix Virtual PC";
                        imageInfo.ApplicationVersion = "5, 6 or 7";
                        break;

                    default:
                        imageInfo.ApplicationVersion = $"Unknown version 0x{thisFooter.CreatorVersion:X8}";
                        break;
                    }

                    break;

                case CREATOR_WINDOWS:
                    switch (thisFooter.CreatorVersion)
                    {
                    case VERSION_VIRTUAL_PC_MAC:
                        imageInfo.Application        = "Connectix Virtual PC";
                        imageInfo.ApplicationVersion = "5, 6 or 7";
                        break;

                    case VERSION_VIRTUAL_PC2004:
                        imageInfo.Application        = "Microsoft Virtual PC";
                        imageInfo.ApplicationVersion = "2004";
                        break;

                    case VERSION_VIRTUAL_PC2007:
                        imageInfo.Application        = "Microsoft Virtual PC";
                        imageInfo.ApplicationVersion = "2007";
                        break;

                    default:
                        imageInfo.ApplicationVersion = $"Unknown version 0x{thisFooter.CreatorVersion:X8}";
                        break;
                    }

                    break;

                default:
                    imageInfo.Application =
                        $"Virtual PC for unknown OS \"{Encoding.ASCII.GetString(BigEndianBitConverter.GetBytes(thisFooter.CreatorHostOs))}\"";
                    imageInfo.ApplicationVersion = $"Unknown version 0x{thisFooter.CreatorVersion:X8}";
                    break;
                }

                break;
            }

            case CREATOR_DISCIMAGECHEF:
            {
                imageInfo.Application        = "DiscImageChef";
                imageInfo.ApplicationVersion =
                    $"{(thisFooter.CreatorVersion & 0xFF000000) >> 24}.{(thisFooter.CreatorVersion & 0xFF0000) >> 16}.{(thisFooter.CreatorVersion & 0xFF00) >> 8}.{thisFooter.CreatorVersion & 0xFF}";
            }
            break;

            default:
            {
                imageInfo.Application =
                    $"Unknown application \"{Encoding.ASCII.GetString(BigEndianBitConverter.GetBytes(thisFooter.CreatorHostOs))}\"";
                imageInfo.ApplicationVersion = $"Unknown version 0x{thisFooter.CreatorVersion:X8}";
                break;
            }
            }

            thisFilter           = imageFilter;
            imageInfo.ImageSize  = thisFooter.CurrentSize;
            imageInfo.Sectors    = thisFooter.CurrentSize / 512;
            imageInfo.SectorSize = 512;

            imageInfo.CreationTime         = imageFilter.GetCreationTime();
            imageInfo.LastModificationTime = thisDateTime;
            imageInfo.MediaTitle           = Path.GetFileNameWithoutExtension(imageFilter.GetFilename());

            imageInfo.Cylinders       = (thisFooter.DiskGeometry & 0xFFFF0000) >> 16;
            imageInfo.Heads           = (thisFooter.DiskGeometry & 0xFF00) >> 8;
            imageInfo.SectorsPerTrack = thisFooter.DiskGeometry & 0xFF;

            if (thisFooter.DiskType == TYPE_DYNAMIC || thisFooter.DiskType == TYPE_DIFFERENCING)
            {
                imageStream.Seek((long)thisFooter.Offset, SeekOrigin.Begin);
                byte[] dynamicBytes = new byte[1024];
                imageStream.Read(dynamicBytes, 0, 1024);

                uint dynamicChecksum = BigEndianBitConverter.ToUInt32(dynamicBytes, 0x24);

                dynamicBytes[0x24] = 0;
                dynamicBytes[0x25] = 0;
                dynamicBytes[0x26] = 0;
                dynamicBytes[0x27] = 0;

                uint dynamicChecksumCalculated = VhdChecksum(dynamicBytes);

                DicConsole.DebugWriteLine("VirtualPC plugin",
                                          "Dynamic header checksum = 0x{0:X8}, calculated = 0x{1:X8}", dynamicChecksum,
                                          dynamicChecksumCalculated);

                if (dynamicChecksum != dynamicChecksumCalculated)
                {
                    throw new
                          ImageNotSupportedException("(VirtualPC plugin): Both header and footer are corrupt, image cannot be opened.");
                }

                thisDynamic =
                    new DynamicDiskHeader {
                    LocatorEntries = new ParentLocatorEntry[8], Reserved2 = new byte[256]
                };

                for (int i = 0; i < 8; i++)
                {
                    thisDynamic.LocatorEntries[i] = new ParentLocatorEntry();
                }

                thisDynamic.Cookie          = BigEndianBitConverter.ToUInt64(dynamicBytes, 0x00);
                thisDynamic.DataOffset      = BigEndianBitConverter.ToUInt64(dynamicBytes, 0x08);
                thisDynamic.TableOffset     = BigEndianBitConverter.ToUInt64(dynamicBytes, 0x10);
                thisDynamic.HeaderVersion   = BigEndianBitConverter.ToUInt32(dynamicBytes, 0x18);
                thisDynamic.MaxTableEntries = BigEndianBitConverter.ToUInt32(dynamicBytes, 0x1C);
                thisDynamic.BlockSize       = BigEndianBitConverter.ToUInt32(dynamicBytes, 0x20);
                thisDynamic.Checksum        = dynamicChecksum;
                thisDynamic.ParentId        = BigEndianBitConverter.ToGuid(dynamicBytes, 0x28);
                thisDynamic.ParentTimestamp = BigEndianBitConverter.ToUInt32(dynamicBytes, 0x38);
                thisDynamic.Reserved        = BigEndianBitConverter.ToUInt32(dynamicBytes, 0x3C);
                thisDynamic.ParentName      = Encoding.BigEndianUnicode.GetString(dynamicBytes, 0x40, 512);

                for (int i = 0; i < 8; i++)
                {
                    thisDynamic.LocatorEntries[i].PlatformCode =
                        BigEndianBitConverter.ToUInt32(dynamicBytes, 0x240 + 0x00 + 24 * i);
                    thisDynamic.LocatorEntries[i].PlatformDataSpace =
                        BigEndianBitConverter.ToUInt32(dynamicBytes, 0x240 + 0x04 + 24 * i);
                    thisDynamic.LocatorEntries[i].PlatformDataLength =
                        BigEndianBitConverter.ToUInt32(dynamicBytes, 0x240 + 0x08 + 24 * i);
                    thisDynamic.LocatorEntries[i].Reserved =
                        BigEndianBitConverter.ToUInt32(dynamicBytes, 0x240 + 0x0C + 24 * i);
                    thisDynamic.LocatorEntries[i].PlatformDataOffset =
                        BigEndianBitConverter.ToUInt64(dynamicBytes, 0x240 + 0x10 + 24 * i);
                }

                Array.Copy(dynamicBytes, 0x300, thisDynamic.Reserved2, 0, 256);

                parentDateTime = new DateTime(2000, 1, 1, 0, 0, 0, DateTimeKind.Utc);
                parentDateTime = parentDateTime.AddSeconds(thisDynamic.ParentTimestamp);

                sha1Ctx = new Sha1Context();
                sha1Ctx.Update(thisDynamic.Reserved2);

                DicConsole.DebugWriteLine("VirtualPC plugin", "dynamic.cookie = 0x{0:X8}", thisDynamic.Cookie);
                DicConsole.DebugWriteLine("VirtualPC plugin", "dynamic.dataOffset = {0}", thisDynamic.DataOffset);
                DicConsole.DebugWriteLine("VirtualPC plugin", "dynamic.tableOffset = {0}", thisDynamic.TableOffset);
                DicConsole.DebugWriteLine("VirtualPC plugin", "dynamic.headerVersion = 0x{0:X8}",
                                          thisDynamic.HeaderVersion);
                DicConsole.DebugWriteLine("VirtualPC plugin", "dynamic.maxTableEntries = {0}",
                                          thisDynamic.MaxTableEntries);
                DicConsole.DebugWriteLine("VirtualPC plugin", "dynamic.blockSize = {0}", thisDynamic.BlockSize);
                DicConsole.DebugWriteLine("VirtualPC plugin", "dynamic.checksum = 0x{0:X8}", thisDynamic.Checksum);
                DicConsole.DebugWriteLine("VirtualPC plugin", "dynamic.parentID = {0}", thisDynamic.ParentId);
                DicConsole.DebugWriteLine("VirtualPC plugin", "dynamic.parentTimestamp = 0x{0:X8} ({1})",
                                          thisDynamic.ParentTimestamp, parentDateTime);
                DicConsole.DebugWriteLine("VirtualPC plugin", "dynamic.reserved = 0x{0:X8}", thisDynamic.Reserved);
                for (int i = 0; i < 8; i++)
                {
                    DicConsole.DebugWriteLine("VirtualPC plugin",
                                              "dynamic.locatorEntries[{0}].platformCode = 0x{1:X8} (\"{2}\")", i,
                                              thisDynamic.LocatorEntries[i].PlatformCode,
                                              Encoding.ASCII.GetString(BigEndianBitConverter.GetBytes(thisDynamic
                                                                                                      .LocatorEntries[i]
                                                                                                      .PlatformCode)));
                    DicConsole.DebugWriteLine("VirtualPC plugin", "dynamic.locatorEntries[{0}].platformDataSpace = {1}",
                                              i, thisDynamic.LocatorEntries[i].PlatformDataSpace);
                    DicConsole.DebugWriteLine("VirtualPC plugin",
                                              "dynamic.locatorEntries[{0}].platformDataLength = {1}", i,
                                              thisDynamic.LocatorEntries[i].PlatformDataLength);
                    DicConsole.DebugWriteLine("VirtualPC plugin", "dynamic.locatorEntries[{0}].reserved = 0x{1:X8}", i,
                                              thisDynamic.LocatorEntries[i].Reserved);
                    DicConsole.DebugWriteLine("VirtualPC plugin",
                                              "dynamic.locatorEntries[{0}].platformDataOffset = {1}", i,
                                              thisDynamic.LocatorEntries[i].PlatformDataOffset);
                }

                DicConsole.DebugWriteLine("VirtualPC plugin", "dynamic.parentName = \"{0}\"",
                                          thisDynamic.ParentName);
                DicConsole.DebugWriteLine("VirtualPC plugin", "dynamic.reserved2's SHA1 = 0x{0}", sha1Ctx.End());

                if (thisDynamic.HeaderVersion != VERSION1)
                {
                    throw new
                          ImageNotSupportedException($"(VirtualPC plugin): Unknown image type {thisFooter.DiskType} found. Please submit a bug with an example image.");
                }

                DateTime startTime = DateTime.UtcNow;

                blockAllocationTable = new uint[thisDynamic.MaxTableEntries];

                // Safe and slow code. It takes 76,572 ms to fill a 30720 entries BAT

                /*
                 * byte[] bat = new byte[thisDynamic.maxTableEntries * 4];
                 * imageStream.Seek((long)thisDynamic.tableOffset, SeekOrigin.Begin);
                 * imageStream.Read(bat, 0, (int)(thisDynamic.maxTableEntries * 4));
                 * for (int i = 0; i < thisDynamic.maxTableEntries; i++)
                 *  blockAllocationTable[i] = BigEndianBitConverter.ToUInt32(bat, 4 * i);
                 *
                 * DateTime endTime = DateTime.UtcNow;
                 * DicConsole.DebugWriteLine("VirtualPC plugin", "Filling the BAT took {0} seconds", (endTime-startTime).TotalSeconds);
                 */

                // How many sectors uses the BAT
                uint batSectorCount = (uint)Math.Ceiling((double)thisDynamic.MaxTableEntries * 4 / 512);

                byte[] batSectorBytes = new byte[512];

                // Unsafe and fast code. It takes 4 ms to fill a 30720 entries BAT
                for (int i = 0; i < batSectorCount; i++)
                {
                    imageStream.Seek((long)thisDynamic.TableOffset + i * 512, SeekOrigin.Begin);
                    imageStream.Read(batSectorBytes, 0, 512);
                    // This does the big-endian trick but reverses the order of elements also
                    Array.Reverse(batSectorBytes);
                    GCHandle  handle    = GCHandle.Alloc(batSectorBytes, GCHandleType.Pinned);
                    BatSector batSector =
                        (BatSector)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(BatSector));
                    handle.Free();
                    // This restores the order of elements
                    Array.Reverse(batSector.blockPointer);
                    if (blockAllocationTable.Length >= i * 512 / 4 + 512 / 4)
                    {
                        Array.Copy(batSector.blockPointer, 0, blockAllocationTable, i * 512 / 4, 512 / 4);
                    }
                    else
                    {
                        Array.Copy(batSector.blockPointer, 0, blockAllocationTable, i * 512 / 4,
                                   blockAllocationTable.Length - i * 512 / 4);
                    }
                }

                DateTime endTime = DateTime.UtcNow;
                DicConsole.DebugWriteLine("VirtualPC plugin", "Filling the BAT took {0} seconds",
                                          (endTime - startTime).TotalSeconds);

                // Too noisy

                /*
                 *  for (int i = 0; i < thisDynamic.maxTableEntries; i++)
                 *      DicConsole.DebugWriteLine("VirtualPC plugin", "blockAllocationTable[{0}] = {1}", i, blockAllocationTable[i]);
                 */

                // Get the roundest number of sectors needed to store the block bitmap
                bitmapSize = (uint)Math.Ceiling((double)thisDynamic.BlockSize / 512
                                                // 1 bit per sector on the bitmap
                                                / 8
                                                // and aligned to 512 byte boundary
                                                / 512);
                DicConsole.DebugWriteLine("VirtualPC plugin", "Bitmap is {0} sectors", bitmapSize);
            }

            imageInfo.XmlMediaType = XmlMediaType.BlockMedia;

            switch (thisFooter.DiskType)
            {
            case TYPE_FIXED:
            case TYPE_DYNAMIC:
            {
                // Nothing to do here, really.
                return(true);
            }

            case TYPE_DIFFERENCING:
            {
                locatorEntriesData = new byte[8][];
                for (int i = 0; i < 8; i++)
                {
                    if (thisDynamic.LocatorEntries[i].PlatformCode != 0x00000000)
                    {
                        locatorEntriesData[i] = new byte[thisDynamic.LocatorEntries[i].PlatformDataLength];
                        imageStream.Seek((long)thisDynamic.LocatorEntries[i].PlatformDataOffset, SeekOrigin.Begin);
                        imageStream.Read(locatorEntriesData[i], 0,
                                         (int)thisDynamic.LocatorEntries[i].PlatformDataLength);

                        switch (thisDynamic.LocatorEntries[i].PlatformCode)
                        {
                        case PLATFORM_CODE_WINDOWS_ABSOLUTE:
                        case PLATFORM_CODE_WINDOWS_RELATIVE:
                            DicConsole.DebugWriteLine("VirtualPC plugin",
                                                      "dynamic.locatorEntries[{0}] = \"{1}\"", i,
                                                      Encoding.ASCII.GetString(locatorEntriesData[i]));
                            break;

                        case PLATFORM_CODE_WINDOWS_ABSOLUTE_U:
                        case PLATFORM_CODE_WINDOWS_RELATIVE_U:
                            DicConsole.DebugWriteLine("VirtualPC plugin",
                                                      "dynamic.locatorEntries[{0}] = \"{1}\"", i,
                                                      Encoding.BigEndianUnicode
                                                      .GetString(locatorEntriesData[i]));
                            break;

                        case PLATFORM_CODE_MACINTOSH_URI:
                            DicConsole.DebugWriteLine("VirtualPC plugin",
                                                      "dynamic.locatorEntries[{0}] = \"{1}\"", i,
                                                      Encoding.UTF8.GetString(locatorEntriesData[i]));
                            break;

                        default:
                            DicConsole.DebugWriteLine("VirtualPC plugin", "dynamic.locatorEntries[{0}] =", i);
                            PrintHex.PrintHexArray(locatorEntriesData[i], 64);
                            break;
                        }
                    }
                }

                int    currentLocator = 0;
                bool   locatorFound   = false;
                string parentPath     = null;

                while (!locatorFound && currentLocator < 8)
                {
                    switch (thisDynamic.LocatorEntries[currentLocator].PlatformCode)
                    {
                    case PLATFORM_CODE_WINDOWS_ABSOLUTE:
                    case PLATFORM_CODE_WINDOWS_RELATIVE:
                        parentPath = Encoding.ASCII.GetString(locatorEntriesData[currentLocator]);
                        break;

                    case PLATFORM_CODE_WINDOWS_ABSOLUTE_U:
                    case PLATFORM_CODE_WINDOWS_RELATIVE_U:
                        parentPath = Encoding.BigEndianUnicode.GetString(locatorEntriesData[currentLocator]);
                        break;

                    case PLATFORM_CODE_MACINTOSH_URI:
                        parentPath =
                            Uri.UnescapeDataString(Encoding.UTF8.GetString(locatorEntriesData[currentLocator]));
                        if (parentPath.StartsWith("file://localhost", StringComparison.InvariantCulture))
                        {
                            parentPath = parentPath.Remove(0, 16);
                        }
                        else
                        {
                            DicConsole.DebugWriteLine("VirtualPC plugin",
                                                      "Unsupported protocol classified found in URI parent path: \"{0}\"",
                                                      parentPath);
                            parentPath = null;
                        }

                        break;
                    }

                    if (parentPath != null)
                    {
                        DicConsole.DebugWriteLine("VirtualPC plugin", "Possible parent path: \"{0}\"", parentPath);
                        IFilter parentFilter =
                            new FiltersList().GetFilter(Path.Combine(imageFilter.GetParentFolder(), parentPath));

                        if (parentFilter != null)
                        {
                            locatorFound = true;
                        }

                        if (!locatorFound)
                        {
                            parentPath = null;
                        }
                    }

                    currentLocator++;
                }

                if (!locatorFound)
                {
                    throw new
                          FileNotFoundException("(VirtualPC plugin): Cannot find parent file for differencing disk image");
                }

                {
                    parentImage = new Vhd();
                    IFilter parentFilter =
                        new FiltersList().GetFilter(Path.Combine(imageFilter.GetParentFolder(), parentPath));

                    if (parentFilter == null)
                    {
                        throw new ImageNotSupportedException("(VirtualPC plugin): Cannot find parent image filter");
                    }

                    /*                            PluginBase plugins = new PluginBase();
                     *                          plugins.RegisterAllPlugins();
                     *                          if (!plugins.ImagePluginsList.TryGetValue(Name.ToLower(), out parentImage))
                     *                              throw new SystemException("(VirtualPC plugin): Unable to open myself");*/

                    if (!parentImage.Identify(parentFilter))
                    {
                        throw new
                              ImageNotSupportedException("(VirtualPC plugin): Parent image is not a Virtual PC disk image");
                    }

                    if (!parentImage.Open(parentFilter))
                    {
                        throw new ImageNotSupportedException("(VirtualPC plugin): Cannot open parent disk image");
                    }

                    // While specification says that parent and child disk images should contain UUID relationship
                    // in reality it seems that old differencing disk images stored a parent UUID that, nonetheless
                    // the parent never stored itself. So the only real way to know that images are related is
                    // because the parent IS found and SAME SIZE. Ugly...
                    // More funny even, tested parent images show an empty host OS, and child images a correct one.
                    if (parentImage.Info.Sectors != imageInfo.Sectors)
                    {
                        throw new
                              ImageNotSupportedException("(VirtualPC plugin): Parent image is of different size");
                    }
                }

                return(true);
            }

            case TYPE_DEPRECATED1:
            case TYPE_DEPRECATED2:
            case TYPE_DEPRECATED3:
            {
                throw new
                      ImageNotSupportedException("(VirtualPC plugin): Deprecated image type found. Please submit a bug with an example image.");
            }

            default:
            {
                throw new
                      ImageNotSupportedException($"(VirtualPC plugin): Unknown image type {thisFooter.DiskType} found. Please submit a bug with an example image.");
            }
            }
        }
Пример #4
0
        public bool?VerifyMediaImage()
        {
            if (_discImage.DiscHashes.Count == 0)
            {
                return(null);
            }

            // Read up to 1 MiB at a time for verification
            const int verifySize = 1024 * 1024;
            long      readBytes;

            byte[] verifyBytes;

            IFilter[] filters = _discImage.Tracks.OrderBy(t => t.Sequence).Select(t => t.TrackFile.DataFilter).
                                Distinct().ToArray();

            if (_discImage.DiscHashes.TryGetValue("sha1", out string sha1))
            {
                var ctx = new Sha1Context();

                foreach (IFilter filter in filters)
                {
                    Stream stream = filter.GetDataForkStream();
                    readBytes   = 0;
                    verifyBytes = new byte[verifySize];

                    while (readBytes + verifySize < stream.Length)
                    {
                        stream.Read(verifyBytes, 0, verifyBytes.Length);
                        ctx.Update(verifyBytes);
                        readBytes += verifyBytes.LongLength;
                    }

                    verifyBytes = new byte[stream.Length - readBytes];
                    stream.Read(verifyBytes, 0, verifyBytes.Length);
                    ctx.Update(verifyBytes);
                }

                string verifySha1 = ctx.End();
                AaruConsole.DebugWriteLine("CDRWin plugin", "Calculated SHA1: {0}", verifySha1);
                AaruConsole.DebugWriteLine("CDRWin plugin", "Expected SHA1: {0}", sha1);

                return(verifySha1 == sha1);
            }

            if (_discImage.DiscHashes.TryGetValue("md5", out string md5))
            {
                var ctx = new Md5Context();

                foreach (IFilter filter in filters)
                {
                    Stream stream = filter.GetDataForkStream();
                    readBytes   = 0;
                    verifyBytes = new byte[verifySize];

                    while (readBytes + verifySize < stream.Length)
                    {
                        stream.Read(verifyBytes, 0, verifyBytes.Length);
                        ctx.Update(verifyBytes);
                        readBytes += verifyBytes.LongLength;
                    }

                    verifyBytes = new byte[stream.Length - readBytes];
                    stream.Read(verifyBytes, 0, verifyBytes.Length);
                    ctx.Update(verifyBytes);
                }

                string verifyMd5 = ctx.End();
                AaruConsole.DebugWriteLine("CDRWin plugin", "Calculated MD5: {0}", verifyMd5);
                AaruConsole.DebugWriteLine("CDRWin plugin", "Expected MD5: {0}", md5);

                return(verifyMd5 == md5);
            }

            if (_discImage.DiscHashes.TryGetValue("crc32", out string crc32))
            {
                var ctx = new Crc32Context();

                foreach (IFilter filter in filters)
                {
                    Stream stream = filter.GetDataForkStream();
                    readBytes   = 0;
                    verifyBytes = new byte[verifySize];

                    while (readBytes + verifySize < stream.Length)
                    {
                        stream.Read(verifyBytes, 0, verifyBytes.Length);
                        ctx.Update(verifyBytes);
                        readBytes += verifyBytes.LongLength;
                    }

                    verifyBytes = new byte[stream.Length - readBytes];
                    stream.Read(verifyBytes, 0, verifyBytes.Length);
                    ctx.Update(verifyBytes);
                }

                string verifyCrc = ctx.End();
                AaruConsole.DebugWriteLine("CDRWin plugin", "Calculated CRC32: {0}", verifyCrc);
                AaruConsole.DebugWriteLine("CDRWin plugin", "Expected CRC32: {0}", crc32);

                return(verifyCrc == crc32);
            }

            foreach (string hash in _discImage.DiscHashes.Keys)
            {
                AaruConsole.DebugWriteLine("CDRWin plugin", "Found unsupported hash {0}", hash);
            }

            return(null);
        }
Пример #5
0
        public static BenchmarkResults Do(int bufferSize, int blockSize)
        {
            BenchmarkResults results = new BenchmarkResults
            {
                Entries      = new Dictionary <string, BenchmarkEntry>(),
                MinMemory    = long.MaxValue,
                MaxMemory    = 0,
                SeparateTime = 0
            };
            MemoryStream ms  = new MemoryStream(bufferSize);
            Random       rnd = new Random();
            DateTime     start;
            DateTime     end;

            start = DateTime.Now;
            InitProgress();
            for (int i = 0; i < bufferSize / blockSize; i++)
            {
                UpdateProgress("Writing block {0} of {1} with random data.", i + 1, bufferSize / blockSize);
                byte[] tmp = new byte[blockSize];
                rnd.NextBytes(tmp);
                ms.Write(tmp, 0, blockSize);
            }

            EndProgress();
            end = DateTime.Now;

            results.FillTime  = (end - start).TotalSeconds;
            results.FillSpeed = bufferSize / 1048576.0 / (end - start).TotalSeconds;

            ms.Seek(0, SeekOrigin.Begin);
            long mem = GC.GetTotalMemory(false);

            if (mem > results.MaxMemory)
            {
                results.MaxMemory = mem;
            }
            if (mem < results.MinMemory)
            {
                results.MinMemory = mem;
            }
            start = DateTime.Now;
            InitProgress();
            for (int i = 0; i < bufferSize / blockSize; i++)
            {
                UpdateProgress("Reading block {0} of {1}.", i + 1, bufferSize / blockSize);
                byte[] tmp = new byte[blockSize];
                ms.Read(tmp, 0, blockSize);
            }

            EndProgress();
            end = DateTime.Now;
            mem = GC.GetTotalMemory(false);
            if (mem > results.MaxMemory)
            {
                results.MaxMemory = mem;
            }
            if (mem < results.MinMemory)
            {
                results.MinMemory = mem;
            }

            results.ReadTime  = (end - start).TotalSeconds;
            results.ReadSpeed = bufferSize / 1048576.0 / (end - start).TotalSeconds;

            #region Adler32
            IChecksum ctx = new Adler32Context();
            ms.Seek(0, SeekOrigin.Begin);
            mem = GC.GetTotalMemory(false);
            if (mem > results.MaxMemory)
            {
                results.MaxMemory = mem;
            }
            if (mem < results.MinMemory)
            {
                results.MinMemory = mem;
            }
            start = DateTime.Now;
            InitProgress();
            for (int i = 0; i < bufferSize / blockSize; i++)
            {
                UpdateProgress("Checksumming block {0} of {1} with Adler32.", i + 1, bufferSize / blockSize);
                byte[] tmp = new byte[blockSize];
                ms.Read(tmp, 0, blockSize);
                ctx.Update(tmp);
            }

            EndProgress();
            ctx.End();
            end = DateTime.Now;
            mem = GC.GetTotalMemory(false);
            if (mem > results.MaxMemory)
            {
                results.MaxMemory = mem;
            }
            if (mem < results.MinMemory)
            {
                results.MinMemory = mem;
            }

            results.Entries.Add("Adler32",
                                new BenchmarkEntry
            {
                TimeSpan = (end - start).TotalSeconds,
                Speed    = bufferSize / 1048576.0 / (end - start).TotalSeconds
            });
            results.SeparateTime += (end - start).TotalSeconds;
            #endregion Adler32

            #region Fletcher16
            ctx = new Fletcher16Context();
            ms.Seek(0, SeekOrigin.Begin);
            mem = GC.GetTotalMemory(false);
            if (mem > results.MaxMemory)
            {
                results.MaxMemory = mem;
            }
            if (mem < results.MinMemory)
            {
                results.MinMemory = mem;
            }
            start = DateTime.Now;
            InitProgress();
            for (int i = 0; i < bufferSize / blockSize; i++)
            {
                UpdateProgress("Checksumming block {0} of {1} with Fletcher-16.", i + 1, bufferSize / blockSize);
                byte[] tmp = new byte[blockSize];
                ms.Read(tmp, 0, blockSize);
                ctx.Update(tmp);
            }

            EndProgress();
            ctx.End();
            end = DateTime.Now;
            mem = GC.GetTotalMemory(false);
            if (mem > results.MaxMemory)
            {
                results.MaxMemory = mem;
            }
            if (mem < results.MinMemory)
            {
                results.MinMemory = mem;
            }

            results.Entries.Add("Fletcher16",
                                new BenchmarkEntry
            {
                TimeSpan = (end - start).TotalSeconds,
                Speed    = bufferSize / 1048576.0 / (end - start).TotalSeconds
            });
            results.SeparateTime += (end - start).TotalSeconds;
            #endregion Fletcher16

            #region Fletcher32
            ctx = new Fletcher32Context();
            ms.Seek(0, SeekOrigin.Begin);
            mem = GC.GetTotalMemory(false);
            if (mem > results.MaxMemory)
            {
                results.MaxMemory = mem;
            }
            if (mem < results.MinMemory)
            {
                results.MinMemory = mem;
            }
            start = DateTime.Now;
            InitProgress();
            for (int i = 0; i < bufferSize / blockSize; i++)
            {
                UpdateProgress("Checksumming block {0} of {1} with Fletcher-32.", i + 1, bufferSize / blockSize);
                byte[] tmp = new byte[blockSize];
                ms.Read(tmp, 0, blockSize);
                ctx.Update(tmp);
            }

            EndProgress();
            ctx.End();
            end = DateTime.Now;
            mem = GC.GetTotalMemory(false);
            if (mem > results.MaxMemory)
            {
                results.MaxMemory = mem;
            }
            if (mem < results.MinMemory)
            {
                results.MinMemory = mem;
            }

            results.Entries.Add("Fletcher32",
                                new BenchmarkEntry
            {
                TimeSpan = (end - start).TotalSeconds,
                Speed    = bufferSize / 1048576.0 / (end - start).TotalSeconds
            });
            results.SeparateTime += (end - start).TotalSeconds;
            #endregion Fletcher32

            #region CRC16
            ctx = new Crc16Context();
            ms.Seek(0, SeekOrigin.Begin);
            mem = GC.GetTotalMemory(false);
            if (mem > results.MaxMemory)
            {
                results.MaxMemory = mem;
            }
            if (mem < results.MinMemory)
            {
                results.MinMemory = mem;
            }
            start = DateTime.Now;
            InitProgress();
            for (int i = 0; i < bufferSize / blockSize; i++)
            {
                UpdateProgress("Checksumming block {0} of {1} with CRC16.", i + 1, bufferSize / blockSize);
                byte[] tmp = new byte[blockSize];
                ms.Read(tmp, 0, blockSize);
                ctx.Update(tmp);
            }

            EndProgress();
            ctx.End();
            end = DateTime.Now;
            mem = GC.GetTotalMemory(false);
            if (mem > results.MaxMemory)
            {
                results.MaxMemory = mem;
            }
            if (mem < results.MinMemory)
            {
                results.MinMemory = mem;
            }

            results.Entries.Add("CRC16",
                                new BenchmarkEntry
            {
                TimeSpan = (end - start).TotalSeconds,
                Speed    = bufferSize / 1048576.0 / (end - start).TotalSeconds
            });
            results.SeparateTime += (end - start).TotalSeconds;
            #endregion CRC16

            #region CRC32
            ctx = new Crc32Context();
            ms.Seek(0, SeekOrigin.Begin);
            mem = GC.GetTotalMemory(false);
            if (mem > results.MaxMemory)
            {
                results.MaxMemory = mem;
            }
            if (mem < results.MinMemory)
            {
                results.MinMemory = mem;
            }
            start = DateTime.Now;
            InitProgress();
            for (int i = 0; i < bufferSize / blockSize; i++)
            {
                UpdateProgress("Checksumming block {0} of {1} with CRC32.", i + 1, bufferSize / blockSize);
                byte[] tmp = new byte[blockSize];
                ms.Read(tmp, 0, blockSize);
                ctx.Update(tmp);
            }

            EndProgress();
            ctx.End();
            end = DateTime.Now;
            mem = GC.GetTotalMemory(false);
            if (mem > results.MaxMemory)
            {
                results.MaxMemory = mem;
            }
            if (mem < results.MinMemory)
            {
                results.MinMemory = mem;
            }

            results.Entries.Add("CRC32",
                                new BenchmarkEntry
            {
                TimeSpan = (end - start).TotalSeconds,
                Speed    = bufferSize / 1048576.0 / (end - start).TotalSeconds
            });
            results.SeparateTime += (end - start).TotalSeconds;
            #endregion CRC32

            #region CRC64
            ctx = new Crc64Context();
            ms.Seek(0, SeekOrigin.Begin);
            mem = GC.GetTotalMemory(false);
            if (mem > results.MaxMemory)
            {
                results.MaxMemory = mem;
            }
            if (mem < results.MinMemory)
            {
                results.MinMemory = mem;
            }
            start = DateTime.Now;
            InitProgress();
            for (int i = 0; i < bufferSize / blockSize; i++)
            {
                UpdateProgress("Checksumming block {0} of {1} with CRC64.", i + 1, bufferSize / blockSize);
                byte[] tmp = new byte[blockSize];
                ms.Read(tmp, 0, blockSize);
                ctx.Update(tmp);
            }

            EndProgress();
            ctx.End();
            end = DateTime.Now;
            mem = GC.GetTotalMemory(false);
            if (mem > results.MaxMemory)
            {
                results.MaxMemory = mem;
            }
            if (mem < results.MinMemory)
            {
                results.MinMemory = mem;
            }

            results.Entries.Add("CRC64",
                                new BenchmarkEntry
            {
                TimeSpan = (end - start).TotalSeconds,
                Speed    = bufferSize / 1048576.0 / (end - start).TotalSeconds
            });
            results.SeparateTime += (end - start).TotalSeconds;
            #endregion CRC64

            #region MD5
            ctx = new Md5Context();
            ms.Seek(0, SeekOrigin.Begin);
            mem = GC.GetTotalMemory(false);
            if (mem > results.MaxMemory)
            {
                results.MaxMemory = mem;
            }
            if (mem < results.MinMemory)
            {
                results.MinMemory = mem;
            }
            start = DateTime.Now;
            InitProgress();
            for (int i = 0; i < bufferSize / blockSize; i++)
            {
                UpdateProgress("Checksumming block {0} of {1} with MD5.", i + 1, bufferSize / blockSize);
                byte[] tmp = new byte[blockSize];
                ms.Read(tmp, 0, blockSize);
                ctx.Update(tmp);
            }

            EndProgress();
            ctx.End();
            end = DateTime.Now;
            mem = GC.GetTotalMemory(false);
            if (mem > results.MaxMemory)
            {
                results.MaxMemory = mem;
            }
            if (mem < results.MinMemory)
            {
                results.MinMemory = mem;
            }

            results.Entries.Add("MD5",
                                new BenchmarkEntry
            {
                TimeSpan = (end - start).TotalSeconds,
                Speed    = bufferSize / 1048576.0 / (end - start).TotalSeconds
            });
            results.SeparateTime += (end - start).TotalSeconds;
            #endregion MD5

            #if !NETSTANDARD2_0
            #region RIPEMD160
            ctx = new Ripemd160Context();
            ms.Seek(0, SeekOrigin.Begin);
            mem = GC.GetTotalMemory(false);
            if (mem > results.MaxMemory)
            {
                results.MaxMemory = mem;
            }
            if (mem < results.MinMemory)
            {
                results.MinMemory = mem;
            }
            start = DateTime.Now;
            InitProgress();
            for (int i = 0; i < bufferSize / blockSize; i++)
            {
                UpdateProgress("Checksumming block {0} of {1} with RIPEMD160.", i + 1, bufferSize / blockSize);
                byte[] tmp = new byte[blockSize];
                ms.Read(tmp, 0, blockSize);
                ctx.Update(tmp);
            }

            EndProgress();
            ctx.End();
            end = DateTime.Now;
            mem = GC.GetTotalMemory(false);
            if (mem > results.MaxMemory)
            {
                results.MaxMemory = mem;
            }
            if (mem < results.MinMemory)
            {
                results.MinMemory = mem;
            }

            results.Entries.Add("RIPEMD160",
                                new BenchmarkEntry
            {
                TimeSpan = (end - start).TotalSeconds,
                Speed    = bufferSize / 1048576.0 / (end - start).TotalSeconds
            });
            results.SeparateTime += (end - start).TotalSeconds;
            #endregion RIPEMD160
            #endif

            #region SHA1
            ctx = new Sha1Context();
            ms.Seek(0, SeekOrigin.Begin);
            mem = GC.GetTotalMemory(false);
            if (mem > results.MaxMemory)
            {
                results.MaxMemory = mem;
            }
            if (mem < results.MinMemory)
            {
                results.MinMemory = mem;
            }
            start = DateTime.Now;
            InitProgress();
            for (int i = 0; i < bufferSize / blockSize; i++)
            {
                UpdateProgress("Checksumming block {0} of {1} with SHA1.", i + 1, bufferSize / blockSize);
                byte[] tmp = new byte[blockSize];
                ms.Read(tmp, 0, blockSize);
                ctx.Update(tmp);
            }

            EndProgress();
            ctx.End();
            end = DateTime.Now;
            mem = GC.GetTotalMemory(false);
            if (mem > results.MaxMemory)
            {
                results.MaxMemory = mem;
            }
            if (mem < results.MinMemory)
            {
                results.MinMemory = mem;
            }

            results.Entries.Add("SHA1",
                                new BenchmarkEntry
            {
                TimeSpan = (end - start).TotalSeconds,
                Speed    = bufferSize / 1048576.0 / (end - start).TotalSeconds
            });
            results.SeparateTime += (end - start).TotalSeconds;
            #endregion SHA1

            #region SHA256
            ctx = new Sha256Context();
            ms.Seek(0, SeekOrigin.Begin);
            mem = GC.GetTotalMemory(false);
            if (mem > results.MaxMemory)
            {
                results.MaxMemory = mem;
            }
            if (mem < results.MinMemory)
            {
                results.MinMemory = mem;
            }
            start = DateTime.Now;
            InitProgress();
            for (int i = 0; i < bufferSize / blockSize; i++)
            {
                UpdateProgress("Checksumming block {0} of {1} with SHA256.", i + 1, bufferSize / blockSize);
                byte[] tmp = new byte[blockSize];
                ms.Read(tmp, 0, blockSize);
                ctx.Update(tmp);
            }

            EndProgress();
            ctx.End();
            end = DateTime.Now;
            mem = GC.GetTotalMemory(false);
            if (mem > results.MaxMemory)
            {
                results.MaxMemory = mem;
            }
            if (mem < results.MinMemory)
            {
                results.MinMemory = mem;
            }

            results.Entries.Add("SHA256",
                                new BenchmarkEntry
            {
                TimeSpan = (end - start).TotalSeconds,
                Speed    = bufferSize / 1048576.0 / (end - start).TotalSeconds
            });
            results.SeparateTime += (end - start).TotalSeconds;
            #endregion SHA256

            #region SHA384
            ctx = new Sha384Context();
            ms.Seek(0, SeekOrigin.Begin);
            mem = GC.GetTotalMemory(false);
            if (mem > results.MaxMemory)
            {
                results.MaxMemory = mem;
            }
            if (mem < results.MinMemory)
            {
                results.MinMemory = mem;
            }
            start = DateTime.Now;
            InitProgress();
            for (int i = 0; i < bufferSize / blockSize; i++)
            {
                UpdateProgress("Checksumming block {0} of {1} with SHA384.", i + 1, bufferSize / blockSize);
                byte[] tmp = new byte[blockSize];
                ms.Read(tmp, 0, blockSize);
                ctx.Update(tmp);
            }

            EndProgress();
            ctx.End();
            end = DateTime.Now;
            mem = GC.GetTotalMemory(false);
            if (mem > results.MaxMemory)
            {
                results.MaxMemory = mem;
            }
            if (mem < results.MinMemory)
            {
                results.MinMemory = mem;
            }

            results.Entries.Add("SHA384",
                                new BenchmarkEntry
            {
                TimeSpan = (end - start).TotalSeconds,
                Speed    = bufferSize / 1048576.0 / (end - start).TotalSeconds
            });
            results.SeparateTime += (end - start).TotalSeconds;
            #endregion SHA384

            #region SHA512
            ctx = new Sha512Context();
            ms.Seek(0, SeekOrigin.Begin);
            mem = GC.GetTotalMemory(false);
            if (mem > results.MaxMemory)
            {
                results.MaxMemory = mem;
            }
            if (mem < results.MinMemory)
            {
                results.MinMemory = mem;
            }
            start = DateTime.Now;
            InitProgress();
            for (int i = 0; i < bufferSize / blockSize; i++)
            {
                UpdateProgress("Checksumming block {0} of {1} with SHA512.", i + 1, bufferSize / blockSize);
                byte[] tmp = new byte[blockSize];
                ms.Read(tmp, 0, blockSize);
                ctx.Update(tmp);
            }

            EndProgress();
            ctx.End();
            end = DateTime.Now;
            mem = GC.GetTotalMemory(false);
            if (mem > results.MaxMemory)
            {
                results.MaxMemory = mem;
            }
            if (mem < results.MinMemory)
            {
                results.MinMemory = mem;
            }

            results.Entries.Add("SHA512",
                                new BenchmarkEntry
            {
                TimeSpan = (end - start).TotalSeconds,
                Speed    = bufferSize / 1048576.0 / (end - start).TotalSeconds
            });
            results.SeparateTime += (end - start).TotalSeconds;
            #endregion SHA512

            #region SpamSum
            ctx = new SpamSumContext();
            ms.Seek(0, SeekOrigin.Begin);
            mem = GC.GetTotalMemory(false);
            if (mem > results.MaxMemory)
            {
                results.MaxMemory = mem;
            }
            if (mem < results.MinMemory)
            {
                results.MinMemory = mem;
            }
            start = DateTime.Now;
            InitProgress();
            for (int i = 0; i < bufferSize / blockSize; i++)
            {
                UpdateProgress("Checksumming block {0} of {1} with SpamSum.", i + 1, bufferSize / blockSize);
                byte[] tmp = new byte[blockSize];
                ms.Read(tmp, 0, blockSize);
                ctx.Update(tmp);
            }

            EndProgress();
            ctx.End();
            end = DateTime.Now;
            mem = GC.GetTotalMemory(false);
            if (mem > results.MaxMemory)
            {
                results.MaxMemory = mem;
            }
            if (mem < results.MinMemory)
            {
                results.MinMemory = mem;
            }

            results.Entries.Add("SpamSum",
                                new BenchmarkEntry
            {
                TimeSpan = (end - start).TotalSeconds,
                Speed    = bufferSize / 1048576.0 / (end - start).TotalSeconds
            });
            results.SeparateTime += (end - start).TotalSeconds;
            #endregion SpamSum

            #region Entropy
            ulong[] entTable = new ulong[256];
            ms.Seek(0, SeekOrigin.Begin);
            mem = GC.GetTotalMemory(false);
            if (mem > results.MaxMemory)
            {
                results.MaxMemory = mem;
            }
            if (mem < results.MinMemory)
            {
                results.MinMemory = mem;
            }
            start = DateTime.Now;
            InitProgress();
            for (int i = 0; i < bufferSize / blockSize; i++)
            {
                UpdateProgress("Entropying block {0} of {1}.", i + 1, bufferSize / blockSize);
                byte[] tmp = new byte[blockSize];
                ms.Read(tmp, 0, blockSize);
                foreach (byte b in tmp)
                {
                    entTable[b]++;
                }
            }

            EndProgress();

            end = DateTime.Now;
            mem = GC.GetTotalMemory(false);
            if (mem > results.MaxMemory)
            {
                results.MaxMemory = mem;
            }
            if (mem < results.MinMemory)
            {
                results.MinMemory = mem;
            }

            results.EntropyTime  = (end - start).TotalSeconds;
            results.EntropySpeed = bufferSize / 1048576.0 / (end - start).TotalSeconds;
            #endregion Entropy

            /*
             #region Multitasking
             * start                 = DateTime.Now;
             * Checksum allChecksums = new Checksum();
             * InitProgress();
             * for(int i = 0; i < bufferSize / blockSize; i++)
             * {
             *  UpdateProgress("Checksumming block {0} of {1} with all algorithms at the same time.", i + 1,
             *                 bufferSize / blockSize);
             *  byte[] tmp = new byte[blockSize];
             *  ms.Read(tmp, 0, blockSize);
             *
             *  allChecksums.Update(tmp);
             * }
             *
             * EndProgress();
             *
             * allChecksums.End();
             * end                                           = DateTime.Now;
             * mem                                           = GC.GetTotalMemory(false);
             * if(mem > results.MaxMemory) results.MaxMemory = mem;
             * if(mem < results.MinMemory) results.MinMemory = mem;
             *
             * results.TotalTime  = (end - start).TotalSeconds;
             * results.TotalSpeed = bufferSize / 1048576.0 / results.TotalTime;
             #endregion
             */
            results.SeparateSpeed = bufferSize / 1048576.0 / results.SeparateTime;

            return(results);
        }
Пример #6
0
        public bool GetInformation(IMediaImage imagePlugin, out List <Partition> partitions, ulong sectorOffset)
        {
            partitions = new List <Partition>();

            byte[] sector = imagePlugin.ReadSector(sectorOffset);

            if (sector.Length < 512)
            {
                return(false);
            }

            var table = new AtariTable
            {
                boot       = new byte[342],
                icdEntries = new AtariEntry[8],
                unused     = new byte[12],
                entries    = new AtariEntry[4]
            };

            Array.Copy(sector, 0, table.boot, 0, 342);

            for (int i = 0; i < 8; i++)
            {
                table.icdEntries[i].type   = BigEndianBitConverter.ToUInt32(sector, 342 + (i * 12) + 0);
                table.icdEntries[i].start  = BigEndianBitConverter.ToUInt32(sector, 342 + (i * 12) + 4);
                table.icdEntries[i].length = BigEndianBitConverter.ToUInt32(sector, 342 + (i * 12) + 8);
            }

            Array.Copy(sector, 438, table.unused, 0, 12);

            table.size = BigEndianBitConverter.ToUInt32(sector, 450);

            for (int i = 0; i < 4; i++)
            {
                table.entries[i].type   = BigEndianBitConverter.ToUInt32(sector, 454 + (i * 12) + 0);
                table.entries[i].start  = BigEndianBitConverter.ToUInt32(sector, 454 + (i * 12) + 4);
                table.entries[i].length = BigEndianBitConverter.ToUInt32(sector, 454 + (i * 12) + 8);
            }

            table.badStart  = BigEndianBitConverter.ToUInt32(sector, 502);
            table.badLength = BigEndianBitConverter.ToUInt32(sector, 506);
            table.checksum  = BigEndianBitConverter.ToUInt16(sector, 510);

            var sha1Ctx = new Sha1Context();

            sha1Ctx.Update(table.boot);
            AaruConsole.DebugWriteLine("Atari partition plugin", "Boot code SHA1: {0}", sha1Ctx.End());

            for (int i = 0; i < 8; i++)
            {
                AaruConsole.DebugWriteLine("Atari partition plugin", "table.icdEntries[{0}].flag = 0x{1:X2}", i,
                                           (table.icdEntries[i].type & 0xFF000000) >> 24);

                AaruConsole.DebugWriteLine("Atari partition plugin", "table.icdEntries[{0}].type = 0x{1:X6}", i,
                                           table.icdEntries[i].type & 0x00FFFFFF);

                AaruConsole.DebugWriteLine("Atari partition plugin", "table.icdEntries[{0}].start = {1}", i,
                                           table.icdEntries[i].start);

                AaruConsole.DebugWriteLine("Atari partition plugin", "table.icdEntries[{0}].length = {1}", i,
                                           table.icdEntries[i].length);
            }

            AaruConsole.DebugWriteLine("Atari partition plugin", "table.size = {0}", table.size);

            for (int i = 0; i < 4; i++)
            {
                AaruConsole.DebugWriteLine("Atari partition plugin", "table.entries[{0}].flag = 0x{1:X2}", i,
                                           (table.entries[i].type & 0xFF000000) >> 24);

                AaruConsole.DebugWriteLine("Atari partition plugin", "table.entries[{0}].type = 0x{1:X6}", i,
                                           table.entries[i].type & 0x00FFFFFF);

                AaruConsole.DebugWriteLine("Atari partition plugin", "table.entries[{0}].start = {1}", i,
                                           table.entries[i].start);

                AaruConsole.DebugWriteLine("Atari partition plugin", "table.entries[{0}].length = {1}", i,
                                           table.entries[i].length);
            }

            AaruConsole.DebugWriteLine("Atari partition plugin", "table.badStart = {0}", table.badStart);
            AaruConsole.DebugWriteLine("Atari partition plugin", "table.badLength = {0}", table.badLength);
            AaruConsole.DebugWriteLine("Atari partition plugin", "table.checksum = 0x{0:X4}", table.checksum);

            bool  validTable        = false;
            ulong partitionSequence = 0;

            for (int i = 0; i < 4; i++)
            {
                uint type = table.entries[i].type & 0x00FFFFFF;

                switch (type)
                {
                case TypeGEMDOS:
                case TypeBigGEMDOS:
                case TypeLinux:
                case TypeSwap:
                case TypeRAW:
                case TypeNetBSD:
                case TypeNetBSDSwap:
                case TypeSysV:
                case TypeMac:
                case TypeMinix:
                case TypeMinix2:
                    validTable = true;

                    if (table.entries[i].start <= imagePlugin.Info.Sectors)
                    {
                        if (table.entries[i].start + table.entries[i].length > imagePlugin.Info.Sectors)
                        {
                            AaruConsole.DebugWriteLine("Atari partition plugin",
                                                       "WARNING: End of partition goes beyond device size");
                        }

                        ulong sectorSize = imagePlugin.Info.SectorSize;

                        if (sectorSize == 2448 ||
                            sectorSize == 2352)
                        {
                            sectorSize = 2048;
                        }

                        byte[] partType = new byte[3];
                        partType[0] = (byte)((type & 0xFF0000) >> 16);
                        partType[1] = (byte)((type & 0x00FF00) >> 8);
                        partType[2] = (byte)(type & 0x0000FF);

                        var part = new Partition
                        {
                            Size     = table.entries[i].length * sectorSize,
                            Length   = table.entries[i].length,
                            Sequence = partitionSequence,
                            Name     = "",
                            Offset   = table.entries[i].start * sectorSize,
                            Start    = table.entries[i].start,
                            Type     = Encoding.ASCII.GetString(partType),
                            Scheme   = Name
                        };

                        switch (type)
                        {
                        case TypeGEMDOS:
                            part.Description = "Atari GEMDOS partition";

                            break;

                        case TypeBigGEMDOS:
                            part.Description = "Atari GEMDOS partition bigger than 32 MiB";

                            break;

                        case TypeLinux:
                            part.Description = "Linux partition";

                            break;

                        case TypeSwap:
                            part.Description = "Swap partition";

                            break;

                        case TypeRAW:
                            part.Description = "RAW partition";

                            break;

                        case TypeNetBSD:
                            part.Description = "NetBSD partition";

                            break;

                        case TypeNetBSDSwap:
                            part.Description = "NetBSD swap partition";

                            break;

                        case TypeSysV:
                            part.Description = "Atari UNIX partition";

                            break;

                        case TypeMac:
                            part.Description = "Macintosh partition";

                            break;

                        case TypeMinix:
                        case TypeMinix2:
                            part.Description = "MINIX partition";

                            break;

                        default:
                            part.Description = "Unknown partition type";

                            break;
                        }

                        partitions.Add(part);
                        partitionSequence++;
                    }

                    break;

                case TypeExtended:
                    byte[] extendedSector = imagePlugin.ReadSector(table.entries[i].start);
                    var    extendedTable  = new AtariTable();
                    extendedTable.entries = new AtariEntry[4];

                    for (int j = 0; j < 4; j++)
                    {
                        extendedTable.entries[j].type =
                            BigEndianBitConverter.ToUInt32(extendedSector, 454 + (j * 12) + 0);

                        extendedTable.entries[j].start =
                            BigEndianBitConverter.ToUInt32(extendedSector, 454 + (j * 12) + 4);

                        extendedTable.entries[j].length =
                            BigEndianBitConverter.ToUInt32(extendedSector, 454 + (j * 12) + 8);
                    }

                    for (int j = 0; j < 4; j++)
                    {
                        uint extendedType = extendedTable.entries[j].type & 0x00FFFFFF;

                        if (extendedType != TypeGEMDOS &&
                            extendedType != TypeBigGEMDOS &&
                            extendedType != TypeLinux &&
                            extendedType != TypeSwap &&
                            extendedType != TypeRAW &&
                            extendedType != TypeNetBSD &&
                            extendedType != TypeNetBSDSwap &&
                            extendedType != TypeSysV &&
                            extendedType != TypeMac &&
                            extendedType != TypeMinix &&
                            extendedType != TypeMinix2)
                        {
                            continue;
                        }

                        validTable = true;

                        if (extendedTable.entries[j].start > imagePlugin.Info.Sectors)
                        {
                            continue;
                        }

                        if (extendedTable.entries[j].start + extendedTable.entries[j].length >
                            imagePlugin.Info.Sectors)
                        {
                            AaruConsole.DebugWriteLine("Atari partition plugin",
                                                       "WARNING: End of partition goes beyond device size");
                        }

                        ulong sectorSize = imagePlugin.Info.SectorSize;

                        if (sectorSize == 2448 ||
                            sectorSize == 2352)
                        {
                            sectorSize = 2048;
                        }

                        byte[] partType = new byte[3];
                        partType[0] = (byte)((extendedType & 0xFF0000) >> 16);
                        partType[1] = (byte)((extendedType & 0x00FF00) >> 8);
                        partType[2] = (byte)(extendedType & 0x0000FF);

                        var part = new Partition
                        {
                            Size     = extendedTable.entries[j].length * sectorSize,
                            Length   = extendedTable.entries[j].length,
                            Sequence = partitionSequence,
                            Name     = "",
                            Offset   = extendedTable.entries[j].start * sectorSize,
                            Start    = extendedTable.entries[j].start,
                            Type     = Encoding.ASCII.GetString(partType),
                            Scheme   = Name
                        };

                        switch (extendedType)
                        {
                        case TypeGEMDOS:
                            part.Description = "Atari GEMDOS partition";

                            break;

                        case TypeBigGEMDOS:
                            part.Description = "Atari GEMDOS partition bigger than 32 MiB";

                            break;

                        case TypeLinux:
                            part.Description = "Linux partition";

                            break;

                        case TypeSwap:
                            part.Description = "Swap partition";

                            break;

                        case TypeRAW:
                            part.Description = "RAW partition";

                            break;

                        case TypeNetBSD:
                            part.Description = "NetBSD partition";

                            break;

                        case TypeNetBSDSwap:
                            part.Description = "NetBSD swap partition";

                            break;

                        case TypeSysV:
                            part.Description = "Atari UNIX partition";

                            break;

                        case TypeMac:
                            part.Description = "Macintosh partition";

                            break;

                        case TypeMinix:
                        case TypeMinix2:
                            part.Description = "MINIX partition";

                            break;

                        default:
                            part.Description = "Unknown partition type";

                            break;
                        }

                        partitions.Add(part);
                        partitionSequence++;
                    }

                    break;
                }
            }

            if (!validTable)
            {
                return(partitions.Count > 0);
            }

            for (int i = 0; i < 8; i++)
            {
                uint type = table.icdEntries[i].type & 0x00FFFFFF;

                if (type != TypeGEMDOS &&
                    type != TypeBigGEMDOS &&
                    type != TypeLinux &&
                    type != TypeSwap &&
                    type != TypeRAW &&
                    type != TypeNetBSD &&
                    type != TypeNetBSDSwap &&
                    type != TypeSysV &&
                    type != TypeMac &&
                    type != TypeMinix &&
                    type != TypeMinix2)
                {
                    continue;
                }

                if (table.icdEntries[i].start > imagePlugin.Info.Sectors)
                {
                    continue;
                }

                if (table.icdEntries[i].start + table.icdEntries[i].length > imagePlugin.Info.Sectors)
                {
                    AaruConsole.DebugWriteLine("Atari partition plugin",
                                               "WARNING: End of partition goes beyond device size");
                }

                ulong sectorSize = imagePlugin.Info.SectorSize;

                if (sectorSize == 2448 ||
                    sectorSize == 2352)
                {
                    sectorSize = 2048;
                }

                byte[] partType = new byte[3];
                partType[0] = (byte)((type & 0xFF0000) >> 16);
                partType[1] = (byte)((type & 0x00FF00) >> 8);
                partType[2] = (byte)(type & 0x0000FF);

                var part = new Partition
                {
                    Size     = table.icdEntries[i].length * sectorSize,
                    Length   = table.icdEntries[i].length,
                    Sequence = partitionSequence,
                    Name     = "",
                    Offset   = table.icdEntries[i].start * sectorSize,
                    Start    = table.icdEntries[i].start,
                    Type     = Encoding.ASCII.GetString(partType),
                    Scheme   = Name
                };

                switch (type)
                {
                case TypeGEMDOS:
                    part.Description = "Atari GEMDOS partition";

                    break;

                case TypeBigGEMDOS:
                    part.Description = "Atari GEMDOS partition bigger than 32 MiB";

                    break;

                case TypeLinux:
                    part.Description = "Linux partition";

                    break;

                case TypeSwap:
                    part.Description = "Swap partition";

                    break;

                case TypeRAW:
                    part.Description = "RAW partition";

                    break;

                case TypeNetBSD:
                    part.Description = "NetBSD partition";

                    break;

                case TypeNetBSDSwap:
                    part.Description = "NetBSD swap partition";

                    break;

                case TypeSysV:
                    part.Description = "Atari UNIX partition";

                    break;

                case TypeMac:
                    part.Description = "Macintosh partition";

                    break;

                case TypeMinix:
                case TypeMinix2:
                    part.Description = "MINIX partition";

                    break;

                default:
                    part.Description = "Unknown partition type";

                    break;
                }

                partitions.Add(part);
                partitionSequence++;
            }

            return(partitions.Count > 0);
        }
Пример #7
0
        internal static List <ChecksumType> GetChecksums(byte[] data)
        {
            Adler32Context   adler32ctxData   = new Adler32Context();
            Crc16Context     crc16ctxData     = new Crc16Context();
            Crc32Context     crc32ctxData     = new Crc32Context();
            Crc64Context     crc64ctxData     = new Crc64Context();
            Md5Context       md5ctxData       = new Md5Context();
            Ripemd160Context ripemd160ctxData = new Ripemd160Context();
            Sha1Context      sha1ctxData      = new Sha1Context();
            Sha256Context    sha256ctxData    = new Sha256Context();
            Sha384Context    sha384ctxData    = new Sha384Context();
            Sha512Context    sha512ctxData    = new Sha512Context();
            SpamSumContext   ssctxData        = new SpamSumContext();

            Thread adlerThreadData     = new Thread(updateAdler);
            Thread crc16ThreadData     = new Thread(updateCRC16);
            Thread crc32ThreadData     = new Thread(updateCRC32);
            Thread crc64ThreadData     = new Thread(updateCRC64);
            Thread md5ThreadData       = new Thread(updateMD5);
            Thread ripemd160ThreadData = new Thread(updateRIPEMD160);
            Thread sha1ThreadData      = new Thread(updateSHA1);
            Thread sha256ThreadData    = new Thread(updateSHA256);
            Thread sha384ThreadData    = new Thread(updateSHA384);
            Thread sha512ThreadData    = new Thread(updateSHA512);
            Thread spamsumThreadData   = new Thread(updateSpamSum);

            adlerPacket     adlerPktData     = new adlerPacket();
            crc16Packet     crc16PktData     = new crc16Packet();
            crc32Packet     crc32PktData     = new crc32Packet();
            crc64Packet     crc64PktData     = new crc64Packet();
            md5Packet       md5PktData       = new md5Packet();
            ripemd160Packet ripemd160PktData = new ripemd160Packet();
            sha1Packet      sha1PktData      = new sha1Packet();
            sha256Packet    sha256PktData    = new sha256Packet();
            sha384Packet    sha384PktData    = new sha384Packet();
            sha512Packet    sha512PktData    = new sha512Packet();
            spamsumPacket   spamsumPktData   = new spamsumPacket();

            adler32ctxData.Init();
            adlerPktData.context = adler32ctxData;
            crc16ctxData.Init();
            crc16PktData.context = crc16ctxData;
            crc32ctxData.Init();
            crc32PktData.context = crc32ctxData;
            crc64ctxData.Init();
            crc64PktData.context = crc64ctxData;
            md5ctxData.Init();
            md5PktData.context = md5ctxData;
            ripemd160ctxData.Init();
            ripemd160PktData.context = ripemd160ctxData;
            sha1ctxData.Init();
            sha1PktData.context = sha1ctxData;
            sha256ctxData.Init();
            sha256PktData.context = sha256ctxData;
            sha384ctxData.Init();
            sha384PktData.context = sha384ctxData;
            sha512ctxData.Init();
            sha512PktData.context = sha512ctxData;
            ssctxData.Init();
            spamsumPktData.context = ssctxData;

            adlerPktData.data = data;
            adlerThreadData.Start(adlerPktData);
            crc16PktData.data = data;
            crc16ThreadData.Start(crc16PktData);
            crc32PktData.data = data;
            crc32ThreadData.Start(crc32PktData);
            crc64PktData.data = data;
            crc64ThreadData.Start(crc64PktData);
            md5PktData.data = data;
            md5ThreadData.Start(md5PktData);
            ripemd160PktData.data = data;
            ripemd160ThreadData.Start(ripemd160PktData);
            sha1PktData.data = data;
            sha1ThreadData.Start(sha1PktData);
            sha256PktData.data = data;
            sha256ThreadData.Start(sha256PktData);
            sha384PktData.data = data;
            sha384ThreadData.Start(sha384PktData);
            sha512PktData.data = data;
            sha512ThreadData.Start(sha512PktData);
            spamsumPktData.data = data;
            spamsumThreadData.Start(spamsumPktData);

            while (adlerThreadData.IsAlive || crc16ThreadData.IsAlive || crc32ThreadData.IsAlive ||
                   crc64ThreadData.IsAlive || md5ThreadData.IsAlive || ripemd160ThreadData.IsAlive ||
                   sha1ThreadData.IsAlive || sha256ThreadData.IsAlive || sha384ThreadData.IsAlive ||
                   sha512ThreadData.IsAlive || spamsumThreadData.IsAlive)
            {
            }

            List <ChecksumType> dataChecksums = new List <ChecksumType>();

            ChecksumType chk = new ChecksumType {
                type = ChecksumTypeType.adler32, Value = adler32ctxData.End()
            };

            dataChecksums.Add(chk);

            chk = new ChecksumType {
                type = ChecksumTypeType.crc16, Value = crc16ctxData.End()
            };
            dataChecksums.Add(chk);

            chk = new ChecksumType {
                type = ChecksumTypeType.crc32, Value = crc32ctxData.End()
            };
            dataChecksums.Add(chk);

            chk = new ChecksumType {
                type = ChecksumTypeType.crc64, Value = crc64ctxData.End()
            };
            dataChecksums.Add(chk);

            chk = new ChecksumType {
                type = ChecksumTypeType.md5, Value = md5ctxData.End()
            };
            dataChecksums.Add(chk);

            chk = new ChecksumType {
                type = ChecksumTypeType.ripemd160, Value = ripemd160ctxData.End()
            };
            dataChecksums.Add(chk);

            chk = new ChecksumType {
                type = ChecksumTypeType.sha1, Value = sha1ctxData.End()
            };
            dataChecksums.Add(chk);

            chk = new ChecksumType {
                type = ChecksumTypeType.sha256, Value = sha256ctxData.End()
            };
            dataChecksums.Add(chk);

            chk = new ChecksumType {
                type = ChecksumTypeType.sha384, Value = sha384ctxData.End()
            };
            dataChecksums.Add(chk);

            chk = new ChecksumType {
                type = ChecksumTypeType.sha512, Value = sha512ctxData.End()
            };
            dataChecksums.Add(chk);

            chk = new ChecksumType {
                type = ChecksumTypeType.spamsum, Value = ssctxData.End()
            };
            dataChecksums.Add(chk);

            return(dataChecksums);
        }
Пример #8
0
        internal List <ChecksumType> End()
        {
            List <ChecksumType> chks = new List <ChecksumType>();

            ChecksumType chk = new ChecksumType {
                type = ChecksumTypeType.adler32, Value = adler32ctx.End()
            };

            chks.Add(chk);

            chk = new ChecksumType {
                type = ChecksumTypeType.crc16, Value = crc16ctx.End()
            };
            chks.Add(chk);

            chk = new ChecksumType {
                type = ChecksumTypeType.crc32, Value = crc32ctx.End()
            };
            chks.Add(chk);

            chk = new ChecksumType {
                type = ChecksumTypeType.crc64, Value = crc64ctx.End()
            };
            chks.Add(chk);

            chk = new ChecksumType {
                type = ChecksumTypeType.md5, Value = md5ctx.End()
            };
            chks.Add(chk);

            chk = new ChecksumType {
                type = ChecksumTypeType.ripemd160, Value = ripemd160ctx.End()
            };
            chks.Add(chk);

            chk = new ChecksumType {
                type = ChecksumTypeType.sha1, Value = sha1ctx.End()
            };
            chks.Add(chk);

            chk = new ChecksumType {
                type = ChecksumTypeType.sha256, Value = sha256ctx.End()
            };
            chks.Add(chk);

            chk = new ChecksumType {
                type = ChecksumTypeType.sha384, Value = sha384ctx.End()
            };
            chks.Add(chk);

            chk = new ChecksumType {
                type = ChecksumTypeType.sha512, Value = sha512ctx.End()
            };
            chks.Add(chk);

            chk = new ChecksumType {
                type = ChecksumTypeType.spamsum, Value = ssctx.End()
            };
            chks.Add(chk);

            return(chks);
        }