/// <summary>
        /// 根据分区表项内容生成子分区;
        /// </summary>
        /// <param name="device"></param>
        /// <param name="key"></param>
        /// <param name="reporter"></param>
        public void FillParts(IDevice device, IProgressReporter reporter)
        {
            if (device == null)
            {
                throw new ArgumentNullException(nameof(device));
            }

            var partIndex = 0;

            foreach (var entry in device.PartitionEntries)
            {
                IFile file = null;

                //若分区表项描述分区大小为空;
                if (entry.PartSize == null ||
                    entry.PartStartLBA == null)
                {
                    continue;
                }

                var partSize     = entry.PartSize.Value;
                var partStartLBA = entry.PartStartLBA.Value;

                //若起始位移大于设备流大小,则舍弃;
                if (entry.PartStartLBA >= device.Size)
                {
                    continue;
                }


                //若分区描述大小偏移超出设备流,则截取从StartLBA到设备流大小长度的区间作为分区区间;
                var size       = Math.Min(partSize + partStartLBA, device.Size) - partStartLBA;
                var partStream = MulPeriodsStream.CreateFromStream(
                    device.BaseStream,
                    new(long StartIndex, long Size)[] {
Пример #2
0
        //通过文件创建流对象;
        public static Stream CreateStreamByFile(IFile file)
        {
            if (file != null)
            {
                try {
                    if (file.Type == FileType.BlockDeviceFile)                          //若为块文件,则文件为设备或分区;
                    {
                        if (file is Partition part)                                     //若为分区,则根据分区的起始,终止地址构造流;
                        {
                            var device = file.GetParent <Device>();
                            if (device != null)
                            {
                                return(InterceptStream.CreateFromStream(device.Stream, part.StartLBA, part.Size));
                            }
                        }
                        else if (file is Device device)                                            //若为设备,直接返回设备流;
                        {
                            return(device.Stream);
                        }
                    }
                    //否则直接根据StartLBA,EndLBA构建截取流;
                    else if (file is RegularFile regFile)
                    {
                        return(regFile.GetStream());
                    }
                    else if (file is IBlockGroupedFile)
                    {
                        var blockGroupedFile = file as IBlockGroupedFile;
                        var part             = file.GetParent <Partition>();
                        var device           = file.GetParent <Device>();
                        if (part != null && device != null)
                        {
                            var blockSize  = part.ClusterSize;
                            var partStream = InterceptStream.CreateFromStream(device.Stream, part.StartLBA, part.Size);
                            //若块组不为空,则遍历块组组成虚拟流;
                            if (blockGroupedFile.BlockGroups != null)
                            {
                                var ranges = blockGroupedFile.BlockGroups.Select(p =>
                                                                                 ValueTuple.Create(p.BlockAddress * blockSize + p.Offset, p.Count * blockSize)).ToArray();

                                var blockSub = ranges.Sum(p => p.Item2) - file.Size;
                                if (ranges?.Count() > 0 && 0 < blockSub && blockSub < blockSize)
                                {
                                    ranges[ranges.Count() - 1].Item2 -= blockSub;
                                }
                                var multiStream = MulPeriodsStream.CreateFromStream(partStream, ranges);
                                return(multiStream);
                            }
                        }
                    }
                }
                catch (Exception ex) {
                    Logger.WriteLine($"{nameof(StreamExtensions)}->{nameof(CreateStreamByFile)}:{ex.Message}");
                }
            }

            return(null);
        }
Пример #3
0
        }                                                           //创建时间;

        public virtual Stream GetStream(bool isReadOnly = true)
        {
            var part = this.GetParent <Partition>();

            if (part == null)
            {
                Logger.WriteCallerLine($"{nameof(part)} can't be null!");
            }

            //若块组不为空,则取所有的块字段流;
            if (BlockGroups != null)
            {
                if (part != null)
                {
                    var blockSize  = part.ClusterSize;
                    var partStream = part.GetStream();
                    //若块组不为空,则遍历块组组成虚拟流;

                    var ranges = BlockGroups.Select(p =>
                                                    ValueTuple.Create(
                                                        p.BlockAddress * blockSize,
                                                        p.Count * blockSize)).ToArray();

                    var blockSub = ranges.Sum(p => p.Item2) - Size;
                    if (ranges?.Count() > 0 && 0 < blockSub && blockSub < blockSize)
                    {
                        ranges[ranges.Count() - 1].Item2 -= blockSub;
                    }
                    var multiStream = MulPeriodsStream.CreateFromStream(partStream, ranges);
                    return(multiStream);
                }
            }
            //否则直接取连续的流;
            else
            {
                var blockSize = part.ClusterSize;

                var partStream = part.GetStream();
                if (partStream != null)
                {
                    var fiStream = InterceptStream.CreateFromStream(partStream, StartLBA, Size);
                    //var buffer = new byte[128];
                    //var read = fiStream.Read(buffer, 0, buffer.Length);
                    return(fiStream);
                }
            }
            return(null);
        }
Пример #4
0
        public Stream GetInputStream(IFile file)
        {
            if (!(file is IBlockGroupedFile blockGrouped))
            {
                return(null);
            }

            var streamFile = blockGrouped.GetParent <IStreamFile>();

            if (streamFile == null)
            {
                LoggerService.Current?.WriteCallerLine($"{nameof(streamFile)} can't be null!");
                return(null);
            }

            //检查块组是否为空;
            if (blockGrouped.BlockGroups == null)
            {
                LoggerService.WriteCallerLine($"{nameof(blockGrouped.BlockGroups)} can't be null.");
                return(null);
            }

            //检查块组集合是否为空;
            if (blockGrouped.BlockGroups.FirstOrDefault() == null)
            {
                LoggerService.WriteCallerLine($"{nameof(blockGrouped.BlockGroups)} can't be empty.");
                return(null);
            }

            var blockSize  = streamFile.BlockSize;
            var partStream = streamFile.BaseStream;

            if (partStream == null)
            {
                LoggerService.WriteCallerLine($"{nameof(streamFile.BaseStream)} can't be null.");
                return(null);
            }

            //若块组不为空,则遍历块组组成虚拟流;
            var blockSum = blockGrouped.BlockGroups.Sum(p => p.BlockSize * p.Count);
            //核对和Size之间的差,最终将要切去最后一个簇的多余内容;
            var blockSub = blockSum - file.Size;
            //取所有块组的位置;
            var ranges = blockGrouped.BlockGroups.Select(p =>
                                                         ValueTuple.Create(p.Offset, p.Count * p.BlockSize)).
                         ToArray();

            //假如file.Size大于块组合,则忽视大小,直接取块组合;
            if (blockSub < 0)
            {
                return(MulPeriodsStream.CreateFromStream(partStream, ranges));
            }
            //假如file.Size小于块组合;
            else
            {
                long blockSumSize  = 0;
                int  rangeIndex    = 0;
                long lastRangeSize = 0;
                foreach (var range in ranges)
                {
                    if (blockSumSize + range.Item2 >= file.Size)
                    {
                        lastRangeSize = file.Size - blockSumSize;
                        break;
                    }
                    blockSumSize += range.Item2;
                    rangeIndex++;
                }

                ranges[rangeIndex].Item2 = lastRangeSize;

                return(MulPeriodsStream.CreateFromStream(partStream, ranges.Take(rangeIndex + 1).ToArray()));
            }
        }