public static bool TryGetMbrInfo(DiskImage hdd, out MbrPartitioningInfo info)
        {
            info = default;

            Debug.Assert(Unsafe.SizeOf <MbrHeader>() == MBR_SIZE);

            var       headerBytes = hdd.ReadBytes(0, MBR_SIZE);
            MbrHeader header      = MemoryMarshal.Cast <byte, MbrHeader>(new Span <byte>(headerBytes))[0];

            if (header.BootSig != MbrHeader.MbrMagic)
            {
                return(false);
            }

            bool hasGpt = false;

            for (int i = 0; i < 4; i++)
            {
                var part = header.GetPartition(i);
                hasGpt |= part.Type == MbrPartitionType.GptProtective;
            }

            //MBR paritioned disks often contain boot loaders in non-paritioned space.
            //So to be safe copy all the data.
            List <FileExtent> partitions = new List <FileExtent>()
            {
                new FileExtent(MBR_SIZE, hdd.Length - MBR_SIZE),
            };

            info = new MbrPartitioningInfo(headerBytes, partitions, hasGpt);
            return(true);
        }
        public async Task WriteParitionTableAsync(Stream diskStream, long diskLength)
        {
            MbrHeader header = MemoryMarshal.Cast <byte, MbrHeader>(new ReadOnlySpan <byte>(mHeader))[0];

            fixupPartitionEntry(ref header.Partition1, diskLength);
            fixupPartitionEntry(ref header.Partition2, diskLength);
            fixupPartitionEntry(ref header.Partition3, diskLength);
            fixupPartitionEntry(ref header.Partition4, diskLength);

            var headerBytes = new byte[MBR_SIZE];

            MemoryMarshal.Write(new Span <byte>(headerBytes), ref header);

            //var headerBytes = MemoryMarshal.Write
            diskStream.Seek(0, SeekOrigin.Begin);
            await diskStream.WriteAsync(headerBytes, 0, headerBytes.Length);

            await diskStream.FlushAsync();
        }