/// <summary>
        /// 编辑时间;
        /// </summary>
        /// <param name="fileStoken2"></param>
        /// <param name="extFileInfo"></param>
        private static void EditTime(
            FileStokenBase2 fileStoken2,
            ExtFileInfo extFileInfo)
        {
            if (fileStoken2 == null)
            {
                throw new ArgumentNullException(nameof(fileStoken2));
            }

            if (extFileInfo == null)
            {
                throw new ArgumentNullException(nameof(extFileInfo));
            }

            //编辑时间;
            if (extFileInfo.StExt4Inode == null)
            {
                LoggerService.WriteCallerLine($"{nameof(extFileInfo)} can't be null.");
            }

            extFileInfo.StExt4Inode.Value.GetMacTime(out var modifiedTime, out var accessedTime, out var createTime);
            fileStoken2.ModifiedTime = modifiedTime;
            fileStoken2.AccessedTime = accessedTime;
            fileStoken2.CreateTime   = createTime;
        }
Пример #2
0
        /// <summary>
        /// 应用本地文件系统信息至FileStoken;
        /// </summary>
        /// <param name="fsInfo"></param>
        /// <param name="stokenBase2"></param>
        private static void ApplyFileSystemInfoToStokenBase(FileSystemInfo fsInfo, FileStokenBase2 stokenBase2)
        {
            if (fsInfo == null)
            {
                throw new ArgumentNullException(nameof(fsInfo));
            }

            if (stokenBase2 == null)
            {
                throw new ArgumentNullException(nameof(stokenBase2));
            }

            stokenBase2.AccessedTime = fsInfo.LastAccessTime;
            stokenBase2.ModifiedTime = fsInfo.LastWriteTime;
            stokenBase2.CreateTime   = fsInfo.CreationTime;

            stokenBase2.Name = fsInfo.Name;
        }
        /// <summary>
        /// 编辑目录/文件/其它的时间,簇列表等值;
        /// </summary>
        /// <param name="fileStoken2"></param>
        private static void EditFileStoken2(
            FileStokenBase2 fileStoken2,
            ExtPartInfo partInfo,
            ExtFileInfo extFileInfo)
        {
            if (fileStoken2 == null)
            {
                throw new ArgumentNullException(nameof(fileStoken2));
            }

            if (extFileInfo == null)
            {
                throw new ArgumentNullException(nameof(extFileInfo));
            }

            if (extFileInfo.BlockListPtr == null)
            {
                throw new InvalidOperationException($"{nameof(extFileInfo.BlockListPtr)} of {nameof(ExtFileInfo)} can't be nullptr.");
            }

            if (partInfo == null)
            {
                throw new ArgumentNullException(nameof(partInfo));
            }

            fileStoken2.SetInstance(extFileInfo, Constants.FileStokenTag_ExtFileInfo);

            fileStoken2.Name    = extFileInfo.StExt4DirEntry?.Name;
            fileStoken2.Size    = extFileInfo.StExt4Inode?.Size ?? 0;
            fileStoken2.Deleted = extFileInfo.StDirEntry?.bDel ?? false;

            EditTime(fileStoken2, extFileInfo);
#if DEBUG
            //if (fileStoken2.Name.StartsWith(".journal")) {

            //}
#endif
            EditBlockGroups(fileStoken2, partInfo, extFileInfo);
        }
        /// <summary>
        /// 编辑块组;
        /// </summary>
        /// <param name="fileStoken2"></param>
        /// <param name="partInfo"></param>
        /// <param name="extFileInfo"></param>
        private static void EditBlockGroups(
            FileStokenBase2 fileStoken2,
            ExtPartInfo partInfo,
            ExtFileInfo extFileInfo)
        {
            if (fileStoken2 == null)
            {
                throw new ArgumentNullException(nameof(fileStoken2));
            }

            if (extFileInfo == null)
            {
                throw new ArgumentNullException(nameof(extFileInfo));
            }

            //if (extFileInfo.BlockListPtr == null) {
            //    throw new InvalidOperationException($"{nameof(extFileInfo.BlockListPtr)} of {nameof(ExtFileInfo)} can't be nullptr.");
            //}

            if (partInfo == null)
            {
                throw new ArgumentNullException(nameof(partInfo));
            }

            if (extFileInfo.BlockList == null)
            {
                //LoggerService.WriteCallerLine($"{nameof(extFileInfo.BlockList)} can't be null.");
                return;
            }

            var blocks    = extFileInfo.BlockList;
            var blockSize = partInfo.SuperBlock.StructInstance.BlockSize;

            if (blocks == null)
            {
                return;
            }

            //遍历,粘合,将连续的簇列表并入为一个块组;
            StBlockList?lastBlock       = null;
            long        firstClusterLBA = 0;

            int   blockCount   = 0;
            ulong lastBlockNum = 0;

            //重置局部变量;参数为本次(循环)最新的独立头块;
            void Reset(StBlockList block)
            {
                lastBlock       = block;
                blockCount      = (int)block.count;
                lastBlockNum    = block.address;
                firstClusterLBA = (long)block.address * blockSize;
            }

            //压栈;
            void PushBlockGroup()
            {
                if (lastBlock == null)
                {
                    return;
                }

                fileStoken2.BlockGroups.Add(
                    BlockGroupFactory.CreateNewBlockGroup((long)lastBlock.Value.address, blockCount, blockSize, firstClusterLBA)
                    );
            }

            try {
                foreach (var cluster in blocks)
                {
                    if (lastBlock == null)
                    {
                        Reset(cluster);
                        continue;
                    }

                    //如果是连续的簇号则+1;
                    if (cluster.address == lastBlockNum + 1)
                    {
                        lastBlockNum = cluster.address;
                        blockCount++;
                    }
                    //否则,构造BlockGroup,插入新建链表,并重置;
                    else
                    {
                        PushBlockGroup();
                        Reset(cluster);
                    }
                }

                if (lastBlock != null)
                {
                    PushBlockGroup();
                }
            }
            catch (Exception ex) {
                LoggerService.WriteCallerLine(ex.Message);
            }
        }
        /// <summary>
        /// 处理子文件/目录/其它加载;
        /// </summary>
        /// <param name="haveFileCollection"></param>
        /// <param name="filePtr">非托管文件节点指针</param>
        /// <param name="ntfSzAct"></param>
        /// <param name="isCancel"></param>
        private static void DealWithFileNode(
            IHaveFileCollection haveFileCollection,
            ExtPartInfo partInfo,
            IntPtr filePtr,
            Action <long> ntfSzAct,
            Func <bool> isCancel)
        {
            while (filePtr != IntPtr.Zero)
            {
                IFile           file        = null;
                FileStokenBase2 fileStoken2 = null;
                var             stDirEntry  = filePtr.GetStructure <StDirEntry>();

                //压栈;避免使用continue导致死循环以及冗余代码;
                void Push()
                {
                    if (file != null)
                    {
                        haveFileCollection.Children.Add(file);
                    }
                    filePtr = stDirEntry.Next;
                }

                if (stDirEntry.DirInfo == IntPtr.Zero)
                {
                    Push();
                    continue;
                }

                var stExtDirEntry = stDirEntry.DirInfo.GetStructure <StExt4DirEntry>();

                var stExtINodePtr = ExtX_Get_InodeInfo(partInfo.ExtUnmanagedManager.ExtManagerPtr, stExtDirEntry.inode);
                if (stExtINodePtr == IntPtr.Zero)
                {
                    LoggerService.WriteCallerLine($"{nameof(stExtINodePtr)} can't be nullptr.");
                    Push();
                    continue;
                }
                var stExtINode = stExtINodePtr.GetStructure <StExt4Inode>();

                var stBlockListPtr = ExtX_Get_BlockList(partInfo.ExtUnmanagedManager.ExtManagerPtr, stExtINodePtr);
                if (stBlockListPtr == IntPtr.Zero)
                {
                    //LoggerService.WriteCallerLine($"{nameof(stBlockListPtr)} can't be nullptr.");
                    Push();
                    continue;
                }

                var extFileInfo = new ExtFileInfo {
                    StDirEntry     = stDirEntry,
                    StExt4DirEntry = stExtDirEntry,
                    BlockListPtr   = stBlockListPtr,
                    StExt4Inode    = stExtINode
                };

                if (stExtDirEntry.file_type == Ext4FileType.Directory)
                {
                    var dir = FileFactory.CreateDirectory(Constants.DirectoryKey_Ext);

                    var dirStoken = dir.GetStoken(Constants.DirectoryKey_Ext);
                    dirStoken.TypeGuid = Constants.DirectoryType_Ext;

                    file        = dir;
                    fileStoken2 = dirStoken;

                    EditFileStoken2(fileStoken2, partInfo, extFileInfo);
                    //当目录名为".."或者"."时,跳过加载子文件;
                    //且所加载目录不能被删除;
                    if (stExtDirEntry._name[0] != '.' && !stDirEntry.bDel)
                    {
                        LoadDirectoryContent(dir, partInfo, ntfSzAct, isCancel);
                    }
                    else if (stExtDirEntry._name[1] == '.')
                    {
                        dirStoken.IsBack = true;
                    }
                    else
                    {
                        dirStoken.IsLocalBackUp = true;
                    }
                }
                else if (stExtDirEntry.file_type == Ext4FileType.RegularFile)
                {
                    var regFile       = FileFactory.CreateRegularFile(Constants.RegularFileKey_Ext);
                    var regFileStoken = regFile.GetStoken(Constants.RegularFileKey_Ext);

                    regFileStoken.TypeGuid = Constants.RegularFileType_Ext;

                    file        = regFile;
                    fileStoken2 = regFileStoken;

                    EditFileStoken2(fileStoken2, partInfo, extFileInfo);
                    ntfSzAct?.Invoke(fileStoken2.Size);
                }

                Push();

                if (isCancel?.Invoke() ?? false)
                {
                    return;
                }
            }
        }