/// <summary>
        /// 根据Gpt分区表项编辑Gpt分区项;
        /// </summary>
        /// <param name="gptDeviceInfo"></param>
        /// <param name="devieStoken"></param>
        private static void EditGptPartEntries(GPTDeviceInfo gptDeviceInfo, DeviceStoken deviceStoken)
        {
            if (gptDeviceInfo == null)
            {
                throw new ArgumentNullException(nameof(gptDeviceInfo));
            }
            if (deviceStoken == null)
            {
                throw new ArgumentNullException(nameof(deviceStoken));
            }

            gptDeviceInfo.GptPartInfos.ForEach(gptPartInfo => {
                //若EFIPTable为空,则非分区;
                if (gptPartInfo.EFIPTable == null)
                {
                    return;
                }

                var efiTable         = gptPartInfo.EFIPTable.StructInstance;
                var entry            = PartitionEntryFactory.CreatePartitionEntry(Constants.PartEntryKey_GPT);
                var entryStoken      = entry.GetStoken(Constants.PartEntryKey_GPT);
                entryStoken.TypeGUID = Constants.PartEntryType_GPT;

                entryStoken.Name = gptPartInfo.EFIPTable.StructInstance.PartTabName;

                entryStoken.StartLBA = (long)gptPartInfo.StGptPTable.nOffset;
                entryStoken.Size     = Marshal.SizeOf(typeof(StEFIPTable));

                entryStoken.PartStartLBA = (long)efiTable.PartTabStartLBA * deviceStoken.BlockSize;
                entryStoken.PartSize     = (long)(efiTable.PartTabEndLBA - efiTable.PartTabStartLBA) * deviceStoken.BlockSize;

                deviceStoken.PartitionEntries.Add(entry);
            });
        }
        /// <summary>
        /// 编辑Dos设备的Stoken;
        /// </summary>
        /// <param name="deviceStoken"></param>
        /// <param name="xElem">案件文件相关Xml元素</param>
        private static void EditStokenOnDos(
            DeviceStoken deviceStoken,
            IUnmanagedBasicDeviceManager entity)
        {
            if (deviceStoken == null)
            {
                throw new ArgumentNullException(nameof(deviceStoken));
            }

            var dosDeviceInfo = new DOSDeviceInfo();

            try {
                deviceStoken.TypeGuid  = Constants.DeviceType_DOS;
                deviceStoken.PartsType = Constants.PartsType_DOS;

                //获取Dos链表;
                var partPtr       = Partition_Get_DosPTable(entity.BasicDevicePtr);
                var partNode      = partPtr;
                var infoDiskIndex = 0;

                while (partNode != IntPtr.Zero)
                {
                    var dosPTable   = partNode.GetStructure <StDosPTable>();
                    var dosPartInfo = new DOSPartInfo {
                        DosPTable = new DosPTable(dosPTable)
                    };

                    if (dosPTable.Info != IntPtr.Zero)
                    {
                        var stInfoDisk = dosPTable.Info.GetStructure <StInFoDisk>();
                        dosPartInfo.InfoDisk = new InfoDisk(stInfoDisk)
                        {
                            InternalDisplayName = $"{LanguageService.FindResourceString(Constants.DisplayName_InfoDisk)}{++infoDiskIndex}"
                        };
                    }

                    dosDeviceInfo.DosPartInfos.Add(dosPartInfo);
                    partNode = dosPTable.next;
                }

                EditDosPartEntries(dosDeviceInfo, deviceStoken);

                //编辑拓展;
                deviceStoken.SetInstance(dosDeviceInfo, Constants.DeviceStokenTag_DOSDeviceInfo);
            }
            catch (Exception ex) {
                LoggerService.WriteCallerLine(ex.Message);
            }
        }
        /// <summary>
        /// 释放非托管的内存;
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected static void OnDeviceDisposing(object sender, EventArgs e)
        {
            if (!(sender is IDevice device))
            {
                return;
            }

            DeviceStoken   deviceStoken = null;
            BaseDeviceInfo deviceInfo   = null;

            //验证类型,尝试获取凭据;
            try {
                if (device.TypeGuid == Constants.DeviceType_DOS)
                {
                    deviceStoken = device.GetStoken(Constants.DeviceKey_DOS);
                    deviceInfo   = deviceStoken.GetInstance <DOSDeviceInfo>(Constants.DeviceStokenTag_DOSDeviceInfo);
                }
                else if (device.TypeGuid == Constants.DeviceType_DOS)
                {
                    deviceStoken = device.GetStoken(Constants.DeviceKey_GPT);
                    deviceInfo   = deviceStoken.GetInstance <GPTDeviceInfo>(Constants.DeviceStokenTag_GPTDeviceInfo);
                }
            }
            catch (Exception ex) {
                LoggerService.WriteCallerLine(ex.Message);
            }

            //若凭据为空,需返回;
            if (deviceStoken == null)
            {
                return;
            }

            if (deviceInfo == null)
            {
                return;
            }

            try {
                deviceInfo.UnmanagedManager.Dispose();
            }
            catch (Exception ex) {
                LoggerService.WriteCallerLine(ex.Message);
            }
        }
Esempio n. 4
0
        //测试点击设备节点后响应;
        static void TestDeviceNodeClick()
        {
            var devStoken = new DeviceStoken {
                BaseStream = System.IO.File.OpenRead("D://youdaonote_unsilent38.exe"),
                Name       = "mmp"
            };

            //for (int i = 0; i < 24; i++) {
            //    var partEnStoken = new PartitionEntryStoken {
            //        StartLBA = i * 16,
            //        Size = 16
            //    };
            //    devStoken.PartitionEntries.Add(
            //        PartitionEntryFactory.CreatePartitionEntry(string.Empty)
            //    );
            //}


            //var dev = new IDevice(string.Empty, devStoken);
            //var rand = new Random();
            //for (int i = 0; i < 24; i++) {
            //    var part = new IPartition(string.Empty, new PartitionStoken {
            //        Name = "Dada",
            //        Size = rand.Next(25535),
            //        BaseStream = MulPeriodsStream.CreateFromStream(devStoken.BaseStream,
            //        new(long StartIndex, long Size)[] {
            //            (25535 * i,1024)
            //        })
            //    });

            //    dev.Children.Add(part);
            //    dev.SetStartLBA(part, i * 200);
            //}

            var unit = TreeUnitFactory.CreateNew(SingularityForensic.Contracts.FileExplorer.Constants.TreeUnitType_FileSystem);

            MainTreeService.Current?.AddUnit(null, unit);
            CommonEventHelper.GetEvent <TreeUnitSelectedChangedEvent>().Publish((unit, MainTreeService.Current));
            CommonEventHelper.GetEvent <TreeUnitSelectedChangedEvent>().Publish((unit, MainTreeService.Current));
            CommonEventHelper.GetEvent <TreeUnitSelectedChangedEvent>().Publish((unit, MainTreeService.Current));
            CommonEventHelper.GetEvent <TreeUnitSelectedChangedEvent>().Publish((unit, MainTreeService.Current));
        }
        public IFile ParseStream(Stream stream, string name, IProgressReporter reporter)
        {
            if (stream == null)
            {
                throw new ArgumentNullException(nameof(stream));
            }

            var pType = GetPartsType(stream);

            if (pType == null)
            {
                throw new InvalidOperationException($"The {nameof(stream)} is not a valid base device stream.");
            }

            IDevice      device       = null;
            DeviceStoken deviceStoken = null;
            var          unEntity     = UnMgdBasicDeviceManagerFactory.Create(stream);

            //编辑Stoken;
            void EditStoken()
            {
                if (deviceStoken == null)
                {
                    throw new InvalidOperationException($"{nameof(deviceStoken)} can't be null.");
                }

                deviceStoken.BaseStream = stream;
                deviceStoken.BlockSize  = 512;
                deviceStoken.Name       = name;
                deviceStoken.Size       = stream.Length;
            }

            switch (pType.Value)
            {
            case InnerPartsType.DOS:
                device       = FileFactory.CreateDevice(Constants.DeviceKey_DOS);
                deviceStoken = device.GetStoken(Constants.DeviceKey_DOS);
                EditStoken();
                EditStokenOnDos(deviceStoken, unEntity);
                break;

            case InnerPartsType.GPT:
                device       = FileFactory.CreateDevice(Constants.DeviceKey_GPT);
                deviceStoken = device.GetStoken(Constants.DeviceKey_GPT);
                EditStoken();
                EditStokenOnGpt(deviceStoken, unEntity);
                break;

            default:
                break;
            }

            if (device != null)
            {
                //加载分区;
                device.FillParts(reporter);
                device.Disposing += OnDeviceDisposing;
            }


            return(device);
        }
        /// <summary>
        /// 编辑GPT设备的Stoken;
        /// </summary>
        /// <param name="stream"></param>
        /// <param name="name"></param>
        /// <param name="xElem"></param>
        /// <param name="reporter"></param>
        /// <returns></returns>
        private static void EditStokenOnGpt(DeviceStoken deviceStoken, IUnmanagedBasicDeviceManager entity)
        {
            if (deviceStoken == null)
            {
                throw new ArgumentNullException(nameof(deviceStoken));
            }

            var gptDeviceInfo = new GPTDeviceInfo();

            try {
                deviceStoken.TypeGuid  = Constants.DeviceType_GPT;
                deviceStoken.PartsType = Constants.PartsType_GPT;

                //获取GPT链表;
                var partPtr        = Partition_Get_GptPTable(entity.BasicDevicePtr);
                var partNode       = partPtr;
                var infoDiskIndex  = 0;
                var efiInfoIndex   = 0;
                var efiPTableIndex = 0;

                while (partNode != IntPtr.Zero)
                {
                    var gptPTable   = partNode.GetStructure <StGptPTable>();
                    var gptPartInfo = new GPTPartInfo {
                        StGptPTable = gptPTable
                    };

                    if (gptPTable.InfoDisk != IntPtr.Zero)
                    {
                        var stInfoDisk = gptPTable.InfoDisk.GetStructure <StInFoDisk>();
                        gptPartInfo.InfoDisk = new InfoDisk(stInfoDisk)
                        {
                            InternalDisplayName = $"{LanguageService.FindResourceString(Constants.DisplayName_InfoDisk)}{++infoDiskIndex}"
                        };
                    }

                    if (gptPTable.EFIInfo != IntPtr.Zero)
                    {
                        var stEFIInfo = gptPTable.EFIInfo.GetStructure <StEFIInfo>();
                        gptPartInfo.EFIInfo = new EFIInfo(stEFIInfo)
                        {
                            InternalDisplayName = $"{LanguageService.FindResourceString(Constants.DisplayName_EFIInfo)}{++efiInfoIndex}"
                        };
                    }

                    if (gptPTable.EFIPTable != IntPtr.Zero)
                    {
                        var stEFITable = gptPTable.EFIPTable.GetStructure <StEFIPTable>();
                        gptPartInfo.EFIPTable = new EFIPTable(stEFITable)
                        {
                            InternalDisplayName = $"{LanguageService.FindResourceString(Constants.DisplayName_EFIPTable)}{++efiPTableIndex}"
                        };
                    }

                    gptDeviceInfo.GptPartInfos.Add(gptPartInfo);
                    partNode = gptPTable.next;
                }

                EditGptPartEntries(gptDeviceInfo, deviceStoken);

                //编辑拓展;
                deviceStoken.SetInstance(gptDeviceInfo, Constants.DeviceStokenTag_GPTDeviceInfo);
            }
            catch (Exception ex) {
                LoggerService.WriteCallerLine(ex.Message);
            }
        }
        /// <summary>
        /// 根据Dos分区表项编辑Dos分区项;
        /// </summary>
        /// <param name="dosDeviceInfo"></param>
        private static void EditDosPartEntries(DOSDeviceInfo dosDeviceInfo, DeviceStoken deviceStoken)
        {
            if (dosDeviceInfo == null)
            {
                throw new ArgumentNullException(nameof(dosDeviceInfo));
            }
            if (deviceStoken == null)
            {
                throw new ArgumentNullException(nameof(deviceStoken));
            }

            //拓展分区偏移;
            long extendPartLBA = 0;

            dosDeviceInfo.DosPartInfos.ForEach(dosPartInfo => {
                //确定起始绝对位移;
                long startLBA     = 0;
                long?partStartLBA = null;
                long?partSize     = dosPartInfo.InfoDisk.StructInstance.AllSector * SECSIZE;

                switch (dosPartInfo.DosPTable.StDosPTable.DosPartType)
                {
                case DosPartType.Error:
                    return;

                case DosPartType.Main:
                    startLBA     = (long)dosPartInfo.DosPTable.StDosPTable.nOffset;
                    partStartLBA = dosPartInfo.InfoDisk.StructInstance.HeadSector * SECSIZE;
                    break;

                case DosPartType.Extend:
                    extendPartLBA += dosPartInfo.InfoDisk.StructInstance.HeadSector * SECSIZE;
                    startLBA       = (long)dosPartInfo.DosPTable.StDosPTable.nOffset;
                    partSize       = null;
                    partStartLBA   = null;
                    break;

                case DosPartType.Logic:
                    startLBA     = (long)dosPartInfo.DosPTable.StDosPTable.nOffset;
                    partStartLBA = extendPartLBA + dosPartInfo.InfoDisk.StructInstance.HeadSector * SECSIZE;
                    break;

                default:
                    break;
                }
                var entry       = PartitionEntryFactory.CreatePartitionEntry(Constants.PartEntryKey_DOS);
                var entryStoken = entry.GetStoken(Constants.PartEntryKey_DOS);

                entryStoken.TypeGUID = FromDosPartTypeToCons(dosPartInfo.DosPTable.StDosPTable.DosPartType);

                entryStoken.StartLBA = startLBA;
                entryStoken.Size     = Marshal.SizeOf(typeof(StInFoDisk));

                entryStoken.PartStartLBA = partStartLBA;
                entryStoken.PartSize     = partSize;

                entryStoken.SetInstance(dosPartInfo, Constants.PartitionEntryStokenTag_DOS);

                deviceStoken.PartitionEntries.Add(entry);
            });
        }